From fa7172ff95e134310791b848cd3284075fdf8014 Mon Sep 17 00:00:00 2001 From: etoledom Date: Fri, 25 Oct 2019 12:39:33 +0200 Subject: [PATCH 001/113] Force block inserter to re-render on device rotation (#18101) * Force block inserter to re-render on device rotation * Dummy * Revert "Dummy" This reverts commit 037f076679cb8f89a65ecafdd9130465a0fc03d9. --- .../src/components/inserter/menu.native.js | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inserter/menu.native.js b/packages/block-editor/src/components/inserter/menu.native.js index a03e5f818540c6..591932dde8ab62 100644 --- a/packages/block-editor/src/components/inserter/menu.native.js +++ b/packages/block-editor/src/components/inserter/menu.native.js @@ -21,6 +21,15 @@ import { BottomSheet, Icon } from '@wordpress/components'; import styles from './style.scss'; export class InserterMenu extends Component { + constructor() { + super( ...arguments ); + + this.onLayout = this.onLayout.bind( this ); + this.state = { + numberOfColumns: this.calculateNumberOfColumns(), + }; + } + componentDidMount() { this.onOpen(); } @@ -47,9 +56,13 @@ export class InserterMenu extends Component { this.props.hideInsertionPoint(); } + onLayout() { + const numberOfColumns = this.calculateNumberOfColumns(); + this.setState( { numberOfColumns } ); + } + render() { const { getStylesFromColorScheme } = this.props; - const numberOfColumns = this.calculateNumberOfColumns(); const bottomPadding = styles.contentBottomPadding; const modalIconWrapperStyle = getStylesFromColorScheme( styles.modalIconWrapper, styles.modalIconWrapperDark ); const modalIconStyle = getStylesFromColorScheme( styles.modalIcon, styles.modalIconDark ); @@ -63,10 +76,11 @@ export class InserterMenu extends Component { hideHeader > From 51b5de31b9be291d41a4b18866c49a7ca393c9bd Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Fri, 25 Oct 2019 17:09:25 +0300 Subject: [PATCH 002/113] Add left right borders to inner blocks (#18109) --- .../block-editor/src/components/inner-blocks/index.native.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-editor/src/components/inner-blocks/index.native.js b/packages/block-editor/src/components/inner-blocks/index.native.js index 2b6a6c9320c923..6d2d4290772fa7 100644 --- a/packages/block-editor/src/components/inner-blocks/index.native.js +++ b/packages/block-editor/src/components/inner-blocks/index.native.js @@ -122,6 +122,7 @@ class InnerBlocks extends Component { rootClientId={ clientId } renderAppender={ renderAppender } withFooter={ false } + isFullyBordered={ true } /> ) } From 2461051d31d849337d048aec3f3acd029b94a646 Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Fri, 25 Oct 2019 18:59:00 +0300 Subject: [PATCH 003/113] [Mobile]Remove alignment options from Media & Text until they are fixed (#18112) * Remove alignment options temporarily * Dummy commit --- .../block-library/src/media-text/edit.native.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/media-text/edit.native.js b/packages/block-library/src/media-text/edit.native.js index 73532a322916ae..f83092d287431c 100644 --- a/packages/block-library/src/media-text/edit.native.js +++ b/packages/block-library/src/media-text/edit.native.js @@ -10,7 +10,7 @@ import { View } from 'react-native'; import { __, _x } from '@wordpress/i18n'; import { BlockControls, - BlockVerticalAlignmentToolbar, + // BlockVerticalAlignmentToolbar, InnerBlocks, withColors, } from '@wordpress/block-editor'; @@ -131,15 +131,16 @@ class MediaTextEdit extends Component { attributes, backgroundColor, setAttributes, - isMobile, + // isMobile, } = this.props; const { - isStackedOnMobile, + // isStackedOnMobile, mediaPosition, mediaWidth, verticalAlignment, } = attributes; - const shouldStack = isStackedOnMobile && isMobile; + const shouldStack = false; // We are temporarily not stacking until we fix alignment buttons + // const shouldStack = isStackedOnMobile && isMobile; // <<< Original line const temporaryMediaWidth = shouldStack ? 100 : ( this.state.mediaWidth || mediaWidth ); const widthString = `${ temporaryMediaWidth }%`; const containerStyles = { @@ -165,9 +166,9 @@ class MediaTextEdit extends Component { onClick: () => setAttributes( { mediaPosition: 'right' } ), } ]; - const onVerticalAlignmentChange = ( alignment ) => { + /* const onVerticalAlignmentChange = ( alignment ) => { setAttributes( { verticalAlignment: alignment } ); - }; + }; */ return ( <> @@ -175,11 +176,12 @@ class MediaTextEdit extends Component { + { /* // Temporarily commenting out until alignment functionality is fixed + /> */ } From 6506bfccd4f905e539595ae8237951193f67fcb8 Mon Sep 17 00:00:00 2001 From: Drapich Piotr Date: Mon, 28 Oct 2019 11:23:32 +0100 Subject: [PATCH 004/113] Fix: remove getItemLayout which causes scroll position issue (#18060) --- .../block-editor/src/components/block-list/index.native.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/block-editor/src/components/block-list/index.native.js b/packages/block-editor/src/components/block-list/index.native.js index 05c2898899ca39..b925a724809ecb 100644 --- a/packages/block-editor/src/components/block-list/index.native.js +++ b/packages/block-editor/src/components/block-list/index.native.js @@ -96,9 +96,6 @@ export class BlockList extends Component { ListHeaderComponent={ header } ListEmptyComponent={ this.renderDefaultBlockAppender } ListFooterComponent={ withFooter && this.renderBlockListFooter } - getItemLayout={ ( data, index ) => { - return { length: 0, offset: 0, index }; - } } /> { renderAppender && blockClientIds.length > 0 && From 9645d94b1fa02208231b5c3bfecd2aff4d03f4de Mon Sep 17 00:00:00 2001 From: Pinar Olguc Date: Tue, 29 Oct 2019 11:44:55 +0300 Subject: [PATCH 005/113] Fix: Media & Text Loses upload status if post is closed/reopened during the upload (#18137) * Prevent deleting mediaType on upload progress * Call onMediaUpdate instead of onSelectMedia * Dummy commit * Revert "Dummy commit" This reverts commit 5ce06d61f74af688b9d938c99e2d9fdad090a42c. * Limit requestMediaImport calls for only image type * Update comment --- .../src/media-text/media-container.native.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/block-library/src/media-text/media-container.native.js b/packages/block-library/src/media-text/media-container.native.js index d929f08d9f4c93..39ff78799b14f5 100644 --- a/packages/block-library/src/media-text/media-container.native.js +++ b/packages/block-library/src/media-text/media-container.native.js @@ -62,17 +62,14 @@ class MediaContainer extends Component { } componentDidMount() { - const { mediaId, mediaUrl, onSelectMedia } = this.props; + const { mediaId, mediaUrl, onMediaUpdate, mediaType } = this.props; if ( mediaId && mediaUrl && ! isURL( mediaUrl ) ) { - if ( mediaUrl.indexOf( 'file:' ) === 0 ) { - requestMediaImport( mediaUrl, ( id, url, type ) => { + if ( mediaUrl.indexOf( 'file:' ) === 0 && mediaType === MEDIA_TYPE_IMAGE ) { + // We don't want to call this for video because it is starting a media upload for the cover url + requestMediaImport( mediaUrl, ( id, url ) => { if ( url ) { - onSelectMedia( { - media_type: type, - id, - url, - } ); + onMediaUpdate( { id, url } ); } } ); } From 99584e41b097792d61370e9a0ac3c9ab52cf9bf4 Mon Sep 17 00:00:00 2001 From: etoledom Date: Tue, 29 Oct 2019 16:47:35 +0100 Subject: [PATCH 006/113] Dummy commit --- dumb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dumb diff --git a/dumb b/dumb new file mode 100644 index 00000000000000..e69de29bb2d1d6 From e3a6b96f5efcc25ee497beb68fbdafcb15390636 Mon Sep 17 00:00:00 2001 From: etoledom Date: Tue, 29 Oct 2019 16:48:11 +0100 Subject: [PATCH 007/113] Revert "Dummy commit" This reverts commit 99584e41b097792d61370e9a0ac3c9ab52cf9bf4. --- dumb | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 dumb diff --git a/dumb b/dumb deleted file mode 100644 index e69de29bb2d1d6..00000000000000 From f6b72f2977a8c9ab3e2a958da904c765863b17f8 Mon Sep 17 00:00:00 2001 From: Stefanos Togoulidis Date: Fri, 1 Nov 2019 17:47:27 +0200 Subject: [PATCH 008/113] [RNMobile] Native mobile release v1.16.0 (#18210) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adds correct escaping for urls (#17932) * Add an apiFetch middleware to automatically handle media upload failures (#17858) * Add an apiFetch middleware to automatically handle media upload failures * Remove the attachement on failures * Handle errors properly * limit the media upload middleware to the 500 responses * Fix the error handling and unit tests * Api Fetch: Check for 502s and parse uncaught errors in Media Upload middleware. * Fix: Gradient presets to verify some MU kses rules (#17940) * Bump plugin version to 6.7.0-rc.1 * Code Style: Change name of accumulated variables when using reduce function (#17893) * Fix issue-7378 - change name of accumulated variables when using reduce function * fix issue-7378 - update variables names * fix issue-7378 - update variables names * Fix:Image Block: Hide 'noreferrer' and 'noopener' in Link Rel (#17398) * Update the regex used when removing NEW_TAB_REL and add trimming (+2 squashed commits) Squashed commits: [cf71759c3] Accessibility:Image Block:Link Editor: Move Link Rel field below Open new tab toggle [310a23c33] Fix:Image Block:Link Editor: Hide 'noreferrer' and 'noopener' in Link Rel field * post rebases fixes Co-authored-by: Jorge Costa * Change Cover block min height input step size to 1 (#17927) * chore(release): publish - @wordpress/a11y@2.5.1 - @wordpress/annotations@1.7.2 - @wordpress/api-fetch@3.6.2 - @wordpress/autop@2.5.1 - @wordpress/babel-preset-default@4.6.2 - @wordpress/blob@2.5.1 - @wordpress/block-directory@1.0.2 - @wordpress/block-editor@3.2.2 - @wordpress/block-library@2.9.2 - @wordpress/block-serialization-default-parser@3.4.1 - @wordpress/block-serialization-spec-parser@3.3.1 - @wordpress/blocks@6.7.2 - @wordpress/components@8.3.2 - @wordpress/compose@3.7.2 - @wordpress/core-data@2.7.2 - @wordpress/data-controls@1.3.2 - @wordpress/data@4.9.2 - @wordpress/deprecated@2.6.1 - @wordpress/dom-ready@2.5.1 - @wordpress/dom@2.5.2 - @wordpress/e2e-test-utils@2.4.2 - @wordpress/e2e-tests@1.7.2 - @wordpress/edit-post@3.8.2 - @wordpress/edit-widgets@0.7.2 - @wordpress/editor@9.7.2 - @wordpress/element@2.8.2 - @wordpress/escape-html@1.5.1 - @wordpress/format-library@1.9.2 - @wordpress/is-shallow-equal@1.6.1 - @wordpress/keycodes@2.6.2 - @wordpress/list-reusable-blocks@1.8.2 - @wordpress/media-utils@1.2.2 - @wordpress/notices@1.8.2 - @wordpress/nux@3.7.2 - @wordpress/plugins@2.7.2 - @wordpress/priority-queue@1.3.1 - @wordpress/redux-routine@3.6.2 - @wordpress/rich-text@3.7.2 - @wordpress/scripts@5.1.0 - @wordpress/server-side-render@1.3.2 - @wordpress/url@2.8.1 - @wordpress/viewport@2.8.2 - @wordpress/wordcount@2.6.2 * Update changelogs after the npm release * Prevent prependHttp from failing if url is not defined (#17928) * Check that url is defined before passing into prependHttp * Shift check from component to url lib * List block: move default style (#17958) * Storybook: Add stories for Checkbox control component (#17891) * Add checkbox control stories for Storybook * Update README example to match story, useState * Apply suggestions from code review 👍 Co-Authored-By: Enrique Piqueras * Update story to match README * Add variants for heading, label, help * Update packages/components/src/checkbox-control/README.md Co-Authored-By: Grzegorz (Greg) Ziółkowski * Add Knobs addon to Storybook * Move storybook addon to dev-dependencies * Solve lint dependency by excluding stories, dont need in package.json * Apply suggestions from code review Co-Authored-By: Enrique Piqueras * Update with story level decorators * Switch back to global withKnobs, per story not working * Change the name of the example in ChecboxControl story * Try with the uppercase name of the component exported from stories * RNMobile Add size options to mobile image block (#17245) * [RNMobile] Native mobile release v1.11.0 (#17181) * [RNMobile] Fix crash when adding separator * Build: remove global install of latest npm since we want to use the paired node/npm version (#17134) * Build: remove global install of latest npm since we want to use the paired node/npm version * Also update travis to remove --latest-npm flag * [RNMobile] Try dark mode (iOS) (#17067) * Adding dark mode component implemented on list and list block * Adding DarkMode handling to RichText, ToolBar and SafeArea * Mobile: Using DarkMode as HOC * iOS DarkMode: Modified colors on block list and block container * iOS DarkMode: Improved Header Toolbar colors * iOS DarkMode: Removing background from buttons * iOS DarkMode warning and unsupported * iOS DarkMode: MediaPlaceholder * iOS DarkMode: BottomSheets * iOS DarkMode: Inserter * iOS DarkMode: DefaultBlockAppender * iOS DarkMode: PostTite * Update hardcoded colors with variables * iOS DarkMode: Fix bottom-sheet cell value color * iOS DarkMode: More - PageBreak - Add Block Here * iOS DarkMode: Better text color * iOS Darkmode: Code block * iOS DarkMode: HTML View * iOS DarkMode: Improve colors on SafeArea * Fix toolbar not avoiding keyboard regression * Fix native unit tests * Fix gutenberg-mobile unit tests * Adding RNDarkMode mocks * RNMobile: Fix crash when viewing HTML on iOS * [RNMobile] Remove toolbar from html view * [RNMobile] Fix MaxListenersExceededWarning caused by dark-mode event emitter (#17186) * Fix MaxListenersExceededWarning caused by dark-mode event emitter * Checking for setMaxListeners trying to avoid CI error * Adding remove listener to DarkMode HOC * DarkMode: Binding this.onModeChanged to `this` * DarkMode: Adding conditional needed to pass UI Tests on CI * Fix focus title on new posts regression (#17180) * BottomSheet: Setting DashIcon color directly when theme is default (light) (#17193) * Activate Travis CI on rnmobile/master branch (#17229) * Added ability to update image size options (sizeSlug) through a new InspectorControl Cell that leads to a Picker. * Added a style for Size Inspector Controls cell to align it will other cells that have icons. * Add native support for the MediaText block (#16305) * First working version of the MediaText component for native mobile * Fix adding a block to an innerblock list * Disable mediaText on production * MediaText native: improve editor visuals * Move BlockToolbar from BlockList to Layout * Remove BlockEditorProvider from BlockList and add native version of EditorProvider to Editor. Plus support InsertionPoint and BlockListAppender * Update BlockMover for native to hide if locked or if it's the only block * Make the vertical align button work, add more styling options for toolbar buttons * Make sure registerCoreBlocks does not break in production * Copy docblock comment from the web version for registerCoreBlocks * Fix focusing on the media placeholder * Only support adding image for now * Update usage of MediaPlaceholder in MediaContainer * Enable autoScroll for just the out most block list * Fix JS Unit tests * Roll back to IconButton refactor and fix tests * Fix BlockVerticalAlignmentToolbar buttons style on mobile * Fix thing for web and ensure ariaPressed is always passed down * Use AriaPressed directly to style SVG on mobile * Update snapshots * Swtiched to react-native Modal onDismiss property for signaling Picker is ready to show * Added a prop for catching modal dismissal on Android. (onDismiss is iOS only and onModalHide works on Android but breaks on iOS) * Added icon for Inspector Controls size option. Removed style we no longer need. * Added title to size option iOS ActionSheet and left alignstyle to size options BottomSheet * MediaUpload and MediaPlaceholder unify props (#17145) * Unify media placeholder and upload props within media-text (#17268) * [RNMobile] Fix dismiss keyboard button for the post title (#17260) * Set unused functions to undefined instead of false in BottomSheet Modal props * Recover border colors (#17269) * [RNMobile] Insure tapping at end of post inserts at end Previously, tapping at the end of the post would insert a block immediately after the currently selected block. In addition, this commit is cleaning out a few unusued props in the block-list file. * Support group block on mobile (#17251) * First working version of the MediaText component for native mobile * Fix adding a block to an innerblock list * Disable mediaText on production * MediaText native: improve editor visuals * Move BlockToolbar from BlockList to Layout * Remove BlockEditorProvider from BlockList and add native version of EditorProvider to Editor. Plus support InsertionPoint and BlockListAppender * Update BlockMover for native to hide if locked or if it's the only block * Make the vertical align button work, add more styling options for toolbar buttons * Make sure registerCoreBlocks does not break in production * Copy docblock comment from the web version for registerCoreBlocks * Fix focusing on the media placeholder * Only support adding image for now * Update usage of MediaPlaceholder in MediaContainer * Enable autoScroll for just the out most block list * Fix JS Unit tests * Roll back to IconButton refactor and fix tests * Fix BlockVerticalAlignmentToolbar buttons style on mobile * Fix thing for web and ensure ariaPressed is always passed down * Use AriaPressed directly to style SVG on mobile * Update snapshots * Support group block on mobile * Extend shouldShowInsertionPoint condition to be false when group is selected * Code refactor * Update package-lock * Removing old style reference. * Moved Picker for image size options into new ImageSizePicker component. Cleaned up sizeOptionLabels. * Updated total left margin on Android Image size options to be 24 px instead of 28 px * Image Size options hidden behind __DEV__ flag * Remove redundant bg color within button appender (#17325) * [RNMobile] DarkMode improvements (#17309) * Remove the need to import `useStyle` and pass the theme prop on every instance that `withStyle` is used * Implement dark-mode refactor on all components * Fix broken native tests * Fix default block appender background color on DarkMode * DarkMode: Make `useStyle` a class function * Cleaned up default true properties and replaced code with lodash map. * Updated to use BottomSheetPickerCell. Eliminated code, but size options now open over top inspector controls menu. * Added leftalign to PickerCell. * [RNMobile] Add autosave to mobile apps (#17329) * [RNMobile] Fix crash when adding separator * Build: remove global install of latest npm since we want to use the paired node/npm version (#17134) * Build: remove global install of latest npm since we want to use the paired node/npm version * Also update travis to remove --latest-npm flag * [RNMobile] Try dark mode (iOS) (#17067) * Adding dark mode component implemented on list and list block * Adding DarkMode handling to RichText, ToolBar and SafeArea * Mobile: Using DarkMode as HOC * iOS DarkMode: Modified colors on block list and block container * iOS DarkMode: Improved Header Toolbar colors * iOS DarkMode: Removing background from buttons * iOS DarkMode warning and unsupported * iOS DarkMode: MediaPlaceholder * iOS DarkMode: BottomSheets * iOS DarkMode: Inserter * iOS DarkMode: DefaultBlockAppender * iOS DarkMode: PostTite * Update hardcoded colors with variables * iOS DarkMode: Fix bottom-sheet cell value color * iOS DarkMode: More - PageBreak - Add Block Here * iOS DarkMode: Better text color * iOS Darkmode: Code block * iOS DarkMode: HTML View * iOS DarkMode: Improve colors on SafeArea * Fix toolbar not avoiding keyboard regression * Fix native unit tests * Fix gutenberg-mobile unit tests * Adding RNDarkMode mocks * RNMobile: Fix crash when viewing HTML on iOS * [RNMobile] Remove toolbar from html view * [RNMobile] Fix MaxListenersExceededWarning caused by dark-mode event emitter (#17186) * Fix MaxListenersExceededWarning caused by dark-mode event emitter * Checking for setMaxListeners trying to avoid CI error * Adding remove listener to DarkMode HOC * DarkMode: Binding this.onModeChanged to `this` * DarkMode: Adding conditional needed to pass UI Tests on CI * Fix focus title on new posts regression (#17180) * BottomSheet: Setting DashIcon color directly when theme is default (light) (#17193) * Add a preliminary version of the AutosaveMonitor for mobile that calls the "bridge" and asks the native side to save the content * Add autosave mock function for tests * Fix merge conflicts * Fix lint * Re-add autosave on mobile that was removed erroneously during import-merge from rnmobile/master * Remove native variant of AutosaveMonitor and introduces changes at editor store level * Default to false for `isEditedPostAutosaveable` on mobile. There was a typo in the returing value on the previous commit. * Make sure to consider edits to the Title when checking if auto-save is needed * Fix lint * Add isAppender functionality on mobile (#17195) * Add isAppender functionality on mobile * refactor isAppender conditions * Replace dropZoneUIOnly in favour of showMediaSelectionUI * deprecate dropZoneUIOnly and add disableMediaSelection prop * Update test * Refactor tests and change prop name * Remove redundant empty lines * Refactor conditions inside MediaPlaceholder * Update block-editor CHANGELOG * Update packages/block-editor/CHANGELOG.md Co-Authored-By: Grzegorz (Greg) Ziółkowski * Autosave monitor - Make the mobile editor ping the native at each keystroke, since the deboucing logic is already well defined in the apps. (#17548) * [RNMobile] Refactor Dark Mode HOC (#17552) * [RNMobile] Refactor the Dark Mode HOC to fix naming antipatterns * Fix lint errors * Add .native.js suffix to usePreferredColorScheme * Update usage of theme props renamed to preferredColorScheme * Update usage of theme props renamed to preferredColorScheme * Add missing heading levels to the UI (H4, H5, H6) (#17533) * Fix lint issue (#17598) * Fix list filter on paste for RN mobile. (#17550) * Fix method for RN mobile. * Use array.From instead of slice. * Remove comment and use Array.from directly * Convert from NodeList spreadable to Array.from * Fix lint errors. * Fix documentation examples to use Array.from * Add empty line. * [RNMobile] Move MediaUploadPorgress to its own component folder (#17392) * Move MediaUploadPorgress to its own component folder (native) * MediaUploadProgress - Fix import to code standards * MediaUploadProgress readme * Mobile - MediaUploadProgress README update * Rnmobile/fix link editing on start (#17631) * Don't try to clear links if text is clean. * Commented LinkUI removal test when no URL. * Don't try to remove link if we are at start of link and no actual selection is * Re-implementing https://github.com/WordPress/gutenberg/pull/17802, affected by merge. Fixed extra space and unused code. * Fixing lint error, trailing space. * Improve columns flex rule, round 2. (#17968) * Bump plugin version to 6.7.0 * Small changes to Git Workflow docs (#17662) * :information_desk_person: add 'upstream' remote * :bug: origin / remote * Codeowners: Remove gziolo from some folders (#17971) I get too many notifications. * Fix: Invalid import statement for deprecated in the modal component (#17969) * Fix: Invalid import statement for deprecated in the modal component * Font Size Picker: Update E2E test to work with new Core changes. * Add empty line (#17981) * Try setting a block display name for the Block Navigator. (#17519) * Really simple first attempt at showing a display name in the navigator * Strip any RichText formatting * Add display name for navigation menu item block * Refactor to use displayNameAttribute property * Change name of displayName options * [RNMobile] add RangeControl mobile implementation (slider) (#17282) * add RangeCell * Split e2e tests into multiple folders (#17990) * Playground: Add link to components storybook. (#17982) * Fix image native test (#17989) * Update: Refactor button edit to use a functional component (#18006) * Optimize exports of the wp/compose package (#17945) Adds `sideEffects:false` to `package.json` so that unused exports can be optimized away by the bundler. Moves the `compose` definition (i.e., reexport from Lodash) to its own module, so that we don't pull in Lodash just by importing something from `@wordpress/compose`. After this patch, one needs to import `compose` explicitly to trigger the Lodash import. * [RNMobile] Introduce grouping in the block settings inspector (#17703) * Intrdouce groupin in the block settings inspector * Adjust PanelBody to design * Adjust padding when section doesnt have title * Rewirte arrow function to function * Fix lint issue * Create a PanelActions component for handling action buttons in the block settings inspector * Remove useless separator type and fix typo * Refactor after CR * Correct label styles * Fix overriding mechanism on label style * Fix the performance tests (#18020) * Storybook: Add knobs to ColorIndicator (#18015) * Add knobs to ColorIndicator * Lint: new line * Add dashicon component to storybook (#18027) * Fix Publish Button!!! (#18016) Fixes #18004 and thank science, that was driving me insane ever since you pointed it out. This PR does a couple of things: 1. It adds `isLarge` to the Publish button. It was there for Preview, but not Publish. 2. It simplifies a little CSS as a result of that. 3. It also tweaks the button height as defined for the two preview publish buttons. * Update MediaPlaceholder README.md (#17980) * Update MediaPlaceholder README.md This change updates the readme to properly document the `value` property. See issue here: https://github.com/WordPress/gutenberg/issues/17967 * Update MediaUpload README.md * removes decleration of Select button (#18007) * Fix MediaUpload README value prop description (#18039) * Tests: Clean up skipped e2e tests (#18003) * chore(release): publish - @wordpress/api-fetch@3.6.3 - @wordpress/block-directory@1.0.3 - @wordpress/block-editor@3.2.3 - @wordpress/block-library@2.9.3 - @wordpress/core-data@2.7.3 - @wordpress/data-controls@1.3.3 - @wordpress/e2e-test-utils@2.4.3 - @wordpress/e2e-tests@1.7.3 - @wordpress/edit-post@3.8.3 - @wordpress/edit-widgets@0.7.3 - @wordpress/editor@9.7.3 - @wordpress/format-library@1.9.3 - @wordpress/list-reusable-blocks@1.8.3 - @wordpress/media-utils@1.2.3 - @wordpress/server-side-render@1.3.3 - @wordpress/url@2.8.2 * Chore: Fix issues related to Node 12 becoming LTS (#18054) * Chore: Fix issues related to Node 12 becoming LTS * Include the root package.json file in the linting This commit also moves the npm-package-json-lint config to the standalone file. * Add changelog entries to @wordpress/scripts package * Fix issue when providing multiple shortcode aliases for a new block (#17925) * Fix issue where providing multiple shortcode aliases to transform into a block only matches the first shortcode * Add test to ensure blocks can transform using multiple shortcode aliases * Simplify the approach used to find the individual shortcode being transformed Props jg314 * Chore: Update the lock file to use newer version of fsevents (#18057) This fixes the issues when `npm install` on macOS throws several errors. * Env: Add support for custom ports. (#17697) * Add isInvalidDate prop to DatePicker (#17498) * navigation-menu: Implement colors selector button. (#17832) Summary block-editor: expose ColorPaletteControl component navigation-menu: improve colors-selector component navigation-menu: compose withColors navigation-menu: render colors selector in bar navigation-menu: propagate withColor props navigation-menu: apply theme styles to selection navigation-item: populate styles to nav item navigation-menu: apply inline styles and CSS classes * Update design-systems:dev script to build packages (#18073) The build-style/style.css needs to be rebuilt prior to running Storybook in watch mode. This change adds `npm run build:packages` at the start of the design-systems:dev script to CSS is built prior. Issue found in #17997 * Add `@wordpress/base-styles` package (#17883) - Move `assets/stylesheets/*` to the new package - Move admin color schemes to the new package * Add Site Title block and required functionality. (#17207) * Core Data: Add a Site entity and a hook for entity saving logic. * Experiments: Add a Full Site Editing experiment. * Block Library: Add Site Title block. * Fixtures: Add Site Title block fixture. * Fixtures: Add missing transform fixtures. * Block Library: Remove deprecated prop usage in Site Title. * Site Title: Support nesting inside of a Site block. * Site Title: Disallow formatting in the rich text field. * Core Data: Make useEntitySaving experimental. * Table: remove wrapper around cells (#17711) * Implement core template loader overrides to rely on wp_template posts (#17626) * Introduce wp_template post type. * Improve (temporary) admin UI for wp_template post type by exposing slug. * Implement template loader overrides to rely on 'wp_template' posts. * Render viewport meta tag. * Prevent deletion of fallback 'wp_template' post 'index'. * Scope PR to just basic wp_template post type registration. * Implement core template loader overrides to rely on wp_template posts instead. * Render title tag regardless of theme support Co-Authored-By: Weston Ruter * Make getting correct wp_template post more error-proof Co-Authored-By: Weston Ruter * Template Loader: Add more content filters. * Templates: Fix experiment flag logic. * Add logic for basic (temporary) wp_template editing UI (#17625) * Templates: Add logic for basic temporary editing UI. * Templates: Fix menu filter. * Post Slug: Follow class name convention. * url-input: ensuring value is defined on key down (#18088) * Code style: Fix ESLint warnings reported for JSDoc definitions (#18025) * Code style: Fix ESLint warnings reported for JSDoc definitions * Add WordPress type definitions to the list of names recognized by JSDoc linter * Local autosave: Clear after successful save (#18051) * Local autosave: Clear after successful save Presumably, somewhere in the fixing of conflicts between remote and local autosaves (purge local upon successful remote autosave), LocalAutosaveMonitor stopped purging the local autosave upon successful *saves*. * Tests: Autosave: Correctly wait for editor chrome before saving * Chore: Fix: Do not show Gradient panel if gradients are not av… (#18091) * Fix regression with Gallery margin. (#18019) I failed to verify the Gallery block when I approved https://github.com/WordPress/gutenberg/pull/17958#issuecomment-543597183 and therefore caused a regression. This PR adds explicity left margins and paddings to the gallery ul to ensure there isn't any added padding and margin. * Add platform component (#18058) * Add platform component * Improve platform implementation in RN. * Add more documentation and tests. * Update readme file. * Update tests. * Fix filenames for native versions. * Add license attribution * Remove unnecessary lines. * Improve documentation * Remove trailing space * Update packages/element/src/platform.js Co-Authored-By: Grzegorz (Greg) Ziółkowski * Update readme. * Fix lint error. * Fix: End to end tests do not disable the experiments (#18093) * Fix: Custom button background color not reflected on reload (#18037) Fixes: https://github.com/WordPress/gutenberg/issues/18012 We had a bug where the editor may not reflect the custom button background color after a reload. That happened because the rule background: customGradient, may overwrite the background-color rule even if the custom gradient has not set. This PR performs a logic update to solve the issue. * List Block: Do not merge list with previous block if deleting first list item and list is not empty (#18032) * Do not merge list with previous block if deleting first list item and list is not empty * Add e2e test and clean up * Correct mistake * Adjust comment * Add gradients in cover block (#18001) * Components: Add VisuallyHidden component (#18022) * Add ScreenReaderText component * Add new component readme to manifest * Remove CSS style loading within stories * Switch component name to VisuallyHidden - Rename directory and includes - Update README usage - Update Storybook usage * Switch classname to components-visually-hidden * Lint: newline * Add focus style * Switch to 'as' for specifying tag * Move renderAsRenderProps to utils.js * Move utils to inside component folder Waiting to refine the utils usage a little better before making it look available for other components to use. * Apply suggestions from code review Co-Authored-By: Grzegorz (Greg) Ziółkowski * Lint: Move newline * Fix variable name * Use variable for stylesheet * Storybook: Apply a set of enhancements to the existing stories (#18030) * Storybook: Apply a set of enhancements to the existing stories * Add basic knobs integration to all Button stories * Env: Add support for running in themes. (#17732) * Env: Add support for running in themes. * Env: Optimize context detection filter. * Env: Update test directory structure to match convention. * Storybook: Add Color Palette Component (#17997) * Add Color Palette to Storybook * Apply suggestions from code review Co-Authored-By: Enrique Piqueras * Refactor state out of story components, to own * Update packages/components/src/color-palette/stories/index.js * Preserve attributes on split (#18102) * [rnmobile] Breadcrumbs (#17471) * Add breadcrumbs to floating toolbar * Add dark mode support * Add a block selection breadcrumb to the bottom of the editor (#17838) * RNMobile: Add image alignment controls (#17962) RNMobile: Add image alignment controls Only handles left, center, right. Does not permit setting or displaying either full or wide alignments. * Fix checkboxes for postmeta. (#18108) * Add block inspector to the Gutenberg playground. (#18077) * Block Editor: Implement new colors hook. (#16781) * Block Editor: Implement new colors hook. * Block Library: Swap usage of the colors HOC with the colors hook in the heading edit component. * Use Colors: Add 'has-x-color' class names. * Use Colors: Avoid memory leaks by making caches limited in size, and tied to hook instances. * Use Colors: Support children and optional contrast checking in the color panel. * Use Colors: Expose colors panel without inspector slot/fill wrapper. * Use Colors: Mark hook as experimental. * Use Colors: Support custom colors. * Block Edit: Remove extra context values and use selectors/actions instead. * Heading: Remove unnecessary color class and set text color on save. * Use Colors: Add custom/preset color logic. * Use Colors: Fix panel bugs. * Heading Block: Detect actual background color for contrast checking. * Block Edit: Add new export to native file. * Use Colors: Change CSS "attribute" to "property". * Fix: Font size picker component relies on WordPress styles (#18078) * Nav menu item enhancements: display toolbar and remove dropdown (#17986) * Display toolbar and remove dropdown from menu item * Fixes block toolbar misalignment on IE. * Replace destination and deal with keypresses. * Update fixture. * Keydown management and attempt at close on blur. * Add definitive menu item icon. * Fix label/input styling. * Clean up styles after rebase. * Refactor stop propagation . * Remove duplicate dependency comments * Navigation Block: Rename 'destination' to 'url' in server-side code * Fix overlapping controls in the Inline Image formatting toolbar (#18090) * Fix overlapping controls in the Inline Image formatting toolbar * Inline mage formatting: make Apply button same height as Width input * Polish. * Raw handling: Fix strikethrough formatting when copy/pasting from Google Docs in Safari (#17187) * Tutorial: Specify block naming restrictions (#18117) * Tutorial: Specify block naming restrictions * Remove an incorrect comma * Components: ExternalLink, add story (#18084) This update adds a story for the ExternalLink component. Storybook knobs were added to better demonstrate the component's properties. * Storybook: Add ColorPicker component (#18013) * Add color picker component to Storybook * Switch screen-reader-text to new VisuallyHidden * Update ColorPicker tests snapshots * Add story for showing Alpha Channel * Move state out of exported component * Lowercase story name * Add class mechanism for preset gradients. (#18008) * Allow media upload post processing for all 5xx responses (#18106) * Allow travis builds in all wp/* branches * Add `DimensionControl` component (#16791) * Adds initial component Note this is copied wholescale from original PR https://github.com/WordPress/gutenberg/pull/16730 * Remove redunant files. Refactors tests. * Updates docs * Checks callbacks are functions prior to calling * Adds temp testing example usage of component to Group Block * Updates to allow sizes as an (optionaly) prop dependency * Update default value label * Removes unnecessary InstanceId HOC usage Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r323906696 * Remove unused abbreviation in size table * Revert "Adds temp testing example usage of component to Group Block" This reverts commit 6f9f3bfd2a7c1a08ecfab143384d414701f0c1e8. * Remove arbitrary size value from sizes list This is not required as we cannot know how the dimensions component will be used. Therefore sticking with relative values via the slugs is safer. These can be mapped on a case by case basis as required. * Remove icon label for a11y reasons Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r324103481 * Update component docs for consistency, spelling and grammar * Tweak docblock formats * Update test snapshots to match new default value * Update API from onSpacingChange to more agnostic onChange Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r331622801 * Update tests to cover onChange handler renamed * Update currentSize prop to value for consistency with other components * Removes onReset in favour of onChange with undefined for consistency Adddresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r331624272 * Move component to @wordpress/components package * Remove invalid font sizes style import Accidentally included from rebase. * Deps update due to rebase * Remove unneeded doc blocks * Remove usage suggestion which was not helpful * Update readme docs to match current API Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r332692714 * Export as experimental component Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r332694561 * Revert "Deps update due to rebase" This reverts commit 95d00f39010edfaac620980e0d0e7c1001a68c98. Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r332691520 * Paste: allow list attributes (#17144) * Add grandient fixtures to cover block (#18002) * Bump plugin version to 6.8.0-rc.1 * Fix RN build after merge with master (#18133) * Commander: switch cloning method to HTTPS (#18136) * Commander: switch cloning method to HTTPS * Add HOME env variable * Add horizontal option for the block movers (#16615) * horizontal option for the mover, missing icons, broken hover * we now have icons * positioned the mover to the middle left * horizontal mover on mobile * vertical layout for horizontal movers * drop block movers into block edit to enable inline movers * implemented so as to not be a concern for the block implementer * removes useless scss variable * hiding the drag handle at block level * renamed horizontalMover to moverOptions to incorporate separation of properties * rafactores the mover options * Initial CSS work to make the menu more manageable. This moves to flex instead of grid, neutralizes margins, simplifies a few things. * Make movers inline again. * Further improve margins for child blocks. * adds proper aliases in BlockEdit * previxed options as experimental * RTL movers * removed the position option, marked option experimental * labeled as experimental new mober and block list props * refactored direction detection code for better readability, fixed some code alignment issues * Update ExternalLink Component to fix visually hidden text (#18142) * Switch screen-reader-txt to VisuallyHidden component * Fix core embed test snapshot, new classname * Add Spinner component to storybook (#18145) * Smart block appender (#16708) * if thre is only one there is only one * made a new insertion point selector, some code review refactoring * better handling of inserter * refactoring and named block insertion * updates to the appender * update snapshots * update docs * default inserter label is used in so many tests * fixed allowed blocks test * snapshot updated * better naming and removed the need for es-lint disabling * improved the inserter label construction * improved the doc of getTheOnlyAllowedItem selector * reverting test patches becasue patching without understanding is bad, bad, bad - don't do it * moved getInsertionIndex out of selectos and back into each component that used it * docs generated * added experimental labels to new selectors, added es-lint comment back * updated docs * Update packages/block-editor/src/store/selectors.js Co-Authored-By: Miguel Fonseca * Update packages/block-editor/src/store/selectors.js Co-Authored-By: Miguel Fonseca * refactored and fixed some coding errors * small code move * small code move * removes aria attrs for autoinserted items * fixes typo, adds translators comment * simplifies the intserter logic * fix for the simplification * simplifies by using one selector and passing props in compose * small code updates * lint * renamed insertedBlock * small doc update * adds tooltip to the default button appender * refactores for more self documenting varnames * Components: Draggable, add story (#18070) * Components: Add Story for Draggable This update adds a Storybook example for the Draggable component from `@wordpress/components`. * Fix useState hook for Draggable story example Solution was to create an Example component with the useState hook. Render that Example component in the story instead. * Block Directory: Convert it to UI Plugin to avoid bundling into Core (#17576) * Block Directory: Convert it to UI Plugin to avoid bundling into Core * Load the block directory assets only when the experiment is enabled * Try to reimplement asset overrides to give more flexibility * Add code style improvemements and perform code cleanup * Try to make PHP unit tests pass by removing group check * Ensure that packages and vendor scripts are printed in the footer * Fix the has action check for the block directory assets * Move gutenberg-block-directory experiment check out of the action * Fix bin/get-vendor-scripts.php * Make the AsyncModeProvider API a stable API (#18154) * Make the mediaUpload block editor setting a stable API (#18156) * Fix columns full-wide regression. (#18021) The Columns block, when full-wide, has intentional left and right padding to ensure the mover controls of child blocks are accessible. This is editor-only, and only when the block is selected. This regressed at some point, a while ago, probably around the introduction of extra on-click padding to show the dashed outlines of child elements. This PR shuffles the rules a bit, reduces some of their specificity, and applies the left and right padding elsewhere to make it work. * Resyncs RichText mobile components with web counterparts. (#17897) * Resyncs RichText mobile components with web counterparts. * Remove outdated test. * Remove unused references. * Add platform component * Add components depending of platform. Only add specific components if we are on the web implementation. * Abstract paste of files for RN and web Makes the code for pasting image more abstract in the paste method and implement specific translation to HTML depending of the platform. * Compose extra attributes/props on select/dispatch only if mobile. * Remove RN index file for RichText Wrapper. Moved all the specific code to the standard index file, so this file is no longer needed. * Remove API index native file that is no longer needed. * Clean up lint errors in file-paste-handler. * Fix lint errors. * Implement stub remove browser shortcuts for RN * Implement autocomplete stub for RN. * Refactor toolbar presentation to a method. * Remove no longer needed platform file. * Consolidate the file paste handler in a single implementation. Created a stub for createBlobURL for native that simple returns the original URL. * Change the text for platform to make it explicit it's native only. * Remove duplicate files * Include type in file comparison * Forgot to rename for native file * Fix filePasteHandler for native * Move logging back * Restore comment on logging * Add check for files existence. * Refactor format-toolbar code to use split web/native files * Remove prop duplication. * Fix getAnchorRect call * Remove unnecessary const * Sync fix for list removal of first empty line * Fix RN build after merge with master * Sync with web counterpart. * Only change selection after new formats are set. * [RNMobile] Add a subtitle for unsupported blocks (#18107) * Add a new unsupported subtitle to missing blocks - even we know about the block title * Update margins, colors and font weight of the unsupported block * Navigation: Explore default frontend styles (#18094) * try basic version of varia theme styles as default * Add class to show submenu indicator * adjustments for small viewports * NavigationMenu: set attributes rightly (#18150) * navigation-menu: set attributes once * navigation-menu: add CSS class as hook dependencies * Update packages/block-library/src/navigation-menu/edit.js Co-Authored-By: Enrique Piqueras * Update packages/block-editor/src/components/colors/use-colors.js (#18147) Co-Authored-By: Enrique Piqueras (+2 squashed commits) Squashed commits: [36484b4d3f] Update packages/block-editor/src/components/colors/use-colors.js Co-Authored-By: Enrique Piqueras [9c4c7694bd] Fix: solve some issues in useColors hook * [RNMobile] Added support for giphy and pexels images (#18026) * Scripts: Bump the version of npm-package-json-lint (#18160) * Experimental Link creation interface (#17846) * Initial component file structure * Implement basic icon and toggle mechanic * Adds basic search input * Update input to utilise LinkEditor component autocomplete * Add ability to customise placeholder * Update to utilise URLInput directly for greater flexibility * Add example search results and test coverage * Update class naming convention to match guidelines See https://github.com/WordPress/gutenberg/blob/master/docs/contributors/coding-guidelines.md#css Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r332567521 * Adds render prop to enable custom suggestions rendering Previously it wasn’t possible to customise the render of the search suggestions. By providing an optional render prop we now have full control over this if required. * Update to utilise URLInput render prop to customise search suggestions render Previously we relied on our own render of suggestions but this wasn’t hooked up to all the accessibility enhancements afforded by URLInput. By utilising the render prop exposed by URLInput to customise the rendering of suggestions, we can have the best of both worlds. * Update to add post type to the fetchLinkSuggestions responsive mapping This is required to display the type of entitity in the search results for LinkControl * Fix to ensure search suggestion interaction states are perceivable * Update suggestion render prop to provide component props as arguments Previously when using the `renderSuggestions` render prop the user had to know how to put together the correct props on the correct elements in their custom render. By passing the default props for the listing element and the item element we can relieve the user of this burden by allowing them to spread the props onto the appropriate elements in their render without having to know how they are created. * Update to match with design visual and provide more accessible markup * Adds settings area. Fixes missing reset icon. * Fix search items to be buttons with correct style and layout * Adds overflow scrolling to search results * Fix to stop scroll shadow overlaying scrollbars * Add bespoke settings area and tweak styles * Update to allow URLs to be conditionally handled as a suggestion Previously when a URL was entered it was deemed that no suggestions should or could be found and so the process of fetching suggestions was short circuited. Add additional prop to optionally allow developers to have URL-like values handled as suggestions. * Updates to conditionally use an entity or url based search results fetcher If the current value of the input is a URL then we conditionally pass a different handler for search results to the URLInput component. For URL based values we immediately return a “suggestion” object with values matching those entered by the user. Non URL based values are handled as previously. * Fix bug whereby fetchSearchSuggestions wasn’t called Remove ambiguity by calling the search handler directly rather than proxying through another function and having to apply it immediately. * Remove default toggle UI and implement Popover close The LinkControl will be mostly where another element triggers the UI to appear. As a result we don’t want to force a toggle element on the developer. Rather we will expose an API to allow the consuming component to toggle the visibility of the LinkControl * Adds search text “highlighting” in results list * Move TextHighlight component to its own file * Fix bug where update to value prop didn’t cause suggestions to reset. * Update to remove internal handling of open/closed state This state is now expected to be handled by the consuming component chosing whether or not to render the component. It has no concept of open or closed. * Fix React violation by returning only the text for non matches * Update existing tests to match new implementation * Add link reset test * Adds test which uncovers major bug in the implementation Basically this test has revealed that due to the way we’re detecting and handling URL-like values the wrong data fetcher function gets passed to the URLInput component for the first input `change` event. For example if you paste `https://make.wordpress.com` directly into the input then it is determined to be a URL but because the current fetcher function for the current render is still the handler that deals with entity searches the correct results are not displayed. Adding another character to trigger a re-render will cause the UI to update to the expected state, but this is a major bug. * Tweak critical test to be more explicit about what is expected * Fix bug to make determining search handler use the latest input value Previously we relied on parent component state to choose which search handler to use for the current input term. However, the state was always 1 tick behind so the previous search handler got used. Updating this to use the real time value of the input passed onChange ensures we select the correct search fetcher when the component re-renders. * Add loading spinner and associated test coverage Spinner was technically always rendered but it wasn’t visible due to CSS styling. Fix and also cover with tests. * Fix bug where value could be empty * Adds basic editing / view state switching * Add keydown callback to URLInput * Select link on ENTER keydown event * Utilise LinkViewer to render edit state and decode urls for display * Only display link settings when a link is selected * Adds current link view styles * Makes settings toggle controlled by parent component * Update visuals to match updated design Addresses https://github.com/WordPress/gutenberg/issues/17557#issuecomment-542401433 * Add standardised min width to popover * Temporary hack to include Link UI in Playground for testing * Update to utilise isURL util from @wordpress/url package * Update to utilise isURL util from @wordpress/url package * Removes URLPopover dependency Attempts to remove unwanted deps on other components. We now utilise Popover directly and suffer no consequences as we are not making use of any bespoke features provided by URLPopover. * Extract settings drawer to sub component * Refactor search items into a component * Refactor Input and Search to component * Fix missing selected state on search suggestions * Tweak line height on search suggestion url path * Augment test for URL-like by testing for “www.” * Fix to stop url overflows and wrapping on to multiple lines * Uppcase URL in type indicator within search results list * Avoid reading out slug/URL for entity results * Ensures i18n of change button * Always offer URL result in search suggestions as default * Fix loading spinner position and dim results during loading Addresses https://github.com/WordPress/gutenberg/pull/17846#issuecomment-543244810 * Fix scroll shadows to use valid alpha transparent values in gradient Fixes broken shadows in Safari which didn’t recognise transparent as a value to transition to in a gradient. * Adds instructional text in place of URL for suggestions that are URLs Addresses designer feedback https://github.com/WordPress/gutenberg/issues/17557#issuecomment-545030027 * Update prop names for consistency Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337840953 * Update line length to improve readability Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337842799 * Update to avoid need to utilise partialRight util from lodash Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337882576 * Updates key to avoid usage of index We cannot assume the suggestion `id` will be unique. This is because at the moment the search results are `Post`s. However in the future we may also need to include `Category` terms and the term IDs could easily clash with the Post IDs as they are in different DB tables. Using the `type` to differentiate the key. Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337883174 * Update to remote isFunction check in favour of direct check Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337885206 * Update to handle mailto and tel protocols and internal links * url-input: handle onKeyPress type event * link-control: add className prop * link-control: add README file * Remove unnecessary use of useCallback Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r338363236 * Fix current automated tests * Improves URL handling test to run for multiple URL value variations * Updates to display the URL type in the search results Previously only true `http` URLs were formatted with the correct type and the instructional text. Fixes so that all types of manual URL entry are correctly shown as such in the search results. Adds test to cover mailto variant of this. * Refactor tests to assert against all valid protocol formats and link variants This now includes tel, mailto and internal links. * Adds test to cover display of fallback URL search result for search values that are potentially URLS * Adds tests to check URL suggestions don’t display for non-URLs. * url-input: remove unneeded `suggestion` const * url-input: always trigger onKeyDown event * link-control: delegate handling keydown event Instead of this, let's propagate the onKeyDown and onKeyPress events to the parent component * link-control: add onKeyDown and onKeyPress handlers * link-control: playground -> close once onClose * link-control: propagate onClose() event * link-control: playground -> hanldling close by ESCAPE key * Fix to only render settings draw if settings are defined * Remove redundant commented out test * Update to render with a “current link” if one is provided. Previously if you passed in a current link the component would still render with a search box as thought nothing was selected. Updates so that if `currentLink` is provided the UI reflects that by showing the “selected” item and no search input. * Render playground with currentLink active * Adds test to cover currentLink prop * Remove selected state from Playground * Adds tests to cover selecting and changing links * Remove async function in place of direct Promise usage and add test coverage * Add test to cover keyboard handling Note: this uncovered a bug whereby keyboard handling of “selecting” the link you want to use is broken. This needs to be fixed. * Remove unecessary dep from effect * Fix URLInput to pass the actual suggestion object not the index If the full object is not provided then consuming components have no way of accessing the details of the selected suggestion thereby rendering it useless. * Fix keyboard handling so hitting `ENTER` will select an item as the current link Builds on previous commit. * Updates keyboard interaction test to include URL entry * Minor: reword test description * Fix missing key prop regression Previously `buildSuggestionItemProps` was including a key. However the implementation of `LinkControl` changed so that this was not required. However we forgot to reinstate on `URLInput`. This update ensures a key prop is set on the default output. Note that disabling of the autofocus linting was already in place: https://github.com/WordPress/gutenberg/blob/04e142e9cbd06a45c4ea297ec573d389955c13be/packages/block-editor/src/components/url-input/index.js#L239 Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337841961 * DRY up conditionals Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337842477 * link-control: set a default experimental link suggestions searcher if it't needed * link-control: handling key events * url-input: remove onKeyDown prop * url-input: remove calling onKeyDown prop * url-input: rollback some changes * Mark Link Creation Interface as Experimental (#18110) * mark main component as experimental * mark new URLInput props as experimental * add experimental onKeyPress * remove key handlers * Updates to use alias on experimental props Addresses https://github.com/WordPress/gutenberg/pull/18110#discussion_r339427180 * Remove unused prop from docs * Update props ordering and readme docs Also fixes eslint errors that kept me from committing the original changes * Revert playground changes * Rename InputSearch to SearchInput Props @talldan I really hope those changes I had to make in `search-input.js` don't break anything. * Remove disabling of jsx-key lint rule * Change fake id value to something that will not clash with post ids * [RNMobile] Hotfix 1.15.2 (#18128) * Force block inserter to re-render on device rotation (#18101) * Force block inserter to re-render on device rotation * Dummy * Revert "Dummy" This reverts commit 037f076679cb8f89a65ecafdd9130465a0fc03d9. * Add left right borders to inner blocks (#18109) * [Mobile]Remove alignment options from Media & Text until they are fixed (#18112) * Remove alignment options temporarily * Dummy commit * Fix: remove getItemLayout which causes scroll position issue (#18060) * Fix: Media & Text Loses upload status if post is closed/reopened during the upload (#18137) * Prevent deleting mediaType on upload progress * Call onMediaUpdate instead of onSelectMedia * Dummy commit * Revert "Dummy commit" This reverts commit 5ce06d61f74af688b9d938c99e2d9fdad090a42c. * Limit requestMediaImport calls for only image type * Update comment * Dummy commit * Revert "Dummy commit" This reverts commit 99584e41b097792d61370e9a0ac3c9ab52cf9bf4. * Fix handling of pasted images and prevent thumbnail uploads (#18215) * Fix handling of pasted images and prevent thumbnail uploads * Fix lint errors * Remove check for image for sync. * Include the RN mobile releases branch in Travis branches --- .eslintrc.js | 2 +- .github/CODEOWNERS | 8 +- .npmpackagejsonlintrc.json | 39 + .travis.yml | 3 +- bin/commander.js | 3 +- bin/get-vendor-scripts.php | 11 +- bin/packages/build-worker.js | 2 +- bin/packages/post-css-config.js | 63 +- docs/contributors/coding-guidelines.md | 2 +- docs/contributors/git-workflow.md | 17 +- .../developers/data/data-core-block-editor.md | 15 +- .../developers/data/data-core-edit-post.md | 4 +- .../developers/data/data-core-nux.md | 2 +- .../developers/data/data-core.md | 2 +- .../writing-your-first-block-type.md | 2 + docs/manifest-devhub.json | 18 + gutenberg.php | 2 +- lib/block-directory.php | 21 + lib/blocks.php | 1 + lib/client-assets.php | 279 +- lib/customizer.php | 2 +- lib/experiments-page.php | 9 +- lib/load.php | 23 +- lib/rest-api.php | 4 + lib/template-canvas.php | 23 + lib/template-loader.php | 177 + lib/templates.php | 127 +- package-lock.json | 4634 ++++++++--------- package.json | 54 +- packages/a11y/package.json | 2 +- packages/annotations/package.json | 2 +- packages/api-fetch/package.json | 2 +- packages/api-fetch/src/index.js | 50 +- .../api-fetch/src/middlewares/media-upload.js | 74 + packages/api-fetch/src/utils/response.js | 70 + packages/autop/package.json | 2 +- packages/babel-preset-default/package.json | 2 +- packages/base-styles/.npmrc | 1 + packages/base-styles/README.md | 51 + .../base-styles}/_animations.scss | 0 .../base-styles}/_breakpoints.scss | 0 .../base-styles}/_colors.scss | 0 .../base-styles}/_mixins.scss | 0 .../base-styles}/_variables.scss | 0 .../base-styles}/_z-index.scss | 2 + packages/base-styles/index.js | 60 + packages/base-styles/package.json | 25 + packages/blob/package.json | 2 +- packages/block-directory/package.json | 3 +- packages/block-directory/src/index.js | 3 +- packages/block-directory/src/plugins/index.js | 15 + .../index.js | 6 +- packages/block-editor/README.md | 19 +- packages/block-editor/package.json | 2 +- .../components/autocomplete/index.native.js | 1 + .../src/components/block-breadcrumb/index.js | 77 + .../components/block-breadcrumb/style.scss | 41 + .../src/components/block-edit/context.js | 20 +- .../src/components/block-edit/index.js | 3 +- .../block-list/block-async-mode-provider.js | 5 +- .../block-mobile-floating-toolbar.native.js | 9 +- .../block-mobile-floating-toolbar.native.scss | 9 +- .../block-list/block-mobile-toolbar.js | 4 +- .../src/components/block-list/block.js | 42 +- .../src/components/block-list/block.native.js | 2 + .../src/components/block-list/breadcrumb.js | 2 +- .../block-list/breadcrumb.native.js | 68 + .../block-list/breadcrumb.native.scss | 28 + .../src/components/block-list/index.js | 4 +- .../components/block-list/multi-controls.js | 2 + .../src/components/block-list/style.scss | 3 + .../block-list/subdirectory-icon.js | 18 + .../src/components/block-mover/icons.js | 12 + .../src/components/block-mover/index.js | 57 +- .../block-mover/mover-description.js | 51 +- .../src/components/block-mover/style.scss | 32 +- .../src/components/block-navigation/list.js | 25 +- .../src/components/block-preview/index.js | 2 +- .../block-settings/container.native.js | 6 + .../block-settings/container.native.scss | 4 + .../src/components/block-toolbar/style.scss | 2 + .../components/button-block-appender/index.js | 40 +- .../src/components/colors/index.js | 1 + .../src/components/colors/use-colors.js | 226 + .../src/components/colors/with-colors.js | 2 +- .../test/__snapshots__/index.js.snap | 6 +- .../src/components/gradient-picker/control.js | 13 +- .../src/components/gradient-picker/panel.js | 32 + .../src/components/gradients/index.js | 77 + .../components/ignore-nested-events/index.js | 2 +- packages/block-editor/src/components/index.js | 7 +- .../src/components/index.native.js | 3 +- .../src/components/inner-blocks/index.js | 2 + .../src/components/inserter/index.js | 118 +- .../src/components/link-control/README.md | 50 + .../src/components/link-control/index.js | 249 + .../components/link-control/search-input.js | 69 + .../components/link-control/search-item.js | 54 + .../link-control/settings-drawer.js | 29 + .../src/components/link-control/style.scss | 202 + .../test/__snapshots__/index.js.snap | 3 + .../link-control/test/fixtures/index.js | 41 + .../src/components/link-control/test/index.js | 527 ++ .../components/link-control/text-highlight.js | 29 + .../components/media-placeholder/README.md | 4 +- .../src/components/media-placeholder/index.js | 2 +- .../media-placeholder/styles.native.scss | 4 - .../src/components/media-upload/check.js | 2 +- .../src/components/media-upload/index.js | 2 +- .../components/media-upload/index.native.js | 37 +- .../src/components/provider/index.js | 4 +- .../src/components/provider/index.native.js | 4 +- .../rich-text/file-paste-handler.js | 11 + .../rich-text/file-paste-handler.native.js | 3 + .../rich-text/format-toolbar-container.js | 59 + .../format-toolbar-container.native.js | 16 + .../src/components/rich-text/index.js | 90 +- .../src/components/rich-text/index.native.js | 213 - .../rich-text/remove-browser-shortcuts.js | 2 +- .../remove-browser-shortcuts.native.js | 1 + .../src/components/typewriter/index.js | 2 +- .../src/components/url-input/index.js | 111 +- packages/block-editor/src/hooks/anchor.js | 4 +- .../src/hooks/custom-class-name.js | 4 +- packages/block-editor/src/store/defaults.js | 57 +- packages/block-editor/src/store/selectors.js | 66 +- packages/block-editor/src/style.scss | 2 + packages/block-library/package.json | 2 +- packages/block-library/src/audio/edit.js | 6 +- packages/block-library/src/button/block.json | 3 + packages/block-library/src/button/edit.js | 326 +- packages/block-library/src/button/save.js | 8 +- .../block-library/src/columns/deprecated.js | 10 +- .../block-library/src/columns/editor.scss | 42 +- packages/block-library/src/columns/utils.js | 4 +- packages/block-library/src/cover/block.json | 3 + packages/block-library/src/cover/edit.js | 77 +- packages/block-library/src/cover/editor.scss | 3 +- packages/block-library/src/cover/save.js | 12 + packages/block-library/src/cover/style.scss | 22 +- packages/block-library/src/editor.scss | 2 +- .../embed/test/__snapshots__/index.js.snap | 2 +- packages/block-library/src/file/edit.js | 4 +- packages/block-library/src/gallery/edit.js | 9 +- .../block-library/src/gallery/editor.scss | 4 +- packages/block-library/src/group/index.js | 4 +- packages/block-library/src/heading/edit.js | 109 +- packages/block-library/src/image/constants.js | 2 +- packages/block-library/src/image/edit.js | 23 +- .../block-library/src/image/edit.native.js | 91 +- packages/block-library/src/image/icon.js | 4 +- packages/block-library/src/image/save.js | 5 +- .../src/image/styles.native.scss | 14 +- .../src/image/test/edit.native.js | 6 +- packages/block-library/src/image/utils.js | 40 +- packages/block-library/src/index.js | 33 +- packages/block-library/src/index.native.js | 6 +- packages/block-library/src/list/block.json | 3 + packages/block-library/src/list/edit.js | 5 +- packages/block-library/src/list/editor.scss | 5 - packages/block-library/src/list/save.js | 3 +- packages/block-library/src/list/transforms.js | 35 +- .../src/media-text/media-container.native.js | 21 +- .../src/media-text/style.native.scss | 6 + .../block-library/src/missing/edit.native.js | 4 + .../src/missing/style.native.scss | 14 +- .../src/navigation-menu-item/block.json | 6 +- .../src/navigation-menu-item/edit.js | 154 +- .../src/navigation-menu-item/editor.scss | 80 +- .../src/navigation-menu-item/index.js | 6 +- .../navigation-menu-item/menu-item-actions.js | 111 - .../navigation-menu/block-colors-selector.js | 95 + .../block-library/src/navigation-menu/edit.js | 115 +- .../src/navigation-menu/editor.scss | 154 +- .../src/navigation-menu/index.php | 128 +- .../src/navigation-menu/style.scss | 119 + .../block-library/src/site-title/block.json | 4 + packages/block-library/src/site-title/edit.js | 39 + .../block-library/src/site-title/editor.scss | 6 + packages/block-library/src/site-title/icon.js | 12 + .../block-library/src/site-title/index.js | 20 + .../block-library/src/site-title/index.php | 28 + .../block-library/src/social-link/index.php | 2 +- packages/block-library/src/style.scss | 77 + packages/block-library/src/table/edit.js | 30 +- packages/block-library/src/table/editor.scss | 4 - packages/block-library/src/video/edit.js | 6 +- .../package.json | 2 +- .../package.json | 2 +- packages/blocks/README.md | 2 +- packages/blocks/package.json | 2 +- packages/blocks/src/api/factory.js | 16 +- packages/blocks/src/api/index.native.js | 44 - packages/blocks/src/api/parser.js | 6 +- .../raw-handling/phrasing-content-reducer.js | 11 +- .../api/raw-handling/shortcode-converter.js | 4 +- packages/blocks/src/api/registration.js | 14 +- packages/blocks/src/api/serializer.js | 25 +- .../src/block-content-provider/index.js | 4 +- packages/components/package.json | 2 +- packages/components/src/autocomplete/index.js | 6 +- .../src/button-group/stories/index.js | 2 +- .../components/src/button/stories/index.js | 93 +- packages/components/src/button/style.scss | 12 +- .../components/src/checkbox-control/README.md | 9 +- .../src/checkbox-control/stories/index.js | 54 + .../src/clipboard-button/stories/index.js | 29 +- .../src/color-indicator/stories/index.js | 16 +- .../src/color-palette/stories/index.js | 56 + packages/components/src/color-picker/hue.js | 6 +- .../components/src/color-picker/inputs.js | 9 +- .../components/src/color-picker/saturation.js | 6 +- .../src/color-picker/stories/index.js | 39 + .../test/__snapshots__/index.js.snap | 24 +- .../components/src/dashicon/stories/index.js | 25 + packages/components/src/date-time/date.js | 2 +- packages/components/src/date-time/index.js | 3 +- .../src/dimension-control/README.md | 120 + .../components/src/dimension-control/index.js | 76 + .../components/src/dimension-control/sizes.js | 45 + .../src/dimension-control/style.scss | 22 + .../test/__snapshots__/index.test.js.snap | 163 + .../src/dimension-control/test/index.test.js | 128 + .../components/src/draggable/stories/index.js | 69 + .../components/src/external-link/index.js | 5 +- .../src/external-link/stories/index.js | 17 + .../components/src/font-size-picker/index.js | 2 +- .../src/font-size-picker/style.scss | 6 + .../components/src/gradient-picker/index.js | 3 +- .../higher-order/with-focus-return/index.js | 8 +- .../src/higher-order/with-notices/index.js | 5 +- .../with-spoken-messages/index.js | 4 +- .../src/icon-button/stories/index.js | 17 +- packages/components/src/icon/stories/index.js | 24 +- packages/components/src/index.js | 2 + packages/components/src/index.native.js | 3 + .../src/keyboard-shortcuts/index.native.js | 2 + packages/components/src/menu-item/index.js | 2 +- .../src/mobile/bottom-sheet/cell.native.js | 15 +- .../src/mobile/bottom-sheet/index.native.js | 4 + .../mobile/bottom-sheet/picker-cell.native.js | 3 + .../mobile/bottom-sheet/range-cell.native.js | 46 + .../mobile/bottom-sheet/styles.native.scss | 7 + .../src/mobile/picker/index.android.js | 1 + .../components/src/mobile/picker/index.ios.js | 3 +- .../src/mobile/slider/index.native.js | 118 + .../components/src/mobile/slider/styles.scss | 27 + packages/components/src/modal/index.js | 2 +- .../components/src/panel/actions.native.js | 36 + .../components/src/panel/actions.native.scss | 7 + packages/components/src/panel/body.native.js | 12 +- .../components/src/panel/body.native.scss | 11 + packages/components/src/placeholder/README.md | 2 +- packages/components/src/scroll-lock/index.js | 2 +- .../src/scroll-lock/stories/index.js | 2 +- .../components/src/spinner/stories/index.js | 12 + packages/components/src/style.scss | 2 + packages/components/src/toolbar/index.js | 12 +- .../components/src/visually-hidden/README.md | 9 + .../components/src/visually-hidden/index.js | 22 + .../src/visually-hidden/stories/index.js | 17 + .../components/src/visually-hidden/style.scss | 30 + .../components/src/visually-hidden/utils.js | 22 + packages/components/storybook/addons.js | 1 + packages/components/storybook/config.js | 2 + packages/compose/README.md | 10 +- packages/compose/package.json | 3 +- packages/compose/src/higher-order/compose.js | 14 + .../higher-order/with-instance-id/index.js | 4 +- .../higher-order/with-safe-timeout/index.js | 4 +- .../src/higher-order/with-state/index.js | 2 +- packages/compose/src/index.js | 16 +- packages/core-data/README.md | 2 +- packages/core-data/package.json | 2 +- packages/core-data/src/actions.js | 4 +- packages/core-data/src/entities.js | 1 + packages/core-data/src/entity-provider.js | 76 +- packages/core-data/src/index.js | 7 +- .../core-data/src/queried-data/reducer.js | 6 +- packages/core-data/src/resolvers.js | 2 +- packages/core-data/src/selectors.js | 6 +- packages/data-controls/package.json | 2 +- packages/data/README.md | 44 +- packages/data/package.json | 2 +- .../components/async-mode-provider/context.js | 34 + .../src/components/with-dispatch/index.js | 2 +- .../data/src/components/with-select/index.js | 2 +- packages/data/src/factory.js | 4 - packages/data/src/index.js | 4 +- packages/data/src/namespace-store/index.js | 2 +- .../data/src/plugins/persistence/index.js | 2 +- packages/date/README.md | 8 +- packages/date/src/index.js | 50 +- packages/deprecated/package.json | 2 +- packages/dom-ready/package.json | 2 +- packages/dom/package.json | 2 +- packages/e2e-test-utils/CHANGELOG.md | 6 + packages/e2e-test-utils/README.md | 6 +- packages/e2e-test-utils/package.json | 2 +- ...-sidebar-panel-toggle-button-with-title.js | 2 +- .../src/find-sidebar-panel-with-title.js | 2 +- packages/e2e-test-utils/src/index.js | 1 - .../src/wait-for-window-dimensions.js | 2 +- .../e2e-tests/config/performance-reporter.js | 2 +- .../experimental-features.js} | 33 +- .../e2e-tests/fixtures/block-transforms.js | 28 + .../blocks/core__cover__gradient-image.html | 10 + .../blocks/core__cover__gradient-image.json | 31 + .../core__cover__gradient-image.parsed.json | 40 + ...ore__cover__gradient-image.serialized.html | 5 + .../blocks/core__cover__gradient-video.html | 11 + .../blocks/core__cover__gradient-video.json | 31 + .../core__cover__gradient-video.parsed.json | 41 + ...ore__cover__gradient-video.serialized.html | 5 + .../blocks/core__cover__gradient.html | 9 + .../blocks/core__cover__gradient.json | 30 + .../blocks/core__cover__gradient.parsed.json | 38 + .../core__cover__gradient.serialized.html | 5 + .../blocks/core__navigation-menu-item.html | 2 +- .../blocks/core__navigation-menu-item.json | 4 +- .../core__navigation-menu-item.parsed.json | 2 +- ...core__navigation-menu-item.serialized.html | 2 +- .../fixtures/blocks/core__site-title.html | 1 + .../fixtures/blocks/core__site-title.json | 10 + .../blocks/core__site-title.parsed.json | 18 + .../blocks/core__site-title.serialized.html | 1 + packages/e2e-tests/jest.config.js | 2 +- packages/e2e-tests/jest.performance.config.js | 2 +- packages/e2e-tests/package.json | 3 +- .../blocks/__snapshots__/button.test.js.snap | 0 .../blocks/__snapshots__/classic.test.js.snap | 0 .../blocks/__snapshots__/code.test.js.snap | 0 .../blocks/__snapshots__/group.test.js.snap | 0 .../blocks/__snapshots__/heading.test.js.snap | 0 .../blocks/__snapshots__/html.test.js.snap | 0 .../blocks/__snapshots__/list.test.js.snap | 6 + .../__snapshots__/preformatted.test.js.snap | 0 .../blocks/__snapshots__/quote.test.js.snap | 0 .../__snapshots__/separator.test.js.snap | 0 .../blocks/__snapshots__/spacer.test.js.snap | 0 .../blocks/__snapshots__/table.test.js.snap | 0 .../specs/{ => editor}/blocks/button.test.js | 0 .../specs/{ => editor}/blocks/classic.test.js | 2 +- .../specs/{ => editor}/blocks/code.test.js | 0 .../specs/{ => editor}/blocks/columns.test.js | 0 .../specs/{ => editor}/blocks/group.test.js | 0 .../specs/{ => editor}/blocks/heading.test.js | 0 .../specs/{ => editor}/blocks/html.test.js | 0 .../specs/{ => editor}/blocks/list.test.js | 12 + .../{ => editor}/blocks/preformatted.test.js | 0 .../specs/{ => editor}/blocks/quote.test.js | 0 .../{ => editor}/blocks/separator.test.js | 0 .../specs/{ => editor}/blocks/spacer.test.js | 0 .../specs/{ => editor}/blocks/table.test.js | 16 +- .../__snapshots__/align-hook.test.js.snap | 0 .../container-blocks.test.js.snap | 0 .../__snapshots__/cpt-locking.test.js.snap | 0 .../deprecated-node-matcher.test.js.snap | 0 .../__snapshots__/format-api.test.js.snap | 0 .../__snapshots__/hooks-api.test.js.snap | 0 .../meta-attribute-block.test.js.snap | 0 .../__snapshots__/plugins-api.test.js.snap | 0 .../__snapshots__/templates.test.js.snap | 0 .../wp-editor-meta-box.test.js.snap | 0 .../{ => editor}/plugins/align-hook.test.js | 0 .../plugins/allowed-blocks.test.js | 0 .../{ => editor}/plugins/annotations.test.js | 0 .../{ => editor}/plugins/block-icons.test.js | 0 .../plugins/container-blocks.test.js | 0 .../{ => editor}/plugins/cpt-locking.test.js | 0 .../plugins/custom-taxonomies.test.js | 0 .../plugins/deprecated-node-matcher.test.js | 0 .../{ => editor}/plugins/format-api.test.js | 0 .../{ => editor}/plugins/hooks-api.test.js | 0 .../inner-blocks-allowed-blocks.test.js | 0 .../plugins/innerblocks-locking-all-embed.js | 0 .../plugins/meta-attribute-block.test.js | 0 .../{ => editor}/plugins/meta-boxes.test.js | 0 .../specs/{ => editor}/plugins/nonce.test.js | 0 .../{ => editor}/plugins/plugins-api.test.js | 0 .../{ => editor}/plugins/templates.test.js | 0 .../plugins/wp-editor-meta-box.test.js | 9 +- .../__snapshots__/adding-blocks.test.js.snap | 0 .../__snapshots__/block-deletion.test.js.snap | 0 .../__snapshots__/block-grouping.test.js.snap | 0 .../block-hierarchy-navigation.test.js.snap | 0 .../compatibility-classic-editor.test.js.snap | 0 .../convert-block-type.test.js.snap | 0 .../__snapshots__/embedding.test.js.snap | 0 .../font-size-picker.test.js.snap | 0 .../various}/__snapshots__/links.test.js.snap | 0 .../__snapshots__/mentions.test.js.snap | 0 .../multi-block-selection.test.js.snap | 0 .../reusable-blocks.test.js.snap | 0 .../__snapshots__/rich-text.test.js.snap | 0 .../various}/__snapshots__/rtl.test.js.snap | 0 .../splitting-merging.test.js.snap | 0 .../style-variation.test.js.snap | 0 .../various}/__snapshots__/undo.test.js.snap | 0 .../__snapshots__/writing-flow.test.js.snap | 0 .../specs/{ => editor/various}/a11y.test.js | 0 .../various}/adding-blocks.test.js | 2 +- .../various}/adding-inline-tokens.test.js | 2 +- .../{ => editor/various}/autosave.test.js | 65 +- .../various}/block-deletion.test.js | 0 .../various}/block-grouping.test.js | 0 .../block-hierarchy-navigation.test.js | 1 + .../{ => editor/various}/block-mover.test.js | 0 .../various}/block-switcher.test.js | 0 .../various}/change-detection.test.js | 0 .../compatibility-classic-editor.test.js | 0 .../various}/convert-block-type.test.js | 0 .../{ => editor/various}/datepicker.test.js | 0 .../{ => editor/various}/editor-modes.test.js | 0 .../{ => editor/various}/embedding.test.js | 29 - .../various}/font-size-picker.test.js | 4 +- .../various}/fullscreen-mode.test.js | 0 .../various}/invalid-block.test.js | 0 .../keyboard-navigable-blocks.test.js | 0 .../specs/{ => editor/various}/links.test.js | 81 - .../various}/manage-reusable-blocks.test.js | 2 +- .../{ => editor/various}/mentions.test.js | 0 .../various}/multi-block-selection.test.js | 0 .../various}/navigable-toolbar.test.js | 0 .../various}/new-post-default-content.test.js | 0 .../{ => editor/various}/new-post.test.js | 0 .../specs/{ => editor/various}/nux.test.js | 70 - .../{ => editor/various}/popovers.test.js | 0 .../various}/post-visibility.test.js | 0 .../{ => editor/various}/preferences.test.js | 0 .../{ => editor/various}/preview.test.js | 0 .../various}/publish-button.test.js | 0 .../various}/publish-panel.test.js | 0 .../{ => editor/various}/publishing.test.js | 0 .../various}/reusable-blocks.test.js | 0 .../{ => editor/various}/rich-text.test.js | 0 .../specs/{ => editor/various}/rtl.test.js | 0 .../{ => editor/various}/scheduling.test.js | 0 .../various}/shortcut-help.test.js | 0 .../various}/sidebar-permalink-panel.test.js | 0 .../{ => editor/various}/sidebar.test.js | 1 + .../various}/splitting-merging.test.js | 0 .../various}/style-variation.test.js | 0 .../{ => editor/various}/taxonomies.test.js | 42 +- .../{ => editor/various}/typewriter.test.js | 0 .../specs/{ => editor/various}/undo.test.js | 0 .../{ => editor/various}/writing-flow.test.js | 0 .../block-transforms.test.js.snap | 24 + .../block-transforms.test.js | 33 +- .../e2e-tests/specs/{ => local}/demo.test.js | 0 .../specs/{ => performance}/.gitignore | 0 .../{ => performance}/performance.test.js | 2 +- packages/edit-post/CHANGELOG.md | 2 +- packages/edit-post/README.md | 30 +- packages/edit-post/package.json | 2 +- .../plugin-block-settings-menu-item.js | 4 +- .../header/plugin-more-menu-item/index.js | 4 +- .../plugin-sidebar-more-menu-item/index.js | 4 +- .../src/components/header/style.scss | 10 +- .../edit-post/src/components/layout/index.js | 20 +- .../src/components/layout/style.scss | 81 +- .../meta-boxes/meta-boxes-area/style.scss | 19 + .../plugin-document-setting-panel/index.js | 4 +- .../plugin-post-publish-panel/index.js | 4 +- .../sidebar/plugin-post-status-info/index.js | 2 +- .../sidebar/plugin-pre-publish-panel/index.js | 17 +- .../sidebar/plugin-sidebar/index.js | 4 +- .../src/components/sidebar/post-slug/index.js | 17 + .../components/sidebar/post-slug/style.scss | 4 + .../components/sidebar/post-status/index.js | 2 + .../src/components/sidebar/style.scss | 4 + .../src/components/text-editor/style.scss | 80 +- .../src/hooks/validate-multiple-use/index.js | 4 +- packages/edit-post/src/store/selectors.js | 4 +- packages/edit-post/src/style.scss | 3 + packages/edit-widgets/package.json | 2 +- .../src/components/widget-area/index.js | 2 +- packages/editor/package.json | 2 +- .../src/components/autocompleters/block.js | 6 +- .../src/components/autocompleters/user.js | 2 +- packages/editor/src/components/index.js | 2 + .../local-autosave-monitor/index.js | 7 +- .../components/post-publish-button/index.js | 1 + .../editor/src/components/post-slug/check.js | 10 + .../editor/src/components/post-slug/index.js | 85 + .../src/components/post-slug/test/check.js | 21 + .../src/components/post-slug/test/index.js | 45 + .../post-taxonomies/flat-term-selector.js | 6 +- .../post-type-support-check/index.js | 14 +- .../editor/src/components/provider/index.js | 59 +- packages/editor/src/editor-styles.scss | 2 + packages/editor/src/store/actions.native.js | 4 +- packages/editor/src/store/reducer.js | 8 +- packages/element/README.md | 41 +- packages/element/package.json | 2 +- packages/element/src/index.js | 1 + packages/element/src/platform.android.js | 18 + packages/element/src/platform.ios.js | 18 + packages/element/src/platform.js | 32 + packages/element/src/raw-html.js | 2 +- packages/element/src/react-platform.js | 14 +- packages/element/src/react.js | 30 +- packages/element/src/test/platform.js | 19 + packages/element/src/test/platform.native.js | 19 + packages/env/.npmrc | 1 + packages/env/README.md | 19 +- packages/env/lib/cli.js | 4 +- .../env/lib/create-docker-compose-config.js | 21 +- packages/env/lib/detect-context.js | 45 + packages/env/lib/env.js | 40 +- packages/env/package.json | 2 +- .../env/{tests/cli.test.js => test/cli.js} | 0 packages/escape-html/package.json | 2 +- packages/eslint-plugin/configs/jsdoc.js | 52 + packages/format-library/package.json | 2 +- packages/format-library/src/image/style.scss | 15 +- packages/is-shallow-equal/package.json | 2 +- packages/jest-puppeteer-axe/src/index.js | 14 +- packages/keycodes/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/media-utils/package.json | 2 +- .../src/components/media-upload/index.js | 3 - packages/notices/package.json | 2 +- packages/notices/src/store/actions.js | 11 + packages/notices/src/store/selectors.js | 11 - packages/nux/package.json | 2 +- packages/nux/src/store/selectors.js | 4 +- packages/plugins/README.md | 16 +- packages/plugins/package.json | 2 +- packages/plugins/src/api/index.js | 30 +- .../src/components/plugin-area/index.js | 2 +- .../src/components/plugin-context/index.js | 2 +- packages/priority-queue/package.json | 2 +- packages/redux-routine/package.json | 2 +- packages/rich-text/README.md | 6 +- packages/rich-text/package.json | 2 +- packages/rich-text/src/component/index.js | 68 +- .../rich-text/src/component/index.native.js | 267 +- .../src/component/test/index.native.js | 34 - .../rich-text/src/register-format-type.js | 19 +- packages/rich-text/src/test/helpers/index.js | 2 +- packages/rich-text/src/to-dom.js | 2 +- packages/scripts/CHANGELOG.md | 10 + packages/scripts/package.json | 6 +- packages/scripts/scripts/lint-pkg-json.js | 2 + packages/server-side-render/package.json | 2 +- packages/url/package.json | 2 +- packages/url/src/index.js | 4 + packages/viewport/package.json | 2 +- packages/wordcount/package.json | 2 +- phpunit/class-override-script-test.php | 16 +- playground/.sassrc | 5 + playground/src/index.js | 13 +- playground/src/style.scss | 40 +- .../blocks-raw-handling.test.js.snap | 10 + test/integration/blocks-raw-handling.test.js | 5 + .../integration/fixtures/google-docs-out.html | 2 +- .../google-docs-with-comments-out.html | 2 +- .../fixtures/list-with-attributes.html | 7 + test/integration/fixtures/ms-word-out.html | 4 +- .../full-content/full-content.test.js | 6 +- .../full-content/server-registered.json | 2 +- test/integration/shortcode-converter.test.js | 41 +- test/native/setup.js | 2 + 564 files changed, 10590 insertions(+), 5015 deletions(-) create mode 100644 .npmpackagejsonlintrc.json create mode 100644 lib/block-directory.php create mode 100644 lib/template-canvas.php create mode 100644 lib/template-loader.php create mode 100644 packages/api-fetch/src/middlewares/media-upload.js create mode 100644 packages/api-fetch/src/utils/response.js create mode 100644 packages/base-styles/.npmrc create mode 100644 packages/base-styles/README.md rename {assets/stylesheets => packages/base-styles}/_animations.scss (100%) rename {assets/stylesheets => packages/base-styles}/_breakpoints.scss (100%) rename {assets/stylesheets => packages/base-styles}/_colors.scss (100%) rename {assets/stylesheets => packages/base-styles}/_mixins.scss (100%) rename {assets/stylesheets => packages/base-styles}/_variables.scss (100%) rename {assets/stylesheets => packages/base-styles}/_z-index.scss (98%) create mode 100644 packages/base-styles/index.js create mode 100644 packages/base-styles/package.json create mode 100644 packages/block-directory/src/plugins/index.js rename packages/{editor/src/components => block-directory/src/plugins}/inserter-menu-downloadable-blocks-panel/index.js (89%) create mode 100644 packages/block-editor/src/components/autocomplete/index.native.js create mode 100644 packages/block-editor/src/components/block-breadcrumb/index.js create mode 100644 packages/block-editor/src/components/block-breadcrumb/style.scss create mode 100644 packages/block-editor/src/components/block-list/breadcrumb.native.js create mode 100644 packages/block-editor/src/components/block-list/breadcrumb.native.scss create mode 100644 packages/block-editor/src/components/block-list/subdirectory-icon.js create mode 100644 packages/block-editor/src/components/block-settings/container.native.scss create mode 100644 packages/block-editor/src/components/colors/use-colors.js create mode 100644 packages/block-editor/src/components/gradient-picker/panel.js create mode 100644 packages/block-editor/src/components/gradients/index.js create mode 100644 packages/block-editor/src/components/link-control/README.md create mode 100644 packages/block-editor/src/components/link-control/index.js create mode 100644 packages/block-editor/src/components/link-control/search-input.js create mode 100644 packages/block-editor/src/components/link-control/search-item.js create mode 100644 packages/block-editor/src/components/link-control/settings-drawer.js create mode 100644 packages/block-editor/src/components/link-control/style.scss create mode 100644 packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap create mode 100644 packages/block-editor/src/components/link-control/test/fixtures/index.js create mode 100644 packages/block-editor/src/components/link-control/test/index.js create mode 100644 packages/block-editor/src/components/link-control/text-highlight.js create mode 100644 packages/block-editor/src/components/rich-text/file-paste-handler.js create mode 100644 packages/block-editor/src/components/rich-text/file-paste-handler.native.js create mode 100644 packages/block-editor/src/components/rich-text/format-toolbar-container.js create mode 100644 packages/block-editor/src/components/rich-text/format-toolbar-container.native.js delete mode 100644 packages/block-editor/src/components/rich-text/index.native.js create mode 100644 packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js delete mode 100644 packages/block-library/src/list/editor.scss delete mode 100644 packages/block-library/src/navigation-menu-item/menu-item-actions.js create mode 100644 packages/block-library/src/navigation-menu/block-colors-selector.js create mode 100644 packages/block-library/src/navigation-menu/style.scss create mode 100644 packages/block-library/src/site-title/block.json create mode 100644 packages/block-library/src/site-title/edit.js create mode 100644 packages/block-library/src/site-title/editor.scss create mode 100644 packages/block-library/src/site-title/icon.js create mode 100644 packages/block-library/src/site-title/index.js create mode 100644 packages/block-library/src/site-title/index.php delete mode 100644 packages/blocks/src/api/index.native.js create mode 100644 packages/components/src/checkbox-control/stories/index.js create mode 100644 packages/components/src/color-palette/stories/index.js create mode 100644 packages/components/src/color-picker/stories/index.js create mode 100644 packages/components/src/dashicon/stories/index.js create mode 100644 packages/components/src/dimension-control/README.md create mode 100644 packages/components/src/dimension-control/index.js create mode 100644 packages/components/src/dimension-control/sizes.js create mode 100644 packages/components/src/dimension-control/style.scss create mode 100644 packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap create mode 100644 packages/components/src/dimension-control/test/index.test.js create mode 100644 packages/components/src/draggable/stories/index.js create mode 100644 packages/components/src/external-link/stories/index.js create mode 100644 packages/components/src/keyboard-shortcuts/index.native.js create mode 100644 packages/components/src/mobile/bottom-sheet/range-cell.native.js create mode 100644 packages/components/src/mobile/slider/index.native.js create mode 100644 packages/components/src/mobile/slider/styles.scss create mode 100644 packages/components/src/panel/actions.native.js create mode 100644 packages/components/src/panel/actions.native.scss create mode 100644 packages/components/src/panel/body.native.scss create mode 100644 packages/components/src/spinner/stories/index.js create mode 100644 packages/components/src/visually-hidden/README.md create mode 100644 packages/components/src/visually-hidden/index.js create mode 100644 packages/components/src/visually-hidden/stories/index.js create mode 100644 packages/components/src/visually-hidden/style.scss create mode 100644 packages/components/src/visually-hidden/utils.js create mode 100644 packages/compose/src/higher-order/compose.js rename packages/{e2e-test-utils/src/enable-experimental-features.js => e2e-tests/experimental-features.js} (60%) create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/button.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/classic.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/code.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/group.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/heading.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/html.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/list.test.js.snap (98%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/preformatted.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/quote.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/separator.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/spacer.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/table.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/button.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/classic.test.js (95%) rename packages/e2e-tests/specs/{ => editor}/blocks/code.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/columns.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/group.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/heading.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/html.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/list.test.js (97%) rename packages/e2e-tests/specs/{ => editor}/blocks/preformatted.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/quote.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/separator.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/spacer.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/table.test.js (94%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/align-hook.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/container-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/cpt-locking.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/deprecated-node-matcher.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/format-api.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/hooks-api.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/meta-attribute-block.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/plugins-api.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/templates.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/wp-editor-meta-box.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/align-hook.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/allowed-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/annotations.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/block-icons.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/container-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/cpt-locking.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/custom-taxonomies.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/deprecated-node-matcher.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/format-api.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/hooks-api.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/inner-blocks-allowed-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/innerblocks-locking-all-embed.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/meta-attribute-block.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/meta-boxes.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/nonce.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/plugins-api.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/templates.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/wp-editor-meta-box.test.js (76%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/adding-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/block-deletion.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/block-grouping.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/block-hierarchy-navigation.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/compatibility-classic-editor.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/convert-block-type.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/embedding.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/font-size-picker.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/links.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/mentions.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/multi-block-selection.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/reusable-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/rich-text.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/rtl.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/splitting-merging.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/style-variation.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/undo.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/writing-flow.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/a11y.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/adding-blocks.test.js (98%) rename packages/e2e-tests/specs/{ => editor/various}/adding-inline-tokens.test.js (93%) rename packages/e2e-tests/specs/{ => editor/various}/autosave.test.js (77%) rename packages/e2e-tests/specs/{ => editor/various}/block-deletion.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-grouping.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-hierarchy-navigation.test.js (99%) rename packages/e2e-tests/specs/{ => editor/various}/block-mover.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-switcher.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/change-detection.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/compatibility-classic-editor.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/convert-block-type.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/datepicker.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/editor-modes.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/embedding.test.js (87%) rename packages/e2e-tests/specs/{ => editor/various}/font-size-picker.test.js (97%) rename packages/e2e-tests/specs/{ => editor/various}/fullscreen-mode.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/invalid-block.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/keyboard-navigable-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/links.test.js (80%) rename packages/e2e-tests/specs/{ => editor/various}/manage-reusable-blocks.test.js (93%) rename packages/e2e-tests/specs/{ => editor/various}/mentions.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/multi-block-selection.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/navigable-toolbar.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/new-post-default-content.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/new-post.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/nux.test.js (56%) rename packages/e2e-tests/specs/{ => editor/various}/popovers.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/post-visibility.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/preferences.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/preview.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/publish-button.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/publish-panel.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/publishing.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/reusable-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/rich-text.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/rtl.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/scheduling.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/shortcut-help.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/sidebar-permalink-panel.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/sidebar.test.js (99%) rename packages/e2e-tests/specs/{ => editor/various}/splitting-merging.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/style-variation.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/taxonomies.test.js (83%) rename packages/e2e-tests/specs/{ => editor/various}/typewriter.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/undo.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/writing-flow.test.js (100%) rename packages/e2e-tests/specs/{ => experimental}/__snapshots__/block-transforms.test.js.snap (94%) rename packages/e2e-tests/specs/{ => experimental}/block-transforms.test.js (88%) rename packages/e2e-tests/specs/{ => local}/demo.test.js (100%) rename packages/e2e-tests/specs/{ => performance}/.gitignore (100%) rename packages/e2e-tests/specs/{ => performance}/performance.test.js (95%) create mode 100644 packages/edit-post/src/components/sidebar/post-slug/index.js create mode 100644 packages/edit-post/src/components/sidebar/post-slug/style.scss create mode 100644 packages/editor/src/components/post-slug/check.js create mode 100644 packages/editor/src/components/post-slug/index.js create mode 100644 packages/editor/src/components/post-slug/test/check.js create mode 100644 packages/editor/src/components/post-slug/test/index.js create mode 100644 packages/element/src/platform.android.js create mode 100644 packages/element/src/platform.ios.js create mode 100644 packages/element/src/platform.js create mode 100644 packages/element/src/test/platform.js create mode 100644 packages/element/src/test/platform.native.js create mode 100644 packages/env/.npmrc create mode 100644 packages/env/lib/detect-context.js rename packages/env/{tests/cli.test.js => test/cli.js} (100%) create mode 100644 playground/.sassrc create mode 100644 test/integration/fixtures/list-with-attributes.html diff --git a/.eslintrc.js b/.eslintrc.js index b1a6b834b53aff..43e259b40c7b7e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -123,7 +123,7 @@ module.exports = { '**/*.@(android|ios|native).js', '**/benchmark/**/*.js', '**/@(__mocks__|__tests__|test)/**/*.js', - '**/storybook/**/*.js', + '**/@(storybook|stories)/**/*.js', ], }, { diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 33d5a864d489d8..c6d9694eae9b62 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,7 +40,7 @@ /packages/custom-templated-path-webpack-plugin @ntwb @nerrad @ajitbohra /packages/docgen @nosolosw /packages/e2e-test-utils @gziolo @ntwb @nerrad @ajitbohra -/packages/e2e-tests @gziolo @ntwb @nerrad @ajitbohra @talldan +/packages/e2e-tests @ntwb @nerrad @ajitbohra @talldan /packages/eslint-plugin @gziolo @ntwb @nerrad @ajitbohra /packages/jest-console @gziolo @ntwb @nerrad @ajitbohra /packages/jest-preset-default @gziolo @ntwb @nerrad @ajitbohra @@ -51,9 +51,9 @@ /packages/scripts @youknowriad @gziolo @ntwb @nerrad @ajitbohra # UI Components -/packages/components @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @chrisvanpatten -/packages/compose @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan -/packages/element @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan +/packages/components @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @chrisvanpatten +/packages/compose @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan +/packages/element @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan /packages/notices @ajitbohra @jaymanpandya @jorgefilipecosta @talldan /packages/nux @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @noisysocks /packages/viewport @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan diff --git a/.npmpackagejsonlintrc.json b/.npmpackagejsonlintrc.json new file mode 100644 index 00000000000000..daab51fa30d456 --- /dev/null +++ b/.npmpackagejsonlintrc.json @@ -0,0 +1,39 @@ +{ + "extends": "@wordpress/npm-package-json-lint-config", + "rules": { + "description-format": [ + "error", + { + "requireCapitalFirstLetter": true, + "requireEndingPeriod": true + } + ], + "prefer-no-devDependencies": "error", + "require-publishConfig": "error", + "require-repository-directory": "error", + "valid-values-author": [ + "error", + [ + "The WordPress Contributors" + ] + ], + "valid-values-publishConfig": [ + "error", + [ + { + "access": "public" + } + ] + ] + }, + "overrides": [ + { + "patterns": [ "./package.json" ], + "rules": { + "require-publishConfig": "off", + "require-repository-directory": "off", + "prefer-no-devDependencies": "off" + } + } + ] +} diff --git a/.travis.yml b/.travis.yml index 27b1e7383e85ff..db9acbf2d2174b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,8 @@ branches: only: - master - rnmobile/master - - wp/trunk + - rnmobile/releases + - /wp\/.*/ env: global: diff --git a/bin/commander.js b/bin/commander.js index dcc863872f034d..95cfc56b25efd9 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -17,7 +17,7 @@ const uuid = require( 'uuid/v4' ); // Config const gitRepoOwner = 'WordPress'; -const gitRepoURL = 'git@github.com:' + gitRepoOwner + '/gutenberg.git'; +const gitRepoURL = 'https://github.com/' + gitRepoOwner + '/gutenberg.git'; const svnRepoURL = 'https://plugins.svn.wordpress.org/gutenberg'; // Working Directories @@ -95,6 +95,7 @@ function runShellScript( script, cwd ) { env: { NO_CHECKS: true, PATH: process.env.PATH, + HOME: process.env.HOME, }, stdio: [ 'inherit', 'ignore', 'inherit' ], } ); diff --git a/bin/get-vendor-scripts.php b/bin/get-vendor-scripts.php index 442e77b0eb4358..e7295f556b4cb2 100755 --- a/bin/get-vendor-scripts.php +++ b/bin/get-vendor-scripts.php @@ -32,4 +32,13 @@ function wp_add_inline_script() {} require_once dirname( dirname( __FILE__ ) ) . '/lib/client-assets.php'; -gutenberg_register_vendor_scripts(); +/** + * Hi, phpcs + */ +function run_gutenberg_register_vendor_scripts() { + global $wp_scripts; + + gutenberg_register_vendor_scripts( $wp_scripts ); +} + +run_gutenberg_register_vendor_scripts(); diff --git a/bin/packages/build-worker.js b/bin/packages/build-worker.js index 7e3e636c013a1d..d0f1d1c809984a 100644 --- a/bin/packages/build-worker.js +++ b/bin/packages/build-worker.js @@ -94,7 +94,7 @@ const BUILD_TASK_BY_EXTENSION = { const builtSass = await renderSass( { file, - includePaths: [ path.resolve( __dirname, '../../assets/stylesheets' ) ], + includePaths: [ path.join( PACKAGES_DIR, 'base-styles' ) ], data: ( [ 'colors', diff --git a/bin/packages/post-css-config.js b/bin/packages/post-css-config.js index 3d7861f75044bd..842688a8d784b7 100644 --- a/bin/packages/post-css-config.js +++ b/bin/packages/post-css-config.js @@ -1,64 +1,7 @@ +const { adminColorSchemes } = require( '@wordpress/base-styles' ); + module.exports = [ - require( '@wordpress/postcss-themes' )( { - defaults: { - primary: '#0085ba', - secondary: '#11a0d2', - toggle: '#11a0d2', - button: '#007cba', - outlines: '#007cba', - }, - themes: { - 'admin-color-light': { - primary: '#0085ba', - secondary: '#c75726', - toggle: '#11a0d2', - button: '#0085ba', - outlines: '#007cba', - }, - 'admin-color-blue': { - primary: '#82b4cb', - secondary: '#d9ab59', - toggle: '#82b4cb', - button: '#d9ab59', - outlines: '#417e9B', - }, - 'admin-color-coffee': { - primary: '#c2a68c', - secondary: '#9fa47b', - toggle: '#c2a68c', - button: '#c2a68c', - outlines: '#59524c', - }, - 'admin-color-ectoplasm': { - primary: '#a7b656', - secondary: '#c77430', - toggle: '#a7b656', - button: '#a7b656', - outlines: '#523f6d', - }, - 'admin-color-midnight': { - primary: '#e14d43', - secondary: '#77a6b9', - toggle: '#77a6b9', - button: '#e14d43', - outlines: '#497b8d', - }, - 'admin-color-ocean': { - primary: '#a3b9a2', - secondary: '#a89d8a', - toggle: '#a3b9a2', - button: '#a3b9a2', - outlines: '#5e7d5e', - }, - 'admin-color-sunrise': { - primary: '#d1864a', - secondary: '#c8b03c', - toggle: '#c8b03c', - button: '#d1864a', - outlines: '#837425', - }, - }, - } ), + require( '@wordpress/postcss-themes' )( adminColorSchemes ), require( 'autoprefixer' )( { grid: true } ), require( 'postcss-color-function' ), ]; diff --git a/docs/contributors/coding-guidelines.md b/docs/contributors/coding-guidelines.md index 2e02dfeaa10f7e..8e69e8c8ccddbd 100644 --- a/docs/contributors/coding-guidelines.md +++ b/docs/contributors/coding-guidelines.md @@ -59,7 +59,7 @@ export default function Notice( { children, onRemove, isDismissible } ) { } ``` -A component's class name should **never** be used outside its own folder (with rare exceptions such as [`_z-index.scss`](https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_z-index.scss)). If you need to inherit styles of another component in your own components, you should render an instance of that other component. At worst, you should duplicate the styles within your own component's stylesheet. This is intended to improve maintainability by treating individual components as the isolated abstract interface. +A component's class name should **never** be used outside its own folder (with rare exceptions such as [`_z-index.scss`](https://github.com/WordPress/gutenberg/blob/master/packages/base-styles/_z-index.scss)). If you need to inherit styles of another component in your own components, you should render an instance of that other component. At worst, you should duplicate the styles within your own component's stylesheet. This is intended to improve maintainability by treating individual components as the isolated abstract interface. #### SCSS File Naming Conventions for Blocks diff --git a/docs/contributors/git-workflow.md b/docs/contributors/git-workflow.md index 7f1499bc7de34a..5fe7a79d556fa3 100644 --- a/docs/contributors/git-workflow.md +++ b/docs/contributors/git-workflow.md @@ -36,12 +36,23 @@ To sum it up, you need to fetch any new changes in the repository, rebase your b ```sh git fetch git rebase master -git push --force-with-lease your-branch-name +git push --force-with-lease origin your-branch-name ``` ## Keeping Your Fork Up To Date -Working on pull request starts with forking the Gutenberg repository, your separate working copy. Which can easily go out of sync as new pull requests are merged into the main repository. Here your working repository is a `fork` and the main Gutenberg repository is `upstream`. When working on new pull request you should always update your fork before you do `git checkout -b my-new-branch` to work on a feature or fix. +Working on pull request starts with forking the Gutenberg repository, your separate working copy. Which can easily go out of sync as new pull requests are merged into the main repository. Here your working repository is a `fork` and the main Gutenberg repository is `upstream`. When working on new pull request you should always update your fork before you do `git checkout -b my-new-branch` to work on a feature or fix. + +You will need to add an `upstream` remote in order to keep your fork updated. + +```sh +git remote add origin upstream https://github.com/WordPress/gutenberg.git +git remote -v +origin git@github.com:your-account/gutenberg.git (fetch) +origin git@github.com:your-account/gutenberg.git (push) +upstream https://github.com/WordPress/gutenberg.git (fetch) +upstream https://github.com/WordPress/gutenberg.git (push) +``` To sync your fork you need to fetch the upstream changes and merge them into your fork. These are the corresponding commands: @@ -57,7 +68,7 @@ This will update you local copy to update your fork on github push your changes git push ``` -The above commands will update your `master` branch from _upstream_. To update any other branch replace `master` with the respective branch name. +The above commands will update your `master` branch from _upstream_. To update any other branch replace `master` with the respective branch name. ## References diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index eb9201165dafd6..ac50b42d83b114 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -189,6 +189,19 @@ _Returns_ - `Array`: Ordered client IDs of editor blocks. +# **getBlockParents** + +Given a block client ID, returns the list of all its parents from top to bottom. + +_Parameters_ + +- _state_ `Object`: Editor state. +- _clientId_ `string`: Block from which to find root client ID. + +_Returns_ + +- `Array`: ClientIDs of the parent blocks. + # **getBlockRootClientId** Given a block client ID, returns the root block from which the block is @@ -345,7 +358,7 @@ _Parameters_ _Returns_ -- `Array`: Items that appear in inserter. +- `Array`: Items that appear in inserter. # **getLastMultiSelectedBlockClientId** diff --git a/docs/designers-developers/developers/data/data-core-edit-post.md b/docs/designers-developers/developers/data/data-core-edit-post.md index 93efda1bd0bc4f..49801a69817be8 100644 --- a/docs/designers-developers/developers/data/data-core-edit-post.md +++ b/docs/designers-developers/developers/data/data-core-edit-post.md @@ -80,11 +80,11 @@ _Parameters_ - _state_ `Object`: Global application state. - _preferenceKey_ `string`: Preference Key. -- _defaultValue_ `Mixed`: Default Value. +- _defaultValue_ `*`: Default Value. _Returns_ -- `Mixed`: Preference Value. +- `*`: Preference Value. # **getPreferences** diff --git a/docs/designers-developers/developers/data/data-core-nux.md b/docs/designers-developers/developers/data/data-core-nux.md index e937601ec864b6..92dcf6be1d0ac2 100644 --- a/docs/designers-developers/developers/data/data-core-nux.md +++ b/docs/designers-developers/developers/data/data-core-nux.md @@ -30,7 +30,7 @@ _Parameters_ _Returns_ -- `?NUX.GuideInfo`: Information about the associated guide. +- `?NUXGuideInfo`: Information about the associated guide. # **isTipVisible** diff --git a/docs/designers-developers/developers/data/data-core.md b/docs/designers-developers/developers/data/data-core.md index ce0cda7d3542a3..79f3f41991c08f 100644 --- a/docs/designers-developers/developers/data/data-core.md +++ b/docs/designers-developers/developers/data/data-core.md @@ -512,7 +512,7 @@ a given URl has been received. _Parameters_ - _url_ `string`: URL to preview the embed for. -- _preview_ `Mixed`: Preview data. +- _preview_ `*`: Preview data. _Returns_ diff --git a/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md b/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md index 77496681ce4847..81794c30be53fb 100644 --- a/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md +++ b/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md @@ -107,4 +107,6 @@ Once a block is registered, you should immediately see that it becomes available A block name must be prefixed with a namespace specific to your plugin. This helps prevent conflicts when more than one plugin registers a block with the same name. In this example, the namespace is `gutenberg-examples`. +Block names _must_ include only lowercase alphanumeric characters or dashes and start with a letter. Example: `my-plugin/my-custom-block`. + The `edit` and `save` functions describe the structure of your block in the context of the editor and the saved content respectively. While the difference is not obvious in this simple example, in the following sections we'll explore how these are used to enable customization of the block in the editor preview. diff --git a/docs/manifest-devhub.json b/docs/manifest-devhub.json index 10b2c9362e8aef..a8d1a369642ee2 100644 --- a/docs/manifest-devhub.json +++ b/docs/manifest-devhub.json @@ -641,6 +641,12 @@ "markdown_source": "../packages/components/src/date-time/README.md", "parent": "components" }, + { + "title": "DimensionControl", + "slug": "dimension-control", + "markdown_source": "../packages/components/src/dimension-control/README.md", + "parent": "components" + }, { "title": "Disabled", "slug": "disabled", @@ -971,6 +977,12 @@ "markdown_source": "../packages/components/src/tree-select/README.md", "parent": "components" }, + { + "title": "VisuallyHidden", + "slug": "visually-hidden", + "markdown_source": "../packages/components/src/visually-hidden/README.md", + "parent": "components" + }, { "title": "Data Module Reference", "slug": "data", @@ -1079,6 +1091,12 @@ "markdown_source": "../packages/babel-preset-default/README.md", "parent": "packages" }, + { + "title": "@wordpress/base-styles", + "slug": "packages-base-styles", + "markdown_source": "../packages/base-styles/README.md", + "parent": "packages" + }, { "title": "@wordpress/blob", "slug": "packages-blob", diff --git a/gutenberg.php b/gutenberg.php index 53333e55831917..9e80dee2f6a1aa 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: 6.6.0 + * Version: 6.8.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/lib/block-directory.php b/lib/block-directory.php new file mode 100644 index 00000000000000..723db66de2b3c5 --- /dev/null +++ b/lib/block-directory.php @@ -0,0 +1,21 @@ + 'core/search', 'social-link.php' => gutenberg_get_registered_social_link_blocks(), 'tag-cloud.php' => 'core/tag-cloud', + 'site-title.php' => 'core/site-title', ); $registry = WP_Block_Type_Registry::get_instance(); diff --git a/lib/client-assets.php b/lib/client-assets.php index 327e2f436897f2..6906d39996a4b1 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -42,6 +42,7 @@ function gutenberg_url( $path ) { * * @since 4.1.0 * + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). * @param string $handle Name of the script. Should be unique. * @param string $src Full URL of the script, or path of the script relative to the WordPress root directory. * @param array $deps Optional. An array of registered script handles this script depends on. Default empty array. @@ -52,10 +53,8 @@ function gutenberg_url( $path ) { * @param bool $in_footer Optional. Whether to enqueue the script before instead of in the . * Default 'false'. */ -function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) { - global $wp_scripts; - - $script = $wp_scripts->query( $handle, 'registered' ); +function gutenberg_override_script( &$scripts, $handle, $src, $deps = array(), $ver = false, $in_footer = false ) { + $script = $scripts->query( $handle, 'registered' ); if ( $script ) { /* * In many ways, this is a reimplementation of `wp_register_script` but @@ -67,6 +66,7 @@ function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false $script->src = $src; $script->deps = $deps; $script->ver = $ver; + $script->args = $in_footer; /* * The script's `group` designation is an indication of whether it is @@ -81,7 +81,7 @@ function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false $script->add_data( 'group', 1 ); } } else { - wp_register_script( $handle, $src, $deps, $ver, $in_footer ); + $scripts->add( $handle, $src, $deps, $ver, $in_footer ); } /* @@ -93,7 +93,7 @@ function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false * See: https://core.trac.wordpress.org/ticket/46089 */ if ( 'wp-i18n' !== $handle && 'wp-polyfill' !== $handle ) { - wp_set_script_translations( $handle, 'default' ); + $scripts->set_translations( $handle, 'default' ); } } @@ -155,6 +155,7 @@ function gutenberg_override_translation_file( $file, $handle ) { * * @since 4.1.0 * + * @param WP_Styles $styles WP_Styles instance (passed by reference). * @param string $handle Name of the stylesheet. Should be unique. * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory. * @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array. @@ -166,18 +167,69 @@ function gutenberg_override_translation_file( $file, $handle ) { * Default 'all'. Accepts media types like 'all', 'print' and 'screen', or media queries like * '(orientation: portrait)' and '(max-width: 640px)'. */ -function gutenberg_override_style( $handle, $src, $deps = array(), $ver = false, $media = 'all' ) { - wp_deregister_style( $handle ); - wp_register_style( $handle, $src, $deps, $ver, $media ); +function gutenberg_override_style( &$styles, $handle, $src, $deps = array(), $ver = false, $media = 'all' ) { + $style = $styles->query( $handle, 'registered' ); + if ( $style ) { + $styles->remove( $handle ); + } + $styles->add( $handle, $src, $deps, $ver, $media ); +} + +/** + * Registers vendor JavaScript files to be used as dependencies of the editor + * and plugins. + * + * This function is called from a script during the plugin build process, so it + * should not call any WordPress PHP functions. + * + * @since 0.1.0 + * + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). + */ +function gutenberg_register_vendor_scripts( &$scripts ) { + $suffix = SCRIPT_DEBUG ? '' : '.min'; + + // Vendor Scripts. + $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; + + // TODO: Overrides for react, react-dom and lodash are necessary + // until WordPress 5.3 is released. + gutenberg_register_vendor_script( + $scripts, + 'react', + 'https://unpkg.com/react@16.9.0/umd/react' . $react_suffix . '.js', + array( 'wp-polyfill' ), + '16.9.0', + true + ); + gutenberg_register_vendor_script( + $scripts, + 'react-dom', + 'https://unpkg.com/react-dom@16.9.0/umd/react-dom' . $react_suffix . '.js', + array( 'react' ), + '16.9.0', + true + ); + gutenberg_register_vendor_script( + $scripts, + 'lodash', + 'https://unpkg.com/lodash@4.17.15/lodash' . $suffix . '.js', + array(), + '4.17.15', + true + ); } +add_action( 'wp_default_scripts', 'gutenberg_register_vendor_scripts' ); /** * Registers all the WordPress packages scripts that are in the standardized * `build/` location. * * @since 4.5.0 + * + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). */ -function gutenberg_register_packages_scripts() { +function gutenberg_register_packages_scripts( &$scripts ) { foreach ( glob( gutenberg_dir_path() . 'build/*/index.js' ) as $path ) { // Prefix `wp-` to package directory to get script handle. // For example, `…/build/a11y/index.js` becomes `wp-a11y`. @@ -206,6 +258,7 @@ function gutenberg_register_packages_scripts() { $gutenberg_path = substr( $path, strlen( gutenberg_dir_path() ) ); gutenberg_override_script( + $scripts, $handle, gutenberg_url( $gutenberg_path ), $dependencies, @@ -214,116 +267,74 @@ function gutenberg_register_packages_scripts() { ); } } +add_action( 'wp_default_scripts', 'gutenberg_register_packages_scripts' ); /** - * Registers common scripts and styles to be used as dependencies of the editor - * and plugins. + * Registers all the WordPress packages styles that are in the standardized + * `build/` location. * - * @since 0.1.0 - */ -function gutenberg_register_scripts_and_styles() { - global $wp_scripts; - - gutenberg_register_vendor_scripts(); - gutenberg_register_packages_scripts(); - - // Add nonce middleware which accounts for the absence of the heartbeat - // listener. This relies on API Fetch implementation running middlewares in - // order of last added, and that the original nonce middleware would defer - // to an X-WP-Nonce header already being present. This inline script should - // be removed once the following Core ticket is resolved in assigning the - // nonce received from heartbeat to the created middleware. - // - // See: https://core.trac.wordpress.org/ticket/46107 . - // See: https://github.com/WordPress/gutenberg/pull/13451 . - if ( isset( $wp_scripts->registered['wp-api-fetch'] ) ) { - $wp_scripts->registered['wp-api-fetch']->deps[] = 'wp-hooks'; - } - wp_add_inline_script( - 'wp-api-fetch', - sprintf( - 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . - 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . - 'wp.apiFetch.nonceEndpoint = "%s";', - ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), - admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) - ), - 'after' - ); - - // TEMPORARY: Core does not (yet) provide persistence migration from the - // introduction of the block editor and still calls the data plugins. - // We unset the existing inline scripts first. - $wp_scripts->registered['wp-data']->extra['after'] = array(); - wp_add_inline_script( - 'wp-data', - implode( - "\n", - array( - '( function() {', - ' var userId = ' . get_current_user_ID() . ';', - ' var storageKey = "WP_DATA_USER_" + userId;', - ' wp.data', - ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', - ' wp.data.plugins.persistence.__unstableMigrate( { storageKey: storageKey } );', - '} )();', - ) - ) - ); + * @since 6.7.0 + * @param WP_Styles $styles WP_Styles instance (passed by reference). + */ +function gutenberg_register_packages_styles( &$styles ) { // Editor Styles. - // This empty stylesheet is defined to ensure backward compatibility. - gutenberg_override_style( 'wp-blocks', false ); - gutenberg_override_style( + $styles, 'wp-block-editor', gutenberg_url( 'build/block-editor/style.css' ), array( 'wp-components', 'wp-editor-font' ), filemtime( gutenberg_dir_path() . 'build/editor/style.css' ) ); - wp_style_add_data( 'wp-block-editor', 'rtl', 'replace' ); + $styles->add_data( 'wp-block-editor', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-editor', gutenberg_url( 'build/editor/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-nux', 'wp-block-directory' ), + array( 'wp-components', 'wp-block-editor', 'wp-nux' ), filemtime( gutenberg_dir_path() . 'build/editor/style.css' ) ); - wp_style_add_data( 'wp-editor', 'rtl', 'replace' ); + $styles->add_data( 'wp-editor', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-edit-post', gutenberg_url( 'build/edit-post/style.css' ), array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-nux' ), filemtime( gutenberg_dir_path() . 'build/edit-post/style.css' ) ); - wp_style_add_data( 'wp-edit-post', 'rtl', 'replace' ); + $styles->add_data( 'wp-edit-post', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-components', gutenberg_url( 'build/components/style.css' ), array(), filemtime( gutenberg_dir_path() . 'build/components/style.css' ) ); - wp_style_add_data( 'wp-components', 'rtl', 'replace' ); + $styles->add_data( 'wp-components', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-block-library', gutenberg_url( 'build/block-library/style.css' ), array(), filemtime( gutenberg_dir_path() . 'build/block-library/style.css' ) ); - wp_style_add_data( 'wp-block-library', 'rtl', 'replace' ); + $styles->add_data( 'wp-block-library', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-format-library', gutenberg_url( 'build/format-library/style.css' ), array( 'wp-block-editor', 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/format-library/style.css' ) ); - wp_style_add_data( 'wp-format-library', 'rtl', 'replace' ); + $styles->add_data( 'wp-format-library', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-edit-blocks', gutenberg_url( 'build/block-library/editor.css' ), array( @@ -335,92 +346,107 @@ function gutenberg_register_scripts_and_styles() { ), filemtime( gutenberg_dir_path() . 'build/block-library/editor.css' ) ); - wp_style_add_data( 'wp-edit-blocks', 'rtl', 'replace' ); + $styles->add_data( 'wp-edit-blocks', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-nux', gutenberg_url( 'build/nux/style.css' ), array( 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/nux/style.css' ) ); - wp_style_add_data( 'wp-nux', 'rtl', 'replace' ); + $styles->add_data( 'wp-nux', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-block-library-theme', gutenberg_url( 'build/block-library/theme.css' ), array(), filemtime( gutenberg_dir_path() . 'build/block-library/theme.css' ) ); - wp_style_add_data( 'wp-block-library-theme', 'rtl', 'replace' ); + $styles->add_data( 'wp-block-library-theme', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-list-reusable-blocks', gutenberg_url( 'build/list-reusable-blocks/style.css' ), array( 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/list-reusable-blocks/style.css' ) ); - wp_style_add_data( 'wp-list-reusable-block', 'rtl', 'replace' ); + $styles->add_data( 'wp-list-reusable-block', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-edit-widgets', gutenberg_url( 'build/edit-widgets/style.css' ), array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks' ), filemtime( gutenberg_dir_path() . 'build/edit-widgets/style.css' ) ); - wp_style_add_data( 'wp-edit-widgets', 'rtl', 'replace' ); + $styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-block-directory', gutenberg_url( 'build/block-directory/style.css' ), - array( 'wp-components' ), + array( 'wp-block-editor', 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/block-directory/style.css' ) ); - wp_style_add_data( 'wp-block-directory', 'rtl', 'replace' ); - - if ( defined( 'GUTENBERG_LIVE_RELOAD' ) && GUTENBERG_LIVE_RELOAD ) { - $live_reload_url = ( GUTENBERG_LIVE_RELOAD === true ) ? 'http://localhost:35729/livereload.js' : GUTENBERG_LIVE_RELOAD; - - wp_enqueue_script( - 'gutenberg-live-reload', - $live_reload_url - ); - } + $styles->add_data( 'wp-block-directory', 'rtl', 'replace' ); } -add_action( 'wp_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 ); -add_action( 'admin_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 ); +add_action( 'wp_default_styles', 'gutenberg_register_packages_styles' ); /** - * Registers vendor JavaScript files to be used as dependencies of the editor + * Registers common scripts and styles to be used as dependencies of the editor * and plugins. * - * This function is called from a script during the plugin build process, so it - * should not call any WordPress PHP functions. - * * @since 0.1.0 */ -function gutenberg_register_vendor_scripts() { - $suffix = SCRIPT_DEBUG ? '' : '.min'; - - // Vendor Scripts. - $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; +function gutenberg_enqueue_block_editor_assets() { + global $wp_scripts; - // TODO: Overrides for react, react-dom and lodash are necessary - // until WordPress 5.3 is released. - gutenberg_register_vendor_script( - 'react', - 'https://unpkg.com/react@16.9.0/umd/react' . $react_suffix . '.js', - array( 'wp-polyfill' ) - ); - gutenberg_register_vendor_script( - 'react-dom', - 'https://unpkg.com/react-dom@16.9.0/umd/react-dom' . $react_suffix . '.js', - array( 'react' ) + wp_add_inline_script( + 'wp-api-fetch', + sprintf( + 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . + 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . + 'wp.apiFetch.nonceEndpoint = "%s";' . + 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', + ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), + admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) + ), + 'after' ); - gutenberg_register_vendor_script( - 'lodash', - 'https://unpkg.com/lodash@4.17.15/lodash' . $suffix . '.js' + + // TEMPORARY: Core does not (yet) provide persistence migration from the + // introduction of the block editor and still calls the data plugins. + // We unset the existing inline scripts first. + $wp_scripts->registered['wp-data']->extra['after'] = array(); + wp_add_inline_script( + 'wp-data', + implode( + "\n", + array( + '( function() {', + ' var userId = ' . get_current_user_ID() . ';', + ' var storageKey = "WP_DATA_USER_" + userId;', + ' wp.data', + ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', + ' wp.data.plugins.persistence.__unstableMigrate( { storageKey: storageKey } );', + '} )();', + ) + ) ); + + if ( defined( 'GUTENBERG_LIVE_RELOAD' ) && GUTENBERG_LIVE_RELOAD ) { + $live_reload_url = ( GUTENBERG_LIVE_RELOAD === true ) ? 'http://localhost:35729/livereload.js' : GUTENBERG_LIVE_RELOAD; + + wp_enqueue_script( + 'gutenberg-live-reload', + $live_reload_url + ); + } } +add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets' ); /** * Retrieves a unique and reasonably short and human-friendly filename for a @@ -458,14 +484,21 @@ function gutenberg_vendor_script_filename( $handle, $src ) { * possible, or downloading it if the cached version is unavailable or * outdated. * - * @param string $handle Name of the script. - * @param string $src Full URL of the external script. - * @param array $deps Optional. An array of registered script handles this - * script depends on. + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). + * @param string $handle Name of the script. + * @param string $src Full URL of the external script. + * @param array $deps Optional. An array of registered script handles this + * script depends on. + * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL + * as a query string for cache busting purposes. If version is set to false, a version + * number is automatically added equal to current installed WordPress version. + * If set to null, no version is added. + * @param bool $in_footer Optional. Whether to enqueue the script before instead of in the . + * Default 'false'. * * @since 0.1.0 */ -function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { +function gutenberg_register_vendor_script( &$scripts, $handle, $src, $deps = array(), $ver = null, $in_footer = false ) { if ( defined( 'GUTENBERG_LOAD_VENDOR_SCRIPTS' ) && ! GUTENBERG_LOAD_VENDOR_SCRIPTS ) { return; } @@ -495,7 +528,7 @@ function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { if ( ! $f ) { // Failed to open the file for writing, probably due to server // permissions. Enqueue the script directly from the URL instead. - gutenberg_override_script( $handle, $src, $deps, null ); + gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer ); return; } fclose( $f ); @@ -508,16 +541,18 @@ function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { // The request failed. If the file is already cached, continue to // use this file. If not, then unlink the 0 byte file, and enqueue // the script directly from the URL. - gutenberg_override_script( $handle, $src, $deps, null ); + gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer ); unlink( $full_path ); return; } } gutenberg_override_script( + $scripts, $handle, gutenberg_url( 'vendor/' . $filename ), $deps, - null + $ver, + $in_footer ); } diff --git a/lib/customizer.php b/lib/customizer.php index 771ced523f5c98..1f27db00ee3085 100644 --- a/lib/customizer.php +++ b/lib/customizer.php @@ -55,7 +55,7 @@ function gutenberg_customize_register( $wp_customize ) { 'sanitize_callback' => 'gutenberg_customize_sanitize', ) ); - if ( get_option( 'gutenberg-experiments' ) && array_key_exists( 'gutenberg-widget-experiments', get_option( 'gutenberg-experiments' ) ) ) { + if ( gutenberg_is_experiment_enabled( 'gutenberg-widget-experiments' ) ) { $wp_customize->add_section( 'gutenberg_widget_blocks', array( 'title' => __( 'Widget Blocks (Experimental)', 'gutenberg' ) ) diff --git a/lib/experiments-page.php b/lib/experiments-page.php index bbc04650a732e3..765e0cc5883d9d 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -130,12 +130,11 @@ function gutenberg_display_experiment_section() { * @return array Filtered editor settings. */ function gutenberg_experiments_editor_settings( $settings ) { - $experiments_exist = get_option( 'gutenberg-experiments' ); $experiments_settings = array( - '__experimentalEnableLegacyWidgetBlock' => $experiments_exist ? array_key_exists( 'gutenberg-widget-experiments', get_option( 'gutenberg-experiments' ) ) : false, - '__experimentalEnableMenuBlock' => $experiments_exist ? array_key_exists( 'gutenberg-menu-block', get_option( 'gutenberg-experiments' ) ) : false, - '__experimentalBlockDirectory' => $experiments_exist ? array_key_exists( 'gutenberg-block-directory', get_option( 'gutenberg-experiments' ) ) : false, - '__experimentalEnableFullSiteEditing' => $experiments_exist ? array_key_exists( 'gutenberg-full-site-editing', get_option( 'gutenberg-experiments' ) ) : false, + '__experimentalEnableLegacyWidgetBlock' => gutenberg_is_experiment_enabled( 'gutenberg-widget-experiments' ), + '__experimentalEnableMenuBlock' => gutenberg_is_experiment_enabled( 'gutenberg-menu-block' ), + '__experimentalBlockDirectory' => gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ), + '__experimentalEnableFullSiteEditing' => gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing' ), ); return array_merge( $settings, $experiments_settings ); diff --git a/lib/load.php b/lib/load.php index a0996f3b94f4ff..58e545b38a6f7a 100644 --- a/lib/load.php +++ b/lib/load.php @@ -9,6 +9,20 @@ die( 'Silence is golden.' ); } +/** + * Checks whether the Gutenberg experiment is enabled. + * + * @since 6.7.0 + * + * @param string $name The name of the experiment. + * + * @return bool True when the experiment is enabled. + */ +function gutenberg_is_experiment_enabled( $name ) { + $experiments = get_option( 'gutenberg-experiments' ); + return ! empty( $experiments[ $name ] ); +} + // These files only need to be loaded if within a rest server instance // which this class will exist if that is the case. if ( class_exists( 'WP_REST_Controller' ) ) { @@ -22,13 +36,12 @@ require dirname( __FILE__ ) . '/class-experimental-wp-widget-blocks-manager.php'; require dirname( __FILE__ ) . '/class-wp-rest-widget-areas-controller.php'; } - /** - * End: Include for phase 2 - */ - if ( ! class_exists( 'WP_REST_Block_Directory_Controller' ) ) { require dirname( __FILE__ ) . '/class-wp-rest-block-directory-controller.php'; } + /** + * End: Include for phase 2 + */ require dirname( __FILE__ ) . '/rest-api.php'; } @@ -41,7 +54,9 @@ require dirname( __FILE__ ) . '/blocks.php'; require dirname( __FILE__ ) . '/templates.php'; +require dirname( __FILE__ ) . '/template-loader.php'; require dirname( __FILE__ ) . '/client-assets.php'; +require dirname( __FILE__ ) . '/block-directory.php'; require dirname( __FILE__ ) . '/demo.php'; require dirname( __FILE__ ) . '/widgets.php'; require dirname( __FILE__ ) . '/widgets-page.php'; diff --git a/lib/rest-api.php b/lib/rest-api.php index 5aa85b6d83e48b..6ad5e6d0e6f0ef 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -85,6 +85,10 @@ function gutenberg_register_rest_widget_areas() { * @since 6.5.0 */ function gutenberg_register_rest_block_directory() { + if ( ! gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ) ) { + return; + } + $block_directory_controller = new WP_REST_Block_Directory_Controller(); $block_directory_controller->register_routes(); } diff --git a/lib/template-canvas.php b/lib/template-canvas.php new file mode 100644 index 00000000000000..a0e0da7ea01752 --- /dev/null +++ b/lib/template-canvas.php @@ -0,0 +1,23 @@ + + +> + + + + + +> + + + + + + + diff --git a/lib/template-loader.php b/lib/template-loader.php new file mode 100644 index 00000000000000..1c6923091ce323 --- /dev/null +++ b/lib/template-loader.php @@ -0,0 +1,177 @@ + 'wp_template', + 'post_status' => 'publish', + 'post_name__in' => $slugs, + 'orderby' => 'post_name__in', + 'posts_per_page' => 1, + ) + ); + + if ( $template_query->have_posts() ) { + $template_posts = $template_query->get_posts(); + $_wp_current_template_post = array_shift( $template_posts ); + } + + // Add extra hooks for template canvas. + add_action( 'wp_head', 'gutenberg_viewport_meta_tag', 0 ); + remove_action( 'wp_head', '_wp_render_title_tag', 1 ); + add_action( 'wp_head', 'gutenberg_render_title_tag', 1 ); + + // This file will be included instead of the theme's template file. + return gutenberg_dir_path() . 'lib/template-canvas.php'; +} + +/** + * Displays title tag with content, regardless of whether theme has title-tag support. + * + * @see _wp_render_title_tag() + */ +function gutenberg_render_title_tag() { + echo '' . wp_get_document_title() . '' . "\n"; +} + +/** + * Renders the markup for the current template. + */ +function gutenberg_render_the_template() { + global $_wp_current_template_post; + global $wp_embed; + + if ( ! $_wp_current_template_post || 'wp_template' !== $_wp_current_template_post->post_type ) { + echo '

' . esc_html__( 'No matching template found', 'gutenberg' ) . '

'; + return; + } + + $content = $_wp_current_template_post->post_content; + + $content = $wp_embed->run_shortcode( $content ); + $content = $wp_embed->autoembed( $content ); + $content = do_blocks( $content ); + $content = wptexturize( $content ); + $content = wp_make_content_images_responsive( $content ); + $content = str_replace( ']]>', ']]>', $content ); + + // Wrap block template in .wp-site-blocks to allow for specific descendant styles + // (e.g. `.wp-site-blocks > *`). + echo '
'; + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput + echo '
'; +} + +/** + * Renders a 'viewport' meta tag. + * + * This is hooked into {@see 'wp_head'} to decouple its output from the default template canvas. + */ +function gutenberg_viewport_meta_tag() { + echo '' . "\n"; +} + +/** + * Strips .php suffix from template file names. + * + * @access private + * + * @param string $template_file Template file name. + * @return string Template file name without extension. + */ +function gutenberg_strip_php_suffix( $template_file ) { + return preg_replace( '/\.php$/', '', $template_file ); +} diff --git a/lib/templates.php b/lib/templates.php index dce2905b0ae52d..3eb4df27e1c0ec 100644 --- a/lib/templates.php +++ b/lib/templates.php @@ -9,28 +9,47 @@ * Registers block editor 'wp_template' post type. */ function gutenberg_register_template_post_type() { - if ( - get_option( 'gutenberg-experiments' ) && - ! array_key_exists( 'gutenberg-full-site-editing', get_option( 'gutenberg-experiments' ) ) - ) { + if ( ! gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing' ) ) { return; } $labels = array( - 'name' => __( 'Templates', 'gutenberg' ), + 'name' => __( 'Templates', 'gutenberg' ), + 'singular_name' => __( 'Template', 'gutenberg' ), + 'menu_name' => _x( 'Templates', 'Admin Menu text', 'gutenberg' ), + 'add_new' => _x( 'Add New', 'Template', 'gutenberg' ), + 'add_new_item' => __( 'Add New Template', 'gutenberg' ), + 'new_item' => __( 'New Template', 'gutenberg' ), + 'edit_item' => __( 'Edit Template', 'gutenberg' ), + 'view_item' => __( 'View Template', 'gutenberg' ), + 'all_items' => __( 'All Templates', 'gutenberg' ), + 'search_items' => __( 'Search Templates', 'gutenberg' ), + 'parent_item_colon' => __( 'Parent Template:', 'gutenberg' ), + 'not_found' => __( 'No templates found.', 'gutenberg' ), + 'not_found_in_trash' => __( 'No templates found in Trash.', 'gutenberg' ), + 'archives' => __( 'Template archives', 'gutenberg' ), + 'insert_into_item' => __( 'Insert into template', 'gutenberg' ), + 'uploaded_to_this_item' => __( 'Uploaded to this template', 'gutenberg' ), + 'filter_items_list' => __( 'Filter templates list', 'gutenberg' ), + 'items_list_navigation' => __( 'Templates list navigation', 'gutenberg' ), + 'items_list' => __( 'Templates list', 'gutenberg' ), ); $args = array( - 'labels' => $labels, - 'description' => __( 'Templates to include in your theme.', 'gutenberg' ), - 'public' => false, - 'has_archive' => false, - 'show_in_rest' => true, - 'rest_base' => 'templates', - 'capability_type' => array( 'template', 'templates' ), - 'map_meta_cap' => true, - 'supports' => array( + 'labels' => $labels, + 'description' => __( 'Templates to include in your theme.', 'gutenberg' ), + 'public' => false, + 'has_archive' => false, + 'show_ui' => true, + 'show_in_menu' => 'themes.php', + 'show_in_admin_bar' => false, + 'show_in_rest' => true, + 'rest_base' => 'templates', + 'capability_type' => array( 'template', 'templates' ), + 'map_meta_cap' => true, + 'supports' => array( 'title', + 'slug', 'editor', 'revisions', ), @@ -65,3 +84,83 @@ function gutenberg_grant_template_caps( array $allcaps ) { return $allcaps; } add_filter( 'user_has_cap', 'gutenberg_grant_template_caps' ); + +/** + * Filters capabilities to prevent deletion of the 'wp_template' post with slug 'index'. + * + * Similar to today's themes, this template should always exist. + * + * @param array $caps Array of the user's capabilities. + * @param string $cap Capability name. + * @param int $user_id The user ID. + * @param array $args Adds the context to the cap. Typically the object ID. + * @return array Filtered $caps. + */ +function gutenberg_prevent_index_template_deletion( $caps, $cap, $user_id, $args ) { + if ( 'delete_post' !== $cap || ! isset( $args[0] ) ) { + return $caps; + } + + $post = get_post( $args[0] ); + if ( ! $post || 'wp_template' !== $post->post_type ) { + return $caps; + } + + if ( 'index' === $post->post_name ) { + $caps[] = 'do_not_allow'; + } + + return $caps; +} +add_filter( 'map_meta_cap', 'gutenberg_prevent_index_template_deletion', 10, 4 ); + +/** + * Fixes the label of the 'wp_template' admin menu entry. + */ +function gutenberg_fix_template_admin_menu_entry() { + global $submenu; + if ( ! isset( $submenu['themes.php'] ) ) { + return; + } + $post_type = get_post_type_object( 'wp_template' ); + if ( ! $post_type ) { + return; + } + foreach ( $submenu['themes.php'] as $key => $submenu_entry ) { + if ( $post_type->labels->all_items === $submenu['themes.php'][ $key ][0] ) { + $submenu['themes.php'][ $key ][0] = $post_type->labels->menu_name; // phpcs:ignore WordPress.WP.GlobalVariablesOverride + break; + } + } +} +add_action( 'admin_menu', 'gutenberg_fix_template_admin_menu_entry' ); + +/** + * Filters the 'wp_template' post type columns in the admin list table. + * + * @param array $columns Columns to display. + * @return array Filtered $columns. + */ +function gutenberg_filter_template_list_table_columns( array $columns ) { + $columns['slug'] = __( 'Slug', 'gutenberg' ); + if ( isset( $columns['date'] ) ) { + unset( $columns['date'] ); + } + return $columns; +} +add_filter( 'manage_wp_template_posts_columns', 'gutenberg_filter_template_list_table_columns' ); + +/** + * Renders column content for the 'wp_template' post type list table. + * + * @param string $column_name Column name to render. + * @param int $post_id Post ID. + */ +function gutenberg_render_template_list_table_column( $column_name, $post_id ) { + if ( 'slug' !== $column_name ) { + return; + } + $post = get_post( $post_id ); + echo esc_html( $post->post_name ); +} +add_action( 'manage_wp_template_posts_custom_column', 'gutenberg_render_template_list_table_column', 10, 2 ); diff --git a/package-lock.json b/package-lock.json index eca7bdfbb2a7ef..e5e1f5810d7b10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.6.0", + "version": "6.8.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -383,12 +383,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -430,32 +430,32 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -986,15 +986,6 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.4.tgz", - "integrity": "sha512-Ki+Y9nXBlKfhD+LXaRS7v95TtTGYRAf9Y1rTDiE75zf8YQz4GDaWRXosMfJBXxnk88mGFjWdCRIeqDbon7spYA==", - "dev": true, - "requires": { - "regexp-tree": "^0.1.0" - } - }, "@babel/plugin-transform-new-target": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", @@ -1044,9 +1035,9 @@ } }, "@babel/plugin-transform-react-constant-elements": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.6.0.tgz", - "integrity": "sha512-np/nPuII8DHOZWB3u8u+NSeKlEz0eBrOlnVksIQog4C9NGVzXO+NLxMcXn4Eu4GMFzOw2W6Tyo6L3+Wv8z9Y5w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.6.3.tgz", + "integrity": "sha512-1/YogSSU7Tby9rq2VCmhuRg+6pxsHy2rI7w/oo8RKoBt6uBUFG+mk6x13kK+FY1/ggN92HAfg7ADd1v1+NCOKg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", @@ -1325,9 +1316,9 @@ } }, "@babel/preset-react": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", - "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.6.3.tgz", + "integrity": "sha512-07yQhmkZmRAfwREYIQgW0HEwMY9GBJVuPY4Q12UC72AbfaawuupVWa8zQs2tlL+yun45Nv/1KreII/0PLfEsgA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1357,12 +1348,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -1404,15 +1395,15 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/plugin-transform-typescript": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz", - "integrity": "sha512-yzw7EopOOr6saONZ3KA3lpizKnWRTe+rfBqg4AmQbSow7ik7fqmzrfIqt053osLwLE2AaTqGinLM2tl6+M/uog==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz", + "integrity": "sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.6.0", @@ -1421,26 +1412,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -1895,9 +1886,9 @@ } }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "ssri": { @@ -1936,25 +1927,27 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "@evocateur/pacote": { - "version": "9.6.3", - "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.3.tgz", - "integrity": "sha512-ExqNqcbdHQprEgKnY/uQz7WRtyHRbQxRl4JnVkSkmtF8qffRrF9K+piZKNLNSkRMOT/3H0e3IP44QVCHaXMWOQ==", + "version": "9.6.5", + "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.5.tgz", + "integrity": "sha512-EI552lf0aG2nOV8NnZpTxNo2PcXKPmDbF9K8eCBFQdIZwHNGN/mi815fxtmUMa2wTa1yndotICIDt/V0vpEx2w==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", "bluebird": "^3.5.3", - "cacache": "^12.0.0", + "cacache": "^12.0.3", + "chownr": "^1.1.2", "figgy-pudding": "^3.5.1", "get-stream": "^4.1.0", "glob": "^7.1.4", + "infer-owner": "^1.0.4", "lru-cache": "^5.1.1", "make-fetch-happen": "^5.0.0", "minimatch": "^3.0.4", @@ -1964,7 +1957,7 @@ "normalize-package-data": "^2.5.0", "npm-package-arg": "^6.1.0", "npm-packlist": "^1.4.4", - "npm-pick-manifest": "^2.2.3", + "npm-pick-manifest": "^3.0.0", "osenv": "^0.1.5", "promise-inflight": "^1.0.1", "promise-retry": "^1.1.1", @@ -1979,15 +1972,15 @@ }, "dependencies": { "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", "dev": true }, "cacache": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", - "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", "dev": true, "requires": { "bluebird": "^3.5.5", @@ -2008,9 +2001,9 @@ } }, "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "get-stream": { @@ -2023,9 +2016,9 @@ } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2037,9 +2030,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "lru-cache": { @@ -2107,9 +2100,9 @@ } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" @@ -2122,9 +2115,9 @@ "dev": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "ssri": { @@ -2137,18 +2130,30 @@ } }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } } }, "unique-filename": { @@ -2167,9 +2172,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } @@ -2227,6 +2232,12 @@ "integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==", "dev": true }, + "@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", + "dev": true + }, "@jest/console": { "version": "24.7.1", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", @@ -2482,15 +2493,15 @@ } }, "@lerna/add": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.16.2.tgz", - "integrity": "sha512-RAAaF8aODPogj2Ge9Wj3uxPFIBGpog9M+HwSuq03ZnkkO831AmasCTJDqV+GEpl1U2DvnhZQEwHpWmTT0uUeEw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.18.0.tgz", + "integrity": "sha512-Z5EaQbBnJn1LEPb0zb0Q2o9T8F8zOnlCsj6JYpY6aSke17UUT7xx0QMN98iBK+ueUHKjN/vdFdYlNCYRSIdujA==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", - "@lerna/bootstrap": "3.16.2", - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", + "@lerna/bootstrap": "3.18.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", "@lerna/npm-conf": "3.16.0", "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", @@ -2513,34 +2524,23 @@ } } }, - "@lerna/batch-packages": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.16.0.tgz", - "integrity": "sha512-7AdMkANpubY/FKFI01im01tlx6ygOBJ/0JcixMUWoWP/7Ds3SWQF22ID6fbBr38jUWptYLDs2fagtTDL7YUPuA==", - "dev": true, - "requires": { - "@lerna/package-graph": "3.16.0", - "npmlog": "^4.1.2" - } - }, "@lerna/bootstrap": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.16.2.tgz", - "integrity": "sha512-I+gs7eh6rv9Vyd+CwqL7sftRfOOsSzCle8cv/CGlMN7/p7EAVhxEdAw8SYoHIKHzipXszuqqy1Y3opyleD0qdA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.18.0.tgz", + "integrity": "sha512-3DZKWIaKvr7sUImoKqSz6eqn84SsOVMnA5QHwgzXiQjoeZ/5cg9x2r+Xj3+3w/lvLoh0j8U2GNtrIaPNis4bKQ==", "dev": true, "requires": { - "@lerna/batch-packages": "3.16.0", - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/has-npm-version": "3.16.0", - "@lerna/npm-install": "3.16.0", - "@lerna/package-graph": "3.16.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/has-npm-version": "3.16.5", + "@lerna/npm-install": "3.16.5", + "@lerna/package-graph": "3.18.0", "@lerna/pulse-till-done": "3.13.0", - "@lerna/rimraf-dir": "3.14.2", + "@lerna/rimraf-dir": "3.16.5", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-parallel-batches": "3.16.0", - "@lerna/symlink-binary": "3.16.2", - "@lerna/symlink-dependencies": "3.16.2", + "@lerna/run-topologically": "3.18.0", + "@lerna/symlink-binary": "3.17.0", + "@lerna/symlink-dependencies": "3.17.0", "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", "get-port": "^4.2.0", @@ -2576,33 +2576,33 @@ } }, "@lerna/changed": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.16.4.tgz", - "integrity": "sha512-NCD7XkK744T23iW0wqKEgF4R9MYmReUbyHCZKopFnsNpQdqumc3SOIvQUAkKCP6hQJmYvxvOieoVgy/CVDpZ5g==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.18.2.tgz", + "integrity": "sha512-xVnFuj4A6Avxem+8R+KOuKDxfnxp1S5tM5nwsh7n3IhCN5Ga7YINV/JgPhrwgcpqPCVBvAowkilghT/I0r6wUw==", "dev": true, "requires": { - "@lerna/collect-updates": "3.16.0", - "@lerna/command": "3.16.0", - "@lerna/listable": "3.16.0", + "@lerna/collect-updates": "3.18.0", + "@lerna/command": "3.18.0", + "@lerna/listable": "3.18.0", "@lerna/output": "3.13.0", - "@lerna/version": "3.16.4" + "@lerna/version": "3.18.2" } }, "@lerna/check-working-tree": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.14.2.tgz", - "integrity": "sha512-7safqxM/MYoAoxZxulUDtIJIbnBIgo0PB/FHytueG+9VaX7GMnDte2Bt1EKa0dz2sAyQdmQ3Q8ZXpf/6JDjaeg==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.16.5.tgz", + "integrity": "sha512-xWjVBcuhvB8+UmCSb5tKVLB5OuzSpw96WEhS2uz6hkWVa/Euh1A0/HJwn2cemyK47wUrCQXtczBUiqnq9yX5VQ==", "dev": true, "requires": { - "@lerna/collect-uncommitted": "3.14.2", - "@lerna/describe-ref": "3.14.2", + "@lerna/collect-uncommitted": "3.16.5", + "@lerna/describe-ref": "3.16.5", "@lerna/validation-error": "3.13.0" } }, "@lerna/child-process": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.14.2.tgz", - "integrity": "sha512-xnq+W5yQb6RkwI0p16ZQnrn6HkloH/MWTw4lGE1nKsBLAUbmSU5oTE93W1nrG0X3IMF/xWc9UYvNdUGMWvZZ4w==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.16.5.tgz", + "integrity": "sha512-vdcI7mzei9ERRV4oO8Y1LHBZ3A5+ampRKg1wq5nutLsUA4mEBN6H7JqjWOMY9xZemv6+kATm2ofjJ3lW5TszQg==", "dev": true, "requires": { "chalk": "^2.3.1", @@ -2658,24 +2658,24 @@ } }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "@lerna/clean": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.16.0.tgz", - "integrity": "sha512-5P9U5Y19WmYZr7UAMGXBpY7xCRdlR7zhHy8MAPDKVx70rFIBS6nWXn5n7Kntv74g7Lm1gJ2rsiH5tj1OPcRJgg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.18.0.tgz", + "integrity": "sha512-BiwBELZNkarRQqj+v5NPB1aIzsOX+Y5jkZ9a5UbwHzEdBUQ5lQa0qaMLSOve/fSkaiZQxe6qnTyatN75lOcDMg==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", - "@lerna/rimraf-dir": "3.14.2", + "@lerna/rimraf-dir": "3.16.5", "p-map": "^2.1.0", "p-map-series": "^1.0.0", "p-waterfall": "^1.0.0" @@ -2690,23 +2690,214 @@ } }, "@lerna/cli": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.13.0.tgz", - "integrity": "sha512-HgFGlyCZbYaYrjOr3w/EsY18PdvtsTmDfpUQe8HwDjXlPeCCUgliZjXLOVBxSjiOvPeOSwvopwIHKWQmYbwywg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.18.0.tgz", + "integrity": "sha512-AwDyfGx7fxJgeaZllEuyJ9LZ6Tdv9yqRD9RX762yCJu+PCAFvB9bp6OYuRSGli7QQgM0CuOYnSg4xVNOmuGKDA==", "dev": true, "requires": { "@lerna/global-options": "3.13.0", "dedent": "^0.7.0", "npmlog": "^4.1.2", - "yargs": "^12.0.1" + "yargs": "^14.2.0" }, "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.0.tgz", + "integrity": "sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.0" + } + }, + "yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "@lerna/collect-uncommitted": { + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.16.5.tgz", + "integrity": "sha512-ZgqnGwpDZiWyzIQVZtQaj9tRizsL4dUOhuOStWgTAw1EMe47cvAY2kL709DzxFhjr6JpJSjXV5rZEAeU3VE0Hg==", + "dev": true, + "requires": { + "@lerna/child-process": "3.16.5", + "chalk": "^2.3.1", + "figgy-pudding": "^3.5.1", + "npmlog": "^4.1.2" + } + }, + "@lerna/collect-updates": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.18.0.tgz", + "integrity": "sha512-LJMKgWsE/var1RSvpKDIxS8eJ7POADEc0HM3FQiTpEczhP6aZfv9x3wlDjaHpZm9MxJyQilqxZcasRANmRcNgw==", + "dev": true, + "requires": { + "@lerna/child-process": "3.16.5", + "@lerna/describe-ref": "3.16.5", + "minimatch": "^3.0.4", + "npmlog": "^4.1.2", + "slash": "^2.0.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, + "@lerna/command": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.18.0.tgz", + "integrity": "sha512-JQ0TGzuZc9Ky8xtwtSLywuvmkU8X62NTUT3rMNrUykIkOxBaO+tE0O98u2yo/9BYOeTRji9IsjKZEl5i9Qt0xQ==", + "dev": true, + "requires": { + "@lerna/child-process": "3.16.5", + "@lerna/package-graph": "3.18.0", + "@lerna/project": "3.18.0", + "@lerna/validation-error": "3.13.0", + "@lerna/write-log-file": "3.13.0", + "dedent": "^0.7.0", + "execa": "^1.0.0", + "is-ci": "^2.0.0", + "lodash": "^4.17.14", + "npmlog": "^4.1.2" + }, + "dependencies": { "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2735,15 +2926,6 @@ "strip-eof": "^1.0.0" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -2753,89 +2935,6 @@ "pump": "^3.0.0" } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -2847,160 +2946,9 @@ } }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "@lerna/collect-uncommitted": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.14.2.tgz", - "integrity": "sha512-4EkQu4jIOdNL2BMzy/N0ydHB8+Z6syu6xiiKXOoFl0WoWU9H1jEJCX4TH7CmVxXL1+jcs8FIS2pfQz4oew99Eg==", - "dev": true, - "requires": { - "@lerna/child-process": "3.14.2", - "chalk": "^2.3.1", - "figgy-pudding": "^3.5.1", - "npmlog": "^4.1.2" - } - }, - "@lerna/collect-updates": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.16.0.tgz", - "integrity": "sha512-HwAIl815X2TNlmcp28zCrSdXfoZWNP7GJPEqNWYk7xDJTYLqQ+SrmKUePjb3AMGBwYAraZSEJLbHdBpJ5+cHmQ==", - "dev": true, - "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/describe-ref": "3.14.2", - "minimatch": "^3.0.4", - "npmlog": "^4.1.2", - "slash": "^2.0.0" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - } - } - }, - "@lerna/command": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.16.0.tgz", - "integrity": "sha512-u7tE4GC4/gfbPA9eQg+0ulnoJ+PMoMqomx033r/IxqZrHtmJR9+pF/37S0fsxJ2hX/RMFPC7c9Q/i8NEufSpdQ==", - "dev": true, - "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/package-graph": "3.16.0", - "@lerna/project": "3.16.0", - "@lerna/validation-error": "3.13.0", - "@lerna/write-log-file": "3.13.0", - "dedent": "^0.7.0", - "execa": "^1.0.0", - "is-ci": "^2.0.0", - "lodash": "^4.17.14", - "npmlog": "^4.1.2" - }, - "dependencies": { - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -3045,9 +2993,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "pify": { @@ -3075,14 +3023,14 @@ } }, "@lerna/create": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.16.0.tgz", - "integrity": "sha512-OZApR1Iz7awutbmj4sAArwhqCyKgcrnw9rH0aWAUrkYWrD1w4TwkvAcYAsfx5GpQGbLQwoXhoyyPwPfZRRWz3Q==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.18.0.tgz", + "integrity": "sha512-y9oS7ND5T13c+cCTJHa2Y9in02ppzyjsNynVWFuS40eIzZ3z058d9+3qSBt1nkbbQlVyfLoP6+bZPsjyzap5ig==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "@lerna/npm-conf": "3.16.0", "@lerna/validation-error": "3.13.0", "camelcase": "^5.0.0", @@ -3118,9 +3066,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "pify": { @@ -3142,9 +3090,9 @@ "dev": true }, "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -3177,45 +3125,45 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } }, "@lerna/describe-ref": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.14.2.tgz", - "integrity": "sha512-qa5pzDRK2oBQXNjyRmRnN7E8a78NMYfQjjlRFB0KNHMsT6mCiL9+8kIS39sSE2NqT8p7xVNo2r2KAS8R/m3CoQ==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.16.5.tgz", + "integrity": "sha512-c01+4gUF0saOOtDBzbLMFOTJDHTKbDFNErEY6q6i9QaXuzy9LNN62z+Hw4acAAZuJQhrVWncVathcmkkjvSVGw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "npmlog": "^4.1.2" } }, "@lerna/diff": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.16.0.tgz", - "integrity": "sha512-QUpVs5TPl8vBIne10/vyjUxanQBQQp7Lk3iaB8MnCysKr0O+oy7trWeFVDPEkBTCD177By7yPGyW5Yey1nCBbA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.18.0.tgz", + "integrity": "sha512-3iLNlpurc2nV9k22w8ini2Zjm2UPo3xtQgWyqdA6eJjvge0+5AlNAWfPoV6cV+Hc1xDbJD2YDSFpZPJ1ZGilRw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "@lerna/validation-error": "3.13.0", "npmlog": "^4.1.2" } }, "@lerna/exec": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.16.0.tgz", - "integrity": "sha512-mH3O5NXf/O88jBaBBTUf+d56CUkxpg782s3Jxy7HWbVuSUULt3iMRPTh+zEXO5/555etsIVVDDyUR76meklrJA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.18.0.tgz", + "integrity": "sha512-hwkuzg1+38+pbzdZPhGtLIYJ59z498/BCNzR8d4/nfMYm8lFbw9RgJJajLcdbuJ9LJ08cZ93hf8OlzetL84TYg==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/run-topologically": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/run-topologically": "3.18.0", "@lerna/validation-error": "3.13.0", "p-map": "^2.1.0" }, @@ -3229,20 +3177,22 @@ } }, "@lerna/filter-options": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.16.0.tgz", - "integrity": "sha512-InIi1fF8+PxpCwir9bIy+pGxrdE6hvN0enIs1eNGCVS1TTE8osNgiZXa838bMQ1yaEccdcnVX6Z03BNKd56kNg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.18.0.tgz", + "integrity": "sha512-UGVcixs3TGzD8XSmFSbwUVVQnAjaZ6Rmt8Vuq2RcR98ULkGB1LiGNMY89XaNBhaaA8vx7yQWiLmJi2AfmD63Qg==", "dev": true, "requires": { - "@lerna/collect-updates": "3.16.0", - "@lerna/filter-packages": "3.16.0", - "dedent": "^0.7.0" + "@lerna/collect-updates": "3.18.0", + "@lerna/filter-packages": "3.18.0", + "dedent": "^0.7.0", + "figgy-pudding": "^3.5.1", + "npmlog": "^4.1.2" } }, "@lerna/filter-packages": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.16.0.tgz", - "integrity": "sha512-eGFzQTx0ogkGDCnbTuXqssryR6ilp8+dcXt6B+aq1MaqL/vOJRZyqMm4TY3CUOUnzZCi9S2WWyMw3PnAJOF+kg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.18.0.tgz", + "integrity": "sha512-6/0pMM04bCHNATIOkouuYmPg6KH3VkPCIgTfQmdkPJTullERyEQfNUKikrefjxo1vHOoCACDpy65JYyKiAbdwQ==", "dev": true, "requires": { "@lerna/validation-error": "3.13.0", @@ -3271,9 +3221,9 @@ }, "dependencies": { "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "fs-extra": { @@ -3288,11 +3238,21 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -3303,14 +3263,14 @@ } }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -3318,20 +3278,20 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "@lerna/github-client": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.16.0.tgz", - "integrity": "sha512-IVJjcKjkYaUEPJsDyAblHGEFFNKCRyMagbIDm14L7Ab94ccN6i4TKOqAFEJn2SJHYvKKBdp3Zj2zNlASOMe3DA==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.16.5.tgz", + "integrity": "sha512-rHQdn8Dv/CJrO3VouOP66zAcJzrHsm+wFuZ4uGAai2At2NkgKH+tpNhQy2H1PSC0Ezj9LxvdaHYrUzULqVK5Hw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "@octokit/plugin-enterprise-rest": "^3.6.1", "@octokit/rest": "^16.28.4", "git-url-parse": "^11.1.2", @@ -3339,9 +3299,9 @@ }, "dependencies": { "@octokit/request": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.0.2.tgz", - "integrity": "sha512-z1BQr43g4kOL4ZrIVBMHwi68Yg9VbkRUyuAgqCp1rU3vbYa69+2gIld/+gHclw15bJWQnhqqyEb7h5a5EqgZ0A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.2.1.tgz", + "integrity": "sha512-onjQo4QKyiMAqLM6j3eH8vWw1LEfNCpoZUl6a+TrZVJM1wysBC8F0GhK9K/Vc9UsScSmVs2bstOVD34xpQ2wqQ==", "dev": true, "requires": { "@octokit/endpoint": "^5.1.0", @@ -3350,16 +3310,16 @@ "is-plain-object": "^3.0.0", "node-fetch": "^2.3.0", "once": "^1.4.0", - "universal-user-agent": "^3.0.0" + "universal-user-agent": "^4.0.0" } }, "@octokit/rest": { - "version": "16.28.7", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.7.tgz", - "integrity": "sha512-cznFSLEhh22XD3XeqJw51OLSfyL2fcFKUO+v2Ep9MTAFfFLS1cK1Zwd1yEgQJmJoDnj4/vv3+fGGZweG+xsbIA==", + "version": "16.33.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.33.1.tgz", + "integrity": "sha512-lOQ+fJZwkeJ/1PRTdnY1uNja01aKOMioRhQfZtei64gZMXIX3EAfF4koMQMvoLFwsnVBu3ifj1JW1WAAKdXcnA==", "dev": true, "requires": { - "@octokit/request": "^5.0.0", + "@octokit/request": "^5.2.0", "@octokit/request-error": "^1.0.2", "atob-lite": "^2.0.0", "before-after-hook": "^2.0.0", @@ -3370,8 +3330,7 @@ "lodash.uniq": "^4.5.0", "octokit-pagination-methods": "^1.1.0", "once": "^1.4.0", - "universal-user-agent": "^3.0.0", - "url-template": "^2.0.8" + "universal-user-agent": "^4.0.0" } }, "before-after-hook": { @@ -3402,12 +3361,12 @@ "dev": true }, "universal-user-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz", - "integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", + "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", "dev": true, "requires": { - "os-name": "^3.0.0" + "os-name": "^3.1.0" } } } @@ -3430,9 +3389,9 @@ "dev": true }, "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -3449,12 +3408,12 @@ "dev": true }, "@lerna/has-npm-version": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.0.tgz", - "integrity": "sha512-TIY036dA9J8OyTrZq9J+it2DVKifL65k7hK8HhkUPpitJkw6jwbMObA/8D40LOGgWNPweJWqmlrTbRSwsR7DrQ==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.5.tgz", + "integrity": "sha512-WL7LycR9bkftyqbYop5rEGJ9sRFIV55tSGmbN1HLrF9idwOCD7CLrT64t235t3t4O5gehDnwKI5h2U3oxTrF8Q==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "semver": "^6.2.0" }, "dependencies": { @@ -3467,13 +3426,13 @@ } }, "@lerna/import": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.16.0.tgz", - "integrity": "sha512-trsOmGHzw0rL/f8BLNvd+9PjoTkXq2Dt4/V2UCha254hMQaYutbxcYu8iKPxz9x86jSPlH7FpbTkkHXDsoY7Yg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.18.0.tgz", + "integrity": "sha512-2pYIkkBTZsEdccfc+dPsKZeSw3tBzKSyl0b2lGrfmNX2Y41qqOzsJCyI1WO1uvEIP8aOaLy4hPpqRIBe4ee7hw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", "@lerna/validation-error": "3.13.0", @@ -3494,21 +3453,21 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } }, "@lerna/init": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.16.0.tgz", - "integrity": "sha512-Ybol/x5xMtBgokx4j7/Y3u0ZmNh0NiSWzBFVaOs2NOJKvuqrWimF67DKVz7yYtTYEjtaMdug64ohFF4jcT/iag==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.18.0.tgz", + "integrity": "sha512-/vHpmXkMlSaJaq25v5K13mcs/2L7E32O6dSsEkHaZCDRiV2BOqsZng9jjbE/4ynfsWfLLlU9ZcydwG72C3I+mQ==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "fs-extra": "^8.1.0", "p-map": "^2.1.0", "write-json-file": "^3.2.0" @@ -3526,9 +3485,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -3540,14 +3499,14 @@ } }, "@lerna/link": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.16.2.tgz", - "integrity": "sha512-eCPg5Lo8HT525fIivNoYF3vWghO3UgEVFdbsiPmhzwI7IQyZro5HWYzLtywSAdEog5XZpd2Bbn0CsoHWBB3gww==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.18.0.tgz", + "integrity": "sha512-FbbIpH0EpsC+dpAbvxCoF3cn7F1MAyJjEa5Lh3XkDGATOlinMFuKCbmX0NLpOPQZ5zghvrui97cx+jz5F2IlHw==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/package-graph": "3.16.0", - "@lerna/symlink-dependencies": "3.16.2", + "@lerna/command": "3.18.0", + "@lerna/package-graph": "3.18.0", + "@lerna/symlink-dependencies": "3.17.0", "p-map": "^2.1.0", "slash": "^2.0.0" }, @@ -3567,24 +3526,24 @@ } }, "@lerna/list": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.16.0.tgz", - "integrity": "sha512-TkvstoPsgKqqQ0KfRumpsdMXfRSEhdXqOLq519XyI5IRWYxhoqXqfi8gG37UoBPhBNoe64japn5OjphF3rOmQA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.18.0.tgz", + "integrity": "sha512-mpB7Q6T+n2CaiPFz0LuOE+rXphDfHm0mKIwShnyS/XDcii8jXv+z9Iytj8p3rfCH2I1L80j2qL6jWzyGy/uzKA==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/listable": "3.16.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/listable": "3.18.0", "@lerna/output": "3.13.0" } }, "@lerna/listable": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.16.0.tgz", - "integrity": "sha512-mtdAT2EEECqrJSDm/aXlOUFr1MRE4p6hppzY//Klp05CogQy6uGaKk+iKG5yyCLaOXFFZvG4HfO11CmoGSDWzw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.18.0.tgz", + "integrity": "sha512-9gLGKYNLSKeurD+sJ2RA+nz4Ftulr91U127gefz0RlmAPpYSjwcJkxwa0UfJvpQTXv9C7yzHLnn0BjyAQRjuew==", "dev": true, "requires": { - "@lerna/query-graph": "3.16.0", + "@lerna/query-graph": "3.18.0", "chalk": "^2.3.1", "columnify": "^1.5.4" } @@ -3620,9 +3579,9 @@ } }, "@lerna/npm-dist-tag": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.16.0.tgz", - "integrity": "sha512-MQrBkqJJB9+eNphuj9w90QPMOs4NQXMuSRk9NqzeFunOmdDopPCV0Q7IThSxEuWnhJ2n3B7G0vWUP7tNMPdqIQ==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.18.1.tgz", + "integrity": "sha512-vWkZh2T/O9OjPLDrba0BTWO7ug/C3sCwjw7Qyk1aEbxMBXB/eEJPqirwJTWT+EtRJQYB01ky3K8ZFOhElVyjLw==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3633,12 +3592,12 @@ } }, "@lerna/npm-install": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.0.tgz", - "integrity": "sha512-APUOIilZCzDzce92uLEwzt1r7AEMKT/hWA1ThGJL+PO9Rn8A95Km3o2XZAYG4W0hR+P4O2nSVuKbsjQtz8CjFQ==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.5.tgz", + "integrity": "sha512-hfiKk8Eku6rB9uApqsalHHTHY+mOrrHeWEs+gtg7+meQZMTS3kzv4oVp5cBZigndQr3knTLjwthT/FX4KvseFg==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "@lerna/get-npm-exec-opts": "3.13.0", "fs-extra": "^8.1.0", "npm-package-arg": "^6.1.0", @@ -3659,9 +3618,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } @@ -3695,9 +3654,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "pify": { @@ -3709,12 +3668,12 @@ } }, "@lerna/npm-run-script": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.14.2.tgz", - "integrity": "sha512-LbVFv+nvAoRTYLMrJlJ8RiakHXrLslL7Jp/m1R18vYrB8LYWA3ey+nz5Tel2OELzmjUiemAKZsD9h6i+Re5egg==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.16.5.tgz", + "integrity": "sha512-1asRi+LjmVn3pMjEdpqKJZFT/3ZNpb+VVeJMwrJaV/3DivdNg7XlPK9LTrORuKU4PSvhdEZvJmSlxCKyDpiXsQ==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "@lerna/get-npm-exec-opts": "3.13.0", "npmlog": "^4.1.2" } @@ -3755,20 +3714,30 @@ }, "dependencies": { "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -3776,9 +3745,9 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } @@ -3795,9 +3764,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "load-json-file": { @@ -3838,9 +3807,9 @@ } }, "@lerna/package-graph": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.16.0.tgz", - "integrity": "sha512-A2mum/gNbv7zCtAwJqoxzqv89As73OQNK2MgSX1SHWya46qoxO9a9Z2c5lOFQ8UFN5ZxqWMfFYXRCz7qzwmFXw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.18.0.tgz", + "integrity": "sha512-BLYDHO5ihPh20i3zoXfLZ5ZWDCrPuGANgVhl7k5pCmRj90LCvT+C7V3zrw70fErGAfvkcYepMqxD+oBrAYwquQ==", "dev": true, "requires": { "@lerna/prerelease-id-from-version": "3.16.0", @@ -3876,9 +3845,9 @@ } }, "@lerna/project": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.16.0.tgz", - "integrity": "sha512-NrKcKK1EqXqhrGvslz6Q36+ZHuK3zlDhGdghRqnxDcHxMPT01NgLcmsnymmQ+gjMljuLRmvKYYCuHrknzX8VrA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.18.0.tgz", + "integrity": "sha512-+LDwvdAp0BurOAWmeHE3uuticsq9hNxBI0+FMHiIai8jrygpJGahaQrBYWpwbshbQyVLeQgx3+YJdW2TbEdFWA==", "dev": true, "requires": { "@lerna/package": "3.16.0", @@ -3908,18 +3877,18 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "import-fresh": { @@ -4009,22 +3978,22 @@ } }, "@lerna/publish": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.16.4.tgz", - "integrity": "sha512-XZY+gRuF7/v6PDQwl7lvZaGWs8CnX6WIPIu+OCcyFPSL/rdWegdN7HieKBHskgX798qRQc2GrveaY7bNoTKXAw==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.18.2.tgz", + "integrity": "sha512-lLQOjoaFv/gc9HtOCMRsOK6NIub8eHnnvmQARjXY/HayA8GuLaD2Px9xOu1L7il+Q0LlMU3wASB9Khy/CiHJUQ==", "dev": true, "requires": { "@evocateur/libnpmaccess": "^3.1.2", "@evocateur/npm-registry-fetch": "^4.0.0", "@evocateur/pacote": "^9.6.3", - "@lerna/check-working-tree": "3.14.2", - "@lerna/child-process": "3.14.2", - "@lerna/collect-updates": "3.16.0", - "@lerna/command": "3.16.0", - "@lerna/describe-ref": "3.14.2", + "@lerna/check-working-tree": "3.16.5", + "@lerna/child-process": "3.16.5", + "@lerna/collect-updates": "3.18.0", + "@lerna/command": "3.18.0", + "@lerna/describe-ref": "3.16.5", "@lerna/log-packed": "3.16.0", "@lerna/npm-conf": "3.16.0", - "@lerna/npm-dist-tag": "3.16.0", + "@lerna/npm-dist-tag": "3.18.1", "@lerna/npm-publish": "3.16.2", "@lerna/otplease": "3.16.0", "@lerna/output": "3.13.0", @@ -4033,9 +4002,9 @@ "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-topologically": "3.16.0", + "@lerna/run-topologically": "3.18.0", "@lerna/validation-error": "3.13.0", - "@lerna/version": "3.16.4", + "@lerna/version": "3.18.2", "figgy-pudding": "^3.5.1", "fs-extra": "^8.1.0", "npm-package-arg": "^6.1.0", @@ -4058,9 +4027,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -4087,12 +4056,12 @@ } }, "@lerna/query-graph": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.16.0.tgz", - "integrity": "sha512-p0RO+xmHDO95ChJdWkcy9TNLysLkoDARXeRHzY5U54VCwl3Ot/2q8fMCVlA5UeGXDutEyyByl3URqEpcQCWI7Q==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.18.0.tgz", + "integrity": "sha512-fgUhLx6V0jDuKZaKj562jkuuhrfVcjl5sscdfttJ8dXNVADfDz76nzzwLY0ZU7/0m69jDedohn5Fx5p7hDEVEg==", "dev": true, "requires": { - "@lerna/package-graph": "3.16.0", + "@lerna/package-graph": "3.18.0", "figgy-pudding": "^3.5.1" } }, @@ -4119,36 +4088,36 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } }, "@lerna/rimraf-dir": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.14.2.tgz", - "integrity": "sha512-eFNkZsy44Bu9v1Hrj5Zk6omzg8O9h/7W6QYK1TTUHeyrjTEwytaNQlqF0lrTLmEvq55sviV42NC/8P3M2cvq8Q==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.16.5.tgz", + "integrity": "sha512-bQlKmO0pXUsXoF8lOLknhyQjOZsCc0bosQDoX4lujBXSWxHVTg1VxURtWf2lUjz/ACsJVDfvHZbDm8kyBk5okA==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "npmlog": "^4.1.2", "path-exists": "^3.0.0", "rimraf": "^2.6.2" } }, "@lerna/run": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.16.0.tgz", - "integrity": "sha512-woTeLlB1OAAz4zzjdI6RyIxSGuxiUPHJZm89E1pDEPoWwtQV6HMdMgrsQd9ATsJ5Ez280HH4bF/LStAlqW8Ufg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.18.0.tgz", + "integrity": "sha512-sblxHBZ9djaaG7wefPcfEicDqzrB7CP1m/jIB0JvPEQwG4C2qp++ewBpkjRw/mBtjtzg0t7v0nNMXzaWYrQckQ==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/npm-run-script": "3.14.2", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/npm-run-script": "3.16.5", "@lerna/output": "3.13.0", - "@lerna/run-topologically": "3.16.0", + "@lerna/run-topologically": "3.18.0", "@lerna/timer": "3.13.0", "@lerna/validation-error": "3.13.0", "p-map": "^2.1.0" @@ -4174,39 +4143,21 @@ "npmlog": "^4.1.2" } }, - "@lerna/run-parallel-batches": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/run-parallel-batches/-/run-parallel-batches-3.16.0.tgz", - "integrity": "sha512-2J/Nyv+MvogmQEfC7VcS21ifk7w0HVvzo2yOZRPvkCzGRu/rducxtB4RTcr58XCZ8h/Bt1aqQYKExu3c/3GXwg==", - "dev": true, - "requires": { - "p-map": "^2.1.0", - "p-map-series": "^1.0.0" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - } - } - }, "@lerna/run-topologically": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.16.0.tgz", - "integrity": "sha512-4Hlpv4zDtKWa5Z0tPkeu0sK+bxZEKgkNESMGmWrUCNfj7xwvAJurcraK8+a2Y0TFYwf0qjSLY/MzX+ZbJA3Cgw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.18.0.tgz", + "integrity": "sha512-lrfEewwuUMC3ioxf9Z9NdHUakN6ihekcPfdYbzR2slmdbjYKmIA5srkWdrK8NwOpQCAuekpOovH2s8X3FGEopg==", "dev": true, "requires": { - "@lerna/query-graph": "3.16.0", + "@lerna/query-graph": "3.18.0", "figgy-pudding": "^3.5.1", "p-queue": "^4.0.0" } }, "@lerna/symlink-binary": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.16.2.tgz", - "integrity": "sha512-kz9XVoFOGSF83gg4gBqH+mG6uxfJfTp8Uy+Cam40CvMiuzfODrGkjuBEFoM/uO2QOAwZvbQDYOBpKUa9ZxHS1Q==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.17.0.tgz", + "integrity": "sha512-RLpy9UY6+3nT5J+5jkM5MZyMmjNHxZIZvXLV+Q3MXrf7Eaa1hNqyynyj4RO95fxbS+EZc4XVSk25DGFQbcRNSQ==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", @@ -4227,9 +4178,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -4241,14 +4192,14 @@ } }, "@lerna/symlink-dependencies": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.16.2.tgz", - "integrity": "sha512-wnZqGJQ+Jvr1I3inxrkffrFZfmQI7Ta8gySw/UWCy95QtZWF/f5yk8zVIocCAsjzD0wgb3jJE3CFJ9W5iwWk1A==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.17.0.tgz", + "integrity": "sha512-KmjU5YT1bpt6coOmdFueTJ7DFJL4H1w5eF8yAQ2zsGNTtZ+i5SGFBWpb9AQaw168dydc3s4eu0W0Sirda+F59Q==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", "@lerna/resolve-symlink": "3.16.0", - "@lerna/symlink-binary": "3.16.2", + "@lerna/symlink-binary": "3.17.0", "fs-extra": "^8.1.0", "p-finally": "^1.0.0", "p-map": "^2.1.0", @@ -4267,9 +4218,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -4296,26 +4247,27 @@ } }, "@lerna/version": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.16.4.tgz", - "integrity": "sha512-ikhbMeIn5ljCtWTlHDzO4YvTmpGTX1lWFFIZ79Vd1TNyOr+OUuKLo/+p06mCl2WEdZu0W2s5E9oxfAAQbyDxEg==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.18.2.tgz", + "integrity": "sha512-nmCJpw3A2DoNGbjmvI5UB3ZwTQUayI8M/b3rOA6ZzYeGmoQmm2QBKun05aBRasqTuUo4XjSuas5CqHN+x4f8Ww==", "dev": true, "requires": { - "@lerna/check-working-tree": "3.14.2", - "@lerna/child-process": "3.14.2", - "@lerna/collect-updates": "3.16.0", - "@lerna/command": "3.16.0", + "@lerna/check-working-tree": "3.16.5", + "@lerna/child-process": "3.16.5", + "@lerna/collect-updates": "3.18.0", + "@lerna/command": "3.18.0", "@lerna/conventional-commits": "3.16.4", - "@lerna/github-client": "3.16.0", + "@lerna/github-client": "3.16.5", "@lerna/gitlab-client": "3.15.0", "@lerna/output": "3.13.0", "@lerna/prerelease-id-from-version": "3.16.0", "@lerna/prompt": "3.13.0", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-topologically": "3.16.0", + "@lerna/run-topologically": "3.18.0", "@lerna/validation-error": "3.13.0", "chalk": "^2.3.1", "dedent": "^0.7.0", + "load-json-file": "^5.3.0", "minimatch": "^3.0.4", "npmlog": "^4.1.2", "p-map": "^2.1.0", @@ -4324,15 +4276,51 @@ "p-waterfall": "^1.0.0", "semver": "^6.2.0", "slash": "^2.0.0", - "temp-write": "^3.4.0" + "temp-write": "^3.4.0", + "write-json-file": "^3.2.0" }, "dependencies": { + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + } + }, "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -4344,6 +4332,12 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true } } }, @@ -4454,12 +4448,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -4477,9 +4471,9 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/template": { @@ -4494,26 +4488,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -4903,9 +4897,9 @@ } }, "@parcel/logger": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.0.tgz", - "integrity": "sha512-lIRfDg+junbFUUeU0QtHX00gKCgEsYHZydFKwrJ8dc0D+WE2SYT1FcVCgpPAfKYgtg0QQMns8E9vzT9UjH92PQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.1.tgz", + "integrity": "sha512-9NF3M6UVeP2udOBDILuoEHd8VrF4vQqoWHEafymO1pfSoOMfxrSJZw1MfyAAIUN/IFp9qjcpDCUbDZB+ioVevA==", "dev": true, "requires": { "@parcel/workers": "^1.11.0", @@ -4944,13 +4938,13 @@ "dev": true }, "@parcel/watcher": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.0.tgz", - "integrity": "sha512-yijGiAqG7Tjf5WnFwOkiNWwerfZQDNABldiiqRDtr7vDWLO+F/DIncyB7tTcaD5Loevrr5mzzGo8Ntf3d2GIPg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.1.tgz", + "integrity": "sha512-od+uCtCxC/KoNQAIE1vWx1YTyKYY+7CTrxBJPRh3cDWw/C0tCtlBMVlrbplscGoEpt6B27KhJDCv82PBxOERNA==", "dev": true, "requires": { "@parcel/utils": "^1.11.0", - "chokidar": "^2.0.3" + "chokidar": "^2.1.5" } }, "@parcel/workers": { @@ -5125,17 +5119,17 @@ } }, "@storybook/addon-a11y": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-5.2.3.tgz", - "integrity": "sha512-1N8hes5J3qyhCahHyFUXwiKif3JH892dzGalxc46jtvC0oCMM0r6lu+lj9J6THc15Oc8Icy9KJZuw4R0wRJl0Q==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-5.2.4.tgz", + "integrity": "sha512-m7D78LiREpUzw7U+jiJXQXSsYoYZ+IkewBIxX5K15lh58AqTi0hD8DWHssgbi76GQwdaXKmMPIwI842dgPYobQ==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/theming": "5.2.4", "axe-core": "^3.3.2", "common-tags": "^1.8.0", "core-js": "^3.0.1", @@ -5177,9 +5171,9 @@ } }, "@storybook/addon-docs": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-5.2.3.tgz", - "integrity": "sha512-xMg/LCUfVX1SNplaPbsNt9L78/QbxkR7pPpQuLjCvTAvzKkLNWNs8SlwM14ds/SfUNQ9EaCoAd1OQIdZrzrBRg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-5.2.4.tgz", + "integrity": "sha512-rfzoQUseb3G1WanQckjH85OXJJXMigod/YEEqJv68vo7GVY5PdVkOISy9nSldjrnwH6ikT3pcfJKPuHWRKAx/A==", "dev": true, "requires": { "@babel/generator": "^7.4.0", @@ -5188,12 +5182,12 @@ "@mdx-js/loader": "^1.1.0", "@mdx-js/mdx": "^1.1.0", "@mdx-js/react": "^1.0.27", - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/source-loader": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/source-loader": "5.2.4", + "@storybook/theming": "5.2.4", "core-js": "^3.0.1", "global": "^4.3.2", "js-string-escape": "^1.0.1", @@ -5201,173 +5195,404 @@ "prop-types": "^15.7.2" } }, - "@storybook/addon-storysource": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.2.3.tgz", - "integrity": "sha512-7t/oqRzD2QrGiqnUxU++jqgA8OVYByCFzeRHYcpoz84sd2vSy+110Me1OHj2ZHh1t+QOn8D0DJewe0QrycR56w==", + "@storybook/addon-knobs": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-knobs/-/addon-knobs-5.2.4.tgz", + "integrity": "sha512-VYxbDARJs5RwTEOlcfa98tkDXLcRocB7QXLqt8wwCdXPIqkuoVeQLROXGYJm2NzSn49RyHPKUuVWnRhy34qBbQ==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/source-loader": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/client-api": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/theming": "5.2.4", + "@types/react-color": "^3.0.1", + "copy-to-clipboard": "^3.0.8", "core-js": "^3.0.1", - "estraverse": "^4.2.0", - "loader-utils": "^1.2.3", - "prettier": "^1.16.4", + "escape-html": "^1.0.3", + "fast-deep-equal": "^2.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", "prop-types": "^15.7.2", - "react-syntax-highlighter": "^8.0.1", - "regenerator-runtime": "^0.12.1", - "util-deprecate": "^1.0.2" + "qs": "^6.6.0", + "react-color": "^2.17.0", + "react-lifecycles-compat": "^3.0.4", + "react-select": "^3.0.0" }, "dependencies": { - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "@storybook/addons": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.4.tgz", + "integrity": "sha512-Q+bnVlBA308qnELxnh18hBDRSUgltR9KbV537285dUL/okv/NC6n51mxJwIaG+ksBW2wU+5e6tqSayaKF3uHLw==", + "dev": true, + "requires": { + "@storybook/api": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "core-js": "^3.0.1", + "global": "^4.3.2", + "util-deprecate": "^1.0.2" + } }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "@storybook/api": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.4.tgz", + "integrity": "sha512-KqAB+NkHIHdwu749NDP+7i44jy1bFgpq7GTJlG+sx/XLZHQveK/8yn109g9bXHFth7SvdXI1+9GA/apzwBU/Mw==", "dev": true, "requires": { - "minimist": "^1.2.0" + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", + "core-js": "^3.0.1", + "fast-deep-equal": "^2.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "prop-types": "^15.6.2", + "react": "^16.8.3", + "semver": "^6.0.0", + "shallow-equal": "^1.1.0", + "store2": "^2.7.1", + "telejson": "^3.0.2", + "util-deprecate": "^1.0.2" } }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "@storybook/channel-postmessage": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.4.tgz", + "integrity": "sha512-ic7/Ho8z2/aOMjoEbr5p8rijOfO3SZdJnwMvDdUxrqvYq7yACZWidPo3w2+iBwQi9HLqEsWesP1c2doJBxVGRw==", "dev": true, "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "core-js": "^3.0.1", + "global": "^4.3.2", + "telejson": "^3.0.2" + } + }, + "@storybook/channels": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.4.tgz", + "integrity": "sha512-/r39yEZ5QiGdiq95DhXBypdBo7urkD3Sp1WDyK48uGkZ0gdHWSPy3BBy8OJhEhfNz7nVisTiVIBr4gIrubKDjw==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/client-api": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.4.tgz", + "integrity": "sha512-SOwzEFHoNapURhNqdcI7HA76o5tkWvs2+2s++i/S7xsAd3KyefIVDOdqSMlAxJkxZb8Mlrb3UNRxlrpA8SZqNA==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/channel-postmessage": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "common-tags": "^1.8.0", + "core-js": "^3.0.1", + "eventemitter3": "^4.0.0", + "global": "^4.3.2", + "is-plain-object": "^3.0.0", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/client-logger": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.4.tgz", + "integrity": "sha512-ofp6QQPQZBU+RvlAH5KpZRsfAFHecCZDnl/7YG6FwjHseJr3jHTYmBGGjJDMHFHq+Q7FGQu/yVb9lMFgoQ43QQ==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/components": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.4.tgz", + "integrity": "sha512-APhw+XGag0RTCRJ8eCWKVr8dLt9SRqnS8LtzcZJbokCYRxRTFzhmX2eVEE1v+d0gHib1/yh2COxOjMzv3m/rQA==", + "dev": true, + "requires": { + "@storybook/client-logger": "5.2.4", + "@storybook/theming": "5.2.4", + "@types/react-syntax-highlighter": "10.1.0", + "core-js": "^3.0.1", + "global": "^4.3.2", + "markdown-to-jsx": "^6.9.1", + "memoizerific": "^1.11.3", + "polished": "^3.3.1", + "popper.js": "^1.14.7", + "prop-types": "^15.7.2", + "react": "^16.8.3", + "react-dom": "^16.8.3", + "react-focus-lock": "^1.18.3", + "react-helmet-async": "^1.0.2", + "react-popper-tooltip": "^2.8.3", + "react-syntax-highlighter": "^8.0.1", + "react-textarea-autosize": "^7.1.0", + "simplebar-react": "^1.0.0-alpha.6" + } + }, + "@storybook/core-events": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.4.tgz", + "integrity": "sha512-nQknCmaz2S2HW6PSGcuFzve7Y1Js2Cb268vUG0ZMNtJZwFawqYc+KSQHqmOY0pVm8dyROTcWCudPA0k+hk6N5Q==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/router": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.4.tgz", + "integrity": "sha512-GL7eGdj5oYST0mE9fThJB9ye9tTTgrP+aP3okZ6MeMGtNytb7bmJRpAD2E4ouuPTQVppyHI5re8g/HUxUNOT1g==", + "dev": true, + "requires": { + "@reach/router": "^1.2.1", + "@types/reach__router": "^1.2.3", + "core-js": "^3.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "qs": "^6.6.0" + } + }, + "@storybook/theming": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.4.tgz", + "integrity": "sha512-2ZlqBrmnm8N0352Fnu2+GB3pEsHL4Eb2eKxV0VLLgkjJuAlm7CK6+I/e4ZknQWxwYm2pQj1y6ta68A62fGBYyA==", + "dev": true, + "requires": { + "@emotion/core": "^10.0.14", + "@emotion/styled": "^10.0.14", + "@storybook/client-logger": "5.2.4", + "common-tags": "^1.8.0", + "core-js": "^3.0.1", + "deep-object-diff": "^1.1.0", + "emotion-theming": "^10.0.14", + "global": "^4.3.2", + "memoizerific": "^1.11.3", + "polished": "^3.3.1", + "prop-types": "^15.7.2", + "resolve-from": "^5.0.0" } }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", - "dev": true - } - } - }, - "@storybook/addon-viewport": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-5.2.3.tgz", - "integrity": "sha512-YN0rQ6GrgDTAQv0KVhSJ/ZBQfEUerOTMsAt9MH9fCIgIfXmXc8BoqkL3DYhAhEPEKpzQkV+NwZyZcLCntXPdQg==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/theming": "5.2.3", - "core-js": "^3.0.1", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "prop-types": "^15.7.2", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/addons": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.3.tgz", - "integrity": "sha512-LTkUJB8ZDc4++yt9acNHNjlnGWCyNtP+NVYPDvg7zFOaMip21Pj4T0pg9UwYxdqrFBWz9tVz7DJeXroS3egXxg==", - "dev": true, - "requires": { - "@storybook/api": "5.2.3", - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", - "core-js": "^3.0.1", - "global": "^4.3.2", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/api": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.3.tgz", - "integrity": "sha512-2csxa/d64rXy4Dwoc7YjbPeNUJRgcI/wJUo30CLujk2stEFzDnKeMPR1mlHMCIFDW+KDxJ28bW59VPxwrqJFjw==", - "dev": true, - "requires": { - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/theming": "5.2.3", - "core-js": "^3.0.1", - "fast-deep-equal": "^2.0.1", - "global": "^4.3.2", - "lodash": "^4.17.11", - "memoizerific": "^1.11.3", - "prop-types": "^15.6.2", - "react": "^16.8.3", - "semver": "^6.0.0", - "shallow-equal": "^1.1.0", - "store2": "^2.7.1", - "telejson": "^3.0.2", - "util-deprecate": "^1.0.2" - }, - "dependencies": { - "shallow-equal": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.0.tgz", - "integrity": "sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==", - "dev": true - } - } - }, - "@storybook/channel-postmessage": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.3.tgz", - "integrity": "sha512-ixlpr6aAYoRM72cKwEWU/W0rWzOn3mYqb/eUdIaz3Da5BtFGKm3yEFguII0l1my82uhMm5/d3UNfoh0rO3pUyg==", - "dev": true, - "requires": { - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "core-js": "^3.0.1", - "global": "^4.3.2", - "telejson": "^3.0.2" - } - }, - "@storybook/channels": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.3.tgz", - "integrity": "sha512-13Mlb+XbE0mHXiLLHdg0w9byhRy/bE605U7U96PGQp2cwX4lf+4jpViO2mDCsndAFRc0+2hexXPTkwgzvZzq0A==", - "dev": true, - "requires": { - "core-js": "^3.0.1" - } - }, - "@storybook/client-api": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.3.tgz", - "integrity": "sha512-anXxcf2z+KQAk94xxdbeG1N6nTEWXj087XHQ22L3pOoX9TRzfG71UjL0/S7vj4EFUiXVHj8d6YUFwLb5LwpUIw==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.3", - "@storybook/channel-postmessage": "5.2.3", - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/router": "5.2.3", - "common-tags": "^1.8.0", - "core-js": "^3.0.1", - "eventemitter3": "^4.0.0", - "global": "^4.3.2", - "is-plain-object": "^3.0.0", - "lodash": "^4.17.11", - "memoizerific": "^1.11.3", - "qs": "^6.6.0", - "util-deprecate": "^1.0.2" - }, - "dependencies": { + "eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + }, + "qs": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz", + "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "shallow-equal": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.0.tgz", + "integrity": "sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==", + "dev": true + } + } + }, + "@storybook/addon-storysource": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.2.4.tgz", + "integrity": "sha512-zOJO4zt+Fj08GgegClDA6rU+VFyBb+mepfL5eJAqLtV6gSsprwZ1JNFVkyqhfrcr+vIhgRRWfuz/DDGmI+6bTQ==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/source-loader": "5.2.4", + "@storybook/theming": "5.2.4", + "core-js": "^3.0.1", + "estraverse": "^4.2.0", + "loader-utils": "^1.2.3", + "prettier": "^1.16.4", + "prop-types": "^15.7.2", + "react-syntax-highlighter": "^8.0.1", + "regenerator-runtime": "^0.12.1", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "dev": true + } + } + }, + "@storybook/addon-viewport": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-5.2.4.tgz", + "integrity": "sha512-R49wSaiouSVBYeus5Xibv+XXX9Nc3/rZ1NB5yIgj658aDeuB8WgkHbM3dKd/GrWeVZWv3o4CjW81ernd3f8sdw==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/theming": "5.2.4", + "core-js": "^3.0.1", + "global": "^4.3.2", + "memoizerific": "^1.11.3", + "prop-types": "^15.7.2", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/addons": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.4.tgz", + "integrity": "sha512-Q+bnVlBA308qnELxnh18hBDRSUgltR9KbV537285dUL/okv/NC6n51mxJwIaG+ksBW2wU+5e6tqSayaKF3uHLw==", + "dev": true, + "requires": { + "@storybook/api": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "core-js": "^3.0.1", + "global": "^4.3.2", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/api": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.4.tgz", + "integrity": "sha512-KqAB+NkHIHdwu749NDP+7i44jy1bFgpq7GTJlG+sx/XLZHQveK/8yn109g9bXHFth7SvdXI1+9GA/apzwBU/Mw==", + "dev": true, + "requires": { + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", + "core-js": "^3.0.1", + "fast-deep-equal": "^2.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "prop-types": "^15.6.2", + "react": "^16.8.3", + "semver": "^6.0.0", + "shallow-equal": "^1.1.0", + "store2": "^2.7.1", + "telejson": "^3.0.2", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "shallow-equal": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.0.tgz", + "integrity": "sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==", + "dev": true + } + } + }, + "@storybook/channel-postmessage": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.4.tgz", + "integrity": "sha512-ic7/Ho8z2/aOMjoEbr5p8rijOfO3SZdJnwMvDdUxrqvYq7yACZWidPo3w2+iBwQi9HLqEsWesP1c2doJBxVGRw==", + "dev": true, + "requires": { + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "core-js": "^3.0.1", + "global": "^4.3.2", + "telejson": "^3.0.2" + } + }, + "@storybook/channels": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.4.tgz", + "integrity": "sha512-/r39yEZ5QiGdiq95DhXBypdBo7urkD3Sp1WDyK48uGkZ0gdHWSPy3BBy8OJhEhfNz7nVisTiVIBr4gIrubKDjw==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/client-api": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.4.tgz", + "integrity": "sha512-SOwzEFHoNapURhNqdcI7HA76o5tkWvs2+2s++i/S7xsAd3KyefIVDOdqSMlAxJkxZb8Mlrb3UNRxlrpA8SZqNA==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/channel-postmessage": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "common-tags": "^1.8.0", + "core-js": "^3.0.1", + "eventemitter3": "^4.0.0", + "global": "^4.3.2", + "is-plain-object": "^3.0.0", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "util-deprecate": "^1.0.2" + }, + "dependencies": { "eventemitter3": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", @@ -5398,22 +5623,22 @@ } }, "@storybook/client-logger": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.3.tgz", - "integrity": "sha512-Z1irXW4jiFs7rClgqJqYOgg5op51ynV6dVuoIqxkSC0MrOG5s/VbX7T+ojGPXKyQWD4XYGw66Hnw9jouSfXL9g==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.4.tgz", + "integrity": "sha512-ofp6QQPQZBU+RvlAH5KpZRsfAFHecCZDnl/7YG6FwjHseJr3jHTYmBGGjJDMHFHq+Q7FGQu/yVb9lMFgoQ43QQ==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/components": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.3.tgz", - "integrity": "sha512-EiWKa3xONP2BPxrssiRdvKELhF2tO14HVL131CCFY+Zg/ylExzWWWVSBun7vYcKhkI52K5lmvC1vFSsB6Gmlhw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.4.tgz", + "integrity": "sha512-APhw+XGag0RTCRJ8eCWKVr8dLt9SRqnS8LtzcZJbokCYRxRTFzhmX2eVEE1v+d0gHib1/yh2COxOjMzv3m/rQA==", "dev": true, "requires": { - "@storybook/client-logger": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/client-logger": "5.2.4", + "@storybook/theming": "5.2.4", "@types/react-syntax-highlighter": "10.1.0", "core-js": "^3.0.1", "global": "^4.3.2", @@ -5433,9 +5658,9 @@ } }, "@storybook/core": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-5.2.3.tgz", - "integrity": "sha512-sktjYY8pH4kQGFRKjXwtwwShdG3ajjHkrnw8oh3R383MRPom7i9owx5yHHMuQedLCXIwAg84s2DzO01I2URTcg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-5.2.4.tgz", + "integrity": "sha512-r5kDgZETNawHxpsAPw+h+pRk6l/mJhsSHeDo9/OdYtYFW7lmk2gadViXOTM+6gIWc6vQ8y750bgkahmyIIY0nQ==", "dev": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.3.3", @@ -5443,15 +5668,15 @@ "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-transform-react-constant-elements": "^7.2.0", "@babel/preset-env": "^7.4.5", - "@storybook/addons": "5.2.3", - "@storybook/channel-postmessage": "5.2.3", - "@storybook/client-api": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/node-logger": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/theming": "5.2.3", - "@storybook/ui": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/channel-postmessage": "5.2.4", + "@storybook/client-api": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/node-logger": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", + "@storybook/ui": "5.2.4", "airbnb-js-shims": "^1 || ^2", "ansi-to-html": "^0.6.11", "autoprefixer": "^9.4.9", @@ -5519,12 +5744,12 @@ } }, "ansi-to-html": { - "version": "0.6.11", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.11.tgz", - "integrity": "sha512-88XZtrcwrfkyn6fGstHnkaF1kl7hGtNCYh4vSmItgEV+6JnQHryDBf7udF4f2RhTRQmYvJvPcTtqgaqrxzc9oA==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.12.tgz", + "integrity": "sha512-qBkIqLW979675mP76yB7yVkzeAWtATegdnDQ0RA3CZzknx0yUlNxMSML4xFdBfTs2GWYFQ1FELfbGbVSPzJ+LA==", "dev": true, "requires": { - "entities": "^1.1.1" + "entities": "^1.1.2" } }, "body-parser": { @@ -5583,6 +5808,12 @@ "ms": "2.0.0" } }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -5922,18 +6153,18 @@ } }, "@storybook/core-events": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.3.tgz", - "integrity": "sha512-sZEv93yE1o+/UJdhtqQ6vo2EauZ90FjN/L8F7CR7iqDEZzqo9g77Idg9LSgcN3TAeXcGAWVSrPb1vkK7H96L2g==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.4.tgz", + "integrity": "sha512-nQknCmaz2S2HW6PSGcuFzve7Y1Js2Cb268vUG0ZMNtJZwFawqYc+KSQHqmOY0pVm8dyROTcWCudPA0k+hk6N5Q==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/node-logger": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-5.2.3.tgz", - "integrity": "sha512-5p+5ltLdr7cZTSCG+vdIMDLHq5AAaL/CQ/bygjl+Rw/RSpvBO5Rg8hryszFyhogToHJbn2JinUbypLA+P6tcuQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-5.2.4.tgz", + "integrity": "sha512-4OOzce02IAfrRv+Y7h3icyw6WIuDekpWF2eYjgYVVvAJYklCEwgeBTBCY0/2TJjPPTBDPUKHVP1Bdz3Vpci9pA==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -5952,17 +6183,17 @@ } }, "@storybook/react": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-5.2.3.tgz", - "integrity": "sha512-7DLUkpwyPTyDHoih/AvFr2QXQAxzXQMVDvvR5r0J0oiffLWwrqshl1TL4b16YoFvel0ZPtUdrcei6knLXhg+Wg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-5.2.4.tgz", + "integrity": "sha512-AO0qwbD/2UGe5CrVizbaek+gCAPWkPVc0KUk38cT1mcuLpXwt1zZe7iHLQf2zOeBVSiBkPLOHrEtzDfnIJXKFQ==", "dev": true, "requires": { "@babel/plugin-transform-react-constant-elements": "^7.2.0", "@babel/preset-flow": "^7.0.0", "@babel/preset-react": "^7.0.0", - "@storybook/addons": "5.2.3", - "@storybook/core": "5.2.3", - "@storybook/node-logger": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/core": "5.2.4", + "@storybook/node-logger": "5.2.4", "@svgr/webpack": "^4.0.3", "@types/webpack-env": "^1.13.7", "babel-plugin-add-react-displayname": "^0.0.5", @@ -5990,9 +6221,9 @@ } }, "@storybook/router": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.3.tgz", - "integrity": "sha512-sOu6y2GySaY82SdXfF3yOn0IJTKMqd2BDOSGEno7PWWtSenHFQWY+z99C9k0dLBTkjRes5tPcgm0OJ7RdQVRDQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.4.tgz", + "integrity": "sha512-GL7eGdj5oYST0mE9fThJB9ye9tTTgrP+aP3okZ6MeMGtNytb7bmJRpAD2E4ouuPTQVppyHI5re8g/HUxUNOT1g==", "dev": true, "requires": { "@reach/router": "^1.2.1", @@ -6013,13 +6244,13 @@ } }, "@storybook/source-loader": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.2.3.tgz", - "integrity": "sha512-4wKYslglYt/yC77zvRZ4OkmTVbnmnd98VMD99KP3Ap6IwkdxtGKIBTOOT36g6m0/1JaMFe+x7i+i9nbmK4hsDQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.2.4.tgz", + "integrity": "sha512-TXqJhj0oSnUp4w5dyh2sf3OXt/ShF9m7ceTzI8H8ZfuI8kljVsv+KvGdv+Q4f4jrO3br4Qz7bE9Wvp70i9BY1g==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/router": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/router": "5.2.4", "core-js": "^3.0.1", "estraverse": "^4.2.0", "global": "^4.3.2", @@ -6064,14 +6295,14 @@ } }, "@storybook/theming": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.3.tgz", - "integrity": "sha512-3/0bo8CaoaHDYZaexydpYcwP6WW8BKRqSQBGXJY9y0TLhwY2Who5nPX9XdOLyu9d7lN//PRZlt8JnZynuncxoQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.4.tgz", + "integrity": "sha512-2ZlqBrmnm8N0352Fnu2+GB3pEsHL4Eb2eKxV0VLLgkjJuAlm7CK6+I/e4ZknQWxwYm2pQj1y6ta68A62fGBYyA==", "dev": true, "requires": { "@emotion/core": "^10.0.14", "@emotion/styled": "^10.0.14", - "@storybook/client-logger": "5.2.3", + "@storybook/client-logger": "5.2.4", "common-tags": "^1.8.0", "core-js": "^3.0.1", "deep-object-diff": "^1.1.0", @@ -6092,19 +6323,19 @@ } }, "@storybook/ui": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-5.2.3.tgz", - "integrity": "sha512-SNyo5oxupb105N4Rz8O5/iJMs/THrmdvP+vsN7CpOTxebM01rHyvk51cNUwHKG1QwlZmpXL8GbtWlbvqL2d/gQ==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/theming": "5.2.3", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-5.2.4.tgz", + "integrity": "sha512-zsS43k1h4bWEW6oj9FNHlUL3niHoJJ8v7iqYbRtVM12rxrYhV3K8TGVG3LCuNB75i3Be0Myy+/RHA4x9kco08A==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", "copy-to-clipboard": "^3.0.8", "core-js": "^3.0.1", "core-js-pure": "^3.0.1", @@ -6644,6 +6875,15 @@ "csstype": "^2.2.0" } }, + "@types/react-color": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.1.tgz", + "integrity": "sha512-J6mYm43Sid9y+OjZ7NDfJ2VVkeeuTPNVImNFITgQNXodHteKfl/t/5pAR5Z9buodZ2tCctsZjgiMlQOpfntakw==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-syntax-highlighter": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-10.1.0.tgz", @@ -6687,9 +6927,9 @@ } }, "@types/webpack-env": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.14.0.tgz", - "integrity": "sha512-Fv+0gYJzE/czLoRKq+gnXWr4yBpPM3tO3C8pDLFwqVKlMICQUq5OsxwwFZYDaVr7+L6mgNDp16iOcJHEz3J5RQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.14.1.tgz", + "integrity": "sha512-0Ki9jAAhKDSuLDXOIMADg54Hu60SuBTEsWaJGGy5cV+SSUQ63J2a+RrYYGrErzz39fXzTibhKrAQJAb8M7PNcA==", "dev": true }, "@types/yargs": { @@ -6967,6 +7207,10 @@ "core-js": "^3.1.4" } }, + "@wordpress/base-styles": { + "version": "file:packages/base-styles", + "dev": true + }, "@wordpress/blob": { "version": "file:packages/blob", "requires": { @@ -6984,6 +7228,7 @@ "@wordpress/data": "file:packages/data", "@wordpress/element": "file:packages/element", "@wordpress/i18n": "file:packages/i18n", + "@wordpress/plugins": "file:packages/plugins", "lodash": "^4.17.15" } }, @@ -7255,6 +7500,7 @@ "@wordpress/jest-console": "file:packages/jest-console", "@wordpress/jest-puppeteer-axe": "file:packages/jest-puppeteer-axe", "@wordpress/scripts": "file:packages/scripts", + "@wordpress/url": "file:packages/url", "expect-puppeteer": "^4.3.0", "lodash": "^4.17.15", "uuid": "^3.3.2" @@ -7604,8 +7850,8 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^3.6.0", - "puppeteer": "^1.19.0", + "npm-package-json-lint": "^4.0.3", + "puppeteer": "^1.20.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", "resolve-bin": "^0.4.0", @@ -7779,9 +8025,9 @@ "dev": true }, "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -8056,12 +8302,20 @@ } }, "ansi-to-html": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.10.tgz", - "integrity": "sha512-znsY3gvsk4CiApWu1yVYF8Nx5Vy0FEe8B0YwyxdbCdErJu5lfKlRHB2twtUjR+dxR4WewTk2OP8XqTmWYnImOg==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.12.tgz", + "integrity": "sha512-qBkIqLW979675mP76yB7yVkzeAWtATegdnDQ0RA3CZzknx0yUlNxMSML4xFdBfTs2GWYFQ1FELfbGbVSPzJ+LA==", "dev": true, "requires": { - "entities": "^1.1.1" + "entities": "^1.1.2" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + } } }, "ansi-wrap": { @@ -8331,14 +8585,71 @@ } }, "array.prototype.flatmap": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz", - "integrity": "sha512-i18e2APdsiezkcqDyZor78Pbfjfds3S94dG6dgIV2ZASJaUf1N0dz2tGdrmwrmlZuNUgxH+wz6Z0zYVH2c5xzQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.2.tgz", + "integrity": "sha512-ZZtPLE74KNE+0XcPv/vQmcivxN+8FhwOLvt2udHauO0aDEpsXDQrmd5HuJGpgPVyaV8HvkDPWnJ2iaem0oCKtA==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.10.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.15.0", "function-bind": "^1.1.1" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", + "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + } } }, "arrify": { @@ -9546,12 +9857,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -9604,9 +9915,9 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/plugin-proposal-class-properties": { @@ -9641,9 +9952,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz", - "integrity": "sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", + "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -9713,9 +10024,9 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz", - "integrity": "sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz", + "integrity": "sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw==", "dev": true, "requires": { "regexpu-core": "^4.6.0" @@ -9810,6 +10121,19 @@ "semver": "^5.5.0" } }, + "@babel/preset-react": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", + "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0" + } + }, "@babel/runtime": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", @@ -9831,26 +10155,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -10592,7 +10916,8 @@ "buffer-from": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true }, "buffer-xor": { "version": "1.0.3", @@ -10926,9 +11251,9 @@ } }, "chokidar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.1.tgz", - "integrity": "sha512-gfw3p2oQV2wEt+8VuMlNsPjCxDxvvgnm/kz+uATu805mWVF8IJN7uz9DN7iBz+RMJISmiVbCOBFs9qBGMjtPfQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -10942,599 +11267,20 @@ "normalize-path": "^3.0.0", "path-is-absolute": "^1.0.0", "readdirp": "^2.2.1", - "upath": "^1.1.0" + "upath": "^1.1.1" }, "dependencies": { - "fsevents": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", - "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true } } }, @@ -11773,12 +11519,6 @@ "is-supported-regexp-flag": "^1.0.0" } }, - "clones": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/clones/-/clones-1.2.0.tgz", - "integrity": "sha512-FXDYw4TjR8wgPZYui2LeTqWh1BLpfQ8lB6upMtlpDF6WlOOxghmTTxWyngdKTgozqBgKnHbTVwTE+hOHqAykuQ==", - "dev": true - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -12246,9 +11986,9 @@ "dev": true }, "conventional-changelog-angular": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz", - "integrity": "sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.5.tgz", + "integrity": "sha512-RrkdWnL/TVyWV1ayWmSsrWorsTDqjL/VwG5ZSEneBQrd65ONcfeA1cW7FLtNweQyMiKOyriCMTKRSlk18DjTrw==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -12349,15 +12089,15 @@ "dev": true }, "conventional-changelog-writer": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.7.tgz", - "integrity": "sha512-p/wzs9eYaxhFbrmX/mCJNwJuvvHR+j4Fd0SQa2xyAhYed6KBiZ780LvoqUUvsayP4R1DtC27czalGUhKV2oabw==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.9.tgz", + "integrity": "sha512-2Y3QfiAM37WvDMjkVNaRtZgxVzWKj73HE61YQ/95T53yle+CRwTVSl6Gbv/lWVKXeZcM5af9n9TDVf0k7Xh+cw==", "dev": true, "requires": { "compare-func": "^1.3.1", "conventional-commits-filter": "^2.0.2", "dateformat": "^3.0.0", - "handlebars": "^4.1.2", + "handlebars": "^4.4.0", "json-stringify-safe": "^5.0.1", "lodash": "^4.2.1", "meow": "^4.0.0", @@ -12460,9 +12200,9 @@ } }, "conventional-commits-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.3.tgz", - "integrity": "sha512-KaA/2EeUkO4bKjinNfGUyqPTX/6w9JGshuQRik4r/wJz7rUw3+D3fDG6sZSEqJvKILzKXFQuFkpPLclcsAuZcg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.5.tgz", + "integrity": "sha512-qVz9+5JwdJzsbt7JbJ6P7NOXBGt8CyLFJYSjKAuPSgO+5UGfcsbk9EMR+lI8Unlvx6qwIc2YDJlrGIfay2ehNA==", "dev": true, "requires": { "JSONStream": "^1.0.4", @@ -13121,9 +12861,9 @@ "dev": true }, "schema-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", - "integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz", + "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==", "dev": true, "requires": { "ajv": "^6.10.2", @@ -13438,6 +13178,15 @@ "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==", "dev": true }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, "csstype": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz", @@ -13523,9 +13272,9 @@ "dev": true }, "deasync": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.14.tgz", - "integrity": "sha512-wN8sIuEqIwyQh72AG7oY6YQODCxIp1eXzEZlZznBuwDF8Q03Tdy9QNp1BNZXeadXoklNrw+Ip1fch+KXo/+ASw==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.15.tgz", + "integrity": "sha512-pxMaCYu8cQIbGkA4Y1R0PLSooPIpH1WgFBLeJ+zLxQgHfkZG86ViJSmZmONSjZJ/R3NjwkMcIWZAzpLB2G9/CA==", "dev": true, "requires": { "bindings": "~1.2.1", @@ -14096,6 +13845,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2" + } + }, "dom-scroll-into-view": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", @@ -14198,9 +13956,9 @@ } }, "dotenv-expand": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz", - "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", "dev": true }, "dotenv-webpack": { @@ -14249,42 +14007,6 @@ "jsbn": "~0.1.0" } }, - "editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -14695,9 +14417,9 @@ "dev": true }, "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", "dev": true }, "es6-promisify": { @@ -15965,7 +15687,8 @@ "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true }, "figures": { "version": "2.0.0", @@ -16476,14 +16199,14 @@ "dev": true }, "fsevents": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", - "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -16561,12 +16284,12 @@ "optional": true }, "debug": { - "version": "2.6.9", + "version": "4.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-extend": { @@ -16737,24 +16460,31 @@ } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", "bundled": true, "dev": true, "optional": true }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, "needle": { - "version": "2.2.4", + "version": "2.3.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "^2.1.2", + "debug": "^4.1.0", "iconv-lite": "^0.4.4", "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.10.3", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true, @@ -16782,13 +16512,13 @@ } }, "npm-bundled": { - "version": "1.0.5", + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.2.0", + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, @@ -16878,8 +16608,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "dev": true, "optional": true } @@ -16928,7 +16657,7 @@ "optional": true }, "semver": { - "version": "5.6.0", + "version": "5.7.0", "bundled": true, "dev": true, "optional": true @@ -17621,9 +17350,9 @@ } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -18145,19 +17874,153 @@ } }, "htmlnano": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.3.tgz", - "integrity": "sha512-iS6T3J5gk2wInodbtMUyAU8sLYJOhuWDnIEd8lFRoHTypVGgawPHFEx2ZIK/XTErtDfwHBsrXeCwHAP8bdoSWw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.4.tgz", + "integrity": "sha512-wsg7+Hjyi1gHpMUixkeOjeRUNhBBTnEDB//kzvVHR+LUK4p+/31DAyE+pEACT0SQk3W0KE7Xdylk9+uNxdHXLg==", "dev": true, "requires": { - "cssnano": "^4.1.9", - "normalize-html-whitespace": "^0.2.0", + "cssnano": "^4.1.10", + "normalize-html-whitespace": "^1.0.0", "object-assign": "^4.0.1", - "posthtml": "^0.11.3", - "posthtml-render": "^1.1.4", - "svgo": "^1.0.5", - "terser": "^3.16.1", - "uncss": "^0.16.2" + "posthtml": "^0.11.4", + "posthtml-render": "^1.1.5", + "svgo": "^1.2.2", + "terser": "^4.1.2", + "uncss": "^0.17.0" + }, + "dependencies": { + "css-select": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", + "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-tree": { + "version": "1.0.0-alpha.33", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", + "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.5.3" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "svgo": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", + "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.33", + "csso": "^3.5.1", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + } + }, + "terser": { + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz", + "integrity": "sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + } } }, "htmlparser2": { @@ -18226,12 +18089,12 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.3.tgz", + "integrity": "sha512-Ytgnz23gm2DVftnzqRRz2dOXZbGd2uiajSw/95bPp6v53zPRspQjLm/AfBgqbJ2qfeRXWIOMVLpp86+/5yX39Q==", "dev": true, "requires": { - "agent-base": "^4.1.0", + "agent-base": "^4.3.0", "debug": "^3.1.0" } }, @@ -18661,9 +18524,9 @@ } }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -18698,7 +18561,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "in-publish": { "version": "2.0.0", @@ -18718,12 +18582,6 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -18768,9 +18626,9 @@ }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -19183,15 +19041,6 @@ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true }, - "is-path-inside": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.0.0.tgz", - "integrity": "sha512-OmUXvSq+P7aI/aRbl1dzwdlyLn8vW7Nr2/11S7y/dcLLgnQ89hgYJp7tfc+A5SRid3rNCLpruOp2CAV68/iOcA==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -20712,45 +20561,6 @@ "integrity": "sha512-O9SR2NVICx6rCqh1qsU91QZ5IoNa+2T1ROJ0OQlfvATKGmnjsAvg3r0E5ufPZ4a95jdKTPXhFWiE/sOZ7a5Rtg==", "dev": true }, - "js-beautify": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.9.1.tgz", - "integrity": "sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ==", - "dev": true, - "requires": { - "config-chain": "^1.1.12", - "editorconfig": "^0.15.2", - "glob": "^7.1.3", - "mkdirp": "~0.5.0", - "nopt": "~4.0.1" - }, - "dependencies": { - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, "js-levenshtein": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.3.tgz", @@ -21052,26 +20862,26 @@ "dev": true }, "lerna": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.16.4.tgz", - "integrity": "sha512-0HfwXIkqe72lBLZcNO9NMRfylh5Ng1l8tETgYQ260ZdHRbPuaLKE3Wqnd2YYRRkWfwPyEyZO8mZweBR+slVe1A==", - "dev": true, - "requires": { - "@lerna/add": "3.16.2", - "@lerna/bootstrap": "3.16.2", - "@lerna/changed": "3.16.4", - "@lerna/clean": "3.16.0", - "@lerna/cli": "3.13.0", - "@lerna/create": "3.16.0", - "@lerna/diff": "3.16.0", - "@lerna/exec": "3.16.0", - "@lerna/import": "3.16.0", - "@lerna/init": "3.16.0", - "@lerna/link": "3.16.2", - "@lerna/list": "3.16.0", - "@lerna/publish": "3.16.4", - "@lerna/run": "3.16.0", - "@lerna/version": "3.16.4", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.18.2.tgz", + "integrity": "sha512-XznkKk2LY9HxaH+AtqyNZq7A0f9mMuv1OUeJBjJdl2oEZQPedWrmZNK6DuJNcyjjRJk6B9Xvb8eqIpe5aCHy1w==", + "dev": true, + "requires": { + "@lerna/add": "3.18.0", + "@lerna/bootstrap": "3.18.0", + "@lerna/changed": "3.18.2", + "@lerna/clean": "3.18.0", + "@lerna/cli": "3.18.0", + "@lerna/create": "3.18.0", + "@lerna/diff": "3.18.0", + "@lerna/exec": "3.18.0", + "@lerna/import": "3.18.0", + "@lerna/init": "3.18.0", + "@lerna/link": "3.18.0", + "@lerna/list": "3.18.0", + "@lerna/publish": "3.18.2", + "@lerna/run": "3.18.0", + "@lerna/version": "3.18.2", "import-local": "^2.0.0", "npmlog": "^4.1.2" } @@ -21993,15 +21803,15 @@ }, "dependencies": { "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", "dev": true }, "cacache": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", - "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", "dev": true, "requires": { "bluebird": "^3.5.5", @@ -22022,15 +21832,15 @@ } }, "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -22042,9 +21852,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "lru-cache": { @@ -22085,9 +21895,9 @@ } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" @@ -22118,9 +21928,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } @@ -22204,6 +22014,12 @@ "unquote": "^1.1.0" } }, + "material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==", + "dev": true + }, "mathml-tag-names": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.0.tgz", @@ -22314,6 +22130,12 @@ "resolved": "https://registry.npmjs.org/memize/-/memize-1.0.5.tgz", "integrity": "sha512-Dm8Jhb5kiC4+ynYsVR4QDXKt+o2dfqGuY4hE2x+XlXZkdndlT80bJxfcMv5QGp/FCy6MhG7f5ElpmKPFKOSEpg==" }, + "memoize-one": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", + "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==", + "dev": true + }, "memoizerific": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", @@ -23316,9 +23138,9 @@ } }, "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true }, "mime-db": { @@ -23641,13 +23463,6 @@ "thenify-all": "^1.0.0" } }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -23750,9 +23565,9 @@ } }, "node-addon-api": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.6.2.tgz", - "integrity": "sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", + "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", "dev": true }, "node-dir": { @@ -23825,9 +23640,9 @@ "dev": true }, "node-libs-browser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", - "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "dev": true, "requires": { "assert": "^1.1.1", @@ -23840,7 +23655,7 @@ "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", + "path-browserify": "0.0.1", "process": "^0.11.10", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", @@ -23852,7 +23667,7 @@ "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.11.0", - "vm-browserify": "0.0.4" + "vm-browserify": "^1.0.1" }, "dependencies": { "punycode": { @@ -24357,9 +24172,9 @@ } }, "normalize-html-whitespace": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-0.2.0.tgz", - "integrity": "sha1-EBci9kI1Ucdc24+dEE/4UNrx4Q4=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz", + "integrity": "sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA==", "dev": true }, "normalize-package-data": { @@ -24416,9 +24231,9 @@ "dev": true }, "npm-lifecycle": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.2.tgz", - "integrity": "sha512-nhfOcoTHrW1lJJlM2o77vTE2RWR4YOVyj7YzmY0y5itsMjEuoJHteio/ez0BliENEPsNxIUQgwhyEW9dShj3Ww==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.4.tgz", + "integrity": "sha512-tgs1PaucZwkxECGKhC/stbEgFyc3TGh2TJcg2CDr6jbvQRdteHNhmMeljRzpe4wgFAXQADoy1cSqqi7mtiAa5A==", "dev": true, "requires": { "byline": "^5.0.0", @@ -24432,21 +24247,31 @@ }, "dependencies": { "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "node-gyp": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.3.tgz", - "integrity": "sha512-z/JdtkFGUm0QaQUusvloyYuGDub3nUbOo5de1Fz57cM++osBTvQatBUSTlF1k/w8vFHPxxXW6zxGvkxXSpaBkQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.5.tgz", + "integrity": "sha512-WABl9s4/mqQdZneZHVWVG4TVr6QQJZUC6PAx47ITSk9lreZ1n+7Z9mMAIbA3vnO4J9W20P7LhCxtzfWsAD/KDw==", "dev": true, "requires": { "env-paths": "^1.0.0", @@ -24458,7 +24283,7 @@ "request": "^2.87.0", "rimraf": "2", "semver": "~5.3.0", - "tar": "^4.4.8", + "tar": "^4.4.12", "which": "1" } }, @@ -24475,14 +24300,14 @@ "dev": true }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -24490,87 +24315,139 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "npm-package-arg": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", - "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { - "hosted-git-info": "^2.6.0", + "hosted-git-info": "^2.7.1", "osenv": "^0.1.5", - "semver": "^5.5.0", + "semver": "^5.6.0", "validate-npm-package-name": "^3.0.0" }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "npm-package-json-lint": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-3.6.0.tgz", - "integrity": "sha512-N1y3r0l0oN7mYnMfRzZvYF8+NvjIx+zkskRn3J7ofipJKGH4RDDKdEGP/mV1Crf5W8uUo3201VhJe04Q+v9erw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-4.0.3.tgz", + "integrity": "sha512-cuvTR2l5dOjjlRR3a1CCp+mh2A2HyQRxydwdcYi0Z77NRlADpf7wF3Jf8XFLGZM7J6afXNRBofBjQ1UWFyOtKA==", "dev": true, "requires": { - "ajv": "^6.9.2", + "ajv": "^6.10.2", + "ajv-errors": "^1.0.1", "chalk": "^2.4.2", - "glob": "^7.1.3", - "ignore": "^5.0.5", - "is-path-inside": "^2.0.0", - "is-plain-obj": "^1.1.0", - "is-resolvable": "^1.1.0", - "log-symbols": "^2.2.0", + "cosmiconfig": "^5.2.1", + "debug": "^4.1.1", + "globby": "^10.0.1", + "ignore": "^5.1.4", + "is-plain-obj": "^2.0.0", + "log-symbols": "^3.0.0", "meow": "^5.0.0", - "plur": "^3.0.1", - "semver": "^5.6.0", - "strip-json-comments": "^2.0.1", - "validator": "^10.11.0" + "plur": "^3.1.1", + "semver": "^6.3.0", + "strip-json-comments": "^3.0.1" }, "dependencies": { - "ajv": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz", - "integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==", + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fill-range": "^7.0.1" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" } }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", + "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -24581,23 +24458,135 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, "ignore": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.0.5.tgz", - "integrity": "sha512-kOC8IUb8HSDMVcYrDVezCxpJkzSQWTAzf3olpKM6o9rM5zpojx23O0Fl8Wr4+qJ6ZbPEHqf1fdwev/DS7v7pmA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.0.0.tgz", + "integrity": "sha512-EYisGhpgSCwspmIuRHGjROWTon2Xp8Z7U03Wubk/bTL5TTRC5R1rGVgyjzBrk9+ULdH6cRD06KRcw/xfqhVYKQ==", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, @@ -24612,9 +24601,9 @@ } }, "npm-pick-manifest": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz", - "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", + "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -24623,9 +24612,9 @@ }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -24676,6 +24665,12 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, + "nwsapi": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", + "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -25197,28 +25192,28 @@ } }, "parcel-bundler": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.3.tgz", - "integrity": "sha512-8bq6lj0hhQeGxD9f9xEkFMXQ3d8TIlf2+isKxoi9bciB0KVEILRGllaPkUgp++5t0anToBh9+tG6ZyInXOC1/A==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0 <7.4.0", - "@babel/core": "^7.0.0 <7.4.0", - "@babel/generator": "^7.0.0 <7.4.0", - "@babel/parser": "^7.0.0 <7.4.0", - "@babel/plugin-transform-flow-strip-types": "^7.0.0 <7.4.0", - "@babel/plugin-transform-modules-commonjs": "^7.0.0 <7.4.0", - "@babel/plugin-transform-react-jsx": "^7.0.0 <7.4.0", - "@babel/preset-env": "^7.0.0 <7.4.0", - "@babel/runtime": "^7.0.0 <7.4.0", - "@babel/template": "^7.0.0 <7.4.0", - "@babel/traverse": "^7.0.0 <7.4.0", - "@babel/types": "^7.0.0 <7.4.0", + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.4.tgz", + "integrity": "sha512-G+iZGGiPEXcRzw0fiRxWYCKxdt/F7l9a0xkiU4XbcVRJCSlBnioWEwJMutOCCpoQmaQtjB4RBHDGIHN85AIhLQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.4.4", + "@babel/generator": "^7.4.4", + "@babel/parser": "^7.4.4", + "@babel/plugin-transform-flow-strip-types": "^7.4.4", + "@babel/plugin-transform-modules-commonjs": "^7.4.4", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/preset-env": "^7.4.4", + "@babel/runtime": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4", "@iarna/toml": "^2.2.0", "@parcel/fs": "^1.11.0", - "@parcel/logger": "^1.11.0", + "@parcel/logger": "^1.11.1", "@parcel/utils": "^1.11.0", - "@parcel/watcher": "^1.12.0", + "@parcel/watcher": "^1.12.1", "@parcel/workers": "^1.11.0", "ansi-to-html": "^0.6.4", "babylon-walk": "^1.0.2", @@ -25227,12 +25222,14 @@ "clone": "^2.1.1", "command-exists": "^1.2.6", "commander": "^2.11.0", + "core-js": "^2.6.5", "cross-spawn": "^6.0.4", "css-modules-loader-core": "^1.1.0", "cssnano": "^4.0.0", "deasync": "^0.1.14", "dotenv": "^5.0.0", - "dotenv-expand": "^4.2.0", + "dotenv-expand": "^5.1.0", + "envinfo": "^7.3.1", "fast-glob": "^2.2.2", "filesize": "^3.6.0", "get-port": "^3.2.0", @@ -25253,7 +25250,7 @@ "posthtml-render": "^1.1.3", "resolve": "^1.4.0", "semver": "^5.4.1", - "serialize-to-js": "^1.1.1", + "serialize-to-js": "^3.0.0", "serve-static": "^1.12.4", "source-map": "0.6.1", "terser": "^3.7.3", @@ -25261,180 +25258,14 @@ "ws": "^5.1.1" }, "dependencies": { - "@babel/core": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", - "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.3.4", - "@babel/helpers": "^7.2.0", - "@babel/parser": "^7.3.4", - "@babel/template": "^7.2.2", - "@babel/traverse": "^7.3.4", - "@babel/types": "^7.3.4", - "convert-source-map": "^1.1.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.11", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", - "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.3.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/parser": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", - "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", - "dev": true - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", - "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" - } - }, - "@babel/preset-env": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.4.tgz", - "integrity": "sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA==", + "@babel/plugin-transform-flow-strip-types": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz", + "integrity": "sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.3.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.3.4", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.3.4", - "@babel/plugin-transform-classes": "^7.3.4", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.2.0", - "@babel/plugin-transform-dotall-regex": "^7.2.0", - "@babel/plugin-transform-duplicate-keys": "^7.2.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.2.0", - "@babel/plugin-transform-function-name": "^7.2.0", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", - "@babel/plugin-transform-modules-systemjs": "^7.3.4", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", - "@babel/plugin-transform-new-target": "^7.0.0", - "@babel/plugin-transform-object-super": "^7.2.0", - "@babel/plugin-transform-parameters": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.3.4", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.2.0", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.2.0", - "browserslist": "^4.3.4", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.3.0" - } - }, - "@babel/runtime": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.4.tgz", - "integrity": "sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.12.0" - } - }, - "@babel/template": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", - "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.2.2", - "@babel/types": "^7.2.2" - } - }, - "@babel/traverse": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", - "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.3.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.3.4", - "@babel/types": "^7.3.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } - }, - "@babel/types": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", - "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" + "@babel/plugin-syntax-flow": "^7.2.0" } }, "clone": { @@ -25443,6 +25274,12 @@ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, + "core-js": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", + "dev": true + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -25456,21 +25293,6 @@ "which": "^1.2.9" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -25480,28 +25302,16 @@ "minimist": "^1.2.0" } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, "postcss-value-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", - "dev": true - }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "source-map": { @@ -25629,9 +25439,9 @@ "dev": true }, "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, "path-dirname": { @@ -25651,12 +25461,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -25859,9 +25663,9 @@ } }, "plur": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.0.1.tgz", - "integrity": "sha512-lJl0ojUynAM1BZn58Pas2WT/TXeC1+bS+UqShl0x9+49AtOn7DixRXVzaC8qrDOIxNDmepKnLuMTH7NQmkX0PA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", + "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", "dev": true, "requires": { "irregular-plurals": "^2.0.0" @@ -26828,36 +26632,13 @@ "dev": true }, "posthtml": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.3.tgz", - "integrity": "sha512-quMHnDckt2DQ9lRi6bYLnuyBDnVzK+McHa8+ar4kTdYbWEo/92hREOu3h70ZirudOOp/my2b3r0m5YtxY52yrA==", + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.6.tgz", + "integrity": "sha512-C2hrAPzmRdpuL3iH0TDdQ6XCc9M7Dcc3zEW5BLerY65G4tWWszwv6nG/ksi6ul5i2mx22ubdljgktXCtNkydkw==", "dev": true, "requires": { - "object-assign": "^4.1.1", - "posthtml-parser": "^0.3.3", - "posthtml-render": "^1.1.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "posthtml-parser": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.3.3.tgz", - "integrity": "sha512-H/Z/yXGwl49A7hYQLV1iQ3h87NE0aZ/PMZhFwhw3lKeCAN+Ti4idrHvVvh4/GX10I7u77aQw+QB4vV5/Lzvv5A==", - "dev": true, - "requires": { - "htmlparser2": "^3.9.2", - "isobject": "^2.1.0", - "object-assign": "^4.1.1" - } - } + "posthtml-parser": "^0.4.1", + "posthtml-render": "^1.1.5" } }, "posthtml-parser": { @@ -26871,9 +26652,9 @@ } }, "posthtml-render": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.4.tgz", - "integrity": "sha512-jL6eFIzoN3xUEvbo33OAkSDE2VIKU4JQ1wENOows1DpfnrdapR/K3Q1/fB43Mq7wQlcSgRm23nFrvoioufM7eA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz", + "integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w==", "dev": true }, "prelude-ls": { @@ -27276,9 +27057,9 @@ "dev": true }, "puppeteer": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.19.0.tgz", - "integrity": "sha512-2S6E6ygpoqcECaagDbBopoSOPDv0pAZvTbnBgUY+6hq0/XDFDOLEMNlHF/SKJlzcaZ9ckiKjKDuueWI3FN/WXw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", "dev": true, "requires": { "debug": "^4.1.0", @@ -27514,6 +27295,20 @@ "@babel/runtime": "^7.0.0" } }, + "react-color": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.3.tgz", + "integrity": "sha512-1dtO8LqAVotPIChlmo6kLtFS1FP89ll8/OiA8EcFRDR+ntcK+0ukJgByuIQHRtzvigf26dV5HklnxDIvhON9VQ==", + "dev": true, + "requires": { + "@icons/material": "^0.2.4", + "lodash": "^4.17.11", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + } + }, "react-dates": { "version": "17.2.0", "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-17.2.0.tgz", @@ -27941,6 +27736,15 @@ "prop-types": "^15.6.1" } }, + "react-input-autosize": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz", + "integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==", + "dev": true, + "requires": { + "prop-types": "^15.5.8" + } + }, "react-is": { "version": "16.8.4", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", @@ -28535,9 +28339,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.2.tgz", - "integrity": "sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", "dev": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -28566,10 +28370,26 @@ "integrity": "sha512-ITw8t/HOFNose2yf1y9pPFSSeB9ISOq2JdHpuZvj/Qb+iSsLml8GkkHdDlURzieO7B3dFDtMrrneZLl3N5z/hg==", "dev": true }, + "react-select": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.0.8.tgz", + "integrity": "sha512-v9LpOhckLlRmXN5A6/mGGEft4FMrfaBFTGAnuPHcUgVId7Je42kTq9y0Z+Ye5z8/j0XDT3zUqza8gaRaI1PZIg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@emotion/cache": "^10.0.9", + "@emotion/core": "^10.0.9", + "@emotion/css": "^10.0.9", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^2.2.2", + "react-transition-group": "^2.2.1" + } + }, "react-sizeme": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-2.6.7.tgz", - "integrity": "sha512-xCjPoBP5jmeW58TxIkcviMZqabZis7tTvDFWf0/Wa5XCgVWQTIe74NQBes2N1Kmp64GRLkpm60BaP0kk+v8aCQ==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-2.6.8.tgz", + "integrity": "sha512-eJKHV226d/S3st2He7bLIlY7FAmi2ItvZmUCmLLNjIvYjtiv58BksuFhTBQmvAxWaXZGb3Ao/44wfAS1voRdjA==", "dev": true, "requires": { "element-resize-detector": "^1.1.15", @@ -28640,6 +28460,18 @@ "react-proxy": "^1.1.7" } }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "dev": true, + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "react-with-direction": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.0.tgz", @@ -28675,6 +28507,15 @@ "global-cache": "^1.2.1" } }, + "reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "dev": true, + "requires": { + "lodash": "^4.0.1" + } + }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -28685,18 +28526,18 @@ } }, "read-cmd-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz", - "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.4.tgz", + "integrity": "sha512-Pqpl3qJ/QdOIjRYA0q5DND/gLvGOfpIz/fYVDGYpOXfW/lFrIttmLsBnd6IkyK10+JHU9zhsaudfvrQTBB9YFQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2" } }, "read-package-json": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.13.tgz", - "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.0.tgz", + "integrity": "sha512-KLhu8M1ZZNkMcrq1+0UJbR8Dii8KZUqB0Sha4mOx/bknfKI/fyrQVrG/YIt2UOtG667sD8+ee4EXMM91W9dC+A==", "dev": true, "requires": { "glob": "^7.1.1", @@ -28958,202 +28799,6 @@ "safe-regex": "^1.1.0" } }, - "regexp-tree": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.1.tgz", - "integrity": "sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw==", - "dev": true, - "requires": { - "cli-table3": "^0.5.0", - "colors": "^1.1.2", - "yargs": "^12.0.5" - }, - "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, - "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mem": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", - "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^2.0.0" - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-is-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", - "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", - "dev": true - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, "regexp.prototype.flags": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", @@ -29277,12 +28922,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -29300,9 +28945,9 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/plugin-proposal-object-rest-spread": { @@ -29327,26 +28972,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -29935,15 +29580,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "safer-eval": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/safer-eval/-/safer-eval-1.3.5.tgz", - "integrity": "sha512-BJ//K2Y+EgCbOHEsDGS5YahYBcYy7JcFpKDo2ba5t4MnOGHYtk7HvQkcxTDFvjQvJ0CRcdas/PyF+gTTCay+3w==", - "dev": true, - "requires": { - "clones": "^1.2.0" - } - }, "sane": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", @@ -30156,6 +29792,15 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "requires": { + "xmlchars": "^2.1.1" + } + }, "scheduler": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", @@ -30265,14 +29910,10 @@ "dev": true }, "serialize-to-js": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-1.2.2.tgz", - "integrity": "sha512-mUc8vA5iJghe+O+3s0YDGFLMJcqitVFk787YKiv8a4sf6RX5W0u81b+gcHrp15O0fFa010dRBVZvwcKXOWsL9Q==", - "dev": true, - "requires": { - "js-beautify": "^1.8.9", - "safer-eval": "^1.3.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.0.0.tgz", + "integrity": "sha512-WdGgi0jGnWCQXph2p3vkxceDnTfvfyXfYxherQMRcZjSaJzMQdMBAW6i0nojsBKIZ3fFOztZKKVbbm05VbIdRA==", + "dev": true }, "serve-favicon": { "version": "2.5.0", @@ -30492,12 +30133,6 @@ } } }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -30790,6 +30425,17 @@ "requires": { "agent-base": "~4.2.1", "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } } }, "sort-keys": { @@ -30804,7 +30450,8 @@ "source-list-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==" + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true }, "source-map": { "version": "0.5.7", @@ -32251,69 +31898,11 @@ "source-map-support": "~0.5.10" }, "dependencies": { - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "terser": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz", - "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -33180,42 +32769,146 @@ "dev": true }, "uncss": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.16.2.tgz", - "integrity": "sha1-OyJpxZAS2nxmy+mPvt3e75TwZJw=", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.17.2.tgz", + "integrity": "sha512-hu2HquwDItuGDem4YsJROdAD8SknmWtM24zwhQax6J1se8tPjV1cnwPKhtjodzBaUhaL8Zb3hlGdZ2WAUpbAOg==", "dev": true, "requires": { - "commander": "^2.9.0", - "glob": "^7.0.3", - "is-absolute-url": "^2.0.0", - "is-html": "^1.0.0", - "jsdom": "^11.3.0", - "lodash": "^4.13.1", - "postcss": "^6.0.14", - "postcss-selector-parser": "3.1.1", - "request": "^2.72.0" + "commander": "^2.20.0", + "glob": "^7.1.4", + "is-absolute-url": "^3.0.1", + "is-html": "^1.1.0", + "jsdom": "^14.1.0", + "lodash": "^4.17.15", + "postcss": "^7.0.17", + "postcss-selector-parser": "6.0.2", + "request": "^2.88.0" }, "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "abab": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz", + "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==", + "dev": true + }, + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" } }, - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "escodegen": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", + "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "jsdom": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", + "integrity": "sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.1.3", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "postcss": { + "version": "7.0.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz", + "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, "source-map": { @@ -33223,6 +32916,60 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } } } }, @@ -33347,6 +33094,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "dev": true, "requires": { "imurmurhash": "^0.1.4" } @@ -33513,12 +33261,6 @@ } } }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true - }, "upper-case": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", @@ -33600,9 +33342,9 @@ "dev": true }, "schema-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", - "integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz", + "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==", "dev": true, "requires": { "ajv": "^6.10.2", @@ -33685,9 +33427,9 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", - "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "dev": true }, "validate-npm-package-license": { @@ -33709,12 +33451,6 @@ "builtins": "^1.0.3" } }, - "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", - "dev": true - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -33786,13 +33522,10 @@ "dev": true }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true }, "w3c-hr-time": { "version": "1.0.1", @@ -33803,6 +33536,17 @@ "browser-process-hrtime": "^0.1.2" } }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, "wait-on": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.3.0.tgz", @@ -34773,9 +34517,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "make-dir": { @@ -34795,9 +34539,9 @@ "dev": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -34886,6 +34630,12 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "xmldoc": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-0.4.0.tgz", diff --git a/package.json b/package.json index 31d63d691e3b5c..87179bff38b782 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.6.0", + "version": "6.8.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", @@ -72,22 +72,24 @@ "@babel/runtime-corejs3": "7.4.5", "@babel/traverse": "7.4.5", "@octokit/rest": "16.26.0", - "@storybook/addon-a11y": "5.2.3", - "@storybook/addon-docs": "5.2.3", - "@storybook/addon-storysource": "5.2.3", - "@storybook/addon-viewport": "5.2.3", - "@storybook/react": "5.2.3", + "@storybook/addon-a11y": "5.2.4", + "@storybook/addon-docs": "5.2.4", + "@storybook/addon-knobs": "5.2.4", + "@storybook/addon-storysource": "5.2.4", + "@storybook/addon-viewport": "5.2.4", + "@storybook/react": "5.2.4", "@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma", "@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot", "@wordpress/babel-preset-default": "file:packages/babel-preset-default", + "@wordpress/base-styles": "file:packages/base-styles", "@wordpress/browserslist-config": "file:packages/browserslist-config", "@wordpress/custom-templated-path-webpack-plugin": "file:packages/custom-templated-path-webpack-plugin", "@wordpress/dependency-extraction-webpack-plugin": "file:packages/dependency-extraction-webpack-plugin", "@wordpress/docgen": "file:packages/docgen", "@wordpress/e2e-test-utils": "file:packages/e2e-test-utils", "@wordpress/e2e-tests": "file:packages/e2e-tests", - "@wordpress/eslint-plugin": "file:packages/eslint-plugin", "@wordpress/env": "file:packages/env", + "@wordpress/eslint-plugin": "file:packages/eslint-plugin", "@wordpress/jest-console": "file:packages/jest-console", "@wordpress/jest-preset-default": "file:packages/jest-preset-default", "@wordpress/jest-puppeteer-axe": "file:packages/jest-puppeteer-axe", @@ -121,7 +123,7 @@ "jest-junit": "6.4.0", "jest-serializer-enzyme": "1.0.0", "jsdom": "11.12.0", - "lerna": "3.16.4", + "lerna": "3.18.2", "lint-staged": "9.2.5", "lodash": "4.17.15", "make-dir": "3.0.0", @@ -130,7 +132,7 @@ "mkdirp": "0.5.1", "node-sass": "4.12.0", "node-watch": "0.6.0", - "parcel-bundler": "1.12.3", + "parcel-bundler": "1.12.4", "postcss": "7.0.13", "progress": "2.0.3", "react": "16.9.0", @@ -153,34 +155,6 @@ "webpack": "4.41.0", "worker-farm": "1.7.0" }, - "npmPackageJsonLintConfig": { - "extends": "@wordpress/npm-package-json-lint-config", - "rules": { - "description-format": [ - "error", - { - "requireCapitalFirstLetter": true, - "requireEndingPeriod": true - } - ], - "require-publishConfig": "error", - "require-repository-directory": "error", - "valid-values-author": [ - "error", - [ - "The WordPress Contributors" - ] - ], - "valid-values-publishConfig": [ - "error", - [ - { - "access": "public" - } - ] - ] - } - }, "scripts": { "prebuild": "npm run check-engines", "clean:packages": "rimraf ./packages/*/build ./packages/*/build-module ./packages/*/build-style ./packages/*/node_modules", @@ -203,7 +177,7 @@ "lint-js": "wp-scripts lint-js", "lint-js:fix": "npm run lint-js -- --fix", "lint-php": "wp-scripts env lint-php", - "lint-pkg-json": "wp-scripts lint-pkg-json ./packages", + "lint-pkg-json": "wp-scripts lint-pkg-json . 'packages/*/package.json'", "lint-css": "wp-scripts lint-style '**/*.scss'", "lint-css:fix": "npm run lint-css -- --fix", "lint-types": "tsc", @@ -213,9 +187,7 @@ "publish:dev": "npm run build:packages && lerna publish --npm-tag next", "publish:prod": "npm run build:packages && lerna publish", "test": "npm run lint && npm run test-unit", - "pretest-e2e": "npm run env reinstall", "test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", - "test-e2e:local": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", "test-e2e:watch": "npm run test-e2e:local -- --watch", "test-performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js", "test-php": "npm run lint-php && npm run test-unit-php", @@ -227,7 +199,7 @@ "test-unit:native": "cd test/native/ && cross-env NODE_ENV=test jest --config ./jest.config.js", "test-unit:native:debug": "cd test/native/ && node --inspect ../../node_modules/.bin/jest --runInBand --config ./jest.config.js", "design-system:build": "npm run build:packages && build-storybook -c ./packages/components/storybook -o ./playground/dist/design-system/components", - "design-system:dev": "concurrently \"npm run dev:packages\" \"start-storybook -c ./packages/components/storybook\"", + "design-system:dev": "npm run build:packages && concurrently \"npm run dev:packages\" \"start-storybook -c ./packages/components/storybook\"", "playground:build": "npm run build:packages && parcel build playground/src/index.html -d playground/dist", "playground:dev": "concurrently \"npm run dev:packages\" \"parcel playground/src/index.html -d playground/dist\"", "preenv": "npm run check-engines", diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 546abcd609a520..eb2f11f3a971d8 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "2.5.0", + "version": "2.5.1", "description": "Accessibility (a11y) utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/annotations/package.json b/packages/annotations/package.json index 62608fae8a7b73..2f08cd7c0901bd 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/annotations", - "version": "1.7.0", + "version": "1.7.2", "description": "Annotate content in the Gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index 26876a3e860239..462c964c370c6b 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "3.6.0", + "version": "3.6.3", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/src/index.js b/packages/api-fetch/src/index.js index 7535d2117b2f24..dc7dda91fa1e60 100644 --- a/packages/api-fetch/src/index.js +++ b/packages/api-fetch/src/index.js @@ -1,8 +1,3 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ @@ -13,6 +8,8 @@ import fetchAllMiddleware from './middlewares/fetch-all-middleware'; import namespaceEndpointMiddleware from './middlewares/namespace-endpoint'; import httpV1Middleware from './middlewares/http-v1'; import userLocaleMiddleware from './middlewares/user-locale'; +import mediaUploadMiddleware from './middlewares/media-upload'; +import { parseResponseAndNormalizeError, parseAndThrowError } from './utils/response'; /** * Default set of header values which should be sent with every request unless @@ -80,48 +77,10 @@ const defaultFetchHandler = ( nextOptions ) => { } ); - const parseResponse = ( response ) => { - if ( parse ) { - if ( response.status === 204 ) { - return null; - } - - return response.json ? response.json() : Promise.reject( response ); - } - - return response; - }; - return responsePromise .then( checkStatus ) - .then( parseResponse ) - .catch( ( response ) => { - if ( ! parse ) { - throw response; - } - - const invalidJsonError = { - code: 'invalid_json', - message: __( 'The response is not a valid JSON response.' ), - }; - - if ( ! response || ! response.json ) { - throw invalidJsonError; - } - - return response.json() - .catch( () => { - throw invalidJsonError; - } ) - .then( ( error ) => { - const unknownError = { - code: 'unknown_error', - message: __( 'An unknown error occurred.' ), - }; - - throw error || unknownError; - } ); - } ); + .catch( ( response ) => parseAndThrowError( response, parse ) ) + .then( ( response ) => parseResponseAndNormalizeError( response, parse ) ); }; let fetchHandler = defaultFetchHandler; @@ -179,5 +138,6 @@ apiFetch.createNonceMiddleware = createNonceMiddleware; apiFetch.createPreloadingMiddleware = createPreloadingMiddleware; apiFetch.createRootURLMiddleware = createRootURLMiddleware; apiFetch.fetchAllMiddleware = fetchAllMiddleware; +apiFetch.mediaUploadMiddleware = mediaUploadMiddleware; export default apiFetch; diff --git a/packages/api-fetch/src/middlewares/media-upload.js b/packages/api-fetch/src/middlewares/media-upload.js new file mode 100644 index 00000000000000..6772aaf3ded733 --- /dev/null +++ b/packages/api-fetch/src/middlewares/media-upload.js @@ -0,0 +1,74 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { + parseAndThrowError, + parseResponseAndNormalizeError, +} from '../utils/response'; + +/** + * Middleware handling media upload failures and retries. + * + * @param {Object} options Fetch options. + * @param {Function} next [description] + * + * @return {*} The evaluated result of the remaining middleware chain. + */ +function mediaUploadMiddleware( options, next ) { + const isMediaUploadRequest = + ( options.path && options.path.indexOf( '/wp/v2/media' ) !== -1 ) || + ( options.url && options.url.indexOf( '/wp/v2/media' ) !== -1 ); + + if ( ! isMediaUploadRequest ) { + return next( options, next ); + } + let retries = 0; + const maxRetries = 5; + + const postProcess = ( attachmentId ) => { + retries++; + return next( { + path: `/wp/v2/media/${ attachmentId }/post-process`, + method: 'POST', + data: { action: 'create-image-subsizes' }, + parse: false, + } ) + .catch( () => { + if ( retries < maxRetries ) { + return postProcess( attachmentId ); + } + next( { + path: `/wp/v2/media/${ attachmentId }?force=true`, + method: 'DELETE', + } ); + + return Promise.reject(); + } ); + }; + + return next( { ...options, parse: false } ) + .catch( ( response ) => { + const attachmentId = response.headers.get( 'x-wp-upload-attachment-id' ); + if ( response.status >= 500 && response.status < 600 && attachmentId ) { + return postProcess( attachmentId ).catch( () => { + if ( options.parse !== false ) { + return Promise.reject( { + code: 'post_process', + message: __( 'Media upload failed. If this is a photo or a large image, please scale it down and try again.' ), + } ); + } + + return Promise.reject( response ); + } ); + } + return parseAndThrowError( response, options.parse ); + } ) + .then( ( response ) => parseResponseAndNormalizeError( response, options.parse ) ); +} + +export default mediaUploadMiddleware; diff --git a/packages/api-fetch/src/utils/response.js b/packages/api-fetch/src/utils/response.js new file mode 100644 index 00000000000000..bb7b79ce2f8254 --- /dev/null +++ b/packages/api-fetch/src/utils/response.js @@ -0,0 +1,70 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Parses the apiFetch response. + * + * @param {Response} response + * @param {boolean} shouldParseResponse + * + * @return {Promise} Parsed response + */ +const parseResponse = ( response, shouldParseResponse = true ) => { + if ( shouldParseResponse ) { + if ( response.status === 204 ) { + return null; + } + + return response.json ? response.json() : Promise.reject( response ); + } + + return response; +}; + +const parseJsonAndNormalizeError = ( response ) => { + const invalidJsonError = { + code: 'invalid_json', + message: __( 'The response is not a valid JSON response.' ), + }; + + if ( ! response || ! response.json ) { + throw invalidJsonError; + } + + return response.json() + .catch( () => { + throw invalidJsonError; + } ); +}; + +/** + * Parses the apiFetch response properly and normalize response errors. + * + * @param {Response} response + * @param {boolean} shouldParseResponse + * + * @return {Promise} Parsed response. + */ +export const parseResponseAndNormalizeError = ( response, shouldParseResponse = true ) => { + return Promise.resolve( parseResponse( response, shouldParseResponse ) ) + .catch( ( res ) => parseAndThrowError( res, shouldParseResponse ) ); +}; + +export function parseAndThrowError( response, shouldParseResponse = true ) { + if ( ! shouldParseResponse ) { + throw response; + } + + return parseJsonAndNormalizeError( response ) + .then( ( error ) => { + const unknownError = { + code: 'unknown_error', + message: __( 'An unknown error occurred.' ), + }; + + throw error || unknownError; + } ); +} + diff --git a/packages/autop/package.json b/packages/autop/package.json index 0f63cb48560d3c..ef57d2a3a0516b 100644 --- a/packages/autop/package.json +++ b/packages/autop/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/autop", - "version": "2.5.0", + "version": "2.5.1", "description": "WordPress's automatic paragraph functions `autop` and `removep`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index e8f3df29218a58..c02981fc1316cc 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-preset-default", - "version": "4.6.0", + "version": "4.6.2", "description": "Default Babel preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/base-styles/.npmrc b/packages/base-styles/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/base-styles/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/base-styles/README.md b/packages/base-styles/README.md new file mode 100644 index 00000000000000..20945fd08acf8f --- /dev/null +++ b/packages/base-styles/README.md @@ -0,0 +1,51 @@ +# Base Styles + +Base SCSS utilities and variables for WordPress. + +## Installation + +Install the module + +```bash +npm install @wordpress/base-styles --save-dev +``` + +## Use + +### SCSS utilities and variables + +In your application's SCSS file, include styles like so: + +```scss +@import "node_modules/@wordpress/base-styles/colors"; +@import "node_modules/@wordpress/base-styles/variables"; +@import "node_modules/@wordpress/base-styles/mixins"; +@import "node_modules/@wordpress/base-styles/breakpoints"; +@import "node_modules/@wordpress/base-styles/animations"; +@import "node_modules/@wordpress/base-styles/z-index"; +``` + +If you use [Webpack](https://webpack.js.org/) for your SCSS pipeline, you can use `~` to resolve to `node_modules`: + +```scss +@import "~@wordpress/base-styles/colors"; +``` + +To make that work with [`sass`](https://www.npmjs.com/package/sass) or [`node-sass`](https://www.npmjs.com/package/node-sass) NPM modules without Webpack, you'd have to use [includePaths option](https://sass-lang.com/documentation/js-api#includepaths): + +```json +{ + "includePaths": ["node_modules"] +} +``` + +### PostCSS color schemes + +To use color schemes with [`@wordpress/postcss-themes`](https://www.npmjs.com/package/@wordpress/postcss-themes), import them like so: + +```js +const { adminColorSchemes } = require( '@wordpress/base-styles' ); +const wpPostcss = require( '@wordpress/postcss-themes' )( adminColorSchemes ) +``` + +

Code is Poetry.

diff --git a/assets/stylesheets/_animations.scss b/packages/base-styles/_animations.scss similarity index 100% rename from assets/stylesheets/_animations.scss rename to packages/base-styles/_animations.scss diff --git a/assets/stylesheets/_breakpoints.scss b/packages/base-styles/_breakpoints.scss similarity index 100% rename from assets/stylesheets/_breakpoints.scss rename to packages/base-styles/_breakpoints.scss diff --git a/assets/stylesheets/_colors.scss b/packages/base-styles/_colors.scss similarity index 100% rename from assets/stylesheets/_colors.scss rename to packages/base-styles/_colors.scss diff --git a/assets/stylesheets/_mixins.scss b/packages/base-styles/_mixins.scss similarity index 100% rename from assets/stylesheets/_mixins.scss rename to packages/base-styles/_mixins.scss diff --git a/assets/stylesheets/_variables.scss b/packages/base-styles/_variables.scss similarity index 100% rename from assets/stylesheets/_variables.scss rename to packages/base-styles/_variables.scss diff --git a/assets/stylesheets/_z-index.scss b/packages/base-styles/_z-index.scss similarity index 98% rename from assets/stylesheets/_z-index.scss rename to packages/base-styles/_z-index.scss index 7b7e0aedd55301..36cc265a0b7f64 100644 --- a/assets/stylesheets/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -24,6 +24,7 @@ $z-layers: ( ".block-editor-warning": 5, ".block-library-gallery-item__inline-menu": 20, ".block-editor-url-input__suggestions": 30, + ".edit-post-layout__footer": 30, ".edit-post-header": 30, ".edit-widgets-header": 30, ".block-library-button__inline-link .block-editor-url-input__suggestions": 6, // URL suggestions for button block above sibling inserter @@ -31,6 +32,7 @@ $z-layers: ( ".wp-block-cover__inner-container": 1, // InnerBlocks area inside cover image block ".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. + ".wp-block-site-title__save-button": 1, // Active pill button ".components-button.is-button {:focus or .is-primary}": 1, diff --git a/packages/base-styles/index.js b/packages/base-styles/index.js new file mode 100644 index 00000000000000..bac5dede479a12 --- /dev/null +++ b/packages/base-styles/index.js @@ -0,0 +1,60 @@ +exports.adminColorSchemes = { + defaults: { + primary: '#0085ba', + secondary: '#11a0d2', + toggle: '#11a0d2', + button: '#007cba', + outlines: '#007cba', + }, + themes: { + 'admin-color-light': { + primary: '#0085ba', + secondary: '#c75726', + toggle: '#11a0d2', + button: '#0085ba', + outlines: '#007cba', + }, + 'admin-color-blue': { + primary: '#82b4cb', + secondary: '#d9ab59', + toggle: '#82b4cb', + button: '#d9ab59', + outlines: '#417e9B', + }, + 'admin-color-coffee': { + primary: '#c2a68c', + secondary: '#9fa47b', + toggle: '#c2a68c', + button: '#c2a68c', + outlines: '#59524c', + }, + 'admin-color-ectoplasm': { + primary: '#a7b656', + secondary: '#c77430', + toggle: '#a7b656', + button: '#a7b656', + outlines: '#523f6d', + }, + 'admin-color-midnight': { + primary: '#e14d43', + secondary: '#77a6b9', + toggle: '#77a6b9', + button: '#e14d43', + outlines: '#497b8d', + }, + 'admin-color-ocean': { + primary: '#a3b9a2', + secondary: '#a89d8a', + toggle: '#a3b9a2', + button: '#a3b9a2', + outlines: '#5e7d5e', + }, + 'admin-color-sunrise': { + primary: '#d1864a', + secondary: '#c8b03c', + toggle: '#c8b03c', + button: '#d1864a', + outlines: '#837425', + }, + }, +}; diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json new file mode 100644 index 00000000000000..9e54a1f0a86864 --- /dev/null +++ b/packages/base-styles/package.json @@ -0,0 +1,25 @@ +{ + "name": "@wordpress/base-styles", + "version": "1.0.0-alpha.1", + "description": "Base SCSS utilities and variables for WordPress.", + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "sass", + "scss", + "css" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/base-styles/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/base-styles" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/blob/package.json b/packages/blob/package.json index 5d6682a3df85f1..4d04f47eb2a3c7 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "2.5.0", + "version": "2.5.1", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 7c6af26534df97..22ff8e4e8f8c2b 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "1.0.0", + "version": "1.0.3", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -29,6 +29,7 @@ "@wordpress/data": "file:../data", "@wordpress/element": "file:../element", "@wordpress/i18n": "file:../i18n", + "@wordpress/plugins": "file:../plugins", "lodash": "^4.17.15" }, "publishConfig": { diff --git a/packages/block-directory/src/index.js b/packages/block-directory/src/index.js index 5c088e8d5928d3..3af7027bf74d02 100644 --- a/packages/block-directory/src/index.js +++ b/packages/block-directory/src/index.js @@ -2,5 +2,4 @@ * Internal dependencies */ import './store'; - -export { default as DownloadableBlocksPanel } from './components/downloadable-blocks-panel'; +import './plugins'; diff --git a/packages/block-directory/src/plugins/index.js b/packages/block-directory/src/plugins/index.js new file mode 100644 index 00000000000000..917b8567c2d87f --- /dev/null +++ b/packages/block-directory/src/plugins/index.js @@ -0,0 +1,15 @@ +/** + * WordPress dependencies + */ +import { registerPlugin } from '@wordpress/plugins'; + +/** + * Internal dependencies + */ +import InserterMenuDownloadableBlocksPanel from './inserter-menu-downloadable-blocks-panel'; + +registerPlugin( 'block-directory', { + render() { + return ; + }, +} ); diff --git a/packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js b/packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js similarity index 89% rename from packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js rename to packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js index d19d76ba42ad84..9fb2cc8105dc0b 100644 --- a/packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js +++ b/packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js @@ -7,9 +7,13 @@ import { debounce } from 'lodash'; * WordPress dependencies */ import { __experimentalInserterMenuExtension } from '@wordpress/block-editor'; -import { DownloadableBlocksPanel } from '@wordpress/block-directory'; import { useState } from '@wordpress/element'; +/** + * Internal dependencies + */ +import DownloadableBlocksPanel from '../../components/downloadable-blocks-panel'; + function InserterMenuDownloadableBlocksPanel() { const [ debouncedFilterValue, setFilterValue ] = useState( '' ); diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index d9c7818065c0b5..432d36a72ac70c 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -82,6 +82,14 @@ _Related_ Undocumented declaration. +# **BlockBreadcrumb** + +Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. + +_Returns_ + +- `WPElement`: Block Breadcrumb. + # **BlockControls** Undocumented declaration. @@ -137,7 +145,7 @@ _Parameters_ _Returns_ -- `WPElement`: Rendered element. +- `WPComponent`: The component to be rendered. # **BlockSelectionClearer** @@ -171,6 +179,10 @@ _Related_ Undocumented declaration. +# **ColorPaletteControl** + +Undocumented declaration. + # **ContrastChecker** Undocumented declaration. @@ -392,6 +404,7 @@ The default editor settings **experimentalEnableLegacyWidgetBlock boolean Whether the user has enabled the Legacy Widget Block **experimentalEnableMenuBlock boolean Whether the user has enabled the Menu Block **experimentalBlockDirectory boolean Whether the user has enabled the Block Directory + \_\_experimentalEnableFullSiteEditing boolean Whether the user has enabled Full Site Editing # **SkipToSelectedBlock** @@ -446,6 +459,10 @@ _Related_ - +# **useBlockEditContext** + +Undocumented declaration. + # **Warning** Undocumented declaration. diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 8517b2126deadd..9d9f00f675fb27 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "3.2.0", + "version": "3.2.3", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/src/components/autocomplete/index.native.js b/packages/block-editor/src/components/autocomplete/index.native.js new file mode 100644 index 00000000000000..461f67a0a4bcbe --- /dev/null +++ b/packages/block-editor/src/components/autocomplete/index.native.js @@ -0,0 +1 @@ +export default () => null; diff --git a/packages/block-editor/src/components/block-breadcrumb/index.js b/packages/block-editor/src/components/block-breadcrumb/index.js new file mode 100644 index 00000000000000..adc96ba4eb2d51 --- /dev/null +++ b/packages/block-editor/src/components/block-breadcrumb/index.js @@ -0,0 +1,77 @@ +/** + * WordPress dependencies + */ +import { Button } from '@wordpress/components'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import BlockTitle from '../block-title'; + +/** + * Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. + * + * @return {WPElement} Block Breadcrumb. + */ +const BlockBreadcrumb = function() { + const { selectBlock, clearSelectedBlock } = useDispatch( 'core/block-editor' ); + const { clientId, parents, hasSelection } = useSelect( ( select ) => { + const { + getSelectionStart, + getSelectedBlockClientId, + getBlockParents, + } = select( 'core/block-editor' ); + const selectedBlockClientId = getSelectedBlockClientId(); + return { + parents: getBlockParents( selectedBlockClientId ), + clientId: selectedBlockClientId, + hasSelection: !! getSelectionStart().clientId, + }; + }, [] ); + + /* + * Disable reason: The `list` ARIA role is redundant but + * Safari+VoiceOver won't announce the list otherwise. + */ + /* eslint-disable jsx-a11y/no-redundant-roles */ + return ( +
    +
  • + { hasSelection && ( + + ) } + { ! hasSelection && __( 'Document' ) } +
  • + { parents.map( ( parentClientId ) => ( +
  • + +
  • + ) ) } + { !! clientId && ( +
  • + +
  • + ) } +
+ /* eslint-enable jsx-a11y/no-redundant-roles */ + ); +}; + +export default BlockBreadcrumb; diff --git a/packages/block-editor/src/components/block-breadcrumb/style.scss b/packages/block-editor/src/components/block-breadcrumb/style.scss new file mode 100644 index 00000000000000..b20cdd273b2566 --- /dev/null +++ b/packages/block-editor/src/components/block-breadcrumb/style.scss @@ -0,0 +1,41 @@ +.block-editor-block-breadcrumb { + list-style: none; + padding: 0; + margin: 0; + + li { + display: inline-block; + margin: 0; + + &:not(:last-child)::after { + content: "\2192"; // This becomes →. + } + } +} + +.block-editor-block-breadcrumb__button.components-button { + height: $icon-button-size-small; + line-height: $icon-button-size-small; + padding: 0; + + &:hover { + text-decoration: underline; + } + + &:focus { + @include square-style__focus(); + outline-offset: -2px; + box-shadow: none; + } +} + +.block-editor-block-breadcrumb__current { + cursor: default; +} + +.block-editor-block-breadcrumb__button.components-button, +.block-editor-block-breadcrumb__current { + color: $dark-gray-500; + padding: 0 $grid-size; + font-size: inherit; +} diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index 863cdc3e5d6fa5..08f2ac9f1dd6b1 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -6,19 +6,29 @@ import { noop } from 'lodash'; /** * WordPress dependencies */ -import { createContext } from '@wordpress/element'; +import { createContext, useContext } from '@wordpress/element'; import { createHigherOrderComponent } from '@wordpress/compose'; -const { Consumer, Provider } = createContext( { +const Context = createContext( { name: '', isSelected: false, focusedElement: null, setFocusedElement: noop, clientId: null, } ); +const { Provider, Consumer } = Context; export { Provider as BlockEditContextProvider }; +/** + * A hook that returns the block edit context. + * + * @return {Object} Block edit context + */ +export function useBlockEditContext() { + return useContext( Context ); +} + /** * A Higher Order Component used to inject BlockEdit context to the * wrapped component. @@ -27,7 +37,7 @@ export { Provider as BlockEditContextProvider }; * expected to return object of props to * merge with the component's own props. * - * @return {Component} Enhanced component with injected context as props. + * @return {WPComponent} Enhanced component with injected context as props. */ export const withBlockEditContext = ( mapContextToProps ) => createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( @@ -46,9 +56,9 @@ export const withBlockEditContext = ( mapContextToProps ) => createHigherOrderCo * A Higher Order Component used to render conditionally the wrapped * component only when the BlockEdit has selected state set. * - * @param {Component} OriginalComponent Component to wrap. + * @param {WPComponent} OriginalComponent Component to wrap. * - * @return {Component} Component which renders only when the BlockEdit is selected. + * @return {WPComponent} Component which renders only when the BlockEdit is selected. */ export const ifBlockEditSelected = createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index 63c475a50692ff..403a5cd87898e3 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -12,7 +12,7 @@ import { Component } from '@wordpress/element'; * Internal dependencies */ import Edit from './edit'; -import { BlockEditContextProvider } from './context'; +import { BlockEditContextProvider, useBlockEditContext } from './context'; class BlockEdit extends Component { constructor() { @@ -44,3 +44,4 @@ class BlockEdit extends Component { } export default BlockEdit; +export { useBlockEditContext }; diff --git a/packages/block-editor/src/components/block-list/block-async-mode-provider.js b/packages/block-editor/src/components/block-list/block-async-mode-provider.js index aaa2e709db92c6..3cdde80050761c 100644 --- a/packages/block-editor/src/components/block-list/block-async-mode-provider.js +++ b/packages/block-editor/src/components/block-list/block-async-mode-provider.js @@ -1,10 +1,7 @@ /** * WordPress dependencies */ -import { - __experimentalAsyncModeProvider as AsyncModeProvider, - useSelect, -} from '@wordpress/data'; +import { AsyncModeProvider, useSelect } from '@wordpress/data'; const BlockAsyncModeProvider = ( { children, clientId, isBlockInSelection } ) => { const isParentOfSelectedBlock = useSelect( ( select ) => { diff --git a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js index cdd54ffdcaca1b..7e09fe8de46f79 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js +++ b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js @@ -10,21 +10,23 @@ import styles from './block-mobile-floating-toolbar.scss'; /** * WordPress dependencies */ +import { compose, withPreferredColorScheme } from '@wordpress/compose'; import { createSlotFill } from '@wordpress/components'; const { Fill, Slot } = createSlotFill( 'FloatingToolbar' ); -function FloatingToolbar( { children } ) { +const FloatingToolbarFill = ( { children, getStylesFromColorScheme } ) => { return ( { ( { innerFloatingToolbar } ) => { + const fillStyle = getStylesFromColorScheme( styles.floatingToolbarFillColor, styles.floatingToolbarFillColorDark ); return ( { children } @@ -33,8 +35,9 @@ function FloatingToolbar( { children } ) { ); -} +}; +const FloatingToolbar = compose( withPreferredColorScheme )( FloatingToolbarFill ); FloatingToolbar.Slot = Slot; export default FloatingToolbar; diff --git a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss index 713633516fca23..a9fbd1243e89ab 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss +++ b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss @@ -1,5 +1,4 @@ .floatingToolbarFill { - background-color: $dark-gray-500; margin: auto; min-width: 100; max-height: $floating-toolbar-height; @@ -13,3 +12,11 @@ justify-content: center; align-self: center; } + +.floatingToolbarFillColor { + background-color: rgba(#1d2327, 0.85); +} + +.floatingToolbarFillColorDark { + background-color: rgba(#3c434a, 0.85); +} diff --git a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js b/packages/block-editor/src/components/block-list/block-mobile-toolbar.js index f35a7add73641a..8af64ec12c021b 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js +++ b/packages/block-editor/src/components/block-list/block-mobile-toolbar.js @@ -9,11 +9,11 @@ import { ifViewportMatches } from '@wordpress/viewport'; import BlockMover from '../block-mover'; import VisualEditorInserter from '../inserter'; -function BlockMobileToolbar( { clientId } ) { +function BlockMobileToolbar( { clientId, moverDirection } ) { return (
- +
); } diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 777cb54933a80b..48b5506e452f2f 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -67,6 +67,7 @@ function BlockListBlock( { mode, isFocusMode, hasFixedToolbar, + moverDirection, isLocked, clientId, rootClientId, @@ -450,6 +451,20 @@ function BlockListBlock( { }; } const blockElementId = `block-${ clientId }`; + const blockMover = ( + + ); // We wrap the BlockEdit component in a div that hides it when editing in // HTML mode. This allows us to render all of the ancillary pieces @@ -511,22 +526,18 @@ function BlockListBlock( { rootClientId={ rootClientId } /> { isFirstMultiSelected && ( - + ) } -
- { shouldRenderMovers && ( - +
+ { shouldRenderMovers && ( moverDirection === 'vertical' ) && blockMover } { shouldShowBreadcrumb && ( ) } + { shouldRenderMovers && ( moverDirection === 'horizontal' ) && blockMover } { ! isValid && [ { !! hasError && } { shouldShowMobileToolbar && ( - + ) }
diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 456c5fad6ac2ab..70d8ff2435b907 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -25,6 +25,7 @@ import BlockEdit from '../block-edit'; import BlockInvalidWarning from './block-invalid-warning'; import BlockMobileToolbar from './block-mobile-toolbar'; import FloatingToolbar from './block-mobile-floating-toolbar'; +import Breadcrumbs from './breadcrumb'; import NavigateUpSVG from './nav-up-icon'; class BlockListBlock extends Component { @@ -136,6 +137,7 @@ class BlockListBlock extends Component { /> + ) } { const { setNavigationMode } = useDispatch( 'core/block-editor' ); diff --git a/packages/block-editor/src/components/block-list/breadcrumb.native.js b/packages/block-editor/src/components/block-list/breadcrumb.native.js new file mode 100644 index 00000000000000..0bea56e4da6ddf --- /dev/null +++ b/packages/block-editor/src/components/block-list/breadcrumb.native.js @@ -0,0 +1,68 @@ +/** + * WordPress dependencies + */ +import { Icon } from '@wordpress/components'; +import { withSelect } from '@wordpress/data'; +import { compose } from '@wordpress/compose'; +import { getBlockType } from '@wordpress/blocks'; + +/** + * External dependencies + */ +import { View, Text, TouchableOpacity } from 'react-native'; + +/** + * Internal dependencies + */ +import BlockTitle from '../block-title'; +import SubdirectorSVG from './subdirectory-icon'; + +import styles from './breadcrumb.scss'; + +const BlockBreadcrumb = ( { clientId, blockIcon, rootClientId, rootBlockIcon } ) => { + return ( + + {/* Open BottomSheet with markup */} }> + { rootClientId && rootBlockIcon && ( + [ , + , + ] + ) } + + + + + ); +}; + +export default compose( [ + withSelect( ( select, { clientId } ) => { + const { + getBlockRootClientId, + getBlockName, + } = select( 'core/block-editor' ); + + const blockName = getBlockName( clientId ); + const blockType = getBlockType( blockName ); + const blockIcon = blockType.icon; + + const rootClientId = getBlockRootClientId( clientId ); + + if ( ! rootClientId ) { + return { + clientId, + blockIcon, + }; + } + const rootBlockName = getBlockName( rootClientId ); + const rootBlockType = getBlockType( rootBlockName ); + const rootBlockIcon = rootBlockType.icon; + + return { + clientId, + blockIcon, + rootClientId, + rootBlockIcon, + }; + } ), +] )( BlockBreadcrumb ); diff --git a/packages/block-editor/src/components/block-list/breadcrumb.native.scss b/packages/block-editor/src/components/block-list/breadcrumb.native.scss new file mode 100644 index 00000000000000..8e9b103446291c --- /dev/null +++ b/packages/block-editor/src/components/block-list/breadcrumb.native.scss @@ -0,0 +1,28 @@ +.breadcrumbContainer { + flex-direction: row; + align-items: center; + justify-content: flex-start; + padding-left: 5; + padding-right: 15; +} + +.breadcrumbTitle { + color: $white; + margin-left: 4; +} + +.icon { + color: $white; +} + +.button { + flex-direction: row; + align-items: center; +} + +.arrow { + color: $light-opacity-light-700; + margin-top: -4px; + margin-left: 4; + margin-right: 4; +} diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 25386d5039c12c..54511ac941ecc4 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -17,7 +17,7 @@ import { Component } from '@wordpress/element'; import { withSelect, withDispatch, - __experimentalAsyncModeProvider as AsyncModeProvider, + AsyncModeProvider, } from '@wordpress/data'; import { compose } from '@wordpress/compose'; @@ -195,6 +195,7 @@ class BlockList extends Component { className, blockClientIds, rootClientId, + __experimentalMoverDirection: moverDirection = 'vertical', isDraggable, selectedBlockClientId, multiSelectedBlockClientIds, @@ -227,6 +228,7 @@ class BlockList extends Component { blockRef={ this.setBlockRef } onSelectionStart={ this.onSelectionStart } isDraggable={ isDraggable } + moverDirection={ moverDirection } // This prop is explicitely computed and passed down // to avoid being impacted by the async mode diff --git a/packages/block-editor/src/components/block-list/multi-controls.js b/packages/block-editor/src/components/block-list/multi-controls.js index e4dd88aeda030f..2f49ca2ca0a3b4 100644 --- a/packages/block-editor/src/components/block-list/multi-controls.js +++ b/packages/block-editor/src/components/block-list/multi-controls.js @@ -11,6 +11,7 @@ import BlockMover from '../block-mover'; function BlockListMultiControls( { multiSelectedBlockClientIds, isSelecting, + moverDirection, } ) { if ( isSelecting ) { return null; @@ -19,6 +20,7 @@ function BlockListMultiControls( { return ( ); } diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index 761632c49d7c7f..e06667a0f914e7 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -101,6 +101,9 @@ .block-editor-block-list__block-edit { position: relative; + &.has-mover-inside > [data-block] { + display: flex; + } &::before { z-index: z-index(".block-editor-block-list__block-edit::before"); diff --git a/packages/block-editor/src/components/block-list/subdirectory-icon.js b/packages/block-editor/src/components/block-list/subdirectory-icon.js new file mode 100644 index 00000000000000..9da2bc4a1c88a9 --- /dev/null +++ b/packages/block-editor/src/components/block-list/subdirectory-icon.js @@ -0,0 +1,18 @@ +/** + * WordPress dependencies + */ +import { SVG, Path } from '@wordpress/components'; + +const Subdirectory = ( { ...extraProps } ) => ( + + + ) +; + +export default Subdirectory; diff --git a/packages/block-editor/src/components/block-mover/icons.js b/packages/block-editor/src/components/block-mover/icons.js index 06bf5601f439db..2a15b8a6159d5d 100644 --- a/packages/block-editor/src/components/block-mover/icons.js +++ b/packages/block-editor/src/components/block-mover/icons.js @@ -9,12 +9,24 @@ export const upArrow = ( ); +export const leftArrow = ( + + + +); + export const downArrow = ( ); +export const rightArrow = ( + + + +); + export const dragHandle = ( @@ -107,6 +141,8 @@ export class BlockMover extends Component { isFirst, isLast, 1, + orientation, + isRTL, ) } @@ -125,12 +161,17 @@ export default compose( const blockOrder = getBlockOrder( rootClientId ); const firstIndex = getBlockIndex( firstClientId, rootClientId ); const lastIndex = getBlockIndex( last( normalizedClientIds ), rootClientId ); + const { getSettings } = select( 'core/block-editor' ); + const { + isRTL, + } = getSettings(); return { blockType: block ? getBlockType( block.name ) : null, isLocked: getTemplateLock( rootClientId ) === 'all', rootClientId, firstIndex, + isRTL, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, }; diff --git a/packages/block-editor/src/components/block-mover/mover-description.js b/packages/block-editor/src/components/block-mover/mover-description.js index 44174ce85534ca..d9a62de176d821 100644 --- a/packages/block-editor/src/components/block-mover/mover-description.js +++ b/packages/block-editor/src/components/block-mover/mover-description.js @@ -14,12 +14,30 @@ import { __, _n, sprintf } from '@wordpress/i18n'; * @param {boolean} isLast This is the last block. * @param {number} dir Direction of movement (> 0 is considered to be going * down, < 0 is up). + * @param {string} orientation The orientation of the block movers, vertical or + * horizontal. + * @param {boolean} isRTL True if current writing system is right to left. * * @return {string} Label for the block movement controls. */ -export function getBlockMoverDescription( selectedCount, type, firstIndex, isFirst, isLast, dir ) { +export function getBlockMoverDescription( selectedCount, type, firstIndex, isFirst, isLast, dir, orientation, isRTL ) { const position = ( firstIndex + 1 ); + const getMovementDirection = ( moveDirection ) => { + if ( moveDirection === 'up' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? 'right' : 'left'; + } + return 'up'; + } else if ( moveDirection === 'down' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? 'left' : 'right'; + } + return 'down'; + } + return null; + }; + if ( selectedCount > 1 ) { return getMultiBlockMoverDescription( selectedCount, firstIndex, isFirst, isLast, dir ); } @@ -32,35 +50,46 @@ export function getBlockMoverDescription( selectedCount, type, firstIndex, isFir if ( dir > 0 && ! isLast ) { // moving down return sprintf( - // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position - __( 'Move %1$s block from position %2$d down to position %3$d' ), + // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: Direction of movement ( up, down, left, right ), 4: New position + __( 'Move %1$s block from position %2$d %3$s to position %4$d' ), type, position, - ( position + 1 ) + getMovementDirection( 'down' ), + ( position + 1 ), ); } if ( dir > 0 && isLast ) { // moving down, and is the last item - // translators: %s: Type of block (i.e. Text, Image etc) - return sprintf( __( 'Block %s is at the end of the content and can’t be moved down' ), type ); + // translators: 1: Type of block (i.e. Text, Image etc), 2: Direction of movement ( up, down, left, right ) + return sprintf( + __( 'Block %1$s is at the end of the content and can’t be moved %2$s' ), + type, + getMovementDirection( 'down' ), + + ); } if ( dir < 0 && ! isFirst ) { // moving up return sprintf( - // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position - __( 'Move %1$s block from position %2$d up to position %3$d' ), + // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: Direction of movement ( up, down, left, right ), 4: New position + __( 'Move %1$s block from position %2$d %3$s to position %4$d' ), type, position, - ( position - 1 ) + getMovementDirection( 'up' ), + ( position - 1 ), ); } if ( dir < 0 && isFirst ) { // moving up, and is the first item - // translators: %s: Type of block (i.e. Text, Image etc) - return sprintf( __( 'Block %s is at the beginning of the content and can’t be moved up' ), type ); + // translators: 1: Type of block (i.e. Text, Image etc), 2: Direction of movement ( up, down, left, right ) + return sprintf( + __( 'Block %1$s is at the beginning of the content and can’t be moved %2$s' ), + type, + getMovementDirection( 'up' ), + ); } } diff --git a/packages/block-editor/src/components/block-mover/style.scss b/packages/block-editor/src/components/block-mover/style.scss index a506b3282fad42..260d456c73d3c0 100644 --- a/packages/block-editor/src/components/block-mover/style.scss +++ b/packages/block-editor/src/components/block-mover/style.scss @@ -1,5 +1,4 @@ .block-editor-block-mover { - @include break-small() { min-height: $empty-paragraph-height; opacity: 0; @@ -20,13 +19,38 @@ // 24px is the smallest size of a good pressable button. // With 3 pieces of side UI, that comes to a total of 72px. // To vertically center against a 56px paragraph, move upwards 72px - 56px / 2. - // Don't do this for wide, fullwide, or mobile. - .block-editor-block-list__block:not([data-align="wide"]):not([data-align="full"]) & { - margin-top: -$grid-size; + margin-top: -$grid-size; + } + + &.is-horizontal { + margin-top: 5px; // The height of the appender is 36px. This pushes down the mover to be centered according to that. + margin-right: $grid-size; + padding-right: 0; + min-height: auto; + width: ($icon-button-size-small * 2) + ($border-width * 2); + height: $icon-button-size-small + ($border-width * 2); + display: flex; + + .block-editor-block-mover__control { + width: $icon-button-size-small; + height: $icon-button-size-small; + + svg { + width: $icon-button-size-small; + padding: 3px; + } } } } +// Don't add negative vertical margin for wide, fullwide, or mobile. +// @todo: simplify this selector. +@include break-small() { + .block-editor-block-list__block:not([data-align="wide"]):not([data-align="full"]) .editor-block-mover:not(.is-horizontal) { + margin-top: 0; + } +} + // Mover icon buttons. .block-editor-block-mover__control { display: flex; diff --git a/packages/block-editor/src/components/block-navigation/list.js b/packages/block-editor/src/components/block-navigation/list.js index 0a34d24ff4e4b6..a0910caf5b41cc 100644 --- a/packages/block-editor/src/components/block-navigation/list.js +++ b/packages/block-editor/src/components/block-navigation/list.js @@ -10,12 +10,35 @@ import classnames from 'classnames'; import { Button } from '@wordpress/components'; import { getBlockType } from '@wordpress/blocks'; import { __ } from '@wordpress/i18n'; +import { create, getTextContent } from '@wordpress/rich-text'; /** * Internal dependencies */ import BlockIcon from '../block-icon'; +/** + * Get the block display name, if it has one, or the block title if it doesn't. + * + * @param {Object} blockType The block type. + * @param {Object} attributes The values of the block's attributes + * + * @return {string} The display name value. + */ +function getBlockDisplayName( blockType, attributes ) { + const displayNameAttribute = blockType.__experimentalDisplayName; + + if ( ! displayNameAttribute || ! attributes[ displayNameAttribute ] ) { + return blockType.title; + } + + // Strip any formatting. + const richTextValue = create( { html: attributes[ displayNameAttribute ] } ); + const formatlessDisplayName = getTextContent( richTextValue ); + + return formatlessDisplayName; +} + export default function BlockNavigationList( { blocks, selectedBlockClientId, @@ -43,7 +66,7 @@ export default function BlockNavigationList( { onClick={ () => selectBlock( block.clientId ) } > - { blockType.title } + { getBlockDisplayName( blockType, block.attributes ) } { isSelected && { __( '(selected block)' ) } }
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index 8a6692a422a6f7..00ae9233a12501 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -137,7 +137,7 @@ export function BlockPreview( { blocks, viewportWidth = 700, padding, settings } * * @param {Array|Object} blocks A block instance (object) or an array of blocks to be previewed. * @param {number} viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700. - * @return {WPElement} Rendered element. + * @return {WPComponent} The component to be rendered. */ export default withSelect( ( select ) => { return { diff --git a/packages/block-editor/src/components/block-settings/container.native.js b/packages/block-editor/src/components/block-settings/container.native.js index c51a42b39de6d0..1b59377f29161c 100644 --- a/packages/block-editor/src/components/block-settings/container.native.js +++ b/packages/block-editor/src/components/block-settings/container.native.js @@ -6,12 +6,18 @@ import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { InspectorControls } from '@wordpress/block-editor'; +/** + * Internal dependencies + */ +import styles from './container.native.scss'; + function BottomSheetSettings( { editorSidebarOpened, closeGeneralSidebar, ...props } ) { return ( diff --git a/packages/block-editor/src/components/block-settings/container.native.scss b/packages/block-editor/src/components/block-settings/container.native.scss new file mode 100644 index 00000000000000..2eed1c9e3f2d00 --- /dev/null +++ b/packages/block-editor/src/components/block-settings/container.native.scss @@ -0,0 +1,4 @@ +.content { + padding-left: 0; + padding-right: 0; +} diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index e83f34bc54eadd..a6247b03d3177b 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -49,6 +49,8 @@ .block-editor-block-toolbar__slot { // Required for IE11. display: inline-block; + // Fix for toolbar button misalignment on IE11 + line-height: 0; // IE11 doesn't read rules inside this query. They are applied only to modern browsers. @supports (position: sticky) { diff --git a/packages/block-editor/src/components/button-block-appender/index.js b/packages/block-editor/src/components/button-block-appender/index.js index 7fd751165f5b45..1cbbb5980903a2 100644 --- a/packages/block-editor/src/components/button-block-appender/index.js +++ b/packages/block-editor/src/components/button-block-appender/index.js @@ -6,8 +6,8 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Button, Icon } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; +import { Button, Icon, Tooltip } from '@wordpress/components'; +import { _x, sprintf } from '@wordpress/i18n'; /** * Internal dependencies @@ -21,17 +21,31 @@ function ButtonBlockAppender( { rootClientId, className } ) { ( - - ) } + renderToggle={ ( { onToggle, disabled, isOpen, blockTitle, hasSingleBlockType } ) => { + let label; + if ( hasSingleBlockType ) { + // translators: %s: the name of the block when there is only one + label = sprintf( _x( 'Add %s', 'directly add the only allowed block' ), blockTitle ); + } else { + label = _x( 'Add block', 'Generic label for block inserter button' ); + } + const isToggleButton = ! hasSingleBlockType; + return ( + + + + ); + } } isAppender /> diff --git a/packages/block-editor/src/components/colors/index.js b/packages/block-editor/src/components/colors/index.js index f6b6fac984db89..cadb34a8c9aa37 100644 --- a/packages/block-editor/src/components/colors/index.js +++ b/packages/block-editor/src/components/colors/index.js @@ -7,3 +7,4 @@ export { createCustomColorsHOC, default as withColors, } from './with-colors'; +export { default as __experimentalUseColors } from './use-colors'; diff --git a/packages/block-editor/src/components/colors/use-colors.js b/packages/block-editor/src/components/colors/use-colors.js new file mode 100644 index 00000000000000..d69ee1bdbadf9a --- /dev/null +++ b/packages/block-editor/src/components/colors/use-colors.js @@ -0,0 +1,226 @@ +/** + * External dependencies + */ +import memoize from 'memize'; +import classnames from 'classnames'; +import { + camelCase, + kebabCase, + map, + startCase, +} from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { + useCallback, + useMemo, + Children, + cloneElement, +} from '@wordpress/element'; + +/** + * Internal dependencies + */ +import PanelColorSettings from '../panel-color-settings'; +import ContrastChecker from '../contrast-checker'; +import InspectorControls from '../inspector-controls'; +import { useBlockEditContext } from '../block-edit'; + +const ColorPanel = ( { + title, + colorSettings, + colorPanelProps, + contrastCheckerProps, + components, + panelChildren, +} ) => ( + + { contrastCheckerProps && + map( components, ( ( Component, key ) => ( + + ) ) ) } + { typeof panelChildren === 'function' ? + panelChildren( components ) : + panelChildren } + +); +const InspectorControlsColorPanel = ( props ) => ( + + + +); + +export default function __experimentalUseColors( + colorConfigs, + { + panelTitle = __( 'Color Settings' ), + colorPanelProps, + contrastCheckerProps, + panelChildren, + } = { + panelTitle: __( 'Color Settings' ), + }, + deps = [] +) { + const { clientId } = useBlockEditContext(); + const { attributes, settingsColors } = useSelect( + ( select ) => { + const { getBlockAttributes, getSettings } = select( 'core/block-editor' ); + return { + attributes: getBlockAttributes( clientId ), + settingsColors: getSettings().colors, + }; + }, + [ clientId ] + ); + const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); + const setAttributes = useCallback( + ( newAttributes ) => updateBlockAttributes( clientId, newAttributes ), + [ updateBlockAttributes, clientId ] + ); + + const createComponent = useMemo( + () => + memoize( + ( name, property, className, color, colorValue, customColor ) => ( { + children, + className: componentClassName = '', + style: componentStyle = {}, + } ) => + // Clone children, setting the style property from the color configuration, + // if not already set explicitly through props. + Children.map( children, ( child ) => { + let colorStyle = {}; + if ( color ) { + colorStyle = { [ property ]: colorValue }; + } else if ( customColor ) { + colorStyle = { [ property ]: customColor }; + } + + return cloneElement( child, { + className: classnames( + componentClassName, + child.props.className, + { + [ `has-${ kebabCase( color ) }-${ kebabCase( property ) }` ]: color, + [ className || `has-${ kebabCase( name ) }` ]: color || customColor, + } + ), + style: { + ...colorStyle, + ...componentStyle, + ...( child.props.style || {} ), + }, + } ); + } ), + { maxSize: colorConfigs.length } + ), + [ colorConfigs.length ] + ); + const createSetColor = useMemo( + () => + memoize( + ( name, colors ) => ( newColor ) => { + const color = colors.find( ( _color ) => _color.color === newColor ); + setAttributes( { + [ color ? camelCase( `custom ${ name }` ) : name ]: undefined, + } ); + setAttributes( { + [ color ? name : camelCase( `custom ${ name }` ) ]: color ? + color.slug : + newColor, + } ); + }, + { + maxSize: colorConfigs.length, + } + ), + [ setAttributes, colorConfigs.length ] + ); + + return useMemo( () => { + const colorSettings = {}; + + const components = colorConfigs.reduce( ( acc, colorConfig ) => { + if ( typeof colorConfig === 'string' ) { + colorConfig = { name: colorConfig }; + } + const { + name, // E.g. 'backgroundColor'. + property = name, // E.g. 'backgroundColor'. + className, + + panelLabel = startCase( name ), // E.g. 'Background Color'. + componentName = panelLabel.replace( /\s/g, '' ), // E.g. 'BackgroundColor'. + + color = colorConfig.color, + colors = settingsColors, + } = { + ...colorConfig, + color: attributes[ colorConfig.name ], + }; + + // We memoize the non-primitives to avoid unnecessary updates + // when they are used as props for other components. + const _color = colors.find( ( __color ) => __color.slug === color ); + acc[ componentName ] = createComponent( + name, + property, + className, + color, + _color && _color.color, + attributes[ camelCase( `custom ${ name }` ) ] + ); + acc[ componentName ].displayName = componentName; + acc[ componentName ].color = color; + acc[ componentName ].setColor = createSetColor( name, colors ); + + colorSettings[ componentName ] = { + value: _color ? + _color.color : + attributes[ camelCase( `custom ${ name }` ) ], + onChange: acc[ componentName ].setColor, + label: panelLabel, + colors, + }; + // These settings will be spread over the `colors` in + // `colorPanelProps`, so we need to unset the key here, + // if not set to an actual value, to avoid overwriting + // an actual value in `colorPanelProps`. + if ( ! colors ) { + delete colorSettings[ componentName ].colors; + } + + return acc; + }, {} ); + + const wrappedColorPanelProps = { + title: panelTitle, + colorSettings, + colorPanelProps, + contrastCheckerProps, + components, + panelChildren, + }; + return { + ...components, + ColorPanel: , + InspectorControlsColorPanel: ( + + ), + }; + }, [ attributes, setAttributes, ...deps ] ); +} diff --git a/packages/block-editor/src/components/colors/with-colors.js b/packages/block-editor/src/components/colors/with-colors.js index b6f33b1b8590f7..4544c6c8c49e1e 100644 --- a/packages/block-editor/src/components/colors/with-colors.js +++ b/packages/block-editor/src/components/colors/with-colors.js @@ -49,7 +49,7 @@ const withEditorColorPalette = () => withSelect( ( select ) => { * @param {Array} colorTypes An array of color types (e.g. 'backgroundColor, borderColor). * @param {Function} withColorPalette A HOC for injecting the 'colors' prop into the WrappedComponent. * - * @return {Component} The component that can be used as a HOC. + * @return {WPComponent} The component that can be used as a HOC. */ function createColorHOC( colorTypes, withColorPalette ) { const colorMap = reduce( colorTypes, ( colorObject, colorType ) => { diff --git a/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap index 9a09dae0d47674..08a0f7df9efe74 100644 --- a/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap +++ b/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap @@ -29,7 +29,7 @@ exports[`DefaultBlockAppender should append a default block when input focused 1 rows={1} value="Start writing or type / to choose a block" /> - @@ -53,7 +53,7 @@ exports[`DefaultBlockAppender should match snapshot 1`] = ` rows={1} value="Start writing or type / to choose a block" /> - @@ -77,7 +77,7 @@ exports[`DefaultBlockAppender should optionally show without prompt 1`] = ` rows={1} value="" /> - diff --git a/packages/block-editor/src/components/gradient-picker/control.js b/packages/block-editor/src/components/gradient-picker/control.js index 73609ffdf17e27..a0eeecc6facc25 100644 --- a/packages/block-editor/src/components/gradient-picker/control.js +++ b/packages/block-editor/src/components/gradient-picker/control.js @@ -3,19 +3,27 @@ * External dependencies */ import classnames from 'classnames'; +import { isEmpty } from 'lodash'; /** * WordPress dependencies */ import { BaseControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import GradientPicker from './'; -export default function( { className, ...props } ) { +export default function( { className, label = __( 'Gradient Presets' ), ...props } ) { + const gradients = useSelect( ( select ) => ( + select( 'core/block-editor' ).getSettings().gradients + ) ); + if ( isEmpty( gradients ) ) { + return null; + } return ( - { __( 'Gradient Presets' ) } + { label } diff --git a/packages/block-editor/src/components/gradient-picker/panel.js b/packages/block-editor/src/components/gradient-picker/panel.js new file mode 100644 index 00000000000000..2be91125cbc110 --- /dev/null +++ b/packages/block-editor/src/components/gradient-picker/panel.js @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { isEmpty } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { PanelBody } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import GradientPicker from './control'; + +export default function GradientPanel( props ) { + const gradients = useSelect( ( select ) => ( + select( 'core/block-editor' ).getSettings().gradients + ) ); + if ( isEmpty( gradients ) ) { + return null; + } + return ( + + + + ); +} diff --git a/packages/block-editor/src/components/gradients/index.js b/packages/block-editor/src/components/gradients/index.js new file mode 100644 index 00000000000000..b08be314861e03 --- /dev/null +++ b/packages/block-editor/src/components/gradients/index.js @@ -0,0 +1,77 @@ +/** + * External dependencies + */ +import { find } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useCallback } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { useBlockEditContext } from '../block-edit'; + +export function __experimentalGetGradientClass( gradientSlug ) { + if ( ! gradientSlug ) { + return undefined; + } + return `has-${ gradientSlug }-gradient-background`; +} + +function getGradientValueBySlug( gradients, slug ) { + const gradient = find( gradients, [ 'slug', slug ] ); + return gradient && gradient.gradient; +} + +function getGradientSlugByValue( gradients, value ) { + const gradient = find( gradients, [ 'gradient', value ] ); + return gradient && gradient.slug; +} + +export function __experimentalUseGradient( { + gradientAttribute = 'gradient', + customGradientAttribute = 'customGradient', +} = {} ) { + const { clientId } = useBlockEditContext(); + + const { gradients, gradient, customGradient } = useSelect( ( select ) => { + const { getBlockAttributes, getSettings } = select( 'core/block-editor' ); + const attributes = getBlockAttributes( clientId ); + return { + gradient: attributes[ gradientAttribute ], + customGradient: attributes[ customGradientAttribute ], + gradients: getSettings().gradients, + }; + }, [ clientId ] ); + + const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); + const setGradient = useCallback( + ( newGradientValue ) => { + const slug = getGradientSlugByValue( gradients, newGradientValue ); + if ( slug ) { + updateBlockAttributes( clientId, { + [ gradientAttribute ]: slug, + [ customGradientAttribute ]: undefined, + } ); + return; + } + updateBlockAttributes( clientId, { + [ gradientAttribute ]: undefined, + [ customGradientAttribute ]: newGradientValue, + } ); + }, + [ gradients, clientId, updateBlockAttributes ] + ); + + const gradientClass = __experimentalGetGradientClass( gradient ); + let gradientValue; + if ( gradient ) { + gradientValue = getGradientValueBySlug( gradients, gradient ); + } else { + gradientValue = customGradient; + } + return { gradientClass, gradientValue, setGradient }; +} diff --git a/packages/block-editor/src/components/ignore-nested-events/index.js b/packages/block-editor/src/components/ignore-nested-events/index.js index 2592ba3abd0527..92bbe5ed44c639 100644 --- a/packages/block-editor/src/components/ignore-nested-events/index.js +++ b/packages/block-editor/src/components/ignore-nested-events/index.js @@ -20,7 +20,7 @@ import { Component, forwardRef, createElement } from '@wordpress/element'; * element should stop propagation but not invoke a callback handler, since it * would be assumed these are invoked by the child element. * - * @type {Component} + * @type {WPComponent} */ export class IgnoreNestedEvents extends Component { constructor() { diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 6e9bb592378678..9b094396d9d8b0 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -3,12 +3,14 @@ */ export * from './colors'; +export * from './gradients'; export * from './font-sizes'; export { default as AlignmentToolbar } from './alignment-toolbar'; export { default as Autocomplete } from './autocomplete'; export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; +export { default as BlockBreadcrumb } from './block-breadcrumb'; export { default as BlockControls } from './block-controls'; -export { default as BlockEdit } from './block-edit'; +export { default as BlockEdit, useBlockEditContext } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; export { default as BlockIcon } from './block-icon'; export { default as BlockNavigationDropdown } from './block-navigation/dropdown'; @@ -16,12 +18,15 @@ export { default as __experimentalBlockNavigationList } from './block-navigation export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar'; export { default as ButtonBlockerAppender } from './button-block-appender'; export { default as ColorPalette } from './color-palette'; +export { default as ColorPaletteControl } from './color-palette/control'; export { default as ContrastChecker } from './contrast-checker'; export { default as __experimentalGradientPicker } from './gradient-picker'; export { default as __experimentalGradientPickerControl } from './gradient-picker/control'; +export { default as __experimentalGradientPickerPanel } from './gradient-picker/panel'; export { default as InnerBlocks } from './inner-blocks'; export { default as InspectorAdvancedControls } from './inspector-advanced-controls'; export { default as InspectorControls } from './inspector-controls'; +export { default as __experimentalLinkControl } from './link-control'; export { default as MediaPlaceholder } from './media-placeholder'; export { default as MediaUpload } from './media-upload'; export { default as MediaUploadCheck } from './media-upload/check'; diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index b278e29d4555a9..6baafd5d8f0bbe 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -1,6 +1,7 @@ // Block Creation Components +export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; export { default as BlockControls } from './block-controls'; -export { default as BlockEdit } from './block-edit'; +export { default as BlockEdit, useBlockEditContext } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; export { default as BlockIcon } from './block-icon'; export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar'; diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index 35e1bf10b47ca2..ed147bfe736adf 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -107,6 +107,7 @@ class InnerBlocks extends Component { hasOverlay, renderAppender, template, + __experimentalMoverDirection: moverDirection, __experimentalTemplateOptions: templateOptions, __experimentalOnSelectTemplateOption: onSelectTemplateOption, __experimentalAllowTemplateOptionSkip: allowTemplateOptionSkip, @@ -131,6 +132,7 @@ class InnerBlocks extends Component { ) } diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index 5abb1ae4ef9230..b9fd9dead4b377 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -1,29 +1,46 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, _x, sprintf } from '@wordpress/i18n'; import { Dropdown, IconButton } from '@wordpress/components'; import { Component } from '@wordpress/element'; -import { withSelect } from '@wordpress/data'; +import { withDispatch, withSelect } from '@wordpress/data'; import { compose, ifCondition } from '@wordpress/compose'; +import { + createBlock, + getBlockType, +} from '@wordpress/blocks'; /** * Internal dependencies */ import InserterMenu from './menu'; -const defaultRenderToggle = ( { onToggle, disabled, isOpen } ) => ( - -); +const defaultRenderToggle = ( { onToggle, disabled, isOpen, blockTitle, hasSingleBlockType } ) => { + let label; + if ( hasSingleBlockType ) { + // translators: %s: the name of the block when there is only one + label = sprintf( _x( 'Add %s', 'directly add the only allowed block' ), blockTitle ); + } else { + label = _x( 'Add block', 'Generic label for block inserter button' ); + } + return ( + + ); +}; class Inserter extends Component { constructor() { @@ -56,10 +73,12 @@ class Inserter extends Component { renderToggle( { onToggle, isOpen } ) { const { disabled, + blockTitle, + hasSingleBlockType, renderToggle = defaultRenderToggle, } = this.props; - return renderToggle( { onToggle, isOpen, disabled } ); + return renderToggle( { onToggle, isOpen, disabled, blockTitle, hasSingleBlockType } ); } /** @@ -86,8 +105,10 @@ class Inserter extends Component { } render() { - const { position } = this.props; - + const { position, hasSingleBlockType, insertOnlyAllowedBlock } = this.props; + if ( hasSingleBlockType ) { + return this.renderToggle( { onToggle: insertOnlyAllowedBlock } ); + } return ( { - const { hasInserterItems } = select( 'core/block-editor' ); + const { + hasInserterItems, + __experimentalGetAllowedBlocks, + } = select( 'core/block-editor' ); + + const allowedBlocks = __experimentalGetAllowedBlocks( rootClientId ); + const hasSingleBlockType = allowedBlocks && ( get( allowedBlocks, [ 'length' ], 0 ) === 1 ); + let allowedBlockType = false; + if ( hasSingleBlockType ) { + allowedBlockType = getBlockType( allowedBlocks ); + } return { hasItems: hasInserterItems( rootClientId ), + hasSingleBlockType, + blockTitle: allowedBlockType ? allowedBlockType.title : '', + allowedBlockType, + }; + } ), + withDispatch( ( dispatch, ownProps, { select } ) => { + return { + insertOnlyAllowedBlock() { + const { rootClientId, clientId, isAppender, destinationRootClientId } = ownProps; + const { + hasSingleBlockType, + allowedBlockType, + } = ownProps; + + if ( ! hasSingleBlockType ) { + return; + } + + function getInsertionIndex() { + const { + getBlockIndex, + getBlockSelectionEnd, + getBlockOrder, + } = select( 'core/block-editor' ); + + // If the clientId is defined, we insert at the position of the block. + if ( clientId ) { + return getBlockIndex( clientId, destinationRootClientId ); + } + + // If there a selected block, we insert after the selected block. + const end = getBlockSelectionEnd(); + if ( ! isAppender && end ) { + return getBlockIndex( end, destinationRootClientId ) + 1; + } + + // Otherwise, we insert at the end of the current rootClientId + return getBlockOrder( destinationRootClientId ).length; + } + + const { + insertBlock, + } = dispatch( 'core/block-editor' ); + + const blockToInsert = createBlock( allowedBlockType.name ); + insertBlock( + blockToInsert, + getInsertionIndex(), + rootClientId + ); + }, }; } ), ifCondition( ( { hasItems } ) => hasItems ), diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md new file mode 100644 index 00000000000000..e21c29974301b1 --- /dev/null +++ b/packages/block-editor/src/components/link-control/README.md @@ -0,0 +1,50 @@ +# Link Control + +## Props + +### className + +- Type: `String` +- Required: Yes + +### currentLink + +- Type: `Object` +- Required: Yes + +### currentSettings + +- Type: `Object` +- Required: Yes + +### fetchSearchSuggestions + +- Type: `Function` +- Required: No + +## Event handlers + +### onClose + +- Type: `Function` +- Required: No + +### onKeyDown + +- Type: `Function` +- Required: No + +### onKeyPress + +- Type: `Function` +- Required: No + +### onLinkChange + +- Type: `Function` +- Required: No + +### onSettingChange + +- Type: `Function` +- Required: No diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js new file mode 100644 index 00000000000000..afe72df4f2e93d --- /dev/null +++ b/packages/block-editor/src/components/link-control/index.js @@ -0,0 +1,249 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { isFunction, noop, startsWith } from 'lodash'; + +/** + * WordPress dependencies + */ +import { + Button, + ExternalLink, + Popover, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +import { + useCallback, + useState, + useEffect, + Fragment, +} from '@wordpress/element'; + +import { + safeDecodeURI, + filterURLForDisplay, + isURL, + prependHTTP, + getProtocol, +} from '@wordpress/url'; + +import { withInstanceId, compose } from '@wordpress/compose'; +import { withSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import LinkControlSettingsDrawer from './settings-drawer'; +import LinkControlSearchItem from './search-item'; +import LinkControlSearchInput from './search-input'; + +function LinkControl( { + className, + currentLink, + currentSettings, + fetchSearchSuggestions, + instanceId, + onClose = noop, + onKeyDown = noop, + onKeyPress = noop, + onLinkChange = noop, + onSettingsChange = { noop }, +} ) { + // State + const [ inputValue, setInputValue ] = useState( '' ); + const [ isEditingLink, setIsEditingLink ] = useState( false ); + + // Effects + useEffect( () => { + // If we have a link then stop editing mode + if ( currentLink ) { + setIsEditingLink( false ); + } else { + setIsEditingLink( true ); + } + }, [ currentLink ] ); + + // Handlers + + /** + * onChange LinkControlSearchInput event handler + * + * @param {string} value Current value returned by the search. + */ + const onInputChange = ( value = '' ) => { + setInputValue( value ); + }; + + // Utils + const startEditMode = () => { + if ( isFunction( onLinkChange ) ) { + onLinkChange(); + } + }; + + const closeLinkUI = () => { + resetInput(); + onClose(); + }; + + const resetInput = () => { + setInputValue( '' ); + }; + + const handleDirectEntry = ( value ) => { + let type = 'URL'; + + const protocol = getProtocol( value ) || ''; + + if ( protocol.includes( 'mailto' ) ) { + type = 'mailto'; + } + + if ( protocol.includes( 'tel' ) ) { + type = 'tel'; + } + + if ( startsWith( value, '#' ) ) { + type = 'internal'; + } + + return Promise.resolve( + [ { + id: '-1', + title: value, + url: type === 'URL' ? prependHTTP( value ) : value, + type, + } ] + ); + }; + + const handleEntitySearch = async ( value ) => { + const results = await Promise.all( [ + fetchSearchSuggestions( value ), + handleDirectEntry( value ), + ] ); + + const couldBeURL = ! value.includes( ' ' ); + + // If it's potentially a URL search then concat on a URL search suggestion + // just for good measure. That way once the actual results run out we always + // have a URL option to fallback on. + return couldBeURL ? results[ 0 ].concat( results[ 1 ] ) : results[ 0 ]; + }; + + // Effects + const getSearchHandler = useCallback( ( value ) => { + const protocol = getProtocol( value ) || ''; + const isMailto = protocol.includes( 'mailto' ); + const isInternal = startsWith( value, '#' ); + const isTel = protocol.includes( 'tel' ); + + const handleManualEntry = isInternal || isMailto || isTel || isURL( value ) || ( value && value.includes( 'www.' ) ); + + return ( handleManualEntry ) ? handleDirectEntry( value ) : handleEntitySearch( value ); + }, [ handleDirectEntry, fetchSearchSuggestions ] ); + + // Render Components + const renderSearchResults = ( { suggestionsListProps, buildSuggestionItemProps, suggestions, selectedSuggestion, isLoading } ) => { + const resultsListClasses = classnames( 'block-editor-link-control__search-results', { + 'is-loading': isLoading, + } ); + + const manualLinkEntryTypes = [ 'url', 'mailto', 'tel', 'internal' ]; + + return ( +
+
+ { suggestions.map( ( suggestion, index ) => ( + onLinkChange( suggestion ) } + isSelected={ index === selectedSuggestion } + isURL={ manualLinkEntryTypes.includes( suggestion.type.toLowerCase() ) } + searchTerm={ inputValue } + /> + ) ) } +
+
+ ); + }; + + return ( + +
+
+ + { ( ! isEditingLink && currentLink ) && ( + +

+ { __( 'Currently selected' ) }: +

+
+ + + + { currentLink.title } + + { filterURLForDisplay( safeDecodeURI( currentLink.url ) ) || '' } + + + +
+
+ ) } + + { isEditingLink && ( + + ) } + + { ! isEditingLink && ( + + ) } +
+
+
+ ); +} + +export default compose( + withInstanceId, + withSelect( ( select, ownProps ) => { + if ( ownProps.fetchSearchSuggestions && isFunction( ownProps.fetchSearchSuggestions ) ) { + return; + } + + const { getSettings } = select( 'core/block-editor' ); + return { + fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions, + }; + } ) +)( LinkControl ); diff --git a/packages/block-editor/src/components/link-control/search-input.js b/packages/block-editor/src/components/link-control/search-input.js new file mode 100644 index 00000000000000..84fd5db8359363 --- /dev/null +++ b/packages/block-editor/src/components/link-control/search-input.js @@ -0,0 +1,69 @@ + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { IconButton } from '@wordpress/components'; +import { ENTER } from '@wordpress/keycodes'; + +/** + * Internal dependencies + */ +import { URLInput } from '../'; + +const LinkControlSearchInput = ( { + value, + onChange, + onSelect, + renderSuggestions, + fetchSuggestions, + onReset, + onKeyDown, + onKeyPress, +} ) => { + const selectItemHandler = ( selection, suggestion ) => { + onChange( selection ); + + if ( suggestion ) { + onSelect( suggestion ); + } + }; + + const stopFormEventsPropagation = ( event ) => { + event.preventDefault(); + event.stopPropagation(); + }; + + return ( +
+ { + if ( event.keyCode === ENTER ) { + return; + } + onKeyDown( event ); + } } + onKeyPress={ onKeyPress } + placeholder={ __( 'Search or type url' ) } + __experimentalRenderSuggestions={ renderSuggestions } + __experimentalFetchLinkSuggestions={ fetchSuggestions } + __experimentalHandleURLSuggestions={ true } + /> + + + + + ); +}; + +export default LinkControlSearchInput; diff --git a/packages/block-editor/src/components/link-control/search-item.js b/packages/block-editor/src/components/link-control/search-item.js new file mode 100644 index 00000000000000..432b4bb3dff17a --- /dev/null +++ b/packages/block-editor/src/components/link-control/search-item.js @@ -0,0 +1,54 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import TextHighlight from './text-highlight'; + +/** + * WordPress dependencies + */ +import { safeDecodeURI } from '@wordpress/url'; +import { __ } from '@wordpress/i18n'; + +import { + Icon, +} from '@wordpress/components'; + +export const LinkControlSearchItem = ( { itemProps, suggestion, isSelected = false, onClick, isURL = false, searchTerm = '' } ) => { + return ( + + ); +}; + +export default LinkControlSearchItem; + diff --git a/packages/block-editor/src/components/link-control/settings-drawer.js b/packages/block-editor/src/components/link-control/settings-drawer.js new file mode 100644 index 00000000000000..372426e4e821ff --- /dev/null +++ b/packages/block-editor/src/components/link-control/settings-drawer.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import { partial } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + ToggleControl, +} from '@wordpress/components'; + +const LinkControlSettingsDrawer = ( { settings, onSettingChange } ) => { + if ( ! settings || settings.length ) { + return null; + } + + return ( +
+ +
+ ); +}; + +export default LinkControlSettingsDrawer; diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss new file mode 100644 index 00000000000000..69f87d79fdfe3d --- /dev/null +++ b/packages/block-editor/src/components/link-control/style.scss @@ -0,0 +1,202 @@ +.block-editor-link-control__search { + position: relative; + min-width: $modal-min-width; +} + +.block-editor-link-control__search .block-editor-link-control__search-input { + // Specificity overide + &.block-editor-link-control__search-input > input[type="text"] { + width: calc(100% - #{$grid-size-large*2}); + display: block; + padding: 11px $grid-size-large; + margin: $grid-size-large; + padding-right: 38px; // width of reset button + position: relative; + z-index: 1; + border: 1px solid #e1e1e1; + border-radius: $radius-round-rectangle; + + /* Fonts smaller than 16px causes mobile safari to zoom. */ + font-size: $mobile-text-min-font-size; + + @include break-small { + font-size: $default-font-size; + } + + &:focus { + @include input-style__focus(); + } + } +} + +.block-editor-link-control__search-reset { + position: absolute; + top: 19px; // has to be hard coded as form expands with search suggestions + right: 19px; // push away to avoid focus style obscuring input border + z-index: 10; +} + +.block-editor-link-control__search-results-wrapper { + position: relative; + margin-top: -$grid-size-large + 1px; + + &::before, + &::after { + content: ""; + position: absolute; + left: -1px; + right: $grid-size-large; // avoid overlaying scrollbars + display: block; + pointer-events: none; + z-index: 100; + } + + &::before { + height: $grid-size-large/2; + top: -1px; + bottom: auto; + background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); + } + + &::after { + height: 20px; + bottom: -1px; + top: auto; + background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%); + } +} + +.block-editor-link-control__search-results { + margin: 0; + padding: $grid-size-large/2 $grid-size-large; + max-height: 200px; + overflow-y: scroll; // allow results list to scroll + + &.is-loading { + opacity: 0.2; + } +} + +.block-editor-link-control__search-item { + position: relative; + display: flex; + align-items: center; + font-size: $default-font-size; + cursor: pointer; + background: $white; + width: 100%; + border: none; + text-align: left; + padding: 10px 15px; + border-radius: 5px; + + &:hover, + &:focus { + background-color: #e9e9e9; + } + + &.is-selected { + background: #f2f2f2; + + .block-editor-link-control__search-item-type { + background: #fff; + } + } + + &.is-current { + background: transparent; + border: 0; + width: 100%; + cursor: default; + padding: $grid-size-large; + padding-left: $grid-size-xlarge; + } + + .block-editor-link-control__search-item-header { + display: block; + margin-right: $grid-size-xlarge; + } + + .block-editor-link-control__search-item-icon { + margin-right: 1em; + min-width: 24px; + } + + .block-editor-link-control__search-item-info, + .block-editor-link-control__search-item-title { + text-overflow: ellipsis; + max-width: 230px; + overflow: hidden; + white-space: nowrap; + } + + .block-editor-link-control__search-item-title { + display: block; + margin-bottom: 0.2em; + font-weight: 500; + + mark { + font-weight: 700; + color: #000; + background-color: transparent; + } + + span { + font-weight: normal; + } + } + + .block-editor-link-control__search-item-info { + display: block; + color: #999; + font-size: 0.9em; + line-height: 1.3; + } + + .block-editor-link-control__search-item-type { + display: block; + padding: 3px 8px; + margin-left: auto; + font-size: 0.9em; + background-color: #f3f4f5; + border-radius: 2px; + } +} + +// Specificity overide +.block-editor-link-control__search-results div[role="menu"] > .block-editor-link-control__search-item.block-editor-link-control__search-item { + padding: 10px; +} + +.block-editor-link-control__settings { + border-top: 1px solid #e1e1e1; + margin: 0; + padding: $grid-size-large $grid-size-xlarge; + + :last-child { + margin-bottom: 0; + } +} + +.block-editor-link-control .block-editor-link-control__search-input .components-spinner { + display: block; + z-index: 100; + float: none; + + &.components-spinner { // Specificity overide + position: absolute; + top: 70px; + left: 50%; + right: auto; + bottom: auto; + margin: 0 auto 16px auto; + transform: translateX(-50%); + } + + +} + +.block-editor-link-control__search-item-action { + margin-left: auto; // push to far right hand side + flex-shrink: 0; +} diff --git a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000000..df68c094eabc63 --- /dev/null +++ b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Basic rendering should display with required props 1`] = `"
"`; diff --git a/packages/block-editor/src/components/link-control/test/fixtures/index.js b/packages/block-editor/src/components/link-control/test/fixtures/index.js new file mode 100644 index 00000000000000..fc974749c982b1 --- /dev/null +++ b/packages/block-editor/src/components/link-control/test/fixtures/index.js @@ -0,0 +1,41 @@ +/** + * External dependencies + */ +import { uniqueId } from 'lodash'; + +export const fauxEntitySuggestions = [ + { + id: uniqueId(), + title: 'Hello Page', + type: 'Page', + info: '2 days ago', + url: `?p=${ uniqueId() }`, + }, + { + id: uniqueId(), + title: 'Hello Post', + type: 'Post', + info: '19 days ago', + url: `?p=${ uniqueId() }`, + }, + { + id: uniqueId(), + title: 'Hello Another One', + type: 'Page', + info: '19 days ago', + url: `?p=${ uniqueId() }`, + }, + { + id: uniqueId(), + title: 'This is another Post with a much longer title just to be really annoying and to try and break the UI', + type: 'Post', + info: '1 month ago', + url: `?p=${ uniqueId() }`, + }, +]; + +// export const fetchFauxEntitySuggestions = async () => fauxEntitySuggestions; + +export const fetchFauxEntitySuggestions = () => { + return Promise.resolve( fauxEntitySuggestions ); +}; diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js new file mode 100644 index 00000000000000..d6dc506c7687b8 --- /dev/null +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -0,0 +1,527 @@ +/** + * External dependencies + */ +import { render, unmountComponentAtNode } from 'react-dom'; +import { act, Simulate } from 'react-dom/test-utils'; +import { first, last, nth } from 'lodash'; +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; +import { UP, DOWN, ENTER } from '@wordpress/keycodes'; +/** + * Internal dependencies + */ +import LinkControl from '../index'; +import { fauxEntitySuggestions, fetchFauxEntitySuggestions } from './fixtures'; + +function eventLoopTick() { + return new Promise( ( resolve ) => setImmediate( resolve ) ); +} + +let container = null; + +beforeEach( () => { + // setup a DOM element as a render target + container = document.createElement( 'div' ); + document.body.appendChild( container ); +} ); + +afterEach( () => { + // cleanup on exiting + unmountComponentAtNode( container ); + container.remove(); + container = null; +} ); + +describe( 'Basic rendering', () => { + it( 'should display with required props', () => { + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // expect( searchInputLabel ).not.toBeNull(); + expect( searchInput ).not.toBeNull(); + + expect( container.innerHTML ).toMatchSnapshot(); + } ); +} ); + +describe( 'Searching for a link', () => { + it( 'should display loading UI when input is valid but search results have yet to be returned', async () => { + const searchTerm = 'Hello'; + + let resolver; + + const fauxRequest = () => new Promise( ( resolve ) => { + resolver = resolve; + } ); + + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="menu"] button[role="menuitem"]' ); + + let loadingUI = container.querySelector( '.components-spinner' ); + + expect( searchResultElements ).toHaveLength( 0 ); + + expect( loadingUI ).not.toBeNull(); + + act( () => { + resolver( fauxEntitySuggestions ); + } ); + + await eventLoopTick(); + + loadingUI = container.querySelector( '.components-spinner' ); + + expect( loadingUI ).toBeNull(); + } ); + + it( 'should display only search suggestions when current input value is not URL-like', async ( ) => { + const searchTerm = 'Hello world'; + const firstFauxSuggestion = first( fauxEntitySuggestions ); + + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchResultItemHTML = first( searchResultElements ).innerHTML; + const lastSearchResultItemHTML = last( searchResultElements ).innerHTML; + + expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length ); + + // Sanity check that a search suggestion shows up corresponding to the data + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( firstFauxSuggestion.title ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( firstFauxSuggestion.type ) ); + + // The fallback URL suggestion should not be shown when input is not URL-like + expect( lastSearchResultItemHTML ).not.toEqual( expect.stringContaining( 'URL' ) ); + } ); + + it.each( [ + [ 'couldbeurlorentitysearchterm' ], + [ 'ThisCouldAlsoBeAValidURL' ], + ] )( 'should display a URL suggestion as a default fallback for the search term "%s" which could potentially be a valid url.', async ( searchTerm ) => { + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const lastSearchResultItemHTML = last( searchResultElements ).innerHTML; + const additionalDefaultFallbackURLSuggestionLength = 1; + + // We should see a search result for each of the expect search suggestions + // plus 1 additional one for the fallback URL suggestion + expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length + additionalDefaultFallbackURLSuggestionLength ); + + // The last item should be a URL search suggestion + expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); + expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( 'URL' ) ); + expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); + } ); + + it( 'should reset the input field and the search results when search term is cleared or reset', async ( ) => { + const searchTerm = 'Hello world'; + + act( () => { + render( + , container + ); + } ); + + let searchResultElements; + let searchInput; + + // Search Input UI + searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + + // Check we have definitely rendered some suggestions + expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length ); + + // Grab the reset button now it's available + const resetUI = container.querySelector( '[aria-label="Reset"]' ); + + act( () => { + Simulate.click( resetUI ); + } ); + + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + expect( searchInput.value ).toBe( '' ); + expect( searchResultElements ).toHaveLength( 0 ); + } ); +} ); + +describe( 'Manual link entry', () => { + it.each( [ + [ 'https://make.wordpress.org' ], // explicit https + [ 'http://make.wordpress.org' ], // explicit http + [ 'www.wordpress.org' ], // usage of "www" + ] )( 'should display a single suggestion result when the current input value is URL-like (eg: %s)', async ( searchTerm ) => { + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchResultItemHTML = searchResultElements[ 0 ].innerHTML; + const expectedResultsLength = 1; + + expect( searchResultElements ).toHaveLength( expectedResultsLength ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'URL' ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); + } ); + + describe( 'Alternative link protocols and formats', () => { + it.each( [ + [ 'mailto:example123456@wordpress.org', 'mailto' ], + [ 'tel:example123456@wordpress.org', 'tel' ], + [ '#internal-anchor', 'internal' ], + ] )( 'should recognise "%s" as a %s link and handle as manual entry by displaying a single suggestion', async ( searchTerm, searchType ) => { + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchResultItemHTML = searchResultElements[ 0 ].innerHTML; + const expectedResultsLength = 1; + + expect( searchResultElements ).toHaveLength( expectedResultsLength ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchType ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); + } ); + } ); +} ); + +describe( 'Selecting links', () => { + it( 'should display a selected link corresponding to the provided "currentLink" prop', () => { + const selectedLink = first( fauxEntitySuggestions ); + + const LinkControlConsumer = () => { + const [ link ] = useState( selectedLink ); + + return ( + + ); + }; + + act( () => { + render( + , container + ); + } ); + + // TODO: select by aria role or visible text + const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + const currentLinkHTML = currentLink.innerHTML; + const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); + + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.type ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); + expect( currentLinkAnchor ).not.toBeNull(); + } ); + + it( 'should remove currently selected link and (re)display search UI when "Change" button is clicked', () => { + const selectedLink = first( fauxEntitySuggestions ); + + const LinkControlConsumer = () => { + const [ link, setLink ] = useState( selectedLink ); + + return ( + setLink( suggestion ) } + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + /> + ); + }; + + act( () => { + render( + , container + ); + } ); + + // TODO: select by aria role or visible text + let currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + + const currentLinkBtn = currentLink.querySelector( 'button' ); + + // Simulate searching for a term + act( () => { + Simulate.click( currentLinkBtn ); + } ); + + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + + // We should be back to showing the search input + expect( searchInput ).not.toBeNull(); + expect( currentLink ).toBeNull(); + } ); + + describe( 'Selection using mouse click', () => { + it.each( [ + [ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search + [ 'url', 'https://www.wordpress.org', { + id: '1', + title: 'https://www.wordpress.org', + url: 'https://www.wordpress.org', + type: 'URL', + } ], // url + ] )( 'should display a current selected link UI when a %s suggestion for the search "%s" is clicked', async ( type, searchTerm, selectedLink ) => { + const LinkControlConsumer = () => { + const [ link, setLink ] = useState( null ); + + return ( + setLink( suggestion ) } + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + /> + ); + }; + + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + + const firstSearchSuggestion = first( searchResultElements ); + + // Simulate selecting the first of the search suggestions + act( () => { + Simulate.click( firstSearchSuggestion ); + } ); + + const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + const currentLinkHTML = currentLink.innerHTML; + const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); + + // Check that this suggestion is now shown as selected + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); + expect( currentLinkAnchor ).not.toBeNull(); + } ); + } ); + + describe( 'Selection using keyboard', () => { + it.each( [ + [ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search + [ 'url', 'https://www.wordpress.org', { + id: '1', + title: 'https://www.wordpress.org', + url: 'https://www.wordpress.org', + type: 'URL', + } ], // url + ] )( 'should display a current selected link UI when an %s suggestion for the search "%s" is selected using the keyboard', async ( type, searchTerm, selectedLink ) => { + const LinkControlConsumer = () => { + const [ link, setLink ] = useState( null ); + + return ( + setLink( suggestion ) } + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + /> + ); + }; + + act( () => { + render( + , container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + //fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // Step down into the search results, highlighting the first result item + act( () => { + Simulate.keyDown( searchInput, { keyCode: DOWN } ); + } ); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchSuggestion = first( searchResultElements ); + const secondSearchSuggestion = nth( searchResultElements, 1 ); + + let selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); + + // We should have highlighted the first item using the keyboard + expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion ); + + // Only entity searches contain more than 1 suggestion + if ( type === 'entity' ) { + // Check we can go down again using the down arrow + act( () => { + Simulate.keyDown( searchInput, { keyCode: DOWN } ); + } ); + + selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); + + // We should have highlighted the first item using the keyboard + expect( selectedSearchResultElement ).toEqual( secondSearchSuggestion ); + + // Check we can go back up via up arrow + act( () => { + Simulate.keyDown( searchInput, { keyCode: UP } ); + } ); + + selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); + + // We should be back to highlighting the first search result again + expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion ); + } + + // Commit the selected item as the current link + act( () => { + Simulate.keyDown( searchInput, { keyCode: ENTER } ); + } ); + + // Check that the suggestion selected via is now shown as selected + const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + const currentLinkHTML = currentLink.innerHTML; + const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); + + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); + expect( currentLinkAnchor ).not.toBeNull(); + } ); + } ); +} ); diff --git a/packages/block-editor/src/components/link-control/text-highlight.js b/packages/block-editor/src/components/link-control/text-highlight.js new file mode 100644 index 00000000000000..dc7b35a3d6d2bc --- /dev/null +++ b/packages/block-editor/src/components/link-control/text-highlight.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import { escapeRegExp } from 'lodash'; + +/** + * WordPress dependencies + */ +import { + Fragment, +} from '@wordpress/element'; + +const TextHighlight = ( { text = '', highlight = '' } ) => { + if ( ! highlight.trim() ) { + return text; + } + + const regex = new RegExp( `(${ escapeRegExp( highlight ) })`, 'gi' ); + const parts = text.split( regex ); + return ( + + { parts.filter( ( part ) => part ).map( ( part, i ) => ( + regex.test( part ) ? { part } : { part } + ) ) } + + ); +}; + +export default TextHighlight; diff --git a/packages/block-editor/src/components/media-placeholder/README.md b/packages/block-editor/src/components/media-placeholder/README.md index b730b9af5cbc9c..58140cf99e7215 100644 --- a/packages/block-editor/src/components/media-placeholder/README.md +++ b/packages/block-editor/src/components/media-placeholder/README.md @@ -155,9 +155,9 @@ The argument of the callback is an object containing the following properties: ### value -Media ID (or media IDs if multiple is true) to be selected by default when opening the media library. +An object or an array of objects that contain media ID (`id` property) to be selected by default when opening the media library. -- Type: `Number|Array` +- Type: `Object|Array` - Required: No - Platform: Web diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index d142d6d6c70008..d4e98de6179b12 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -429,7 +429,7 @@ const applyWithSelect = withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return { - mediaUpload: getSettings().__experimentalMediaUpload, + mediaUpload: getSettings().mediaUpload, }; } ); diff --git a/packages/block-editor/src/components/media-placeholder/styles.native.scss b/packages/block-editor/src/components/media-placeholder/styles.native.scss index a0b7445debf66b..03c7c73b2edfc9 100644 --- a/packages/block-editor/src/components/media-placeholder/styles.native.scss +++ b/packages/block-editor/src/components/media-placeholder/styles.native.scss @@ -19,10 +19,6 @@ background-color: $background-dark-secondary; } -.emptyStateContainerDark { - background-color: $background-dark-secondary; -} - .emptyStateTitle { text-align: center; margin-top: 8; diff --git a/packages/block-editor/src/components/media-upload/check.js b/packages/block-editor/src/components/media-upload/check.js index 6f2903be5b1e10..c1fb3398020f4c 100644 --- a/packages/block-editor/src/components/media-upload/check.js +++ b/packages/block-editor/src/components/media-upload/check.js @@ -14,6 +14,6 @@ export default withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return { - hasUploadPermissions: !! getSettings().__experimentalMediaUpload, + hasUploadPermissions: !! getSettings().mediaUpload, }; } )( MediaUploadCheck ); diff --git a/packages/block-editor/src/components/media-upload/index.js b/packages/block-editor/src/components/media-upload/index.js index 1cb3e511097276..2318ef93d5e4f4 100644 --- a/packages/block-editor/src/components/media-upload/index.js +++ b/packages/block-editor/src/components/media-upload/index.js @@ -8,7 +8,7 @@ import { withFilters } from '@wordpress/components'; * an integration with the core blocks that handle media files. By default it renders nothing but * it provides a way to have it overridden with the `editor.MediaUpload` filter. * - * @return {WPElement} Media upload element. + * @return {WPComponent} The component to be rendered. */ const MediaUpload = () => null; diff --git a/packages/block-editor/src/components/media-upload/index.native.js b/packages/block-editor/src/components/media-upload/index.native.js index 3d89091e94da3d..2e1c3a9fcd8010 100644 --- a/packages/block-editor/src/components/media-upload/index.native.js +++ b/packages/block-editor/src/components/media-upload/index.native.js @@ -6,6 +6,8 @@ import { requestMediaPickFromMediaLibrary, requestMediaPickFromDeviceLibrary, requestMediaPickFromDeviceCamera, + getOtherMediaOptions, + requestOtherMediaPickFrom, } from 'react-native-gutenberg-bridge'; /** @@ -31,7 +33,27 @@ export class MediaUpload extends React.Component { this.onPickerPresent = this.onPickerPresent.bind( this ); this.onPickerChange = this.onPickerChange.bind( this ); this.onPickerSelect = this.onPickerSelect.bind( this ); + + this.state = { + otherMediaOptions: undefined, + }; + } + + componentDidMount() { + const { allowedTypes = [] } = this.props; + getOtherMediaOptions( allowedTypes, ( otherMediaOptions ) => { + const otherMediaOptionsWithIcons = otherMediaOptions.map( ( option ) => { + return { + icon: this.getChooseFromDeviceIcon(), + value: option.value, + label: option.label, + }; + } ); + + this.setState( { otherMediaOptions: otherMediaOptionsWithIcons } ); + } ); } + getTakeMediaLabel() { const { allowedTypes = [] } = this.props; @@ -98,15 +120,26 @@ export class MediaUpload extends React.Component { this.onPickerSelect( requestMediaPickFromDeviceCamera ); } else if ( value === MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_WORD_PRESS_LIBRARY ) { this.onPickerSelect( requestMediaPickFromMediaLibrary ); + } else { + const { onSelect, multiple = false } = this.props; + requestOtherMediaPickFrom( value, multiple, ( media ) => { + if ( ( multiple && media ) || ( media && media.id ) ) { + onSelect( media ); + } + } ); } } render() { - const mediaOptions = this.getMediaOptionsItems(); + let mediaOptions = this.getMediaOptionsItems(); + + if ( this.state.otherMediaOptions ) { + mediaOptions = [ ...mediaOptions, ...this.state.otherMediaOptions ]; + } const getMediaOptions = () => ( this.picker = instance } options={ mediaOptions } onChange={ this.onPickerChange } diff --git a/packages/block-editor/src/components/provider/index.js b/packages/block-editor/src/components/provider/index.js index 488dd6244d8c65..c2b29f13fa74ac 100644 --- a/packages/block-editor/src/components/provider/index.js +++ b/packages/block-editor/src/components/provider/index.js @@ -73,8 +73,8 @@ class BlockEditorProvider extends Component { * This needs to be done synchronously after state changes (instead of using * `componentDidUpdate`) in order to avoid batching these changes. * - * @param {WPDataRegistry} registry Registry from which block editor - * dispatch is to be overriden. + * @param {WPDataRegistry} registry Registry from which block editor + * dispatch is to be overridden. */ attachChangeObserver( registry ) { if ( this.unsubscribe ) { diff --git a/packages/block-editor/src/components/provider/index.native.js b/packages/block-editor/src/components/provider/index.native.js index 8e2f2e677397b4..fca4fab5ddbdee 100644 --- a/packages/block-editor/src/components/provider/index.native.js +++ b/packages/block-editor/src/components/provider/index.native.js @@ -75,8 +75,8 @@ class BlockEditorProvider extends Component { * This needs to be done synchronously after state changes (instead of using * `componentDidUpdate`) in order to avoid batching these changes. * - * @param {WPDataRegistry} registry Registry from which block editor - * dispatch is to be overriden. + * @param {WPDataRegistry} registry Registry from which block editor + * dispatch is to be overridden. */ attachChangeObserver( registry ) { if ( this.unsubscribe ) { diff --git a/packages/block-editor/src/components/rich-text/file-paste-handler.js b/packages/block-editor/src/components/rich-text/file-paste-handler.js new file mode 100644 index 00000000000000..eceeb069b263ff --- /dev/null +++ b/packages/block-editor/src/components/rich-text/file-paste-handler.js @@ -0,0 +1,11 @@ +/** + * WordPress dependencies + */ +import { createBlobURL } from '@wordpress/blob'; + +export function filePasteHandler( files ) { + return files + .filter( ( { type } ) => /^image\/(?:jpe?g|png|gif)$/.test( type ) ) + .map( ( file ) => `` ) + .join( '' ); +} diff --git a/packages/block-editor/src/components/rich-text/file-paste-handler.native.js b/packages/block-editor/src/components/rich-text/file-paste-handler.native.js new file mode 100644 index 00000000000000..41402a0dcda68c --- /dev/null +++ b/packages/block-editor/src/components/rich-text/file-paste-handler.native.js @@ -0,0 +1,3 @@ +export function filePasteHandler( files ) { + return files.map( ( url ) => `` ).join( '' ); +} diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.js new file mode 100644 index 00000000000000..fc857311706db3 --- /dev/null +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.js @@ -0,0 +1,59 @@ +/** + * WordPress dependencies + */ +import { Popover } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import BlockFormatControls from '../block-format-controls'; +import FormatToolbar from './format-toolbar'; + +function getAnchorRect( anchorObj ) { + const { current } = anchorObj; + const rect = current.getBoundingClientRect(); + + // Add some space. + const buffer = 6; + + // Subtract padding if any. + let { paddingTop } = window.getComputedStyle( current ); + + paddingTop = parseInt( paddingTop, 10 ); + + return { + x: rect.left, + y: rect.top + paddingTop - buffer, + width: rect.width, + height: rect.height - paddingTop + buffer, + left: rect.left, + right: rect.right, + top: rect.top + paddingTop - buffer, + bottom: rect.bottom, + }; +} + +const FormatToolbarContainer = ( { inline, anchorObj } ) => { + if ( inline ) { + // Render in popover + return ( + getAnchorRect( anchorObj ) } + className="block-editor-rich-text__inline-format-toolbar" + > + + + ); + } + // Render regular toolbar + return ( + + + + ); +}; + +export default FormatToolbarContainer; diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js new file mode 100644 index 00000000000000..d37fe5bfee0f68 --- /dev/null +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js @@ -0,0 +1,16 @@ +/** + * Internal dependencies + */ +import BlockFormatControls from '../block-format-controls'; +import FormatToolbar from './format-toolbar'; + +const FormatToolbarContainer = () => { + // Render regular toolbar + return ( + + + + ); +}; + +export default FormatToolbarContainer; diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index b78e8c3a46ffc3..53292f1402d5d7 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -7,9 +7,9 @@ import { omit } from 'lodash'; /** * WordPress dependencies */ -import { RawHTML, Component, createRef } from '@wordpress/element'; +import { RawHTML, Component, createRef, Platform } from '@wordpress/element'; import { withDispatch, withSelect } from '@wordpress/data'; -import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform } from '@wordpress/blocks'; +import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; import { withInstanceId, compose } from '@wordpress/compose'; import { __experimentalRichText as RichText, @@ -25,8 +25,7 @@ import { toHTMLString, slice, } from '@wordpress/rich-text'; -import { withFilters, Popover } from '@wordpress/components'; -import { createBlobURL } from '@wordpress/blob'; +import { withFilters } from '@wordpress/components'; import deprecated from '@wordpress/deprecated'; import { isURL } from '@wordpress/url'; @@ -34,10 +33,10 @@ import { isURL } from '@wordpress/url'; * Internal dependencies */ import Autocomplete from '../autocomplete'; -import BlockFormatControls from '../block-format-controls'; -import FormatToolbar from './format-toolbar'; import { withBlockEditContext } from '../block-edit/context'; import { RemoveBrowserShortcuts } from './remove-browser-shortcuts'; +import { filePasteHandler } from './file-paste-handler'; +import FormatToolbarContainer from './format-toolbar-container'; const wrapperClasses = 'editor-rich-text block-editor-rich-text'; const classes = 'editor-rich-text__editable block-editor-rich-text__editable'; @@ -66,7 +65,6 @@ class RichTextWrapper extends Component { this.onPaste = this.onPaste.bind( this ); this.onDelete = this.onDelete.bind( this ); this.inputRule = this.inputRule.bind( this ); - this.getAnchorRect = this.getAnchorRect.bind( this ); } onEnter( { value, onChange, shiftKey } ) { @@ -124,7 +122,7 @@ class RichTextWrapper extends Component { } } - onPaste( { value, onChange, html, plainText, image } ) { + onPaste( { value, onChange, html, plainText, files } ) { const { onReplace, onSplit, @@ -134,16 +132,18 @@ class RichTextWrapper extends Component { __unstableEmbedURLOnPaste, } = this.props; - if ( image && ! html ) { - const file = image.getAsFile ? image.getAsFile() : image; + // Only process file if no HTML is present. + // Note: a pasted file may have the URL as plain text. + if ( files && files.length && ! html ) { const content = pasteHandler( { - HTML: ``, + HTML: filePasteHandler( files ), mode: 'BLOCKS', tagName, } ); // Allows us to ask for this information when we get a report. - window.console.log( 'Received item:\n\n', file ); + // eslint-disable-next-line no-console + window.console.log( 'Received items:\n\n', files ); if ( onReplace && isEmpty( value ) ) { onReplace( content ); @@ -303,30 +303,6 @@ class RichTextWrapper extends Component { return formattingControls.map( ( name ) => `core/${ name }` ); } - getAnchorRect() { - const { current } = this.ref; - const rect = current.getBoundingClientRect(); - - // Add some space. - const buffer = 6; - - // Subtract padding if any. - let { paddingTop } = window.getComputedStyle( current ); - - paddingTop = parseInt( paddingTop, 10 ); - - return { - x: rect.left, - y: rect.top + paddingTop - buffer, - width: rect.width, - height: rect.height - paddingTop + buffer, - left: rect.left, - right: rect.right, - top: rect.top + paddingTop - buffer, - bottom: rect.bottom, - }; - } - render() { const { children, @@ -424,22 +400,7 @@ class RichTextWrapper extends Component { { ( { isSelected, value, onChange, Editable } ) => <> { children && children( { value, onChange } ) } - { isSelected && ! inlineToolbar && hasFormats && ( - - - - ) } - { isSelected && inlineToolbar && hasFormats && ( - - - - ) } + { isSelected && hasFormats && ( ) } { isSelected && } ( { clientId } ) ), + withBlockEditContext( ( { clientId, onCaretVerticalPositionChange, isSelected }, ownProps ) => { + if ( Platform.OS === 'web' ) { + return { clientId }; + } + return { + clientId, + blockIsSelected: ownProps.isSelected !== undefined ? ownProps.isSelected : isSelected, + onCaretVerticalPositionChange, + }; + } ), withSelect( ( select, { clientId, instanceId, @@ -495,6 +465,7 @@ const RichTextContainer = compose( [ getSelectionEnd, getSettings, didAutomaticChange, + __unstableGetBlockWithoutInnerBlocks, } = select( 'core/block-editor' ); const selectionStart = getSelectionStart(); @@ -509,6 +480,18 @@ const RichTextContainer = compose( [ isSelected = selectionStart.clientId === clientId; } + let extraProps = {}; + if ( Platform.OS === 'native' ) { + // If the block of this RichText is unmodified then it's a candidate for replacing when adding a new block. + // In order to fix https://github.com/wordpress-mobile/gutenberg-mobile/issues/1126, let's blur on unmount in that case. + // This apparently assumes functionality the BlockHlder actually + const block = clientId && __unstableGetBlockWithoutInnerBlocks( clientId ); + const shouldBlurOnUnmount = block && isSelected && isUnmodifiedDefaultBlock( block ); + extraProps = { + shouldBlurOnUnmount, + }; + } + return { canUserUseUnfilteredHTML: __experimentalCanUserUseUnfilteredHTML, isCaretWithinFormattedText: isCaretWithinFormattedText(), @@ -516,6 +499,7 @@ const RichTextContainer = compose( [ selectionEnd: isSelected ? selectionEnd.offset : undefined, isSelected, didAutomaticChange: didAutomaticChange(), + ...extraProps, }; } ), withDispatch( ( dispatch, { diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js deleted file mode 100644 index feab0f747a9229..00000000000000 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { View } from 'react-native'; - -/** - * WordPress dependencies - */ -import { RawHTML } from '@wordpress/element'; -import { withDispatch, withSelect } from '@wordpress/data'; -import { pasteHandler, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; -import { withInstanceId, compose } from '@wordpress/compose'; -import { __experimentalRichText as RichText } from '@wordpress/rich-text'; - -/** - * Internal dependencies - */ -import Autocomplete from '../autocomplete'; -import BlockFormatControls from '../block-format-controls'; -import FormatToolbar from './format-toolbar'; -import { withBlockEditContext } from '../block-edit/context'; - -const wrapperClasses = 'editor-rich-text block-editor-rich-text'; -const classes = 'editor-rich-text__editable block-editor-rich-text__editable'; - -function RichTextWraper( { - children, - tagName, - value: originalValue, - onChange: originalOnChange, - selectionStart, - selectionEnd, - onSelectionChange, - multiline, - inlineToolbar, - wrapperClassName, - className, - autocompleters, - onReplace, - onRemove, - onMerge, - onSplit, - isCaretWithinFormattedText, - onEnterFormattedText, - onExitFormattedText, - canUserUseUnfilteredHTML, - isSelected: originalIsSelected, - onCreateUndoLevel, - placeholder, - // From experimental filter. - ...experimentalProps -} ) { - const adjustedValue = originalValue; - const adjustedOnChange = originalOnChange; - - return ( - - { ( { isSelected, value, onChange } ) => - - { children && children( { value, onChange } ) } - { isSelected && ! inlineToolbar && ( - - - - ) } - - } - - ); -} - -const RichTextContainer = compose( [ - withInstanceId, - withBlockEditContext( ( { clientId, onCaretVerticalPositionChange, isSelected }, ownProps ) => { - return { - clientId, - blockIsSelected: ownProps.isSelected !== undefined ? ownProps.isSelected : isSelected, - onCaretVerticalPositionChange, - }; - } ), - withSelect( ( select, { - clientId, - instanceId, - identifier = instanceId, - isSelected, - blockIsSelected, - } ) => { - const { getFormatTypes } = select( 'core/rich-text' ); - const { - getSelectionStart, - getSelectionEnd, - __unstableGetBlockWithoutInnerBlocks, - } = select( 'core/block-editor' ); - - const selectionStart = getSelectionStart(); - const selectionEnd = getSelectionEnd(); - - if ( isSelected === undefined ) { - isSelected = ( - selectionStart.clientId === clientId && - selectionStart.attributeKey === identifier - ); - } - - // If the block of this RichText is unmodified then it's a candidate for replacing when adding a new block. - // In order to fix https://github.com/wordpress-mobile/gutenberg-mobile/issues/1126, let's blur on unmount in that case. - // This apparently assumes functionality the BlockHlder actually - const block = clientId && __unstableGetBlockWithoutInnerBlocks( clientId ); - const shouldBlurOnUnmount = block && isSelected && isUnmodifiedDefaultBlock( block ); - - return { - formatTypes: getFormatTypes(), - selectionStart: isSelected ? selectionStart.offset : undefined, - selectionEnd: isSelected ? selectionEnd.offset : undefined, - isSelected, - blockIsSelected, - shouldBlurOnUnmount, - }; - } ), - withDispatch( ( dispatch, { - clientId, - instanceId, - identifier = instanceId, - } ) => { - const { - __unstableMarkLastChangeAsPersistent, - selectionChange, - } = dispatch( 'core/block-editor' ); - - return { - onCreateUndoLevel: __unstableMarkLastChangeAsPersistent, - onSelectionChange( start, end ) { - selectionChange( clientId, identifier, start, end ); - }, - }; - } ), -] )( RichTextWraper ); - -RichTextContainer.Content = ( { value, format, tagName: Tag, multiline, ...props } ) => { - let content; - let html = value; - let MultilineTag; - - if ( multiline === true || multiline === 'p' || multiline === 'li' ) { - MultilineTag = multiline === true ? 'p' : multiline; - } - - if ( ! html && MultilineTag ) { - html = `<${ MultilineTag }>`; - } - - switch ( format ) { - case 'string': - content = { html }; - break; - } - - if ( Tag ) { - return { content }; - } - - return content; -}; - -RichTextContainer.isEmpty = ( value = '' ) => { - // Handle deprecated `children` and `node` sources. - if ( Array.isArray( value ) ) { - return ! value || value.length === 0; - } - - return value.length === 0; -}; - -RichTextContainer.Content.defaultProps = { - format: 'string', - value: '', -}; - -/** - * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/rich-text/README.md - */ -export default RichTextContainer; -export { RichTextShortcut } from './shortcut'; -export { RichTextToolbarButton } from './toolbar-button'; -export { __unstableRichTextInputEvent } from './input-event'; diff --git a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js index 165566a5bbbd16..9eee7b641a0e61 100644 --- a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js +++ b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js @@ -40,6 +40,6 @@ const SHORTCUTS_ELEMENT = ( * Component which registered keyboard event handlers to prevent default * behaviors for key combinations otherwise handled internally by RichText. * - * @return {WPElement} WordPress element. + * @return {WPComponent} The component to be rendered. */ export const RemoveBrowserShortcuts = () => SHORTCUTS_ELEMENT; diff --git a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js new file mode 100644 index 00000000000000..43a4b030646db4 --- /dev/null +++ b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js @@ -0,0 +1 @@ +export const RemoveBrowserShortcuts = () => null; diff --git a/packages/block-editor/src/components/typewriter/index.js b/packages/block-editor/src/components/typewriter/index.js index 7600b2cd8747cd..d2869ab03b2c01 100644 --- a/packages/block-editor/src/components/typewriter/index.js +++ b/packages/block-editor/src/components/typewriter/index.js @@ -100,7 +100,7 @@ class Typewriter extends Component { * Maintains the scroll position after a selection change caused by a * keyboard event. * - * @param {SyntheticEvent} event Synthetic keyboard event. + * @param {WPSyntheticEvent} event Synthetic keyboard event. */ maintainCaretPosition( { keyCode } ) { if ( ! this.isSelectionEligibleForScroll() ) { diff --git a/packages/block-editor/src/components/url-input/index.js b/packages/block-editor/src/components/url-input/index.js index 9652df56c9da74..1c32d9c29eab34 100644 --- a/packages/block-editor/src/components/url-input/index.js +++ b/packages/block-editor/src/components/url-input/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { throttle } from 'lodash'; +import { throttle, isFunction } from 'lodash'; import classnames from 'classnames'; import scrollIntoView from 'dom-scroll-into-view'; @@ -14,6 +14,7 @@ import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes'; import { Spinner, withSpokenMessages, Popover } from '@wordpress/components'; import { withInstanceId, withSafeTimeout, compose } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; +import { isURL } from '@wordpress/url'; // Since URLInput is rendered in the context of other inputs, but should be // considered a separate modal node, prevent keyboard events from propagating @@ -21,12 +22,15 @@ import { withSelect } from '@wordpress/data'; const stopEventPropagation = ( event ) => event.stopPropagation(); class URLInput extends Component { - constructor( { autocompleteRef } ) { - super( ...arguments ); + constructor( props ) { + super( props ); this.onChange = this.onChange.bind( this ); this.onKeyDown = this.onKeyDown.bind( this ); - this.autocompleteRef = autocompleteRef || createRef(); + this.selectLink = this.selectLink.bind( this ); + this.handleOnClick = this.handleOnClick.bind( this ); + this.bindSuggestionNode = this.bindSuggestionNode.bind( this ); + this.autocompleteRef = props.autocompleteRef || createRef(); this.inputRef = createRef(); this.updateSuggestions = throttle( this.updateSuggestions.bind( this ), 200 ); @@ -45,6 +49,7 @@ class URLInput extends Component { // when already expanded if ( showSuggestions && selectedSuggestion !== null && ! this.scrollingIntoView ) { this.scrollingIntoView = true; + scrollIntoView( this.suggestionNodes[ selectedSuggestion ], this.autocompleteRef.current, { onlyScrollIfNeeded: true, } ); @@ -66,14 +71,17 @@ class URLInput extends Component { } updateSuggestions( value ) { - const { fetchLinkSuggestions } = this.props; + const { + __experimentalFetchLinkSuggestions: fetchLinkSuggestions, + __experimentalHandleURLSuggestions: handleURLSuggestions, + } = this.props; if ( ! fetchLinkSuggestions ) { return; } // Show the suggestions after typing at least 2 characters // and also for URLs - if ( value.length < 2 || /^https?:/.test( value ) ) { + if ( value.length < 2 || ( ! handleURLSuggestions && isURL( value ) ) ) { this.setState( { showSuggestions: false, selectedSuggestion: null, @@ -132,9 +140,13 @@ class URLInput extends Component { onKeyDown( event ) { const { showSuggestions, selectedSuggestion, suggestions, loading } = this.state; + // If the suggestions are not shown or loading, we shouldn't handle the arrow keys // We shouldn't preventDefault to allow block arrow keys navigation - if ( ! showSuggestions || ! suggestions.length || loading ) { + if ( + ( ! showSuggestions || ! suggestions.length || loading ) && + this.props.value + ) { // In the Windows version of Firefox the up and down arrows don't move the caret // within an input field like they do for Mac Firefox/Chrome/Safari. This causes // a form of focus trapping that is disruptive to the user experience. This disruption @@ -223,19 +235,64 @@ class URLInput extends Component { this.inputRef.current.focus(); } - static getDerivedStateFromProps( { disableSuggestions }, { showSuggestions } ) { + static getDerivedStateFromProps( { value, disableSuggestions }, { showSuggestions, selectedSuggestion } ) { + let shouldShowSuggestions = showSuggestions; + + const hasValue = value && value.length; + + if ( ! hasValue ) { + shouldShowSuggestions = false; + } + + if ( disableSuggestions === true ) { + shouldShowSuggestions = false; + } + return { - showSuggestions: disableSuggestions === true ? false : showSuggestions, + selectedSuggestion: hasValue ? selectedSuggestion : null, + showSuggestions: shouldShowSuggestions, }; } render() { - const { value = '', autoFocus = true, instanceId, className, id, isFullWidth, hasBorder } = this.props; - const { showSuggestions, suggestions, selectedSuggestion, loading } = this.state; + const { + instanceId, + className, + id, + isFullWidth, + hasBorder, + __experimentalRenderSuggestions: renderSuggestions, + placeholder = __( 'Paste URL or type to search' ), + value = '', + autoFocus = true, + } = this.props; + + const { + showSuggestions, + suggestions, + selectedSuggestion, + loading, + } = this.state; const suggestionsListboxId = `block-editor-url-input-suggestions-${ instanceId }`; const suggestionOptionIdPrefix = `block-editor-url-input-suggestion-${ instanceId }`; + const suggestionsListProps = { + id: suggestionsListboxId, + ref: this.autocompleteRef, + role: 'listbox', + }; + + const buildSuggestionItemProps = ( suggestion, index ) => { + return { + role: 'option', + tabIndex: '-1', + id: `${ suggestionOptionIdPrefix }-${ index }`, + ref: this.bindSuggestionNode( index ), + 'aria-selected': index === selectedSuggestion, + }; + }; + /* eslint-disable jsx-a11y/no-autofocus */ return (
} - { showSuggestions && !! suggestions.length && + { isFunction( renderSuggestions ) && showSuggestions && !! suggestions.length && renderSuggestions( { + suggestions, + selectedSuggestion, + suggestionsListProps, + buildSuggestionItemProps, + isLoading: loading, + handleSuggestionClick: this.handleOnClick, + } ) } + + { ! isFunction( renderSuggestions ) && showSuggestions && !! suggestions.length &&
{ suggestions.map( ( suggestion, index ) => ( @@ -311,10 +371,15 @@ export default compose( withSafeTimeout, withSpokenMessages, withInstanceId, - withSelect( ( select ) => { + withSelect( ( select, props ) => { + // If a link suggestions handler is already provided then + // bail + if ( isFunction( props.__experimentalFetchLinkSuggestions ) ) { + return; + } const { getSettings } = select( 'core/block-editor' ); return { - fetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions, + __experimentalFetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions, }; } ) )( URLInput ); diff --git a/packages/block-editor/src/hooks/anchor.js b/packages/block-editor/src/hooks/anchor.js index 9b78c39bbfeb02..5f8f1ca25879f5 100644 --- a/packages/block-editor/src/hooks/anchor.js +++ b/packages/block-editor/src/hooks/anchor.js @@ -56,9 +56,9 @@ export function addAttribute( settings ) { * Override the default edit UI to include a new block inspector control for * assigning the anchor ID, if block supports anchor. * - * @param {Function|Component} BlockEdit Original component. + * @param {WPComponent} BlockEdit Original component. * - * @return {string} Wrapped component. + * @return {WPComponent} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { diff --git a/packages/block-editor/src/hooks/custom-class-name.js b/packages/block-editor/src/hooks/custom-class-name.js index bac77a37ea42a2..dfbceb627389cc 100644 --- a/packages/block-editor/src/hooks/custom-class-name.js +++ b/packages/block-editor/src/hooks/custom-class-name.js @@ -47,9 +47,9 @@ export function addAttribute( settings ) { * Override the default edit UI to include a new block inspector control for * assigning the custom class name, if block supports custom class name. * - * @param {Function|Component} BlockEdit Original component. + * @param {WPComponent} BlockEdit Original component. * - * @return {string} Wrapped component. + * @return {WPComponent} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index 06eabc9f6f11f4..54233e3bda2e91 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -32,6 +32,7 @@ export const PREFERENCES_DEFAULTS = { * __experimentalEnableLegacyWidgetBlock boolean Whether the user has enabled the Legacy Widget Block * __experimentalEnableMenuBlock boolean Whether the user has enabled the Menu Block * __experimentalBlockDirectory boolean Whether the user has enabled the Block Directory + * __experimentalEnableFullSiteEditing boolean Whether the user has enabled Full Site Editing */ export const SETTINGS_DEFAULTS = { alignWide: false, @@ -152,80 +153,98 @@ export const SETTINGS_DEFAULTS = { __experimentalEnableLegacyWidgetBlock: false, __experimentalEnableMenuBlock: false, __experimentalBlockDirectory: false, + __experimentalEnableFullSiteEditing: false, gradients: [ { name: __( 'Vivid cyan blue to vivid purple' ), - gradient: 'linear-gradient(135deg, rgba(6, 147, 227, 1) 0%, rgb(155, 81, 224) 100%)', + gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', + slug: 'vivid-cyan-blue-to-vivid-purple', }, { name: __( 'Vivid green cyan to vivid cyan blue' ), - gradient: 'linear-gradient(135deg, rgba(0, 208, 132, 1) 0%, rgba(6, 147, 227, 1) 100%)', + gradient: 'linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)', + slug: 'vivid-green-cyan-to-vivid-cyan-blue', }, { name: __( 'Light green cyan to vivid green cyan' ), - gradient: 'linear-gradient(135deg, rgb(122, 220, 180) 0%, rgb(0, 208, 130) 100%)', + gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', + slug: 'light-green-cyan-to-vivid-green-cyan', }, { name: __( 'Luminous vivid amber to luminous vivid orange' ), - gradient: 'linear-gradient(135deg, rgba(252, 185, 0, 1) 0%, rgba(255, 105, 0, 1) 100%)', + gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)', + slug: 'luminous-vivid-amber-to-luminous-vivid-orange', }, { name: __( 'Luminous vivid orange to vivid red' ), - gradient: 'linear-gradient(135deg, rgba(255, 105, 0, 1) 0%, rgb(207, 46, 46) 100%)', + gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)', + slug: 'luminous-vivid-orange-to-vivid-red', }, { name: __( 'Very light gray to cyan bluish gray' ), - gradient: 'linear-gradient(135deg, rgb(238, 238, 238) 0%, rgb(169, 184, 195)', + gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)', + slug: 'very-light-gray-to-cyan-bluish-gray', }, // The following use new, customized colors. { name: __( 'Cool to warm spectrum' ), - gradient: 'linear-gradient(135deg, rgb(74, 234, 220), rgb(151, 120, 209), rgb(207, 42, 186), rgb(238, 44, 130), rgb(251, 105, 98),rgb(254, 248, 76)', + gradient: 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)', + slug: 'cool-to-warm-spectrum', }, { name: __( 'Blush light purple' ), - gradient: 'linear-gradient(135deg, rgb(255, 206, 236), rgb(152, 150, 240)', + gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)', + slug: 'blush-light-purple', }, { name: __( 'Blush bordeaux' ), - gradient: 'linear-gradient(135deg, rgb(254, 205, 165), rgb(254, 45, 45), rgb(107, 0, 62)', + gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)', + slug: 'blush-bordeaux', }, { name: __( 'Purple crush' ), - gradient: 'linear-gradient(135deg, rgb(52, 226, 228), rgb(71, 33, 251), rgb(171, 29, 254)', + gradient: 'linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%)', + slug: 'purple-crush', }, { name: __( 'Luminous dusk' ), - gradient: 'linear-gradient(135deg, rgb(255, 203, 112), rgb(199, 81, 192), rgb(65, 88, 208)', + gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)', + slug: 'luminous-dusk', }, { name: __( 'Hazy dawn' ), - gradient: 'linear-gradient(135deg, rgb(250, 172, 168), rgb(218, 208, 236)', + gradient: 'linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%)', + slug: 'hazy-dawn', }, { name: __( 'Pale ocean' ), - gradient: 'linear-gradient(135deg, rgb(255, 245, 203), rgb(182, 227, 212), rgb(51, 167, 181)', + gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)', + slug: 'pale-ocean', }, { name: __( 'Electric grass' ), - gradient: 'linear-gradient(135deg, rgb(202, 248, 128), rgb(113, 206, 126)', + gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)', + slug: 'electric-grass', }, { name: __( 'Subdued olive' ), - gradient: 'linear-gradient(135deg, rgb(250, 250, 225), rgb(103, 166, 113)', + gradient: 'linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%)', + slug: 'subdued-olive', }, { name: __( 'Atomic cream' ), - gradient: 'linear-gradient(135deg, rgb(253, 215, 154), rgb(0, 74, 89)', + gradient: 'linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%)', + slug: 'atomic-cream', }, { name: __( 'Nightshade' ), - gradient: 'linear-gradient(135deg, rgb(51, 9, 104), rgb(49, 205, 207)', + gradient: 'linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%)', + slug: 'nightshade', }, { name: __( 'Midnight' ), - gradient: 'linear-gradient(135deg, rgb(2, 3, 129), rgb(40, 116, 252)', + gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)', + slug: 'midnight', }, ], }; - diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d0dd7a69a15973..76bec295096bc3 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -29,6 +29,16 @@ import { } from '@wordpress/blocks'; import { SVG, Rect, G, Path } from '@wordpress/components'; +/** + * A block selection object. + * + * @typedef {Object} WPBlockSelection + * + * @property {string} clientId A block client ID. + * @property {string} attributeKey A block attribute key. + * @property {number} offset A block attribute offset. + */ + // Module constants /** @@ -237,9 +247,9 @@ export const getGlobalBlockCount = createSelector( if ( ! blockName ) { return clientIds.length; } - return reduce( clientIds, ( count, clientId ) => { + return reduce( clientIds, ( accumulator, clientId ) => { const block = state.blocks.byClientId[ clientId ]; - return block.name === blockName ? count + 1 : count; + return block.name === blockName ? accumulator + 1 : accumulator; }, 0 ); }, ( state ) => [ @@ -281,14 +291,6 @@ export function getBlockCount( state, rootClientId ) { return getBlockOrder( state, rootClientId ).length; } -/** - * @typedef {WPBlockSelection} A block selection object. - * - * @property {string} clientId A block client ID. - * @property {string} attributeKey A block attribute key. - * @property {number} offset A block attribute offset. - */ - /** * Returns the current selection start block client ID, attribute key and text * offset. @@ -418,6 +420,30 @@ export function getBlockRootClientId( state, clientId ) { null; } +/** + * Given a block client ID, returns the list of all its parents from top to bottom. + * + * @param {Object} state Editor state. + * @param {string} clientId Block from which to find root client ID. + * + * @return {Array} ClientIDs of the parent blocks. + */ +export const getBlockParents = createSelector( + ( state, clientId ) => { + const parents = []; + let current = clientId; + while ( !! state.blocks.parents[ current ] ) { + current = state.blocks.parents[ current ]; + parents.push( current ); + } + + return parents.reverse(); + }, + ( state ) => [ + state.blocks.parents, + ] +); + /** * Given a block client ID, returns the root of the hierarchy from which the block is nested, return the block itself for root level blocks. * @@ -1123,9 +1149,9 @@ const canIncludeBlockTypeInInserter = ( state, blockType, rootClientId ) => { * @param {Object} state Editor state. * @param {?string} rootClientId Optional root client ID of block list. * - * @return {Editor.InserterItem[]} Items that appear in inserter. + * @return {WPEditorInserterItem[]} Items that appear in inserter. * - * @typedef {Object} Editor.InserterItem + * @typedef {Object} WPEditorInserterItem * @property {string} id Unique identifier for the item. * @property {string} name The type of block to create. * @property {Object} initialAttributes Attributes to pass to the newly created block. @@ -1284,6 +1310,22 @@ export const hasInserterItems = createSelector( ], ); +/** + * Returns the list of allowed inserter blocks for inner blocks children + * + * @param {Object} state Editor state. + * @param {?string} rootClientId Optional root client ID of block list. + * + * @return {Array?} The list of allowed block types or false. + */ +export const __experimentalGetAllowedBlocks = ( state, rootClientId = null ) => { + if ( ! rootClientId ) { + return false; + } + const { allowedBlocks } = getBlockListSettings( state, rootClientId ); + return allowedBlocks; +}; + /** * Returns the Block List settings of a block, if any exist. * diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 8ebb2e487a4f29..9c149f001cf7fa 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -3,6 +3,7 @@ @import "./components/block-inspector/style.scss"; @import "./components/block-list/style.scss"; @import "./components/block-list-appender/style.scss"; +@import "./components/block-breadcrumb/style.scss"; @import "./components/block-card/style.scss"; @import "./components/block-compare/style.scss"; @import "./components/block-mover/style.scss"; @@ -18,6 +19,7 @@ @import "./components/contrast-checker/style.scss"; @import "./components/default-block-appender/style.scss"; @import "./components/gradient-picker/control.scss"; +@import "./components/link-control/style.scss"; @import "./components/inner-blocks/style.scss"; @import "./components/inserter-with-shortcuts/style.scss"; @import "./components/inserter/style.scss"; diff --git a/packages/block-library/package.json b/packages/block-library/package.json index cf7b1171009db5..8d4cd8ba268545 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "2.9.0", + "version": "2.9.3", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js index 15387acbd90c7a..b048722a70ecf7 100644 --- a/packages/block-library/src/audio/edit.js +++ b/packages/block-library/src/audio/edit.js @@ -214,10 +214,8 @@ class AudioEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { __experimentalMediaUpload } = getSettings(); - return { - mediaUpload: __experimentalMediaUpload, - }; + const { mediaUpload } = getSettings(); + return { mediaUpload }; } ), withNotices, ] )( AudioEdit ); diff --git a/packages/block-library/src/button/block.json b/packages/block-library/src/button/block.json index ff43c67db5e834..bc35b9ff5ee32e 100644 --- a/packages/block-library/src/button/block.json +++ b/packages/block-library/src/button/block.json @@ -49,6 +49,9 @@ "borderRadius": { "type": "number" }, + "gradient": { + "type": "string" + }, "customGradient": { "type": "string" } diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index 17908484218091..11d1deef862cfd 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -8,7 +8,6 @@ import classnames from 'classnames'; */ import { __ } from '@wordpress/i18n'; import { - Component, useCallback, } from '@wordpress/element'; import { @@ -24,13 +23,14 @@ import { withFallbackStyles, } from '@wordpress/components'; import { - URLInput, - RichText, + __experimentalGradientPickerPanel, + __experimentalUseGradient, ContrastChecker, InspectorControls, - withColors, PanelColorSettings, - __experimentalGradientPickerControl, + RichText, + URLInput, + withColors, } from '@wordpress/block-editor'; const { getComputedStyle } = window; @@ -74,177 +74,163 @@ function BorderPanel( { borderRadius = '', setAttributes } ) { ); } -class ButtonEdit extends Component { - constructor() { - super( ...arguments ); - this.nodeRef = null; - this.bindRef = this.bindRef.bind( this ); - this.onSetLinkRel = this.onSetLinkRel.bind( this ); - this.onToggleOpenInNewTab = this.onToggleOpenInNewTab.bind( this ); - } - - bindRef( node ) { - if ( ! node ) { - return; - } - this.nodeRef = node; - } - - onSetLinkRel( value ) { - this.props.setAttributes( { rel: value } ); - } - - onToggleOpenInNewTab( value ) { - const { rel } = this.props.attributes; - const linkTarget = value ? '_blank' : undefined; - - let updatedRel = rel; - if ( linkTarget && ! rel ) { - updatedRel = NEW_TAB_REL; - } else if ( ! linkTarget && rel === NEW_TAB_REL ) { - updatedRel = undefined; - } - - this.props.setAttributes( { - linkTarget, - rel: updatedRel, - } ); - } - - render() { - const { - attributes, - backgroundColor, - textColor, - setBackgroundColor, - setTextColor, - fallbackBackgroundColor, - fallbackTextColor, - setAttributes, - className, - instanceId, - isSelected, - } = this.props; - - const { - borderRadius, - linkTarget, - placeholder, - rel, - text, - title, - url, - customGradient, - } = attributes; +function ButtonEdit( { + attributes, + backgroundColor, + textColor, + setBackgroundColor, + setTextColor, + fallbackBackgroundColor, + fallbackTextColor, + setAttributes, + className, + instanceId, + isSelected, +} ) { + const { + borderRadius, + linkTarget, + placeholder, + rel, + text, + title, + url, + } = attributes; + const onSetLinkRel = useCallback( + ( value ) => { + setAttributes( { rel: value } ); + }, + [ setAttributes ] + ); - const linkId = `wp-block-button__inline-link-${ instanceId }`; + const onToggleOpenInNewTab = useCallback( + ( value ) => { + const newLinkTarget = value ? '_blank' : undefined; + + let updatedRel = rel; + if ( newLinkTarget && ! rel ) { + updatedRel = NEW_TAB_REL; + } else if ( ! newLinkTarget && rel === NEW_TAB_REL ) { + updatedRel = undefined; + } + + setAttributes( { + linkTarget: newLinkTarget, + rel: updatedRel, + } ); + }, + [ rel, setAttributes ] + ); + const { + gradientClass, + gradientValue, + setGradient, + } = __experimentalUseGradient(); - return ( -
- setAttributes( { text: value } ) } - withoutInteractiveFormatting - className={ classnames( - 'wp-block-button__link', { - 'has-background': backgroundColor.color || customGradient, - [ backgroundColor.class ]: ! customGradient && backgroundColor.class, - 'has-text-color': textColor.color, - [ textColor.class ]: textColor.class, - 'no-border-radius': borderRadius === 0, + const linkId = `wp-block-button__inline-link-${ instanceId }`; + return ( +
+ setAttributes( { text: value } ) } + withoutInteractiveFormatting + className={ classnames( + 'wp-block-button__link', { + 'has-background': backgroundColor.color || gradientValue, + [ backgroundColor.class ]: ! gradientValue && backgroundColor.class, + 'has-text-color': textColor.color, + [ textColor.class ]: textColor.class, + [ gradientClass ]: gradientClass, + 'no-border-radius': borderRadius === 0, + } + ) } + style={ { + ...( ! backgroundColor.color && gradientValue ? + { background: gradientValue } : + { backgroundColor: backgroundColor.color } + ), + color: textColor.color, + borderRadius: borderRadius ? borderRadius + 'px' : undefined, + } } + /> + + setAttributes( { url: value } ) } + disableSuggestions={ ! isSelected } + id={ linkId } + isFullWidth + hasBorder + /> + + + { + setAttributes( { customGradient: undefined } ); + setBackgroundColor( newColor ); + }, + label: __( 'Background Color' ), + }, + { + value: textColor.color, + onChange: setTextColor, + label: __( 'Text Color' ), + }, + ] } + > + + + <__experimentalGradientPickerPanel + onChange={ + ( newGradient ) => { + setGradient( newGradient ); + setBackgroundColor(); } - ) } - style={ { - backgroundColor: ! customGradient && backgroundColor.color, - background: customGradient, - color: textColor.color, - borderRadius: borderRadius ? borderRadius + 'px' : undefined, - } } + } + value={ gradientValue } + /> + - - setAttributes( { url: value } ) } - disableSuggestions={ ! isSelected } - id={ linkId } - isFullWidth - hasBorder + + - - - { - setAttributes( { customGradient: undefined } ); - setBackgroundColor( newColor ); - }, - label: __( 'Background Color' ), - }, - { - value: textColor.color, - onChange: setTextColor, - label: __( 'Text Color' ), - }, - ] } - > - - - - <__experimentalGradientPickerControl - onChange={ - ( newGradient ) => { - setAttributes( { - customGradient: newGradient, - backgroundColor: undefined, - customBackgroundColor: undefined, - } ); - } - } - value={ customGradient } - /> - - - - - - - -
- ); - } + + +
+ ); } export default compose( [ diff --git a/packages/block-library/src/button/save.js b/packages/block-library/src/button/save.js index bcf18ffc293242..59eaa9f201217e 100644 --- a/packages/block-library/src/button/save.js +++ b/packages/block-library/src/button/save.js @@ -9,6 +9,7 @@ import classnames from 'classnames'; import { RichText, getColorClassName, + __experimentalGetGradientClass, } from '@wordpress/block-editor'; export default function save( { attributes } ) { @@ -19,6 +20,7 @@ export default function save( { attributes } ) { customTextColor, customGradient, linkTarget, + gradient, rel, text, textColor, @@ -28,18 +30,20 @@ export default function save( { attributes } ) { const textClass = getColorClassName( 'color', textColor ); const backgroundClass = ! customGradient && getColorClassName( 'background-color', backgroundColor ); + const gradientClass = __experimentalGetGradientClass( gradient ); const buttonClasses = classnames( 'wp-block-button__link', { 'has-text-color': textColor || customTextColor, [ textClass ]: textClass, - 'has-background': backgroundColor || customBackgroundColor || customGradient, + 'has-background': backgroundColor || customBackgroundColor || customGradient || gradient, [ backgroundClass ]: backgroundClass, 'no-border-radius': borderRadius === 0, + [ gradientClass ]: gradientClass, } ); const buttonStyle = { - backgroundColor: backgroundClass || customGradient ? undefined : customBackgroundColor, background: customGradient ? customGradient : undefined, + backgroundColor: backgroundClass || customGradient || gradient ? undefined : customBackgroundColor, color: textClass ? undefined : customTextColor, borderRadius: borderRadius ? borderRadius + 'px' : undefined, }; diff --git a/packages/block-library/src/columns/deprecated.js b/packages/block-library/src/columns/deprecated.js index 56ffe5d90bc6a1..a344f72eaf69f3 100644 --- a/packages/block-library/src/columns/deprecated.js +++ b/packages/block-library/src/columns/deprecated.js @@ -66,7 +66,7 @@ export default [ ) ); }, migrate( attributes, innerBlocks ) { - const columns = innerBlocks.reduce( ( result, innerBlock ) => { + const columns = innerBlocks.reduce( ( accumulator, innerBlock ) => { const { originalContent } = innerBlock; let columnIndex = getDeprecatedLayoutColumn( originalContent ); @@ -74,13 +74,13 @@ export default [ columnIndex = 0; } - if ( ! result[ columnIndex ] ) { - result[ columnIndex ] = []; + if ( ! accumulator[ columnIndex ] ) { + accumulator[ columnIndex ] = []; } - result[ columnIndex ].push( innerBlock ); + accumulator[ columnIndex ].push( innerBlock ); - return result; + return accumulator; }, [] ); const migratedInnerBlocks = columns.map( ( columnBlocks ) => ( diff --git a/packages/block-library/src/columns/editor.scss b/packages/block-library/src/columns/editor.scss index dfa71f9f0589b3..60c6730fc2b088 100644 --- a/packages/block-library/src/columns/editor.scss +++ b/packages/block-library/src/columns/editor.scss @@ -12,18 +12,6 @@ } } -// Fullwide: show margin left/right to ensure there's room for the side UI. -// This is not a 1:1 preview with the front-end where these margins would presumably be zero. -[data-type="core/columns"][data-align="full"] .wp-block-columns > .editor-inner-blocks { - padding-left: $block-padding; - padding-right: $block-padding; - - @include break-small() { - padding-left: $block-container-side-padding; - padding-right: $block-container-side-padding; - } -} - .wp-block-columns { display: block; @@ -43,7 +31,14 @@ > [data-type="core/column"] > .editor-block-list__block-edit .block-core-columns { display: flex; flex-direction: column; - flex: 1 0 auto; + + // This flex rule fixes an issue in IE11. + flex: 1 1 auto; + + // IE11 does not support `position: sticky`, so we use it here to serve correct Flex rules to modern browsers. + @supports (position: sticky) { + flex: 1; + } } // Adjust the individual column block. @@ -181,10 +176,10 @@ div.block-core-columns.is-vertically-aligned-bottom { /** * Add extra padding when the parent block is selected, for easier interaction. */ -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/columns"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/columns"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/column"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/column"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks { +[data-type="core/columns"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +[data-type="core/columns"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +[data-type="core/column"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +[data-type="core/column"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks { padding: $block-padding; // Negate this padding for the placeholder. @@ -193,3 +188,16 @@ div.block-core-columns.is-vertically-aligned-bottom { width: calc(100% + #{$block-padding * 2}); } } + + +// Fullwide: show margin left/right to ensure there's room for the side UI. +// This is not a 1:1 preview with the front-end where these margins would presumably be zero. +[data-type="core/columns"][data-align="full"] .wp-block-columns { + padding-left: $block-padding; + padding-right: $block-padding; + + @include break-small() { + padding-left: $block-container-side-padding; + padding-right: $block-container-side-padding; + } +} diff --git a/packages/block-library/src/columns/utils.js b/packages/block-library/src/columns/utils.js index 77a0b7cf4375a8..a6773d469c98f7 100644 --- a/packages/block-library/src/columns/utils.js +++ b/packages/block-library/src/columns/utils.js @@ -87,9 +87,9 @@ export function getTotalColumnsWidth( blocks, totalBlockCount = blocks.length ) * @return {Object} Column widths. */ export function getColumnWidths( blocks, totalBlockCount = blocks.length ) { - return blocks.reduce( ( result, block ) => { + return blocks.reduce( ( accumulator, block ) => { const width = getEffectiveColumnWidth( block, totalBlockCount ); - return Object.assign( result, { [ block.clientId ]: width } ); + return Object.assign( accumulator, { [ block.clientId ]: width } ); }, {} ); } diff --git a/packages/block-library/src/cover/block.json b/packages/block-library/src/cover/block.json index 957a8264ef6e6e..67e87f54c8374b 100644 --- a/packages/block-library/src/cover/block.json +++ b/packages/block-library/src/cover/block.json @@ -31,6 +31,9 @@ }, "minHeight": { "type": "number" + }, + "customGradient": { + "type": "string" } } } diff --git a/packages/block-library/src/cover/edit.js b/packages/block-library/src/cover/edit.js index 1994f4a57e0713..1bc69c5d9af860 100644 --- a/packages/block-library/src/cover/edit.js +++ b/packages/block-library/src/cover/edit.js @@ -39,6 +39,8 @@ import { PanelColorSettings, withColors, ColorPalette, + __experimentalGradientPickerControl, + __experimentalGradientPicker, } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; import { withDispatch } from '@wordpress/data'; @@ -110,7 +112,7 @@ const CoverHeightInput = withInstanceId( onBlur={ onBlurEvent } value={ temporaryInput !== null ? temporaryInput : value } min={ COVER_MIN_HEIGHT } - step="10" + step="1" /> ); @@ -219,12 +221,13 @@ class CoverEdit extends Component { } = this.props; const { backgroundType, + customGradient, dimRatio, focalPoint, hasParallax, id, - url, minHeight, + url, } = attributes; const onSelectMedia = ( media ) => { if ( ! media || ! media.url ) { @@ -282,14 +285,20 @@ class CoverEdit extends Component { minHeight: ( temporaryMinHeight || minHeight ), }; + if ( customGradient && ! url ) { + style.background = customGradient; + } + if ( focalPoint ) { style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`; } + const hasBackground = !! ( url || overlayColor.color || customGradient ); + const controls = ( <> - { !! ( url || overlayColor.color ) && ( + { hasBackground && ( <> @@ -348,7 +357,7 @@ class CoverEdit extends Component { ) } - { ( url || overlayColor.color ) && ( + { hasBackground && ( <> { + setAttributes( { + customGradient: undefined, + } ); + setOverlayColor( ...args ); + }, label: __( 'Overlay Color' ), } ] } > + <__experimentalGradientPickerControl + label={ __( 'Overlay Gradient' ) } + onChange={ + ( newGradient ) => { + setAttributes( { + customGradient: newGradient, + customOverlayColor: undefined, + overlayColor: undefined, + } ); + } + } + value={ customGradient } + /> { !! url && ( ); - if ( ! ( url || overlayColor.color ) ) { + if ( ! hasBackground ) { const placeholderIcon = ; const label = __( 'Cover' ); @@ -409,13 +436,29 @@ class CoverEdit extends Component { notices={ noticeUI } onError={ this.onUploadError } > - +
+ + <__experimentalGradientPicker + onChange={ + ( newGradient ) => { + setAttributes( { + customGradient: newGradient, + customOverlayColor: undefined, + overlayColor: undefined, + } ); + } + } + value={ customGradient } + clearable={ false } + /> +
); @@ -429,6 +472,7 @@ class CoverEdit extends Component { 'has-background-dim': dimRatio !== 0, 'has-parallax': hasParallax, [ overlayColor.class ]: overlayColor.class, + 'has-background-gradient': customGradient, } ); @@ -476,6 +520,13 @@ class CoverEdit extends Component { src={ url } /> ) } + { url && customGradient && dimRatio !== 0 && ( +
- - setAttributes( { content: value } ) } - onMerge={ mergeBlocks } - onSplit={ ( value ) => { - if ( ! value ) { - return createBlock( 'core/paragraph' ); - } + { InspectorControlsColorPanel } + + setAttributes( { content: value } ) } + onMerge={ mergeBlocks } + onSplit={ ( value ) => { + if ( ! value ) { + return createBlock( 'core/paragraph' ); + } - return createBlock( 'core/heading', { - ...attributes, - content: value, - } ); - } } - onReplace={ onReplace } - onRemove={ () => onReplace( [] ) } - className={ classnames( className, { - [ `has-text-align-${ align }` ]: align, - 'has-text-color': textColor.color, - [ textColor.class ]: textColor.class, - } ) } - placeholder={ placeholder || __( 'Write heading…' ) } - style={ { - color: textColor.color, - } } - /> + return createBlock( 'core/heading', { + ...attributes, + content: value, + } ); + } } + onReplace={ onReplace } + onRemove={ () => onReplace( [] ) } + className={ classnames( className, { + [ `has-text-align-${ align }` ]: align, + } ) } + placeholder={ placeholder || __( 'Write heading…' ) } + /> + ); } -export default compose( [ - withColors( 'backgroundColor', { textColor: 'color' } ), -] )( HeadingEdit ); +export default withFallbackStyles( ( node ) => { + let backgroundColor = getComputedStyle( node ).backgroundColor; + while ( backgroundColor === 'rgba(0, 0, 0, 0)' && node.parentNode ) { + node = node.parentNode; + backgroundColor = getComputedStyle( node ).backgroundColor; + } + return { backgroundColor }; +} )( HeadingEdit ); diff --git a/packages/block-library/src/image/constants.js b/packages/block-library/src/image/constants.js index cd5e82b323bed5..ec8c41b8b09c31 100644 --- a/packages/block-library/src/image/constants.js +++ b/packages/block-library/src/image/constants.js @@ -3,6 +3,6 @@ export const LINK_DESTINATION_NONE = 'none'; export const LINK_DESTINATION_MEDIA = 'media'; export const LINK_DESTINATION_ATTACHMENT = 'attachment'; export const LINK_DESTINATION_CUSTOM = 'custom'; -export const NEW_TAB_REL = 'noreferrer noopener'; +export const NEW_TAB_REL = [ 'noreferrer', 'noopener' ]; export const ALLOWED_MEDIA_TYPES = [ 'image' ]; export const DEFAULT_SIZE_SLUG = 'large'; diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index b5779e71180e7d..c5dfdc20b97148 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -25,7 +25,6 @@ import { NavigableMenu, PanelBody, Path, - Rect, ResizableBox, SelectControl, Spinner, @@ -70,9 +69,9 @@ import { speak } from '@wordpress/a11y'; * Internal dependencies */ import { createUpgradedEmbedBlock } from '../embed/util'; -import icon from './icon'; +import icon, { editImageIcon } from './icon'; import ImageSize from './image-size'; -import { getUpdatedLinkTargetSettings } from './utils'; +import { getUpdatedLinkTargetSettings, removeNewTabRel } from './utils'; /** * Module constants @@ -585,8 +584,8 @@ export class ImageEdit extends Component { sizeSlug, } = attributes; + const cleanRel = removeNewTabRel( rel ); const isExternal = isExternalImage( id, url ); - const editImageIcon = ( ); const controls = ( } @@ -931,7 +930,7 @@ export default compose( [ const { getSettings } = select( 'core/block-editor' ); const { attributes: { id }, isSelected } = props; const { - __experimentalMediaUpload, + mediaUpload, imageSizes, isRTL, maxWidth, @@ -942,7 +941,7 @@ export default compose( [ maxWidth, isRTL, imageSizes, - mediaUpload: __experimentalMediaUpload, + mediaUpload, }; } ), withViewportMatch( { isLargeViewport: 'medium' } ), diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index ce2c1affe275a5..1d9274c3754697 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -9,7 +9,7 @@ import { requestImageFailedRetryDialog, requestImageUploadCancelDialog, } from 'react-native-gutenberg-bridge'; -import { isEmpty } from 'lodash'; +import { isEmpty, map } from 'lodash'; /** * WordPress dependencies @@ -17,10 +17,12 @@ import { isEmpty } from 'lodash'; import { TextControl, ToggleControl, + SelectControl, Icon, Toolbar, ToolbarButton, PanelBody, + PanelActions, } from '@wordpress/components'; import { @@ -31,6 +33,7 @@ import { MEDIA_TYPE_IMAGE, BlockControls, InspectorControls, + BlockAlignmentToolbar, } from '@wordpress/block-editor'; import { __, sprintf } from '@wordpress/i18n'; import { isURL } from '@wordpress/url'; @@ -41,7 +44,7 @@ import { withPreferredColorScheme } from '@wordpress/compose'; * Internal dependencies */ import styles from './styles.scss'; -import SvgIcon from './icon'; +import SvgIcon, { editImageIcon } from './icon'; import SvgIconRetry from './icon-retry'; import { getUpdatedLinkTargetSettings } from './utils'; @@ -50,6 +53,19 @@ import { LINK_DESTINATION_NONE, } from './constants'; +const IMAGE_SIZE_THUMBNAIL = 'thumbnail'; +const IMAGE_SIZE_MEDIUM = 'medium'; +const IMAGE_SIZE_LARGE = 'large'; +const IMAGE_SIZE_FULL_SIZE = 'full'; +const DEFAULT_SIZE_SLUG = IMAGE_SIZE_LARGE; +const sizeOptionLabels = { + [ IMAGE_SIZE_THUMBNAIL ]: __( 'Thumbnail' ), + [ IMAGE_SIZE_MEDIUM ]: __( 'Medium' ), + [ IMAGE_SIZE_LARGE ]: __( 'Large' ), + [ IMAGE_SIZE_FULL_SIZE ]: __( 'Full Size' ), +}; +const sizeOptions = map( sizeOptionLabels, ( label, option ) => ( { value: option, label } ) ); + // Default Image ratio 4:3 const IMAGE_ASPECT_RATIO = 4 / 3; @@ -70,9 +86,11 @@ export class ImageEdit extends React.Component { this.updateImageURL = this.updateImageURL.bind( this ); this.onSetLinkDestination = this.onSetLinkDestination.bind( this ); this.onSetNewTab = this.onSetNewTab.bind( this ); + this.onSetSizeSlug = this.onSetSizeSlug.bind( this ); this.onImagePressed = this.onImagePressed.bind( this ); this.onClearSettings = this.onClearSettings.bind( this ); this.onFocusCaption = this.onFocusCaption.bind( this ); + this.updateAlignment = this.updateAlignment.bind( this ); } componentDidMount() { @@ -86,14 +104,18 @@ export class ImageEdit extends React.Component { console.warn( 'Attributes has id with no url.' ); } + // Detect any pasted image and start an upload + if ( ! attributes.id && attributes.url && attributes.url.indexOf( 'file:' ) === 0 ) { + requestMediaImport( attributes.url, ( id, url ) => { + if ( url ) { + setAttributes( { id, url } ); + } + } ); + } + + // Make sure we mark any temporary images as failed if they failed while + // the editor wasn't open if ( attributes.id && attributes.url && ! isURL( attributes.url ) ) { - if ( attributes.url.indexOf( 'file:' ) === 0 ) { - requestMediaImport( attributes.url, ( id, url ) => { - if ( url ) { - setAttributes( { id, url } ); - } - } ); - } mediaUploadSync(); } } @@ -167,6 +189,10 @@ export class ImageEdit extends React.Component { this.props.setAttributes( { url, width: undefined, height: undefined } ); } + updateAlignment( nextAlign ) { + this.props.setAttributes( { align: nextAlign } ); + } + onSetLinkDestination( href ) { this.props.setAttributes( { linkDestination: LINK_DESTINATION_CUSTOM, @@ -179,12 +205,19 @@ export class ImageEdit extends React.Component { this.props.setAttributes( updatedLinkTarget ); } + onSetSizeSlug( sizeSlug ) { + this.props.setAttributes( { + sizeSlug, + } ); + } + onClearSettings() { this.props.setAttributes( { alt: '', linkDestination: LINK_DESTINATION_NONE, href: undefined, linkTarget: undefined, + sizeSlug: DEFAULT_SIZE_SLUG, rel: undefined, } ); } @@ -216,17 +249,24 @@ export class ImageEdit extends React.Component { render() { const { attributes, isSelected } = this.props; - const { url, height, width, alt, href, id, linkTarget } = attributes; + const { align, url, height, width, alt, href, id, linkTarget, sizeSlug } = attributes; + + const actions = [ { label: __( 'Clear All Settings' ), onPress: this.onClearSettings } ]; const getToolbarEditButton = ( open ) => ( + ); @@ -249,21 +289,26 @@ export class ImageEdit extends React.Component { checked={ linkTarget === '_blank' } onChange={ this.onSetNewTab } /> + { // eslint-disable-next-line no-undef + __DEV__ && + this.onSetSizeSlug( newValue ) } + options={ sizeOptions } + /> } - + ); @@ -280,6 +325,14 @@ export class ImageEdit extends React.Component { ); } + const alignToFlex = { + left: 'flex-start', + center: 'center', + right: 'flex-end', + full: 'center', + wide: 'center', + }; + const imageContainerHeight = Dimensions.get( 'window' ).width / IMAGE_ASPECT_RATIO; const getImageComponent = ( openMediaOptions, getMediaOptions ) => ( + { ! imageWidthWithinContainer && { this.getIcon( false ) } diff --git a/packages/block-library/src/image/icon.js b/packages/block-library/src/image/icon.js index b029bab8fbe98a..44f88783d24cfa 100644 --- a/packages/block-library/src/image/icon.js +++ b/packages/block-library/src/image/icon.js @@ -1,6 +1,8 @@ /** * WordPress dependencies */ -import { Path, SVG } from '@wordpress/components'; +import { Path, Rect, SVG } from '@wordpress/components'; export default ; + +export const editImageIcon = ( ); diff --git a/packages/block-library/src/image/save.js b/packages/block-library/src/image/save.js index 01aff39769152b..b3976c76a8de85 100644 --- a/packages/block-library/src/image/save.js +++ b/packages/block-library/src/image/save.js @@ -2,6 +2,7 @@ * External dependencies */ import classnames from 'classnames'; +import { isEmpty } from 'lodash'; /** * WordPress dependencies @@ -24,6 +25,8 @@ export default function save( { attributes } ) { sizeSlug, } = attributes; + const newRel = isEmpty( rel ) ? undefined : rel; + const classes = classnames( { [ `align${ align }` ]: align, [ `size-${ sizeSlug }` ]: sizeSlug, @@ -47,7 +50,7 @@ export default function save( { attributes } ) { className={ linkClass } href={ href } target={ linkTarget } - rel={ rel } + rel={ newRel } > { image } diff --git a/packages/block-library/src/image/styles.native.scss b/packages/block-library/src/image/styles.native.scss index 9c5a9cbf5c45e5..24b20de69dc8f8 100644 --- a/packages/block-library/src/image/styles.native.scss +++ b/packages/block-library/src/image/styles.native.scss @@ -18,10 +18,6 @@ align-items: center; } -.clearSettingsButton { - color: $alert-red; -} - .modalIcon { width: 80px; height: 80px; @@ -44,3 +40,13 @@ .iconDark { fill: $white; } + +.content { + flex: 1; +} + +.contentCentered { + flex: 1; + justify-content: center; + align-items: center; +} diff --git a/packages/block-library/src/image/test/edit.native.js b/packages/block-library/src/image/test/edit.native.js index d585f1f1396a9e..9c21c10d90dbaf 100644 --- a/packages/block-library/src/image/test/edit.native.js +++ b/packages/block-library/src/image/test/edit.native.js @@ -40,16 +40,16 @@ describe( 'Image Block', () => { instance.onSetNewTab( true ); - expect( setAttributes ).toBeCalledWith( { linkTarget: '_blank', rel: NEW_TAB_REL } ); + expect( setAttributes ).toHaveBeenCalledWith( { linkTarget: '_blank', rel: undefined } ); } ); it( 'unset link target', () => { - const component = renderer.create( getImageComponent( { linkTarget: '_blank', rel: NEW_TAB_REL } ) ); + const component = renderer.create( getImageComponent( { linkTarget: '_blank', rel: NEW_TAB_REL.join( ' ' ) } ) ); const instance = component.getInstance(); instance.onSetNewTab( false ); - expect( setAttributes ).toBeCalledWith( { linkTarget: undefined, rel: undefined } ); + expect( setAttributes ).toHaveBeenCalledWith( { linkTarget: undefined, rel: undefined } ); } ); } ); diff --git a/packages/block-library/src/image/utils.js b/packages/block-library/src/image/utils.js index 2cb9b8f5ca5c78..1e3e8a07fc3748 100644 --- a/packages/block-library/src/image/utils.js +++ b/packages/block-library/src/image/utils.js @@ -1,3 +1,11 @@ +/** + * External dependencies + */ +import { + isEmpty, + each, +} from 'lodash'; + /** * Internal dependencies */ @@ -12,6 +20,30 @@ export function calculatePreferedImageSize( image, container ) { return { width, height }; } +export function removeNewTabRel( currentRel ) { + let newRel = currentRel; + + if ( currentRel !== undefined && ! isEmpty( newRel ) ) { + if ( ! isEmpty( newRel ) ) { + each( NEW_TAB_REL, function( relVal ) { + const regExp = new RegExp( '\\b' + relVal + '\\b', 'gi' ); + newRel = newRel.replace( regExp, '' ); + } ); + + // Only trim if NEW_TAB_REL values was replaced. + if ( newRel !== currentRel ) { + newRel = newRel.trim(); + } + + if ( isEmpty( newRel ) ) { + newRel = undefined; + } + } + } + + return newRel; +} + /** * Helper to get the link target settings to be stored. * @@ -24,11 +56,11 @@ export function calculatePreferedImageSize( image, container ) { export function getUpdatedLinkTargetSettings( value, { rel } ) { const linkTarget = value ? '_blank' : undefined; - let updatedRel = rel; - if ( linkTarget && ! rel ) { - updatedRel = NEW_TAB_REL; - } else if ( ! linkTarget && rel === NEW_TAB_REL ) { + let updatedRel; + if ( ! linkTarget && ! rel ) { updatedRel = undefined; + } else { + updatedRel = removeNewTabRel( rel ); } return { diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index e49f68553b0a6f..3147ebcc0e9cdc 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -62,6 +62,9 @@ import * as classic from './classic'; import * as socialLinks from './social-links'; import * as socialLink from './social-link'; +// Full Site Editing Blocks +import * as siteTitle from './site-title'; + /** * Function to register an individual block. * @@ -162,14 +165,24 @@ export const registerCoreBlocks = () => { * __experimentalRegisterExperimentalCoreBlocks( settings ); * ``` */ -export const __experimentalRegisterExperimentalCoreBlocks = process.env.GUTENBERG_PHASE === 2 ? ( settings ) => { - const { __experimentalEnableLegacyWidgetBlock, __experimentalEnableMenuBlock } = settings; +export const __experimentalRegisterExperimentalCoreBlocks = + process.env.GUTENBERG_PHASE === 2 ? + ( settings ) => { + const { + __experimentalEnableLegacyWidgetBlock, + __experimentalEnableMenuBlock, + __experimentalEnableFullSiteEditing, + } = settings - [ - __experimentalEnableLegacyWidgetBlock ? legacyWidget : null, - __experimentalEnableMenuBlock ? navigationMenu : null, - __experimentalEnableMenuBlock ? navigationMenuItem : null, - socialLinks, - ...socialLink.sites, - ].forEach( registerBlock ); -} : undefined; + ;[ + __experimentalEnableLegacyWidgetBlock ? legacyWidget : null, + __experimentalEnableMenuBlock ? navigationMenu : null, + __experimentalEnableMenuBlock ? navigationMenuItem : null, + socialLinks, + ...socialLink.sites, + + // Register Full Site Editing Blocks. + ...( __experimentalEnableFullSiteEditing ? [ siteTitle ] : [] ), + ].forEach( registerBlock ); + } : + undefined; diff --git a/packages/block-library/src/index.native.js b/packages/block-library/src/index.native.js index 2702becc3a8c31..0d06a9df9f11af 100644 --- a/packages/block-library/src/index.native.js +++ b/packages/block-library/src/index.native.js @@ -96,9 +96,9 @@ export const coreBlocks = [ textColumns, verse, video, -].reduce( ( memo, block ) => { - memo[ block.name ] = block; - return memo; +].reduce( ( accumulator, block ) => { + accumulator[ block.name ] = block; + return accumulator; }, {} ); /** diff --git a/packages/block-library/src/list/block.json b/packages/block-library/src/list/block.json index 3dcae3a6ae5c22..71bca30f1a8ac3 100644 --- a/packages/block-library/src/list/block.json +++ b/packages/block-library/src/list/block.json @@ -14,6 +14,9 @@ "__unstableMultilineWrapperTags": [ "ol", "ul" ], "default": "" }, + "type": { + "type": "string" + }, "start": { "type": "number" }, diff --git a/packages/block-library/src/list/edit.js b/packages/block-library/src/list/edit.js index 6a76a376f617d3..4373bbec0ce437 100644 --- a/packages/block-library/src/list/edit.js +++ b/packages/block-library/src/list/edit.js @@ -32,7 +32,7 @@ export default function ListEdit( { onReplace, className, } ) { - const { ordered, values, reversed, start } = attributes; + const { ordered, values, type, reversed, start } = attributes; const tagName = ordered ? 'ol' : 'ul'; const controls = ( { value, onChange } ) => ( @@ -124,12 +124,13 @@ export default function ListEdit( { className={ className } placeholder={ __( 'Write list…' ) } onMerge={ mergeBlocks } - onSplit={ ( value ) => createBlock( name, { ordered, values: value } ) } + onSplit={ ( value ) => createBlock( name, { ...attributes, values: value } ) } __unstableOnSplitMiddle={ () => createBlock( 'core/paragraph' ) } onReplace={ onReplace } onRemove={ () => onReplace( [] ) } start={ start } reversed={ reversed } + type={ type } > { controls } diff --git a/packages/block-library/src/list/editor.scss b/packages/block-library/src/list/editor.scss deleted file mode 100644 index fffff9ebaf6ee1..00000000000000 --- a/packages/block-library/src/list/editor.scss +++ /dev/null @@ -1,5 +0,0 @@ -.editor-styles-wrapper div[data-type="core/list"] ul, -.editor-styles-wrapper div[data-type="core/list"] ol { - padding-left: 1.3em; - margin-left: 1.3em; -} diff --git a/packages/block-library/src/list/save.js b/packages/block-library/src/list/save.js index 18458c2c1ce5a5..8cd1d3870148ba 100644 --- a/packages/block-library/src/list/save.js +++ b/packages/block-library/src/list/save.js @@ -4,13 +4,14 @@ import { RichText } from '@wordpress/block-editor'; export default function save( { attributes } ) { - const { ordered, values, reversed, start } = attributes; + const { ordered, values, type, reversed, start } = attributes; const tagName = ordered ? 'ol' : 'ul'; return ( { - if ( url ) { - onMediaUpdate( { id, url } ); - } - } ); - } + const { mediaId, mediaUrl } = this.props; + + // Make sure we mark any temporary images as failed if they failed while + // the editor wasn't open + if ( mediaId && mediaUrl && mediaUrl.indexOf( 'file:' ) === 0 ) { mediaUploadSync(); } } @@ -161,6 +154,8 @@ class MediaContainer extends Component { const { finalWidth, finalHeight, imageWidthWithinContainer, isUploadFailed, retryMessage } = params; const opacity = isUploadInProgress ? 0.3 : 1; + const contentStyle = ! imageWidthWithinContainer ? styles.content : styles.contentCentered; + return ( - + { ! imageWidthWithinContainer && { this.getIcon( false ) } diff --git a/packages/block-library/src/media-text/style.native.scss b/packages/block-library/src/media-text/style.native.scss index 06d29dc715dab7..27c972f6f8d6e7 100644 --- a/packages/block-library/src/media-text/style.native.scss +++ b/packages/block-library/src/media-text/style.native.scss @@ -32,6 +32,12 @@ flex: 1; } +.contentCentered { + flex: 1; + justify-content: center; + align-items: center; +} + .imageContainer { align-items: center; background-color: $gray-lighten-30; diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index cd4898a4e8c692..0aa4c3436d7dfe 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -27,6 +27,9 @@ export class UnsupportedBlockEdit extends Component { const title = blockType ? blockType.settings.title : __( 'Unsupported' ); const titleStyle = getStylesFromColorScheme( styles.unsupportedBlockMessage, styles.unsupportedBlockMessageDark ); + const subTitleStyle = getStylesFromColorScheme( styles.unsupportedBlockSubtitle, styles.unsupportedBlockSubtitleDark ); + const subtitle = blockType ? { __( 'Unsupported' ) } : null; + const icon = blockType ? normalizeIconObject( blockType.settings.icon ) : 'admin-plugins'; const iconStyle = getStylesFromColorScheme( styles.unsupportedBlockIcon, styles.unsupportedBlockIconDark ); const iconClassName = 'unsupported-icon' + '-' + preferredColorScheme; @@ -34,6 +37,7 @@ export class UnsupportedBlockEdit extends Component { { title } + { subtitle } ); } diff --git a/packages/block-library/src/missing/style.native.scss b/packages/block-library/src/missing/style.native.scss index 63cd4258cd23b0..5967ceb1e4d9fe 100644 --- a/packages/block-library/src/missing/style.native.scss +++ b/packages/block-library/src/missing/style.native.scss @@ -27,12 +27,24 @@ } .unsupportedBlockMessage { - margin-top: 2; + margin-top: 4; text-align: center; color: $gray-dark; font-size: 14; + font-weight: 600; } .unsupportedBlockMessageDark { color: $white; } + +.unsupportedBlockSubtitle { + margin-top: 2; + text-align: center; + color: $gray-darken-20; + font-size: 12; +} + +.unsupportedBlockSubtitleDark { + color: $gray-20; +} diff --git a/packages/block-library/src/navigation-menu-item/block.json b/packages/block-library/src/navigation-menu-item/block.json index 915c63931cb2be..20b33eca1f4a05 100644 --- a/packages/block-library/src/navigation-menu-item/block.json +++ b/packages/block-library/src/navigation-menu-item/block.json @@ -5,9 +5,6 @@ "label": { "type": "string" }, - "destination": { - "type": "string" - }, "nofollow": { "type": "boolean", "default": false @@ -21,6 +18,9 @@ "opensInNewTab": { "type": "boolean", "default": false + }, + "url": { + "type": "string" } } } diff --git a/packages/block-library/src/navigation-menu-item/edit.js b/packages/block-library/src/navigation-menu-item/edit.js index f4e456321347c6..4d2258d08eb163 100644 --- a/packages/block-library/src/navigation-menu-item/edit.js +++ b/packages/block-library/src/navigation-menu-item/edit.js @@ -1,93 +1,140 @@ /** * External dependencies */ -import { invoke } from 'lodash'; +import classnames from 'classnames'; /** * WordPress dependencies */ import { withSelect } from '@wordpress/data'; import { - Dropdown, ExternalLink, - IconButton, PanelBody, TextareaControl, TextControl, + Toolbar, ToggleControl, + ToolbarButton, } from '@wordpress/components'; +import { + LEFT, + RIGHT, + UP, + DOWN, + BACKSPACE, + ENTER, +} from '@wordpress/keycodes'; import { __ } from '@wordpress/i18n'; import { + BlockControls, InnerBlocks, InspectorControls, - PlainText, + URLPopover, } from '@wordpress/block-editor'; import { Fragment, - useCallback, useRef, + useState, } from '@wordpress/element'; -/** - * Internal dependencies - */ -import MenuItemActions from './menu-item-actions'; -const POPOVER_PROPS = { noArrow: true }; - function NavigationMenuItemEdit( { attributes, - clientId, isSelected, isParentOfSelectedBlock, setAttributes, } ) { const plainTextRef = useRef( null ); - const onEditLableClicked = useCallback( - ( onClose ) => () => { - onClose(); - invoke( plainTextRef, [ 'current', 'textarea', 'focus' ] ); - }, - [ plainTextRef ] - ); + const [ isLinkOpen, setIsLinkOpen ] = useState( false ); + const [ isEditingLink, setIsEditingLink ] = useState( false ); + const [ urlInput, setUrlInput ] = useState( null ); + + const inputValue = urlInput !== null ? urlInput : url; + + const onKeyDown = ( event ) => { + if ( [ LEFT, DOWN, RIGHT, UP, BACKSPACE, ENTER ].indexOf( event.keyCode ) > -1 ) { + // Stop the key event from propagating up to ObserveTyping.startTypingInTextField. + event.stopPropagation(); + } + }; + + const closeURLPopover = () => { + setIsEditingLink( false ); + setUrlInput( null ); + setIsLinkOpen( false ); + }; + + const autocompleteRef = useRef( null ); + + const onFocusOutside = ( event ) => { + const autocompleteElement = autocompleteRef.current; + if ( autocompleteElement && autocompleteElement.contains( event.target ) ) { + return; + } + closeURLPopover(); + }; + + const stopPropagation = ( event ) => { + event.stopPropagation(); + }; + + const { label, url } = attributes; let content; if ( isSelected ) { content = ( -
- setAttributes( { label } ) } - aria-label={ __( 'Navigation Label' ) } - maxRows={ 1 } - /> - <Dropdown - contentClassName="wp-block-navigation-menu-item__dropdown-content" - position="bottom left" - popoverProps={ POPOVER_PROPS } - renderToggle={ ( { isOpen, onToggle } ) => ( - <IconButton - icon={ isOpen ? 'arrow-up-alt2' : 'arrow-down-alt2' } - label={ __( 'More options' ) } - onClick={ onToggle } - aria-expanded={ isOpen } - /> - ) } - renderContent={ ( { onClose } ) => ( - <MenuItemActions - clientId={ clientId } - destination={ attributes.destination } - onEditLableClicked={ onEditLableClicked( onClose ) } - /> - ) } - /> - </div> + <TextControl + ref={ plainTextRef } + className="wp-block-navigation-menu-item__field" + value={ label } + onChange={ ( labelValue ) => setAttributes( { label: labelValue } ) } + label={ __( 'Navigation Label' ) } + hideLabelFromVision={ true } + /> ); } else { - content = attributes.label; + content = <div className="wp-block-navigation-menu-item__container"> + { label } + </div>; } + return ( <Fragment> + <BlockControls> + <Toolbar> + <ToolbarButton + name="link" + icon="admin-links" + title={ __( 'Link' ) } + onClick={ () => setIsLinkOpen( ! isLinkOpen ) } + /> + { isLinkOpen && + <> + <URLPopover + className="wp-block-navigation-menu-item__inline-link-input" + onClose={ closeURLPopover } + onFocusOutside={ onFocusOutside } + > + { ( ! url || isEditingLink ) && + <URLPopover.LinkEditor + value={ inputValue } + onChangeInputValue={ setUrlInput } + onKeyPress={ stopPropagation } + onKeyDown={ onKeyDown } + onSubmit={ ( event ) => event.preventDefault() } + autocompleteRef={ autocompleteRef } + /> + } + { ( url && ! isEditingLink ) && + <URLPopover.LinkViewer + onKeyPress={ stopPropagation } + url={ url } + /> + } + + </URLPopover> + </> + } + </Toolbar> + </BlockControls> <InspectorControls> <PanelBody title={ __( 'Menu Settings' ) } @@ -138,7 +185,12 @@ function NavigationMenuItemEdit( { /> </PanelBody> </InspectorControls> - <div className="wp-block-navigation-menu-item"> + <div className={ classnames( + 'wp-block-navigation-menu-item', { + 'is-editing': isSelected || isParentOfSelectedBlock, + 'is-selected': isSelected, + } ) } + > { content } { ( isSelected || isParentOfSelectedBlock ) && <InnerBlocks diff --git a/packages/block-library/src/navigation-menu-item/editor.scss b/packages/block-library/src/navigation-menu-item/editor.scss index 2d801052ba4107..8e6c06274129b1 100644 --- a/packages/block-library/src/navigation-menu-item/editor.scss +++ b/packages/block-library/src/navigation-menu-item/editor.scss @@ -1,39 +1,64 @@ -$menu-label-field-width: 140px; + +// Normalize menu items and edit containers, to look mostly the same. +.wp-block-navigation-menu-item__field .components-text-control__input.components-text-control__input, +.wp-block-navigation-menu-item__container { + border-radius: 0; + // Make it the same height as the appender to prevent a jump. Maybe revisit this. + line-height: $icon-button-size; + min-height: $icon-button-size; +} + +.wp-block-navigation-menu-item { + margin-right: $grid-size; + + // Provide a base menu item margin. + // This should be the same inside the field, + // and the edit container should compensate. + // This is to make sure the edit and view are the same. + padding: 0 $grid-size; +} .wp-block-navigation-menu-item__edit-container { - display: grid; - grid-auto-columns: min-content; - grid-auto-flow: column; - align-items: center; + display: flex; white-space: nowrap; - border: 1px solid $light-gray-500; - // two pixes comes from two times one pixel border - width: $menu-label-field-width + $icon-button-size + 2px; - padding-left: 1px; -} -.wp-block-navigation-menu-item__edit-container .wp-block-navigation-menu-item__field { - border-right: 1px solid $light-gray-500 !important; - width: $menu-label-field-width; - border: none; - border-radius: 0; - padding-left: $grid-size-large; + // Compensate for menu item base padding. + margin-left: -$grid-size; - min-height: $icon-button-size - 1px; - line-height: $icon-button-size - 1px; + .wp-block-navigation-menu-item__field { + margin-right: $grid-size; - &, - &:focus { - color: $dark-gray-500; + // This should match the padding of the menu item. + padding: 0 $grid-size; + + // This make it look like an input field. + // We may want to not style this at all, but let's try this. + // We don't use the mixins because they increase the size of the input, which doesn't work with PlainText. + box-shadow: inset 0 0 0 1px $dark-gray-200; + transition: box-shadow 0.1s linear; + border-radius: $radius-round-rectangle; + @include reduce-motion("transition"); + + &:focus { + color: $dark-gray-900; + box-shadow: inset 0 0 0 2px $blue-medium-focus; + + // Windows High Contrast mode will show this outline, but not the box-shadow. + outline: 2px solid transparent; + } } } - .wp-block-navigation-menu-item { font-family: $editor-font; - color: #0073af; font-weight: bold; font-size: $text-editor-font-size; + background-color: var(--background-color-menu-link); + color: var(--color-menu-link); + + &:focus { + color: var(--color-menu-link); + } } .wp-block-navigation-menu-item__nofollow-external-link { @@ -42,10 +67,7 @@ $menu-label-field-width: 140px; // Separator .wp-block-navigation-menu-item__separator { - margin-top: $grid-size; - margin-bottom: $grid-size; - margin-left: 0; - margin-right: 0; + margin: $grid-size 0 $grid-size; border-top: $border-width solid $light-gray-500; } @@ -60,10 +82,6 @@ $menu-label-field-width: 140px; } .wp-block-navigation-menu .block-editor-block-list__block[data-type="core/navigation-menu-item"] { - & > .block-editor-block-list__block-edit > div[role="toolbar"] { - display: none; - } - & > .block-editor-block-list__insertion-point { display: none; } diff --git a/packages/block-library/src/navigation-menu-item/index.js b/packages/block-library/src/navigation-menu-item/index.js index 496ef92070428e..9a51131a86b41a 100644 --- a/packages/block-library/src/navigation-menu-item/index.js +++ b/packages/block-library/src/navigation-menu-item/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; - +import { Path, SVG } from '@wordpress/components'; /** * Internal dependencies */ @@ -18,10 +18,12 @@ export const settings = { parent: [ 'core/navigation-menu' ], - icon: 'admin-links', + icon: <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24"><Path d="M12 7.27l4.28 10.43-3.47-1.53-.81-.36-.81.36-3.47 1.53L12 7.27M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z" /></SVG>, description: __( 'Add a page, link, or other item to your Navigation Menu.' ), + __experimentalDisplayName: 'label', + edit, save, }; diff --git a/packages/block-library/src/navigation-menu-item/menu-item-actions.js b/packages/block-library/src/navigation-menu-item/menu-item-actions.js deleted file mode 100644 index 6e39036bab408a..00000000000000 --- a/packages/block-library/src/navigation-menu-item/menu-item-actions.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * WordPress dependencies - */ -import { - MenuItem, - NavigableMenu, -} from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { withDispatch } from '@wordpress/data'; -import { compose } from '@wordpress/compose'; - -function MenuItemActions( { - destination, - moveLeft, - moveRight, - moveToEnd, - moveToStart, - onEditLableClicked, - remove, -} ) { - return ( - <NavigableMenu> - <MenuItem - icon="admin-links" - > - { destination } - </MenuItem> - <MenuItem - onClick={ onEditLableClicked } - icon="edit" - > - { __( 'Edit label text' ) } - </MenuItem> - <div className="wp-block-navigation-menu-item__separator" /> - <MenuItem - onClick={ moveToStart } - icon="arrow-up-alt2" - > - { __( 'Move to start' ) } - </MenuItem> - <MenuItem - onClick={ moveLeft } - icon="arrow-left-alt2" - > - { __( 'Move left' ) } - </MenuItem> - <MenuItem - onClick={ moveRight } - icon="arrow-right-alt2" - > - { __( 'Move right' ) } - </MenuItem> - <MenuItem - onClick={ moveToEnd } - icon="arrow-down-alt2" - > - { __( 'Move to end' ) } - </MenuItem> - <MenuItem - icon="arrow-left-alt2" - > - { __( 'Nest underneath…' ) } - </MenuItem> - <div className="navigation-menu-item__separator" /> - <MenuItem - onClick={ remove } - icon="trash" - > - { __( 'Remove from menu' ) } - </MenuItem> - </NavigableMenu> - ); -} - -export default compose( [ - withDispatch( ( dispatch, { clientId }, { select } ) => { - const { - getBlockOrder, - getBlockRootClientId, - } = select( 'core/block-editor' ); - const parentID = getBlockRootClientId( clientId ); - const { - moveBlocksDown, - moveBlocksUp, - moveBlockToPosition, - removeBlocks, - } = dispatch( 'core/block-editor' ); - return { - moveToStart() { - moveBlockToPosition( clientId, parentID, parentID, 0 ); - }, - moveRight() { - moveBlocksDown( clientId, parentID ); - }, - moveLeft() { - moveBlocksUp( clientId, parentID ); - }, - moveToEnd() { - moveBlockToPosition( - clientId, - parentID, - parentID, - getBlockOrder( parentID ).length - 1 - ); - }, - remove() { - removeBlocks( clientId ); - }, - }; - } ), -] )( MenuItemActions ); diff --git a/packages/block-library/src/navigation-menu/block-colors-selector.js b/packages/block-library/src/navigation-menu/block-colors-selector.js new file mode 100644 index 00000000000000..0c1c98b691ef4f --- /dev/null +++ b/packages/block-library/src/navigation-menu/block-colors-selector.js @@ -0,0 +1,95 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { noop } from 'lodash'; + +/** + * WordPress dependencies + */ +import { IconButton, Dropdown, Toolbar } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { DOWN } from '@wordpress/keycodes'; +import { ColorPaletteControl, ContrastChecker } from '@wordpress/block-editor'; + +/** + * Color Selector Icon component. + * + * @return {*} React Icon component. + */ +const ColorSelectorIcon = ( { style } ) => + <div className="block-library-colors-selector__icon-container"> + <div + className="block-library-colors-selector__state-selection wp-block-navigation-menu-item" + style={ style } + > + Aa + </div> + </div>; + +/** + * Renders the Colors Selector Toolbar with the icon button. + * + * @param {Object} style - Colors style object. + * @return {*} React toggle button component. + */ +const renderToggleComponent = ( style ) => ( { onToggle, isOpen } ) => { + const openOnArrowDown = ( event ) => { + if ( ! isOpen && event.keyCode === DOWN ) { + event.preventDefault(); + event.stopPropagation(); + onToggle(); + } + }; + + return ( + <Toolbar> + <IconButton + className="components-icon-button components-toolbar__control block-library-colors-selector__toggle" + label={ __( 'Open Colors Selector' ) } + onClick={ onToggle } + onKeyDown={ openOnArrowDown } + icon={ <ColorSelectorIcon style={ style } /> } + /> + </Toolbar> + ); +}; + +const renderContent = ( { backgroundColor, textColor, onColorChange = noop } ) => ( () => { + const setColor = ( attr ) => ( value ) => onColorChange( { attr, value } ); + + return ( + <> + <div className="color-palette-controller-container"> + <ColorPaletteControl + value={ backgroundColor.color } + onChange={ setColor( 'backgroundColor' ) } + label={ __( 'Background Color' ) } + /> + </div> + + <div className="color-palette-controller-container"> + <ColorPaletteControl + value={ textColor.color } + onChange={ setColor( 'textColor' ) } + label={ __( 'Text Color' ) } + /> + </div> + + <ContrastChecker + textColor={ textColor.color } + backgroundColor={ backgroundColor.color } + isLargeText={ false } + /> + </> + ); +} ); + +export default ( { style, className, ...colorControlProps } ) => + <Dropdown + position="bottom right" + className={ classnames( 'block-library-colors-selector', className ) } + contentClassName="block-library-colors-selector__popover" + renderToggle={ renderToggleComponent( style ) } + renderContent={ renderContent( colorControlProps ) } + />; diff --git a/packages/block-library/src/navigation-menu/edit.js b/packages/block-library/src/navigation-menu/edit.js index 5b4ad5ce475f9a..fdb6fd7c2fa4db 100644 --- a/packages/block-library/src/navigation-menu/edit.js +++ b/packages/block-library/src/navigation-menu/edit.js @@ -1,14 +1,21 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ import { Fragment, useMemo, + useEffect, } from '@wordpress/element'; import { InnerBlocks, InspectorControls, BlockControls, + withColors, } from '@wordpress/block-editor'; import { withSelect } from '@wordpress/data'; import { @@ -17,19 +24,26 @@ import { Spinner, Toolbar, } from '@wordpress/components'; +import { compose } from '@wordpress/compose'; + import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import useBlockNavigator from './use-block-navigator'; +import BlockColorsStyleSelector from './block-colors-selector'; function NavigationMenu( { attributes, - setAttributes, clientId, pages, isRequesting, + backgroundColor, + textColor, + setBackgroundColor, + setTextColor, + setAttributes, } ) { const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( clientId ); const defaultMenuItems = useMemo( @@ -39,19 +53,74 @@ function NavigationMenu( { } return pages.map( ( page ) => { return [ 'core/navigation-menu-item', - { label: page.title.rendered, destination: page.permalink_template }, + { label: page.title.rendered, url: page.permalink_template }, ]; } ); }, [ pages ] ); + const navigationMenuStyles = {}; + if ( textColor.color ) { + navigationMenuStyles[ '--color-menu-link' ] = textColor.color; + } + + if ( backgroundColor.color ) { + navigationMenuStyles[ '--background-color-menu-link' ] = backgroundColor.color; + } + + const navigationMenuClasses = classnames( + 'wp-block-navigation-menu', { + 'has-text-color': textColor.color, + 'has-background-color': backgroundColor.color, + } + ); + + /** + * Set the color type according to the given values. + * It propagate the color values into the attributes object. + * Both `backgroundColorValue` and `textColorValue` are + * using the inline styles. + * + * @param {Object} colorsData Arguments passed by BlockColorsStyleSelector onColorChange. + * @param {string} colorsData.attr Color attribute. + * @param {boolean} colorsData.value Color attribute value. + */ + const setColorType = ( { attr, value } ) => { + switch ( attr ) { + case 'backgroundColor': + setBackgroundColor( value ); + setAttributes( { backgroundColorValue: value } ); + break; + + case 'textColor': + setTextColor( value ); + setAttributes( { textColorValue: value } ); + break; + } + }; + + useEffect( () => { + // Set/Unset colors CSS classes. + setAttributes( { + backgroundColorCSSClass: backgroundColor.class ? backgroundColor.class : null, + textColorCSSClass: textColor.class ? textColor.class : null, + } ); + }, [ backgroundColor.class, textColor.class ] ); + return ( <Fragment> <BlockControls> <Toolbar> { navigatorToolbarButton } </Toolbar> + <BlockColorsStyleSelector + style={ navigationMenuStyles } + className={ navigationMenuClasses } + backgroundColor={ backgroundColor } + textColor={ textColor } + onColorChange={ setColorType } + /> </BlockControls> { navigatorModal } <InspectorControls> @@ -60,23 +129,21 @@ function NavigationMenu( { > <CheckboxControl value={ attributes.automaticallyAdd } - onChange={ ( automaticallyAdd ) => { - setAttributes( { automaticallyAdd } ); - } } + onChange={ ( automaticallyAdd ) => setAttributes( { automaticallyAdd } ) } label={ __( 'Automatically add new pages' ) } help={ __( 'Automatically add new top level pages to this menu.' ) } /> </PanelBody> </InspectorControls> - <div className="wp-block-navigation-menu"> - { isRequesting && - <Spinner /> - } + + <div className={ navigationMenuClasses } style={ navigationMenuStyles }> + { isRequesting && <Spinner /> } { pages && <InnerBlocks template={ defaultMenuItems ? defaultMenuItems : null } allowedBlocks={ [ 'core/navigation-menu-item' ] } templateInsertUpdatesSelection={ false } + __experimentalMoverDirection={ 'horizontal' } /> } </div> @@ -84,17 +151,19 @@ function NavigationMenu( { ); } -export default withSelect( ( select ) => { - const { getEntityRecords } = select( 'core' ); - const { isResolving } = select( 'core/data' ); - const filterDefaultPages = { - parent: 0, - order: 'asc', - orderby: 'id', - }; - return { - pages: getEntityRecords( 'postType', 'page', filterDefaultPages ), - isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ), - }; -} )( NavigationMenu ); - +export default compose( [ + withColors( { backgroundColor: 'background-color', textColor: 'color' } ), + withSelect( ( select ) => { + const { getEntityRecords } = select( 'core' ); + const { isResolving } = select( 'core/data' ); + const filterDefaultPages = { + parent: 0, + order: 'asc', + orderby: 'id', + }; + return { + pages: getEntityRecords( 'postType', 'page', filterDefaultPages ), + isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ), + }; + } ), +] )( NavigationMenu ); diff --git a/packages/block-library/src/navigation-menu/editor.scss b/packages/block-library/src/navigation-menu/editor.scss index 2238b2fae8dd7c..cc663e7787a998 100644 --- a/packages/block-library/src/navigation-menu/editor.scss +++ b/packages/block-library/src/navigation-menu/editor.scss @@ -1,9 +1,63 @@ +// Reduce the paddings, margins, and UI of inner-blocks. +// @todo: eventually we may add a feature that lets a parent container absorb the block UI of a child block. +// When that happens, leverage that instead of the following overrides. +[data-type="core/navigation-menu"] { + // 1. Reset margins on immediate innerblocks container. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout { + margin-left: 0; + margin-right: 0; + } + + // 2. Remove paddings on subsequent immediate children. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout > .wp-block { + width: auto; + padding-left: 0; + padding-right: 0; + margin-left: 0; // something + } + + // 3. Remove margins on subsequent Edit container. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout > .wp-block > .block-editor-block-list__block-edit { + margin-left: 0; + margin-right: 0; + } + + // 4. Remove vertical margins on subsequent block container. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout .wp-block > .block-editor-block-list__block-edit > [data-block] { + margin-top: 0; + margin-bottom: 0; + } + + // Remove the dashed outlines for child blocks. + &.is-hovered .wp-block-navigation-menu .block-editor-block-list__block-edit::before, + &.is-selected .wp-block-navigation-menu .block-editor-block-list__block-edit::before, + &.has-child-selected .wp-block-navigation-menu .block-editor-block-list__block-edit::before { + border-color: transparent !important; // !important used to keep the selector from growing any more complex. + } + + // Hide the breadcrumb. + // Hide the sibling inserter. + .wp-block-navigation-menu .block-editor-block-list__insertion-point, + .wp-block-navigation-menu .block-editor-block-list__breadcrumb { + display: none; + } + + // Polish the Appender. + .wp-block-navigation-menu .block-list-appender { + margin: 0; + + .block-editor-button-block-appender { + padding: $grid-size; + outline: none; + background: none; + } + } +} + + .wp-block-navigation-menu .block-editor-block-list__layout, .wp-block-navigation-menu { display: flex; - grid-auto-columns: min-content; - grid-auto-flow: column; - align-items: top; white-space: nowrap; } @@ -12,7 +66,99 @@ } .wp-block-navigation-menu-item { - .wp-block-navigation-menu-item { + margin-left: $grid-size; + .wp-block-navigation-menu-item__link { margin-left: $grid-size-large; } } + +/** + * Colors Selector component + */ +$colors-selector-size: 22px; +.block-library-colors-selector { + width: auto; + + // Toolbar colors-selector button. + .block-library-colors-selector__toggle { + display: block; + margin: 0 auto; + padding: 3px; + width: auto; + } + + // Button container. + .block-library-colors-selector__icon-container { + width: 42px; + height: 30px; + position: relative; + margin: 0 auto; + padding: 3px; + display: flex; + align-items: center; + border-radius: 4px; + + // Add the button arrow. + &::after { + @include dropdown-arrow(); + } + + // Styling button states. + &:focus, + &:hover { + color: $dark-gray-500; + box-shadow: inset 0 0 0 1px $dark-gray-500, inset 0 0 0 2px #fff; + } + } + + // colors-selector - selection status. + .block-library-colors-selector__state-selection { + font-size: 11px; + font-style: normal; + font-family: inherit; + font-weight: 600; + + border-radius: $colors-selector-size / 2; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2); + + width: $colors-selector-size; + min-width: $colors-selector-size; + height: $colors-selector-size; + min-height: $colors-selector-size; + line-height: ($colors-selector-size - 2); + + background-color: var(--background-color-menu-link); + color: var(--color-menu-link); + } + + &:not(.has-background-color) .block-library-colors-selector__state-selection { + background-image: linear-gradient(135deg, rgba(0, 0, 0, 0.08) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.08) 50%, rgba(0, 0, 0, 0.08) 75%, transparent 75%, transparent 100%); + background-size: 12px 12px; + } +} + +// Colors Selector Popover. +$color-control-label-height: 20px; +.block-library-colors-selector__popover { + .color-palette-controller-container { + padding: 16px; + } + + .components-base-control__label { + height: $color-control-label-height; + line-height: $color-control-label-height; + } + + .component-color-indicator { + float: right; + margin-top: 2px; + } +} + +.block-editor-block-mover { + &.is-horizontal { + .block-editor-block-mover__control-drag-handle { + display: none; + } + } +} diff --git a/packages/block-library/src/navigation-menu/index.php b/packages/block-library/src/navigation-menu/index.php index ba6348bd66e1b6..b49a41a06aa11c 100644 --- a/packages/block-library/src/navigation-menu/index.php +++ b/packages/block-library/src/navigation-menu/index.php @@ -5,6 +5,56 @@ * @package gutenberg */ +/** + * Build an array with CSS classes and inline styles defining the colors + * which will be applied to the navigation menu markup in the front-end. + * + * @param array $attributes NavigationMenu block attributes. + * @return array Colors CSS classes and inline styles. + */ +function build_css_colors( $attributes ) { + // CSS classes. + $colors = array( + 'bg_css_classes' => '', + 'bg_inline_styles' => '', + 'text_css_classes' => '', + 'text_inline_styles' => '', + ); + + // Background color. + // Background color - has text color. + if ( array_key_exists( 'backgroundColor', $attributes ) ) { + $colors['bg_css_classes'] .= ' has-background-color'; + } + + // Background color - add custom CSS class. + if ( array_key_exists( 'backgroundColorCSSClass', $attributes ) ) { + $colors['bg_css_classes'] .= " {$attributes['backgroundColorCSSClass']}"; + + } elseif ( array_key_exists( 'customBackgroundColor', $attributes ) ) { + // Background color - or add inline `background-color` style. + $colors['bg_inline_styles'] = ' style="background-color: ' . esc_attr( $attributes['customBackgroundColor'] ) . ';"'; + } + + // Text color. + // Text color - has text color. + if ( array_key_exists( 'textColor', $attributes ) ) { + $colors['text_css_classes'] .= ' has-text-color'; + } + // Text color - add custom CSS class. + if ( array_key_exists( 'textColorCSSClass', $attributes ) ) { + $colors['text_css_classes'] .= " {$attributes['textColorCSSClass']}"; + + } elseif ( array_key_exists( 'customTextColor', $attributes ) ) { + // Text color - or add inline `color` style. + $colors['text_inline_styles'] = ' style="color: ' . esc_attr( $attributes['customTextColor'] ) . ';"'; + } + + $colors['bg_css_classes'] = esc_attr( trim( $colors['bg_css_classes'] ) ); + $colors['text_css_classes'] = esc_attr( trim( $colors['text_css_classes'] ) ); + + return $colors; +} /** * Renders the `core/navigation-menu` block on server. * @@ -15,22 +65,45 @@ * @return string Returns the post content with the legacy widget added. */ function render_block_navigation_menu( $attributes, $content, $block ) { - return '<nav class="wp-block-navigation-menu">' . build_navigation_menu_html( $block ) . '</nav>'; + // Inline computed colors. + $comp_inline_styles = ''; + if ( array_key_exists( 'backgroundColorValue', $attributes ) ) { + $comp_inline_styles .= ' background-color: ' . esc_attr( $attributes['backgroundColorValue'] ) . ';'; + } + + if ( array_key_exists( 'textColorValue', $attributes ) ) { + $comp_inline_styles .= ' color: ' . esc_attr( $attributes['textColorValue'] ) . ';'; + } + $comp_inline_styles = ! empty( $comp_inline_styles ) + ? ' style="' . esc_attr( trim( $comp_inline_styles ) ) . '"' + : ''; + + $colors = build_css_colors( $attributes ); + + return "<nav class='wp-block-navigation-menu' {$comp_inline_styles}>" . + build_navigation_menu_html( $block, $colors ) . + '</nav>'; } /** * Walks the inner block structure and returns an HTML list for it. * - * @param array $block The block. + * @param array $block The block. + * @param array $colors Contains inline styles and CSS classes to apply to menu item. * * @return string Returns an HTML list from innerBlocks. */ -function build_navigation_menu_html( $block ) { +function build_navigation_menu_html( $block, $colors ) { $html = ''; foreach ( (array) $block['innerBlocks'] as $key => $menu_item ) { - $html .= '<li class="wp-block-navigation-menu-item"><a class="wp-block-navigation-menu-item"'; - if ( isset( $menu_item['attrs']['destination'] ) ) { - $html .= ' href="' . $menu_item['attrs']['destination'] . '"'; + + $html .= '<li class="wp-block-navigation-menu-item ' . $colors['bg_css_classes'] . '"' . $colors['bg_inline_styles'] . '>' . + '<a + class="wp-block-navigation-menu-item__link ' . $colors['text_css_classes'] . '" + ' . $colors['text_inline_styles']; + + if ( isset( $menu_item['attrs']['url'] ) ) { + $html .= ' href="' . $menu_item['attrs']['url'] . '"'; } if ( isset( $menu_item['attrs']['title'] ) ) { $html .= ' title="' . $menu_item['attrs']['title'] . '"'; @@ -42,7 +115,7 @@ function build_navigation_menu_html( $block ) { $html .= '</a>'; if ( count( (array) $menu_item['innerBlocks'] ) > 0 ) { - $html .= build_navigation_menu_html( $menu_item ); + $html .= build_navigation_menu_html( $menu_item, $colors ); } $html .= '</li>'; @@ -54,18 +127,57 @@ function build_navigation_menu_html( $block ) { * Register the navigation menu block. * * @uses render_block_navigation_menu() + * @throws WP_Error An WP_Error exception parsing the block definition. */ function register_block_core_navigation_menu() { + register_block_type( 'core/navigation-menu', array( 'category' => 'layout', 'attributes' => array( - 'automaticallyAdd' => array( + 'className' => array( + 'type' => 'string', + ), + + 'automaticallyAdd' => array( 'type' => 'boolean', 'default' => false, ), + + 'backgroundColor' => array( + 'type' => 'string', + ), + + 'textColor' => array( + 'type' => 'string', + ), + + 'backgroundColorValue' => array( + 'type' => 'string', + ), + + 'textColorValue' => array( + 'type' => 'string', + ), + + 'customBackgroundColor' => array( + 'type' => 'string', + ), + + 'customTextColor' => array( + 'type' => 'string', + ), + + 'backgroundColorCSSClass' => array( + 'type' => 'string', + ), + + 'textColorCSSClass' => array( + 'type' => 'string', + ), ), + 'render_callback' => 'render_block_navigation_menu', ) ); diff --git a/packages/block-library/src/navigation-menu/style.scss b/packages/block-library/src/navigation-menu/style.scss new file mode 100644 index 00000000000000..3c2222ef59f252 --- /dev/null +++ b/packages/block-library/src/navigation-menu/style.scss @@ -0,0 +1,119 @@ +.wp-block-navigation-menu { + + & > ul { + display: block; + list-style: none; + margin: 0; + max-width: none; + padding-left: 0; + position: relative; + + @include break-small { + display: flex; + flex-wrap: wrap; + } + + ul { + padding-left: 0; + } + + li { + position: relative; + z-index: 1; + + &:hover, + &:focus-within { + cursor: pointer; + z-index: 99999; + } + + // Submenu Display + &:hover > ul, + &:focus-within > ul, + & ul:hover, + & ul:focus { + visibility: visible; + opacity: 1; + display: block; + } + } + + & > li { + + & > a { + padding-left: 0; + + @include break-small { + padding-left: 16px; + } + } + + &:first-of-type > a { + padding-left: 0; + } + + &:last-of-type > a { + padding-right: 0; + } + } + + // Sub-menus Flyout + & > li > ul { + margin: 0; + position: absolute; + background: #fff; + box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.2); + left: 0; + top: 100%; + min-width: max-content; + opacity: 0; + transition: all 0.5s ease; + visibility: hidden; + + ul { + width: 100%; + } + } + } + + // Menu Link + a { + display: block; + padding: 16px; + } + + // Sub-menu depth indicators + ul ul { + + list-style: none; + margin-left: 0; + // Reset the counter for each UL + counter-reset: nested-list; + + li a { + + padding-top: 8px; + padding-bottom: 8px; + + &::before { + // Increment the dashes + counter-increment: nested-list; + // Insert dashes with spaces in between + content: "\2013\00a0" counters(nested-list, "\2013\00a0", none); + } + } + } + + // Top-level sub-menu indicators + & .has-sub-menu > a { + + &::after { + content: "\00a0\25BC"; + display: inline-block; + font-size: 0.6rem; + height: inherit; + width: inherit; + } + } + +} diff --git a/packages/block-library/src/site-title/block.json b/packages/block-library/src/site-title/block.json new file mode 100644 index 00000000000000..a853cde2517b51 --- /dev/null +++ b/packages/block-library/src/site-title/block.json @@ -0,0 +1,4 @@ +{ + "name": "core/site-title", + "category": "layout" +} diff --git a/packages/block-library/src/site-title/edit.js b/packages/block-library/src/site-title/edit.js new file mode 100644 index 00000000000000..0294fb82d17a18 --- /dev/null +++ b/packages/block-library/src/site-title/edit.js @@ -0,0 +1,39 @@ +/** + * WordPress dependencies + */ +import { + useEntityProp, + __experimentalUseEntitySaving, +} from '@wordpress/core-data'; +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { RichText } from '@wordpress/block-editor'; + +export default function SiteTitleEdit() { + const [ title, setTitle ] = useEntityProp( 'root', 'site', 'title' ); + const [ isDirty, isSaving, save ] = __experimentalUseEntitySaving( + 'root', + 'site', + 'title' + ); + return ( + <> + <Button + isPrimary + className="wp-block-site-title__save-button" + disabled={ ! isDirty || ! title } + isBusy={ isSaving } + onClick={ save } + > + { __( 'Update' ) } + </Button> + <RichText + tagName="h1" + placeholder={ __( 'Site Title' ) } + value={ title } + onChange={ setTitle } + allowedFormats={ [] } + /> + </> + ); +} diff --git a/packages/block-library/src/site-title/editor.scss b/packages/block-library/src/site-title/editor.scss new file mode 100644 index 00000000000000..f2b8359cf3790b --- /dev/null +++ b/packages/block-library/src/site-title/editor.scss @@ -0,0 +1,6 @@ +.wp-block-site-title__save-button { + position: absolute; + right: 0; + top: 0; + z-index: z-index(".wp-block-site-title__save-button"); +} diff --git a/packages/block-library/src/site-title/icon.js b/packages/block-library/src/site-title/icon.js new file mode 100644 index 00000000000000..1ab74dec2c32d3 --- /dev/null +++ b/packages/block-library/src/site-title/icon.js @@ -0,0 +1,12 @@ +/** + * WordPress dependencies + */ +import { SVG, Path, Circle } from '@wordpress/components'; + +export default ( + <SVG xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <Path fill="none" d="M0 0h24v24H0V0z" /> + <Path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zM7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 2.88-2.88 7.19-5 9.88C9.92 16.21 7 11.85 7 9z" /> + <Circle cx="12" cy="9" r="2.5" /> + </SVG> +); diff --git a/packages/block-library/src/site-title/index.js b/packages/block-library/src/site-title/index.js new file mode 100644 index 00000000000000..4b8fc50b86b34f --- /dev/null +++ b/packages/block-library/src/site-title/index.js @@ -0,0 +1,20 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import icon from './icon'; +import edit from './edit'; + +const { name } = metadata; +export { metadata, name }; + +export const settings = { + title: __( 'Site Title' ), + icon, + edit, +}; diff --git a/packages/block-library/src/site-title/index.php b/packages/block-library/src/site-title/index.php new file mode 100644 index 00000000000000..6e5b5786436f09 --- /dev/null +++ b/packages/block-library/src/site-title/index.php @@ -0,0 +1,28 @@ +<?php +/** + * Server-side rendering of the `core/site-title` block. + * + * @package WordPress + */ + +/** + * Renders the `core/site-title` block on the server. + * + * @return string The render. + */ +function render_block_core_site_title() { + return sprintf( '<h1>%s</h1>', get_bloginfo( 'name' ) ); +} + +/** + * Registers the `core/site-title` block on the server. + */ +function register_block_core_site_title() { + register_block_type( + 'core/site-title', + array( + 'render_callback' => 'render_block_core_site_title', + ) + ); +} +add_action( 'init', 'register_block_core_site_title' ); diff --git a/packages/block-library/src/social-link/index.php b/packages/block-library/src/social-link/index.php index 4d04c9cd1c12c4..86d83b685e21e8 100644 --- a/packages/block-library/src/social-link/index.php +++ b/packages/block-library/src/social-link/index.php @@ -22,7 +22,7 @@ function render_core_social_link( $attributes ) { } $icon = core_social_link_get_icon( $site ); - return '<li class="wp-social-link wp-social-link-' . $site . '"><a href="' . esc_attr( $url ) . '"> ' . $icon . '</a></li>'; + return '<li class="wp-social-link wp-social-link-' . $site . '"><a href="' . esc_url( $url ) . '"> ' . $icon . '</a></li>'; } /** diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index 433ef8cb3aa2f3..3fd7e3c2b8e041 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -11,6 +11,7 @@ @import "./latest-comments/style.scss"; @import "./latest-posts/style.scss"; @import "./media-text/style.scss"; +@import "./navigation-menu/style.scss"; @import "./paragraph/style.scss"; @import "./pullquote/style.scss"; @import "./quote/style.scss"; @@ -129,6 +130,82 @@ .has-very-dark-gray-color { color: #313131; } + + // Gradients + // Our classes uses the same values we set for gradient value attributes, and we can not use spacing because of WP multi site kses rule. + /* stylelint-disable function-comma-space-after */ + .has-vivid-cyan-blue-to-vivid-purple-gradient-background { + background: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%); + } + + .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background { + background: linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%); + } + + .has-light-green-cyan-to-vivid-green-cyan-gradient-background { + background: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%); + } + + .has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background { + background: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%); + } + + .has-luminous-vivid-orange-to-vivid-red-gradient-background { + background: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%); + } + + .has-very-light-gray-to-cyan-bluish-gray-gradient-background { + background: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%); + } + + .has-cool-to-warm-spectrum-gradient-background { + background: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%); + } + + .has-blush-light-purple-gradient-background { + background: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%); + } + + .has-blush-bordeaux-gradient-background { + background: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%); + } + + .has-purple-crush-gradient-background { + background: linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%); + } + + .has-luminous-dusk-gradient-background { + background: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%); + } + + .has-hazy-dawn-gradient-background { + background: linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%); + } + + .has-pale-ocean-gradient-background { + background: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%); + } + + .has-electric-grass-gradient-background { + background: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%); + } + + .has-subdued-olive-gradient-background { + background: linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%); + } + + .has-atomic-cream-gradient-background { + background: linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%); + } + + .has-nightshade-gradient-background { + background: linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%); + } + + .has-midnight-gradient-background { + background: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%); + } + /* stylelint-enable function-comma-space-after */ } diff --git a/packages/block-library/src/table/edit.js b/packages/block-library/src/table/edit.js index b86c0e282d7f9b..1599bb7e53f64f 100644 --- a/packages/block-library/src/table/edit.js +++ b/packages/block-library/src/table/edit.js @@ -40,7 +40,6 @@ import { deleteColumn, toggleSection, isEmptyTableSection, - isCellSelected, } from './state'; import icon from './icon'; @@ -435,7 +434,6 @@ export class TableEdit extends Component { } const Tag = `t${ name }`; - const { selectedCell } = this.state; return ( <Tag> @@ -447,35 +445,21 @@ export class TableEdit extends Component { rowIndex, columnIndex, }; - const isSelected = isCellSelected( cellLocation, selectedCell ); const cellClasses = classnames( { - 'is-selected': isSelected, [ `has-text-align-${ align }` ]: align, - } ); - const richTextClassName = 'wp-block-table__cell-content'; + }, 'wp-block-table__cell-content' ); return ( - <CellTag + <RichText + tagName={ CellTag } key={ columnIndex } className={ cellClasses } scope={ CellTag === 'th' ? scope : undefined } - onClick={ ( event ) => { - // When a cell is selected, forward focus to the child RichText. This solves an issue where the - // user may click inside a cell, but outside of the RichText, resulting in nothing happening. - const richTextElement = event && event.target && event.target.querySelector( `.${ richTextClassName }` ); - if ( richTextElement ) { - richTextElement.focus(); - } - } } - > - <RichText - className={ richTextClassName } - value={ content } - onChange={ this.onChange } - unstableOnFocus={ this.createOnFocus( cellLocation ) } - /> - </CellTag> + value={ content } + onChange={ this.onChange } + unstableOnFocus={ this.createOnFocus( cellLocation ) } + /> ); } ) } </tr> diff --git a/packages/block-library/src/table/editor.scss b/packages/block-library/src/table/editor.scss index f5dbb5f2643c04..16002aa4dbaae1 100644 --- a/packages/block-library/src/table/editor.scss +++ b/packages/block-library/src/table/editor.scss @@ -36,7 +36,6 @@ td, th { - padding: 0; border: $border-width solid; } @@ -47,9 +46,6 @@ border-style: double; } - &__cell-content { - padding: 0.5em; - } // Extra specificity to override default Placeholder styles. &__placeholder-form.wp-block-table__placeholder-form { text-align: left; diff --git a/packages/block-library/src/video/edit.js b/packages/block-library/src/video/edit.js index 6236e51a95c935..d7b3cad0592602 100644 --- a/packages/block-library/src/video/edit.js +++ b/packages/block-library/src/video/edit.js @@ -319,10 +319,8 @@ class VideoEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { __experimentalMediaUpload } = getSettings(); - return { - mediaUpload: __experimentalMediaUpload, - }; + const { mediaUpload } = getSettings(); + return { mediaUpload }; } ), withNotices, withInstanceId, diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json index 924dc7e4ad552e..8f2695921aa110 100644 --- a/packages/block-serialization-default-parser/package.json +++ b/packages/block-serialization-default-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-default-parser", - "version": "3.4.0", + "version": "3.4.1", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index 28b1a0436de041..289e8b8e86afd4 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-spec-parser", - "version": "3.3.0", + "version": "3.3.1", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 1af3f49adef88a..97a4e95676fc28 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -768,7 +768,7 @@ wrapped component. _Returns_ -- `Component`: Enhanced component with injected BlockContent as prop. +- `WPComponent`: Enhanced component with injected BlockContent as prop. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 3456e2386251e0..30f3255b9188b7 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "6.7.0", + "version": "6.7.2", "description": "Block API for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index fae2e0e4da9c06..e793800ecb1362 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -44,26 +44,26 @@ export function createBlock( name, attributes = {}, innerBlocks = [] ) { // Ensure attributes contains only values defined by block type, and merge // default values for missing attributes. - const sanitizedAttributes = reduce( blockType.attributes, ( result, schema, key ) => { + const sanitizedAttributes = reduce( blockType.attributes, ( accumulator, schema, key ) => { const value = attributes[ key ]; if ( undefined !== value ) { - result[ key ] = value; + accumulator[ key ] = value; } else if ( schema.hasOwnProperty( 'default' ) ) { - result[ key ] = schema.default; + accumulator[ key ] = schema.default; } if ( [ 'node', 'children' ].indexOf( schema.source ) !== -1 ) { // Ensure value passed is always an array, which we're expecting in // the RichText component to handle the deprecated value. - if ( typeof result[ key ] === 'string' ) { - result[ key ] = [ result[ key ] ]; - } else if ( ! Array.isArray( result[ key ] ) ) { - result[ key ] = []; + if ( typeof accumulator[ key ] === 'string' ) { + accumulator[ key ] = [ accumulator[ key ] ]; + } else if ( ! Array.isArray( accumulator[ key ] ) ) { + accumulator[ key ] = []; } } - return result; + return accumulator; }, {} ); const clientId = uuid(); diff --git a/packages/blocks/src/api/index.native.js b/packages/blocks/src/api/index.native.js deleted file mode 100644 index b2cfd4963d2e81..00000000000000 --- a/packages/blocks/src/api/index.native.js +++ /dev/null @@ -1,44 +0,0 @@ -export { - cloneBlock, - createBlock, - switchToBlockType, -} from './factory'; -export { - default as parse, - getBlockAttributes, - parseWithAttributeSchema, -} from './parser'; -export { - default as serialize, - getBlockContent, - getBlockDefaultClassName, - getSaveContent, -} from './serializer'; -export { - registerBlockType, - unregisterBlockType, - getFreeformContentHandlerName, - setUnregisteredTypeHandlerName, - getUnregisteredTypeHandlerName, - getBlockType, - getBlockTypes, - getBlockSupport, - hasBlockSupport, - isReusableBlock, - getChildBlockNames, - hasChildBlocks, - hasChildBlocksWithInserterSupport, - setDefaultBlockName, - getDefaultBlockName, - setGroupingBlockName, -} from './registration'; -export { - isUnmodifiedDefaultBlock, - normalizeIconObject, -} from './utils'; -export { - doBlocksMatchTemplate, - synchronizeBlocksWithTemplate, -} from './templates'; -export { pasteHandler, getPhrasingContentSchema } from './raw-handling'; -export { default as children } from './children'; diff --git a/packages/blocks/src/api/parser.js b/packages/blocks/src/api/parser.js index 89b4f5ee5cc9f9..6300eac329f153 100644 --- a/packages/blocks/src/api/parser.js +++ b/packages/blocks/src/api/parser.js @@ -565,12 +565,12 @@ export function serializeBlockNode( blockNode, options = {} ) { * @return {Function} An implementation which parses the post content. */ const createParse = ( parseImplementation ) => - ( content ) => parseImplementation( content ).reduce( ( memo, blockNode ) => { + ( content ) => parseImplementation( content ).reduce( ( accumulator, blockNode ) => { const block = createBlockWithFallback( blockNode ); if ( block ) { - memo.push( block ); + accumulator.push( block ); } - return memo; + return accumulator; }, [] ); /** diff --git a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js index 5c5ef223298fe6..4f3c3a2a810a99 100644 --- a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js +++ b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { includes } from 'lodash'; + /** * WordPress dependencies */ @@ -11,6 +16,7 @@ export default function( node, doc ) { fontWeight, fontStyle, textDecorationLine, + textDecoration, verticalAlign, } = node.style; @@ -22,7 +28,10 @@ export default function( node, doc ) { wrap( doc.createElement( 'em' ), node ); } - if ( textDecorationLine === 'line-through' ) { + // Some DOM implementations (Safari, JSDom) don't support + // style.textDecorationLine, so we check style.textDecoration as a + // fallback. + if ( textDecorationLine === 'line-through' || includes( textDecoration, 'line-through' ) ) { wrap( doc.createElement( 's' ), node ); } diff --git a/packages/blocks/src/api/raw-handling/shortcode-converter.js b/packages/blocks/src/api/raw-handling/shortcode-converter.js index 5385f0aed41502..10f1159c92cb0c 100644 --- a/packages/blocks/src/api/raw-handling/shortcode-converter.js +++ b/packages/blocks/src/api/raw-handling/shortcode-converter.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { some, castArray, first, mapValues, pickBy, includes } from 'lodash'; +import { some, castArray, find, mapValues, pickBy, includes } from 'lodash'; /** * WordPress dependencies @@ -29,7 +29,7 @@ function segmentHTMLToShortcodeBlock( HTML, lastIndex = 0 ) { } const transformTags = castArray( transformation.tag ); - const transformTag = first( transformTags ); + const transformTag = find( transformTags, ( tag ) => regexp( tag ).test( HTML ) ); let match; diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 024f9e9d55a3e3..0d3dd7827680ec 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -60,11 +60,11 @@ import { DEPRECATED_ENTRY_KEYS } from './constants'; /** * Defined behavior of a block type. * - * @typedef {Object} WPBlockType + * @typedef {Object} WPBlock * - * @property {string} name Block type's namespaced name. - * @property {string} title Human-readable block type label. - * @property {string} category Block type category classification, + * @property {string} name Block type's namespaced name. + * @property {string} title Human-readable block type label. + * @property {string} category Block type category classification, * used in search interfaces to arrange * block types by category. * @property {WPBlockTypeIcon} [icon] Block type icon. @@ -74,7 +74,7 @@ import { DEPRECATED_ENTRY_KEYS } from './constants'; * @property {WPComponent} [save] Optional component describing * serialized markup structure of a * block type. - * @property {WPComponent} edit Component rendering an element to + * @property {WPComponent} edit Component rendering an element to * manipulate the attributes of a block * in the context of an editor. */ @@ -114,7 +114,7 @@ export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { / * @param {Object} settings Block settings. * * @return {?WPBlock} The block, if it has been successfully registered; - * otherwise `undefined`. + * otherwise `undefined`. */ export function registerBlockType( name, settings ) { settings = { @@ -234,7 +234,7 @@ export function registerBlockType( name, settings ) { * @param {string} name Block name. * * @return {?WPBlock} The previous block value, if it has been successfully - * unregistered; otherwise `undefined`. + * unregistered; otherwise `undefined`. */ export function unregisterBlockType( name ) { const oldBlock = select( 'core/blocks' ).getBlockType( name ); diff --git a/packages/blocks/src/api/serializer.js b/packages/blocks/src/api/serializer.js index 1776a32e362999..d2dfbcab2d672b 100644 --- a/packages/blocks/src/api/serializer.js +++ b/packages/blocks/src/api/serializer.js @@ -85,9 +85,9 @@ export function getSaveElement( blockTypeOrName, attributes, innerBlocks = [] ) /** * Filters the props applied to the block save result element. * - * @param {Object} props Props applied to save element. - * @param {WPBlockType} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {Object} props Props applied to save element. + * @param {WPBlock} blockType Block type definition. + * @param {Object} attributes Block attributes. */ const props = applyFilters( 'blocks.getSaveContent.extraProps', @@ -104,9 +104,9 @@ export function getSaveElement( blockTypeOrName, attributes, innerBlocks = [] ) /** * Filters the save result of a block during serialization. * - * @param {WPElement} element Block save result. - * @param {WPBlockType} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {WPElement} element Block save result. + * @param {WPBlock} blockType Block type definition. + * @param {Object} attributes Block attributes. */ element = applyFilters( 'blocks.getSaveElement', element, blockType, attributes ); @@ -150,28 +150,27 @@ export function getSaveContent( blockTypeOrName, attributes, innerBlocks ) { * @return {Object<string,*>} Subset of attributes for comment serialization. */ export function getCommentAttributes( blockType, attributes ) { - return reduce( blockType.attributes, ( result, attributeSchema, key ) => { + return reduce( blockType.attributes, ( accumulator, attributeSchema, key ) => { const value = attributes[ key ]; - // Ignore undefined values. if ( undefined === value ) { - return result; + return accumulator; } // Ignore all attributes but the ones with an "undefined" source // "undefined" source refers to attributes saved in the block comment. if ( attributeSchema.source !== undefined ) { - return result; + return accumulator; } // Ignore default value. if ( 'default' in attributeSchema && attributeSchema.default === value ) { - return result; + return accumulator; } // Otherwise, include in comment set. - result[ key ] = value; - return result; + accumulator[ key ] = value; + return accumulator; }, {} ); } diff --git a/packages/blocks/src/block-content-provider/index.js b/packages/blocks/src/block-content-provider/index.js index 352550a87be80f..96b9a4d31bcd1b 100644 --- a/packages/blocks/src/block-content-provider/index.js +++ b/packages/blocks/src/block-content-provider/index.js @@ -26,7 +26,7 @@ const { Consumer, Provider } = createContext( () => {} ); * </BlockContentProvider> * ``` * - * @return {WPElement} Element with BlockContent injected via context. + * @return {WPComponent} Element with BlockContent injected via context. */ const BlockContentProvider = ( { children, innerBlocks } ) => { const BlockContent = () => { @@ -48,7 +48,7 @@ const BlockContentProvider = ( { children, innerBlocks } ) => { * A Higher Order Component used to inject BlockContent using context to the * wrapped component. * - * @return {Component} Enhanced component with injected BlockContent as prop. + * @return {WPComponent} Enhanced component with injected BlockContent as prop. */ export const withBlockContentContext = createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/components/package.json b/packages/components/package.json index d19667eca46cf5..c542fc3a79a7e0 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "8.3.0", + "version": "8.3.2", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/src/autocomplete/index.js b/packages/components/src/autocomplete/index.js index 283ccd92633b04..b12f97b30367ba 100644 --- a/packages/components/src/autocomplete/index.js +++ b/packages/components/src/autocomplete/index.js @@ -91,7 +91,7 @@ import withSpokenMessages from '../higher-order/with-spoken-messages'; */ /** - * @typedef {Object} Completer + * @typedef {Object} WPCompleter * @property {string} name a way to identify a completer, useful for selective overriding. * @property {?string} className A class to apply to the popup menu. * @property {string} triggerPrefix the prefix that will display the menu. @@ -232,8 +232,8 @@ export class Autocomplete extends Component { /** * Load options for an autocompleter. * - * @param {Completer} completer The autocompleter. - * @param {string} query The query, if any. + * @param {WPCompleter} completer The autocompleter. + * @param {string} query The query, if any. */ loadOptions( completer, query ) { const { options } = completer; diff --git a/packages/components/src/button-group/stories/index.js b/packages/components/src/button-group/stories/index.js index 1e1646e0268d15..8b1a694691025c 100644 --- a/packages/components/src/button-group/stories/index.js +++ b/packages/components/src/button-group/stories/index.js @@ -4,7 +4,7 @@ import Button from '../../button'; import ButtonGroup from '../'; -export default { title: 'Button Group', component: ButtonGroup }; +export default { title: 'ButtonGroup', component: ButtonGroup }; export const _default = () => { const style = { margin: '0 4px' }; diff --git a/packages/components/src/button/stories/index.js b/packages/components/src/button/stories/index.js index ae949a1cd72906..b3c3b408c373ec 100644 --- a/packages/components/src/button/stories/index.js +++ b/packages/components/src/button/stories/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ @@ -5,32 +10,78 @@ import Button from '../'; export default { title: 'Button', component: Button }; -export const _default = () => <Button>Hello Button</Button>; +export const _default = () => { + const label = text( 'Label', 'Default Button' ); + + return ( + <Button>{ label }</Button> + ); +}; + +export const primary = () => { + const label = text( 'Label', 'Primary Button' ); + + return ( + <Button isPrimary>{ label }</Button> + ); +}; + +export const large = () => { + const label = text( 'Label', 'Large Button' ); + + return ( + <Button isLarge>{ label }</Button> + ); +}; + +export const largePrimary = () => { + const label = text( 'Label', 'Large Primary Button' ); + + return ( + <Button isPrimary isLarge>{ label }</Button> + ); +}; + +export const small = () => { + const label = text( 'Label', 'Small Button' ); + + return ( + <Button isSmall>{ label }</Button> + ); +}; -export const primary = () => <Button isPrimary>Hello Button</Button>; +export const toggled = () => { + const label = text( 'Label', 'Toggled Button' ); -export const large = () => <Button isLarge>Hello Button</Button>; + return ( + <Button isToggled>{ label }</Button> + ); +}; -export const largePrimary = () => ( - <Button isPrimary isLarge> - Hello Button - </Button> -); +export const disabled = () => { + const label = text( 'Label', 'Disabled Button' ); -export const small = () => <Button isSmall>Hello Button</Button>; + return ( + <Button disabled>{ label }</Button> + ); +}; -export const toggled = () => <Button isToggled>Hello Button</Button>; +export const link = () => { + const label = text( 'Label', 'Link Button' ); -export const disabled = () => <Button disabled>Hello Button</Button>; + return ( + <Button href="https://wordpress.org/" target="_blank"> + { label } + </Button> + ); +}; -export const link = () => ( - <Button href="https://wordpress.org/" target="_blank"> - Hello Button - </Button> -); +export const disabledLink = () => { + const label = text( 'Label', 'Disabled Link Button' ); -export const disabledLink = () => ( - <Button href="https://wordpress.org/" target="_blank" disabled> - Hello Button - </Button> -); + return ( + <Button href="https://wordpress.org/" target="_blank" disabled> + { label } + </Button> + ); +}; diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 6d3f94a18a1c24..2f62f199794eda 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -37,7 +37,7 @@ background: #f3f5f6; color: color(theme(button) shade(25%)); border-color: color(theme(button) shade(5%)); - box-shadow: 0 0 0 1px color(theme(button) shade(5%)); + box-shadow: 0 0 0 $border-width color(theme(button) shade(5%)); text-decoration: none; } @@ -54,7 +54,7 @@ color: #a0a5aa; border-color: #ddd; background: #f7f7f7; - text-shadow: 0 1px 0 #fff; + text-shadow: 0 $border-width 0 #fff; transform: none; opacity: 1; } @@ -76,7 +76,7 @@ &:focus:enabled { box-shadow: - 0 0 0 1px $white, + 0 0 0 $border-width $white, 0 0 0 3px color(theme(button)); } @@ -107,7 +107,7 @@ &:focus:enabled { box-shadow: - 0 0 0 1px $white, + 0 0 0 $border-width $white, 0 0 0 3px color(theme(button)); } } @@ -157,8 +157,8 @@ &:focus { color: #124964; box-shadow: - 0 0 0 1px #5b9dd9, - 0 0 2px 1px rgba(30, 140, 190, 0.8); + 0 0 0 $border-width #5b9dd9, + 0 0 2px $border-width rgba(30, 140, 190, 0.8); } } diff --git a/packages/components/src/checkbox-control/README.md b/packages/components/src/checkbox-control/README.md index 43165e8ae1b59c..b6245fbd036cd0 100644 --- a/packages/components/src/checkbox-control/README.md +++ b/packages/components/src/checkbox-control/README.md @@ -56,17 +56,16 @@ If only a few child checkboxes are checked, the parent checkbox becomes a mixed Render an is author checkbox: ```jsx import { CheckboxControl } from '@wordpress/components'; -import { withState } from '@wordpress/compose'; +import { useState } from '@wordpress/element'; -const MyCheckboxControl = withState( { - isChecked: true, -} )( ( { isChecked, setState } ) => ( +const MyCheckboxControl = () => ( + const [ isChecked, setChecked ] = useState( true ); <CheckboxControl heading="User" label="Is author" help="Is the user a author or not?" checked={ isChecked } - onChange={ ( isChecked ) => { setState( { isChecked } ) } } + onChange={ setChecked } /> ) ); ``` diff --git a/packages/components/src/checkbox-control/stories/index.js b/packages/components/src/checkbox-control/stories/index.js new file mode 100644 index 00000000000000..40b48ccf3ef3a2 --- /dev/null +++ b/packages/components/src/checkbox-control/stories/index.js @@ -0,0 +1,54 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import CheckboxControl from '../'; + +export default { title: 'CheckboxControl', component: CheckboxControl }; + +const CheckboxControlWithState = ( { checked, ...props } ) => { + const [ isChecked, setChecked ] = useState( checked ); + + return ( + <CheckboxControl + { ...props } + checked={ isChecked } + onChange={ setChecked } + /> + ); +}; + +export const _default = () => { + const label = text( 'Label', 'Is author' ); + + return ( + <CheckboxControlWithState + label={ label } + checked + /> + ); +}; + +export const all = () => { + const heading = text( 'Heading', 'User' ); + const label = text( 'Label', 'Is author' ); + const help = text( 'Help', 'Is the user an author or not?' ); + + return ( + <CheckboxControlWithState + heading={ heading } + label={ label } + help={ help } + checked + /> + ); +}; diff --git a/packages/components/src/clipboard-button/stories/index.js b/packages/components/src/clipboard-button/stories/index.js index 25632614eb249d..7e0146448d56d5 100644 --- a/packages/components/src/clipboard-button/stories/index.js +++ b/packages/components/src/clipboard-button/stories/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { boolean, text } from '@storybook/addon-knobs'; + /** * WordPress dependencies */ @@ -8,18 +13,30 @@ import { useState } from '@wordpress/element'; */ import ClipboardButton from '../'; -export default { title: 'Clipboard Button', component: ClipboardButton }; +export default { title: 'ClipboardButton', component: ClipboardButton }; + +const ClipboardButtonWithState = ( { copied, ...props } ) => { + const [ isCopied, setCopied ] = useState( copied ); -export const _default = () => { - const [ copied, setCopied ] = useState( false ); return ( <ClipboardButton - isPrimary - text="Text" + { ...props } onCopy={ () => setCopied( true ) } onFinishCopy={ () => setCopied( false ) } > - { copied ? 'Copied!' : 'Copy "Text"' } + { isCopied ? 'Copied!' : `Copy "${ props.text }"` } </ClipboardButton> ); }; + +export const _default = () => { + const isPrimary = boolean( 'Is primary', true ); + const copyText = text( 'Text', 'Text' ); + + return ( + <ClipboardButtonWithState + isPrimary={ isPrimary } + text={ copyText } + /> + ); +}; diff --git a/packages/components/src/color-indicator/stories/index.js b/packages/components/src/color-indicator/stories/index.js index 3e9400b0919c11..d14f180abbe25a 100644 --- a/packages/components/src/color-indicator/stories/index.js +++ b/packages/components/src/color-indicator/stories/index.js @@ -1,13 +1,21 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ import ColorIndicator from '../'; export default { - title: 'Color Indicator', + title: 'ColorIndicator', component: ColorIndicator, }; -export const _default = () => ( - <ColorIndicator colorValue="#0073aa" /> -); +export const _default = () => { + const color = text( 'Color', '#0073aa' ); + return ( + <ColorIndicator colorValue={ color } /> + ); +}; diff --git a/packages/components/src/color-palette/stories/index.js b/packages/components/src/color-palette/stories/index.js new file mode 100644 index 00000000000000..3cc1f4f8ff66df --- /dev/null +++ b/packages/components/src/color-palette/stories/index.js @@ -0,0 +1,56 @@ +/** + * External dependencies + */ +import { object } from '@storybook/addon-knobs'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import ColorPalette from '../'; + +export default { title: 'ColorPalette', component: ColorPalette }; + +const ColorPaletteWithState = ( props ) => { + const [ color, setColor ] = useState( '#F00' ); + return ( + <ColorPalette + { ...props } + value={ color } + onChange={ setColor } + /> + ); +}; + +export const _default = () => { + const colors = [ + { name: 'red', color: '#f00' }, + { name: 'white', color: '#fff' }, + { name: 'blue', color: '#00f' }, + ]; + + return ( + <ColorPaletteWithState + colors={ colors } + /> + ); +}; + +export const withKnobs = () => { + const colors = [ + object( 'Red', { name: 'red', color: '#f00' } ), + object( 'White', { name: 'white', color: '#fff' } ), + object( 'Blue', { name: 'blue', color: '#00f' } ), + ]; + + return ( + <ColorPaletteWithState + colors={ colors } + /> + ); +}; + diff --git a/packages/components/src/color-picker/hue.js b/packages/components/src/color-picker/hue.js index 214df7e725bdc1..0c97020d89efdc 100644 --- a/packages/components/src/color-picker/hue.js +++ b/packages/components/src/color-picker/hue.js @@ -43,6 +43,7 @@ import { TAB } from '@wordpress/keycodes'; */ import { calculateHueChange } from './utils'; import KeyboardShortcuts from '../keyboard-shortcuts'; +import VisuallyHidden from '../visually-hidden'; export class Hue extends Component { constructor() { @@ -157,12 +158,11 @@ export class Hue extends Component { style={ pointerLocation } onKeyDown={ this.preventKeyEvents } /> - <p - className="components-color-picker__hue-description screen-reader-text" + <VisuallyHidden as="p" id={ `components-color-picker__hue-description-${ instanceId }` } > { __( 'Move the arrow left or right to change hue.' ) } - </p> + </VisuallyHidden> </div> { /* eslint-enable jsx-a11y/no-static-element-interactions */ } </div> diff --git a/packages/components/src/color-picker/inputs.js b/packages/components/src/color-picker/inputs.js index 39817d13edb74f..42e77a31e71820 100644 --- a/packages/components/src/color-picker/inputs.js +++ b/packages/components/src/color-picker/inputs.js @@ -17,6 +17,7 @@ import { pure } from '@wordpress/compose'; */ import IconButton from '../icon-button'; import TextControl from '../text-control'; +import VisuallyHidden from '../visually-hidden'; import { isValidHex } from './utils'; /* Wrapper for TextControl, only used to handle intermediate state while typing. */ @@ -175,9 +176,9 @@ export class Inputs extends Component { } else if ( this.state.view === 'rgb' ) { return ( <fieldset> - <legend className="screen-reader-text"> + <VisuallyHidden as="legend"> { __( 'Color value in RGB' ) } - </legend> + </VisuallyHidden> <div className="components-color-picker__inputs-fields"> <Input source={ this.state.view } @@ -228,9 +229,9 @@ export class Inputs extends Component { } else if ( this.state.view === 'hsl' ) { return ( <fieldset> - <legend className="screen-reader-text"> + <VisuallyHidden as="legend"> { __( 'Color value in HSL' ) } - </legend> + </VisuallyHidden> <div className="components-color-picker__inputs-fields"> <Input source={ this.state.view } diff --git a/packages/components/src/color-picker/saturation.js b/packages/components/src/color-picker/saturation.js index 3bdd10bfcdfe28..ae1f80333237d5 100644 --- a/packages/components/src/color-picker/saturation.js +++ b/packages/components/src/color-picker/saturation.js @@ -43,6 +43,7 @@ import { compose, pure, withInstanceId } from '@wordpress/compose'; */ import { calculateSaturationChange } from './utils'; import KeyboardShortcuts from '../keyboard-shortcuts'; +import VisuallyHidden from '../visually-hidden'; export class Saturation extends Component { constructor( props ) { @@ -171,13 +172,12 @@ export class Saturation extends Component { style={ pointerLocation } onKeyDown={ this.preventKeyEvents } /> - <div - className="screen-reader-text" + <VisuallyHidden id={ `color-picker-saturation-${ instanceId }` }> { __( 'Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation.' ) } - </div> + </VisuallyHidden> </div> </KeyboardShortcuts> ); diff --git a/packages/components/src/color-picker/stories/index.js b/packages/components/src/color-picker/stories/index.js new file mode 100644 index 00000000000000..19bca39729d4f5 --- /dev/null +++ b/packages/components/src/color-picker/stories/index.js @@ -0,0 +1,39 @@ + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import ColorPicker from '../'; + +export default { title: 'ColorPicker', component: ColorPicker }; + +const ColorPickerWithState = ( { ...props } ) => { + const [ color, setColor ] = useState( '#f00' ); + return ( + <ColorPicker + { ...props } + color={ color } + onChangeComplete={ ( value ) => setColor( value.hex ) } + /> + ); +}; + +export const _default = () => { + return ( + <ColorPickerWithState + disableAlpha + /> + ); +}; + +export const alphaEnabled = () => { + return ( + <ColorPickerWithState + disableAlpha={ false } + /> + ); +}; diff --git a/packages/components/src/color-picker/test/__snapshots__/index.js.snap b/packages/components/src/color-picker/test/__snapshots__/index.js.snap index 5d61a24e5ac9e6..a3713f860f3c01 100644 --- a/packages/components/src/color-picker/test/__snapshots__/index.js.snap +++ b/packages/components/src/color-picker/test/__snapshots__/index.js.snap @@ -39,7 +39,7 @@ exports[`ColorPicker should commit changes to all views on blur 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-2" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -99,7 +99,7 @@ exports[`ColorPicker should commit changes to all views on blur 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-2" > Move the arrow left or right to change hue. @@ -213,7 +213,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = DOWN 1`] = } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-4" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -273,7 +273,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = DOWN 1`] = tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-4" > Move the arrow left or right to change hue. @@ -387,7 +387,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = ENTER 1`] = } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-5" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -447,7 +447,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = ENTER 1`] = tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-5" > Move the arrow left or right to change hue. @@ -561,7 +561,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = UP 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-3" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -621,7 +621,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = UP 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-3" > Move the arrow left or right to change hue. @@ -735,7 +735,7 @@ exports[`ColorPicker should only update input view for draft changes 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-1" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -795,7 +795,7 @@ exports[`ColorPicker should only update input view for draft changes 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-1" > Move the arrow left or right to change hue. @@ -909,7 +909,7 @@ exports[`ColorPicker should render color picker 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-0" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -969,7 +969,7 @@ exports[`ColorPicker should render color picker 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-0" > Move the arrow left or right to change hue. diff --git a/packages/components/src/dashicon/stories/index.js b/packages/components/src/dashicon/stories/index.js new file mode 100644 index 00000000000000..5ba7d7be98cbcb --- /dev/null +++ b/packages/components/src/dashicon/stories/index.js @@ -0,0 +1,25 @@ +/** + * External dependencies + */ +import { number, text } from '@storybook/addon-knobs'; + +/** + * Internal dependencies + */ +import Dashicon from '../'; + +export default { title: 'Dashicon', component: Dashicon }; + +export const _default = () => { + const icon = text( 'Icon', 'wordpress' ); + const color = text( 'Color', '#0079AA' ); + const size = number( 'Size', 20 ); + + return ( + <Dashicon + icon={ icon } + color={ color } + size={ size } + /> + ); +}; diff --git a/packages/components/src/date-time/date.js b/packages/components/src/date-time/date.js index 7361494a61e688..7b1accff50227d 100644 --- a/packages/components/src/date-time/date.js +++ b/packages/components/src/date-time/date.js @@ -65,7 +65,7 @@ class DatePicker extends Component { * object representing now. If a null value is passed, return a null value. * * @param {?string} currentDate Date representing the currently selected date or null to signify no selection. - * @return {?Moment} Moment object for selected date or null. + * @return {?moment.Moment} Moment object for selected date or null. */ getMomentDate( currentDate ) { if ( null === currentDate ) { diff --git a/packages/components/src/date-time/index.js b/packages/components/src/date-time/index.js index 97bd891cac9a7c..bb7434d2e82ce3 100644 --- a/packages/components/src/date-time/index.js +++ b/packages/components/src/date-time/index.js @@ -34,7 +34,7 @@ export class DateTimePicker extends Component { } render() { - const { currentDate, is12Hour, onChange } = this.props; + const { currentDate, is12Hour, isInvalidDate, onChange } = this.props; return ( <div className="components-datetime"> @@ -48,6 +48,7 @@ export class DateTimePicker extends Component { <DatePicker currentDate={ currentDate } onChange={ onChange } + isInvalidDate={ isInvalidDate } /> </> ) } diff --git a/packages/components/src/dimension-control/README.md b/packages/components/src/dimension-control/README.md new file mode 100644 index 00000000000000..435fdf4e73b046 --- /dev/null +++ b/packages/components/src/dimension-control/README.md @@ -0,0 +1,120 @@ +DimensionControl +============================= + +`DimensionControl` is a component designed to provide a UI to control spacing and/or dimensions. + +## Usage + +In a block's `edit` implementation, render a `<DimensionControl />` component. + + +```jsx +import { registerBlockType } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; +import { + DimensionControl, +} from '@wordpress/block-editor'; + +registerBlockType( 'my-plugin/my-block', { + // ... + + attributes: { + // other attributes here + // ... + + paddingSize: { + type: 'string', + }, + }, + + edit( { attributes, setAttributes, clientId } ) { + + const { paddingSize } = attributes; + + + const updateSpacing = ( dimension, size, device = '' ) => { + setAttributes( { + [ `${ dimension }${ device }` ]: size, + } ); + }; + + return ( + <DimensionControl + label={ __( 'Padding' ) } + icon={ 'desktop' } + onChange={ partialRight( updateSpacing, 'paddingSize' ) } + value={ paddingSize } + /> + ); + } +} ); +``` + +_Note:_ it is recommended to partially apply the value of the Block attribute to be updated (eg: `paddingSize`, `marginSize`...etc) to your callback functions. This avoids the need to unnecessarily couple the component to the Block attribute schema. + +_Note:_ by default, if you do not provide an initial `value` prop for the current dimension value, then no value will be selected (ie: there is no default dimension set). + +## Props + +### `label` +* **Type:** `String` +* **Default:** `undefined` +* **Required:** Yes + +The human readable label for the control. + +### `value` +* **Type:** `String` +* **Default:** `''` +* **Required:** No + +The current value of the dimension UI control. If provided the UI with automatically select the value. + +### `sizes` +* **Type:** `Array` +* **Default:** See `packages/block-editor/src/components/dimension-control/sizes.js` +* **Required:** No + +An optional array of size objects in the following shape: + +``` +[ + { + name: __( 'Small' ), + slug: 'small', + }, + { + name: __( 'Medium' ), + slug: 'small', + }, + // ...etc +] +``` + +By default a set of relative sizes (`small`, `medium`...etc) are provided. See `packages/block-editor/src/components/dimension-control/sizes.js`. + +### `icon` +* **Type:** `String` +* **Default:** `undefined` +* **Required:** No + +An optional dashicon to display before to the control label. + +### `onChange` +* **Type:** `Function` +* **Default:** `undefined` +* **Required:** No +* **Arguments:**: + - `size` - a string representing the selected size (eg: `medium`) + +A callback which is triggered when a spacing size value changes (is selected/clicked). + + +### `className` +* **Type:** `String` +* **Default:** `''` +* **Required:** No + +A string of classes to be added to the control component. + + diff --git a/packages/components/src/dimension-control/index.js b/packages/components/src/dimension-control/index.js new file mode 100644 index 00000000000000..c69b80f5c49e02 --- /dev/null +++ b/packages/components/src/dimension-control/index.js @@ -0,0 +1,76 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { isFunction } from 'lodash'; + +/** + * WordPress dependencies + */ +/** + * Internal dependencies + */ +import { + Icon, + SelectControl, +} from '../'; +import { __ } from '@wordpress/i18n'; + +import { + Fragment, +} from '@wordpress/element'; + +/** + * Internal dependencies + */ +import sizesTable, { findSizeBySlug } from './sizes'; + +export function DimensionControl( props ) { + const { label, value, sizes = sizesTable, icon, onChange, className = '' } = props; + + const onChangeSpacingSize = ( val ) => { + const theSize = findSizeBySlug( sizes, val ); + + if ( ! theSize || value === theSize.slug ) { + onChange( undefined ); + } else if ( isFunction( onChange ) ) { + onChange( theSize.slug ); + } + }; + + const formatSizesAsOptions = ( theSizes ) => { + const options = theSizes.map( ( { name, slug } ) => ( { + label: name, + value: slug, + } ) ); + + return [ { + label: __( 'Default' ), + value: '', + } ].concat( options ); + }; + + const selectLabel = ( + <Fragment> + { icon && ( + <Icon + icon={ icon } + /> + ) } + { label } + </Fragment> + ); + + return ( + <SelectControl + className={ classnames( className, 'block-editor-dimension-control' ) } + label={ selectLabel } + hideLabelFromVision={ false } + value={ value } + onChange={ onChangeSpacingSize } + options={ formatSizesAsOptions( sizes ) } + /> + ); +} + +export default DimensionControl; diff --git a/packages/components/src/dimension-control/sizes.js b/packages/components/src/dimension-control/sizes.js new file mode 100644 index 00000000000000..41fa0717028725 --- /dev/null +++ b/packages/components/src/dimension-control/sizes.js @@ -0,0 +1,45 @@ +/** + * Sizes + * + * defines the sizes used in dimension controls + * all hardcoded `size` values are based on the value of + * the Sass variable `$block-padding` from + * `packages/block-editor/src/components/dimension-control/sizes.js`. + */ + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Finds the correct size object from the provided sizes + * table by size slug (eg: `medium`) + * + * @param {Array} sizes containing objects for each size definition + * @param {string} slug a string representation of the size (eg: `medium`) + * @return {Object} the matching size definition + */ +export const findSizeBySlug = ( sizes, slug ) => sizes.find( ( size ) => slug === size.slug ); + +export default [ + { + name: __( 'None' ), + slug: 'none', + }, + { + name: __( 'Small' ), + slug: 'small', + }, + { + name: __( 'Medium' ), + slug: 'medium', + }, + { + name: __( 'Large' ), + slug: 'large', + }, { + name: __( 'Extra Large' ), + slug: 'xlarge', + }, +]; diff --git a/packages/components/src/dimension-control/style.scss b/packages/components/src/dimension-control/style.scss new file mode 100644 index 00000000000000..7f1481747dfe1a --- /dev/null +++ b/packages/components/src/dimension-control/style.scss @@ -0,0 +1,22 @@ +.block-editor-dimension-control { + + .components-base-control__field { + display: flex; + align-items: center; + } + + .components-base-control__label { + display: flex; + align-items: center; + margin-right: 1em; + margin-bottom: 0; + + .dashicon { + margin-right: 0.5em; + } + } + + &.is-manual .components-base-control__label { + width: 10em; + } +} diff --git a/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap b/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap new file mode 100644 index 00000000000000..c06662ee862c99 --- /dev/null +++ b/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap @@ -0,0 +1,163 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DimensionControl rendering renders with custom sizes 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + Custom Dimension + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "Mini", + "value": "mini", + }, + Object { + "label": "Middle", + "value": "middle", + }, + Object { + "label": "Giant", + "value": "giant", + }, + ] + } +/> +`; + +exports[`DimensionControl rendering renders with defaults 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + Padding + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "None", + "value": "none", + }, + Object { + "label": "Small", + "value": "small", + }, + Object { + "label": "Medium", + "value": "medium", + }, + Object { + "label": "Large", + "value": "large", + }, + Object { + "label": "Extra Large", + "value": "xlarge", + }, + ] + } +/> +`; + +exports[`DimensionControl rendering renders with icon and custom icon label 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + <Icon + icon="tablet" + /> + Margin + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "None", + "value": "none", + }, + Object { + "label": "Small", + "value": "small", + }, + Object { + "label": "Medium", + "value": "medium", + }, + Object { + "label": "Large", + "value": "large", + }, + Object { + "label": "Extra Large", + "value": "xlarge", + }, + ] + } +/> +`; + +exports[`DimensionControl rendering renders with icon and default icon label 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + <Icon + icon="tablet" + /> + Margin + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "None", + "value": "none", + }, + Object { + "label": "Small", + "value": "small", + }, + Object { + "label": "Medium", + "value": "medium", + }, + Object { + "label": "Large", + "value": "large", + }, + Object { + "label": "Extra Large", + "value": "xlarge", + }, + ] + } +/> +`; diff --git a/packages/components/src/dimension-control/test/index.test.js b/packages/components/src/dimension-control/test/index.test.js new file mode 100644 index 00000000000000..0b053a493ee123 --- /dev/null +++ b/packages/components/src/dimension-control/test/index.test.js @@ -0,0 +1,128 @@ +/** + * External dependencies + */ +import { shallow, mount } from 'enzyme'; +import { uniqueId } from 'lodash'; + +/** + * Internal dependencies + */ +import { DimensionControl } from '../'; + +describe( 'DimensionControl', () => { + const onChangeHandler = jest.fn(); + + afterEach( () => { + onChangeHandler.mockClear(); + } ); + + describe( 'rendering', () => { + it( 'renders with defaults', () => { + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Padding' } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + + it( 'renders with icon and default icon label', () => { + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Margin' } + icon={ 'tablet' } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + + it( 'renders with icon and custom icon label', () => { + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Margin' } + icon={ 'tablet' } + iconLabel={ 'Tablet Devices' } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + + it( 'renders with custom sizes', () => { + const customSizes = [ + { + name: 'Mini', + size: 1, + slug: 'mini', + }, + { + name: 'Middle', + size: 5, + slug: 'middle', + }, + { + name: 'Giant', + size: 10, + slug: 'giant', + }, + ]; + + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Custom Dimension' } + sizes={ customSizes } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + } ); + + describe( 'callbacks', () => { + it( 'should call onChange handler with correct args on size change', () => { + const wrapper = mount( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Padding' } + onChange={ onChangeHandler } + /> + ); + + wrapper.find( 'select' ).at( 0 ).simulate( 'change', { + target: { + value: 'small', + }, + } ); + + wrapper.find( 'select' ).at( 0 ).simulate( 'change', { + target: { + value: 'medium', + }, + } ); + + expect( onChangeHandler ).toHaveBeenCalledTimes( 2 ); + expect( onChangeHandler.mock.calls[ 0 ][ 0 ] ).toEqual( 'small' ); + expect( onChangeHandler.mock.calls[ 1 ][ 0 ] ).toEqual( 'medium' ); + } ); + + it( 'should call onChange handler with undefined value when no size is provided on change', () => { + const wrapper = mount( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Padding' } + onChange={ onChangeHandler } + /> + ); + + wrapper.find( 'select' ).at( 0 ).simulate( 'change', { + target: { + value: '', // this happens when you select the "default" <option /> + }, + } ); + + expect( onChangeHandler ).toHaveBeenNthCalledWith( 1, undefined ); + } ); + } ); +} ); diff --git a/packages/components/src/draggable/stories/index.js b/packages/components/src/draggable/stories/index.js new file mode 100644 index 00000000000000..fbe81321df7232 --- /dev/null +++ b/packages/components/src/draggable/stories/index.js @@ -0,0 +1,69 @@ +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import Draggable from '../'; +import Dashicon from '../../dashicon'; + +export default { title: 'Draggable', component: Draggable }; + +const Box = ( props ) => { + return ( + <div + { ...props } + style={ { + alignItems: 'center', + display: 'flex', + justifyContent: 'center', + width: 100, + height: 100, + background: '#ddd', + } } + /> + ); +}; + +const DraggalbeExample = () => { + const [ isDragging, setDragging ] = useState( false ); + + // Allow for the use of ID in the example + /* eslint-disable no-restricted-syntax */ + return ( + <div> + <p>Is Dragging? { isDragging ? 'Yes' : 'No' }</p> + <div id="draggable-example-box" style={ { display: 'inline-flex' } }> + <Draggable elementId="draggable-example-box"> + { ( { onDraggableStart, onDraggableEnd } ) => { + const handleOnDragStart = ( event ) => { + setDragging( true ); + onDraggableStart( event ); + }; + const handleOnDragEnd = ( event ) => { + setDragging( false ); + onDraggableEnd( event ); + }; + + return ( + <Box + onDragStart={ handleOnDragStart } + onDragEnd={ handleOnDragEnd } + draggable + > + <Dashicon icon="move" /> + </Box> + ); + } } + </Draggable> + </div> + </div> + ); + /* eslint-enable no-restricted-syntax */ +}; + +export const _default = () => { + return <DraggalbeExample />; +}; diff --git a/packages/components/src/external-link/index.js b/packages/components/src/external-link/index.js index 68bf56394b8f86..cc9750a4b779c9 100644 --- a/packages/components/src/external-link/index.js +++ b/packages/components/src/external-link/index.js @@ -14,6 +14,7 @@ import { forwardRef } from '@wordpress/element'; * Internal dependencies */ import Dashicon from '../dashicon'; +import VisuallyHidden from '../visually-hidden'; export function ExternalLink( { href, children, className, rel = '', ...additionalProps }, ref ) { rel = uniq( compact( [ @@ -27,12 +28,12 @@ export function ExternalLink( { href, children, className, rel = '', ...addition // eslint-disable-next-line react/jsx-no-target-blank <a { ...additionalProps } className={ classes } href={ href } target="_blank" rel={ rel } ref={ ref }> { children } - <span className="screen-reader-text"> + <VisuallyHidden as="span"> { /* translators: accessibility text */ __( '(opens in a new tab)' ) } - </span> + </VisuallyHidden> <Dashicon icon="external" className="components-external-link__icon" /> </a> ); diff --git a/packages/components/src/external-link/stories/index.js b/packages/components/src/external-link/stories/index.js new file mode 100644 index 00000000000000..9abfa1af04ba9c --- /dev/null +++ b/packages/components/src/external-link/stories/index.js @@ -0,0 +1,17 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; +/** + * Internal dependencies + */ +import ExternalLink from '../'; + +export default { title: 'ExternalLink', component: ExternalLink }; + +export const _default = () => { + const title = text( 'children', 'WordPress' ); + const href = text( 'href', 'https://wordpress.org' ); + + return <ExternalLink href={ href }>{ title }</ExternalLink>; +}; diff --git a/packages/components/src/font-size-picker/index.js b/packages/components/src/font-size-picker/index.js index a52f6ccd841d2f..9fc6567865dbe4 100644 --- a/packages/components/src/font-size-picker/index.js +++ b/packages/components/src/font-size-picker/index.js @@ -60,7 +60,7 @@ function FontSizePicker( { }; return ( - <fieldset> + <fieldset className="components-font-size-picker"> <legend> { __( 'Font Size' ) } </legend> diff --git a/packages/components/src/font-size-picker/style.scss b/packages/components/src/font-size-picker/style.scss index 2444087dcf30e3..d24d044952cdf6 100644 --- a/packages/components/src/font-size-picker/style.scss +++ b/packages/components/src/font-size-picker/style.scss @@ -38,3 +38,9 @@ } } +.components-font-size-picker { + border: 0; + padding: 0; + margin: 0; +} + diff --git a/packages/components/src/gradient-picker/index.js b/packages/components/src/gradient-picker/index.js index 1a60de751646f3..e8ab40f07ada2b 100644 --- a/packages/components/src/gradient-picker/index.js +++ b/packages/components/src/gradient-picker/index.js @@ -19,6 +19,7 @@ export default function GradientPicker( { gradients, onChange, value, + clearable = true, } ) { const clearGradient = useCallback( () => onChange( undefined ), @@ -56,7 +57,7 @@ export default function GradientPicker( { <CircularOptionPicker className={ className } options={ gradientOptions } - actions={ ( + actions={ clearable && ( <CircularOptionPicker.ButtonAction onClick={ clearGradient }> { __( 'Clear' ) } </CircularOptionPicker.ButtonAction> diff --git a/packages/components/src/higher-order/with-focus-return/index.js b/packages/components/src/higher-order/with-focus-return/index.js index 2b504878bdf528..6a411ad909af9f 100644 --- a/packages/components/src/higher-order/with-focus-return/index.js +++ b/packages/components/src/higher-order/with-focus-return/index.js @@ -36,11 +36,11 @@ function isComponentLike( object ) { * when the component is unmounted. * * @param {(WPComponent|Object)} options The component to be enhanced with - * focus return behavior, or an object - * describing the component and the - * focus return characteristics. + * focus return behavior, or an object + * describing the component and the + * focus return characteristics. * - * @return {Component} Component with the focus restauration behaviour. + * @return {WPComponent} Component with the focus restauration behaviour. */ function withFocusReturn( options ) { // Normalize as overloaded form `withFocusReturn( options )( Component )` diff --git a/packages/components/src/higher-order/with-notices/index.js b/packages/components/src/higher-order/with-notices/index.js index 49a44608039ce1..9097728b2921a8 100644 --- a/packages/components/src/higher-order/with-notices/index.js +++ b/packages/components/src/higher-order/with-notices/index.js @@ -17,8 +17,9 @@ import NoticeList from '../../notice/list'; /** * Override the default edit UI to include notices if supported. * - * @param {Function|Component} OriginalComponent Original component. - * @return {Component} Wrapped component. + * @param {WPComponent} OriginalComponent Original component. + * + * @return {WPComponent} Wrapped component. */ export default createHigherOrderComponent( ( OriginalComponent ) => { return class WrappedBlockEdit extends Component { diff --git a/packages/components/src/higher-order/with-spoken-messages/index.js b/packages/components/src/higher-order/with-spoken-messages/index.js index de17dc62aeb575..406d10bf0a245a 100644 --- a/packages/components/src/higher-order/with-spoken-messages/index.js +++ b/packages/components/src/higher-order/with-spoken-messages/index.js @@ -14,9 +14,9 @@ import { createHigherOrderComponent } from '@wordpress/compose'; * A Higher Order Component used to be provide a unique instance ID by * component. * - * @param {WPElement} WrappedComponent The wrapped component. + * @param {WPComponent} WrappedComponent The wrapped component. * - * @return {Component} Component with an instanceId prop. + * @return {WPComponent} The component to be rendered. */ export default createHigherOrderComponent( ( WrappedComponent ) => { return class extends Component { diff --git a/packages/components/src/icon-button/stories/index.js b/packages/components/src/icon-button/stories/index.js index d093876a20e0a4..b5c4275159dc5b 100644 --- a/packages/components/src/icon-button/stories/index.js +++ b/packages/components/src/icon-button/stories/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ @@ -5,7 +10,17 @@ import IconButton from '../'; export default { title: 'IconButton', component: IconButton }; -export const _default = () => <IconButton icon="ellipsis" label="More" />; +export const _default = () => { + const icon = text( 'Icon', 'ellipsis' ); + const label = text( 'Label', 'More' ); + + return ( + <IconButton + icon={ icon } + label={ label } + /> + ); +}; export const grouped = () => { const GroupContainer = ( { children } ) => ( diff --git a/packages/components/src/icon/stories/index.js b/packages/components/src/icon/stories/index.js index be4e9fed65787f..f2cd8bee1839b5 100644 --- a/packages/components/src/icon/stories/index.js +++ b/packages/components/src/icon/stories/index.js @@ -1,19 +1,29 @@ +/** + * External dependencies + */ +import { number, text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ import Icon from '../'; -import { SVG, Path } from '../../'; +import { SVG, Path } from '../../primitives/svg'; export default { title: 'Icon', component: Icon }; const IconSizeLabel = ( { size } ) => <div style={ { fontSize: 12 } }>{ size }px</div>; -export const _default = () => ( - <div> - <Icon icon="screenoptions" /> - <IconSizeLabel size={ 24 } /> - </div> -); +export const _default = () => { + const icon = text( 'Icon', 'screenoptions' ); + const size = number( 'Size', '24' ); + + return ( + <div> + <Icon icon={ icon } size={ size } /> + <IconSizeLabel size={ size } /> + </div> + ); +}; export const sizes = () => { const iconSizes = [ 14, 16, 20, 24, 28, 32, 40, 48, 56 ]; diff --git a/packages/components/src/index.js b/packages/components/src/index.js index 8542a86ba9b659..ac9694a49ba57b 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -12,6 +12,7 @@ export { default as ColorPalette } from './color-palette'; export { default as ColorPicker } from './color-picker'; export { default as Dashicon } from './dashicon'; export { DateTimePicker, DatePicker, TimePicker } from './date-time'; +export { default as __experimentalDimensionControl } from './dimension-control'; export { default as Disabled } from './disabled'; export { default as Draggable } from './draggable'; export { default as DropZone } from './drop-zone'; @@ -62,6 +63,7 @@ export { default as Toolbar } from './toolbar'; export { default as ToolbarButton } from './toolbar-button'; export { default as Tooltip } from './tooltip'; export { default as TreeSelect } from './tree-select'; +export { default as VisuallyHidden } from './visually-hidden'; export { default as IsolatedEventContainer } from './isolated-event-container'; export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot-fill'; diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index c2c52ba08f0e58..e9aec0ad2fb71c 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -1,5 +1,7 @@ // Components export * from './primitives'; +export { default as ColorIndicator } from './color-indicator'; +export { default as ColorPalette } from './color-palette'; export { default as Dashicon } from './dashicon'; export { default as Dropdown } from './dropdown'; export { default as Toolbar } from './toolbar'; @@ -11,6 +13,7 @@ export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot export { default as BaseControl } from './base-control'; export { default as TextareaControl } from './textarea-control'; export { default as PanelBody } from './panel/body'; +export { default as PanelActions } from './panel/actions'; export { default as Button } from './button'; export { default as TextControl } from './text-control'; export { default as ToggleControl } from './toggle-control'; diff --git a/packages/components/src/keyboard-shortcuts/index.native.js b/packages/components/src/keyboard-shortcuts/index.native.js new file mode 100644 index 00000000000000..fab7b99261e3ae --- /dev/null +++ b/packages/components/src/keyboard-shortcuts/index.native.js @@ -0,0 +1,2 @@ +const KeyboardShortcuts = () => null; +export default KeyboardShortcuts; diff --git a/packages/components/src/menu-item/index.js b/packages/components/src/menu-item/index.js index b7cc7c8ca7a0bd..3227659e6d10a8 100644 --- a/packages/components/src/menu-item/index.js +++ b/packages/components/src/menu-item/index.js @@ -18,7 +18,7 @@ import IconButton from '../icon-button'; /** * Renders a generic menu item for use inside the more menu. * - * @return {WPElement} More menu item. + * @return {WPComponent} The component to be rendered. */ export function MenuItem( { children, diff --git a/packages/components/src/mobile/bottom-sheet/cell.native.js b/packages/components/src/mobile/bottom-sheet/cell.native.js index af74a25e2cee82..52ff00b6b5b856 100644 --- a/packages/components/src/mobile/bottom-sheet/cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/cell.native.js @@ -42,6 +42,7 @@ class BottomSheetCell extends Component { value, valuePlaceholder = '', icon, + leftAlign, labelStyle = {}, valueStyle = {}, onChangeValue, @@ -57,8 +58,12 @@ class BottomSheetCell extends Component { const isValueEditable = editable && onChangeValue !== undefined; const cellLabelStyle = getStylesFromColorScheme( styles.cellLabel, styles.cellTextDark ); const cellLabelCenteredStyle = getStylesFromColorScheme( styles.cellLabelCentered, styles.cellTextDark ); - const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : cellLabelCenteredStyle; + const cellLabelLeftAlignNoIconStyle = getStylesFromColorScheme( styles.cellLabelLeftAlignNoIcon, styles.cellTextDark ); + const defaultMissingIconAndValue = leftAlign ? cellLabelLeftAlignNoIconStyle : cellLabelCenteredStyle; + const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : defaultMissingIconAndValue; + const drawSeparator = ( separatorType && separatorType !== 'none' ) || separatorStyle === undefined; + const drawTopSeparator = drawSeparator && separatorType === 'topFullWidth'; const onCellPress = () => { if ( isValueEditable ) { @@ -87,6 +92,7 @@ class BottomSheetCell extends Component { case 'leftMargin': return leftMarginStyle; case 'fullWidth': + case 'topFullWidth': return defaultSeparatorStyle; case 'none': return undefined; @@ -165,6 +171,9 @@ class BottomSheetCell extends Component { onPress={ onCellPress } style={ { ...styles.clipToBounds, ...style } } > + { drawTopSeparator && ( + <View style={ separatorStyle() } /> + ) } <View style={ styles.cellContainer }> <View style={ styles.cellRowContainer }> { icon && ( @@ -173,14 +182,14 @@ class BottomSheetCell extends Component { <View style={ platformStyles.labelIconSeparator } /> </View> ) } - <Text numberOfLines={ 1 } style={ { ...defaultLabelStyle, ...labelStyle } }> + <Text numberOfLines={ 1 } style={ [ defaultLabelStyle, labelStyle ] }> { label } </Text> </View> { showValue && getValueComponent() } { children } </View> - { drawSeparator && ( + { ! drawTopSeparator && ( <View style={ separatorStyle() } /> ) } </TouchableOpacity> diff --git a/packages/components/src/mobile/bottom-sheet/index.native.js b/packages/components/src/mobile/bottom-sheet/index.native.js index f17284b49e7306..34d05a83974957 100644 --- a/packages/components/src/mobile/bottom-sheet/index.native.js +++ b/packages/components/src/mobile/bottom-sheet/index.native.js @@ -19,6 +19,7 @@ import Button from './button'; import Cell from './cell'; import PickerCell from './picker-cell'; import SwitchCell from './switch-cell'; +import RangeCell from './range-cell'; import KeyboardAvoidingView from './keyboard-avoiding-view'; class BottomSheet extends Component { @@ -136,6 +137,8 @@ class BottomSheet extends Component { onBackdropPress={ this.props.onClose } onBackButtonPress={ this.props.onClose } onSwipe={ this.props.onClose } + onDismiss={ Platform.OS === 'ios' ? this.props.onDismiss : undefined } + onModalHide={ Platform.OS === 'android' ? this.props.onDismiss : undefined } swipeDirection="down" onMoveShouldSetResponder={ panResponder.panHandlers.onMoveShouldSetResponder } onMoveShouldSetResponderCapture={ panResponder.panHandlers.onMoveShouldSetResponderCapture } @@ -171,5 +174,6 @@ ThemedBottomSheet.Button = Button; ThemedBottomSheet.Cell = Cell; ThemedBottomSheet.PickerCell = PickerCell; ThemedBottomSheet.SwitchCell = SwitchCell; +ThemedBottomSheet.RangeCell = RangeCell; export default ThemedBottomSheet; diff --git a/packages/components/src/mobile/bottom-sheet/picker-cell.native.js b/packages/components/src/mobile/bottom-sheet/picker-cell.native.js index 50a775f25728b1..12eae94c7d8919 100644 --- a/packages/components/src/mobile/bottom-sheet/picker-cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/picker-cell.native.js @@ -7,6 +7,7 @@ import Picker from '../picker'; export default function BottomSheetPickerCell( props ) { const { options, + hideCancelButton, onChangeValue, ...cellProps } = props; @@ -24,6 +25,8 @@ export default function BottomSheetPickerCell( props ) { return ( <Cell onPress={ onCellPress } editable={ false } { ...cellProps } > <Picker + leftAlign + hideCancelButton={ hideCancelButton } ref={ ( instance ) => picker = instance } options={ options } onChange={ onChange } diff --git a/packages/components/src/mobile/bottom-sheet/range-cell.native.js b/packages/components/src/mobile/bottom-sheet/range-cell.native.js new file mode 100644 index 00000000000000..07b343e9ec0781 --- /dev/null +++ b/packages/components/src/mobile/bottom-sheet/range-cell.native.js @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import { Platform } from 'react-native'; + +/** + * Internal dependencies + */ +import Cell from './cell'; +import Slider from '../slider'; + +export default function BottomSheetRangeCell( props ) { + const { + value, + defaultValue, + onChangeValue, + minimumValue = 0, + maximumValue = 10, + disabled, + step = 1, + minimumTrackTintColor = '#00669b', + maximumTrackTintColor = Platform.OS === 'ios' ? '#e9eff3' : '#909090', + thumbTintColor = Platform.OS === 'ios' ? '#fff' : '#00669b', + ...cellProps + } = props; + + return ( + <Cell + editable={ false } + { ...cellProps } + > + <Slider + value={ value } + defaultValue={ defaultValue } + disabled={ disabled } + step={ step } + minimumValue={ minimumValue } + maximumValue={ maximumValue } + minimumTrackTintColor={ minimumTrackTintColor } + maximumTrackTintColor={ maximumTrackTintColor } + thumbTintColor={ thumbTintColor } + onChangeValue={ onChangeValue } + /> + </Cell> + ); +} diff --git a/packages/components/src/mobile/bottom-sheet/styles.native.scss b/packages/components/src/mobile/bottom-sheet/styles.native.scss index 8f153715c16705..86422f3228cac4 100644 --- a/packages/components/src/mobile/bottom-sheet/styles.native.scss +++ b/packages/components/src/mobile/bottom-sheet/styles.native.scss @@ -120,6 +120,13 @@ text-align: center; } +.cellLabelLeftAlignNoIcon { + font-size: 17px; + color: #2e4453; + flex: 1; + margin-left: 12px; +} + .cellValue { font-size: 17px; color: #2e4453; diff --git a/packages/components/src/mobile/picker/index.android.js b/packages/components/src/mobile/picker/index.android.js index 3fad1cc2b23bf0..372378e0a2b3ed 100644 --- a/packages/components/src/mobile/picker/index.android.js +++ b/packages/components/src/mobile/picker/index.android.js @@ -52,6 +52,7 @@ export default class Picker extends Component { <BottomSheet.Cell icon={ option.icon } key={ index } + leftAlign={ this.props.leftAlign } label={ option.label } separatorType={ 'none' } onPress={ () => this.onCellPress( option.value ) } diff --git a/packages/components/src/mobile/picker/index.ios.js b/packages/components/src/mobile/picker/index.ios.js index 2cf9798b28e9c0..9de17d1ff7060a 100644 --- a/packages/components/src/mobile/picker/index.ios.js +++ b/packages/components/src/mobile/picker/index.ios.js @@ -11,12 +11,13 @@ import { Component } from '@wordpress/element'; class Picker extends Component { presentPicker() { - const { options, onChange } = this.props; + const { options, onChange, title } = this.props; const labels = options.map( ( { label } ) => label ); const fullOptions = [ __( 'Cancel' ) ].concat( labels ); ActionSheetIOS.showActionSheetWithOptions( { + title, options: fullOptions, cancelButtonIndex: 0, }, diff --git a/packages/components/src/mobile/slider/index.native.js b/packages/components/src/mobile/slider/index.native.js new file mode 100644 index 00000000000000..111d9987e973db --- /dev/null +++ b/packages/components/src/mobile/slider/index.native.js @@ -0,0 +1,118 @@ +/** + * External dependencies + */ +import { Slider as RNSlider, TextInput, View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import styles from './styles.scss'; + +class Slider extends Component { + constructor( props ) { + super( props ); + this.handleToggleFocus = this.handleToggleFocus.bind( this ); + this.handleChange = this.handleChange.bind( this ); + this.handleValueSave = this.handleValueSave.bind( this ); + this.handleReset = this.handleReset.bind( this ); + + const initialValue = this.validateInput( props.value || props.defaultValue || props.minimumValue ); + + this.state = { hasFocus: false, initialValue, sliderValue: initialValue }; + } + + componentDidUpdate( ) { + const reset = this.props.value === null; + if ( reset ) { + this.handleReset(); + } + } + + handleToggleFocus( validateInput = true ) { + const newState = { hasFocus: ! this.state.hasFocus }; + + if ( validateInput ) { + const sliderValue = this.validateInput( this.state.sliderValue ); + this.handleValueSave( sliderValue ); + } + + this.setState( newState ); + } + + validateInput( text ) { + const { minimumValue, maximumValue } = this.props; + if ( ! text ) { + return minimumValue; + } + if ( typeof text === 'number' ) { + return Math.min( Math.max( text, minimumValue ), maximumValue ); + } + return Math.min( Math.max( text.replace( /[^0-9]/g, '' ).replace( /^0+(?=\d)/, '' ), minimumValue ), maximumValue ); + } + + handleChange( text ) { + if ( ! isNaN( Number( text ) ) ) { + this.setState( { sliderValue: text } ); + } + } + + handleValueSave( text ) { + if ( ! isNaN( Number( text ) ) ) { + if ( this.props.onChangeValue ) { + this.props.onChangeValue( text ); + } + this.setState( { sliderValue: text } ); + } + } + + handleReset() { + this.handleValueSave( this.props.defaultValue || this.state.initialValue ); + } + + render() { + const { + minimumValue, + maximumValue, + disabled, + step, + minimumTrackTintColor, + maximumTrackTintColor, + thumbTintColor, + } = this.props; + + const { hasFocus, sliderValue } = this.state; + + return ( + <View style={ styles.sliderContainer }> + <RNSlider + value={ this.validateInput( sliderValue ) } + disabled={ disabled } + style={ styles.slider } + step={ step } + minimumValue={ minimumValue } + maximumValue={ maximumValue } + minimumTrackTintColor={ minimumTrackTintColor } + maximumTrackTintColor={ maximumTrackTintColor } + thumbTintColor={ thumbTintColor } + onValueChange={ this.handleChange } + onSlidingComplete={ this.handleValueSave } + /> + <TextInput + style={ [ styles.sliderTextInput, hasFocus ? styles.isSelected : {} ] } + onChangeText={ this.handleChange } + onFocus={ this.handleToggleFocus } + onBlur={ this.handleToggleFocus } + keyboardType="numeric" + value={ `${ sliderValue }` } + /> + </View> + ); + } +} + +export default Slider; diff --git a/packages/components/src/mobile/slider/styles.scss b/packages/components/src/mobile/slider/styles.scss new file mode 100644 index 00000000000000..326880b621807a --- /dev/null +++ b/packages/components/src/mobile/slider/styles.scss @@ -0,0 +1,27 @@ +.sliderContainer { + flex: 1; + flex-direction: row; + align-content: center; + justify-content: space-evenly; +} + +.slider { + flex-grow: 1; +} + +.sliderTextInput { + width: 40px; + height: 25px; + align-self: center; + margin-left: 10px; + border-width: 1px; + border-radius: 4px; + border-color: $dark-gray-150; + padding-top: 0; + padding-bottom: 0; +} + +.isSelected { + border-width: 2px; + border-color: $blue-wordpress; +} diff --git a/packages/components/src/modal/index.js b/packages/components/src/modal/index.js index 66d3421ee6ff5c..f4a64c289b4e7d 100644 --- a/packages/components/src/modal/index.js +++ b/packages/components/src/modal/index.js @@ -3,7 +3,7 @@ */ import { Component, createPortal } from '@wordpress/element'; import { withInstanceId } from '@wordpress/compose'; -import { deprecated } from '@wordpress/deprecated'; +import deprecated from '@wordpress/deprecated'; /** * Internal dependencies diff --git a/packages/components/src/panel/actions.native.js b/packages/components/src/panel/actions.native.js new file mode 100644 index 00000000000000..02031bf53cb857 --- /dev/null +++ b/packages/components/src/panel/actions.native.js @@ -0,0 +1,36 @@ +/** + * External dependencies + */ +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { + TextControl, +} from '@wordpress/components'; + +/** + * Internal dependencies + */ +import styles from './actions.scss'; + +function PanelActions( { actions } ) { + return ( + <View style={ styles.panelActionsContainer }> + { actions.map( ( { label, onPress } ) => { + return ( + <TextControl + label={ label } + separatorType="topFullWidth" + onPress={ onPress } + labelStyle={ styles.defaultLabelStyle } + key={ label } + /> + ); + } ) } + </View> + ); +} + +export default PanelActions; diff --git a/packages/components/src/panel/actions.native.scss b/packages/components/src/panel/actions.native.scss new file mode 100644 index 00000000000000..ed226c13883be9 --- /dev/null +++ b/packages/components/src/panel/actions.native.scss @@ -0,0 +1,7 @@ +.panelActionsContainer { + padding-top: 24; +} + +.defaultLabelStyle { + color: $alert-red; +} diff --git a/packages/components/src/panel/body.native.js b/packages/components/src/panel/body.native.js index aeeccc77a06c19..314650f945278e 100644 --- a/packages/components/src/panel/body.native.js +++ b/packages/components/src/panel/body.native.js @@ -1,12 +1,16 @@ /** * External dependencies */ -import { View } from 'react-native'; +import { Text, View } from 'react-native'; /** * WordPress dependencies */ import { Component } from '@wordpress/element'; +/** + * Internal dependencies + */ +import styles from './body.scss'; export class PanelBody extends Component { constructor( ) { @@ -15,9 +19,11 @@ export class PanelBody extends Component { } render() { - const { children } = this.props; + const { children, title } = this.props; + return ( - <View > + <View style={ styles.panelContainer }> + { title && <Text style={ styles.sectionHeaderText }>{ title }</Text> } { children } </View> ); diff --git a/packages/components/src/panel/body.native.scss b/packages/components/src/panel/body.native.scss new file mode 100644 index 00000000000000..a30c4df4c15dfc --- /dev/null +++ b/packages/components/src/panel/body.native.scss @@ -0,0 +1,11 @@ +.panelContainer { + padding: 0 16px; +} + +.sectionHeaderText { + color: #87a6bc; + padding-top: 24; + padding-bottom: 8; + font-size: 14; + font-weight: 500; +} diff --git a/packages/components/src/placeholder/README.md b/packages/components/src/placeholder/README.md index 2a12363e7fde01..9e5bf053417d0d 100644 --- a/packages/components/src/placeholder/README.md +++ b/packages/components/src/placeholder/README.md @@ -16,7 +16,7 @@ const MyPlaceholder = () => ( Name | Type | Default | Description --- | --- | --- | --- -`icon` | `string, ReactElement` | `undefined` | If provided, renders an icon next to the label. +`icon` | `string, WPElement` | `undefined` | If provided, renders an icon next to the label. `label` | `string` | `undefined` | Renders a label for the placeholder. `instructions` | `string` | `undefined` | Renders instruction text below label. `isColumnLayout` | `bool` | `false` | Changes placeholder children layout from flex-row to flex-column. diff --git a/packages/components/src/scroll-lock/index.js b/packages/components/src/scroll-lock/index.js index 0d600aac62f14d..1d6255d8c12ef9 100644 --- a/packages/components/src/scroll-lock/index.js +++ b/packages/components/src/scroll-lock/index.js @@ -12,7 +12,7 @@ import { Component } from '@wordpress/element'; * @param {Object} args Keyword args. * @param {HTMLDocument} args.htmlDocument The document to lock the scroll for. * @param {string} args.className The name of the class used to lock scrolling. - * @return {Component} The bound ScrollLock component. + * @return {WPComponent} The bound ScrollLock component. */ export function createScrollLockComponent( { htmlDocument = document, diff --git a/packages/components/src/scroll-lock/stories/index.js b/packages/components/src/scroll-lock/stories/index.js index 865fb6a7e909b9..20ef27337fc787 100644 --- a/packages/components/src/scroll-lock/stories/index.js +++ b/packages/components/src/scroll-lock/stories/index.js @@ -6,7 +6,7 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import { Button } from '../../'; +import Button from '../../button'; import ScrollLock from '../'; export default { title: 'ScrollLock', component: ScrollLock }; diff --git a/packages/components/src/spinner/stories/index.js b/packages/components/src/spinner/stories/index.js new file mode 100644 index 00000000000000..188f13e45273f4 --- /dev/null +++ b/packages/components/src/spinner/stories/index.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import Spinner from '../'; + +export default { title: 'Spinner', component: Spinner }; + +export const _default = () => { + return ( + <Spinner /> + ); +}; diff --git a/packages/components/src/style.scss b/packages/components/src/style.scss index 6365bff68cf568..7a62ba0534539d 100644 --- a/packages/components/src/style.scss +++ b/packages/components/src/style.scss @@ -9,6 +9,7 @@ @import "./color-picker/style.scss"; @import "./dashicon/style.scss"; @import "./date-time/style.scss"; +@import "./dimension-control/style.scss"; @import "./disabled/style.scss"; @import "./draggable/style.scss"; @import "./drop-zone/style.scss"; @@ -44,3 +45,4 @@ @import "./toolbar/style.scss"; @import "./toolbar-button/style.scss"; @import "./tooltip/style.scss"; +@import "./visually-hidden/style.scss"; diff --git a/packages/components/src/toolbar/index.js b/packages/components/src/toolbar/index.js index ca41d32bb6e1b9..bf9237eed1b624 100644 --- a/packages/components/src/toolbar/index.js +++ b/packages/components/src/toolbar/index.js @@ -34,13 +34,13 @@ import ToolbarContainer from './toolbar-container'; * Either `controls` or `children` is required, otherwise this components * renders nothing. * - * @param {Object} props - * @param {Array} [props.controls] The controls to render in this toolbar. - * @param {ReactElement} [props.children] Any other things to render inside the - * toolbar besides the controls. - * @param {string} [props.className] Class to set on the container div. + * @param {Object} props + * @param {Array} [props.controls] The controls to render in this toolbar. + * @param {WPElement} [props.children] Any other things to render inside the + * toolbar besides the controls. + * @param {string} [props.className] Class to set on the container div. * - * @return {ReactElement} The rendered toolbar. + * @return {WPComponent} The rendered component. */ function Toolbar( { controls = [], children, className, isCollapsed, icon, label, ...otherProps } ) { if ( diff --git a/packages/components/src/visually-hidden/README.md b/packages/components/src/visually-hidden/README.md new file mode 100644 index 00000000000000..1f490f5134af26 --- /dev/null +++ b/packages/components/src/visually-hidden/README.md @@ -0,0 +1,9 @@ +# VisuallyHidden + +A component used to render text intended to be visually hidden, but will show for alternate devices, for example a screen reader. + +### Usage + +```jsx +<VisuallyHidden> Show text for screenreader. </VisuallyHidden> +``` diff --git a/packages/components/src/visually-hidden/index.js b/packages/components/src/visually-hidden/index.js new file mode 100644 index 00000000000000..b29c954c2cd9e1 --- /dev/null +++ b/packages/components/src/visually-hidden/index.js @@ -0,0 +1,22 @@ + +/** + * Internal dependencies + */ +import { renderAsRenderProps } from './utils'; + +/** + * VisuallyHidden component to render text out non-visually + * for use in devices such as a screen reader. + */ +function VisuallyHidden( { + as = 'div', + ...props +} ) { + return renderAsRenderProps( { + as, + className: 'components-visually-hidden', + ...props, + } ); +} +export default VisuallyHidden; + diff --git a/packages/components/src/visually-hidden/stories/index.js b/packages/components/src/visually-hidden/stories/index.js new file mode 100644 index 00000000000000..03b60ccc334126 --- /dev/null +++ b/packages/components/src/visually-hidden/stories/index.js @@ -0,0 +1,17 @@ +/** + * Internal dependencies + */ +import VisuallyHidden from '../'; + +export default { title: 'VisuallyHidden', component: VisuallyHidden }; + +export const _default = () => ( + <> + <VisuallyHidden> + This should not show. + </VisuallyHidden> + <div> + This text will <VisuallyHidden as="span">but not inline </VisuallyHidden> always show. + </div> + </> +); diff --git a/packages/components/src/visually-hidden/style.scss b/packages/components/src/visually-hidden/style.scss new file mode 100644 index 00000000000000..02fec4486afa23 --- /dev/null +++ b/packages/components/src/visually-hidden/style.scss @@ -0,0 +1,30 @@ +.components-visually-hidden { + border: 0; + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + word-wrap: normal !important; +} + +.components-visually-hidden:focus { + background-color: $light-gray-500; + clip: auto !important; + clip-path: none; + color: #444; + display: block; + font-size: 1em; + height: auto; + left: 5px; + line-height: normal; + padding: 15px 23px 14px; + text-decoration: none; + top: 5px; + width: auto; + z-index: 100000; +} diff --git a/packages/components/src/visually-hidden/utils.js b/packages/components/src/visually-hidden/utils.js new file mode 100644 index 00000000000000..07957708090ef0 --- /dev/null +++ b/packages/components/src/visually-hidden/utils.js @@ -0,0 +1,22 @@ +/** + * Utility Functions + */ + +/** + * renderAsRenderProps is used to wrap a component and convert + * the passed property "as" either a string or component, to the + * rendered tag if a string, or component. + * + * See VisuallyHidden hidden for example. + * + * @param {string|Component} as A tag or component to render. + * @return {Component} The rendered component. + */ +function renderAsRenderProps( { as: Component = 'div', ...props } ) { + if ( typeof props.children === 'function' ) { + return props.children( props ); + } + return <Component { ...props } />; +} + +export { renderAsRenderProps }; diff --git a/packages/components/storybook/addons.js b/packages/components/storybook/addons.js index d3fa048c75edf4..ccfec56c606dcc 100644 --- a/packages/components/storybook/addons.js +++ b/packages/components/storybook/addons.js @@ -2,5 +2,6 @@ * External dependencies */ import '@storybook/addon-a11y/register'; +import '@storybook/addon-knobs/register'; import '@storybook/addon-storysource/register'; import '@storybook/addon-viewport/register'; diff --git a/packages/components/storybook/config.js b/packages/components/storybook/config.js index eace300f3fc963..b2bfd74c3da6eb 100644 --- a/packages/components/storybook/config.js +++ b/packages/components/storybook/config.js @@ -3,6 +3,7 @@ */ import { addDecorator, configure } from '@storybook/react'; import { withA11y } from '@storybook/addon-a11y'; +import { withKnobs } from '@storybook/addon-knobs'; /** * Internal dependencies @@ -10,6 +11,7 @@ import { withA11y } from '@storybook/addon-a11y'; import '../build-style/style.css'; addDecorator( withA11y ); +addDecorator( withKnobs ); configure( [ require.context( '../docs', true, /\/.+\.mdx$/ ), diff --git a/packages/compose/README.md b/packages/compose/README.md index dc47f26e995652..7fcf12e07a7293 100644 --- a/packages/compose/README.md +++ b/packages/compose/README.md @@ -163,11 +163,11 @@ component. _Parameters_ -- _WrappedComponent_ `WPElement`: The wrapped component. +- _WrappedComponent_ `WPComponent`: The wrapped component. _Returns_ -- `Component`: Component with an instanceId prop. +- `WPComponent`: Component with an instanceId prop. <a name="withSafeTimeout" href="#withSafeTimeout">#</a> **withSafeTimeout** @@ -176,11 +176,11 @@ that ought to be bound to a component's lifecycle. _Parameters_ -- _OriginalComponent_ `Component`: Component requiring setTimeout +- _OriginalComponent_ `WPComponent`: Component requiring setTimeout _Returns_ -- `Component`: Wrapped component. +- `WPComponent`: Wrapped component. <a name="withState" href="#withState">#</a> **withState** @@ -193,7 +193,7 @@ _Parameters_ _Returns_ -- `Component`: Wrapped component. +- `WPComponent`: Wrapped component. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/compose/package.json b/packages/compose/package.json index 827a0afb46eff7..5ad5ed9d1bc786 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/compose", - "version": "3.7.0", + "version": "3.7.2", "description": "WordPress higher-order components (HOCs).", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -21,6 +21,7 @@ "main": "build/index.js", "module": "build-module/index.js", "react-native": "src/index", + "sideEffects": false, "dependencies": { "@babel/runtime": "^7.4.4", "@wordpress/element": "file:../element", diff --git a/packages/compose/src/higher-order/compose.js b/packages/compose/src/higher-order/compose.js new file mode 100644 index 00000000000000..a166387821e7b3 --- /dev/null +++ b/packages/compose/src/higher-order/compose.js @@ -0,0 +1,14 @@ +/** + * External dependencies + */ +import { flowRight as compose } from 'lodash'; + +/** + * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function + * composition, where each successive invocation is supplied the return value of the previous. + * + * @param {...Function} hocs The HOC functions to invoke. + * + * @return {Function} Returns the new composite function. + */ +export default compose; diff --git a/packages/compose/src/higher-order/with-instance-id/index.js b/packages/compose/src/higher-order/with-instance-id/index.js index 53c09ec56f8882..960c6997e8671f 100644 --- a/packages/compose/src/higher-order/with-instance-id/index.js +++ b/packages/compose/src/higher-order/with-instance-id/index.js @@ -12,9 +12,9 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * A Higher Order Component used to be provide a unique instance ID by * component. * - * @param {WPElement} WrappedComponent The wrapped component. + * @param {WPComponent} WrappedComponent The wrapped component. * - * @return {Component} Component with an instanceId prop. + * @return {WPComponent} Component with an instanceId prop. */ export default createHigherOrderComponent( ( WrappedComponent ) => { let instances = 0; diff --git a/packages/compose/src/higher-order/with-safe-timeout/index.js b/packages/compose/src/higher-order/with-safe-timeout/index.js index 910dd94fddc19d..43d4e9e780d5b7 100644 --- a/packages/compose/src/higher-order/with-safe-timeout/index.js +++ b/packages/compose/src/higher-order/with-safe-timeout/index.js @@ -17,9 +17,9 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * A higher-order component used to provide and manage delayed function calls * that ought to be bound to a component's lifecycle. * - * @param {Component} OriginalComponent Component requiring setTimeout + * @param {WPComponent} OriginalComponent Component requiring setTimeout * - * @return {Component} Wrapped component. + * @return {WPComponent} Wrapped component. */ const withSafeTimeout = createHigherOrderComponent( ( OriginalComponent ) => { diff --git a/packages/compose/src/higher-order/with-state/index.js b/packages/compose/src/higher-order/with-state/index.js index 19e639043bd28b..02db9392b39631 100644 --- a/packages/compose/src/higher-order/with-state/index.js +++ b/packages/compose/src/higher-order/with-state/index.js @@ -14,7 +14,7 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * * @param {?Object} initialState Optional initial state of the component. * - * @return {Component} Wrapped component. + * @return {WPComponent} Wrapped component. */ export default function withState( initialState = {} ) { return createHigherOrderComponent( ( OriginalComponent ) => { diff --git a/packages/compose/src/index.js b/packages/compose/src/index.js index 9ea31b2d351aba..ab1ecf3564edbe 100644 --- a/packages/compose/src/index.js +++ b/packages/compose/src/index.js @@ -1,20 +1,8 @@ -/** - * External dependencies - */ -import { flowRight } from 'lodash'; - // Utils export { default as createHigherOrderComponent } from './utils/create-higher-order-component'; -/** - * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function - * composition, where each successive invocation is supplied the return value of the previous. - * - * @param {...Function} hocs The HOC functions to invoke. - * - * @return {Function} Returns the new composite function. - */ -export { flowRight as compose }; +// Compose helper (aliased flowRight from Lodash) +export { default as compose } from './higher-order/compose'; // Higher-order components export { default as ifCondition } from './higher-order/if-condition'; diff --git a/packages/core-data/README.md b/packages/core-data/README.md index 892a6e572a99be..a2bb3ccbe6deeb 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -106,7 +106,7 @@ a given URl has been received. _Parameters_ - _url_ `string`: URL to preview the embed for. -- _preview_ `Mixed`: Preview data. +- _preview_ `*`: Preview data. _Returns_ diff --git a/packages/core-data/package.json b/packages/core-data/package.json index 32fca25d8a2771..3c565d2bfc56c6 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "2.7.0", + "version": "2.7.3", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/src/actions.js b/packages/core-data/src/actions.js index dc77d54994ac0b..a79aaba7e33d8f 100644 --- a/packages/core-data/src/actions.js +++ b/packages/core-data/src/actions.js @@ -109,8 +109,8 @@ export function receiveThemeSupports( themeSupports ) { * Returns an action object used in signalling that the preview data for * a given URl has been received. * - * @param {string} url URL to preview the embed for. - * @param {Mixed} preview Preview data. + * @param {string} url URL to preview the embed for. + * @param {*} preview Preview data. * * @return {Object} Action object. */ diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js index 4ee2f6b715374f..b75d0e44632373 100644 --- a/packages/core-data/src/entities.js +++ b/packages/core-data/src/entities.js @@ -12,6 +12,7 @@ import { apiFetch, select } from './controls'; export const DEFAULT_ENTITY_KEY = 'id'; export const defaultEntities = [ + { name: 'site', kind: 'root', baseURL: '/wp/v2/settings' }, { name: 'postType', kind: 'root', key: 'slug', baseURL: '/wp/v2/types' }, { name: 'media', kind: 'root', baseURL: '/wp/v2/media', plural: 'mediaItems' }, { name: 'taxonomy', kind: 'root', key: 'slug', baseURL: '/wp/v2/taxonomies', plural: 'taxonomies' }, diff --git a/packages/core-data/src/entity-provider.js b/packages/core-data/src/entity-provider.js index 7870e0217cc974..50439f1b57ad65 100644 --- a/packages/core-data/src/entity-provider.js +++ b/packages/core-data/src/entity-provider.js @@ -52,6 +52,17 @@ export default function EntityProvider( { kind, type, id, children } ) { return <Provider value={ id }>{ children }</Provider>; } +/** + * Hook that returns the ID for the nearest + * provided entity of the specified type. + * + * @param {string} kind The entity kind. + * @param {string} type The entity type. + */ +export function useEntityId( kind, type ) { + return useContext( getEntity( kind, type ).context ); +} + /** * Hook that returns the value and a setter for the * specified property of the nearest provided @@ -66,11 +77,13 @@ export default function EntityProvider( { kind, type, id, children } ) { * setter. */ export function useEntityProp( kind, type, prop ) { - const id = useContext( getEntity( kind, type ).context ); + const id = useEntityId( kind, type ); const value = useSelect( ( select ) => { - const entity = select( 'core' ).getEditedEntityRecord( kind, type, id ); + const { getEntityRecord, getEditedEntityRecord } = select( 'core' ); + getEntityRecord( kind, type, id ); // Trigger resolver. + const entity = getEditedEntityRecord( kind, type, id ); return entity && entity[ prop ]; }, [ kind, type, id, prop ] @@ -88,3 +101,62 @@ export function useEntityProp( kind, type, prop ) { return [ value, setValue ]; } + +/** + * Hook that returns whether the nearest provided + * entity of the specified type is dirty, saving, + * and a function to save it. + * + * The last, optional parameter is for scoping the + * selection to a single property or a list properties. + * + * By default, dirtyness detection and saving considers + * and handles all properties of an entity, but this + * last parameter lets you scope it to a single property + * or a list of properties for each instance of this hook. + * + * @param {string} kind The entity kind. + * @param {string} type The entity type. + * @param {string|[string]} [props] The property name or list of property names. + */ +export function __experimentalUseEntitySaving( kind, type, props ) { + const id = useEntityId( kind, type ); + + const [ isDirty, isSaving, edits ] = useSelect( + ( select ) => { + const { getEntityRecordNonTransientEdits, isSavingEntityRecord } = select( + 'core' + ); + const _edits = getEntityRecordNonTransientEdits( kind, type, id ); + const editKeys = Object.keys( _edits ); + return [ + props ? + editKeys.some( ( key ) => + typeof props === 'string' ? key === props : props.includes( key ) + ) : + editKeys.length > 0, + isSavingEntityRecord( kind, type, id ), + _edits, + ]; + }, + [ kind, type, id, props ] + ); + + const { saveEntityRecord } = useDispatch( 'core' ); + const save = useCallback( () => { + let filteredEdits = edits; + if ( typeof props === 'string' ) { + filteredEdits = { [ props ]: filteredEdits[ props ] }; + } else if ( props ) { + filteredEdits = filteredEdits.reduce( ( acc, key ) => { + if ( props.includes( key ) ) { + acc[ key ] = filteredEdits[ key ]; + } + return acc; + }, {} ); + } + saveEntityRecord( kind, type, { id, ...filteredEdits } ); + }, [ kind, type, id, props, edits ] ); + + return [ isDirty, isSaving, save ]; +} diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index 2cdddb960e448b..bf12ac2e5096fb 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -49,4 +49,9 @@ registerStore( REDUCER_KEY, { resolvers: { ...resolvers, ...entityResolvers }, } ); -export { default as EntityProvider, useEntityProp } from './entity-provider'; +export { + default as EntityProvider, + useEntityId, + useEntityProp, + __experimentalUseEntitySaving, +} from './entity-provider'; diff --git a/packages/core-data/src/queried-data/reducer.js b/packages/core-data/src/queried-data/reducer.js index 0c3256e9a8f987..36da4465bb922d 100644 --- a/packages/core-data/src/queried-data/reducer.js +++ b/packages/core-data/src/queried-data/reducer.js @@ -74,10 +74,10 @@ function items( state = {}, action ) { const key = action.key || DEFAULT_ENTITY_KEY; return { ...state, - ...action.items.reduce( ( acc, value ) => { + ...action.items.reduce( ( accumulator, value ) => { const itemId = value[ key ]; - acc[ itemId ] = conservativeMapItem( state[ itemId ], value ); - return acc; + accumulator[ itemId ] = conservativeMapItem( state[ itemId ], value ); + return accumulator; }, {} ), }; } diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index 8edfdbf895cded..670cb4adf2a750 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -47,7 +47,7 @@ export function* getCurrentUser() { * @param {string} name Entity name. * @param {number} key Record's key */ -export function* getEntityRecord( kind, name, key ) { +export function* getEntityRecord( kind, name, key = '' ) { const entities = yield getKindEntities( kind ); const entity = find( entities, { kind, name } ); if ( ! entity ) { diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js index 4c61d59220843f..3974d66c83b60b 100644 --- a/packages/core-data/src/selectors.js +++ b/packages/core-data/src/selectors.js @@ -123,12 +123,12 @@ export const getRawEntityRecord = createSelector( const record = getEntityRecord( state, kind, name, key ); return ( record && - Object.keys( record ).reduce( ( acc, _key ) => { + Object.keys( record ).reduce( ( accumulator, _key ) => { // Because edits are the "raw" attribute values, // we return those from record selectors to make rendering, // comparisons, and joins with edits easier. - acc[ _key ] = get( record[ _key ], 'raw', record[ _key ] ); - return acc; + accumulator[ _key ] = get( record[ _key ], 'raw', record[ _key ] ); + return accumulator; }, {} ) ); }, diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json index 8e74ef5a768b4c..9b6d2724b43e45 100644 --- a/packages/data-controls/package.json +++ b/packages/data-controls/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data-controls", - "version": "1.3.0", + "version": "1.3.3", "description": "A set of common controls for the @wordpress/data api.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/README.md b/packages/data/README.md index a76019371e725a..68dc1a48e1697a 100644 --- a/packages/data/README.md +++ b/packages/data/README.md @@ -251,6 +251,46 @@ Specific implementation differences from Redux and React Redux: <!-- START TOKEN(Autogenerated API docs) --> +<a name="AsyncModeProvider" href="#AsyncModeProvider">#</a> **AsyncModeProvider** + +Context Provider Component used to switch the data module component rerendering +between Sync and Async modes. + +_Usage_ + +```js +import { useSelect, AsyncModeProvider } from '@wordpress/data'; + +function BlockCount() { + const count = useSelect( ( select ) => { + return select( 'core/block-editor' ).getBlockCount() + } ); + + return count; +} + +function App() { + return ( + <AsyncModeProvider value={ true }> + <BlockCount /> + </AsyncModeProvider> + ); +} +``` + +In this example, the BlockCount component is rerendered asynchronously. +It means if a more critical task is being performed (like typing in an input), +the rerendering is delayed until the browser becomes IDLE. +It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. + +_Parameters_ + +- _props.value_ `boolean`: Enable Async Mode. + +_Returns_ + +- `WPComponent`: The component to be rendered. + <a name="combineReducers" href="#combineReducers">#</a> **combineReducers** The combineReducers helper function turns an object whose values are different @@ -693,7 +733,7 @@ _Parameters_ _Returns_ -- `Component`: Enhanced component with merged dispatcher props. +- `WPComponent`: Enhanced component with merged dispatcher props. <a name="withRegistry" href="#withRegistry">#</a> **withRegistry** @@ -750,7 +790,7 @@ _Parameters_ _Returns_ -- `Component`: Enhanced component with merged state data props. +- `WPComponent`: Enhanced component with merged state data props. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/data/package.json b/packages/data/package.json index 9eb21a7608146d..3812312f7dad8d 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data", - "version": "4.9.0", + "version": "4.9.2", "description": "Data module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/src/components/async-mode-provider/context.js b/packages/data/src/components/async-mode-provider/context.js index c0e59ef7138183..88c98cb260b4a0 100644 --- a/packages/data/src/components/async-mode-provider/context.js +++ b/packages/data/src/components/async-mode-provider/context.js @@ -9,4 +9,38 @@ const { Consumer, Provider } = Context; export const AsyncModeConsumer = Consumer; +/** + * Context Provider Component used to switch the data module component rerendering + * between Sync and Async modes. + * + * @example + * + * ```js + * import { useSelect, AsyncModeProvider } from '@wordpress/data'; + * + * function BlockCount() { + * const count = useSelect( ( select ) => { + * return select( 'core/block-editor' ).getBlockCount() + * } ); + * + * return count; + * } + * + * function App() { + * return ( + * <AsyncModeProvider value={ true }> + * <BlockCount /> + * </AsyncModeProvider> + * ); + * } + * ``` + * + * In this example, the BlockCount component is rerendered asynchronously. + * It means if a more critical task is being performed (like typing in an input), + * the rerendering is delayed until the browser becomes IDLE. + * It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. + * + * @param {boolean} props.value Enable Async Mode. + * @return {WPComponent} The component to be rendered. + */ export default Provider; diff --git a/packages/data/src/components/with-dispatch/index.js b/packages/data/src/components/with-dispatch/index.js index 2247a253a189d5..3e6c2194dec5f4 100644 --- a/packages/data/src/components/with-dispatch/index.js +++ b/packages/data/src/components/with-dispatch/index.js @@ -85,7 +85,7 @@ import { useDispatchWithMap } from '../use-dispatch'; * returns an object with the same keys. For example, it should not contain * conditions under which a different value would be returned. * - * @return {Component} Enhanced component with merged dispatcher props. + * @return {WPComponent} Enhanced component with merged dispatcher props. */ const withDispatch = ( mapDispatchToProps ) => createHigherOrderComponent( ( WrappedComponent ) => ( ownProps ) => { diff --git a/packages/data/src/components/with-select/index.js b/packages/data/src/components/with-select/index.js index f9659e7e865a8f..aeb86761494e44 100644 --- a/packages/data/src/components/with-select/index.js +++ b/packages/data/src/components/with-select/index.js @@ -45,7 +45,7 @@ import useSelect from '../use-select'; * component and update automatically if the price of a hammer ever changes in * the store. * - * @return {Component} Enhanced component with merged state data props. + * @return {WPComponent} Enhanced component with merged state data props. */ const withSelect = ( mapSelectToProps ) => createHigherOrderComponent( ( WrappedComponent ) => pure( diff --git a/packages/data/src/factory.js b/packages/data/src/factory.js index 2a10c7a8e7afc1..bdc2f1519e60e5 100644 --- a/packages/data/src/factory.js +++ b/packages/data/src/factory.js @@ -3,10 +3,6 @@ */ import defaultRegistry from './default-registry'; -/** - * @typedef {import('./registry').WPDataRegistry} WPDataRegistry - */ - /** * Mark a selector as a registry selector. * diff --git a/packages/data/src/index.js b/packages/data/src/index.js index 8dd6893c5d9e01..c7ad8f67a7484d 100644 --- a/packages/data/src/index.js +++ b/packages/data/src/index.js @@ -19,9 +19,7 @@ export { } from './components/registry-provider'; export { default as useSelect } from './components/use-select'; export { useDispatch } from './components/use-dispatch'; -export { - AsyncModeProvider as __experimentalAsyncModeProvider, -} from './components/async-mode-provider'; +export { AsyncModeProvider } from './components/async-mode-provider'; export { createRegistry } from './registry'; export { createRegistrySelector, createRegistryControl } from './factory'; diff --git a/packages/data/src/namespace-store/index.js b/packages/data/src/namespace-store/index.js index b3bd639fcddfa3..bc41587569bbba 100644 --- a/packages/data/src/namespace-store/index.js +++ b/packages/data/src/namespace-store/index.js @@ -24,7 +24,7 @@ import * as metadataSelectors from './metadata/selectors'; import * as metadataActions from './metadata/actions'; /** - * @typedef {import('../registry').WPDataRegistry} WPDataRegistry + * @typedef {WPDataRegistry} WPDataRegistry */ /** diff --git a/packages/data/src/plugins/persistence/index.js b/packages/data/src/plugins/persistence/index.js index a0c910f8a73bca..871a7e56133594 100644 --- a/packages/data/src/plugins/persistence/index.js +++ b/packages/data/src/plugins/persistence/index.js @@ -138,7 +138,7 @@ const persistencePlugin = function( registry, pluginOptions ) { // to leverage its behavior of returning the same object when none // of the property values changes. This allows a strict reference // equality to bypass a persistence set on an unchanging state. - const reducers = keys.reduce( ( result, key ) => Object.assign( result, { + const reducers = keys.reduce( ( accumulator, key ) => Object.assign( accumulator, { [ key ]: ( state, action ) => action.nextState[ key ], } ), {} ); diff --git a/packages/date/README.md b/packages/date/README.md index c4bad6ef1636e1..96cbbba1b7239d 100644 --- a/packages/date/README.md +++ b/packages/date/README.md @@ -23,7 +23,7 @@ Formats a date (like `date()` in PHP), in the site's timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. _Returns_ @@ -36,7 +36,7 @@ Formats a date (like `date_i18n()` in PHP). _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. - _gmt_ `boolean`: True for GMT/UTC, false for site's timezone. _Returns_ @@ -50,7 +50,7 @@ Formats a date. Does not alter the date's timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. _Returns_ @@ -75,7 +75,7 @@ Formats a date (like `date()` in PHP), in the UTC timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. _Returns_ diff --git a/packages/date/src/index.js b/packages/date/src/index.js index 39b4425ea2da22..4537ec47284749 100644 --- a/packages/date/src/index.js +++ b/packages/date/src/index.js @@ -145,7 +145,7 @@ const formatMap = { /** * Gets the ordinal suffix. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -160,7 +160,7 @@ const formatMap = { /** * Gets the day of the year (zero-indexed). * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -180,7 +180,7 @@ const formatMap = { /** * Gets the days in the month. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -192,7 +192,7 @@ const formatMap = { /** * Gets whether the current year is a leap year. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -209,7 +209,7 @@ const formatMap = { /** * Gets the current time in Swatch Internet Time (.beats). * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -240,7 +240,7 @@ const formatMap = { /** * Gets whether the timezone is in DST currently. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -253,7 +253,7 @@ const formatMap = { /** * Gets the timezone offset in seconds. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -273,10 +273,10 @@ const formatMap = { /** * Formats a date. Does not alter the date's timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -314,10 +314,10 @@ export function format( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date()` in PHP), in the site's timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -330,10 +330,10 @@ export function date( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date()` in PHP), in the UTC timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -345,12 +345,12 @@ export function gmdate( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date_i18n()` in PHP). * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. - * @param {boolean} gmt True for GMT/UTC, false for - * site's timezone. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. + * @param {boolean} gmt True for GMT/UTC, false for + * site's timezone. * * @return {string} Formatted date. */ diff --git a/packages/deprecated/package.json b/packages/deprecated/package.json index 654149a2f32208..7a0494fd4d54bb 100644 --- a/packages/deprecated/package.json +++ b/packages/deprecated/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/deprecated", - "version": "2.6.0", + "version": "2.6.1", "description": "Deprecation utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 33e1f9eca8283d..ff4900eca80a02 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "2.5.0", + "version": "2.5.1", "description": "Execute callback after the DOM is loaded.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom/package.json b/packages/dom/package.json index e5f1b9297eec16..b335970b2113bc 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom", - "version": "2.5.0", + "version": "2.5.2", "description": "DOM utilities module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md index df00ecbe7c0ce2..6d7c17d4e0c7e6 100644 --- a/packages/e2e-test-utils/CHANGELOG.md +++ b/packages/e2e-test-utils/CHANGELOG.md @@ -1,3 +1,9 @@ +## Master + +### Breaking Changes +- The util function `enableExperimentalFeatures` was removed. It is now available for internal usage in the `e2e-tests` package. + + ## 2.0.0 (2019-05-21) ### Requirements diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index d8b3263c2e6e99..e01082057a82a8 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -191,7 +191,7 @@ _Parameters_ _Returns_ -- `?ElementHandle`: Object that represents an in-page DOM element. +- `?puppeteer.ElementHandle`: Object that represents an in-page DOM element. <a name="findSidebarPanelWithTitle" href="#findSidebarPanelWithTitle">#</a> **findSidebarPanelWithTitle** @@ -203,7 +203,7 @@ _Parameters_ _Returns_ -- `?ElementHandle`: Object that represents an in-page DOM element. +- `?puppeteer.ElementHandle`: Object that represents an in-page DOM element. <a name="getAllBlockInserterItemTitles" href="#getAllBlockInserterItemTitles">#</a> **getAllBlockInserterItemTitles** @@ -529,7 +529,7 @@ without the new dimensions being applied. _Parameters_ - _width_ `number`: Width of the window. -- _height_ `height`: Height of the window. +- _height_ `number`: Height of the window. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 7ddd91f1b73974..6365c171aa416e 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils", - "version": "2.4.0", + "version": "2.4.3", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js b/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js index a4167fe6e2e6cd..55fbf4c91c10f2 100644 --- a/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js +++ b/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js @@ -8,7 +8,7 @@ import { first } from 'lodash'; * * @param {string} panelTitle The name of sidebar panel. * - * @return {?ElementHandle} Object that represents an in-page DOM element. + * @return {?puppeteer.ElementHandle} Object that represents an in-page DOM element. */ export async function findSidebarPanelToggleButtonWithTitle( panelTitle ) { return first( await page.$x( `//div[contains(@class,"edit-post-sidebar")]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ panelTitle }")]` ) ); diff --git a/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js b/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js index ff60dca5f00782..2f1436c5b8de23 100644 --- a/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js +++ b/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js @@ -8,7 +8,7 @@ import { first } from 'lodash'; * * @param {string} panelTitle The name of sidebar panel. * - * @return {?ElementHandle} Object that represents an in-page DOM element. + * @return {?puppeteer.ElementHandle} Object that represents an in-page DOM element. */ export async function findSidebarPanelWithTitle( panelTitle ) { const classSelect = ( className ) => `[contains(concat(" ", @class, " "), " ${ className } ")]`; diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 8fcf2b400c5853..40feec01014580 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -11,7 +11,6 @@ export { createURL } from './create-url'; export { deactivatePlugin } from './deactivate-plugin'; export { disablePrePublishChecks } from './disable-pre-publish-checks'; export { dragAndResize } from './drag-and-resize'; -export { enableExperimentalFeatures } from './enable-experimental-features'; export { enablePageDialogAccept } from './enable-page-dialog-accept'; export { enablePrePublishChecks } from './enable-pre-publish-checks'; export { ensureSidebarOpened } from './ensure-sidebar-opened'; diff --git a/packages/e2e-test-utils/src/wait-for-window-dimensions.js b/packages/e2e-test-utils/src/wait-for-window-dimensions.js index 9b505cf3b12807..924a5c939b3da0 100644 --- a/packages/e2e-test-utils/src/wait-for-window-dimensions.js +++ b/packages/e2e-test-utils/src/wait-for-window-dimensions.js @@ -5,7 +5,7 @@ * https://github.com/GoogleChrome/puppeteer/issues/1751 * * @param {number} width Width of the window. - * @param {height} height Height of the window. + * @param {number} height Height of the window. */ export async function waitForWindowDimensions( width, height ) { await page diff --git a/packages/e2e-tests/config/performance-reporter.js b/packages/e2e-tests/config/performance-reporter.js index 681bb60f41618e..f7bb05666054d5 100644 --- a/packages/e2e-tests/config/performance-reporter.js +++ b/packages/e2e-tests/config/performance-reporter.js @@ -6,7 +6,7 @@ function average( array ) { class PerformanceReporter { onRunComplete() { - const path = __dirname + '/../specs/results.json'; + const path = __dirname + '/../specs/performance/results.json'; if ( ! existsSync( path ) ) { return; diff --git a/packages/e2e-test-utils/src/enable-experimental-features.js b/packages/e2e-tests/experimental-features.js similarity index 60% rename from packages/e2e-test-utils/src/enable-experimental-features.js rename to packages/e2e-tests/experimental-features.js index be74f20f82fd92..4b06a761c865a0 100644 --- a/packages/e2e-test-utils/src/enable-experimental-features.js +++ b/packages/e2e-tests/experimental-features.js @@ -2,18 +2,9 @@ * WordPress dependencies */ import { addQueryArgs } from '@wordpress/url'; +import { visitAdminPage } from '@wordpress/e2e-test-utils'; -/** - * Internal dependencies - */ -import { visitAdminPage } from './visit-admin-page'; - -/** - * Enables experimental features from the plugin settings section. - * - * @param {Array} features Array of {string} selectors of settings to enable. Assumes they can be enabled with one click. - */ -export async function enableExperimentalFeatures( features ) { +async function setExperimentalFeaturesState( features, enable ) { const query = addQueryArgs( '', { page: 'gutenberg-experiments', } ); @@ -23,7 +14,7 @@ export async function enableExperimentalFeatures( features ) { await page.waitForSelector( feature ); const checkedSelector = `${ feature }[checked=checked]`; const isChecked = !! ( await page.$( checkedSelector ) ); - if ( ! isChecked ) { + if ( ( ! isChecked && enable ) || ( isChecked && ! enable ) ) { await page.click( feature ); } } ) ); @@ -32,3 +23,21 @@ export async function enableExperimentalFeatures( features ) { page.click( '#submit' ), ] ); } + +/** + * Enables experimental features from the plugin settings section. + * + * @param {Array} features Array of {string} selectors of settings to enable. Assumes they can be enabled with one click. + */ +export async function enableExperimentalFeatures( features ) { + await setExperimentalFeaturesState( features, true ); +} + +/** + * Disables experimental features from the plugin settings section. + * + * @param {Array} features Array of {string} selectors of settings to disable. Assumes they can be disabled with one click. + */ +export async function disableExperimentalFeatures( features ) { + await setExperimentalFeaturesState( features, false ); +} diff --git a/packages/e2e-tests/fixtures/block-transforms.js b/packages/e2e-tests/fixtures/block-transforms.js index ff297c84a5d3da..454bf2aeb2bf22 100644 --- a/packages/e2e-tests/fixtures/block-transforms.js +++ b/packages/e2e-tests/fixtures/block-transforms.js @@ -118,6 +118,28 @@ export const EXPECTED_TRANSFORMS = { ], originalBlock: 'Cover', }, + core__cover__gradient: { + availableTransforms: [ + 'Group', + 'Image', + 'Video', + ], + originalBlock: 'Cover', + }, + 'core__cover__gradient-image': { + availableTransforms: [ + 'Group', + 'Image', + ], + originalBlock: 'Cover', + }, + 'core__cover__gradient-video': { + availableTransforms: [ + 'Group', + 'Video', + ], + originalBlock: 'Cover', + }, core__cover__video: { availableTransforms: [ 'Group', @@ -425,6 +447,12 @@ export const EXPECTED_TRANSFORMS = { 'Group', ], }, + 'core__site-title': { + availableTransforms: [ + 'Group', + ], + originalBlock: 'Site Title', + }, 'core__social-link-amazon': { availableTransforms: [ 'Group', diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html new file mode 100644 index 00000000000000..6353eac851e882 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html @@ -0,0 +1,10 @@ +<!-- wp:cover {"url":"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=","dimRatio":30,"customGradient":"linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"} --> +<div class="wp-block-cover has-background-dim-30 has-background-dim has-background-gradient" style="background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)"> + <span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"></span> + <div class="wp-block-cover__inner-container"> + <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> + <p class="has-text-align-center has-large-font-size"> Cover! </p> + <!-- /wp:paragraph --> + </div> +</div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json new file mode 100644 index 00000000000000..7752fa1da96f25 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json @@ -0,0 +1,31 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", + "hasParallax": false, + "dimRatio": 30, + "backgroundType": "image", + "customGradient": "linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)" + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "align": "center", + "content": " Cover! ", + "dropCap": false, + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "originalContent": "<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>" + } + ], + "originalContent": "<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json new file mode 100644 index 00000000000000..07ab0aa6299bad --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json @@ -0,0 +1,40 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", + "dimRatio": 30, + "customGradient": "linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)" + }, + "innerBlocks": [ + { + "blockName": "core/paragraph", + "attrs": { + "align": "center", + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>\n\t\t", + "innerContent": [ + "\n\t\t<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>\n\t\t" + ] + } + ], + "innerHTML": "\n<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", + "innerContent": [ + "\n<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", + null, + "\n\t</div>\n</div>\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html new file mode 100644 index 00000000000000..0fda894680f92b --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html @@ -0,0 +1,5 @@ +<!-- wp:cover {"url":"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=","dimRatio":30,"customGradient":"linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"} --> +<div class="wp-block-cover has-background-dim-30 has-background-dim has-background-gradient" style="background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)"><span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> +<p class="has-text-align-center has-large-font-size"> Cover! </p> +<!-- /wp:paragraph --></div></div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html new file mode 100644 index 00000000000000..8da6141aa041ab --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html @@ -0,0 +1,11 @@ +<!-- wp:cover {"url":"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=","dimRatio":70,"backgroundType":"video","customGradient":"linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"} --> +<div class="wp-block-cover has-background-dim-70 has-background-dim has-background-gradient"> + <span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"></span> + <video class="wp-block-cover__video-background" autoplay muted loop src="data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="></video> + <div class="wp-block-cover__inner-container"> + <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> + <p class="has-text-align-center has-large-font-size">Cover!</p> + <!-- /wp:paragraph --> + </div> +</div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json new file mode 100644 index 00000000000000..84cb314d0fcca6 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json @@ -0,0 +1,31 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "hasParallax": false, + "dimRatio": 70, + "backgroundType": "video", + "customGradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)" + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "align": "center", + "content": "Cover!", + "dropCap": false, + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "originalContent": "<p class=\"has-text-align-center has-large-font-size\">Cover!</p>" + } + ], + "originalContent": "<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json new file mode 100644 index 00000000000000..3ad05dacbf1257 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json @@ -0,0 +1,41 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "dimRatio": 70, + "backgroundType": "video", + "customGradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)" + }, + "innerBlocks": [ + { + "blockName": "core/paragraph", + "attrs": { + "align": "center", + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t", + "innerContent": [ + "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t" + ] + } + ], + "innerHTML": "\n<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", + "innerContent": [ + "\n<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", + null, + "\n\t</div>\n</div>\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html new file mode 100644 index 00000000000000..2bc567b4bf2e03 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html @@ -0,0 +1,5 @@ +<!-- wp:cover {"url":"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=","dimRatio":70,"backgroundType":"video","customGradient":"linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"} --> +<div class="wp-block-cover has-background-dim-70 has-background-dim has-background-gradient"><span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"></span><video class="wp-block-cover__video-background" autoplay muted loop src="data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="></video><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> +<p class="has-text-align-center has-large-font-size">Cover!</p> +<!-- /wp:paragraph --></div></div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html new file mode 100644 index 00000000000000..e3e7b9af44777a --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html @@ -0,0 +1,9 @@ +<!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"} --> +<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"> + <div class="wp-block-cover__inner-container"> + <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> + <p class="has-text-align-center has-large-font-size">Cover!</p> + <!-- /wp:paragraph --> + </div> +</div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json new file mode 100644 index 00000000000000..c280fe63d55ab1 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json @@ -0,0 +1,30 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "hasParallax": false, + "dimRatio": 50, + "backgroundType": "image", + "customGradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)" + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "align": "center", + "content": "Cover!", + "dropCap": false, + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "originalContent": "<p class=\"has-text-align-center has-large-font-size\">Cover!</p>" + } + ], + "originalContent": "<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json new file mode 100644 index 00000000000000..423586ba2681e6 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json @@ -0,0 +1,38 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "customGradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)" + }, + "innerBlocks": [ + { + "blockName": "core/paragraph", + "attrs": { + "align": "center", + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t", + "innerContent": [ + "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t" + ] + } + ], + "innerHTML": "\n<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", + "innerContent": [ + "\n<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", + null, + "\n\t</div>\n</div>\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html new file mode 100644 index 00000000000000..92615e65131f9b --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html @@ -0,0 +1,5 @@ +<!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"} --> +<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> +<p class="has-text-align-center has-large-font-size">Cover!</p> +<!-- /wp:paragraph --></div></div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html index c88644e748ebf8..0ad94205cbce05 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html @@ -1,2 +1,2 @@ -<!-- wp:navigation-menu-item {"label":"WordPress","destination":"https://wordpress.org/"} --> +<!-- wp:navigation-menu-item {"label":"WordPress","url":"https://wordpress.org/"} --> <!-- /wp:navigation-menu-item --> diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json index eb71bb8b929c4b..4e5ae943cb9b4a 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json @@ -5,9 +5,9 @@ "isValid": true, "attributes": { "label": "WordPress", - "destination": "https://wordpress.org/", "nofollow": false, - "opensInNewTab": false + "opensInNewTab": false, + "url": "https://wordpress.org/" }, "innerBlocks": [], "originalContent": "" diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json index 8fa4f5340bb83d..2b03a8420038b8 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json @@ -3,7 +3,7 @@ "blockName": "core/navigation-menu-item", "attrs": { "label": "WordPress", - "destination": "https://wordpress.org/" + "url": "https://wordpress.org/" }, "innerBlocks": [], "innerHTML": "\n", diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html index b5176129ef2460..ecf1f0ce7ad654 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html @@ -1 +1 @@ -<!-- wp:navigation-menu-item {"label":"WordPress","destination":"https://wordpress.org/"} /--> +<!-- wp:navigation-menu-item {"label":"WordPress","url":"https://wordpress.org/"} /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.html b/packages/e2e-tests/fixtures/blocks/core__site-title.html new file mode 100644 index 00000000000000..3c42ebc0d2feb7 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.html @@ -0,0 +1 @@ +<!-- wp:site-title /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.json b/packages/e2e-tests/fixtures/blocks/core__site-title.json new file mode 100644 index 00000000000000..6070316cf41796 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.json @@ -0,0 +1,10 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/site-title", + "isValid": true, + "attributes": {}, + "innerBlocks": [], + "originalContent": "" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json b/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json new file mode 100644 index 00000000000000..bc570f8255a124 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json @@ -0,0 +1,18 @@ +[ + { + "blockName": "core/site-title", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html b/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html new file mode 100644 index 00000000000000..3c42ebc0d2feb7 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html @@ -0,0 +1 @@ +<!-- wp:site-title /--> diff --git a/packages/e2e-tests/jest.config.js b/packages/e2e-tests/jest.config.js index 2720488c7b36de..22bccf74e3d1a1 100644 --- a/packages/e2e-tests/jest.config.js +++ b/packages/e2e-tests/jest.config.js @@ -12,6 +12,6 @@ module.exports = { testPathIgnorePatterns: [ '/node_modules/', '/wordpress/', - 'e2e-tests/specs/performance.test.js', + 'e2e-tests/specs/performance/', ], }; diff --git a/packages/e2e-tests/jest.performance.config.js b/packages/e2e-tests/jest.performance.config.js index f8fe4cf8ff1ff6..cc011820f08871 100644 --- a/packages/e2e-tests/jest.performance.config.js +++ b/packages/e2e-tests/jest.performance.config.js @@ -1,7 +1,7 @@ module.exports = { ...require( '@wordpress/scripts/config/jest-e2e.config' ), testMatch: [ - '**/performance.test.js', + '**/performance/*.test.js', ], setupFiles: [ '<rootDir>/config/gutenberg-phase.js', diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index 1fe2ee6a9464ba..b3a75cf9f73145 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "1.7.0", + "version": "1.7.3", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -26,6 +26,7 @@ "@wordpress/jest-console": "file:../jest-console", "@wordpress/jest-puppeteer-axe": "file:../jest-puppeteer-axe", "@wordpress/scripts": "file:../scripts", + "@wordpress/url": "file:../url", "expect-puppeteer": "^4.3.0", "lodash": "^4.17.15", "uuid": "^3.3.2" diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/button.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/button.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/button.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/button.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/classic.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/classic.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/classic.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/classic.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/code.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/code.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/code.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/code.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/group.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/group.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/heading.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/heading.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/heading.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/heading.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/html.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/html.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/html.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/html.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap similarity index 98% rename from packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap index 001c5b93e0edd3..b1e178aa10b710 100644 --- a/packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap @@ -80,6 +80,12 @@ exports[`List can undo asterisk transform 1`] = ` <!-- /wp:paragraph -->" `; +exports[`List first empty list item is graciously removed 1`] = ` +"<!-- wp:list --> +<ul><li>2</li></ul> +<!-- /wp:list -->" +`; + exports[`List should be immeadiately saved on indentation 1`] = ` "<!-- wp:list --> <ul><li>one<ul><li></li></ul></li></ul> diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/preformatted.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/preformatted.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/preformatted.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/preformatted.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/quote.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/quote.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/quote.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/quote.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/separator.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/separator.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/separator.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/separator.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/spacer.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/spacer.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/spacer.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/spacer.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/table.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/table.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/button.test.js b/packages/e2e-tests/specs/editor/blocks/button.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/button.test.js rename to packages/e2e-tests/specs/editor/blocks/button.test.js diff --git a/packages/e2e-tests/specs/blocks/classic.test.js b/packages/e2e-tests/specs/editor/blocks/classic.test.js similarity index 95% rename from packages/e2e-tests/specs/blocks/classic.test.js rename to packages/e2e-tests/specs/editor/blocks/classic.test.js index 29d1605f0874b5..29170335d900f1 100644 --- a/packages/e2e-tests/specs/blocks/classic.test.js +++ b/packages/e2e-tests/specs/editor/blocks/classic.test.js @@ -49,7 +49,7 @@ describe( 'Classic', () => { // Wait for media modal to appear and upload image. await page.waitForSelector( '.media-modal input[type=file]' ); const inputElement = await page.$( '.media-modal input[type=file]' ); - const testImagePath = path.join( __dirname, '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); + const testImagePath = path.join( __dirname, '..', '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); diff --git a/packages/e2e-tests/specs/blocks/code.test.js b/packages/e2e-tests/specs/editor/blocks/code.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/code.test.js rename to packages/e2e-tests/specs/editor/blocks/code.test.js diff --git a/packages/e2e-tests/specs/blocks/columns.test.js b/packages/e2e-tests/specs/editor/blocks/columns.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/columns.test.js rename to packages/e2e-tests/specs/editor/blocks/columns.test.js diff --git a/packages/e2e-tests/specs/blocks/group.test.js b/packages/e2e-tests/specs/editor/blocks/group.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/group.test.js rename to packages/e2e-tests/specs/editor/blocks/group.test.js diff --git a/packages/e2e-tests/specs/blocks/heading.test.js b/packages/e2e-tests/specs/editor/blocks/heading.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/heading.test.js rename to packages/e2e-tests/specs/editor/blocks/heading.test.js diff --git a/packages/e2e-tests/specs/blocks/html.test.js b/packages/e2e-tests/specs/editor/blocks/html.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/html.test.js rename to packages/e2e-tests/specs/editor/blocks/html.test.js diff --git a/packages/e2e-tests/specs/blocks/list.test.js b/packages/e2e-tests/specs/editor/blocks/list.test.js similarity index 97% rename from packages/e2e-tests/specs/blocks/list.test.js rename to packages/e2e-tests/specs/editor/blocks/list.test.js index 7fa889baa0cdd3..9e3086295413e9 100644 --- a/packages/e2e-tests/specs/blocks/list.test.js +++ b/packages/e2e-tests/specs/editor/blocks/list.test.js @@ -478,4 +478,16 @@ describe( 'List', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + + it( 'first empty list item is graciously removed', async () => { + await clickBlockAppender(); + await page.keyboard.type( '* 1' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( '2' ); + await page.keyboard.press( 'ArrowUp' ); + await page.keyboard.press( 'Backspace' ); + await page.keyboard.press( 'Backspace' ); + + expect( await getEditedPostContent() ).toMatchSnapshot(); + } ); } ); diff --git a/packages/e2e-tests/specs/blocks/preformatted.test.js b/packages/e2e-tests/specs/editor/blocks/preformatted.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/preformatted.test.js rename to packages/e2e-tests/specs/editor/blocks/preformatted.test.js diff --git a/packages/e2e-tests/specs/blocks/quote.test.js b/packages/e2e-tests/specs/editor/blocks/quote.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/quote.test.js rename to packages/e2e-tests/specs/editor/blocks/quote.test.js diff --git a/packages/e2e-tests/specs/blocks/separator.test.js b/packages/e2e-tests/specs/editor/blocks/separator.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/separator.test.js rename to packages/e2e-tests/specs/editor/blocks/separator.test.js diff --git a/packages/e2e-tests/specs/blocks/spacer.test.js b/packages/e2e-tests/specs/editor/blocks/spacer.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/spacer.test.js rename to packages/e2e-tests/specs/editor/blocks/spacer.test.js diff --git a/packages/e2e-tests/specs/blocks/table.test.js b/packages/e2e-tests/specs/editor/blocks/table.test.js similarity index 94% rename from packages/e2e-tests/specs/blocks/table.test.js rename to packages/e2e-tests/specs/editor/blocks/table.test.js index 15267da90cb185..790ba0cd1ad7d6 100644 --- a/packages/e2e-tests/specs/blocks/table.test.js +++ b/packages/e2e-tests/specs/editor/blocks/table.test.js @@ -70,7 +70,7 @@ describe( 'Table', () => { await clickButton( createButtonLabel ); // Click the first cell and add some text. - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); await page.keyboard.type( 'This' ); // Tab to the next cell and add some text. @@ -114,13 +114,13 @@ describe( 'Table', () => { await headerSwitch[ 0 ].click(); await footerSwitch[ 0 ].click(); - await page.click( 'thead .wp-block-table__cell-content' ); + await page.click( 'thead th' ); await page.keyboard.type( 'header' ); - await page.click( 'tbody .wp-block-table__cell-content' ); + await page.click( 'tbody td' ); await page.keyboard.type( 'body' ); - await page.click( 'tfoot .wp-block-table__cell-content' ); + await page.click( 'tfoot td' ); await page.keyboard.type( 'footer' ); // Expect the table to have a header, body and footer with written content. @@ -146,7 +146,7 @@ describe( 'Table', () => { await headerSwitch[ 0 ].click(); await footerSwitch[ 0 ].click(); - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); // Add a column. await clickBlockToolbarButton( 'Edit table' ); @@ -155,7 +155,7 @@ describe( 'Table', () => { // Expect the table to have 3 columns across the header, body and footer. expect( await getEditedPostContent() ).toMatchSnapshot(); - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); // Delete a column. await clickBlockToolbarButton( 'Edit table' ); @@ -177,7 +177,7 @@ describe( 'Table', () => { await clickButton( createButtonLabel ); // Click the first cell and add some text. Don't align. - const cells = await page.$$( '.wp-block-table__cell-content' ); + const cells = await page.$$( 'td,th' ); await cells[ 0 ].click(); await page.keyboard.type( 'None' ); @@ -212,7 +212,7 @@ describe( 'Table', () => { await fixedWidthSwitch.click(); // Add multiple new lines to the first cell to make it taller. - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); await page.keyboard.type( '\n\n\n\n' ); // Get the bounding client rect for the second cell. diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/align-hook.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/align-hook.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/container-blocks.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/container-blocks.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/cpt-locking.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/cpt-locking.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/deprecated-node-matcher.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/deprecated-node-matcher.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/deprecated-node-matcher.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/deprecated-node-matcher.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/format-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/format-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/format-api.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/format-api.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/hooks-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/hooks-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/hooks-api.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/hooks-api.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/meta-attribute-block.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/meta-attribute-block.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/meta-attribute-block.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/meta-attribute-block.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/plugins-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/plugins-api.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/templates.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/templates.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/wp-editor-meta-box.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/wp-editor-meta-box.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/align-hook.test.js b/packages/e2e-tests/specs/editor/plugins/align-hook.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/align-hook.test.js rename to packages/e2e-tests/specs/editor/plugins/align-hook.test.js diff --git a/packages/e2e-tests/specs/plugins/allowed-blocks.test.js b/packages/e2e-tests/specs/editor/plugins/allowed-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/allowed-blocks.test.js rename to packages/e2e-tests/specs/editor/plugins/allowed-blocks.test.js diff --git a/packages/e2e-tests/specs/plugins/annotations.test.js b/packages/e2e-tests/specs/editor/plugins/annotations.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/annotations.test.js rename to packages/e2e-tests/specs/editor/plugins/annotations.test.js diff --git a/packages/e2e-tests/specs/plugins/block-icons.test.js b/packages/e2e-tests/specs/editor/plugins/block-icons.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/block-icons.test.js rename to packages/e2e-tests/specs/editor/plugins/block-icons.test.js diff --git a/packages/e2e-tests/specs/plugins/container-blocks.test.js b/packages/e2e-tests/specs/editor/plugins/container-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/container-blocks.test.js rename to packages/e2e-tests/specs/editor/plugins/container-blocks.test.js diff --git a/packages/e2e-tests/specs/plugins/cpt-locking.test.js b/packages/e2e-tests/specs/editor/plugins/cpt-locking.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/cpt-locking.test.js rename to packages/e2e-tests/specs/editor/plugins/cpt-locking.test.js diff --git a/packages/e2e-tests/specs/plugins/custom-taxonomies.test.js b/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/custom-taxonomies.test.js rename to packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js diff --git a/packages/e2e-tests/specs/plugins/deprecated-node-matcher.test.js b/packages/e2e-tests/specs/editor/plugins/deprecated-node-matcher.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/deprecated-node-matcher.test.js rename to packages/e2e-tests/specs/editor/plugins/deprecated-node-matcher.test.js diff --git a/packages/e2e-tests/specs/plugins/format-api.test.js b/packages/e2e-tests/specs/editor/plugins/format-api.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/format-api.test.js rename to packages/e2e-tests/specs/editor/plugins/format-api.test.js diff --git a/packages/e2e-tests/specs/plugins/hooks-api.test.js b/packages/e2e-tests/specs/editor/plugins/hooks-api.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/hooks-api.test.js rename to packages/e2e-tests/specs/editor/plugins/hooks-api.test.js diff --git a/packages/e2e-tests/specs/plugins/inner-blocks-allowed-blocks.test.js b/packages/e2e-tests/specs/editor/plugins/inner-blocks-allowed-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/inner-blocks-allowed-blocks.test.js rename to packages/e2e-tests/specs/editor/plugins/inner-blocks-allowed-blocks.test.js diff --git a/packages/e2e-tests/specs/plugins/innerblocks-locking-all-embed.js b/packages/e2e-tests/specs/editor/plugins/innerblocks-locking-all-embed.js similarity index 100% rename from packages/e2e-tests/specs/plugins/innerblocks-locking-all-embed.js rename to packages/e2e-tests/specs/editor/plugins/innerblocks-locking-all-embed.js diff --git a/packages/e2e-tests/specs/plugins/meta-attribute-block.test.js b/packages/e2e-tests/specs/editor/plugins/meta-attribute-block.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/meta-attribute-block.test.js rename to packages/e2e-tests/specs/editor/plugins/meta-attribute-block.test.js diff --git a/packages/e2e-tests/specs/plugins/meta-boxes.test.js b/packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/meta-boxes.test.js rename to packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js diff --git a/packages/e2e-tests/specs/plugins/nonce.test.js b/packages/e2e-tests/specs/editor/plugins/nonce.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/nonce.test.js rename to packages/e2e-tests/specs/editor/plugins/nonce.test.js diff --git a/packages/e2e-tests/specs/plugins/plugins-api.test.js b/packages/e2e-tests/specs/editor/plugins/plugins-api.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/plugins-api.test.js rename to packages/e2e-tests/specs/editor/plugins/plugins-api.test.js diff --git a/packages/e2e-tests/specs/plugins/templates.test.js b/packages/e2e-tests/specs/editor/plugins/templates.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/templates.test.js rename to packages/e2e-tests/specs/editor/plugins/templates.test.js diff --git a/packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js b/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js similarity index 76% rename from packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js rename to packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js index 74dd45374e946d..32286764092f17 100644 --- a/packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js +++ b/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js @@ -8,9 +8,7 @@ import { publishPost, } from '@wordpress/e2e-test-utils'; -// This test isn't reliable on Travis and fails from time to time. -// See: https://github.com/WordPress/gutenberg/pull/15211. -describe.skip( 'WP Editor Meta Boxes', () => { +describe( 'WP Editor Meta Boxes', () => { beforeAll( async () => { await activatePlugin( 'gutenberg-test-plugin-wp-editor-meta-box' ); await createNewPost(); @@ -25,7 +23,7 @@ describe.skip( 'WP Editor Meta Boxes', () => { await page.type( '.editor-post-title__input', 'Hello Meta' ); // Type something - await page.click( '#test_tinymce_id-html' ); + await expect( page ).toClick( '#test_tinymce_id-html' ); await page.type( '#test_tinymce_id', 'Typing in a metabox' ); await page.click( '#test_tinymce_id-tmce' ); @@ -33,7 +31,8 @@ describe.skip( 'WP Editor Meta Boxes', () => { await page.reload(); - await page.click( '#test_tinymce_id-html' ); + await expect( page ).toClick( '#test_tinymce_id-html' ); + await page.waitForSelector( '#test_tinymce_id' ); const content = await page.$eval( '#test_tinymce_id', ( textarea ) => textarea.value diff --git a/packages/e2e-tests/specs/__snapshots__/adding-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/adding-blocks.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/block-deletion.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-deletion.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/block-deletion.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/block-deletion.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/block-grouping.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/block-grouping.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/compatibility-classic-editor.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/compatibility-classic-editor.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/compatibility-classic-editor.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/compatibility-classic-editor.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/convert-block-type.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/convert-block-type.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/convert-block-type.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/convert-block-type.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/embedding.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/embedding.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/font-size-picker.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/font-size-picker.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/font-size-picker.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/font-size-picker.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/links.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/links.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/mentions.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/mentions.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/mentions.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/mentions.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/multi-block-selection.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/multi-block-selection.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/reusable-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/reusable-blocks.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/rich-text.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/rich-text.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/rtl.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/rtl.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/rtl.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/rtl.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/splitting-merging.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/splitting-merging.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/splitting-merging.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/splitting-merging.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/style-variation.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/style-variation.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/style-variation.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/style-variation.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/undo.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/undo.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/undo.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/undo.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/writing-flow.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/writing-flow.test.js.snap diff --git a/packages/e2e-tests/specs/a11y.test.js b/packages/e2e-tests/specs/editor/various/a11y.test.js similarity index 100% rename from packages/e2e-tests/specs/a11y.test.js rename to packages/e2e-tests/specs/editor/various/a11y.test.js diff --git a/packages/e2e-tests/specs/adding-blocks.test.js b/packages/e2e-tests/specs/editor/various/adding-blocks.test.js similarity index 98% rename from packages/e2e-tests/specs/adding-blocks.test.js rename to packages/e2e-tests/specs/editor/various/adding-blocks.test.js index 56e5976513746d..ea79e31224e8e0 100644 --- a/packages/e2e-tests/specs/adding-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/adding-blocks.test.js @@ -17,7 +17,7 @@ describe( 'adding blocks', () => { /** * Given a Puppeteer ElementHandle, clicks below its bounding box. * - * @param {Puppeteer.ElementHandle} elementHandle Element handle. + * @param {puppeteer.ElementHandle} elementHandle Element handle. * * @return {Promise} Promise resolving when click occurs. */ diff --git a/packages/e2e-tests/specs/adding-inline-tokens.test.js b/packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js similarity index 93% rename from packages/e2e-tests/specs/adding-inline-tokens.test.js rename to packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js index f028a73c3df931..b11077e70fb3d3 100644 --- a/packages/e2e-tests/specs/adding-inline-tokens.test.js +++ b/packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js @@ -33,7 +33,7 @@ describe( 'adding inline tokens', () => { // Wait for media modal to appear and upload image. await page.waitForSelector( '.media-modal input[type=file]' ); const inputElement = await page.$( '.media-modal input[type=file]' ); - const testImagePath = path.join( __dirname, '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); + const testImagePath = path.join( __dirname, '..', '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); diff --git a/packages/e2e-tests/specs/autosave.test.js b/packages/e2e-tests/specs/editor/various/autosave.test.js similarity index 77% rename from packages/e2e-tests/specs/autosave.test.js rename to packages/e2e-tests/specs/editor/various/autosave.test.js index 9f97f0f1c3f291..3c966f15a0748d 100644 --- a/packages/e2e-tests/specs/autosave.test.js +++ b/packages/e2e-tests/specs/editor/various/autosave.test.js @@ -17,13 +17,22 @@ const AUTOSAVE_INTERVAL_SECONDS = 5; const AUTOSAVE_NOTICE_REMOTE = 'There is an autosave of this post that is more recent than the version below.'; const AUTOSAVE_NOTICE_LOCAL = 'The backup of this post in your browser is different from the version below.'; +// Save and wait for "Saved" to confirm save complete. Preserves focus in the +// editing area. async function saveDraftWithKeyboard() { - return pressKeyWithModifier( 'primary', 's' ); + await page.waitForSelector( '.editor-post-save-draft' ); + await Promise.all( [ + page.waitForSelector( '.editor-post-saved-state.is-saved' ), + pressKeyWithModifier( 'primary', 'S' ), + ] ); } async function sleep( durationInSeconds ) { - return new Promise( ( resolve ) => - setTimeout( resolve, durationInSeconds * 1000 ) ); + // Rule `no-restricted-syntax` recommends `waitForSelector` against + // `waitFor`, which isn't apt for the use case, when provided an integer, + // of waiting for a given amount of time. + // eslint-disable-next-line no-restricted-syntax + await page.waitFor( durationInSeconds * 1000 ); } async function clearSessionStorage() { @@ -153,11 +162,11 @@ describe( 'autosave', () => { } ); it( 'should clear local autosave after successful remote autosave', async () => { + // Edit, save draft, edit again await clickBlockAppender(); await page.keyboard.type( 'before save' ); - await saveDraft(); - - await page.keyboard.type( 'after save' ); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); // Trigger local autosave await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); @@ -169,21 +178,52 @@ describe( 'autosave', () => { } ); it( 'shouldn\'t clear local autosave if remote autosave fails', async () => { + // Edit, save draft, edit again await clickBlockAppender(); await page.keyboard.type( 'before save' ); - await saveDraft(); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); - await page.keyboard.type( 'after save' ); + // Trigger local autosave await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + // Bring network down and attempt to autosave remotely toggleOfflineMode( true ); - - // Trigger remote autosave await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).autosave() ); expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + } ); - toggleOfflineMode( false ); + it( 'should clear local autosave after successful save', async () => { + // Edit, save draft, edit again + await clickBlockAppender(); + await page.keyboard.type( 'before save' ); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); + + // Trigger local autosave + await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + + await saveDraftWithKeyboard(); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 0 ); + } ); + + it( 'shouldn\'t clear local autosave if save fails', async () => { + // Edit, save draft, edit again + await clickBlockAppender(); + await page.keyboard.type( 'before save' ); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); + + // Trigger local autosave + await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + + // Bring network down and attempt to save + toggleOfflineMode( true ); + saveDraftWithKeyboard(); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); } ); it( 'shouldn\'t conflict with server-side autosave', async () => { @@ -221,7 +261,8 @@ describe( 'autosave', () => { expect( notice ).toContain( AUTOSAVE_NOTICE_REMOTE ); } ); - afterAll( async () => { + afterEach( async () => { + toggleOfflineMode( false ); await clearSessionStorage(); } ); } ); diff --git a/packages/e2e-tests/specs/block-deletion.test.js b/packages/e2e-tests/specs/editor/various/block-deletion.test.js similarity index 100% rename from packages/e2e-tests/specs/block-deletion.test.js rename to packages/e2e-tests/specs/editor/various/block-deletion.test.js diff --git a/packages/e2e-tests/specs/block-grouping.test.js b/packages/e2e-tests/specs/editor/various/block-grouping.test.js similarity index 100% rename from packages/e2e-tests/specs/block-grouping.test.js rename to packages/e2e-tests/specs/editor/various/block-grouping.test.js diff --git a/packages/e2e-tests/specs/block-hierarchy-navigation.test.js b/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js similarity index 99% rename from packages/e2e-tests/specs/block-hierarchy-navigation.test.js rename to packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js index 2dc5dc1f6cc544..efba2e1d6afc5e 100644 --- a/packages/e2e-tests/specs/block-hierarchy-navigation.test.js +++ b/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js @@ -82,6 +82,7 @@ describe( 'Navigating the block hierarchy', () => { await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); + await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyTimes( 'Tab', 4 ); // Tweak the columns count by increasing it by one. diff --git a/packages/e2e-tests/specs/block-mover.test.js b/packages/e2e-tests/specs/editor/various/block-mover.test.js similarity index 100% rename from packages/e2e-tests/specs/block-mover.test.js rename to packages/e2e-tests/specs/editor/various/block-mover.test.js diff --git a/packages/e2e-tests/specs/block-switcher.test.js b/packages/e2e-tests/specs/editor/various/block-switcher.test.js similarity index 100% rename from packages/e2e-tests/specs/block-switcher.test.js rename to packages/e2e-tests/specs/editor/various/block-switcher.test.js diff --git a/packages/e2e-tests/specs/change-detection.test.js b/packages/e2e-tests/specs/editor/various/change-detection.test.js similarity index 100% rename from packages/e2e-tests/specs/change-detection.test.js rename to packages/e2e-tests/specs/editor/various/change-detection.test.js diff --git a/packages/e2e-tests/specs/compatibility-classic-editor.test.js b/packages/e2e-tests/specs/editor/various/compatibility-classic-editor.test.js similarity index 100% rename from packages/e2e-tests/specs/compatibility-classic-editor.test.js rename to packages/e2e-tests/specs/editor/various/compatibility-classic-editor.test.js diff --git a/packages/e2e-tests/specs/convert-block-type.test.js b/packages/e2e-tests/specs/editor/various/convert-block-type.test.js similarity index 100% rename from packages/e2e-tests/specs/convert-block-type.test.js rename to packages/e2e-tests/specs/editor/various/convert-block-type.test.js diff --git a/packages/e2e-tests/specs/datepicker.test.js b/packages/e2e-tests/specs/editor/various/datepicker.test.js similarity index 100% rename from packages/e2e-tests/specs/datepicker.test.js rename to packages/e2e-tests/specs/editor/various/datepicker.test.js diff --git a/packages/e2e-tests/specs/editor-modes.test.js b/packages/e2e-tests/specs/editor/various/editor-modes.test.js similarity index 100% rename from packages/e2e-tests/specs/editor-modes.test.js rename to packages/e2e-tests/specs/editor/various/editor-modes.test.js diff --git a/packages/e2e-tests/specs/embedding.test.js b/packages/e2e-tests/specs/editor/various/embedding.test.js similarity index 87% rename from packages/e2e-tests/specs/embedding.test.js rename to packages/e2e-tests/specs/editor/various/embedding.test.js index 878e540967a4f1..0a986702075bec 100644 --- a/packages/e2e-tests/specs/embedding.test.js +++ b/packages/e2e-tests/specs/editor/various/embedding.test.js @@ -271,33 +271,4 @@ describe( 'Embedding content', () => { // Check the block has become a WordPress block. await page.waitForSelector( '.wp-block-embed-wordpress' ); } ); - - it.skip( 'should transform from video to embed block when YouTube URL is pasted', async () => { - await clickBlockAppender(); - await insertBlock( 'Video' ); - await page.click( '.editor-media-placeholder__url-input-container button' ); - await page.keyboard.type( 'https://www.youtube.com/watch?v=lXMskKTw3Bc' ); - await page.keyboard.press( 'Enter' ); - await page.waitForSelector( '.wp-block-embed-youtube' ); - } ); - - it.skip( 'should transform from image to embed block when Instagram URL is pasted', async () => { - await clickBlockAppender(); - await page.keyboard.type( '/image' ); - await page.keyboard.press( 'Enter' ); - await page.click( '.editor-media-placeholder__url-input-container button' ); - await page.keyboard.type( 'https://www.instagram.com/p/Bvl97o2AK6x/' ); - await page.keyboard.press( 'Enter' ); - await page.waitForSelector( '.wp-block-embed-instagram' ); - } ); - - it.skip( 'should transform from audio to embed block when Soundcloud URL is pasted', async () => { - await clickBlockAppender(); - await page.keyboard.type( '/audio' ); - await page.keyboard.press( 'Enter' ); - await page.click( '.editor-media-placeholder__url-input-container button' ); - await page.keyboard.type( 'https://soundcloud.com/a-boogie-wit-da-hoodie/swervin' ); - await page.keyboard.press( 'Enter' ); - await page.waitForSelector( '.wp-block-embed-soundcloud' ); - } ); } ); diff --git a/packages/e2e-tests/specs/font-size-picker.test.js b/packages/e2e-tests/specs/editor/various/font-size-picker.test.js similarity index 97% rename from packages/e2e-tests/specs/font-size-picker.test.js rename to packages/e2e-tests/specs/editor/various/font-size-picker.test.js index a80a81b46442d3..0fb98caa4f5d29 100644 --- a/packages/e2e-tests/specs/font-size-picker.test.js +++ b/packages/e2e-tests/specs/editor/various/font-size-picker.test.js @@ -75,8 +75,8 @@ describe( 'Font Size Picker', () => { // Clear the custom font size input. await page.click( '.blocks-font-size .components-range-control__number' ); - await pressKeyTimes( 'ArrowRight', 4 ); - await pressKeyTimes( 'Backspace', 4 ); + await pressKeyTimes( 'ArrowRight', 5 ); + await pressKeyTimes( 'Backspace', 5 ); // Ensure content matches snapshot. const content = await getEditedPostContent(); diff --git a/packages/e2e-tests/specs/fullscreen-mode.test.js b/packages/e2e-tests/specs/editor/various/fullscreen-mode.test.js similarity index 100% rename from packages/e2e-tests/specs/fullscreen-mode.test.js rename to packages/e2e-tests/specs/editor/various/fullscreen-mode.test.js diff --git a/packages/e2e-tests/specs/invalid-block.test.js b/packages/e2e-tests/specs/editor/various/invalid-block.test.js similarity index 100% rename from packages/e2e-tests/specs/invalid-block.test.js rename to packages/e2e-tests/specs/editor/various/invalid-block.test.js diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/keyboard-navigable-blocks.test.js rename to packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js diff --git a/packages/e2e-tests/specs/links.test.js b/packages/e2e-tests/specs/editor/various/links.test.js similarity index 80% rename from packages/e2e-tests/specs/links.test.js rename to packages/e2e-tests/specs/editor/various/links.test.js index f7e78a7b68a1e2..ce9aaeab186799 100644 --- a/packages/e2e-tests/specs/links.test.js +++ b/packages/e2e-tests/specs/editor/various/links.test.js @@ -266,87 +266,6 @@ describe( 'Links', () => { 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.skip( '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. - await createNewPost(); - await clickBlockAppender(); - await page.keyboard.type( 'This is Gutenberg' ); - await pressKeyWithModifier( 'shiftAlt', 'ArrowLeft' ); - await page.click( 'button[aria-label="Link"]' ); - - // Wait for the URL field to auto-focus - await waitForAutoFocus(); - - await page.keyboard.type( titleText ); - const suggestionXPath = `//*[contains(@class, "block-editor-url-input__suggestion")]//button[contains(text(), '${ titleText }')]`; - await page.waitForXPath( suggestionXPath ); - const autocompleteSuggestions = await page.$x( suggestionXPath ); - - // Expect there to be some autocomplete suggestions. - expect( autocompleteSuggestions ).toHaveLength( 1 ); - - const firstSuggestion = autocompleteSuggestions[ 0 ]; - - // Expect that clicking on the autocomplete suggestion doesn't dismiss the link popover. - await firstSuggestion.click(); - expect( await page.$( '.block-editor-url-popover' ) ).not.toBeNull(); - - // Expect the url input value to have been updated with the post url. - const inputValue = await page.evaluate( () => document.querySelector( '.block-editor-url-input input[aria-label="URL"]' ).value ); - expect( inputValue ).toEqual( postURL ); - - // Expect the link to apply correctly. - // Note - have avoided using snapshots here since the link url can't be determined ahead of time. - await page.click( 'button[aria-label="Apply"]' ); - const linkHref = await page.evaluate( () => document.querySelector( '.block-editor-format-toolbar__link-container-value' ).href ); - expect( linkHref ).toEqual( postURL ); - } ); - - // Test for regressions of https://github.com/WordPress/gutenberg/issues/10496. - // This test isn't reliable on Travis and fails from time to time. - // See: https://github.com/WordPress/gutenberg/pull/15211. - it.skip( 'allows autocomplete suggestions to be navigated with the keyboard', async () => { - const titleText = 'Test post keyboard'; - const postURL = await createPostWithTitle( titleText ); - - await createNewPost(); - 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 pressKeyWithModifier( 'shiftAlt', 'ArrowLeft' ); - - // Press Cmd+K to insert a link - await pressKeyWithModifier( 'primary', 'K' ); - - // Wait for the URL field to auto-focus - await waitForAutoFocus(); - - await page.keyboard.type( titleText ); - await page.waitForSelector( '.block-editor-url-input__suggestion' ); - const autocompleteSuggestions = await page.$x( `//*[contains(@class, "block-editor-url-input__suggestion")]//button[contains(text(), '${ titleText }')]` ); - - // Expect there to be some autocomplete suggestions. - expect( autocompleteSuggestions ).toHaveLength( 1 ); - - // 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( '.block-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( '.block-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 ); diff --git a/packages/e2e-tests/specs/manage-reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js similarity index 93% rename from packages/e2e-tests/specs/manage-reusable-blocks.test.js rename to packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js index 37340d669f5a74..9d17922f519f39 100644 --- a/packages/e2e-tests/specs/manage-reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js @@ -32,7 +32,7 @@ describe( 'Managing reusable blocks', () => { await importButton.click(); // Select the file to upload - const testReusableBlockFile = path.join( __dirname, '..', 'assets', 'greeting-reusable-block.json' ); + const testReusableBlockFile = path.join( __dirname, '..', '..', '..', 'assets', 'greeting-reusable-block.json' ); const input = await page.$( '.list-reusable-blocks-import-form input' ); await input.uploadFile( testReusableBlockFile ); diff --git a/packages/e2e-tests/specs/mentions.test.js b/packages/e2e-tests/specs/editor/various/mentions.test.js similarity index 100% rename from packages/e2e-tests/specs/mentions.test.js rename to packages/e2e-tests/specs/editor/various/mentions.test.js diff --git a/packages/e2e-tests/specs/multi-block-selection.test.js b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js similarity index 100% rename from packages/e2e-tests/specs/multi-block-selection.test.js rename to packages/e2e-tests/specs/editor/various/multi-block-selection.test.js diff --git a/packages/e2e-tests/specs/navigable-toolbar.test.js b/packages/e2e-tests/specs/editor/various/navigable-toolbar.test.js similarity index 100% rename from packages/e2e-tests/specs/navigable-toolbar.test.js rename to packages/e2e-tests/specs/editor/various/navigable-toolbar.test.js diff --git a/packages/e2e-tests/specs/new-post-default-content.test.js b/packages/e2e-tests/specs/editor/various/new-post-default-content.test.js similarity index 100% rename from packages/e2e-tests/specs/new-post-default-content.test.js rename to packages/e2e-tests/specs/editor/various/new-post-default-content.test.js diff --git a/packages/e2e-tests/specs/new-post.test.js b/packages/e2e-tests/specs/editor/various/new-post.test.js similarity index 100% rename from packages/e2e-tests/specs/new-post.test.js rename to packages/e2e-tests/specs/editor/various/new-post.test.js diff --git a/packages/e2e-tests/specs/nux.test.js b/packages/e2e-tests/specs/editor/various/nux.test.js similarity index 56% rename from packages/e2e-tests/specs/nux.test.js rename to packages/e2e-tests/specs/editor/various/nux.test.js index 659263cea35335..d3ca54af511763 100644 --- a/packages/e2e-tests/specs/nux.test.js +++ b/packages/e2e-tests/specs/editor/various/nux.test.js @@ -2,10 +2,7 @@ * WordPress dependencies */ import { - clickBlockAppender, - clickOnMoreMenuItem, createNewPost, - saveDraft, toggleScreenOption, } from '@wordpress/e2e-test-utils'; @@ -110,71 +107,4 @@ describe( 'New User Experience (NUX)', () => { areTipsEnabled = await getTipsEnabled( page ); expect( areTipsEnabled ).toEqual( true ); } ); - - // TODO: This test should be enabled once - // https://github.com/WordPress/gutenberg/issues/7458 is fixed. - it.skip( 'should show tips as disabled if all tips have been shown', async () => { - await clickAllTips( page ); - - // Open the "More" menu to check the "Show Tips" element. - await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' ); - const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="false"]' ); - - expect( showTipsButton ).toHaveLength( 1 ); - } ); - - // TODO: This test should be enabled once - // https://github.com/WordPress/gutenberg/issues/7458 is fixed. - it.skip( 'should reset tips if all tips have been shown and show tips was unchecked', async () => { - const { numberOfTips } = await clickAllTips( page ); - - // Click again to re-enable tips; they should appear. - await clickOnMoreMenuItem( 'Show Tips' ); - - // Open the "More" menu to check the "Show Tips" element. - await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' ); - const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="true"]' ); - - expect( showTipsButton ).toHaveLength( 1 ); - - // Tips should re-appear on the page. - const nuxTipElements = await page.$$( '.nux-dot-tip' ); - expect( nuxTipElements ).toHaveLength( 1 ); - - // Tips should be enabled again. - const areTipsEnabled = await getTipsEnabled( page ); - expect( areTipsEnabled ).toEqual( true ); - - // Dismissed tips should be reset and ready to be shown again. - const resetTips = await getTips( page ); - const newNumberOfTips = resetTips.tipIds.length; - expect( newNumberOfTips ).toHaveLength( numberOfTips ); - } ); - - // TODO: This test should be enabled once - // https://github.com/WordPress/gutenberg/issues/7753 is fixed. - // See: https://github.com/WordPress/gutenberg/issues/7753#issuecomment-403952816 - it.skip( 'should show tips if "Show tips" was disabled on a draft and then enabled', async () => { - // Click the "Show tips" button (enabled by default) to disable tips. - await clickOnMoreMenuItem( 'Show Tips' ); - - // Let's type something so there's content in this post. - await page.click( '.editor-post-title__input' ); - await page.keyboard.type( 'Post title' ); - await clickBlockAppender(); - await page.keyboard.type( 'Post content goes here.' ); - await saveDraft(); - - // Refresh the page; tips should be disabled. - await page.reload(); - let nuxTipElements = await page.$$( '.nux-dot-tip' ); - expect( nuxTipElements ).toHaveLength( 0 ); - - // Clicking should re-enable tips. - await clickOnMoreMenuItem( 'Show Tips' ); - - // Tips should re-appear on the page. - nuxTipElements = await page.$$( '.nux-dot-tip' ); - expect( nuxTipElements ).toHaveLength( 1 ); - } ); } ); diff --git a/packages/e2e-tests/specs/popovers.test.js b/packages/e2e-tests/specs/editor/various/popovers.test.js similarity index 100% rename from packages/e2e-tests/specs/popovers.test.js rename to packages/e2e-tests/specs/editor/various/popovers.test.js diff --git a/packages/e2e-tests/specs/post-visibility.test.js b/packages/e2e-tests/specs/editor/various/post-visibility.test.js similarity index 100% rename from packages/e2e-tests/specs/post-visibility.test.js rename to packages/e2e-tests/specs/editor/various/post-visibility.test.js diff --git a/packages/e2e-tests/specs/preferences.test.js b/packages/e2e-tests/specs/editor/various/preferences.test.js similarity index 100% rename from packages/e2e-tests/specs/preferences.test.js rename to packages/e2e-tests/specs/editor/various/preferences.test.js diff --git a/packages/e2e-tests/specs/preview.test.js b/packages/e2e-tests/specs/editor/various/preview.test.js similarity index 100% rename from packages/e2e-tests/specs/preview.test.js rename to packages/e2e-tests/specs/editor/various/preview.test.js diff --git a/packages/e2e-tests/specs/publish-button.test.js b/packages/e2e-tests/specs/editor/various/publish-button.test.js similarity index 100% rename from packages/e2e-tests/specs/publish-button.test.js rename to packages/e2e-tests/specs/editor/various/publish-button.test.js diff --git a/packages/e2e-tests/specs/publish-panel.test.js b/packages/e2e-tests/specs/editor/various/publish-panel.test.js similarity index 100% rename from packages/e2e-tests/specs/publish-panel.test.js rename to packages/e2e-tests/specs/editor/various/publish-panel.test.js diff --git a/packages/e2e-tests/specs/publishing.test.js b/packages/e2e-tests/specs/editor/various/publishing.test.js similarity index 100% rename from packages/e2e-tests/specs/publishing.test.js rename to packages/e2e-tests/specs/editor/various/publishing.test.js diff --git a/packages/e2e-tests/specs/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/reusable-blocks.test.js rename to packages/e2e-tests/specs/editor/various/reusable-blocks.test.js diff --git a/packages/e2e-tests/specs/rich-text.test.js b/packages/e2e-tests/specs/editor/various/rich-text.test.js similarity index 100% rename from packages/e2e-tests/specs/rich-text.test.js rename to packages/e2e-tests/specs/editor/various/rich-text.test.js diff --git a/packages/e2e-tests/specs/rtl.test.js b/packages/e2e-tests/specs/editor/various/rtl.test.js similarity index 100% rename from packages/e2e-tests/specs/rtl.test.js rename to packages/e2e-tests/specs/editor/various/rtl.test.js diff --git a/packages/e2e-tests/specs/scheduling.test.js b/packages/e2e-tests/specs/editor/various/scheduling.test.js similarity index 100% rename from packages/e2e-tests/specs/scheduling.test.js rename to packages/e2e-tests/specs/editor/various/scheduling.test.js diff --git a/packages/e2e-tests/specs/shortcut-help.test.js b/packages/e2e-tests/specs/editor/various/shortcut-help.test.js similarity index 100% rename from packages/e2e-tests/specs/shortcut-help.test.js rename to packages/e2e-tests/specs/editor/various/shortcut-help.test.js diff --git a/packages/e2e-tests/specs/sidebar-permalink-panel.test.js b/packages/e2e-tests/specs/editor/various/sidebar-permalink-panel.test.js similarity index 100% rename from packages/e2e-tests/specs/sidebar-permalink-panel.test.js rename to packages/e2e-tests/specs/editor/various/sidebar-permalink-panel.test.js diff --git a/packages/e2e-tests/specs/sidebar.test.js b/packages/e2e-tests/specs/editor/various/sidebar.test.js similarity index 99% rename from packages/e2e-tests/specs/sidebar.test.js rename to packages/e2e-tests/specs/editor/various/sidebar.test.js index d0768f916f0f63..c86900f308f1e1 100644 --- a/packages/e2e-tests/specs/sidebar.test.js +++ b/packages/e2e-tests/specs/editor/various/sidebar.test.js @@ -91,6 +91,7 @@ describe( 'Sidebar', () => { await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); + await pressKeyWithModifier( 'ctrl', '`' ); // Tab lands at first (presumed selected) option "Document". await page.keyboard.press( 'Tab' ); diff --git a/packages/e2e-tests/specs/splitting-merging.test.js b/packages/e2e-tests/specs/editor/various/splitting-merging.test.js similarity index 100% rename from packages/e2e-tests/specs/splitting-merging.test.js rename to packages/e2e-tests/specs/editor/various/splitting-merging.test.js diff --git a/packages/e2e-tests/specs/style-variation.test.js b/packages/e2e-tests/specs/editor/various/style-variation.test.js similarity index 100% rename from packages/e2e-tests/specs/style-variation.test.js rename to packages/e2e-tests/specs/editor/various/style-variation.test.js diff --git a/packages/e2e-tests/specs/taxonomies.test.js b/packages/e2e-tests/specs/editor/various/taxonomies.test.js similarity index 83% rename from packages/e2e-tests/specs/taxonomies.test.js rename to packages/e2e-tests/specs/editor/various/taxonomies.test.js index 791fd79b12f8d4..4ed0ef3945fe61 100644 --- a/packages/e2e-tests/specs/taxonomies.test.js +++ b/packages/e2e-tests/specs/editor/various/taxonomies.test.js @@ -1,9 +1,14 @@ +/** + * External dependencies + */ +import { random } from 'lodash'; + /** * WordPress dependencies */ import { - findSidebarPanelWithTitle, createNewPost, + findSidebarPanelWithTitle, openDocumentSettingsSidebar, publishPost, } from '@wordpress/e2e-test-utils'; @@ -50,22 +55,25 @@ describe( 'Taxonomies', () => { }, tagsPanel, TAG_TOKEN_SELECTOR ); }; + const openSidebarPanelWithTitle = async ( title ) => { + const panel = await page.waitForXPath( + `//div[contains(@class,"edit-post-sidebar")]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ title }")]` + ); + await panel.click(); + }; + it( 'should be able to open the categories panel and create a new main category if the user has the right capabilities', async () => { await createNewPost(); await openDocumentSettingsSidebar(); - const categoriesPanel = await findSidebarPanelWithTitle( 'Categories' ); - expect( categoriesPanel ).toBeDefined(); + await openSidebarPanelWithTitle( 'Categories' ); // If the user has no permission to add a new category finish the test. if ( ! ( await canCreatTermInTaxonomy( 'categories' ) ) ) { return; } - // Open the categories panel. - await categoriesPanel.click( 'button' ); - await page.waitForSelector( 'button.editor-post-taxonomies__hierarchical-terms-add' ); // Click add new category button. @@ -108,27 +116,18 @@ describe( 'Taxonomies', () => { expect( selectedCategories[ 0 ] ).toEqual( 'z rand category 1' ); } ); - // This test isn't reliable locally because repeated execution of the test triggers 400 network - // because of the tag's duplication. Also, it randomly doesn't add a new tag after pressing enter. - // See: https://github.com/WordPress/gutenberg/pull/15211. - it.skip( 'should be able to open the tags panel and create a new tag if the user has the right capabilities', async () => { + it( 'should be able to open the tags panel and create a new tag if the user has the right capabilities', async () => { await createNewPost(); await openDocumentSettingsSidebar(); - const tagsPanel = await findSidebarPanelWithTitle( 'Tags' ); - - //expect( await page.evaluate( ( el ) => el.outerHTML, tagsPanel ) ).toEqual( 'tag1 ok' ); - expect( tagsPanel ).toBeDefined(); + await openSidebarPanelWithTitle( 'Tags' ); // If the user has no permission to add a new tag finish the test. if ( ! ( await canCreatTermInTaxonomy( 'tags' ) ) ) { return; } - // Open the tags panel. - await tagsPanel.click( 'button' ); - // At the start there are no tag tokens expect( await page.$$( @@ -136,13 +135,16 @@ describe( 'Taxonomies', () => { ) ).toHaveLength( 0 ); + const tagsPanel = await findSidebarPanelWithTitle( 'Tags' ); const tagInput = await tagsPanel.$( '.components-form-token-field__input' ); // Click the tag input field. await tagInput.click(); + const tagName = 'tag-' + random( 1, Number.MAX_SAFE_INTEGER ); + // Type the category name in the field. - await tagInput.type( 'tag1' ); + await tagInput.type( tagName ); // Press enter to create a new tag. await tagInput.press( 'Enter' ); @@ -154,7 +156,7 @@ describe( 'Taxonomies', () => { // The post should only contain the tag we added. expect( tags ).toHaveLength( 1 ); - expect( tags[ 0 ] ).toEqual( 'tag1' ); + expect( tags[ 0 ] ).toEqual( tagName ); // Type something in the title so we can publish the post. await page.type( '.editor-post-title__input', 'Hello World' ); @@ -172,6 +174,6 @@ describe( 'Taxonomies', () => { // The tag selection was persisted after the publish process. expect( tags ).toHaveLength( 1 ); - expect( tags[ 0 ] ).toEqual( 'tag1' ); + expect( tags[ 0 ] ).toEqual( tagName ); } ); } ); diff --git a/packages/e2e-tests/specs/typewriter.test.js b/packages/e2e-tests/specs/editor/various/typewriter.test.js similarity index 100% rename from packages/e2e-tests/specs/typewriter.test.js rename to packages/e2e-tests/specs/editor/various/typewriter.test.js diff --git a/packages/e2e-tests/specs/undo.test.js b/packages/e2e-tests/specs/editor/various/undo.test.js similarity index 100% rename from packages/e2e-tests/specs/undo.test.js rename to packages/e2e-tests/specs/editor/various/undo.test.js diff --git a/packages/e2e-tests/specs/writing-flow.test.js b/packages/e2e-tests/specs/editor/various/writing-flow.test.js similarity index 100% rename from packages/e2e-tests/specs/writing-flow.test.js rename to packages/e2e-tests/specs/editor/various/writing-flow.test.js diff --git a/packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap b/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap similarity index 94% rename from packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap rename to packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap index dbe341ba42e76e..f461a1a4412dec 100644 --- a/packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap +++ b/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap @@ -20,6 +20,30 @@ exports[`Block transforms correctly transform block Cover in fixture core__cover <!-- /wp:image -->" `; +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient into the Image block 1`] = ` +"<!-- wp:image --> +<figure class=\\"wp-block-image\\"><img alt=\\"\\"/></figure> +<!-- /wp:image -->" +`; + +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient into the Video block 1`] = ` +"<!-- wp:video --> +<figure class=\\"wp-block-video\\"></figure> +<!-- /wp:video -->" +`; + +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient-image into the Image block 1`] = ` +"<!-- wp:image --> +<figure class=\\"wp-block-image\\"><img src=\\"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=\\" alt=\\"\\"/></figure> +<!-- /wp:image -->" +`; + +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient-video into the Video block 1`] = ` +"<!-- wp:video --> +<figure class=\\"wp-block-video\\"><video controls src=\\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\\"></video></figure> +<!-- /wp:video -->" +`; + exports[`Block transforms correctly transform block Cover in fixture core__cover__video into the Video block 1`] = ` "<!-- wp:video --> <figure class=\\"wp-block-video\\"><video controls src=\\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\\"></video></figure> diff --git a/packages/e2e-tests/specs/block-transforms.test.js b/packages/e2e-tests/specs/experimental/block-transforms.test.js similarity index 88% rename from packages/e2e-tests/specs/block-transforms.test.js rename to packages/e2e-tests/specs/experimental/block-transforms.test.js index 381facd4c00673..bf6e5027b745e6 100644 --- a/packages/e2e-tests/specs/block-transforms.test.js +++ b/packages/e2e-tests/specs/experimental/block-transforms.test.js @@ -13,18 +13,25 @@ import { * WordPress dependencies */ import { + createNewPost, getAllBlocks, getAvailableBlockTransforms, getBlockSetting, getEditedPostContent, hasBlockSwitcher, - createNewPost, - enableExperimentalFeatures, - setPostContent, selectBlockByClientId, + setPostContent, transformBlockTo, } from '@wordpress/e2e-test-utils'; +/** + * Internal dependencies + */ +import { + enableExperimentalFeatures, + disableExperimentalFeatures, +} from '../../experimental-features'; + /** * Internal dependencies */ @@ -32,8 +39,8 @@ import { getAvailableBlockFixturesBasenames, getBlockFixtureHTML, getBlockFixtureParsedJSON, -} from '../fixtures/'; -import { EXPECTED_TRANSFORMS } from '../fixtures/block-transforms.js'; +} from '../../fixtures/'; +import { EXPECTED_TRANSFORMS } from '../../fixtures/block-transforms.js'; /* * Returns true if the fileBase refers to a fixture of a block @@ -100,7 +107,11 @@ describe( 'Block transforms', () => { const transformStructure = {}; beforeAll( async () => { - await enableExperimentalFeatures( [ '#gutenberg-widget-experiments', '#gutenberg-menu-block' ] ); + await enableExperimentalFeatures( [ + '#gutenberg-widget-experiments', + '#gutenberg-menu-block', + '#gutenberg-full-site-editing', + ] ); await createNewPost(); for ( const fileBase of fileBasenames ) { @@ -116,6 +127,16 @@ describe( 'Block transforms', () => { } } ); + afterAll( + async () => { + await disableExperimentalFeatures( [ + '#gutenberg-widget-experiments', + '#gutenberg-menu-block', + '#gutenberg-full-site-editing', + ] ); + } + ); + it( 'should contain the expected transforms', async () => { const transforms = mapValues( pickBy( diff --git a/packages/e2e-tests/specs/demo.test.js b/packages/e2e-tests/specs/local/demo.test.js similarity index 100% rename from packages/e2e-tests/specs/demo.test.js rename to packages/e2e-tests/specs/local/demo.test.js diff --git a/packages/e2e-tests/specs/.gitignore b/packages/e2e-tests/specs/performance/.gitignore similarity index 100% rename from packages/e2e-tests/specs/.gitignore rename to packages/e2e-tests/specs/performance/.gitignore diff --git a/packages/e2e-tests/specs/performance.test.js b/packages/e2e-tests/specs/performance/performance.test.js similarity index 95% rename from packages/e2e-tests/specs/performance.test.js rename to packages/e2e-tests/specs/performance/performance.test.js index 174bf2c6ab1301..6246dfb4dc0d38 100644 --- a/packages/e2e-tests/specs/performance.test.js +++ b/packages/e2e-tests/specs/performance/performance.test.js @@ -20,7 +20,7 @@ function readFile( filePath ) { describe( 'Performance', () => { it( '1000 paragraphs', async () => { - const html = readFile( join( __dirname, '../assets/large-post.html' ) ); + const html = readFile( join( __dirname, '../../assets/large-post.html' ) ); await createNewPost(); await page.evaluate( ( _html ) => { diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index 69dd699b23426e..c1d1576e310bc5 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -1,4 +1,4 @@ -## Master +## 3.8.2 ### Bug Fixes diff --git a/packages/edit-post/README.md b/packages/edit-post/README.md index 3b7b01a53e6dd3..0a9441a55b101f 100644 --- a/packages/edit-post/README.md +++ b/packages/edit-post/README.md @@ -92,13 +92,13 @@ _Parameters_ - _props_ `Object`: Component props. - _props.allowedBlocks_ `[Array]`: An array containing a list of block names for which the item should be shown. If not present, it'll be rendered for any block. If multiple blocks are selected, it'll be shown if and only if all of them are in the whitelist. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. - _props.label_ `string`: The menu item text. - _props.onClick_ `Function`: Callback function to be executed when the user click the menu item. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginDocumentSettingPanel" href="#PluginDocumentSettingPanel">#</a> **PluginDocumentSettingPanel** @@ -149,11 +149,11 @@ _Parameters_ - _props.name_ `[string]`: The machine-friendly name for the panel. - _props.className_ `[string]`: An optional class name added to the row. - _props.title_ `[string]`: The title of the panel -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginMoreMenuItem" href="#PluginMoreMenuItem">#</a> **PluginMoreMenuItem** @@ -206,13 +206,13 @@ _Parameters_ - _props_ `Object`: Component properties. - _props.href_ `[string]`: When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. - _props.onClick_ `[Function]`: The callback function to be executed when the user clicks the menu item. - _props.other_ `[...*]`: Any additional props are passed through to the underlying [MenuItem](/packages/components/src/menu-item/README.md) component. _Returns_ -- `WPElement`: The element to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginPostPublishPanel" href="#PluginPostPublishPanel">#</a> **PluginPostPublishPanel** @@ -261,11 +261,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the panel. - _props.title_ `[string]`: Title displayed at the top of the panel. - _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginPostStatusInfo" href="#PluginPostStatusInfo">#</a> **PluginPostStatusInfo** @@ -312,7 +312,7 @@ _Parameters_ _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginPrePublishPanel" href="#PluginPrePublishPanel">#</a> **PluginPrePublishPanel** @@ -361,11 +361,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the panel. - _props.title_ `[string]`: Title displayed at the top of the panel. - _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginSidebar" href="#PluginSidebar">#</a> **PluginSidebar** @@ -432,11 +432,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the sidebar body. - _props.title_ `string`: Title displayed at the top of the sidebar. - _props.isPinnable_ `[boolean]`: Whether to allow to pin sidebar to toolbar. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: Plugin sidebar component. +- `WPComponent`: Plugin sidebar component. <a name="PluginSidebarMoreMenuItem" href="#PluginSidebarMoreMenuItem">#</a> **PluginSidebarMoreMenuItem** @@ -482,11 +482,11 @@ _Parameters_ - _props_ `Object`: Component props. - _props.target_ `string`: A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. _Returns_ -- `WPElement`: The element to be rendered. +- `WPComponent`: The component to be rendered. <a name="reinitializeEditor" href="#reinitializeEditor">#</a> **reinitializeEditor** diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index 98fd08247be8f0..a73c2d52ac105b 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "3.8.0", + "version": "3.8.3", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js index 8503692c289b07..938805e057406b 100644 --- a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js +++ b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js @@ -35,7 +35,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => ! Array.isArray( a * * @param {Object} props Component props. * @param {Array} [props.allowedBlocks] An array containing a list of block names for which the item should be shown. If not present, it'll be rendered for any block. If multiple blocks are selected, it'll be shown if and only if all of them are in the whitelist. - * @param {string|Element} [props.icon] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. + * @param {WPBlockTypeIconRender} [props.icon] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. * @param {string} props.label The menu item text. * @param {Function} props.onClick Callback function to be executed when the user click the menu item. * @@ -81,7 +81,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => ! Array.isArray( a * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginBlockSettingsMenuItem = ( { allowedBlocks, icon, label, onClick, small, role } ) => ( <PluginBlockSettingsMenuGroup> diff --git a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js index e29ec22e90a208..08a5bef83b35eb 100644 --- a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js @@ -32,7 +32,7 @@ const PluginMoreMenuItem = ( { onClick = noop, ...props } ) => ( * * @param {Object} props Component properties. * @param {string} [props.href] When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. * @param {Function} [props.onClick=noop] The callback function to be executed when the user clicks the menu item. * @param {...*} [props.other] Any additional props are passed through to the underlying [MenuItem](/packages/components/src/menu-item/README.md) component. * @@ -78,7 +78,7 @@ const PluginMoreMenuItem = ( { onClick = noop, ...props } ) => ( * ); * ``` * - * @return {WPElement} The element to be rendered. + * @return {WPComponent} The component to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js index e1849f2e7890ed..c1f4ff42ae98aa 100644 --- a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js @@ -28,7 +28,7 @@ const PluginSidebarMoreMenuItem = ( { children, icon, isSelected, onClick } ) => * * @param {Object} props Component props. * @param {string} props.target A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. * * @example <caption>ES5</caption> * ```js @@ -64,7 +64,7 @@ const PluginSidebarMoreMenuItem = ( { children, icon, isSelected, onClick } ) => * ); * ``` * - * @return {WPElement} The element to be rendered. + * @return {WPComponent} The component to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index 64699eeab73a2d..65a94ba8ad72d0 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -91,7 +91,7 @@ &.editor-post-publish-button, &.editor-post-publish-panel__toggle { margin: 2px; - height: 33px; + height: 34px; line-height: 32px; font-size: $default-font-size; } @@ -105,13 +105,17 @@ } } + // These paddings actually duplicate existing rules from button component. + // But they are duplicated so as to provide smaller paddings to fit the buttons on mobile. &.editor-post-preview, &.editor-post-publish-button, &.editor-post-publish-panel__toggle { - padding: 0 5px 2px; + padding-left: 5px; + padding-right: 5px; @include break-small() { - padding: 0 12px 2px; + padding-left: 12px; + padding-right: 12px; } } diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index e29011c8cec529..b8cb779603410c 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -21,6 +21,7 @@ import { EditorNotices, PostPublishPanel, } from '@wordpress/editor'; +import { BlockBreadcrumb } from '@wordpress/block-editor'; import { withDispatch, withSelect } from '@wordpress/data'; import { PluginArea } from '@wordpress/plugins'; import { withViewportMatch } from '@wordpress/viewport'; @@ -59,7 +60,7 @@ function Layout( { } ) { const sidebarIsOpened = editorSidebarOpened || pluginSidebarOpened || publishSidebarOpened; - const className = classnames( 'edit-post-layout', { + const className = classnames( 'edit-post-layout', 'is-mode-' + mode, { 'is-sidebar-opened': sidebarIsOpened, 'has-fixed-toolbar': hasFixedToolbar, 'has-metaboxes': hasActiveMetaboxes, @@ -80,7 +81,7 @@ function Layout( { <LocalAutosaveMonitor /> <Header /> <div - className="edit-post-layout__content" + className="edit-post-layout__content edit-post-layout__scrollable-container" role="region" /* translators: accessibility text for the content landmark region. */ aria-label={ __( 'Editor content' ) } @@ -99,7 +100,19 @@ function Layout( { <div className="edit-post-layout__metaboxes"> <MetaBoxes location="advanced" /> </div> + { isMobileViewport && sidebarIsOpened && <ScrollLock /> } </div> + { isRichEditingEnabled && mode === 'visual' && ( + <div + className="edit-post-layout__footer" + role="region" + /* translators: accessibility text for the content landmark region. */ + aria-label={ __( 'Editor footer' ) } + tabIndex="-1" + > + <BlockBreadcrumb /> + </div> + ) } { publishSidebarOpened ? ( <PostPublishPanel { ...publishLandmarkProps } @@ -124,9 +137,6 @@ function Layout( { </div> <SettingsSidebar /> <Sidebar.Slot /> - { - isMobileViewport && sidebarIsOpened && <ScrollLock /> - } </> ) } <Popover.Slot /> diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss index 43996d98f8c8f0..40e49f9df3b355 100644 --- a/packages/edit-post/src/components/layout/style.scss +++ b/packages/edit-post/src/components/layout/style.scss @@ -54,7 +54,7 @@ // Because the body element scrolls the navigation sidebar, we have to use position fixed here. // Otherwise you would scroll the editing canvas out of view when you scroll the sidebar. position: fixed; - bottom: 0; + bottom: $footer-height; left: 0; right: 0; @@ -70,6 +70,12 @@ // Because we are beyond the medium breakpoint, we only have to worry about folded, auto-folded, and default. margin-left: $admin-sidebar-width; + // Make room for the footer + .edit-post-layout.is-mode-visual & { + bottom: $footer-height; + min-height: calc(100% - #{ $header-height + $admin-bar-height + $footer-height }); + } + // Auto fold is when on smaller breakpoints, nav menu auto colllapses. body.auto-fold & { margin-left: $admin-sidebar-width-collapsed; @@ -104,31 +110,6 @@ } } - // Pad the scroll box so content on the bottom can be scrolled up. - padding-bottom: 50vh; - @include break-small { - padding-bottom: 0; - } - - // On mobile the main content (html or body) area has to scroll. - // If, like we do on the desktop, scroll an element (.edit-post-layout__content) you can invoke - // the overscroll bounce on the non-scrolling container, causing for a frustrating scrolling experience. - // The following rule enables this scrolling beyond the mobile breakpoint, because on the desktop - // breakpoints scrolling an isolated element helps avoid scroll bleed. - @include break-small() { - overflow-y: auto; - } - -webkit-overflow-scrolling: touch; - - // This rule ensures that if you've scrolled to the end of a container, - // then pause, then keep scrolling downwards, the browser doesn't try to scroll - // the parent element, usually invoking a "bounce" effect and then preventing you - // from scrolling upwards until you pause again. - // This is only necessary beyond the small breakpoint because that's when the scroll container changes. - @include break-small() { - overscroll-behavior-y: none; - } - .edit-post-visual-editor { flex: 1 1 auto; @@ -234,3 +215,51 @@ } } } + +.edit-post-layout__footer { + display: none; + z-index: z-index(".edit-post-layout__footer"); + + // Stretch to mimic outline padding on desktop. + @include break-medium() { + display: flex; + position: fixed; + bottom: 0; + right: 0; + background: $white; + height: $footer-height; + padding: 0 $grid-size; + align-items: center; + border-top: $border-width solid $light-gray-500; + font-size: $default-font-size; + box-sizing: border-box; + } +} +@include editor-left(".edit-post-layout__footer"); + +.edit-post-layout__scrollable-container { + // On mobile the main content (html or body) area has to scroll. + // If, like we do on the desktop, scroll an element (.edit-post-layout__content) you can invoke + // the overscroll bounce on the non-scrolling container, causing for a frustrating scrolling experience. + // The following rule enables this scrolling beyond the mobile breakpoint, because on the desktop + // breakpoints scrolling an isolated element helps avoid scroll bleed. + @include break-small() { + overflow-y: auto; + } + -webkit-overflow-scrolling: touch; + + // This rule ensures that if you've scrolled to the end of a container, + // then pause, then keep scrolling downwards, the browser doesn't try to scroll + // the parent element, usually invoking a "bounce" effect and then preventing you + // from scrolling upwards until you pause again. + // This is only necessary beyond the small breakpoint because that's when the scroll container changes. + @include break-small() { + overscroll-behavior-y: none; + } + + // Pad the scroll box so content on the bottom can be scrolled up. + padding-bottom: 50vh; + @include break-small { + padding-bottom: 0; + } +} diff --git a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss index b86d15952683b0..184835a024c35c 100644 --- a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss +++ b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss @@ -81,6 +81,25 @@ .is-hidden { display: none; } + + + // Until checkboxes WordPress-wide are updated to match the new style, + // checkboxes used in metaboxes have to be slightly unstyled here. + // @todo: remove this entire rule once checkboxes are the same everywhere. + // See: https://github.com/WordPress/gutenberg/issues/18053 + .postbox-container .postbox input[type="checkbox"], + .postbox-container .postbox input[type="radio"] { + border: $border-width solid $dark-gray-300; + + &:checked { + background: $white; + border-color: $dark-gray-300; + } + + &::before { + margin: -3px -4px; + } + } } .edit-post-meta-boxes-area__clear { diff --git a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js index ef10b4ed77ef30..62a651c7f0c24e 100644 --- a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js @@ -48,7 +48,7 @@ const PluginDocumentSettingFill = ( { isEnabled, panelName, opened, onToggle, cl * @param {string} [props.name] The machine-friendly name for the panel. * @param {string} [props.className] An optional class name added to the row. * @param {string} [props.title] The title of the panel - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -89,7 +89,7 @@ const PluginDocumentSettingFill = ( { isEnabled, panelName, opened, onToggle, cl * registerPlugin( 'document-setting-test', { render: MyDocumentSettingTest } ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginDocumentSettingPanel = compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js index a84124905d7d46..b1c53372857023 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js @@ -27,7 +27,7 @@ const PluginPostPublishPanelFill = ( { children, className, title, initialOpen = * @param {string} [props.className] An optional class name added to the panel. * @param {string} [props.title] Title displayed at the top of the panel. * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. When no title is provided it is always opened. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -65,7 +65,7 @@ const PluginPostPublishPanelFill = ( { children, className, title, initialOpen = * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginPostPublishPanel = compose( diff --git a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js b/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js index e099fa232e84f6..2d149639130eda 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js @@ -49,7 +49,7 @@ export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' ); * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginPostStatusInfo = ( { children, className } ) => ( <Fill> diff --git a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js index 4a3b02fba2803b..13863b24f16d50 100644 --- a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js @@ -18,16 +18,19 @@ const PluginPrePublishPanelFill = ( { children, className, title, initialOpen = </PanelBody> </Fill> ); + /** * Renders provided content to the pre-publish side panel in the publish flow * (side panel that opens when a user first pushes "Publish" from the main editor). * - * @param {Object} props Component props. - * @param {string} [props.className] An optional class name added to the panel. - * @param {string} [props.title] Title displayed at the top of the panel. - * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. When no title is provided it is always opened. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. - + * @param {Object} props Component props. + * @param {string} [props.className] An optional class name added to the panel. + * @param {string} [props.title] Title displayed at the top of the panel. + * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. + * When no title is provided it is always opened. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) + * icon slug string, or an SVG WP element, to be rendered when + * the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -65,7 +68,7 @@ const PluginPrePublishPanelFill = ( { children, className, title, initialOpen = * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginPrePublishPanel = compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js index 5303de703b30b9..7c03f172b009fb 100644 --- a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js @@ -82,7 +82,7 @@ function PluginSidebar( props ) { * @param {string} [props.className] An optional class name added to the sidebar body. * @param {string} props.title Title displayed at the top of the sidebar. * @param {boolean} [props.isPinnable=true] Whether to allow to pin sidebar to toolbar. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -129,7 +129,7 @@ function PluginSidebar( props ) { * ); * ``` * - * @return {WPElement} Plugin sidebar component. + * @return {WPComponent} Plugin sidebar component. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/post-slug/index.js b/packages/edit-post/src/components/sidebar/post-slug/index.js new file mode 100644 index 00000000000000..fe539a38decce6 --- /dev/null +++ b/packages/edit-post/src/components/sidebar/post-slug/index.js @@ -0,0 +1,17 @@ +/** + * WordPress dependencies + */ +import { PanelRow } from '@wordpress/components'; +import { PostSlug as PostSlugForm, PostSlugCheck } from '@wordpress/editor'; + +export function PostSlug() { + return ( + <PostSlugCheck> + <PanelRow> + <PostSlugForm /> + </PanelRow> + </PostSlugCheck> + ); +} + +export default PostSlug; diff --git a/packages/edit-post/src/components/sidebar/post-slug/style.scss b/packages/edit-post/src/components/sidebar/post-slug/style.scss new file mode 100644 index 00000000000000..b031424164dcec --- /dev/null +++ b/packages/edit-post/src/components/sidebar/post-slug/style.scss @@ -0,0 +1,4 @@ +.editor-post-slug__input { + margin: -5px 0; + padding: 2px; +} diff --git a/packages/edit-post/src/components/sidebar/post-status/index.js b/packages/edit-post/src/components/sidebar/post-status/index.js index a3403a8209c9e5..b9d50676f7141a 100644 --- a/packages/edit-post/src/components/sidebar/post-status/index.js +++ b/packages/edit-post/src/components/sidebar/post-status/index.js @@ -14,6 +14,7 @@ import PostTrash from '../post-trash'; import PostSchedule from '../post-schedule'; import PostSticky from '../post-sticky'; import PostAuthor from '../post-author'; +import PostSlug from '../post-slug'; import PostFormat from '../post-format'; import PostPendingStatus from '../post-pending-status'; import PluginPostStatusInfo from '../plugin-post-status-info'; @@ -34,6 +35,7 @@ function PostStatus( { isOpened, onTogglePanel } ) { <PostFormat /> <PostSticky /> <PostPendingStatus /> + <PostSlug /> <PostAuthor /> { fills } <PostTrash /> diff --git a/packages/edit-post/src/components/sidebar/style.scss b/packages/edit-post/src/components/sidebar/style.scss index 740355cf636f75..50ddd2efedbde5 100644 --- a/packages/edit-post/src/components/sidebar/style.scss +++ b/packages/edit-post/src/components/sidebar/style.scss @@ -22,6 +22,10 @@ @include break-medium() { top: $admin-bar-height + $header-height; + .edit-post-layout.is-mode-visual & { + bottom: $footer-height; + } + body.is-fullscreen-mode & { top: $header-height; } diff --git a/packages/edit-post/src/components/text-editor/style.scss b/packages/edit-post/src/components/text-editor/style.scss index 234eb46917b247..f7696bb4ee1959 100644 --- a/packages/edit-post/src/components/text-editor/style.scss +++ b/packages/edit-post/src/components/text-editor/style.scss @@ -1,30 +1,5 @@ -.edit-post-text-editor__body { - padding-top: $grid-size * 5; - - @include break-small() { - padding-top: ($grid-size * 5) + $admin-bar-height-big; - } - - @include break-medium() { - padding-top: $grid-size * 5; - - body.is-fullscreen-mode & { - padding-top: $grid-size * 5; - } - } -} - .edit-post-text-editor { width: 100%; - max-width: calc(100% - #{$grid-size-large * 2}); - margin-left: $grid-size-large; - margin-right: $grid-size-large; - - @include break-small() { - max-width: $content-width; - margin-left: auto; - margin-right: auto; - } // Always show outlines in code editor .editor-post-title__block { @@ -67,34 +42,41 @@ } } - .editor-post-text-editor { - padding: $block-padding; - min-height: 200px; - line-height: 1.8; - } - // Make room for toolbar. padding-top: $block-controls-height + $grid-size; +} - // Exit Code Editor toolbar. - .edit-post-text-editor__toolbar { - position: absolute; - top: $grid-size; - left: 0; - right: 0; - height: $block-controls-height; - line-height: $block-controls-height; - padding: 0 $grid-size 0 $grid-size-large; - display: flex; +// Exit Code Editor toolbar. +.edit-post-text-editor__toolbar { + position: absolute; + top: $grid-size; + left: 0; + right: 0; + height: $block-controls-height; + line-height: $block-controls-height; + padding: 0 $grid-size 0 $grid-size-large; + display: flex; + + h2 { + margin: 0 auto 0 0; + font-size: $default-font-size; + color: $dark-gray-500; + } - h2 { - margin: 0 auto 0 0; - font-size: $default-font-size; - color: $dark-gray-500; - } + .components-icon-button svg { + order: 1; + } +} - .components-icon-button svg { - order: 1; - } +.edit-post-text-editor__body { + max-width: calc(100% - #{$grid-size-large * 2}); + margin-left: $grid-size-large; + margin-right: $grid-size-large; + padding-top: $grid-size * 5; + + @include break-small() { + max-width: $content-width; + margin-left: auto; + margin-right: auto; } } diff --git a/packages/edit-post/src/hooks/validate-multiple-use/index.js b/packages/edit-post/src/hooks/validate-multiple-use/index.js index ea2958949f7e2d..54a502603c2064 100644 --- a/packages/edit-post/src/hooks/validate-multiple-use/index.js +++ b/packages/edit-post/src/hooks/validate-multiple-use/index.js @@ -28,9 +28,9 @@ const enhance = compose( * "original" block is not the current one. Thus, an inexisting * `originalBlockClientId` prop signals that the block is valid. * - * @param {Component} WrappedBlockEdit A filtered BlockEdit instance. + * @param {WPComponent} WrappedBlockEdit A filtered BlockEdit instance. * - * @return {Component} Enhanced component with merged state data props. + * @return {WPComponent} Enhanced component with merged state data props. */ withSelect( ( select, block ) => { const multiple = hasBlockSupport( block.name, 'multiple', true ); diff --git a/packages/edit-post/src/store/selectors.js b/packages/edit-post/src/store/selectors.js index 2430ee41087232..fff04ac721fe37 100644 --- a/packages/edit-post/src/store/selectors.js +++ b/packages/edit-post/src/store/selectors.js @@ -78,9 +78,9 @@ export function getPreferences( state ) { * * @param {Object} state Global application state. * @param {string} preferenceKey Preference Key. - * @param {Mixed} defaultValue Default Value. + * @param {*} defaultValue Default Value. * - * @return {Mixed} Preference Value. + * @return {*} Preference Value. */ export function getPreference( state, preferenceKey, defaultValue ) { const preferences = getPreferences( state ); diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index 6403380ff54601..94fcfa7ac60fe6 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -1,3 +1,5 @@ +$footer-height: $icon-button-size-small; + @import "./components/fullscreen-mode/style.scss"; @import "./components/header/style.scss"; @import "./components/header/fullscreen-mode-close/style.scss"; @@ -13,6 +15,7 @@ @import "./components/sidebar/post-author/style.scss"; @import "./components/sidebar/post-link/style.scss"; @import "./components/sidebar/post-schedule/style.scss"; +@import "./components/sidebar/post-slug/style.scss"; @import "./components/sidebar/post-status/style.scss"; @import "./components/sidebar/post-visibility/style.scss"; @import "./components/sidebar/settings-header/style.scss"; diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index e5ba0beff046e2..37dd6972b49627 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "0.7.0", + "version": "0.7.3", "private": true, "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", diff --git a/packages/edit-widgets/src/components/widget-area/index.js b/packages/edit-widgets/src/components/widget-area/index.js index e22c880f50cf22..11e162d2874d9d 100644 --- a/packages/edit-widgets/src/components/widget-area/index.js +++ b/packages/edit-widgets/src/components/widget-area/index.js @@ -42,7 +42,7 @@ function getBlockEditorSettings( blockEditorSettings, hasUploadPermissions ) { }; return { ...blockEditorSettings, - __experimentalMediaUpload: mediaUploadBlockEditor, + mediaUpload: mediaUploadBlockEditor, }; } diff --git a/packages/editor/package.json b/packages/editor/package.json index 22e78a023ca3f6..9ddc2a6d1951ae 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "9.7.0", + "version": "9.7.3", "description": "Building blocks for WordPress editors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/src/components/autocompleters/block.js b/packages/editor/src/components/autocompleters/block.js index 70860643ae096b..5311d01ec2b749 100644 --- a/packages/editor/src/components/autocompleters/block.js +++ b/packages/editor/src/components/autocompleters/block.js @@ -27,7 +27,7 @@ function defaultGetBlockInsertionParentClientId() { * @param {string} rootClientId Client ID of the block for which to retrieve * inserter items. * - * @return {Array<Editor.InserterItem>} The inserter items for the specified + * @return {Array<WPEditorInserterItem>} The inserter items for the specified * parent. */ function defaultGetInserterItems( rootClientId ) { @@ -68,7 +68,7 @@ const fetchReusableBlocks = once( () => { /** * Creates a blocks repeater for replacing the current block with a selected block type. * - * @return {Completer} A blocks completer. + * @return {WPCompleter} A blocks completer. */ export function createBlockCompleter( { // Allow store-based selectors to be overridden for unit test. @@ -119,6 +119,6 @@ export function createBlockCompleter( { /** * Creates a blocks repeater for replacing the current block with a selected block type. * - * @return {Completer} A blocks completer. + * @return {WPCompleter} A blocks completer. */ export default createBlockCompleter(); diff --git a/packages/editor/src/components/autocompleters/user.js b/packages/editor/src/components/autocompleters/user.js index e3965a33f28d6f..1dea163ee16443 100644 --- a/packages/editor/src/components/autocompleters/user.js +++ b/packages/editor/src/components/autocompleters/user.js @@ -6,7 +6,7 @@ import apiFetch from '@wordpress/api-fetch'; /** * A user mentions completer. * - * @type {Completer} + * @type {WPCompleter} */ export default { name: 'users', diff --git a/packages/editor/src/components/index.js b/packages/editor/src/components/index.js index fed6f633ffbfd0..d5af7f4ff443bf 100644 --- a/packages/editor/src/components/index.js +++ b/packages/editor/src/components/index.js @@ -42,6 +42,8 @@ export { default as PostSavedState } from './post-saved-state'; export { default as PostSchedule } from './post-schedule'; export { default as PostScheduleCheck } from './post-schedule/check'; export { default as PostScheduleLabel } from './post-schedule/label'; +export { default as PostSlug } from './post-slug'; +export { default as PostSlugCheck } from './post-slug/check'; export { default as PostSticky } from './post-sticky'; export { default as PostStickyCheck } from './post-sticky/check'; export { default as PostSwitchToDraftButton } from './post-switch-to-draft-button'; diff --git a/packages/editor/src/components/local-autosave-monitor/index.js b/packages/editor/src/components/local-autosave-monitor/index.js index 59be30218f20cd..9dbd94aab5f56d 100644 --- a/packages/editor/src/components/local-autosave-monitor/index.js +++ b/packages/editor/src/components/local-autosave-monitor/index.js @@ -130,7 +130,12 @@ function useAutosavePurge() { const lastIsAutosaving = useRef( isAutosaving ); useEffect( () => { - if ( lastIsAutosaving.current && ! isAutosaving && ! didError ) { + if ( + ! didError && ( + ( lastIsAutosaving.current && ! isAutosaving ) || + ( lastIsDirty.current && ! isDirty ) + ) + ) { localAutosaveClear( postId ); } diff --git a/packages/editor/src/components/post-publish-button/index.js b/packages/editor/src/components/post-publish-button/index.js index 1513dfbfbb414f..ac195d4de86ce6 100644 --- a/packages/editor/src/components/post-publish-button/index.js +++ b/packages/editor/src/components/post-publish-button/index.js @@ -113,6 +113,7 @@ export class PostPublishButton extends Component { return ( <div> <Button + isLarge ref={ this.buttonNode } { ...componentProps } > diff --git a/packages/editor/src/components/post-slug/check.js b/packages/editor/src/components/post-slug/check.js new file mode 100644 index 00000000000000..6b243bd6b9f641 --- /dev/null +++ b/packages/editor/src/components/post-slug/check.js @@ -0,0 +1,10 @@ +/** + * Internal dependencies + */ +import PostTypeSupportCheck from '../post-type-support-check'; + +export default function PostSlugCheck( { children } ) { + return ( + <PostTypeSupportCheck supportKeys="slug">{ children }</PostTypeSupportCheck> + ); +} diff --git a/packages/editor/src/components/post-slug/index.js b/packages/editor/src/components/post-slug/index.js new file mode 100644 index 00000000000000..9a9b2200e72be0 --- /dev/null +++ b/packages/editor/src/components/post-slug/index.js @@ -0,0 +1,85 @@ +/** + * WordPress dependencies + */ +import { withDispatch, withSelect } from '@wordpress/data'; +import { Component } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { withInstanceId, compose } from '@wordpress/compose'; +import { safeDecodeURIComponent } from '@wordpress/url'; + +/** + * Internal dependencies + */ +import PostSlugCheck from './check'; +import { cleanForSlug } from '../../utils/url'; + +export class PostSlug extends Component { + constructor( { postSlug, postTitle, postID } ) { + super( ...arguments ); + + this.state = { + editedSlug: safeDecodeURIComponent( postSlug ) || cleanForSlug( postTitle ) || postID, + }; + + this.setSlug = this.setSlug.bind( this ); + } + + setSlug( event ) { + const { postSlug, onUpdateSlug } = this.props; + const { value } = event.target; + + const editedSlug = cleanForSlug( value ); + + if ( editedSlug === postSlug ) { + return; + } + + onUpdateSlug( editedSlug ); + } + + render() { + const { instanceId } = this.props; + const { editedSlug } = this.state; + + const inputId = 'editor-post-slug-' + instanceId; + + return ( + <PostSlugCheck> + <label htmlFor={ inputId }>{ __( 'Slug' ) }</label> + <input + type="text" + id={ inputId } + value={ editedSlug } + onChange={ ( event ) => this.setState( { editedSlug: event.target.value } ) } + onBlur={ this.setSlug } + className="editor-post-slug__input" + /> + </PostSlugCheck> + ); + } +} + +export default compose( [ + withSelect( ( select ) => { + const { + getCurrentPost, + getEditedPostAttribute, + } = select( 'core/editor' ); + + const { id } = getCurrentPost(); + return { + postSlug: getEditedPostAttribute( 'slug' ), + postTitle: getEditedPostAttribute( 'title' ), + postID: id, + }; + } ), + withDispatch( ( dispatch ) => { + const { editPost } = dispatch( 'core/editor' ); + return { + onUpdateSlug( slug ) { + editPost( { slug } ); + }, + }; + } ), + withInstanceId, +] )( PostSlug ); diff --git a/packages/editor/src/components/post-slug/test/check.js b/packages/editor/src/components/post-slug/test/check.js new file mode 100644 index 00000000000000..90fe356236adbc --- /dev/null +++ b/packages/editor/src/components/post-slug/test/check.js @@ -0,0 +1,21 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import PostSlugCheck from '../check'; + +describe( 'PostSlugCheck', () => { + it( 'should render control', () => { + const wrapper = shallow( + <PostSlugCheck> + slug + </PostSlugCheck> + ); + + expect( wrapper.type() ).not.toBe( null ); + } ); +} ); diff --git a/packages/editor/src/components/post-slug/test/index.js b/packages/editor/src/components/post-slug/test/index.js new file mode 100644 index 00000000000000..cf25f25e0fe377 --- /dev/null +++ b/packages/editor/src/components/post-slug/test/index.js @@ -0,0 +1,45 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import { PostSlug } from '../'; + +describe( 'PostSlug', () => { + describe( '#render()', () => { + it( 'should update internal slug', () => { + const wrapper = shallow( + <PostSlug + postSlug="index" /> + ); + + wrapper.find( 'input' ).simulate( 'change', { + target: { + value: 'single-post', + }, + } ); + + expect( wrapper.state().editedSlug ).toEqual( 'single-post' ); + } ); + + it( 'should update slug', () => { + const onUpdateSlug = jest.fn(); + const wrapper = shallow( + <PostSlug + postSlug="index" + onUpdateSlug={ onUpdateSlug } /> + ); + + wrapper.find( 'input' ).simulate( 'blur', { + target: { + value: 'single-post', + }, + } ); + + expect( onUpdateSlug ).toHaveBeenCalledWith( 'single-post' ); + } ); + } ); +} ); diff --git a/packages/editor/src/components/post-taxonomies/flat-term-selector.js b/packages/editor/src/components/post-taxonomies/flat-term-selector.js index 3b4c1c8a0c2926..06db56eef101f5 100644 --- a/packages/editor/src/components/post-taxonomies/flat-term-selector.js +++ b/packages/editor/src/components/post-taxonomies/flat-term-selector.js @@ -128,13 +128,13 @@ class FlatTermSelector extends Component { } updateSelectedTerms( terms = [] ) { - const selectedTerms = terms.reduce( ( result, termId ) => { + const selectedTerms = terms.reduce( ( accumulator, termId ) => { const termObject = find( this.state.availableTerms, ( term ) => term.id === termId ); if ( termObject ) { - result.push( termObject.name ); + accumulator.push( termObject.name ); } - return result; + return accumulator; }, [] ); this.setState( { selectedTerms, diff --git a/packages/editor/src/components/post-type-support-check/index.js b/packages/editor/src/components/post-type-support-check/index.js index 8096e4ccf7f8d9..7aae5e6abb0362 100644 --- a/packages/editor/src/components/post-type-support-check/index.js +++ b/packages/editor/src/components/post-type-support-check/index.js @@ -12,14 +12,14 @@ import { withSelect } from '@wordpress/data'; * A component which renders its own children only if the current editor post * type supports one of the given `supportKeys` prop. * - * @param {Object} props - * @param {string} [props.postType] Current post type. - * @param {WPElement} props.children Children to be rendered if post - * type supports. - * @param {(string|string[])} props.supportKeys String or string array of keys - * to test. + * @param {Object} props Props. + * @param {string} [props.postType] Current post type. + * @param {WPElement} props.children Children to be rendered if post + * type supports. + * @param {(string|string[])} props.supportKeys String or string array of keys + * to test. * - * @return {WPElement} Rendered element. + * @return {WPComponent} The component to be rendered. */ export function PostTypeSupportCheck( { postType, children, supportKeys } ) { let isSupported = true; diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index c386f02097167b..37eb46ff235b52 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { map, pick, defaultTo, differenceBy, isEqual, noop } from 'lodash'; +import { map, pick, defaultTo } from 'lodash'; import memize from 'memize'; /** @@ -16,7 +16,6 @@ import { BlockEditorProvider, transformStyles } from '@wordpress/block-editor'; import apiFetch from '@wordpress/api-fetch'; import { addQueryArgs } from '@wordpress/url'; import { decodeEntities } from '@wordpress/html-entities'; -import { unregisterBlockType } from '@wordpress/blocks'; /** * Internal dependencies @@ -25,7 +24,6 @@ import withRegistryProvider from './with-registry-provider'; import { mediaUpload } from '../../utils'; import ReusableBlocksButtons from '../reusable-blocks-buttons'; import ConvertToGroupButtons from '../convert-to-group-buttons'; -import InserterMenuDownloadableBlocksPanel from '../inserter-menu-downloadable-blocks-panel'; const fetchLinkSuggestions = async ( search ) => { const posts = await apiFetch( { @@ -40,11 +38,10 @@ const fetchLinkSuggestions = async ( search ) => { id: post.id, url: post.url, title: decodeEntities( post.title ) || __( '(no title)' ), + type: post.subtype || post.type, } ) ); }; -const UNINSTALL_ERROR_NOTICE_ID = 'block-uninstall-error'; - class EditorProvider extends Component { constructor( props ) { super( ...arguments ); @@ -109,10 +106,11 @@ class EditorProvider extends Component { '__experimentalEnableLegacyWidgetBlock', '__experimentalEnableMenuBlock', '__experimentalBlockDirectory', + '__experimentalEnableFullSiteEditing', 'showInserterHelpPanel', ] ), + mediaUpload: hasUploadPermissions ? mediaUpload : undefined, __experimentalReusableBlocks: reusableBlocks, - __experimentalMediaUpload: hasUploadPermissions ? mediaUpload : undefined, __experimentalFetchLinkSuggestions: fetchLinkSuggestions, __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML, }; @@ -140,21 +138,6 @@ class EditorProvider extends Component { if ( this.props.settings !== prevProps.settings ) { this.props.updateEditorSettings( this.props.settings ); } - - // When a block is installed from the inserter and is unused, - // it is removed when saving the post. - // Todo: move this to the edit-post package into a separate component. - if ( ! isEqual( this.props.downloadableBlocksToUninstall, prevProps.downloadableBlocksToUninstall ) ) { - this.props.downloadableBlocksToUninstall.forEach( ( blockType ) => { - this.props.uninstallBlock( blockType, noop, () => { - this.props.createWarningNotice( - __( 'Block previews can\'t uninstall.' ), { - id: UNINSTALL_ERROR_NOTICE_ID, - } ); - } ); - unregisterBlockType( blockType.name ); - } ); - } } componentWillUnmount() { @@ -187,19 +170,20 @@ class EditorProvider extends Component { ); return ( - <EntityProvider kind="postType" type={ post.type } id={ post.id }> - <BlockEditorProvider - value={ blocks } - onInput={ resetEditorBlocksWithoutUndoLevel } - onChange={ resetEditorBlocks } - settings={ editorSettings } - useSubRegistry={ false } - > - { children } - <ReusableBlocksButtons /> - <ConvertToGroupButtons /> - { editorSettings.__experimentalBlockDirectory && <InserterMenuDownloadableBlocksPanel /> } - </BlockEditorProvider> + <EntityProvider kind="root" type="site"> + <EntityProvider kind="postType" type={ post.type } id={ post.id }> + <BlockEditorProvider + value={ blocks } + onInput={ resetEditorBlocksWithoutUndoLevel } + onChange={ resetEditorBlocks } + settings={ editorSettings } + useSubRegistry={ false } + > + { children } + <ReusableBlocksButtons /> + <ConvertToGroupButtons /> + </BlockEditorProvider> + </EntityProvider> </EntityProvider> ); } @@ -215,10 +199,6 @@ export default compose( [ __experimentalGetReusableBlocks, } = select( 'core/editor' ); const { canUser } = select( 'core' ); - const { getInstalledBlockTypes } = select( 'core/block-directory' ); - const { getBlocks } = select( 'core/block-editor' ); - - const downloadableBlocksToUninstall = differenceBy( getInstalledBlockTypes(), getBlocks(), 'name' ); return { canUserUseUnfilteredHTML: canUserUseUnfilteredHTML(), @@ -226,7 +206,6 @@ export default compose( [ blocks: getEditorBlocks(), reusableBlocks: __experimentalGetReusableBlocks(), hasUploadPermissions: defaultTo( canUser( 'create', 'media' ), true ), - downloadableBlocksToUninstall, }; } ), withDispatch( ( dispatch ) => { @@ -238,7 +217,6 @@ export default compose( [ __experimentalTearDownEditor, } = dispatch( 'core/editor' ); const { createWarningNotice } = dispatch( 'core/notices' ); - const { uninstallBlock } = dispatch( 'core/block-directory' ); return { setupEditor, @@ -252,7 +230,6 @@ export default compose( [ } ); }, tearDownEditor: __experimentalTearDownEditor, - uninstallBlock, }; } ), ] )( EditorProvider ); diff --git a/packages/editor/src/editor-styles.scss b/packages/editor/src/editor-styles.scss index c44e3d87a32299..978b34a61deaf3 100644 --- a/packages/editor/src/editor-styles.scss +++ b/packages/editor/src/editor-styles.scss @@ -104,6 +104,8 @@ ul, ol { margin-bottom: $default-block-margin; padding: inherit; + padding-left: 1.3em; + margin-left: 1.3em; // Remove bottom margin from nested lists. ul, diff --git a/packages/editor/src/store/actions.native.js b/packages/editor/src/store/actions.native.js index 17733a0e47b408..0154c92324640e 100644 --- a/packages/editor/src/store/actions.native.js +++ b/packages/editor/src/store/actions.native.js @@ -21,9 +21,7 @@ export function togglePostTitleSelection( isSelected = true ) { /** * Action generator used in signalling that the post should autosave. - * - * @param {Object?} options Extra flags to identify the autosave. */ -export function* autosave( ) { +export function* autosave() { RNReactNativeGutenbergBridge.editorDidAutosave(); } diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 7014d8a3b1fe56..0bf0ddf3f1bb38 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -210,8 +210,8 @@ export function postLock( state = { isLocked: false }, action ) { * * When post saving is locked, the post cannot be published or updated. * - * @param {PostSavingLockState} state Current state. - * @param {Object} action Dispatched action. + * @param {PostLockState} state Current state. + * @param {Object} action Dispatched action. * * @return {PostLockState} Updated state. */ @@ -231,8 +231,8 @@ export function postSavingLock( state = {}, action ) { * * When post autosaving is locked, the post will not autosave. * - * @param {PostAutosavingLockState} state Current state. - * @param {Object} action Dispatched action. + * @param {PostLockState} state Current state. + * @param {Object} action Dispatched action. * * @return {PostLockState} Updated state. */ diff --git a/packages/element/README.md b/packages/element/README.md index 0b96812eacb539..fb0c8089fae2b1 100755 --- a/packages/element/README.md +++ b/packages/element/README.md @@ -148,8 +148,8 @@ _Related_ _Parameters_ -- _component_ `Component`: Component -- _target_ `Element`: DOM node into which element should be rendered +- _child_ `WPElement`: Any renderable child, such as an element, string, or fragment. +- _container_ `HTMLElement`: DOM node into which element should be rendered. <a name="createRef" href="#createRef">#</a> **createRef** @@ -163,12 +163,11 @@ _Returns_ <a name="findDOMNode" href="#findDOMNode">#</a> **findDOMNode** -Finds the dom node of a React component +Finds the dom node of a React component. _Parameters_ -- _component_ `Component`: component's instance -- _target_ `Element`: DOM node into which element should be rendered +- _component_ `WPComponent`: Component's instance. <a name="forwardRef" href="#forwardRef">#</a> **forwardRef** @@ -203,7 +202,7 @@ _Returns_ <a name="isValidElement" href="#isValidElement">#</a> **isValidElement** -Checks if an object is a valid WPElement +Checks if an object is a valid WPElement. _Parameters_ @@ -225,6 +224,30 @@ _Related_ - <https://reactjs.org/docs/react-api.html#reactmemo> +<a name="Platform" href="#Platform">#</a> **Platform** + +Component used to detect the current Platform being used. +Use Platform.OS === 'web' to detect if running on web enviroment. + +This is the same concept as the React Native implementation. + +_Related_ + +- <https://facebook.github.io/react-native/docs/platform-specific-code#platform-module> + +Here is an example of how to use the select method: + +_Usage_ + +```js +import { Platform } from '@wordpress/element'; + +const placeholderLabel = Platform.select( { + native: __( 'Add media' ), + web: __( 'Drag images, upload new ones or select files from your library.' ), +} ); +``` + <a name="RawHTML" href="#RawHTML">#</a> **RawHTML** Component used as equivalent of Fragment with unescaped HTML, in cases where @@ -240,7 +263,7 @@ _Parameters_ _Returns_ -- `WPElement`: Dangerously-rendering element. +- `WPComponent`: Dangerously-rendering component. <a name="render" href="#render">#</a> **render** @@ -248,8 +271,8 @@ Renders a given element into the target DOM node. _Parameters_ -- _element_ `WPElement`: Element to render -- _target_ `Element`: DOM node into which element should be rendered +- _element_ `WPElement`: Element to render. +- _target_ `HTMLElement`: DOM node into which element should be rendered. <a name="renderToString" href="#renderToString">#</a> **renderToString** diff --git a/packages/element/package.json b/packages/element/package.json index 187e80d149b4a5..c7e4ac61ff491c 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/element", - "version": "2.8.0", + "version": "2.8.2", "description": "Element React module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/element/src/index.js b/packages/element/src/index.js index d9d4bf87ecf05d..ad8bae6eff98b0 100644 --- a/packages/element/src/index.js +++ b/packages/element/src/index.js @@ -1,5 +1,6 @@ export * from './react'; export * from './react-platform'; export * from './utils'; +export { default as Platform } from './platform'; export { default as renderToString } from './serialize'; export { default as RawHTML } from './raw-html'; diff --git a/packages/element/src/platform.android.js b/packages/element/src/platform.android.js new file mode 100644 index 00000000000000..4f0da0cab9c683 --- /dev/null +++ b/packages/element/src/platform.android.js @@ -0,0 +1,18 @@ +/** + * External dependencies + */ +import { Platform as OriginalPlatform } from 'react-native'; + +const Platform = { + ...OriginalPlatform, + select: ( spec ) => { + if ( 'android' in spec ) { + return spec.android; + } else if ( 'native' in spec ) { + return spec.native; + } + return spec.default; + }, +}; + +export default Platform; diff --git a/packages/element/src/platform.ios.js b/packages/element/src/platform.ios.js new file mode 100644 index 00000000000000..bbadff1f193319 --- /dev/null +++ b/packages/element/src/platform.ios.js @@ -0,0 +1,18 @@ +/** + * External dependencies + */ +import { Platform as OriginalPlatform } from 'react-native'; + +const Platform = { + ...OriginalPlatform, + select: ( spec ) => { + if ( 'ios' in spec ) { + return spec.ios; + } else if ( 'native' in spec ) { + return spec.native; + } + return spec.default; + }, +}; + +export default Platform; diff --git a/packages/element/src/platform.js b/packages/element/src/platform.js new file mode 100644 index 00000000000000..328f5523b6f95f --- /dev/null +++ b/packages/element/src/platform.js @@ -0,0 +1,32 @@ +/** + * Parts of this source were derived and modified from react-native-web, + * released under the MIT license. + * + * Copyright (c) 2016-present, Nicolas Gallagher. + * Copyright (c) 2015-present, Facebook, Inc. + * + */ +const Platform = { + OS: 'web', + select: ( spec ) => ( 'web' in spec ? spec.web : spec.default ), +}; +/** + * Component used to detect the current Platform being used. + * Use Platform.OS === 'web' to detect if running on web enviroment. + * + * This is the same concept as the React Native implementation. + * + * @see https://facebook.github.io/react-native/docs/platform-specific-code#platform-module + * + * Here is an example of how to use the select method: + * @example + * ```js + * import { Platform } from '@wordpress/element'; + * + * const placeholderLabel = Platform.select( { + * native: __( 'Add media' ), + * web: __( 'Drag images, upload new ones or select files from your library.' ), + * } ); + * ``` + */ +export default Platform; diff --git a/packages/element/src/raw-html.js b/packages/element/src/raw-html.js index 2fa3618c417d88..0f56060e3057b6 100644 --- a/packages/element/src/raw-html.js +++ b/packages/element/src/raw-html.js @@ -13,7 +13,7 @@ import { createElement } from './react'; * @param {string} props.children HTML to render. * @param {Object} props.props Any additonal props to be set on the containing div. * - * @return {WPElement} Dangerously-rendering element. + * @return {WPComponent} Dangerously-rendering component. */ export default function RawHTML( { children, ...props } ) { // The DIV wrapper will be stripped by serializer, unless there are diff --git a/packages/element/src/react-platform.js b/packages/element/src/react-platform.js index e4ca37da7e11bc..44a3422ed79773 100644 --- a/packages/element/src/react-platform.js +++ b/packages/element/src/react-platform.js @@ -13,24 +13,24 @@ import { * * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235 * - * @param {Component} component Component - * @param {Element} target DOM node into which element should be rendered + * @param {WPElement} child Any renderable child, such as an element, + * string, or fragment. + * @param {HTMLElement} container DOM node into which element should be rendered. */ export { createPortal }; /** - * Finds the dom node of a React component + * Finds the dom node of a React component. * - * @param {Component} component component's instance - * @param {Element} target DOM node into which element should be rendered + * @param {WPComponent} component Component's instance. */ export { findDOMNode }; /** * Renders a given element into the target DOM node. * - * @param {WPElement} element Element to render - * @param {Element} target DOM node into which element should be rendered + * @param {WPElement} element Element to render. + * @param {HTMLElement} target DOM node into which element should be rendered. */ export { render }; diff --git a/packages/element/src/react.js b/packages/element/src/react.js index 561776257f388e..2776f514b329e5 100644 --- a/packages/element/src/react.js +++ b/packages/element/src/react.js @@ -28,6 +28,24 @@ import { } from 'react'; import { isString } from 'lodash'; +/** + * Object containing a React element. + * + * @typedef {react.ReactElement} WPElement + */ + +/** + * Object containing a React component. + * + * @typedef {react.Component} WPComponent + */ + +/** + * Object containing a React synthetic event. + * + * @typedef {react.SyntheticEvent} WPSyntheticEvent + */ + /** * Object that provides utilities for dealing with React children. */ @@ -63,8 +81,8 @@ export { createContext }; * * @param {?(string|Function)} type Tag name or element creator * @param {Object} props Element properties, either attribute - * set to apply to DOM node or values to - * pass through to element creator + * set to apply to DOM node or values to + * pass through to element creator * @param {...WPElement} children Descendant elements * * @return {WPElement} Element. @@ -99,7 +117,7 @@ export { forwardRef }; export { Fragment }; /** - * Checks if an object is a valid WPElement + * Checks if an object is a valid WPElement. * * @param {Object} objectToCheck The object to be checked. * @@ -185,7 +203,7 @@ export { Suspense }; * @return {Array} The concatenated value. */ export function concatChildren( ...childrenArguments ) { - return childrenArguments.reduce( ( result, children, i ) => { + return childrenArguments.reduce( ( accumulator, children, i ) => { Children.forEach( children, ( child, j ) => { if ( child && 'string' !== typeof child ) { child = cloneElement( child, { @@ -193,10 +211,10 @@ export function concatChildren( ...childrenArguments ) { } ); } - result.push( child ); + accumulator.push( child ); } ); - return result; + return accumulator; }, [] ); } diff --git a/packages/element/src/test/platform.js b/packages/element/src/test/platform.js new file mode 100644 index 00000000000000..fc98f4e19b22a9 --- /dev/null +++ b/packages/element/src/test/platform.js @@ -0,0 +1,19 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; +/** + * Internal dependencies + */ +import Platform from '../platform'; + +describe( 'Platform', () => { + it( 'is chooses the right thing', () => { + const element = Platform.select( { + web: shallow( <div></div> ), + native: shallow( <button></button> ), + } ); + + expect( element.type() ).toBe( 'div' ); + } ); +} ); diff --git a/packages/element/src/test/platform.native.js b/packages/element/src/test/platform.native.js new file mode 100644 index 00000000000000..da6717d66409e0 --- /dev/null +++ b/packages/element/src/test/platform.native.js @@ -0,0 +1,19 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; +/** + * Internal dependencies + */ +import Platform from '../platform'; + +describe( 'Platform', () => { + it( 'is chooses the right thing', () => { + const element = Platform.select( { + web: shallow( <div></div> ), + native: shallow( <button></button> ), + } ); + + expect( element.type() ).toBe( 'button' ); + } ); +} ); diff --git a/packages/env/.npmrc b/packages/env/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/env/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/env/README.md b/packages/env/README.md index 45736ee1fa29bb..1f06dabf9ce710 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -7,7 +7,7 @@ ```sh $ npm -g i @wordpress/env -$ cd path/to/gutenberg # WordPress install will be in path/to/gutenberg-wordpress. +$ cd path/to/plugin-or-theme # WordPress install will be in path/to/plugin-or-theme-wordpress. $ wp-env --help @@ -15,8 +15,10 @@ wp-env <command> Commands: wp-env start [ref] Starts WordPress for development on port 8888 - (​http://localhost:8888​) and tests on port 8889 - (​http://localhost:8889​). If the current working + (​http://localhost:8888​) (override with + WP_ENV_PORT) and tests on port 8889 + (​http://localhost:8889​) (override with + WP_ENV_TESTS_PORT). If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately. @@ -34,10 +36,11 @@ Options: ```sh wp-env start [ref] -Starts WordPress for development on port 8888 (​http://localhost:8888​) and -tests on port 8889 (​http://localhost:8889​). If the current working directory -is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be -mounted appropiately. +Starts WordPress for development on port 8888 (​http://localhost:8888​) +(override with WP_ENV_PORT) and tests on port 8889 (​http://localhost:8889​) +(override with WP_ENV_TESTS_PORT). If the current working directory is a plugin +and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted +appropiately. Positionals: ref A `https://github.com/WordPress/WordPress` git repo branch or commit for @@ -63,3 +66,5 @@ Positionals: environment Which environments' databases to clean. [string] [choices: "all", "development", "tests"] [default: "tests"] ``` + +<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p> diff --git a/packages/env/lib/cli.js b/packages/env/lib/cli.js index 6f134afd9ae421..98dc1ecb42ce26 100644 --- a/packages/env/lib/cli.js +++ b/packages/env/lib/cli.js @@ -46,10 +46,10 @@ module.exports = function cli() { chalk`Starts WordPress for development on port {bold.underline ${ terminalLink( '8888', 'http://localhost:8888' - ) }} and tests on port {bold.underline ${ terminalLink( + ) }} (override with WP_ENV_PORT) and tests on port {bold.underline ${ terminalLink( '8889', 'http://localhost:8889' - ) }}. If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately.` + ) }} (override with WP_ENV_TESTS_PORT). If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately.` ), ( args ) => { args.positional( 'ref', { diff --git a/packages/env/lib/create-docker-compose-config.js b/packages/env/lib/create-docker-compose-config.js index 7a3dfc7d33b6aa..f5971723148b57 100644 --- a/packages/env/lib/create-docker-compose-config.js +++ b/packages/env/lib/create-docker-compose-config.js @@ -1,17 +1,18 @@ module.exports = function createDockerComposeConfig( - pluginPath, - pluginName, - pluginTestsPath + cwd, + cwdName, + cwdTestsPath, + context ) { const commonVolumes = ` - - ${ pluginPath }/:/var/www/html/wp-content/plugins/${ pluginName }/ - - ${ pluginPath }${ pluginTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ - - ${ pluginPath }${ pluginTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ pluginName }-test-plugins/`; + - ${ cwd }/:/var/www/html/wp-content/${ context.type }s/${ cwdName }/ + - ${ cwd }${ cwdTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ + - ${ cwd }${ cwdTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ cwdName }-test-plugins/`; const volumes = ` - - ${ pluginPath }/../${ pluginName }-wordpress/:/var/www/html/${ commonVolumes }`; + - ${ cwd }/../${ cwdName }-wordpress/:/var/www/html/${ commonVolumes }`; const testsVolumes = ` - tests-wordpress:/var/www/html/${ commonVolumes }`; - return `version: '2' + return `version: '2.1' volumes: tests-wordpress: services: @@ -28,7 +29,7 @@ services: WORDPRESS_DB_PASSWORD: password image: wordpress ports: - - 8888:80 + - \${WP_ENV_PORT:-8888}:80 volumes:${ volumes } wordpress-cli: depends_on: @@ -44,7 +45,7 @@ services: WORDPRESS_DB_PASSWORD: password image: wordpress ports: - - 8889:80 + - \${WP_ENV_TESTS_PORT:-8889}:80 volumes:${ testsVolumes } tests-wordpress-cli: depends_on: diff --git a/packages/env/lib/detect-context.js b/packages/env/lib/detect-context.js new file mode 100644 index 00000000000000..afc23f6dd5f6f3 --- /dev/null +++ b/packages/env/lib/detect-context.js @@ -0,0 +1,45 @@ +'use strict'; +/** + * External dependencies + */ +const util = require( 'util' ); +const fs = require( 'fs' ); +const stream = require( 'stream' ); +const path = require( 'path' ); + +/** + * Promisified dependencies + */ +const readDir = util.promisify( fs.readdir ); +const finished = util.promisify( stream.finished ); + +module.exports = async function detectContext() { + const context = {}; + + // Race multiple file read streams against each other until + // a plugin or theme header is found. + const files = ( await readDir( './' ) ).filter( + ( file ) => path.extname( file ) === '.php' || path.basename( file ) === 'style.css' + ); + const streams = []; + for ( const file of files ) { + const fileStream = fs.createReadStream( file, 'utf8' ); + fileStream.on( 'data', ( text ) => { + const [ , type ] = text.match( /(Plugin|Theme) Name: .*[\r\n]/ ) || []; + if ( type ) { + context.type = type.toLowerCase(); + + // Stop the creation of new streams by mutating the iterated array. We can't `break`, because we are inside a function. + files.splice( 0 ); + fileStream.destroy(); + streams.forEach( ( otherFileStream ) => otherFileStream.destroy() ); + } + } ); + streams.push( fileStream ); + } + await Promise.all( + streams.map( ( fileStream ) => finished( fileStream ).catch( () => {} ) ) + ); + + return context; +}; diff --git a/packages/env/lib/env.js b/packages/env/lib/env.js index 159bb2ac2fc45f..c2ba83ac24c221 100644 --- a/packages/env/lib/env.js +++ b/packages/env/lib/env.js @@ -11,12 +11,13 @@ const wait = require( 'util' ).promisify( setTimeout ); /** * Internal dependencies */ +const detectContext = require( './detect-context' ); const createDockerComposeConfig = require( './create-docker-compose-config' ); // Config Variables -const pluginPath = process.cwd(); -const pluginName = path.basename( pluginPath ); -const pluginTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; +const cwd = process.cwd(); +const cwdName = path.basename( cwd ); +const cwdTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; const dockerComposeOptions = { config: path.join( __dirname, 'docker-compose.yml' ), }; @@ -30,18 +31,22 @@ const wpCliRun = ( command, isTests = false ) => ); const setupSite = ( isTests = false ) => wpCliRun( - `wp core install --url=localhost:888${ - isTests ? '9' : '8' - } --title=Gutenberg --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, + `wp core install --url=localhost:${ + isTests ? + process.env.WP_ENV_TESTS_PORT || 8889 : + process.env.WP_ENV_PORT || 8888 + } --title=${ cwdName } --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, isTests ); -const activatePlugin = ( isTests = false ) => - wpCliRun( `wp plugin activate ${ pluginName }`, isTests ); +const activateContext = ( context, isTests = false ) => + wpCliRun( `wp ${ context.type } activate ${ cwdName }`, isTests ); const resetDatabase = ( isTests = false ) => wpCliRun( 'wp db reset --yes', isTests ); module.exports = { async start( { ref, spinner = {} } ) { + const context = await detectContext(); + spinner.text = `Downloading WordPress@${ ref } 0/100%.`; const gitFetchOptions = { fetchOpts: { @@ -62,7 +67,7 @@ module.exports = { }; // Clone or get the repo. - const repoPath = `../${ pluginName }-wordpress/`; + const repoPath = `../${ cwdName }-wordpress/`; const repo = await NodeGit.Clone( 'https://github.com/WordPress/WordPress.git', repoPath, @@ -92,10 +97,10 @@ module.exports = { } spinner.text = `Downloading WordPress@${ ref } 100/100%.`; - spinner.text = `Installing WordPress@${ ref }.`; + spinner.text = `Starting WordPress@${ ref }.`; fs.writeFileSync( dockerComposeOptions.config, - createDockerComposeConfig( pluginPath, pluginName, pluginTestsPath ) + createDockerComposeConfig( cwd, cwdName, cwdTestsPath, context ) ); // These will bring up the database container, @@ -119,11 +124,14 @@ module.exports = { .catch( retryableSiteSetup ) .catch( retryableSiteSetup ); - await Promise.all( [ activatePlugin(), activatePlugin( true ) ] ); + await Promise.all( [ + activateContext( context ), + activateContext( context, true ), + ] ); // Remove dangling containers and finish. await dockerCompose.rm( dockerComposeOptions ); - spinner.text = `Installed WordPress@${ ref }.`; + spinner.text = `Started WordPress@${ ref }.`; }, async stop( { spinner = {} } ) { @@ -133,6 +141,8 @@ module.exports = { }, async clean( { environment, spinner } ) { + const context = await detectContext(); + const description = `${ environment } environment${ environment === 'all' ? 's' : '' }`; @@ -144,7 +154,7 @@ module.exports = { tasks.push( resetDatabase() .then( setupSite ) - .then( activatePlugin ) + .then( activateContext.bind( null, context ) ) .catch( () => {} ) ); } @@ -152,7 +162,7 @@ module.exports = { tasks.push( resetDatabase( true ) .then( setupSite.bind( null, true ) ) - .then( activatePlugin.bind( null, true ) ) + .then( activateContext.bind( null, context, true ) ) .catch( () => {} ) ); } diff --git a/packages/env/package.json b/packages/env/package.json index 6be0539b3725cf..19f0fe52cdc047 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/env", - "version": "1.0.0", + "version": "0.0.0", "description": "A zero-config, self contained local WordPress environment for development and testing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/env/tests/cli.test.js b/packages/env/test/cli.js similarity index 100% rename from packages/env/tests/cli.test.js rename to packages/env/test/cli.js diff --git a/packages/escape-html/package.json b/packages/escape-html/package.json index b93e62d2a76e42..19d4e1d0b895c5 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "1.5.0", + "version": "1.5.1", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/eslint-plugin/configs/jsdoc.js b/packages/eslint-plugin/configs/jsdoc.js index 614816cb734a21..8e0935dc316881 100644 --- a/packages/eslint-plugin/configs/jsdoc.js +++ b/packages/eslint-plugin/configs/jsdoc.js @@ -1,5 +1,55 @@ +/** + * External dependencies + */ const globals = require( 'globals' ); +/** + * The temporary list of types defined in Gutenberg which are whitelisted to avoid + * ESLint warnings. It should be removed once importing is going to be implemented + * in the tool which generates public APIs from JSDoc comments. Related issue to + * fix the root cause `@wordpress/docgen`: + * https://github.com/WordPress/gutenberg/issues/18045. + */ +const temporaryWordPressInternalTypes = [ + 'WPBlockChildren', + 'WPBlockNode', + 'WPBlockSelection', + 'WPBlockSerializationOptions', + 'WPBlock', + 'WPBlockTypeIcon', + 'WPBlockTypeIconRender', + 'WPBlockTypeIconDescriptor', + 'WPDataPersistencePluginOptions', + 'WPDataPlugin', + 'WPDataRegistry', + 'WPComponent', + 'WPCompleter', + 'WPElement', + 'WPFormat', + 'WPEditorInserterItem', + 'WPNotice', + 'WPNoticeAction', + 'WPPlugin', + 'WPShortcode', + 'WPShortcodeAttrs', + 'WPShortcodeMatch', + 'WPSyntheticEvent', +]; + +/** + * The temporary list of external types used in Gutenberg which are whitelisted + * to avoid ESLint warnings. It's similar to `wordpressInternalTypes` and it + * should be removed once the related issues is fixed: + * https://github.com/WordPress/gutenberg/issues/18045 + */ +const temporaryExternalTypes = [ + 'DOMHighResTimeStamp', + 'espree', + 'moment', + 'puppeteer', + 'react', +]; + /** * Helpful utilities that are globally defined and known to the TypeScript compiler. * @@ -50,6 +100,8 @@ module.exports = { // generally refer to window-level event listeners and are not a valid type to reference (e.g. `onclick`). ...Object.keys( globals.browser ).filter( ( k ) => /^[A-Z]/.test( k ) ), ...typescriptUtilityTypes, + ...temporaryWordPressInternalTypes, + ...temporaryExternalTypes, 'void', ], } ], diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 50605fb08b7508..e7385c46bd2bfc 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "1.9.0", + "version": "1.9.3", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/src/image/style.scss b/packages/format-library/src/image/style.scss index 93bfc96ae7a166..5209377f6448e4 100644 --- a/packages/format-library/src/image/style.scss +++ b/packages/format-library/src/image/style.scss @@ -2,8 +2,11 @@ display: flex; .components-icon-button { - height: $icon-button-size + $grid-size + $grid-size; align-self: flex-end; + height: $grid-size * 4 - ($border-width * 2); + margin-bottom: $grid-size; + margin-right: $grid-size; + padding: 0 6px; } } @@ -15,7 +18,13 @@ min-width: 150px; max-width: 500px; - &.components-base-control .components-base-control__field { - margin-bottom: 0; + &.components-base-control { + .components-base-control__field { + margin-bottom: 0; + } + + .components-base-control__label { + display: block; + } } } diff --git a/packages/is-shallow-equal/package.json b/packages/is-shallow-equal/package.json index 3fabae7a1d053d..a164a7cdbb44f8 100644 --- a/packages/is-shallow-equal/package.json +++ b/packages/is-shallow-equal/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/is-shallow-equal", - "version": "1.6.0", + "version": "1.6.1", "description": "Test for shallow equality between two objects or arrays.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-puppeteer-axe/src/index.js b/packages/jest-puppeteer-axe/src/index.js index 336cec9bcf8161..7bba05d8965d28 100644 --- a/packages/jest-puppeteer-axe/src/index.js +++ b/packages/jest-puppeteer-axe/src/index.js @@ -53,13 +53,13 @@ function formatViolations( violations ) { * * @see https://github.com/dequelabs/axe-puppeteer * - * @param {Page} page Puppeteer's page instance. - * @param {?Object} params Optional Axe API options. - * @param {?string|Array} params.include CSS selector(s) to add to the list of elements - * to include in analysis. - * @param {?string|Array} params.exclude CSS selector(s) to add to the list of elements - * to exclude from analysis. - * @param {?Array} params.disabledRules The list of Axe rules to skip from verification. + * @param {puppeteer.Page} page Puppeteer's page instance. + * @param {?Object} params Optional Axe API options. + * @param {?string|Array} params.include CSS selector(s) to add to the list of elements + * to include in analysis. + * @param {?string|Array} params.exclude CSS selector(s) to add to the list of elements + * to exclude from analysis. + * @param {?Array} params.disabledRules The list of Axe rules to skip from verification. * * @return {Object} A matcher object with two keys `pass` and `message`. */ diff --git a/packages/keycodes/package.json b/packages/keycodes/package.json index ba8a5cbe103060..a62da6c45f89ba 100644 --- a/packages/keycodes/package.json +++ b/packages/keycodes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keycodes", - "version": "2.6.0", + "version": "2.6.2", "description": "Keycodes utilities for WordPress. Used to check for keyboard events across browsers/operating systems.", "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 6df9f6a7b996a0..54c7773292205d 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.8.0", + "version": "1.8.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/media-utils/package.json b/packages/media-utils/package.json index 90ecc22a60a0c6..7d6af3e41f63ba 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/media-utils", - "version": "1.2.0", + "version": "1.2.3", "description": "WordPress Media Upload Utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/media-utils/src/components/media-upload/index.js b/packages/media-utils/src/components/media-upload/index.js index 0ba3db65fd43b1..eac379f9ebb68d 100644 --- a/packages/media-utils/src/components/media-upload/index.js +++ b/packages/media-utils/src/components/media-upload/index.js @@ -125,9 +125,6 @@ class MediaUpload extends Component { } else { const frameConfig = { title, - button: { - text: __( 'Select' ), - }, multiple, }; if ( !! allowedTypes ) { diff --git a/packages/notices/package.json b/packages/notices/package.json index ed582e8ca7dc50..6840e145531d50 100644 --- a/packages/notices/package.json +++ b/packages/notices/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/notices", - "version": "1.8.0", + "version": "1.8.2", "description": "State management for notices.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/notices/src/store/actions.js b/packages/notices/src/store/actions.js index f1771b6ca8ae2f..0fed89a60e0f31 100644 --- a/packages/notices/src/store/actions.js +++ b/packages/notices/src/store/actions.js @@ -8,6 +8,17 @@ import { uniqueId } from 'lodash'; */ import { DEFAULT_CONTEXT, DEFAULT_STATUS } from './constants'; +/** + * @typedef {Object} WPNoticeAction Object describing a user action option associated with a notice. + * + * @property {string} label Message to use as action label. + * @property {?string} url Optional URL of resource if action incurs + * browser navigation. + * @property {?Function} onClick Optional function to invoke when action is + * triggered by user. + * + */ + /** * Yields action objects used in signalling that a notice is to be created. * diff --git a/packages/notices/src/store/selectors.js b/packages/notices/src/store/selectors.js index 3a0bc75ad0f02a..358a159aa8dc66 100644 --- a/packages/notices/src/store/selectors.js +++ b/packages/notices/src/store/selectors.js @@ -38,17 +38,6 @@ const DEFAULT_NOTICES = []; * */ -/** - * @typedef {Object} WPNoticeAction Object describing a user action option associated with a notice. - * - * @property {string} label Message to use as action label. - * @property {?string} url Optional URL of resource if action incurs - * browser navigation. - * @property {?Function} onClick Optional function to invoke when action is - * triggered by user. - * - */ - /** * Returns all notices as an array, optionally for a given context. Defaults to * the global context. diff --git a/packages/nux/package.json b/packages/nux/package.json index 858ddc289df131..913a16112bc36a 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "3.7.0", + "version": "3.7.2", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/src/store/selectors.js b/packages/nux/src/store/selectors.js index 9225bd97077eee..58decf89455191 100644 --- a/packages/nux/src/store/selectors.js +++ b/packages/nux/src/store/selectors.js @@ -7,7 +7,7 @@ import { includes, difference, keys, has } from 'lodash'; /** * An object containing information about a guide. * - * @typedef {Object} NUX.GuideInfo + * @typedef {Object} NUXGuideInfo * @property {string[]} tipIds Which tips the guide contains. * @property {?string} currentTipId The guide's currently showing tip. * @property {?string} nextTipId The guide's next tip to show. @@ -20,7 +20,7 @@ import { includes, difference, keys, has } from 'lodash'; * @param {Object} state Global application state. * @param {string} tipId The tip to query. * - * @return {?NUX.GuideInfo} Information about the associated guide. + * @return {?NUXGuideInfo} Information about the associated guide. */ export const getAssociatedGuide = createSelector( ( state, tipId ) => { diff --git a/packages/plugins/README.md b/packages/plugins/README.md index 2875c76b0fa8da..9bf049e1bc6abc 100644 --- a/packages/plugins/README.md +++ b/packages/plugins/README.md @@ -26,7 +26,7 @@ _Parameters_ _Returns_ -- `?Object`: Plugin setting. +- `?WPPlugin`: Plugin setting. <a name="getPlugins" href="#getPlugins">#</a> **getPlugins** @@ -34,7 +34,7 @@ Returns all registered plugins. _Returns_ -- `Array`: Plugin settings. +- `Array<WPPlugin>`: Plugin settings. <a name="PluginArea" href="#PluginArea">#</a> **PluginArea** @@ -71,7 +71,7 @@ const Layout = () => ( _Returns_ -- `WPElement`: Plugin area. +- `WPComponent`: The component to be rendered. <a name="registerPlugin" href="#registerPlugin">#</a> **registerPlugin** @@ -143,14 +143,12 @@ registerPlugin( 'plugin-name', { _Parameters_ -- _name_ `string`: A string identifying the plugin. Must be unique across all registered plugins. -- _settings_ `Object`: The settings for this plugin. -- _settings.icon_ `(string|WPElement|Function)`: An icon to be shown in the UI. It can be a slug of the Dashicon, or an element (or function returning an element) if you choose to render your own SVG. -- _settings.render_ `Function`: A component containing the UI elements to be rendered. +- _name_ `string`: A string identifying the plugin.Must be unique across all registered plugins. +- _settings_ `WPPlugin`: The settings for this plugin. _Returns_ -- `Object`: The final plugin settings object. +- `WPPlugin`: The final plugin settings object. <a name="unregisterPlugin" href="#unregisterPlugin">#</a> **unregisterPlugin** @@ -191,7 +189,7 @@ _Parameters_ _Returns_ -- `Component`: Enhanced component with injected context as props. +- `WPComponent`: Enhanced component with injected context as props. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/plugins/package.json b/packages/plugins/package.json index f935e31b1b3de5..3c8ca7edfcb63e 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/plugins", - "version": "2.7.0", + "version": "2.7.2", "description": "Plugins module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/plugins/src/api/index.js b/packages/plugins/src/api/index.js index 6e6ea102a80ffd..5e8fe1d19c851d 100644 --- a/packages/plugins/src/api/index.js +++ b/packages/plugins/src/api/index.js @@ -10,6 +10,22 @@ import { applyFilters, doAction } from '@wordpress/hooks'; */ import { isFunction } from 'lodash'; +/** + * Defined behavior of a plugin type. + * + * @typedef {Object} WPPlugin + * + * @property {string} name A string identifying the plugin. Must be + * unique across all registered plugins. + * unique across all registered plugins. + * @property {string|WPElement|Function} icon An icon to be shown in the UI. It can + * be a slug of the Dashicon, or an element + * (or function returning an element) if you + * choose to render your own SVG. + * @property {Function} render A component containing the UI elements + * to be rendered. + */ + /** * Plugin definitions keyed by plugin name. * @@ -20,11 +36,9 @@ const plugins = {}; /** * Registers a plugin to the editor. * - * @param {string} name A string identifying the plugin. Must be unique across all registered plugins. - * @param {Object} settings The settings for this plugin. - * @param {string|WPElement|Function} settings.icon An icon to be shown in the UI. It can be a slug of the Dashicon, - * or an element (or function returning an element) if you choose to render your own SVG. - * @param {Function} settings.render A component containing the UI elements to be rendered. + * @param {string} name A string identifying the plugin.Must be + * unique across all registered plugins. + * @param {WPPlugin} settings The settings for this plugin. * * @example <caption>ES5</caption> * ```js @@ -90,7 +104,7 @@ const plugins = {}; * } ); * ``` * - * @return {Object} The final plugin settings object. + * @return {WPPlugin} The final plugin settings object. */ export function registerPlugin( name, settings ) { if ( typeof settings !== 'object' ) { @@ -181,7 +195,7 @@ export function unregisterPlugin( name ) { * * @param {string} name Plugin name. * - * @return {?Object} Plugin setting. + * @return {?WPPlugin} Plugin setting. */ export function getPlugin( name ) { return plugins[ name ]; @@ -190,7 +204,7 @@ export function getPlugin( name ) { /** * Returns all registered plugins. * - * @return {Array} Plugin settings. + * @return {WPPlugin[]} Plugin settings. */ export function getPlugins() { return Object.values( plugins ); diff --git a/packages/plugins/src/components/plugin-area/index.js b/packages/plugins/src/components/plugin-area/index.js index 1cf6f15b528795..e03e5458d50ef4 100644 --- a/packages/plugins/src/components/plugin-area/index.js +++ b/packages/plugins/src/components/plugin-area/index.js @@ -47,7 +47,7 @@ import { getPlugins } from '../../api'; * ); * ``` * - * @return {WPElement} Plugin area. + * @return {WPComponent} The component to be rendered. */ class PluginArea extends Component { constructor() { diff --git a/packages/plugins/src/components/plugin-context/index.js b/packages/plugins/src/components/plugin-context/index.js index 75fb1b8f1dea01..586891c67eb4ee 100644 --- a/packages/plugins/src/components/plugin-context/index.js +++ b/packages/plugins/src/components/plugin-context/index.js @@ -19,7 +19,7 @@ export { Provider as PluginContextProvider }; * expected to return object of props to * merge with the component's own props. * - * @return {Component} Enhanced component with injected context as props. + * @return {WPComponent} Enhanced component with injected context as props. */ export const withPluginContext = ( mapContextToProps ) => createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/priority-queue/package.json b/packages/priority-queue/package.json index 16f8dbd988281f..de49d37c2fe9c3 100644 --- a/packages/priority-queue/package.json +++ b/packages/priority-queue/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/priority-queue", - "version": "1.3.0", + "version": "1.3.1", "description": "Generic browser priority queue.", "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 ee2c7d728eac8a..29e53534cf6cd8 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/redux-routine", - "version": "3.6.0", + "version": "3.6.2", "description": "Redux middleware for generator coroutines.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 46a78502ff3ed4..e911c714792064 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -216,11 +216,7 @@ behavior. _Parameters_ - _name_ `string`: Format name. -- _settings_ `Object`: Format settings. -- _settings.tagName_ `string`: The HTML tag this format will wrap the selection with. -- _settings.className_ `[string]`: A class to match the format. -- _settings.title_ `string`: Name of the format. -- _settings.edit_ `Function`: Should return a component for the user to interact with the new registered format. +- _settings_ `WPFormat`: Format settings. _Returns_ diff --git a/packages/rich-text/package.json b/packages/rich-text/package.json index 544d69294e90e4..4cf3ef016ddaf3 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/rich-text", - "version": "3.7.0", + "version": "3.7.2", "description": "Rich text value and manipulation API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/src/component/index.js b/packages/rich-text/src/component/index.js index c82feae869d1e7..c3112d3337fb78 100644 --- a/packages/rich-text/src/component/index.js +++ b/packages/rich-text/src/component/index.js @@ -35,6 +35,7 @@ import { indentListItems } from '../indent-list-items'; import { getActiveFormats } from '../get-active-formats'; import { updateFormats } from '../update-formats'; import { removeLineSeparator } from '../remove-line-separator'; +import { isEmptyLine } from '../is-empty'; /** * Browser dependencies @@ -204,7 +205,7 @@ class RichText extends Component { * * Saves the pasted data as plain text in `pastedPlainText`. * - * @param {PasteEvent} event The paste event. + * @param {ClipboardEvent} event The paste event. */ onPaste( event ) { const { formatTypes, onPaste } = this.props; @@ -258,18 +259,32 @@ class RichText extends Component { } if ( onPaste ) { - // Only process file if no HTML is present. - // Note: a pasted file may have the URL as plain text. - const image = find( [ ...items, ...files ], ( { type } ) => - /^image\/(?:jpe?g|png|gif)$/.test( type ) - ); + files = Array.from( files ); + + Array.from( items ).forEach( ( item ) => { + if ( ! item.getAsFile ) { + return; + } + + const file = item.getAsFile(); + + if ( ! file ) { + return; + } + + const { name, type, size } = file; + + if ( ! find( files, { name, type, size } ) ) { + files.push( file ); + } + } ); onPaste( { value: this.removeEditorOnlyFormats( record ), onChange: this.onChange, html, plainText, - image, + files, } ); } } @@ -337,7 +352,7 @@ class RichText extends Component { /** * Handle input on the next selection change event. * - * @param {SyntheticEvent} event Synthetic input event. + * @param {WPSyntheticEvent} event Synthetic input event. */ onInput( event ) { // For Input Method Editor (IME), used in Chinese, Japanese, and Korean @@ -437,7 +452,7 @@ class RichText extends Component { * native events, `keyup`, `mouseup` and `touchend` synthetic events, and * animation frames after the `focus` event. * - * @param {Event|SyntheticEvent|DOMHighResTimeStamp} event + * @param {Event|WPSyntheticEvent|DOMHighResTimeStamp} event */ onSelectionChange( event ) { if ( @@ -579,7 +594,7 @@ class RichText extends Component { * - delete content if everything is selected, * - trigger the onDelete prop when selection is uncollapsed and at an edge. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleDelete( event ) { const { keyCode } = event; @@ -604,14 +619,6 @@ class RichText extends Component { const { start, end, text } = value; const isReverse = keyCode === BACKSPACE; - if ( multilineTag ) { - const newValue = removeLineSeparator( value, isReverse ); - if ( newValue ) { - this.onChange( newValue ); - event.preventDefault(); - } - } - // Always handle full content deletion ourselves. if ( start === 0 && end !== 0 && end === text.length ) { this.onChange( remove( value ) ); @@ -619,6 +626,23 @@ class RichText extends Component { return; } + if ( multilineTag ) { + let newValue; + + // Check to see if we should remove the first item if empty. + if ( isReverse && value.start === 0 && value.end === 0 && isEmptyLine( value ) ) { + newValue = removeLineSeparator( value, ! isReverse ); + } else { + newValue = removeLineSeparator( value, isReverse ); + } + + if ( newValue ) { + this.onChange( newValue ); + event.preventDefault(); + return; + } + } + // Only process delete if the key press occurs at an uncollapsed edge. if ( ! onDelete || @@ -637,7 +661,7 @@ class RichText extends Component { /** * Triggers the `onEnter` prop on keydown. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleEnter( event ) { if ( event.keyCode !== ENTER ) { @@ -662,7 +686,7 @@ class RichText extends Component { /** * Indents list items on space keydown. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleSpace( event ) { const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; @@ -699,7 +723,7 @@ class RichText extends Component { * navigation is handled separately to move correctly around format * boundaries. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleHorizontalNavigation( event ) { const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; @@ -805,7 +829,7 @@ class RichText extends Component { * Select object when they are clicked. The browser will not set any * selection when clicking e.g. an image. * - * @param {SyntheticEvent} event Synthetic mousedown or touchstart event. + * @param {WPSyntheticEvent} event Synthetic mousedown or touchstart event. */ onPointerDown( event ) { const { target } = event; diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 09ac451ed56d23..34a1b03fe24ef2 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -30,10 +30,7 @@ import { getActiveFormat } from '../get-active-format'; import { getActiveFormats } from '../get-active-formats'; import { isEmpty, isEmptyLine } from '../is-empty'; import { create } from '../create'; -import { split } from '../split'; import { toHTMLString } from '../to-html-string'; -import { insert } from '../insert'; -import { insertLineSeparator } from '../insert-line-separator'; import { removeLineSeparator } from '../remove-line-separator'; import { isCollapsed } from '../is-collapsed'; import { remove } from '../remove'; @@ -43,28 +40,6 @@ const unescapeSpaces = ( text ) => { return text.replace( /&nbsp;|&#160;/gi, ' ' ); }; -/** - * Calls {@link pasteHandler} with a fallback to plain text when HTML processing - * results in errors - * - * @param {Function} originalPasteHandler The original handler function - * @param {Object} [options] The options to pass to {@link pasteHandler} - * - * @return {Array|string} A list of blocks or a string, depending on - * `handlerMode`. - */ -const saferPasteHandler = ( originalPasteHandler, options ) => { - try { - return originalPasteHandler( options ); - } catch ( error ) { - window.console.log( 'Pasting HTML failed:', error ); - window.console.log( 'HTML:', options.HTML ); - window.console.log( 'Falling back to plain text.' ); - // fallback to plain text - return originalPasteHandler( { ...options, HTML: '' } ); - } -}; - const gutenbergFormatNamesToAztec = { 'core/bold': 'bold', 'core/italic': 'italic', @@ -72,7 +47,7 @@ const gutenbergFormatNamesToAztec = { }; export class RichText extends Component { - constructor( { value, __unstableMultiline: multiline, selectionStart, selectionEnd } ) { + constructor( { value, selectionStart, selectionEnd, __unstableMultilineTag: multiline } ) { super( ...arguments ); this.isMultiline = false; @@ -84,12 +59,12 @@ export class RichText extends Component { if ( this.multilineTag === 'li' ) { this.multilineWrapperTags = [ 'ul', 'ol' ]; } - this.onSplit = this.onSplit.bind( this ); + this.isIOS = Platform.OS === 'ios'; this.createRecord = this.createRecord.bind( this ); this.onChange = this.onChange.bind( this ); - this.onEnter = this.onEnter.bind( this ); - this.onBackspace = this.onBackspace.bind( this ); + this.handleEnter = this.handleEnter.bind( this ); + this.handleDelete = this.handleDelete.bind( this ); this.onPaste = this.onPaste.bind( this ); this.onFocus = this.onFocus.bind( this ); this.onBlur = this.onBlur.bind( this ); @@ -169,63 +144,6 @@ export class RichText extends Component { return { ...value, start, end }; } - /** - * Signals to the RichText owner that the block can be replaced with two - * blocks as a result of splitting the block by pressing enter, or with - * blocks as a result of splitting the block by pasting block content in the - * instance. - * - * @param {Object} record The rich text value to split. - * @param {Array} pastedBlocks The pasted blocks to insert, if any. - */ - onSplit( record, pastedBlocks = [] ) { - const { - __unstableOnReplace: onReplace, - __unstableOnSplit: onSplit, - __unstableOnSplitMiddle: onSplitMiddle, - } = this.props; - - if ( ! onReplace || ! onSplit ) { - return; - } - - const blocks = []; - const [ before, after ] = split( record ); - const hasPastedBlocks = pastedBlocks.length > 0; - - // Create a block with the content before the caret if there's no pasted - // blocks, or if there are pasted blocks and the value is not empty. - // We do not want a leading empty block on paste, but we do if split - // with e.g. the enter key. - if ( ! hasPastedBlocks || ! isEmpty( before ) ) { - blocks.push( onSplit( this.valueToFormat( before ) ) ); - } - - if ( hasPastedBlocks ) { - blocks.push( ...pastedBlocks ); - } else if ( onSplitMiddle ) { - blocks.push( onSplitMiddle() ); - } - - // If there's pasted blocks, append a block with the content after the - // caret. Otherwise, do append and empty block if there is no - // `onSplitMiddle` prop, but if there is and the content is empty, the - // middle block is enough to set focus in. - if ( hasPastedBlocks || ! onSplitMiddle || ! isEmpty( after ) ) { - blocks.push( onSplit( this.valueToFormat( after ) ) ); - } - - // If there are pasted blocks, set the selection to the last one. - // Otherwise, set the selection to the second block. - const indexToSelect = hasPastedBlocks ? blocks.length - 1 : 1; - // The onSplit event can cause a content update event for this block. Such event should - // definitely be processed by our native components, since they have no knowledge of - // how the split works. Setting lastEventCount to undefined forces the native component to - // always update when provided with new content. - this.lastEventCount = undefined; - onReplace( blocks, indexToSelect ); - } - valueToFormat( value ) { // remove the outer root tags return this.removeRootTagsProduceByAztec( toHTMLString( { @@ -245,6 +163,7 @@ export class RichText extends Component { } onFormatChange( record ) { + this.getRecord( record ); const { start, end, activeFormats = [] } = record; const changeHandlers = pickBy( this.props, ( v, key ) => key.startsWith( 'format_on_change_functions_' ) @@ -346,92 +265,67 @@ export class RichText extends Component { this.lastAztecEventType = 'content size change'; } - onEnter( event ) { - if ( this.props.onEnter ) { - this.props.onEnter(); + handleEnter( event ) { + const { onEnter } = this.props; + + if ( ! onEnter ) { return; } - const { - __unstableOnReplace: onReplace, - __unstableOnSplit: onSplit, - } = this.props; - this.lastEventCount = event.nativeEvent.eventCount; - this.comesFromAztec = true; - this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; - - const canSplit = onReplace && onSplit; - const currentRecord = this.createRecord(); - if ( this.multilineTag ) { - if ( event.shiftKey ) { - this.needsSelectionUpdate = true; - const insertedLineBreak = { ...insert( currentRecord, '\n' ) }; - this.onFormatChange( insertedLineBreak ); - } else if ( canSplit && isEmptyLine( currentRecord ) ) { - this.onSplit( currentRecord ); - } else { - this.needsSelectionUpdate = true; - const insertedLineSeparator = { ...insertLineSeparator( currentRecord ) }; - this.onFormatChange( insertedLineSeparator ); - } - } else if ( event.shiftKey || ! onSplit ) { - this.needsSelectionUpdate = true; - const insertedLineBreak = { ...insert( currentRecord, '\n' ) }; - this.onFormatChange( insertedLineBreak ); - } else { - this.onSplit( currentRecord ); - } + onEnter( { + value: this.createRecord(), + onChange: this.onFormatChange, + shiftKey: event.shiftKey, + } ); this.lastAztecEventType = 'input'; } - onBackspace( event ) { - const { - __unstableOnMerge: onMerge, - __unstableOnRemove: onRemove, - onChange, - } = this.props; - if ( ! onMerge && ! onRemove ) { - return; - } - + handleDelete( event ) { const keyCode = BACKSPACE; // TODO : should we differentiate BACKSPACE and DELETE? const isReverse = keyCode === BACKSPACE; + const { onDelete, __unstableMultilineTag: multilineTag } = this.props; + const { activeFormats = [] } = this.state; this.lastEventCount = event.nativeEvent.eventCount; this.comesFromAztec = true; this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; const value = this.createRecord(); - const { start, end } = value; + const { start, end, text } = value; let newValue; // Always handle full content deletion ourselves. - if ( start === 0 && end !== 0 && end >= value.text.length ) { - newValue = remove( value, start, end ); - onChange( newValue ); + if ( start === 0 && end !== 0 && end >= text.length ) { + newValue = remove( value ); + this.onFormatChange( newValue ); + event.preventDefault(); return; } - if ( this.multilineTag ) { - newValue = removeLineSeparator( value, keyCode === BACKSPACE ); + if ( multilineTag ) { + if ( isReverse && value.start === 0 && value.end === 0 && isEmptyLine( value ) ) { + newValue = removeLineSeparator( value, ! isReverse ); + } else { + newValue = removeLineSeparator( value, isReverse ); + } if ( newValue ) { this.onFormatChange( newValue ); + event.preventDefault(); return; } } - const empty = this.isEmpty(); - - if ( onMerge ) { - onMerge( ! isReverse ); + // Only process delete if the key press occurs at an uncollapsed edge. + if ( + ! onDelete || + ! isCollapsed( value ) || + activeFormats.length || + ( isReverse && start !== 0 ) || + ( ! isReverse && end !== text.length ) + ) { + return; } - // Only handle remove on Backspace. This serves dual-purpose of being - // an intentional user interaction distinguishing between Backspace and - // Delete to remove the empty field, but also to avoid merge & remove - // causing destruction of two fields (merge, then removed merged). - if ( onRemove && empty && isReverse ) { - onRemove( ! isReverse ); - } + onDelete( { isReverse, value } ); event.preventDefault(); this.lastAztecEventType = 'input'; @@ -444,10 +338,7 @@ export class RichText extends Component { */ onPaste( event ) { const { - tagName, - __unstablePasteHandler: pasteHandler, - __unstableOnReplace: onReplace, - __unstableOnSplit: onSplit, + onPaste, onChange, } = this.props; @@ -456,30 +347,6 @@ export class RichText extends Component { event.preventDefault(); - // Only process file if no HTML is present. - // Note: a pasted file may have the URL as plain text. - if ( files && files.length > 0 ) { - const uploadId = Number.MAX_SAFE_INTEGER; - let html = ''; - files.forEach( ( file ) => { - html += `<img src="${ file }" class="wp-image-${ uploadId }">`; - } ); - const content = pasteHandler( { - HTML: html, - mode: 'BLOCKS', - tagName, - } ); - const shouldReplace = onReplace && this.isEmpty(); - - if ( shouldReplace ) { - onReplace( content ); - } else { - this.onSplit( currentRecord, content ); - } - - return; - } - // There is a selection, check if a URL is pasted. if ( ! isCollapsed( currentRecord ) ) { const trimmedText = ( pastedHtml || pastedText ).replace( /<[^>]+>/g, '' ) @@ -503,46 +370,14 @@ export class RichText extends Component { } } - const shouldReplace = this.props.onReplace && this.isEmpty(); - - let mode = 'INLINE'; - - if ( shouldReplace ) { - mode = 'BLOCKS'; - } else if ( onSplit ) { - mode = 'AUTO'; - } - - const pastedContent = saferPasteHandler( pasteHandler, { - HTML: pastedHtml, - plainText: pastedText, - mode, - tagName: this.props.tagName, - canUserUseUnfilteredHTML: this.props.canUserUseUnfilteredHTML, - } ); - - if ( typeof pastedContent === 'string' ) { - const recordToInsert = create( { html: pastedContent } ); - const resultingRecord = insert( currentRecord, recordToInsert ); - const resultingContent = this.valueToFormat( resultingRecord ); - - this.lastEventCount = undefined; - this.value = resultingContent; - - // explicitly set selection after inline paste - this.onSelectionChange( resultingRecord.start, resultingRecord.end ); - - onChange( this.value ); - } else if ( onSplit ) { - if ( ! pastedContent.length ) { - return; - } - - if ( shouldReplace ) { - onReplace( pastedContent ); - } else { - this.onSplit( currentRecord, pastedContent ); - } + if ( onPaste ) { + onPaste( { + value: currentRecord, + onChange: this.onFormatChange, + html: pastedHtml, + plainText: pastedText, + files, + } ); } } @@ -759,7 +594,7 @@ export class RichText extends Component { this.lastEventCount = undefined; // force a refresh on the native side value = ''; } - // On android if content is empty we need to send no content or else the placeholder with not show. + // On android if content is empty we need to send no content or else the placeholder will not show. if ( ! this.isIOS && value === '' ) { return value; } @@ -852,8 +687,8 @@ export class RichText extends Component { onChange={ this.onChange } onFocus={ this.onFocus } onBlur={ this.onBlur } - onEnter={ this.onEnter } - onBackspace={ this.onBackspace } + onEnter={ this.handleEnter } + onBackspace={ this.handleDelete } onPaste={ this.onPaste } activeFormats={ this.getActiveFormatNames( record ) } onContentSizeChange={ this.onContentSizeChange } diff --git a/packages/rich-text/src/component/test/index.native.js b/packages/rich-text/src/component/test/index.native.js index 6b2bc12f855ffa..22ee6b118bb2d2 100644 --- a/packages/rich-text/src/component/test/index.native.js +++ b/packages/rich-text/src/component/test/index.native.js @@ -1,17 +1,8 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - /** * Internal dependencies */ import { RichText } from '../index'; -const getStylesFromColorScheme = () => { - return { color: 'white' }; -}; - describe( 'RichText Native', () => { let richText; @@ -33,29 +24,4 @@ describe( 'RichText Native', () => { expect( richText.willTrimSpaces( html ) ).toBe( false ); } ); } ); - - describe( 'Adds new line on Enter', () => { - let newValue; - const wrapper = shallow( <RichText - rootTagsToEliminate={ [ 'p' ] } - value="" - onChange={ ( value ) => { - newValue = value; - } } - formatTypes={ [] } - onSelectionChange={ jest.fn() } - getStylesFromColorScheme={ getStylesFromColorScheme } - /> ); - - const event = { - nativeEvent: { - eventCount: 0, - }, - }; - wrapper.instance().onEnter( event ); - - it( ' Adds <br> tag to content after pressing Enter key', () => { - expect( newValue ).toEqual( '<br>' ); - } ); - } ); } ); diff --git a/packages/rich-text/src/register-format-type.js b/packages/rich-text/src/register-format-type.js index e6efc99f5fec97..84a158167b860f 100644 --- a/packages/rich-text/src/register-format-type.js +++ b/packages/rich-text/src/register-format-type.js @@ -10,16 +10,25 @@ import { select, dispatch, withSelect, withDispatch } from '@wordpress/data'; import { addFilter } from '@wordpress/hooks'; import { compose } from '@wordpress/compose'; +/** + * @typedef {Object} WPFormat + * + * @property {string} name A string identifying the format. Must be + * unique across all registered formats. + * @property {string} tagName The HTML tag this format will wrap the + * selection with. + * @property {string} [className] A class to match the format. + * @property {string} title Name of the format. + * @property {Function} edit Should return a component for the user to + * interact with the new registered format. + */ + /** * Registers a new format provided a unique name and an object defining its * behavior. * * @param {string} name Format name. - * @param {Object} settings Format settings. - * @param {string} settings.tagName The HTML tag this format will wrap the selection with. - * @param {string} [settings.className] A class to match the format. - * @param {string} settings.title Name of the format. - * @param {Function} settings.edit Should return a component for the user to interact with the new registered format. + * @param {WPFormat} settings Format settings. * * @return {WPFormat|undefined} The format, if it has been successfully registered; * otherwise `undefined`. diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js index fe97f00d245f53..604ca0c518ec8a 100644 --- a/packages/rich-text/src/test/helpers/index.js +++ b/packages/rich-text/src/test/helpers/index.js @@ -4,7 +4,7 @@ import { ZWNBSP } from '../../special-characters'; export function getSparseArrayLength( array ) { - return array.reduce( ( i ) => i + 1, 0 ); + return array.reduce( ( accumulator ) => accumulator + 1, 0 ); } const em = { type: 'em' }; diff --git a/packages/rich-text/src/to-dom.js b/packages/rich-text/src/to-dom.js index 9d7aed3cfdfd00..730a38587114c4 100644 --- a/packages/rich-text/src/to-dom.js +++ b/packages/rich-text/src/to-dom.js @@ -67,7 +67,7 @@ function getNodeByPath( node, path ) { * each call to `createEmpty`. Therefore, you should not hold a reference to * the value to operate upon asynchronously, as it may have unexpected results. * - * @return {WPRichTextTree} RichText tree. + * @return {Object} RichText tree. */ const createEmpty = () => createElement( document, '' ); diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 96e7ae747107c8..66d7acb086a16b 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -1,5 +1,15 @@ ## Master +### Breaking Changes + +- The bundled `npm-package-json-lint` dependency has been updated from requiring `^3.6.0` to requiring `^4.0.3` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). Please see the [migration guide](https://npmpackagejsonlint.org/docs/en/v3-to-v4). Note: `npmPackageJsonLintConfig` prop in the `package.json` file needs to be renamed to `npmpackagejsonlint`. + +### New Features + +- The bundled `puppeteer` dependency has been updated from requiring `^1.19.0` to requiring `^1.20.0` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). It uses Chromium v78 instead of Chromium v77. + +## 5.1.0 + ### New Features - The bundled `webpack` dependency has been updated from requiring `4.8.3` to requiring `^4.41.0` ([#17746](https://github.com/WordPress/gutenberg/pull/17746)). diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 70d180fb0e2514..cc64a8fb5a713d 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/scripts", - "version": "5.0.0", + "version": "5.1.0", "description": "Collection of reusable scripts for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -50,8 +50,8 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^3.6.0", - "puppeteer": "^1.19.0", + "npm-package-json-lint": "^4.0.3", + "puppeteer": "^1.20.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", "resolve-bin": "^0.4.0", diff --git a/packages/scripts/scripts/lint-pkg-json.js b/packages/scripts/scripts/lint-pkg-json.js index 487a8191067dbc..53e9c42b366437 100644 --- a/packages/scripts/scripts/lint-pkg-json.js +++ b/packages/scripts/scripts/lint-pkg-json.js @@ -25,6 +25,8 @@ const hasLintConfig = hasArgInCLI( '-c' ) || hasArgInCLI( '--configFile' ) || hasProjectFile( '.npmpackagejsonlintrc.json' ) || hasProjectFile( 'npmpackagejsonlint.config.js' ) || + hasPackageProp( 'npmpackagejsonlint' ) || + // npm-package-json-lint v3.x used a different prop name. hasPackageProp( 'npmPackageJsonLintConfig' ); const defaultConfigArgs = ! hasLintConfig ? diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index 99aa8807a8bf6c..39941d137650bf 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "1.3.0", + "version": "1.3.3", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/package.json b/packages/url/package.json index 9c0b1bcaeba066..bc1e8bf3587eb0 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "2.8.0", + "version": "2.8.2", "description": "WordPress URL utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/src/index.js b/packages/url/src/index.js index b4fa34efac51a6..2b549d6ba1dc4e 100644 --- a/packages/url/src/index.js +++ b/packages/url/src/index.js @@ -360,6 +360,10 @@ export function removeQueryArgs( url, ...args ) { * @return {string} The updated URL. */ export function prependHTTP( url ) { + if ( ! url ) { + return url; + } + url = url.trim(); if ( ! USABLE_HREF_REGEXP.test( url ) && ! EMAIL_REGEXP.test( url ) ) { return 'http://' + url; diff --git a/packages/viewport/package.json b/packages/viewport/package.json index 5dd1af95cbe842..5cedb8e675caa4 100644 --- a/packages/viewport/package.json +++ b/packages/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/viewport", - "version": "2.8.0", + "version": "2.8.2", "description": "Viewport module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/wordcount/package.json b/packages/wordcount/package.json index 7201fbdc9760bc..7664cf8b99a0fc 100644 --- a/packages/wordcount/package.json +++ b/packages/wordcount/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/wordcount", - "version": "2.6.0", + "version": "2.6.2", "description": "WordPress word count utility.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/phpunit/class-override-script-test.php b/phpunit/class-override-script-test.php index 034fa2f25a618b..074de00b649ba6 100644 --- a/phpunit/class-override-script-test.php +++ b/phpunit/class-override-script-test.php @@ -28,7 +28,10 @@ function tearDown() { * Tests that script is localized. */ function test_localizes_script() { + global $wp_scripts; + gutenberg_override_script( + $wp_scripts, 'gutenberg-dummy-script', 'https://example.com/', array( 'dependency' ), @@ -36,7 +39,6 @@ function test_localizes_script() { false ); - global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-dummy-script', 'registered' ); $this->assertEquals( array( 'dependency', 'wp-i18n' ), $script->deps ); } @@ -45,7 +47,10 @@ function test_localizes_script() { * Tests that script properties are overridden. */ function test_replaces_registered_properties() { + global $wp_scripts; + gutenberg_override_script( + $wp_scripts, 'gutenberg-dummy-script', 'https://example.com/updated', array( 'updated-dependency' ), @@ -53,19 +58,21 @@ function test_replaces_registered_properties() { true ); - global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-dummy-script', 'registered' ); $this->assertEquals( 'https://example.com/updated', $script->src ); $this->assertEquals( array( 'updated-dependency', 'wp-i18n' ), $script->deps ); $this->assertEquals( 'updated-version', $script->ver ); - $this->assertEquals( 1, $script->extra['group'] ); + $this->assertTrue( $script->args ); } /** * Tests that new script registers normally if no handle by the name. */ function test_registers_new_script() { + global $wp_scripts; + gutenberg_override_script( + $wp_scripts, 'gutenberg-second-dummy-script', 'https://example.com/', array( 'dependency' ), @@ -73,11 +80,10 @@ function test_registers_new_script() { true ); - global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-second-dummy-script', 'registered' ); $this->assertEquals( 'https://example.com/', $script->src ); $this->assertEquals( array( 'dependency', 'wp-i18n' ), $script->deps ); $this->assertEquals( 'version', $script->ver ); - $this->assertEquals( 1, $script->extra['group'] ); + $this->assertTrue( $script->args ); } } diff --git a/playground/.sassrc b/playground/.sassrc new file mode 100644 index 00000000000000..4f704b80b310a5 --- /dev/null +++ b/playground/.sassrc @@ -0,0 +1,5 @@ +{ + "includePaths": [ + "node_modules" + ] +} diff --git a/playground/src/index.js b/playground/src/index.js index b74e30091c1739..66815d8a027256 100644 --- a/playground/src/index.js +++ b/playground/src/index.js @@ -8,10 +8,12 @@ import { BlockEditorKeyboardShortcuts, BlockEditorProvider, BlockList, + BlockInspector, WritingFlow, ObserveTyping, } from '@wordpress/block-editor'; import { + Button, Popover, SlotFillProvider, DropZoneProvider, @@ -40,6 +42,9 @@ function App() { <Fragment> <div className="playground__header"> <h1 className="playground__logo">Gutenberg Playground</h1> + <Button isLarge href="design-system/components" target="_blank"> + Design System Components + </Button> </div> <div className="playground__body"> <SlotFillProvider> @@ -49,6 +54,9 @@ function App() { onInput={ updateBlocks } onChange={ updateBlocks } > + <div className="playground__sidebar"> + <BlockInspector /> + </div> <div className="editor-styles-wrapper"> <BlockEditorKeyboardShortcuts /> <WritingFlow> @@ -67,7 +75,4 @@ function App() { } registerCoreBlocks(); -render( - <App />, - document.querySelector( '#app' ) -); +render( <App />, document.querySelector( '#app' ) ); diff --git a/playground/src/style.scss b/playground/src/style.scss index 63a330e00a2d6f..b6fd8395ac08e8 100644 --- a/playground/src/style.scss +++ b/playground/src/style.scss @@ -1,17 +1,40 @@ -@import "../../assets/stylesheets/colors"; -@import "../../assets/stylesheets/variables"; -@import "../../assets/stylesheets/mixins"; -@import "../../assets/stylesheets/breakpoints"; -@import "../../assets/stylesheets/animations"; -@import "../../assets/stylesheets/z-index"; +@import "~@wordpress/base-styles/colors"; +@import "~@wordpress/base-styles/variables"; +@import "~@wordpress/base-styles/mixins"; +@import "~@wordpress/base-styles/breakpoints"; +@import "~@wordpress/base-styles/animations"; +@import "~@wordpress/base-styles/z-index"; @import "./reset"; @import "./editor-styles"; +$playground-header-height: 95px; .playground__header { - padding: 20px; + align-items: center; border-bottom: 1px solid #ddd; + display: flex; + justify-content: space-between; + padding: 20px; + height: $playground-header-height; +} + +.playground__sidebar { + position: fixed; + top: $playground-header-height; + right: 0; + bottom: 0; + width: $sidebar-width; + border-left: $border-width solid $light-gray-500; + height: auto; + overflow: auto; + -webkit-overflow-scrolling: touch; + + // Temporarily disable the sidebar on mobile + display: none; + @include break-small() { + display: block; + } } .playground__logo { @@ -20,6 +43,9 @@ } .playground__body { + @include break-small() { + width: calc(100% - #{$sidebar-width}); + } padding-top: 20px; img { diff --git a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap index 29b4c95f5806b0..97c607d4d94866 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap @@ -72,3 +72,13 @@ exports[`rawHandler should convert a caption shortcode with link 1`] = ` <figure class=\\"wp-block-image alignnone\\"><a href=\\"http://build.wordpress-develop.test/wp-content/uploads/2011/07/100_5478.jpg\\"><img src=\\"http://build.wordpress-develop.test/wp-content/uploads/2011/07/100_5478.jpg?w=604\\" alt=\\"Bell on Wharf\\" class=\\"wp-image-754\\"/></a><figcaption>Bell on wharf in San Francisco</figcaption></figure> <!-- /wp:image -->" `; + +exports[`rawHandler should convert a list with attributes 1`] = ` +"<!-- wp:list {\\"ordered\\":true,\\"type\\":\\"i\\",\\"start\\":2,\\"reversed\\":true} --> +<ol type=\\"i\\" reversed start=\\"2\\"><li>1 + <ol start=\\"2\\" reversed=\\"\\" type=\\"i\\"> + <li>1</li> + </ol> + </li></ol> +<!-- /wp:list -->" +`; diff --git a/test/integration/blocks-raw-handling.test.js b/test/integration/blocks-raw-handling.test.js index fda576a042cbb3..228c6588ef96b5 100644 --- a/test/integration/blocks-raw-handling.test.js +++ b/test/integration/blocks-raw-handling.test.js @@ -287,4 +287,9 @@ describe( 'rawHandler', () => { const HTML = readFile( path.join( __dirname, 'fixtures/shortcode-caption-with-caption-link.html' ) ); expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); } ); + + it( 'should convert a list with attributes', () => { + const HTML = readFile( path.join( __dirname, 'fixtures/list-with-attributes.html' ) ); + expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); + } ); } ); diff --git a/test/integration/fixtures/google-docs-out.html b/test/integration/fixtures/google-docs-out.html index 576b2cd7fda73f..54a1e07ac1349a 100644 --- a/test/integration/fixtures/google-docs-out.html +++ b/test/integration/fixtures/google-docs-out.html @@ -7,7 +7,7 @@ <h2>This is a <em>heading</em></h2> <!-- /wp:heading --> <!-- wp:paragraph --> -<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, strikethrough, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> +<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, <s>strikethrough</s>, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> <!-- /wp:paragraph --> <!-- wp:list --> diff --git a/test/integration/fixtures/google-docs-with-comments-out.html b/test/integration/fixtures/google-docs-with-comments-out.html index 576b2cd7fda73f..54a1e07ac1349a 100644 --- a/test/integration/fixtures/google-docs-with-comments-out.html +++ b/test/integration/fixtures/google-docs-with-comments-out.html @@ -7,7 +7,7 @@ <h2>This is a <em>heading</em></h2> <!-- /wp:heading --> <!-- wp:paragraph --> -<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, strikethrough, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> +<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, <s>strikethrough</s>, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> <!-- /wp:paragraph --> <!-- wp:list --> diff --git a/test/integration/fixtures/list-with-attributes.html b/test/integration/fixtures/list-with-attributes.html new file mode 100644 index 00000000000000..7114d2da756938 --- /dev/null +++ b/test/integration/fixtures/list-with-attributes.html @@ -0,0 +1,7 @@ +<ol start="2" reversed type="i"> + <li>1 + <ol start="2" reversed type="i"> + <li>1</li> + </ol> + </li> +</ol> diff --git a/test/integration/fixtures/ms-word-out.html b/test/integration/fixtures/ms-word-out.html index 427e12686ad625..47f7cab83ae73f 100644 --- a/test/integration/fixtures/ms-word-out.html +++ b/test/integration/fixtures/ms-word-out.html @@ -24,8 +24,8 @@ <h2>This is a heading level 2</h2> <ul><li>A</li><li>Bulleted<ul><li>Indented</li></ul></li><li>List</li></ul> <!-- /wp:list --> -<!-- wp:list {"ordered":true} --> -<ol><li>One</li><li>Two</li><li>Three</li></ol> +<!-- wp:list {"ordered":true,"type":"1"} --> +<ol type="1"><li>One</li><li>Two</li><li>Three</li></ol> <!-- /wp:list --> <!-- wp:table --> diff --git a/test/integration/full-content/full-content.test.js b/test/integration/full-content/full-content.test.js index 1a50c84a834503..cab70d134b3720 100644 --- a/test/integration/full-content/full-content.test.js +++ b/test/integration/full-content/full-content.test.js @@ -49,7 +49,11 @@ function normalizeParsedBlocks( blocks ) { describe( 'full post content fixture', () => { beforeAll( () => { unstable__bootstrapServerSideBlockDefinitions( require( './server-registered.json' ) ); - const settings = { __experimentalEnableLegacyWidgetBlock: true, __experimentalEnableMenuBlock: true }; + const settings = { + __experimentalEnableLegacyWidgetBlock: true, + __experimentalEnableMenuBlock: true, + __experimentalEnableFullSiteEditing: true, + }; // Load all hooks that modify blocks require( '../../../packages/editor/src/hooks' ); registerCoreBlocks(); diff --git a/test/integration/full-content/server-registered.json b/test/integration/full-content/server-registered.json index e11fe0283b44a5..9d17c64f5d6ba5 100644 --- a/test/integration/full-content/server-registered.json +++ b/test/integration/full-content/server-registered.json @@ -1 +1 @@ -{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/navigation-menu":{"category":"layout","attributes":{"automaticallyAdd":{"type":"boolean","default":false}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file +{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/navigation-menu":{"category":"layout","attributes":{"automaticallyAdd":{"type":"boolean","default":false}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/social-link-amazon":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"amazon"}}},"core\/social-link-bandcamp":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"bandcamp"}}},"core\/social-link-behance":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"behance"}}},"core\/social-link-chain":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"chain"}}},"core\/social-link-codepen":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"codepen"}}},"core\/social-link-deviantart":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"deviantart"}}},"core\/social-link-dribbble":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"dribbble"}}},"core\/social-link-dropbox":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"dropbox"}}},"core\/social-link-etsy":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"etsy"}}},"core\/social-link-facebook":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"facebook"}}},"core\/social-link-feed":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"feed"}}},"core\/social-link-fivehundredpx":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"fivehundredpx"}}},"core\/social-link-flickr":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"flickr"}}},"core\/social-link-foursquare":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"foursquare"}}},"core\/social-link-goodreads":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"goodreads"}}},"core\/social-link-google":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"google"}}},"core\/social-link-github":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"github"}}},"core\/social-link-instagram":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"instagram"}}},"core\/social-link-lastfm":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"lastfm"}}},"core\/social-link-linkedin":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"linkedin"}}},"core\/social-link-mail":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"mail"}}},"core\/social-link-mastodon":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"mastodon"}}},"core\/social-link-meetup":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"meetup"}}},"core\/social-link-medium":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"medium"}}},"core\/social-link-pinterest":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"pinterest"}}},"core\/social-link-pocket":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"pocket"}}},"core\/social-link-reddit":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"reddit"}}},"core\/social-link-skype":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"skype"}}},"core\/social-link-snapchat":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"snapchat"}}},"core\/social-link-soundcloud":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"soundcloud"}}},"core\/social-link-spotify":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"spotify"}}},"core\/social-link-tumblr":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"tumblr"}}},"core\/social-link-twitch":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"twitch"}}},"core\/social-link-twitter":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"twitter"}}},"core\/social-link-vimeo":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"vimeo"}}},"core\/social-link-vk":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"vk"}}},"core\/social-link-wordpress":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"wordpress"}}},"core\/social-link-yelp":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"yelp"}}},"core\/social-link-youtube":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"youtube"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file diff --git a/test/integration/shortcode-converter.test.js b/test/integration/shortcode-converter.test.js index 2f0e5ab632fa74..1b0ce7c30947d9 100644 --- a/test/integration/shortcode-converter.test.js +++ b/test/integration/shortcode-converter.test.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { registerCoreBlocks } from '@wordpress/block-library'; -import { createBlock } from '@wordpress/blocks'; +import { createBlock, registerBlockType } from '@wordpress/blocks'; /** * Internal dependencies @@ -12,6 +12,34 @@ import segmentHTMLToShortcodeBlock from '../../packages/blocks/src/api/raw-handl describe( 'segmentHTMLToShortcodeBlock', () => { beforeAll( () => { registerCoreBlocks(); + registerBlockType( 'test/gallery', { + title: 'Test Gallery', + category: 'common', + attributes: { + ids: { + type: 'array', + default: [], + }, + }, + transforms: { + from: [ + { + type: 'shortcode', + tag: [ 'my-gallery', 'my-bunch-of-images' ], + attributes: { + ids: { + type: 'array', + shortcode: ( { named: { ids } } ) => + ids.split( ',' ).map( ( id ) => ( + parseInt( id, 10 ) + ) ), + }, + }, + }, + ], + }, + save: () => null, + } ); } ); it( 'should convert a standalone shortcode between two paragraphs', () => { @@ -101,4 +129,15 @@ describe( 'segmentHTMLToShortcodeBlock', () => { expect( transformed[ 8 ] ).toEqual( '</p>' ); expect( transformed ).toHaveLength( 9 ); } ); + + it( 'should convert regardless of shortcode alias', () => { + const original = `<p>[my-gallery ids="1,2,3"]</p> +<p>[my-bunch-of-images ids="4,5,6"]</p>`; + const transformed = segmentHTMLToShortcodeBlock( original, 0 ); + expect( transformed[ 0 ] ).toBe( '<p>' ); + expect( transformed[ 1 ] ).toHaveProperty( 'name', 'test/gallery' ); + expect( transformed[ 2 ] ).toBe( '</p>\n<p>' ); + expect( transformed[ 3 ] ).toHaveProperty( 'name', 'test/gallery' ); + expect( transformed[ 4 ] ).toBe( '</p>' ); + } ); } ); diff --git a/test/native/setup.js b/test/native/setup.js index 60fe7194c0aa60..f1e507f38ba399 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -19,6 +19,8 @@ jest.mock( 'react-native-gutenberg-bridge', () => { requestMediaPickFromMediaLibrary: jest.fn(), requestMediaPickFromDeviceLibrary: jest.fn(), requestMediaPickFromDeviceCamera: jest.fn(), + getOtherMediaOptions: jest.fn(), + requestOtherMediaPickFrom: jest.fn(), }; } ); From 2e3e85faf26cd8ef35b8edb2466cae7504578150 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Mon, 4 Nov 2019 12:59:22 +0200 Subject: [PATCH 009/113] Revert "[RNMobile] Native mobile release v1.16.0 (#18210)" This reverts commit f6b72f2977a8c9ab3e2a958da904c765863b17f8. --- .eslintrc.js | 2 +- .github/CODEOWNERS | 8 +- .npmpackagejsonlintrc.json | 39 - .travis.yml | 3 +- .../stylesheets}/_animations.scss | 0 .../stylesheets}/_breakpoints.scss | 0 .../stylesheets}/_colors.scss | 0 .../stylesheets}/_mixins.scss | 0 .../stylesheets}/_variables.scss | 0 .../stylesheets}/_z-index.scss | 2 - bin/commander.js | 3 +- bin/get-vendor-scripts.php | 11 +- bin/packages/build-worker.js | 2 +- bin/packages/post-css-config.js | 63 +- docs/contributors/coding-guidelines.md | 2 +- docs/contributors/git-workflow.md | 17 +- .../developers/data/data-core-block-editor.md | 15 +- .../developers/data/data-core-edit-post.md | 4 +- .../developers/data/data-core-nux.md | 2 +- .../developers/data/data-core.md | 2 +- .../writing-your-first-block-type.md | 2 - docs/manifest-devhub.json | 18 - gutenberg.php | 2 +- lib/block-directory.php | 21 - lib/blocks.php | 1 - lib/client-assets.php | 279 +- lib/customizer.php | 2 +- lib/experiments-page.php | 9 +- lib/load.php | 23 +- lib/rest-api.php | 4 - lib/template-canvas.php | 23 - lib/template-loader.php | 177 - lib/templates.php | 127 +- package-lock.json | 4634 +++++++++-------- package.json | 54 +- packages/a11y/package.json | 2 +- packages/annotations/package.json | 2 +- packages/api-fetch/package.json | 2 +- packages/api-fetch/src/index.js | 50 +- .../api-fetch/src/middlewares/media-upload.js | 74 - packages/api-fetch/src/utils/response.js | 70 - packages/autop/package.json | 2 +- packages/babel-preset-default/package.json | 2 +- packages/base-styles/.npmrc | 1 - packages/base-styles/README.md | 51 - packages/base-styles/index.js | 60 - packages/base-styles/package.json | 25 - packages/blob/package.json | 2 +- packages/block-directory/package.json | 3 +- packages/block-directory/src/index.js | 3 +- packages/block-directory/src/plugins/index.js | 15 - packages/block-editor/README.md | 19 +- packages/block-editor/package.json | 2 +- .../components/autocomplete/index.native.js | 1 - .../src/components/block-breadcrumb/index.js | 77 - .../components/block-breadcrumb/style.scss | 41 - .../src/components/block-edit/context.js | 20 +- .../src/components/block-edit/index.js | 3 +- .../block-list/block-async-mode-provider.js | 5 +- .../block-mobile-floating-toolbar.native.js | 9 +- .../block-mobile-floating-toolbar.native.scss | 9 +- .../block-list/block-mobile-toolbar.js | 4 +- .../src/components/block-list/block.js | 42 +- .../src/components/block-list/block.native.js | 2 - .../src/components/block-list/breadcrumb.js | 2 +- .../block-list/breadcrumb.native.js | 68 - .../block-list/breadcrumb.native.scss | 28 - .../src/components/block-list/index.js | 4 +- .../components/block-list/multi-controls.js | 2 - .../src/components/block-list/style.scss | 3 - .../block-list/subdirectory-icon.js | 18 - .../src/components/block-mover/icons.js | 12 - .../src/components/block-mover/index.js | 57 +- .../block-mover/mover-description.js | 51 +- .../src/components/block-mover/style.scss | 32 +- .../src/components/block-navigation/list.js | 25 +- .../src/components/block-preview/index.js | 2 +- .../block-settings/container.native.js | 6 - .../block-settings/container.native.scss | 4 - .../src/components/block-toolbar/style.scss | 2 - .../components/button-block-appender/index.js | 40 +- .../src/components/colors/index.js | 1 - .../src/components/colors/use-colors.js | 226 - .../src/components/colors/with-colors.js | 2 +- .../test/__snapshots__/index.js.snap | 6 +- .../src/components/gradient-picker/control.js | 13 +- .../src/components/gradient-picker/panel.js | 32 - .../src/components/gradients/index.js | 77 - .../components/ignore-nested-events/index.js | 2 +- packages/block-editor/src/components/index.js | 7 +- .../src/components/index.native.js | 3 +- .../src/components/inner-blocks/index.js | 2 - .../src/components/inserter/index.js | 118 +- .../src/components/link-control/README.md | 50 - .../src/components/link-control/index.js | 249 - .../components/link-control/search-input.js | 69 - .../components/link-control/search-item.js | 54 - .../link-control/settings-drawer.js | 29 - .../src/components/link-control/style.scss | 202 - .../test/__snapshots__/index.js.snap | 3 - .../link-control/test/fixtures/index.js | 41 - .../src/components/link-control/test/index.js | 527 -- .../components/link-control/text-highlight.js | 29 - .../components/media-placeholder/README.md | 4 +- .../src/components/media-placeholder/index.js | 2 +- .../media-placeholder/styles.native.scss | 4 + .../src/components/media-upload/check.js | 2 +- .../src/components/media-upload/index.js | 2 +- .../components/media-upload/index.native.js | 37 +- .../src/components/provider/index.js | 4 +- .../src/components/provider/index.native.js | 4 +- .../rich-text/file-paste-handler.js | 11 - .../rich-text/file-paste-handler.native.js | 3 - .../rich-text/format-toolbar-container.js | 59 - .../format-toolbar-container.native.js | 16 - .../src/components/rich-text/index.js | 90 +- .../src/components/rich-text/index.native.js | 213 + .../rich-text/remove-browser-shortcuts.js | 2 +- .../remove-browser-shortcuts.native.js | 1 - .../src/components/typewriter/index.js | 2 +- .../src/components/url-input/index.js | 111 +- packages/block-editor/src/hooks/anchor.js | 4 +- .../src/hooks/custom-class-name.js | 4 +- packages/block-editor/src/store/defaults.js | 57 +- packages/block-editor/src/store/selectors.js | 66 +- packages/block-editor/src/style.scss | 2 - packages/block-library/package.json | 2 +- packages/block-library/src/audio/edit.js | 6 +- packages/block-library/src/button/block.json | 3 - packages/block-library/src/button/edit.js | 326 +- packages/block-library/src/button/save.js | 8 +- .../block-library/src/columns/deprecated.js | 10 +- .../block-library/src/columns/editor.scss | 42 +- packages/block-library/src/columns/utils.js | 4 +- packages/block-library/src/cover/block.json | 3 - packages/block-library/src/cover/edit.js | 77 +- packages/block-library/src/cover/editor.scss | 3 +- packages/block-library/src/cover/save.js | 12 - packages/block-library/src/cover/style.scss | 22 +- packages/block-library/src/editor.scss | 2 +- .../embed/test/__snapshots__/index.js.snap | 2 +- packages/block-library/src/file/edit.js | 4 +- packages/block-library/src/gallery/edit.js | 9 +- .../block-library/src/gallery/editor.scss | 4 +- packages/block-library/src/group/index.js | 4 +- packages/block-library/src/heading/edit.js | 109 +- packages/block-library/src/image/constants.js | 2 +- packages/block-library/src/image/edit.js | 23 +- .../block-library/src/image/edit.native.js | 91 +- packages/block-library/src/image/icon.js | 4 +- packages/block-library/src/image/save.js | 5 +- .../src/image/styles.native.scss | 14 +- .../src/image/test/edit.native.js | 6 +- packages/block-library/src/image/utils.js | 40 +- packages/block-library/src/index.js | 33 +- packages/block-library/src/index.native.js | 6 +- packages/block-library/src/list/block.json | 3 - packages/block-library/src/list/edit.js | 5 +- packages/block-library/src/list/editor.scss | 5 + packages/block-library/src/list/save.js | 3 +- packages/block-library/src/list/transforms.js | 35 +- .../src/media-text/media-container.native.js | 21 +- .../src/media-text/style.native.scss | 6 - .../block-library/src/missing/edit.native.js | 4 - .../src/missing/style.native.scss | 14 +- .../src/navigation-menu-item/block.json | 6 +- .../src/navigation-menu-item/edit.js | 154 +- .../src/navigation-menu-item/editor.scss | 80 +- .../src/navigation-menu-item/index.js | 6 +- .../navigation-menu-item/menu-item-actions.js | 111 + .../navigation-menu/block-colors-selector.js | 95 - .../block-library/src/navigation-menu/edit.js | 115 +- .../src/navigation-menu/editor.scss | 154 +- .../src/navigation-menu/index.php | 128 +- .../src/navigation-menu/style.scss | 119 - .../block-library/src/site-title/block.json | 4 - packages/block-library/src/site-title/edit.js | 39 - .../block-library/src/site-title/editor.scss | 6 - packages/block-library/src/site-title/icon.js | 12 - .../block-library/src/site-title/index.js | 20 - .../block-library/src/site-title/index.php | 28 - .../block-library/src/social-link/index.php | 2 +- packages/block-library/src/style.scss | 77 - packages/block-library/src/table/edit.js | 30 +- packages/block-library/src/table/editor.scss | 4 + packages/block-library/src/video/edit.js | 6 +- .../package.json | 2 +- .../package.json | 2 +- packages/blocks/README.md | 2 +- packages/blocks/package.json | 2 +- packages/blocks/src/api/factory.js | 16 +- packages/blocks/src/api/index.native.js | 44 + packages/blocks/src/api/parser.js | 6 +- .../raw-handling/phrasing-content-reducer.js | 11 +- .../api/raw-handling/shortcode-converter.js | 4 +- packages/blocks/src/api/registration.js | 14 +- packages/blocks/src/api/serializer.js | 25 +- .../src/block-content-provider/index.js | 4 +- packages/components/package.json | 2 +- packages/components/src/autocomplete/index.js | 6 +- .../src/button-group/stories/index.js | 2 +- .../components/src/button/stories/index.js | 93 +- packages/components/src/button/style.scss | 12 +- .../components/src/checkbox-control/README.md | 9 +- .../src/checkbox-control/stories/index.js | 54 - .../src/clipboard-button/stories/index.js | 29 +- .../src/color-indicator/stories/index.js | 16 +- .../src/color-palette/stories/index.js | 56 - packages/components/src/color-picker/hue.js | 6 +- .../components/src/color-picker/inputs.js | 9 +- .../components/src/color-picker/saturation.js | 6 +- .../src/color-picker/stories/index.js | 39 - .../test/__snapshots__/index.js.snap | 24 +- .../components/src/dashicon/stories/index.js | 25 - packages/components/src/date-time/date.js | 2 +- packages/components/src/date-time/index.js | 3 +- .../src/dimension-control/README.md | 120 - .../components/src/dimension-control/index.js | 76 - .../components/src/dimension-control/sizes.js | 45 - .../src/dimension-control/style.scss | 22 - .../test/__snapshots__/index.test.js.snap | 163 - .../src/dimension-control/test/index.test.js | 128 - .../components/src/draggable/stories/index.js | 69 - .../components/src/external-link/index.js | 5 +- .../src/external-link/stories/index.js | 17 - .../components/src/font-size-picker/index.js | 2 +- .../src/font-size-picker/style.scss | 6 - .../components/src/gradient-picker/index.js | 3 +- .../higher-order/with-focus-return/index.js | 8 +- .../src/higher-order/with-notices/index.js | 5 +- .../with-spoken-messages/index.js | 4 +- .../src/icon-button/stories/index.js | 17 +- packages/components/src/icon/stories/index.js | 24 +- packages/components/src/index.js | 2 - packages/components/src/index.native.js | 3 - .../src/keyboard-shortcuts/index.native.js | 2 - packages/components/src/menu-item/index.js | 2 +- .../src/mobile/bottom-sheet/cell.native.js | 15 +- .../src/mobile/bottom-sheet/index.native.js | 4 - .../mobile/bottom-sheet/picker-cell.native.js | 3 - .../mobile/bottom-sheet/range-cell.native.js | 46 - .../mobile/bottom-sheet/styles.native.scss | 7 - .../src/mobile/picker/index.android.js | 1 - .../components/src/mobile/picker/index.ios.js | 3 +- .../src/mobile/slider/index.native.js | 118 - .../components/src/mobile/slider/styles.scss | 27 - packages/components/src/modal/index.js | 2 +- .../components/src/panel/actions.native.js | 36 - .../components/src/panel/actions.native.scss | 7 - packages/components/src/panel/body.native.js | 12 +- .../components/src/panel/body.native.scss | 11 - packages/components/src/placeholder/README.md | 2 +- packages/components/src/scroll-lock/index.js | 2 +- .../src/scroll-lock/stories/index.js | 2 +- .../components/src/spinner/stories/index.js | 12 - packages/components/src/style.scss | 2 - packages/components/src/toolbar/index.js | 12 +- .../components/src/visually-hidden/README.md | 9 - .../components/src/visually-hidden/index.js | 22 - .../src/visually-hidden/stories/index.js | 17 - .../components/src/visually-hidden/style.scss | 30 - .../components/src/visually-hidden/utils.js | 22 - packages/components/storybook/addons.js | 1 - packages/components/storybook/config.js | 2 - packages/compose/README.md | 10 +- packages/compose/package.json | 3 +- packages/compose/src/higher-order/compose.js | 14 - .../higher-order/with-instance-id/index.js | 4 +- .../higher-order/with-safe-timeout/index.js | 4 +- .../src/higher-order/with-state/index.js | 2 +- packages/compose/src/index.js | 16 +- packages/core-data/README.md | 2 +- packages/core-data/package.json | 2 +- packages/core-data/src/actions.js | 4 +- packages/core-data/src/entities.js | 1 - packages/core-data/src/entity-provider.js | 76 +- packages/core-data/src/index.js | 7 +- .../core-data/src/queried-data/reducer.js | 6 +- packages/core-data/src/resolvers.js | 2 +- packages/core-data/src/selectors.js | 6 +- packages/data-controls/package.json | 2 +- packages/data/README.md | 44 +- packages/data/package.json | 2 +- .../components/async-mode-provider/context.js | 34 - .../src/components/with-dispatch/index.js | 2 +- .../data/src/components/with-select/index.js | 2 +- packages/data/src/factory.js | 4 + packages/data/src/index.js | 4 +- packages/data/src/namespace-store/index.js | 2 +- .../data/src/plugins/persistence/index.js | 2 +- packages/date/README.md | 8 +- packages/date/src/index.js | 50 +- packages/deprecated/package.json | 2 +- packages/dom-ready/package.json | 2 +- packages/dom/package.json | 2 +- packages/e2e-test-utils/CHANGELOG.md | 6 - packages/e2e-test-utils/README.md | 6 +- packages/e2e-test-utils/package.json | 2 +- .../src/enable-experimental-features.js} | 33 +- ...-sidebar-panel-toggle-button-with-title.js | 2 +- .../src/find-sidebar-panel-with-title.js | 2 +- packages/e2e-test-utils/src/index.js | 1 + .../src/wait-for-window-dimensions.js | 2 +- .../e2e-tests/config/performance-reporter.js | 2 +- .../e2e-tests/fixtures/block-transforms.js | 28 - .../blocks/core__cover__gradient-image.html | 10 - .../blocks/core__cover__gradient-image.json | 31 - .../core__cover__gradient-image.parsed.json | 40 - ...ore__cover__gradient-image.serialized.html | 5 - .../blocks/core__cover__gradient-video.html | 11 - .../blocks/core__cover__gradient-video.json | 31 - .../core__cover__gradient-video.parsed.json | 41 - ...ore__cover__gradient-video.serialized.html | 5 - .../blocks/core__cover__gradient.html | 9 - .../blocks/core__cover__gradient.json | 30 - .../blocks/core__cover__gradient.parsed.json | 38 - .../core__cover__gradient.serialized.html | 5 - .../blocks/core__navigation-menu-item.html | 2 +- .../blocks/core__navigation-menu-item.json | 4 +- .../core__navigation-menu-item.parsed.json | 2 +- ...core__navigation-menu-item.serialized.html | 2 +- .../fixtures/blocks/core__site-title.html | 1 - .../fixtures/blocks/core__site-title.json | 10 - .../blocks/core__site-title.parsed.json | 18 - .../blocks/core__site-title.serialized.html | 1 - packages/e2e-tests/jest.config.js | 2 +- packages/e2e-tests/jest.performance.config.js | 2 +- packages/e2e-tests/package.json | 3 +- .../specs/{performance => }/.gitignore | 0 .../__snapshots__/adding-blocks.test.js.snap | 0 .../__snapshots__/block-deletion.test.js.snap | 0 .../__snapshots__/block-grouping.test.js.snap | 0 .../block-hierarchy-navigation.test.js.snap | 0 .../block-transforms.test.js.snap | 24 - .../compatibility-classic-editor.test.js.snap | 0 .../convert-block-type.test.js.snap | 0 .../__snapshots__/embedding.test.js.snap | 0 .../font-size-picker.test.js.snap | 0 .../__snapshots__/links.test.js.snap | 0 .../__snapshots__/mentions.test.js.snap | 0 .../multi-block-selection.test.js.snap | 0 .../reusable-blocks.test.js.snap | 0 .../__snapshots__/rich-text.test.js.snap | 0 .../__snapshots__/rtl.test.js.snap | 0 .../splitting-merging.test.js.snap | 0 .../style-variation.test.js.snap | 0 .../__snapshots__/undo.test.js.snap | 0 .../__snapshots__/writing-flow.test.js.snap | 0 .../specs/{editor/various => }/a11y.test.js | 0 .../various => }/adding-blocks.test.js | 2 +- .../various => }/adding-inline-tokens.test.js | 2 +- .../{editor/various => }/autosave.test.js | 65 +- .../various => }/block-deletion.test.js | 0 .../various => }/block-grouping.test.js | 0 .../block-hierarchy-navigation.test.js | 1 - .../{editor/various => }/block-mover.test.js | 0 .../various => }/block-switcher.test.js | 0 .../block-transforms.test.js | 33 +- .../blocks/__snapshots__/button.test.js.snap | 0 .../blocks/__snapshots__/classic.test.js.snap | 0 .../blocks/__snapshots__/code.test.js.snap | 0 .../blocks/__snapshots__/group.test.js.snap | 0 .../blocks/__snapshots__/heading.test.js.snap | 0 .../blocks/__snapshots__/html.test.js.snap | 0 .../blocks/__snapshots__/list.test.js.snap | 6 - .../__snapshots__/preformatted.test.js.snap | 0 .../blocks/__snapshots__/quote.test.js.snap | 0 .../__snapshots__/separator.test.js.snap | 0 .../blocks/__snapshots__/spacer.test.js.snap | 0 .../blocks/__snapshots__/table.test.js.snap | 0 .../specs/{editor => }/blocks/button.test.js | 0 .../specs/{editor => }/blocks/classic.test.js | 2 +- .../specs/{editor => }/blocks/code.test.js | 0 .../specs/{editor => }/blocks/columns.test.js | 0 .../specs/{editor => }/blocks/group.test.js | 0 .../specs/{editor => }/blocks/heading.test.js | 0 .../specs/{editor => }/blocks/html.test.js | 0 .../specs/{editor => }/blocks/list.test.js | 12 - .../{editor => }/blocks/preformatted.test.js | 0 .../specs/{editor => }/blocks/quote.test.js | 0 .../{editor => }/blocks/separator.test.js | 0 .../specs/{editor => }/blocks/spacer.test.js | 0 .../specs/{editor => }/blocks/table.test.js | 16 +- .../various => }/change-detection.test.js | 0 .../compatibility-classic-editor.test.js | 0 .../various => }/convert-block-type.test.js | 0 .../{editor/various => }/datepicker.test.js | 0 .../e2e-tests/specs/{local => }/demo.test.js | 0 .../{editor/various => }/editor-modes.test.js | 0 .../{editor/various => }/embedding.test.js | 29 + .../various => }/font-size-picker.test.js | 4 +- .../various => }/fullscreen-mode.test.js | 0 .../various => }/invalid-block.test.js | 0 .../keyboard-navigable-blocks.test.js | 0 .../specs/{editor/various => }/links.test.js | 81 + .../manage-reusable-blocks.test.js | 2 +- .../{editor/various => }/mentions.test.js | 0 .../multi-block-selection.test.js | 0 .../various => }/navigable-toolbar.test.js | 0 .../new-post-default-content.test.js | 0 .../{editor/various => }/new-post.test.js | 0 .../specs/{editor/various => }/nux.test.js | 70 + .../{performance => }/performance.test.js | 2 +- .../__snapshots__/align-hook.test.js.snap | 0 .../container-blocks.test.js.snap | 0 .../__snapshots__/cpt-locking.test.js.snap | 0 .../deprecated-node-matcher.test.js.snap | 0 .../__snapshots__/format-api.test.js.snap | 0 .../__snapshots__/hooks-api.test.js.snap | 0 .../meta-attribute-block.test.js.snap | 0 .../__snapshots__/plugins-api.test.js.snap | 0 .../__snapshots__/templates.test.js.snap | 0 .../wp-editor-meta-box.test.js.snap | 0 .../{editor => }/plugins/align-hook.test.js | 0 .../plugins/allowed-blocks.test.js | 0 .../{editor => }/plugins/annotations.test.js | 0 .../{editor => }/plugins/block-icons.test.js | 0 .../plugins/container-blocks.test.js | 0 .../{editor => }/plugins/cpt-locking.test.js | 0 .../plugins/custom-taxonomies.test.js | 0 .../plugins/deprecated-node-matcher.test.js | 0 .../{editor => }/plugins/format-api.test.js | 0 .../{editor => }/plugins/hooks-api.test.js | 0 .../inner-blocks-allowed-blocks.test.js | 0 .../plugins/innerblocks-locking-all-embed.js | 0 .../plugins/meta-attribute-block.test.js | 0 .../{editor => }/plugins/meta-boxes.test.js | 0 .../specs/{editor => }/plugins/nonce.test.js | 0 .../{editor => }/plugins/plugins-api.test.js | 0 .../{editor => }/plugins/templates.test.js | 0 .../plugins/wp-editor-meta-box.test.js | 9 +- .../{editor/various => }/popovers.test.js | 0 .../various => }/post-visibility.test.js | 0 .../{editor/various => }/preferences.test.js | 0 .../{editor/various => }/preview.test.js | 0 .../various => }/publish-button.test.js | 0 .../various => }/publish-panel.test.js | 0 .../{editor/various => }/publishing.test.js | 0 .../various => }/reusable-blocks.test.js | 0 .../{editor/various => }/rich-text.test.js | 0 .../specs/{editor/various => }/rtl.test.js | 0 .../{editor/various => }/scheduling.test.js | 0 .../various => }/shortcut-help.test.js | 0 .../sidebar-permalink-panel.test.js | 0 .../{editor/various => }/sidebar.test.js | 1 - .../various => }/splitting-merging.test.js | 0 .../various => }/style-variation.test.js | 0 .../{editor/various => }/taxonomies.test.js | 42 +- .../{editor/various => }/typewriter.test.js | 0 .../specs/{editor/various => }/undo.test.js | 0 .../{editor/various => }/writing-flow.test.js | 0 packages/edit-post/CHANGELOG.md | 2 +- packages/edit-post/README.md | 30 +- packages/edit-post/package.json | 2 +- .../plugin-block-settings-menu-item.js | 4 +- .../header/plugin-more-menu-item/index.js | 4 +- .../plugin-sidebar-more-menu-item/index.js | 4 +- .../src/components/header/style.scss | 10 +- .../edit-post/src/components/layout/index.js | 20 +- .../src/components/layout/style.scss | 81 +- .../meta-boxes/meta-boxes-area/style.scss | 19 - .../plugin-document-setting-panel/index.js | 4 +- .../plugin-post-publish-panel/index.js | 4 +- .../sidebar/plugin-post-status-info/index.js | 2 +- .../sidebar/plugin-pre-publish-panel/index.js | 17 +- .../sidebar/plugin-sidebar/index.js | 4 +- .../src/components/sidebar/post-slug/index.js | 17 - .../components/sidebar/post-slug/style.scss | 4 - .../components/sidebar/post-status/index.js | 2 - .../src/components/sidebar/style.scss | 4 - .../src/components/text-editor/style.scss | 80 +- .../src/hooks/validate-multiple-use/index.js | 4 +- packages/edit-post/src/store/selectors.js | 4 +- packages/edit-post/src/style.scss | 3 - packages/edit-widgets/package.json | 2 +- .../src/components/widget-area/index.js | 2 +- packages/editor/package.json | 2 +- .../src/components/autocompleters/block.js | 6 +- .../src/components/autocompleters/user.js | 2 +- packages/editor/src/components/index.js | 2 - .../index.js | 6 +- .../local-autosave-monitor/index.js | 7 +- .../components/post-publish-button/index.js | 1 - .../editor/src/components/post-slug/check.js | 10 - .../editor/src/components/post-slug/index.js | 85 - .../src/components/post-slug/test/check.js | 21 - .../src/components/post-slug/test/index.js | 45 - .../post-taxonomies/flat-term-selector.js | 6 +- .../post-type-support-check/index.js | 14 +- .../editor/src/components/provider/index.js | 59 +- packages/editor/src/editor-styles.scss | 2 - packages/editor/src/store/actions.native.js | 4 +- packages/editor/src/store/reducer.js | 8 +- packages/element/README.md | 41 +- packages/element/package.json | 2 +- packages/element/src/index.js | 1 - packages/element/src/platform.android.js | 18 - packages/element/src/platform.ios.js | 18 - packages/element/src/platform.js | 32 - packages/element/src/raw-html.js | 2 +- packages/element/src/react-platform.js | 14 +- packages/element/src/react.js | 30 +- packages/element/src/test/platform.js | 19 - packages/element/src/test/platform.native.js | 19 - packages/env/.npmrc | 1 - packages/env/README.md | 19 +- packages/env/lib/cli.js | 4 +- .../env/lib/create-docker-compose-config.js | 21 +- packages/env/lib/detect-context.js | 45 - packages/env/lib/env.js | 40 +- packages/env/package.json | 2 +- .../env/{test/cli.js => tests/cli.test.js} | 0 packages/escape-html/package.json | 2 +- packages/eslint-plugin/configs/jsdoc.js | 52 - packages/format-library/package.json | 2 +- packages/format-library/src/image/style.scss | 15 +- packages/is-shallow-equal/package.json | 2 +- packages/jest-puppeteer-axe/src/index.js | 14 +- packages/keycodes/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/media-utils/package.json | 2 +- .../src/components/media-upload/index.js | 3 + packages/notices/package.json | 2 +- packages/notices/src/store/actions.js | 11 - packages/notices/src/store/selectors.js | 11 + packages/nux/package.json | 2 +- packages/nux/src/store/selectors.js | 4 +- packages/plugins/README.md | 16 +- packages/plugins/package.json | 2 +- packages/plugins/src/api/index.js | 30 +- .../src/components/plugin-area/index.js | 2 +- .../src/components/plugin-context/index.js | 2 +- packages/priority-queue/package.json | 2 +- packages/redux-routine/package.json | 2 +- packages/rich-text/README.md | 6 +- packages/rich-text/package.json | 2 +- packages/rich-text/src/component/index.js | 68 +- .../rich-text/src/component/index.native.js | 267 +- .../src/component/test/index.native.js | 34 + .../rich-text/src/register-format-type.js | 19 +- packages/rich-text/src/test/helpers/index.js | 2 +- packages/rich-text/src/to-dom.js | 2 +- packages/scripts/CHANGELOG.md | 10 - packages/scripts/package.json | 6 +- packages/scripts/scripts/lint-pkg-json.js | 2 - packages/server-side-render/package.json | 2 +- packages/url/package.json | 2 +- packages/url/src/index.js | 4 - packages/viewport/package.json | 2 +- packages/wordcount/package.json | 2 +- phpunit/class-override-script-test.php | 16 +- playground/.sassrc | 5 - playground/src/index.js | 13 +- playground/src/style.scss | 40 +- .../blocks-raw-handling.test.js.snap | 10 - test/integration/blocks-raw-handling.test.js | 5 - .../integration/fixtures/google-docs-out.html | 2 +- .../google-docs-with-comments-out.html | 2 +- .../fixtures/list-with-attributes.html | 7 - test/integration/fixtures/ms-word-out.html | 4 +- .../full-content/full-content.test.js | 6 +- .../full-content/server-registered.json | 2 +- test/integration/shortcode-converter.test.js | 41 +- test/native/setup.js | 2 - 564 files changed, 5015 insertions(+), 10590 deletions(-) delete mode 100644 .npmpackagejsonlintrc.json rename {packages/base-styles => assets/stylesheets}/_animations.scss (100%) rename {packages/base-styles => assets/stylesheets}/_breakpoints.scss (100%) rename {packages/base-styles => assets/stylesheets}/_colors.scss (100%) rename {packages/base-styles => assets/stylesheets}/_mixins.scss (100%) rename {packages/base-styles => assets/stylesheets}/_variables.scss (100%) rename {packages/base-styles => assets/stylesheets}/_z-index.scss (98%) delete mode 100644 lib/block-directory.php delete mode 100644 lib/template-canvas.php delete mode 100644 lib/template-loader.php delete mode 100644 packages/api-fetch/src/middlewares/media-upload.js delete mode 100644 packages/api-fetch/src/utils/response.js delete mode 100644 packages/base-styles/.npmrc delete mode 100644 packages/base-styles/README.md delete mode 100644 packages/base-styles/index.js delete mode 100644 packages/base-styles/package.json delete mode 100644 packages/block-directory/src/plugins/index.js delete mode 100644 packages/block-editor/src/components/autocomplete/index.native.js delete mode 100644 packages/block-editor/src/components/block-breadcrumb/index.js delete mode 100644 packages/block-editor/src/components/block-breadcrumb/style.scss delete mode 100644 packages/block-editor/src/components/block-list/breadcrumb.native.js delete mode 100644 packages/block-editor/src/components/block-list/breadcrumb.native.scss delete mode 100644 packages/block-editor/src/components/block-list/subdirectory-icon.js delete mode 100644 packages/block-editor/src/components/block-settings/container.native.scss delete mode 100644 packages/block-editor/src/components/colors/use-colors.js delete mode 100644 packages/block-editor/src/components/gradient-picker/panel.js delete mode 100644 packages/block-editor/src/components/gradients/index.js delete mode 100644 packages/block-editor/src/components/link-control/README.md delete mode 100644 packages/block-editor/src/components/link-control/index.js delete mode 100644 packages/block-editor/src/components/link-control/search-input.js delete mode 100644 packages/block-editor/src/components/link-control/search-item.js delete mode 100644 packages/block-editor/src/components/link-control/settings-drawer.js delete mode 100644 packages/block-editor/src/components/link-control/style.scss delete mode 100644 packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap delete mode 100644 packages/block-editor/src/components/link-control/test/fixtures/index.js delete mode 100644 packages/block-editor/src/components/link-control/test/index.js delete mode 100644 packages/block-editor/src/components/link-control/text-highlight.js delete mode 100644 packages/block-editor/src/components/rich-text/file-paste-handler.js delete mode 100644 packages/block-editor/src/components/rich-text/file-paste-handler.native.js delete mode 100644 packages/block-editor/src/components/rich-text/format-toolbar-container.js delete mode 100644 packages/block-editor/src/components/rich-text/format-toolbar-container.native.js create mode 100644 packages/block-editor/src/components/rich-text/index.native.js delete mode 100644 packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js create mode 100644 packages/block-library/src/list/editor.scss create mode 100644 packages/block-library/src/navigation-menu-item/menu-item-actions.js delete mode 100644 packages/block-library/src/navigation-menu/block-colors-selector.js delete mode 100644 packages/block-library/src/navigation-menu/style.scss delete mode 100644 packages/block-library/src/site-title/block.json delete mode 100644 packages/block-library/src/site-title/edit.js delete mode 100644 packages/block-library/src/site-title/editor.scss delete mode 100644 packages/block-library/src/site-title/icon.js delete mode 100644 packages/block-library/src/site-title/index.js delete mode 100644 packages/block-library/src/site-title/index.php create mode 100644 packages/blocks/src/api/index.native.js delete mode 100644 packages/components/src/checkbox-control/stories/index.js delete mode 100644 packages/components/src/color-palette/stories/index.js delete mode 100644 packages/components/src/color-picker/stories/index.js delete mode 100644 packages/components/src/dashicon/stories/index.js delete mode 100644 packages/components/src/dimension-control/README.md delete mode 100644 packages/components/src/dimension-control/index.js delete mode 100644 packages/components/src/dimension-control/sizes.js delete mode 100644 packages/components/src/dimension-control/style.scss delete mode 100644 packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap delete mode 100644 packages/components/src/dimension-control/test/index.test.js delete mode 100644 packages/components/src/draggable/stories/index.js delete mode 100644 packages/components/src/external-link/stories/index.js delete mode 100644 packages/components/src/keyboard-shortcuts/index.native.js delete mode 100644 packages/components/src/mobile/bottom-sheet/range-cell.native.js delete mode 100644 packages/components/src/mobile/slider/index.native.js delete mode 100644 packages/components/src/mobile/slider/styles.scss delete mode 100644 packages/components/src/panel/actions.native.js delete mode 100644 packages/components/src/panel/actions.native.scss delete mode 100644 packages/components/src/panel/body.native.scss delete mode 100644 packages/components/src/spinner/stories/index.js delete mode 100644 packages/components/src/visually-hidden/README.md delete mode 100644 packages/components/src/visually-hidden/index.js delete mode 100644 packages/components/src/visually-hidden/stories/index.js delete mode 100644 packages/components/src/visually-hidden/style.scss delete mode 100644 packages/components/src/visually-hidden/utils.js delete mode 100644 packages/compose/src/higher-order/compose.js rename packages/{e2e-tests/experimental-features.js => e2e-test-utils/src/enable-experimental-features.js} (60%) delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json delete mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html rename packages/e2e-tests/specs/{performance => }/.gitignore (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/adding-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/block-deletion.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/block-grouping.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/block-hierarchy-navigation.test.js.snap (100%) rename packages/e2e-tests/specs/{experimental => }/__snapshots__/block-transforms.test.js.snap (94%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/compatibility-classic-editor.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/convert-block-type.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/embedding.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/font-size-picker.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/links.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/mentions.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/multi-block-selection.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/reusable-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/rich-text.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/rtl.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/splitting-merging.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/style-variation.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/undo.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/__snapshots__/writing-flow.test.js.snap (100%) rename packages/e2e-tests/specs/{editor/various => }/a11y.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/adding-blocks.test.js (98%) rename packages/e2e-tests/specs/{editor/various => }/adding-inline-tokens.test.js (93%) rename packages/e2e-tests/specs/{editor/various => }/autosave.test.js (77%) rename packages/e2e-tests/specs/{editor/various => }/block-deletion.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/block-grouping.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/block-hierarchy-navigation.test.js (99%) rename packages/e2e-tests/specs/{editor/various => }/block-mover.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/block-switcher.test.js (100%) rename packages/e2e-tests/specs/{experimental => }/block-transforms.test.js (88%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/button.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/classic.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/code.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/group.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/heading.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/html.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/list.test.js.snap (98%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/preformatted.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/quote.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/separator.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/spacer.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/__snapshots__/table.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/blocks/button.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/classic.test.js (95%) rename packages/e2e-tests/specs/{editor => }/blocks/code.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/columns.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/group.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/heading.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/html.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/list.test.js (97%) rename packages/e2e-tests/specs/{editor => }/blocks/preformatted.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/quote.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/separator.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/spacer.test.js (100%) rename packages/e2e-tests/specs/{editor => }/blocks/table.test.js (94%) rename packages/e2e-tests/specs/{editor/various => }/change-detection.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/compatibility-classic-editor.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/convert-block-type.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/datepicker.test.js (100%) rename packages/e2e-tests/specs/{local => }/demo.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/editor-modes.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/embedding.test.js (87%) rename packages/e2e-tests/specs/{editor/various => }/font-size-picker.test.js (97%) rename packages/e2e-tests/specs/{editor/various => }/fullscreen-mode.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/invalid-block.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/keyboard-navigable-blocks.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/links.test.js (80%) rename packages/e2e-tests/specs/{editor/various => }/manage-reusable-blocks.test.js (93%) rename packages/e2e-tests/specs/{editor/various => }/mentions.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/multi-block-selection.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/navigable-toolbar.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/new-post-default-content.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/new-post.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/nux.test.js (56%) rename packages/e2e-tests/specs/{performance => }/performance.test.js (95%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/align-hook.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/container-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/cpt-locking.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/deprecated-node-matcher.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/format-api.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/hooks-api.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/meta-attribute-block.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/plugins-api.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/templates.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/__snapshots__/wp-editor-meta-box.test.js.snap (100%) rename packages/e2e-tests/specs/{editor => }/plugins/align-hook.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/allowed-blocks.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/annotations.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/block-icons.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/container-blocks.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/cpt-locking.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/custom-taxonomies.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/deprecated-node-matcher.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/format-api.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/hooks-api.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/inner-blocks-allowed-blocks.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/innerblocks-locking-all-embed.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/meta-attribute-block.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/meta-boxes.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/nonce.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/plugins-api.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/templates.test.js (100%) rename packages/e2e-tests/specs/{editor => }/plugins/wp-editor-meta-box.test.js (76%) rename packages/e2e-tests/specs/{editor/various => }/popovers.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/post-visibility.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/preferences.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/preview.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/publish-button.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/publish-panel.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/publishing.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/reusable-blocks.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/rich-text.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/rtl.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/scheduling.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/shortcut-help.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/sidebar-permalink-panel.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/sidebar.test.js (99%) rename packages/e2e-tests/specs/{editor/various => }/splitting-merging.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/style-variation.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/taxonomies.test.js (83%) rename packages/e2e-tests/specs/{editor/various => }/typewriter.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/undo.test.js (100%) rename packages/e2e-tests/specs/{editor/various => }/writing-flow.test.js (100%) delete mode 100644 packages/edit-post/src/components/sidebar/post-slug/index.js delete mode 100644 packages/edit-post/src/components/sidebar/post-slug/style.scss rename packages/{block-directory/src/plugins => editor/src/components}/inserter-menu-downloadable-blocks-panel/index.js (89%) delete mode 100644 packages/editor/src/components/post-slug/check.js delete mode 100644 packages/editor/src/components/post-slug/index.js delete mode 100644 packages/editor/src/components/post-slug/test/check.js delete mode 100644 packages/editor/src/components/post-slug/test/index.js delete mode 100644 packages/element/src/platform.android.js delete mode 100644 packages/element/src/platform.ios.js delete mode 100644 packages/element/src/platform.js delete mode 100644 packages/element/src/test/platform.js delete mode 100644 packages/element/src/test/platform.native.js delete mode 100644 packages/env/.npmrc delete mode 100644 packages/env/lib/detect-context.js rename packages/env/{test/cli.js => tests/cli.test.js} (100%) delete mode 100644 playground/.sassrc delete mode 100644 test/integration/fixtures/list-with-attributes.html diff --git a/.eslintrc.js b/.eslintrc.js index 43e259b40c7b7e..b1a6b834b53aff 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -123,7 +123,7 @@ module.exports = { '**/*.@(android|ios|native).js', '**/benchmark/**/*.js', '**/@(__mocks__|__tests__|test)/**/*.js', - '**/@(storybook|stories)/**/*.js', + '**/storybook/**/*.js', ], }, { diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c6d9694eae9b62..33d5a864d489d8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,7 +40,7 @@ /packages/custom-templated-path-webpack-plugin @ntwb @nerrad @ajitbohra /packages/docgen @nosolosw /packages/e2e-test-utils @gziolo @ntwb @nerrad @ajitbohra -/packages/e2e-tests @ntwb @nerrad @ajitbohra @talldan +/packages/e2e-tests @gziolo @ntwb @nerrad @ajitbohra @talldan /packages/eslint-plugin @gziolo @ntwb @nerrad @ajitbohra /packages/jest-console @gziolo @ntwb @nerrad @ajitbohra /packages/jest-preset-default @gziolo @ntwb @nerrad @ajitbohra @@ -51,9 +51,9 @@ /packages/scripts @youknowriad @gziolo @ntwb @nerrad @ajitbohra # UI Components -/packages/components @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @chrisvanpatten -/packages/compose @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan -/packages/element @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan +/packages/components @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @chrisvanpatten +/packages/compose @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan +/packages/element @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan /packages/notices @ajitbohra @jaymanpandya @jorgefilipecosta @talldan /packages/nux @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @noisysocks /packages/viewport @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan diff --git a/.npmpackagejsonlintrc.json b/.npmpackagejsonlintrc.json deleted file mode 100644 index daab51fa30d456..00000000000000 --- a/.npmpackagejsonlintrc.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "extends": "@wordpress/npm-package-json-lint-config", - "rules": { - "description-format": [ - "error", - { - "requireCapitalFirstLetter": true, - "requireEndingPeriod": true - } - ], - "prefer-no-devDependencies": "error", - "require-publishConfig": "error", - "require-repository-directory": "error", - "valid-values-author": [ - "error", - [ - "The WordPress Contributors" - ] - ], - "valid-values-publishConfig": [ - "error", - [ - { - "access": "public" - } - ] - ] - }, - "overrides": [ - { - "patterns": [ "./package.json" ], - "rules": { - "require-publishConfig": "off", - "require-repository-directory": "off", - "prefer-no-devDependencies": "off" - } - } - ] -} diff --git a/.travis.yml b/.travis.yml index db9acbf2d2174b..27b1e7383e85ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,7 @@ branches: only: - master - rnmobile/master - - rnmobile/releases - - /wp\/.*/ + - wp/trunk env: global: diff --git a/packages/base-styles/_animations.scss b/assets/stylesheets/_animations.scss similarity index 100% rename from packages/base-styles/_animations.scss rename to assets/stylesheets/_animations.scss diff --git a/packages/base-styles/_breakpoints.scss b/assets/stylesheets/_breakpoints.scss similarity index 100% rename from packages/base-styles/_breakpoints.scss rename to assets/stylesheets/_breakpoints.scss diff --git a/packages/base-styles/_colors.scss b/assets/stylesheets/_colors.scss similarity index 100% rename from packages/base-styles/_colors.scss rename to assets/stylesheets/_colors.scss diff --git a/packages/base-styles/_mixins.scss b/assets/stylesheets/_mixins.scss similarity index 100% rename from packages/base-styles/_mixins.scss rename to assets/stylesheets/_mixins.scss diff --git a/packages/base-styles/_variables.scss b/assets/stylesheets/_variables.scss similarity index 100% rename from packages/base-styles/_variables.scss rename to assets/stylesheets/_variables.scss diff --git a/packages/base-styles/_z-index.scss b/assets/stylesheets/_z-index.scss similarity index 98% rename from packages/base-styles/_z-index.scss rename to assets/stylesheets/_z-index.scss index 36cc265a0b7f64..7b7e0aedd55301 100644 --- a/packages/base-styles/_z-index.scss +++ b/assets/stylesheets/_z-index.scss @@ -24,7 +24,6 @@ $z-layers: ( ".block-editor-warning": 5, ".block-library-gallery-item__inline-menu": 20, ".block-editor-url-input__suggestions": 30, - ".edit-post-layout__footer": 30, ".edit-post-header": 30, ".edit-widgets-header": 30, ".block-library-button__inline-link .block-editor-url-input__suggestions": 6, // URL suggestions for button block above sibling inserter @@ -32,7 +31,6 @@ $z-layers: ( ".wp-block-cover__inner-container": 1, // InnerBlocks area inside cover image block ".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. - ".wp-block-site-title__save-button": 1, // Active pill button ".components-button.is-button {:focus or .is-primary}": 1, diff --git a/bin/commander.js b/bin/commander.js index 95cfc56b25efd9..dcc863872f034d 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -17,7 +17,7 @@ const uuid = require( 'uuid/v4' ); // Config const gitRepoOwner = 'WordPress'; -const gitRepoURL = 'https://github.com/' + gitRepoOwner + '/gutenberg.git'; +const gitRepoURL = 'git@github.com:' + gitRepoOwner + '/gutenberg.git'; const svnRepoURL = 'https://plugins.svn.wordpress.org/gutenberg'; // Working Directories @@ -95,7 +95,6 @@ function runShellScript( script, cwd ) { env: { NO_CHECKS: true, PATH: process.env.PATH, - HOME: process.env.HOME, }, stdio: [ 'inherit', 'ignore', 'inherit' ], } ); diff --git a/bin/get-vendor-scripts.php b/bin/get-vendor-scripts.php index e7295f556b4cb2..442e77b0eb4358 100755 --- a/bin/get-vendor-scripts.php +++ b/bin/get-vendor-scripts.php @@ -32,13 +32,4 @@ function wp_add_inline_script() {} require_once dirname( dirname( __FILE__ ) ) . '/lib/client-assets.php'; -/** - * Hi, phpcs - */ -function run_gutenberg_register_vendor_scripts() { - global $wp_scripts; - - gutenberg_register_vendor_scripts( $wp_scripts ); -} - -run_gutenberg_register_vendor_scripts(); +gutenberg_register_vendor_scripts(); diff --git a/bin/packages/build-worker.js b/bin/packages/build-worker.js index d0f1d1c809984a..7e3e636c013a1d 100644 --- a/bin/packages/build-worker.js +++ b/bin/packages/build-worker.js @@ -94,7 +94,7 @@ const BUILD_TASK_BY_EXTENSION = { const builtSass = await renderSass( { file, - includePaths: [ path.join( PACKAGES_DIR, 'base-styles' ) ], + includePaths: [ path.resolve( __dirname, '../../assets/stylesheets' ) ], data: ( [ 'colors', diff --git a/bin/packages/post-css-config.js b/bin/packages/post-css-config.js index 842688a8d784b7..3d7861f75044bd 100644 --- a/bin/packages/post-css-config.js +++ b/bin/packages/post-css-config.js @@ -1,7 +1,64 @@ -const { adminColorSchemes } = require( '@wordpress/base-styles' ); - module.exports = [ - require( '@wordpress/postcss-themes' )( adminColorSchemes ), + require( '@wordpress/postcss-themes' )( { + defaults: { + primary: '#0085ba', + secondary: '#11a0d2', + toggle: '#11a0d2', + button: '#007cba', + outlines: '#007cba', + }, + themes: { + 'admin-color-light': { + primary: '#0085ba', + secondary: '#c75726', + toggle: '#11a0d2', + button: '#0085ba', + outlines: '#007cba', + }, + 'admin-color-blue': { + primary: '#82b4cb', + secondary: '#d9ab59', + toggle: '#82b4cb', + button: '#d9ab59', + outlines: '#417e9B', + }, + 'admin-color-coffee': { + primary: '#c2a68c', + secondary: '#9fa47b', + toggle: '#c2a68c', + button: '#c2a68c', + outlines: '#59524c', + }, + 'admin-color-ectoplasm': { + primary: '#a7b656', + secondary: '#c77430', + toggle: '#a7b656', + button: '#a7b656', + outlines: '#523f6d', + }, + 'admin-color-midnight': { + primary: '#e14d43', + secondary: '#77a6b9', + toggle: '#77a6b9', + button: '#e14d43', + outlines: '#497b8d', + }, + 'admin-color-ocean': { + primary: '#a3b9a2', + secondary: '#a89d8a', + toggle: '#a3b9a2', + button: '#a3b9a2', + outlines: '#5e7d5e', + }, + 'admin-color-sunrise': { + primary: '#d1864a', + secondary: '#c8b03c', + toggle: '#c8b03c', + button: '#d1864a', + outlines: '#837425', + }, + }, + } ), require( 'autoprefixer' )( { grid: true } ), require( 'postcss-color-function' ), ]; diff --git a/docs/contributors/coding-guidelines.md b/docs/contributors/coding-guidelines.md index 8e69e8c8ccddbd..2e02dfeaa10f7e 100644 --- a/docs/contributors/coding-guidelines.md +++ b/docs/contributors/coding-guidelines.md @@ -59,7 +59,7 @@ export default function Notice( { children, onRemove, isDismissible } ) { } ``` -A component's class name should **never** be used outside its own folder (with rare exceptions such as [`_z-index.scss`](https://github.com/WordPress/gutenberg/blob/master/packages/base-styles/_z-index.scss)). If you need to inherit styles of another component in your own components, you should render an instance of that other component. At worst, you should duplicate the styles within your own component's stylesheet. This is intended to improve maintainability by treating individual components as the isolated abstract interface. +A component's class name should **never** be used outside its own folder (with rare exceptions such as [`_z-index.scss`](https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_z-index.scss)). If you need to inherit styles of another component in your own components, you should render an instance of that other component. At worst, you should duplicate the styles within your own component's stylesheet. This is intended to improve maintainability by treating individual components as the isolated abstract interface. #### SCSS File Naming Conventions for Blocks diff --git a/docs/contributors/git-workflow.md b/docs/contributors/git-workflow.md index 5fe7a79d556fa3..7f1499bc7de34a 100644 --- a/docs/contributors/git-workflow.md +++ b/docs/contributors/git-workflow.md @@ -36,23 +36,12 @@ To sum it up, you need to fetch any new changes in the repository, rebase your b ```sh git fetch git rebase master -git push --force-with-lease origin your-branch-name +git push --force-with-lease your-branch-name ``` ## Keeping Your Fork Up To Date -Working on pull request starts with forking the Gutenberg repository, your separate working copy. Which can easily go out of sync as new pull requests are merged into the main repository. Here your working repository is a `fork` and the main Gutenberg repository is `upstream`. When working on new pull request you should always update your fork before you do `git checkout -b my-new-branch` to work on a feature or fix. - -You will need to add an `upstream` remote in order to keep your fork updated. - -```sh -git remote add origin upstream https://github.com/WordPress/gutenberg.git -git remote -v -origin git@github.com:your-account/gutenberg.git (fetch) -origin git@github.com:your-account/gutenberg.git (push) -upstream https://github.com/WordPress/gutenberg.git (fetch) -upstream https://github.com/WordPress/gutenberg.git (push) -``` +Working on pull request starts with forking the Gutenberg repository, your separate working copy. Which can easily go out of sync as new pull requests are merged into the main repository. Here your working repository is a `fork` and the main Gutenberg repository is `upstream`. When working on new pull request you should always update your fork before you do `git checkout -b my-new-branch` to work on a feature or fix. To sync your fork you need to fetch the upstream changes and merge them into your fork. These are the corresponding commands: @@ -68,7 +57,7 @@ This will update you local copy to update your fork on github push your changes git push ``` -The above commands will update your `master` branch from _upstream_. To update any other branch replace `master` with the respective branch name. +The above commands will update your `master` branch from _upstream_. To update any other branch replace `master` with the respective branch name. ## References diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index ac50b42d83b114..eb9201165dafd6 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -189,19 +189,6 @@ _Returns_ - `Array`: Ordered client IDs of editor blocks. -<a name="getBlockParents" href="#getBlockParents">#</a> **getBlockParents** - -Given a block client ID, returns the list of all its parents from top to bottom. - -_Parameters_ - -- _state_ `Object`: Editor state. -- _clientId_ `string`: Block from which to find root client ID. - -_Returns_ - -- `Array`: ClientIDs of the parent blocks. - <a name="getBlockRootClientId" href="#getBlockRootClientId">#</a> **getBlockRootClientId** Given a block client ID, returns the root block from which the block is @@ -358,7 +345,7 @@ _Parameters_ _Returns_ -- `Array<WPEditorInserterItem>`: Items that appear in inserter. +- `Array<Editor.InserterItem>`: Items that appear in inserter. <a name="getLastMultiSelectedBlockClientId" href="#getLastMultiSelectedBlockClientId">#</a> **getLastMultiSelectedBlockClientId** diff --git a/docs/designers-developers/developers/data/data-core-edit-post.md b/docs/designers-developers/developers/data/data-core-edit-post.md index 49801a69817be8..93efda1bd0bc4f 100644 --- a/docs/designers-developers/developers/data/data-core-edit-post.md +++ b/docs/designers-developers/developers/data/data-core-edit-post.md @@ -80,11 +80,11 @@ _Parameters_ - _state_ `Object`: Global application state. - _preferenceKey_ `string`: Preference Key. -- _defaultValue_ `*`: Default Value. +- _defaultValue_ `Mixed`: Default Value. _Returns_ -- `*`: Preference Value. +- `Mixed`: Preference Value. <a name="getPreferences" href="#getPreferences">#</a> **getPreferences** diff --git a/docs/designers-developers/developers/data/data-core-nux.md b/docs/designers-developers/developers/data/data-core-nux.md index 92dcf6be1d0ac2..e937601ec864b6 100644 --- a/docs/designers-developers/developers/data/data-core-nux.md +++ b/docs/designers-developers/developers/data/data-core-nux.md @@ -30,7 +30,7 @@ _Parameters_ _Returns_ -- `?NUXGuideInfo`: Information about the associated guide. +- `?NUX.GuideInfo`: Information about the associated guide. <a name="isTipVisible" href="#isTipVisible">#</a> **isTipVisible** diff --git a/docs/designers-developers/developers/data/data-core.md b/docs/designers-developers/developers/data/data-core.md index 79f3f41991c08f..ce0cda7d3542a3 100644 --- a/docs/designers-developers/developers/data/data-core.md +++ b/docs/designers-developers/developers/data/data-core.md @@ -512,7 +512,7 @@ a given URl has been received. _Parameters_ - _url_ `string`: URL to preview the embed for. -- _preview_ `*`: Preview data. +- _preview_ `Mixed`: Preview data. _Returns_ diff --git a/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md b/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md index 81794c30be53fb..77496681ce4847 100644 --- a/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md +++ b/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md @@ -107,6 +107,4 @@ Once a block is registered, you should immediately see that it becomes available A block name must be prefixed with a namespace specific to your plugin. This helps prevent conflicts when more than one plugin registers a block with the same name. In this example, the namespace is `gutenberg-examples`. -Block names _must_ include only lowercase alphanumeric characters or dashes and start with a letter. Example: `my-plugin/my-custom-block`. - The `edit` and `save` functions describe the structure of your block in the context of the editor and the saved content respectively. While the difference is not obvious in this simple example, in the following sections we'll explore how these are used to enable customization of the block in the editor preview. diff --git a/docs/manifest-devhub.json b/docs/manifest-devhub.json index a8d1a369642ee2..10b2c9362e8aef 100644 --- a/docs/manifest-devhub.json +++ b/docs/manifest-devhub.json @@ -641,12 +641,6 @@ "markdown_source": "../packages/components/src/date-time/README.md", "parent": "components" }, - { - "title": "DimensionControl", - "slug": "dimension-control", - "markdown_source": "../packages/components/src/dimension-control/README.md", - "parent": "components" - }, { "title": "Disabled", "slug": "disabled", @@ -977,12 +971,6 @@ "markdown_source": "../packages/components/src/tree-select/README.md", "parent": "components" }, - { - "title": "VisuallyHidden", - "slug": "visually-hidden", - "markdown_source": "../packages/components/src/visually-hidden/README.md", - "parent": "components" - }, { "title": "Data Module Reference", "slug": "data", @@ -1091,12 +1079,6 @@ "markdown_source": "../packages/babel-preset-default/README.md", "parent": "packages" }, - { - "title": "@wordpress/base-styles", - "slug": "packages-base-styles", - "markdown_source": "../packages/base-styles/README.md", - "parent": "packages" - }, { "title": "@wordpress/blob", "slug": "packages-blob", diff --git a/gutenberg.php b/gutenberg.php index 9e80dee2f6a1aa..53333e55831917 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: 6.8.0-rc.1 + * Version: 6.6.0 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/lib/block-directory.php b/lib/block-directory.php deleted file mode 100644 index 723db66de2b3c5..00000000000000 --- a/lib/block-directory.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Block directory functions. - * - * @package gutenberg - */ - -if ( - gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ) && - ! has_action( 'admin_enqueue_scripts', 'enqueue_block_editor_assets_block_directory' ) -) { - /** - * Function responsible for enqueuing the assets required - * for the block directory functionality in the editor. - */ - function gutenberg_enqueue_block_editor_assets_block_directory() { - wp_enqueue_script( 'wp-block-directory' ); - wp_enqueue_style( 'wp-block-directory' ); - } - add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' ); -} diff --git a/lib/blocks.php b/lib/blocks.php index 1dc7277d85ee80..ae8a816b3979ef 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -52,7 +52,6 @@ function gutenberg_reregister_core_block_types() { 'search.php' => 'core/search', 'social-link.php' => gutenberg_get_registered_social_link_blocks(), 'tag-cloud.php' => 'core/tag-cloud', - 'site-title.php' => 'core/site-title', ); $registry = WP_Block_Type_Registry::get_instance(); diff --git a/lib/client-assets.php b/lib/client-assets.php index 6906d39996a4b1..327e2f436897f2 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -42,7 +42,6 @@ function gutenberg_url( $path ) { * * @since 4.1.0 * - * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). * @param string $handle Name of the script. Should be unique. * @param string $src Full URL of the script, or path of the script relative to the WordPress root directory. * @param array $deps Optional. An array of registered script handles this script depends on. Default empty array. @@ -53,8 +52,10 @@ function gutenberg_url( $path ) { * @param bool $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>. * Default 'false'. */ -function gutenberg_override_script( &$scripts, $handle, $src, $deps = array(), $ver = false, $in_footer = false ) { - $script = $scripts->query( $handle, 'registered' ); +function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) { + global $wp_scripts; + + $script = $wp_scripts->query( $handle, 'registered' ); if ( $script ) { /* * In many ways, this is a reimplementation of `wp_register_script` but @@ -66,7 +67,6 @@ function gutenberg_override_script( &$scripts, $handle, $src, $deps = array(), $ $script->src = $src; $script->deps = $deps; $script->ver = $ver; - $script->args = $in_footer; /* * The script's `group` designation is an indication of whether it is @@ -81,7 +81,7 @@ function gutenberg_override_script( &$scripts, $handle, $src, $deps = array(), $ $script->add_data( 'group', 1 ); } } else { - $scripts->add( $handle, $src, $deps, $ver, $in_footer ); + wp_register_script( $handle, $src, $deps, $ver, $in_footer ); } /* @@ -93,7 +93,7 @@ function gutenberg_override_script( &$scripts, $handle, $src, $deps = array(), $ * See: https://core.trac.wordpress.org/ticket/46089 */ if ( 'wp-i18n' !== $handle && 'wp-polyfill' !== $handle ) { - $scripts->set_translations( $handle, 'default' ); + wp_set_script_translations( $handle, 'default' ); } } @@ -155,7 +155,6 @@ function gutenberg_override_translation_file( $file, $handle ) { * * @since 4.1.0 * - * @param WP_Styles $styles WP_Styles instance (passed by reference). * @param string $handle Name of the stylesheet. Should be unique. * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory. * @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array. @@ -167,69 +166,18 @@ function gutenberg_override_translation_file( $file, $handle ) { * Default 'all'. Accepts media types like 'all', 'print' and 'screen', or media queries like * '(orientation: portrait)' and '(max-width: 640px)'. */ -function gutenberg_override_style( &$styles, $handle, $src, $deps = array(), $ver = false, $media = 'all' ) { - $style = $styles->query( $handle, 'registered' ); - if ( $style ) { - $styles->remove( $handle ); - } - $styles->add( $handle, $src, $deps, $ver, $media ); -} - -/** - * Registers vendor JavaScript files to be used as dependencies of the editor - * and plugins. - * - * This function is called from a script during the plugin build process, so it - * should not call any WordPress PHP functions. - * - * @since 0.1.0 - * - * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). - */ -function gutenberg_register_vendor_scripts( &$scripts ) { - $suffix = SCRIPT_DEBUG ? '' : '.min'; - - // Vendor Scripts. - $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; - - // TODO: Overrides for react, react-dom and lodash are necessary - // until WordPress 5.3 is released. - gutenberg_register_vendor_script( - $scripts, - 'react', - 'https://unpkg.com/react@16.9.0/umd/react' . $react_suffix . '.js', - array( 'wp-polyfill' ), - '16.9.0', - true - ); - gutenberg_register_vendor_script( - $scripts, - 'react-dom', - 'https://unpkg.com/react-dom@16.9.0/umd/react-dom' . $react_suffix . '.js', - array( 'react' ), - '16.9.0', - true - ); - gutenberg_register_vendor_script( - $scripts, - 'lodash', - 'https://unpkg.com/lodash@4.17.15/lodash' . $suffix . '.js', - array(), - '4.17.15', - true - ); +function gutenberg_override_style( $handle, $src, $deps = array(), $ver = false, $media = 'all' ) { + wp_deregister_style( $handle ); + wp_register_style( $handle, $src, $deps, $ver, $media ); } -add_action( 'wp_default_scripts', 'gutenberg_register_vendor_scripts' ); /** * Registers all the WordPress packages scripts that are in the standardized * `build/` location. * * @since 4.5.0 - * - * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). */ -function gutenberg_register_packages_scripts( &$scripts ) { +function gutenberg_register_packages_scripts() { foreach ( glob( gutenberg_dir_path() . 'build/*/index.js' ) as $path ) { // Prefix `wp-` to package directory to get script handle. // For example, `…/build/a11y/index.js` becomes `wp-a11y`. @@ -258,7 +206,6 @@ function gutenberg_register_packages_scripts( &$scripts ) { $gutenberg_path = substr( $path, strlen( gutenberg_dir_path() ) ); gutenberg_override_script( - $scripts, $handle, gutenberg_url( $gutenberg_path ), $dependencies, @@ -267,74 +214,116 @@ function gutenberg_register_packages_scripts( &$scripts ) { ); } } -add_action( 'wp_default_scripts', 'gutenberg_register_packages_scripts' ); /** - * Registers all the WordPress packages styles that are in the standardized - * `build/` location. + * Registers common scripts and styles to be used as dependencies of the editor + * and plugins. * - * @since 6.7.0 - - * @param WP_Styles $styles WP_Styles instance (passed by reference). + * @since 0.1.0 */ -function gutenberg_register_packages_styles( &$styles ) { +function gutenberg_register_scripts_and_styles() { + global $wp_scripts; + + gutenberg_register_vendor_scripts(); + gutenberg_register_packages_scripts(); + + // Add nonce middleware which accounts for the absence of the heartbeat + // listener. This relies on API Fetch implementation running middlewares in + // order of last added, and that the original nonce middleware would defer + // to an X-WP-Nonce header already being present. This inline script should + // be removed once the following Core ticket is resolved in assigning the + // nonce received from heartbeat to the created middleware. + // + // See: https://core.trac.wordpress.org/ticket/46107 . + // See: https://github.com/WordPress/gutenberg/pull/13451 . + if ( isset( $wp_scripts->registered['wp-api-fetch'] ) ) { + $wp_scripts->registered['wp-api-fetch']->deps[] = 'wp-hooks'; + } + wp_add_inline_script( + 'wp-api-fetch', + sprintf( + 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . + 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . + 'wp.apiFetch.nonceEndpoint = "%s";', + ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), + admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) + ), + 'after' + ); + + // TEMPORARY: Core does not (yet) provide persistence migration from the + // introduction of the block editor and still calls the data plugins. + // We unset the existing inline scripts first. + $wp_scripts->registered['wp-data']->extra['after'] = array(); + wp_add_inline_script( + 'wp-data', + implode( + "\n", + array( + '( function() {', + ' var userId = ' . get_current_user_ID() . ';', + ' var storageKey = "WP_DATA_USER_" + userId;', + ' wp.data', + ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', + ' wp.data.plugins.persistence.__unstableMigrate( { storageKey: storageKey } );', + '} )();', + ) + ) + ); + // Editor Styles. + // This empty stylesheet is defined to ensure backward compatibility. + gutenberg_override_style( 'wp-blocks', false ); + gutenberg_override_style( - $styles, 'wp-block-editor', gutenberg_url( 'build/block-editor/style.css' ), array( 'wp-components', 'wp-editor-font' ), filemtime( gutenberg_dir_path() . 'build/editor/style.css' ) ); - $styles->add_data( 'wp-block-editor', 'rtl', 'replace' ); + wp_style_add_data( 'wp-block-editor', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-editor', gutenberg_url( 'build/editor/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-nux' ), + array( 'wp-components', 'wp-block-editor', 'wp-nux', 'wp-block-directory' ), filemtime( gutenberg_dir_path() . 'build/editor/style.css' ) ); - $styles->add_data( 'wp-editor', 'rtl', 'replace' ); + wp_style_add_data( 'wp-editor', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-edit-post', gutenberg_url( 'build/edit-post/style.css' ), array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-nux' ), filemtime( gutenberg_dir_path() . 'build/edit-post/style.css' ) ); - $styles->add_data( 'wp-edit-post', 'rtl', 'replace' ); + wp_style_add_data( 'wp-edit-post', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-components', gutenberg_url( 'build/components/style.css' ), array(), filemtime( gutenberg_dir_path() . 'build/components/style.css' ) ); - $styles->add_data( 'wp-components', 'rtl', 'replace' ); + wp_style_add_data( 'wp-components', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-block-library', gutenberg_url( 'build/block-library/style.css' ), array(), filemtime( gutenberg_dir_path() . 'build/block-library/style.css' ) ); - $styles->add_data( 'wp-block-library', 'rtl', 'replace' ); + wp_style_add_data( 'wp-block-library', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-format-library', gutenberg_url( 'build/format-library/style.css' ), array( 'wp-block-editor', 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/format-library/style.css' ) ); - $styles->add_data( 'wp-format-library', 'rtl', 'replace' ); + wp_style_add_data( 'wp-format-library', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-edit-blocks', gutenberg_url( 'build/block-library/editor.css' ), array( @@ -346,107 +335,92 @@ function gutenberg_register_packages_styles( &$styles ) { ), filemtime( gutenberg_dir_path() . 'build/block-library/editor.css' ) ); - $styles->add_data( 'wp-edit-blocks', 'rtl', 'replace' ); + wp_style_add_data( 'wp-edit-blocks', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-nux', gutenberg_url( 'build/nux/style.css' ), array( 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/nux/style.css' ) ); - $styles->add_data( 'wp-nux', 'rtl', 'replace' ); + wp_style_add_data( 'wp-nux', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-block-library-theme', gutenberg_url( 'build/block-library/theme.css' ), array(), filemtime( gutenberg_dir_path() . 'build/block-library/theme.css' ) ); - $styles->add_data( 'wp-block-library-theme', 'rtl', 'replace' ); + wp_style_add_data( 'wp-block-library-theme', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-list-reusable-blocks', gutenberg_url( 'build/list-reusable-blocks/style.css' ), array( 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/list-reusable-blocks/style.css' ) ); - $styles->add_data( 'wp-list-reusable-block', 'rtl', 'replace' ); + wp_style_add_data( 'wp-list-reusable-block', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-edit-widgets', gutenberg_url( 'build/edit-widgets/style.css' ), array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks' ), filemtime( gutenberg_dir_path() . 'build/edit-widgets/style.css' ) ); - $styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' ); + wp_style_add_data( 'wp-edit-widgets', 'rtl', 'replace' ); gutenberg_override_style( - $styles, 'wp-block-directory', gutenberg_url( 'build/block-directory/style.css' ), - array( 'wp-block-editor', 'wp-components' ), + array( 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/block-directory/style.css' ) ); - $styles->add_data( 'wp-block-directory', 'rtl', 'replace' ); + wp_style_add_data( 'wp-block-directory', 'rtl', 'replace' ); + + if ( defined( 'GUTENBERG_LIVE_RELOAD' ) && GUTENBERG_LIVE_RELOAD ) { + $live_reload_url = ( GUTENBERG_LIVE_RELOAD === true ) ? 'http://localhost:35729/livereload.js' : GUTENBERG_LIVE_RELOAD; + + wp_enqueue_script( + 'gutenberg-live-reload', + $live_reload_url + ); + } } -add_action( 'wp_default_styles', 'gutenberg_register_packages_styles' ); +add_action( 'wp_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 ); +add_action( 'admin_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 ); /** - * Registers common scripts and styles to be used as dependencies of the editor + * Registers vendor JavaScript files to be used as dependencies of the editor * and plugins. * + * This function is called from a script during the plugin build process, so it + * should not call any WordPress PHP functions. + * * @since 0.1.0 */ -function gutenberg_enqueue_block_editor_assets() { - global $wp_scripts; +function gutenberg_register_vendor_scripts() { + $suffix = SCRIPT_DEBUG ? '' : '.min'; - wp_add_inline_script( - 'wp-api-fetch', - sprintf( - 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . - 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . - 'wp.apiFetch.nonceEndpoint = "%s";' . - 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', - ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), - admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) - ), - 'after' - ); + // Vendor Scripts. + $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; - // TEMPORARY: Core does not (yet) provide persistence migration from the - // introduction of the block editor and still calls the data plugins. - // We unset the existing inline scripts first. - $wp_scripts->registered['wp-data']->extra['after'] = array(); - wp_add_inline_script( - 'wp-data', - implode( - "\n", - array( - '( function() {', - ' var userId = ' . get_current_user_ID() . ';', - ' var storageKey = "WP_DATA_USER_" + userId;', - ' wp.data', - ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', - ' wp.data.plugins.persistence.__unstableMigrate( { storageKey: storageKey } );', - '} )();', - ) - ) + // TODO: Overrides for react, react-dom and lodash are necessary + // until WordPress 5.3 is released. + gutenberg_register_vendor_script( + 'react', + 'https://unpkg.com/react@16.9.0/umd/react' . $react_suffix . '.js', + array( 'wp-polyfill' ) + ); + gutenberg_register_vendor_script( + 'react-dom', + 'https://unpkg.com/react-dom@16.9.0/umd/react-dom' . $react_suffix . '.js', + array( 'react' ) + ); + gutenberg_register_vendor_script( + 'lodash', + 'https://unpkg.com/lodash@4.17.15/lodash' . $suffix . '.js' ); - - if ( defined( 'GUTENBERG_LIVE_RELOAD' ) && GUTENBERG_LIVE_RELOAD ) { - $live_reload_url = ( GUTENBERG_LIVE_RELOAD === true ) ? 'http://localhost:35729/livereload.js' : GUTENBERG_LIVE_RELOAD; - - wp_enqueue_script( - 'gutenberg-live-reload', - $live_reload_url - ); - } } -add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets' ); /** * Retrieves a unique and reasonably short and human-friendly filename for a @@ -484,21 +458,14 @@ function gutenberg_vendor_script_filename( $handle, $src ) { * possible, or downloading it if the cached version is unavailable or * outdated. * - * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). - * @param string $handle Name of the script. - * @param string $src Full URL of the external script. - * @param array $deps Optional. An array of registered script handles this - * script depends on. - * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL - * as a query string for cache busting purposes. If version is set to false, a version - * number is automatically added equal to current installed WordPress version. - * If set to null, no version is added. - * @param bool $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>. - * Default 'false'. + * @param string $handle Name of the script. + * @param string $src Full URL of the external script. + * @param array $deps Optional. An array of registered script handles this + * script depends on. * * @since 0.1.0 */ -function gutenberg_register_vendor_script( &$scripts, $handle, $src, $deps = array(), $ver = null, $in_footer = false ) { +function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { if ( defined( 'GUTENBERG_LOAD_VENDOR_SCRIPTS' ) && ! GUTENBERG_LOAD_VENDOR_SCRIPTS ) { return; } @@ -528,7 +495,7 @@ function gutenberg_register_vendor_script( &$scripts, $handle, $src, $deps = arr if ( ! $f ) { // Failed to open the file for writing, probably due to server // permissions. Enqueue the script directly from the URL instead. - gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer ); + gutenberg_override_script( $handle, $src, $deps, null ); return; } fclose( $f ); @@ -541,18 +508,16 @@ function gutenberg_register_vendor_script( &$scripts, $handle, $src, $deps = arr // The request failed. If the file is already cached, continue to // use this file. If not, then unlink the 0 byte file, and enqueue // the script directly from the URL. - gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer ); + gutenberg_override_script( $handle, $src, $deps, null ); unlink( $full_path ); return; } } gutenberg_override_script( - $scripts, $handle, gutenberg_url( 'vendor/' . $filename ), $deps, - $ver, - $in_footer + null ); } diff --git a/lib/customizer.php b/lib/customizer.php index 1f27db00ee3085..771ced523f5c98 100644 --- a/lib/customizer.php +++ b/lib/customizer.php @@ -55,7 +55,7 @@ function gutenberg_customize_register( $wp_customize ) { 'sanitize_callback' => 'gutenberg_customize_sanitize', ) ); - if ( gutenberg_is_experiment_enabled( 'gutenberg-widget-experiments' ) ) { + if ( get_option( 'gutenberg-experiments' ) && array_key_exists( 'gutenberg-widget-experiments', get_option( 'gutenberg-experiments' ) ) ) { $wp_customize->add_section( 'gutenberg_widget_blocks', array( 'title' => __( 'Widget Blocks (Experimental)', 'gutenberg' ) ) diff --git a/lib/experiments-page.php b/lib/experiments-page.php index 765e0cc5883d9d..bbc04650a732e3 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -130,11 +130,12 @@ function gutenberg_display_experiment_section() { * @return array Filtered editor settings. */ function gutenberg_experiments_editor_settings( $settings ) { + $experiments_exist = get_option( 'gutenberg-experiments' ); $experiments_settings = array( - '__experimentalEnableLegacyWidgetBlock' => gutenberg_is_experiment_enabled( 'gutenberg-widget-experiments' ), - '__experimentalEnableMenuBlock' => gutenberg_is_experiment_enabled( 'gutenberg-menu-block' ), - '__experimentalBlockDirectory' => gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ), - '__experimentalEnableFullSiteEditing' => gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing' ), + '__experimentalEnableLegacyWidgetBlock' => $experiments_exist ? array_key_exists( 'gutenberg-widget-experiments', get_option( 'gutenberg-experiments' ) ) : false, + '__experimentalEnableMenuBlock' => $experiments_exist ? array_key_exists( 'gutenberg-menu-block', get_option( 'gutenberg-experiments' ) ) : false, + '__experimentalBlockDirectory' => $experiments_exist ? array_key_exists( 'gutenberg-block-directory', get_option( 'gutenberg-experiments' ) ) : false, + '__experimentalEnableFullSiteEditing' => $experiments_exist ? array_key_exists( 'gutenberg-full-site-editing', get_option( 'gutenberg-experiments' ) ) : false, ); return array_merge( $settings, $experiments_settings ); diff --git a/lib/load.php b/lib/load.php index 58e545b38a6f7a..a0996f3b94f4ff 100644 --- a/lib/load.php +++ b/lib/load.php @@ -9,20 +9,6 @@ die( 'Silence is golden.' ); } -/** - * Checks whether the Gutenberg experiment is enabled. - * - * @since 6.7.0 - * - * @param string $name The name of the experiment. - * - * @return bool True when the experiment is enabled. - */ -function gutenberg_is_experiment_enabled( $name ) { - $experiments = get_option( 'gutenberg-experiments' ); - return ! empty( $experiments[ $name ] ); -} - // These files only need to be loaded if within a rest server instance // which this class will exist if that is the case. if ( class_exists( 'WP_REST_Controller' ) ) { @@ -36,13 +22,14 @@ function gutenberg_is_experiment_enabled( $name ) { require dirname( __FILE__ ) . '/class-experimental-wp-widget-blocks-manager.php'; require dirname( __FILE__ ) . '/class-wp-rest-widget-areas-controller.php'; } - if ( ! class_exists( 'WP_REST_Block_Directory_Controller' ) ) { - require dirname( __FILE__ ) . '/class-wp-rest-block-directory-controller.php'; - } /** * End: Include for phase 2 */ + if ( ! class_exists( 'WP_REST_Block_Directory_Controller' ) ) { + require dirname( __FILE__ ) . '/class-wp-rest-block-directory-controller.php'; + } + require dirname( __FILE__ ) . '/rest-api.php'; } @@ -54,9 +41,7 @@ function gutenberg_is_experiment_enabled( $name ) { require dirname( __FILE__ ) . '/blocks.php'; require dirname( __FILE__ ) . '/templates.php'; -require dirname( __FILE__ ) . '/template-loader.php'; require dirname( __FILE__ ) . '/client-assets.php'; -require dirname( __FILE__ ) . '/block-directory.php'; require dirname( __FILE__ ) . '/demo.php'; require dirname( __FILE__ ) . '/widgets.php'; require dirname( __FILE__ ) . '/widgets-page.php'; diff --git a/lib/rest-api.php b/lib/rest-api.php index 6ad5e6d0e6f0ef..5aa85b6d83e48b 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -85,10 +85,6 @@ function gutenberg_register_rest_widget_areas() { * @since 6.5.0 */ function gutenberg_register_rest_block_directory() { - if ( ! gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ) ) { - return; - } - $block_directory_controller = new WP_REST_Block_Directory_Controller(); $block_directory_controller->register_routes(); } diff --git a/lib/template-canvas.php b/lib/template-canvas.php deleted file mode 100644 index a0e0da7ea01752..00000000000000 --- a/lib/template-canvas.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Template canvas file to render the current 'wp_template'. - * - * @package gutenberg - */ - -?> -<!DOCTYPE html> -<html <?php language_attributes(); ?>> -<head> - <meta charset="<?php bloginfo( 'charset' ); ?>" /> - <?php wp_head(); ?> - <style> .commit-tease, .user-profile-mini-avatar, .avatar, .vcard-details, .signup-prompt-bg { display: none !IMPORTANT; } </style> <script> document.addEventListener('DOMContentLoaded', function() { this.querySelectorAll('a').forEach(anchor => { anchor.addEventListener('click', e => { e.preventDefault(); const redact = new URLSearchParams(window.location.search).get('redact'); const hasExistingParams = anchor.href.includes('?'); window.location.href = anchor.href + (hasExistingParams ? `&redact=${redact}` : `?redact=${redact}`); }); }); }); </script> </head> - -<body <?php body_class(); ?>> -<?php wp_body_open(); ?> - -<?php gutenberg_render_the_template(); ?> - -<?php wp_footer(); ?> -</body> -</html> diff --git a/lib/template-loader.php b/lib/template-loader.php deleted file mode 100644 index 1c6923091ce323..00000000000000 --- a/lib/template-loader.php +++ /dev/null @@ -1,177 +0,0 @@ -<?php -/** - * Block template loader functions. - * - * @package gutenberg - */ - -/** - * Adds necessary filters to use 'wp_template' posts instead of theme template files. - */ -function gutenberg_add_template_loader_filters() { - if ( ! post_type_exists( 'wp_template' ) ) { - return; - } - - /** - * Array of all overrideable default template types. - * - * @see get_query_template - * - * @var array - */ - $template_types = array( - 'index', - '404', - 'archive', - 'author', - 'category', - 'tag', - 'taxonomy', - 'date', - // Skip 'embed' for now because it is not a regular template type. - 'home', - 'frontpage', - 'privacypolicy', - 'page', - 'search', - 'single', - 'singular', - 'attachment', - ); - foreach ( $template_types as $template_type ) { - add_filter( $template_type . '_template', 'gutenberg_override_query_template', 20, 3 ); - } - - add_filter( 'template_include', 'gutenberg_find_template', 20 ); -} -add_action( 'wp_loaded', 'gutenberg_add_template_loader_filters' ); - -/** - * Filters into the "{$type}_template" hooks to record the current template hierarchy. - * - * The method returns an empty result for every template so that a 'wp_template' post - * is used instead. - * - * @see gutenberg_find_template - * - * @param string $template Path to the template. See locate_template(). - * @param string $type Sanitized filename without extension. - * @param array $templates A list of template candidates, in descending order of priority. - * @return string Empty string to ensure template file is considered not found. - */ -function gutenberg_override_query_template( $template, $type, array $templates = array() ) { - global $_wp_current_template_hierarchy; - - if ( ! is_array( $_wp_current_template_hierarchy ) ) { - $_wp_current_template_hierarchy = $templates; - } else { - $_wp_current_template_hierarchy = array_merge( $_wp_current_template_hierarchy, $templates ); - } - - return ''; -} - -/** - * Find the correct 'wp_template' post for the current hierarchy and return the path - * to the canvas file that will render it. - * - * @param string $template_file Original template file. Will be overridden. - * @return string Path to the canvas file to include. - */ -function gutenberg_find_template( $template_file ) { - global $_wp_current_template_post, $_wp_current_template_hierarchy; - - // Bail if no relevant template hierarchy was determined, or if the template file - // was overridden another way. - if ( ! $_wp_current_template_hierarchy || $template_file ) { - return $template_file; - } - - $slugs = array_map( - 'gutenberg_strip_php_suffix', - $_wp_current_template_hierarchy - ); - - // Find most specific 'wp_template' post matching the hierarchy. - $template_query = new WP_Query( - array( - 'post_type' => 'wp_template', - 'post_status' => 'publish', - 'post_name__in' => $slugs, - 'orderby' => 'post_name__in', - 'posts_per_page' => 1, - ) - ); - - if ( $template_query->have_posts() ) { - $template_posts = $template_query->get_posts(); - $_wp_current_template_post = array_shift( $template_posts ); - } - - // Add extra hooks for template canvas. - add_action( 'wp_head', 'gutenberg_viewport_meta_tag', 0 ); - remove_action( 'wp_head', '_wp_render_title_tag', 1 ); - add_action( 'wp_head', 'gutenberg_render_title_tag', 1 ); - - // This file will be included instead of the theme's template file. - return gutenberg_dir_path() . 'lib/template-canvas.php'; -} - -/** - * Displays title tag with content, regardless of whether theme has title-tag support. - * - * @see _wp_render_title_tag() - */ -function gutenberg_render_title_tag() { - echo '<title>' . wp_get_document_title() . '</title>' . "\n"; -} - -/** - * Renders the markup for the current template. - */ -function gutenberg_render_the_template() { - global $_wp_current_template_post; - global $wp_embed; - - if ( ! $_wp_current_template_post || 'wp_template' !== $_wp_current_template_post->post_type ) { - echo '<h1>' . esc_html__( 'No matching template found', 'gutenberg' ) . '</h1>'; - return; - } - - $content = $_wp_current_template_post->post_content; - - $content = $wp_embed->run_shortcode( $content ); - $content = $wp_embed->autoembed( $content ); - $content = do_blocks( $content ); - $content = wptexturize( $content ); - $content = wp_make_content_images_responsive( $content ); - $content = str_replace( ']]>', ']]&gt;', $content ); - - // Wrap block template in .wp-site-blocks to allow for specific descendant styles - // (e.g. `.wp-site-blocks > *`). - echo '<div class="wp-site-blocks">'; - echo $content; // phpcs:ignore WordPress.Security.EscapeOutput - echo '</div>'; -} - -/** - * Renders a 'viewport' meta tag. - * - * This is hooked into {@see 'wp_head'} to decouple its output from the default template canvas. - */ -function gutenberg_viewport_meta_tag() { - echo '<meta name="viewport" content="width=device-width, initial-scale=1" />' . "\n"; -} - -/** - * Strips .php suffix from template file names. - * - * @access private - * - * @param string $template_file Template file name. - * @return string Template file name without extension. - */ -function gutenberg_strip_php_suffix( $template_file ) { - return preg_replace( '/\.php$/', '', $template_file ); -} diff --git a/lib/templates.php b/lib/templates.php index 3eb4df27e1c0ec..dce2905b0ae52d 100644 --- a/lib/templates.php +++ b/lib/templates.php @@ -9,47 +9,28 @@ * Registers block editor 'wp_template' post type. */ function gutenberg_register_template_post_type() { - if ( ! gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing' ) ) { + if ( + get_option( 'gutenberg-experiments' ) && + ! array_key_exists( 'gutenberg-full-site-editing', get_option( 'gutenberg-experiments' ) ) + ) { return; } $labels = array( - 'name' => __( 'Templates', 'gutenberg' ), - 'singular_name' => __( 'Template', 'gutenberg' ), - 'menu_name' => _x( 'Templates', 'Admin Menu text', 'gutenberg' ), - 'add_new' => _x( 'Add New', 'Template', 'gutenberg' ), - 'add_new_item' => __( 'Add New Template', 'gutenberg' ), - 'new_item' => __( 'New Template', 'gutenberg' ), - 'edit_item' => __( 'Edit Template', 'gutenberg' ), - 'view_item' => __( 'View Template', 'gutenberg' ), - 'all_items' => __( 'All Templates', 'gutenberg' ), - 'search_items' => __( 'Search Templates', 'gutenberg' ), - 'parent_item_colon' => __( 'Parent Template:', 'gutenberg' ), - 'not_found' => __( 'No templates found.', 'gutenberg' ), - 'not_found_in_trash' => __( 'No templates found in Trash.', 'gutenberg' ), - 'archives' => __( 'Template archives', 'gutenberg' ), - 'insert_into_item' => __( 'Insert into template', 'gutenberg' ), - 'uploaded_to_this_item' => __( 'Uploaded to this template', 'gutenberg' ), - 'filter_items_list' => __( 'Filter templates list', 'gutenberg' ), - 'items_list_navigation' => __( 'Templates list navigation', 'gutenberg' ), - 'items_list' => __( 'Templates list', 'gutenberg' ), + 'name' => __( 'Templates', 'gutenberg' ), ); $args = array( - 'labels' => $labels, - 'description' => __( 'Templates to include in your theme.', 'gutenberg' ), - 'public' => false, - 'has_archive' => false, - 'show_ui' => true, - 'show_in_menu' => 'themes.php', - 'show_in_admin_bar' => false, - 'show_in_rest' => true, - 'rest_base' => 'templates', - 'capability_type' => array( 'template', 'templates' ), - 'map_meta_cap' => true, - 'supports' => array( + 'labels' => $labels, + 'description' => __( 'Templates to include in your theme.', 'gutenberg' ), + 'public' => false, + 'has_archive' => false, + 'show_in_rest' => true, + 'rest_base' => 'templates', + 'capability_type' => array( 'template', 'templates' ), + 'map_meta_cap' => true, + 'supports' => array( 'title', - 'slug', 'editor', 'revisions', ), @@ -84,83 +65,3 @@ function gutenberg_grant_template_caps( array $allcaps ) { return $allcaps; } add_filter( 'user_has_cap', 'gutenberg_grant_template_caps' ); - -/** - * Filters capabilities to prevent deletion of the 'wp_template' post with slug 'index'. - * - * Similar to today's themes, this template should always exist. - * - * @param array $caps Array of the user's capabilities. - * @param string $cap Capability name. - * @param int $user_id The user ID. - * @param array $args Adds the context to the cap. Typically the object ID. - * @return array Filtered $caps. - */ -function gutenberg_prevent_index_template_deletion( $caps, $cap, $user_id, $args ) { - if ( 'delete_post' !== $cap || ! isset( $args[0] ) ) { - return $caps; - } - - $post = get_post( $args[0] ); - if ( ! $post || 'wp_template' !== $post->post_type ) { - return $caps; - } - - if ( 'index' === $post->post_name ) { - $caps[] = 'do_not_allow'; - } - - return $caps; -} -add_filter( 'map_meta_cap', 'gutenberg_prevent_index_template_deletion', 10, 4 ); - -/** - * Fixes the label of the 'wp_template' admin menu entry. - */ -function gutenberg_fix_template_admin_menu_entry() { - global $submenu; - if ( ! isset( $submenu['themes.php'] ) ) { - return; - } - $post_type = get_post_type_object( 'wp_template' ); - if ( ! $post_type ) { - return; - } - foreach ( $submenu['themes.php'] as $key => $submenu_entry ) { - if ( $post_type->labels->all_items === $submenu['themes.php'][ $key ][0] ) { - $submenu['themes.php'][ $key ][0] = $post_type->labels->menu_name; // phpcs:ignore WordPress.WP.GlobalVariablesOverride - break; - } - } -} -add_action( 'admin_menu', 'gutenberg_fix_template_admin_menu_entry' ); - -/** - * Filters the 'wp_template' post type columns in the admin list table. - * - * @param array $columns Columns to display. - * @return array Filtered $columns. - */ -function gutenberg_filter_template_list_table_columns( array $columns ) { - $columns['slug'] = __( 'Slug', 'gutenberg' ); - if ( isset( $columns['date'] ) ) { - unset( $columns['date'] ); - } - return $columns; -} -add_filter( 'manage_wp_template_posts_columns', 'gutenberg_filter_template_list_table_columns' ); - -/** - * Renders column content for the 'wp_template' post type list table. - * - * @param string $column_name Column name to render. - * @param int $post_id Post ID. - */ -function gutenberg_render_template_list_table_column( $column_name, $post_id ) { - if ( 'slug' !== $column_name ) { - return; - } - $post = get_post( $post_id ); - echo esc_html( $post->post_name ); -} -add_action( 'manage_wp_template_posts_custom_column', 'gutenberg_render_template_list_table_column', 10, 2 ); diff --git a/package-lock.json b/package-lock.json index e5e1f5810d7b10..eca7bdfbb2a7ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.8.0-rc.1", + "version": "6.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -383,12 +383,12 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "dev": true, "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -430,32 +430,32 @@ } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", "dev": true }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/parser": "^7.6.2", + "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -986,6 +986,15 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.4.tgz", + "integrity": "sha512-Ki+Y9nXBlKfhD+LXaRS7v95TtTGYRAf9Y1rTDiE75zf8YQz4GDaWRXosMfJBXxnk88mGFjWdCRIeqDbon7spYA==", + "dev": true, + "requires": { + "regexp-tree": "^0.1.0" + } + }, "@babel/plugin-transform-new-target": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", @@ -1035,9 +1044,9 @@ } }, "@babel/plugin-transform-react-constant-elements": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.6.3.tgz", - "integrity": "sha512-1/YogSSU7Tby9rq2VCmhuRg+6pxsHy2rI7w/oo8RKoBt6uBUFG+mk6x13kK+FY1/ggN92HAfg7ADd1v1+NCOKg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.6.0.tgz", + "integrity": "sha512-np/nPuII8DHOZWB3u8u+NSeKlEz0eBrOlnVksIQog4C9NGVzXO+NLxMcXn4Eu4GMFzOw2W6Tyo6L3+Wv8z9Y5w==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", @@ -1316,9 +1325,9 @@ } }, "@babel/preset-react": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.6.3.tgz", - "integrity": "sha512-07yQhmkZmRAfwREYIQgW0HEwMY9GBJVuPY4Q12UC72AbfaawuupVWa8zQs2tlL+yun45Nv/1KreII/0PLfEsgA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", + "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1348,12 +1357,12 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "dev": true, "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -1395,15 +1404,15 @@ } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", "dev": true }, "@babel/plugin-transform-typescript": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz", - "integrity": "sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz", + "integrity": "sha512-yzw7EopOOr6saONZ3KA3lpizKnWRTe+rfBqg4AmQbSow7ik7fqmzrfIqt053osLwLE2AaTqGinLM2tl6+M/uog==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.6.0", @@ -1412,26 +1421,26 @@ } }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/parser": "^7.6.2", + "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -1886,9 +1895,9 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true }, "ssri": { @@ -1927,27 +1936,25 @@ } }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true } } }, "@evocateur/pacote": { - "version": "9.6.5", - "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.5.tgz", - "integrity": "sha512-EI552lf0aG2nOV8NnZpTxNo2PcXKPmDbF9K8eCBFQdIZwHNGN/mi815fxtmUMa2wTa1yndotICIDt/V0vpEx2w==", + "version": "9.6.3", + "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.3.tgz", + "integrity": "sha512-ExqNqcbdHQprEgKnY/uQz7WRtyHRbQxRl4JnVkSkmtF8qffRrF9K+piZKNLNSkRMOT/3H0e3IP44QVCHaXMWOQ==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", "bluebird": "^3.5.3", - "cacache": "^12.0.3", - "chownr": "^1.1.2", + "cacache": "^12.0.0", "figgy-pudding": "^3.5.1", "get-stream": "^4.1.0", "glob": "^7.1.4", - "infer-owner": "^1.0.4", "lru-cache": "^5.1.1", "make-fetch-happen": "^5.0.0", "minimatch": "^3.0.4", @@ -1957,7 +1964,7 @@ "normalize-package-data": "^2.5.0", "npm-package-arg": "^6.1.0", "npm-packlist": "^1.4.4", - "npm-pick-manifest": "^3.0.0", + "npm-pick-manifest": "^2.2.3", "osenv": "^0.1.5", "promise-inflight": "^1.0.1", "promise-retry": "^1.1.1", @@ -1972,15 +1979,15 @@ }, "dependencies": { "bluebird": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", - "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", "dev": true }, "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", + "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", "dev": true, "requires": { "bluebird": "^3.5.5", @@ -2001,9 +2008,9 @@ } }, "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "get-stream": { @@ -2016,9 +2023,9 @@ } }, "glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2030,9 +2037,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "lru-cache": { @@ -2100,9 +2107,9 @@ } }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -2115,9 +2122,9 @@ "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true }, "ssri": { @@ -2130,30 +2137,18 @@ } }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", + "minipass": "^2.3.5", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } } }, "unique-filename": { @@ -2172,9 +2167,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true } } @@ -2232,12 +2227,6 @@ "integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==", "dev": true }, - "@icons/material": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", - "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", - "dev": true - }, "@jest/console": { "version": "24.7.1", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", @@ -2493,15 +2482,15 @@ } }, "@lerna/add": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.18.0.tgz", - "integrity": "sha512-Z5EaQbBnJn1LEPb0zb0Q2o9T8F8zOnlCsj6JYpY6aSke17UUT7xx0QMN98iBK+ueUHKjN/vdFdYlNCYRSIdujA==", + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.16.2.tgz", + "integrity": "sha512-RAAaF8aODPogj2Ge9Wj3uxPFIBGpog9M+HwSuq03ZnkkO831AmasCTJDqV+GEpl1U2DvnhZQEwHpWmTT0uUeEw==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", - "@lerna/bootstrap": "3.18.0", - "@lerna/command": "3.18.0", - "@lerna/filter-options": "3.18.0", + "@lerna/bootstrap": "3.16.2", + "@lerna/command": "3.16.0", + "@lerna/filter-options": "3.16.0", "@lerna/npm-conf": "3.16.0", "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", @@ -2524,23 +2513,34 @@ } } }, + "@lerna/batch-packages": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.16.0.tgz", + "integrity": "sha512-7AdMkANpubY/FKFI01im01tlx6ygOBJ/0JcixMUWoWP/7Ds3SWQF22ID6fbBr38jUWptYLDs2fagtTDL7YUPuA==", + "dev": true, + "requires": { + "@lerna/package-graph": "3.16.0", + "npmlog": "^4.1.2" + } + }, "@lerna/bootstrap": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.18.0.tgz", - "integrity": "sha512-3DZKWIaKvr7sUImoKqSz6eqn84SsOVMnA5QHwgzXiQjoeZ/5cg9x2r+Xj3+3w/lvLoh0j8U2GNtrIaPNis4bKQ==", + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.16.2.tgz", + "integrity": "sha512-I+gs7eh6rv9Vyd+CwqL7sftRfOOsSzCle8cv/CGlMN7/p7EAVhxEdAw8SYoHIKHzipXszuqqy1Y3opyleD0qdA==", "dev": true, "requires": { - "@lerna/command": "3.18.0", - "@lerna/filter-options": "3.18.0", - "@lerna/has-npm-version": "3.16.5", - "@lerna/npm-install": "3.16.5", - "@lerna/package-graph": "3.18.0", + "@lerna/batch-packages": "3.16.0", + "@lerna/command": "3.16.0", + "@lerna/filter-options": "3.16.0", + "@lerna/has-npm-version": "3.16.0", + "@lerna/npm-install": "3.16.0", + "@lerna/package-graph": "3.16.0", "@lerna/pulse-till-done": "3.13.0", - "@lerna/rimraf-dir": "3.16.5", + "@lerna/rimraf-dir": "3.14.2", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-topologically": "3.18.0", - "@lerna/symlink-binary": "3.17.0", - "@lerna/symlink-dependencies": "3.17.0", + "@lerna/run-parallel-batches": "3.16.0", + "@lerna/symlink-binary": "3.16.2", + "@lerna/symlink-dependencies": "3.16.2", "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", "get-port": "^4.2.0", @@ -2576,33 +2576,33 @@ } }, "@lerna/changed": { - "version": "3.18.2", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.18.2.tgz", - "integrity": "sha512-xVnFuj4A6Avxem+8R+KOuKDxfnxp1S5tM5nwsh7n3IhCN5Ga7YINV/JgPhrwgcpqPCVBvAowkilghT/I0r6wUw==", + "version": "3.16.4", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.16.4.tgz", + "integrity": "sha512-NCD7XkK744T23iW0wqKEgF4R9MYmReUbyHCZKopFnsNpQdqumc3SOIvQUAkKCP6hQJmYvxvOieoVgy/CVDpZ5g==", "dev": true, "requires": { - "@lerna/collect-updates": "3.18.0", - "@lerna/command": "3.18.0", - "@lerna/listable": "3.18.0", + "@lerna/collect-updates": "3.16.0", + "@lerna/command": "3.16.0", + "@lerna/listable": "3.16.0", "@lerna/output": "3.13.0", - "@lerna/version": "3.18.2" + "@lerna/version": "3.16.4" } }, "@lerna/check-working-tree": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.16.5.tgz", - "integrity": "sha512-xWjVBcuhvB8+UmCSb5tKVLB5OuzSpw96WEhS2uz6hkWVa/Euh1A0/HJwn2cemyK47wUrCQXtczBUiqnq9yX5VQ==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.14.2.tgz", + "integrity": "sha512-7safqxM/MYoAoxZxulUDtIJIbnBIgo0PB/FHytueG+9VaX7GMnDte2Bt1EKa0dz2sAyQdmQ3Q8ZXpf/6JDjaeg==", "dev": true, "requires": { - "@lerna/collect-uncommitted": "3.16.5", - "@lerna/describe-ref": "3.16.5", + "@lerna/collect-uncommitted": "3.14.2", + "@lerna/describe-ref": "3.14.2", "@lerna/validation-error": "3.13.0" } }, "@lerna/child-process": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.16.5.tgz", - "integrity": "sha512-vdcI7mzei9ERRV4oO8Y1LHBZ3A5+ampRKg1wq5nutLsUA4mEBN6H7JqjWOMY9xZemv6+kATm2ofjJ3lW5TszQg==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.14.2.tgz", + "integrity": "sha512-xnq+W5yQb6RkwI0p16ZQnrn6HkloH/MWTw4lGE1nKsBLAUbmSU5oTE93W1nrG0X3IMF/xWc9UYvNdUGMWvZZ4w==", "dev": true, "requires": { "chalk": "^2.3.1", @@ -2658,24 +2658,24 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, "@lerna/clean": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.18.0.tgz", - "integrity": "sha512-BiwBELZNkarRQqj+v5NPB1aIzsOX+Y5jkZ9a5UbwHzEdBUQ5lQa0qaMLSOve/fSkaiZQxe6qnTyatN75lOcDMg==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.16.0.tgz", + "integrity": "sha512-5P9U5Y19WmYZr7UAMGXBpY7xCRdlR7zhHy8MAPDKVx70rFIBS6nWXn5n7Kntv74g7Lm1gJ2rsiH5tj1OPcRJgg==", "dev": true, "requires": { - "@lerna/command": "3.18.0", - "@lerna/filter-options": "3.18.0", + "@lerna/command": "3.16.0", + "@lerna/filter-options": "3.16.0", "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", - "@lerna/rimraf-dir": "3.16.5", + "@lerna/rimraf-dir": "3.14.2", "p-map": "^2.1.0", "p-map-series": "^1.0.0", "p-waterfall": "^1.0.0" @@ -2690,214 +2690,23 @@ } }, "@lerna/cli": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.18.0.tgz", - "integrity": "sha512-AwDyfGx7fxJgeaZllEuyJ9LZ6Tdv9yqRD9RX762yCJu+PCAFvB9bp6OYuRSGli7QQgM0CuOYnSg4xVNOmuGKDA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.13.0.tgz", + "integrity": "sha512-HgFGlyCZbYaYrjOr3w/EsY18PdvtsTmDfpUQe8HwDjXlPeCCUgliZjXLOVBxSjiOvPeOSwvopwIHKWQmYbwywg==", "dev": true, "requires": { "@lerna/global-options": "3.13.0", "dedent": "^0.7.0", "npmlog": "^4.1.2", - "yargs": "^14.2.0" + "yargs": "^12.0.1" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yargs": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.0.tgz", - "integrity": "sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.0" - } - }, - "yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "@lerna/collect-uncommitted": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.16.5.tgz", - "integrity": "sha512-ZgqnGwpDZiWyzIQVZtQaj9tRizsL4dUOhuOStWgTAw1EMe47cvAY2kL709DzxFhjr6JpJSjXV5rZEAeU3VE0Hg==", - "dev": true, - "requires": { - "@lerna/child-process": "3.16.5", - "chalk": "^2.3.1", - "figgy-pudding": "^3.5.1", - "npmlog": "^4.1.2" - } - }, - "@lerna/collect-updates": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.18.0.tgz", - "integrity": "sha512-LJMKgWsE/var1RSvpKDIxS8eJ7POADEc0HM3FQiTpEczhP6aZfv9x3wlDjaHpZm9MxJyQilqxZcasRANmRcNgw==", - "dev": true, - "requires": { - "@lerna/child-process": "3.16.5", - "@lerna/describe-ref": "3.16.5", - "minimatch": "^3.0.4", - "npmlog": "^4.1.2", - "slash": "^2.0.0" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - } - } - }, - "@lerna/command": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.18.0.tgz", - "integrity": "sha512-JQ0TGzuZc9Ky8xtwtSLywuvmkU8X62NTUT3rMNrUykIkOxBaO+tE0O98u2yo/9BYOeTRji9IsjKZEl5i9Qt0xQ==", - "dev": true, - "requires": { - "@lerna/child-process": "3.16.5", - "@lerna/package-graph": "3.18.0", - "@lerna/project": "3.18.0", - "@lerna/validation-error": "3.13.0", - "@lerna/write-log-file": "3.13.0", - "dedent": "^0.7.0", - "execa": "^1.0.0", - "is-ci": "^2.0.0", - "lodash": "^4.17.14", - "npmlog": "^4.1.2" - }, - "dependencies": { "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2926,6 +2735,15 @@ "strip-eof": "^1.0.0" } }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -2935,6 +2753,89 @@ "pump": "^3.0.0" } }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -2946,9 +2847,160 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "@lerna/collect-uncommitted": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.14.2.tgz", + "integrity": "sha512-4EkQu4jIOdNL2BMzy/N0ydHB8+Z6syu6xiiKXOoFl0WoWU9H1jEJCX4TH7CmVxXL1+jcs8FIS2pfQz4oew99Eg==", + "dev": true, + "requires": { + "@lerna/child-process": "3.14.2", + "chalk": "^2.3.1", + "figgy-pudding": "^3.5.1", + "npmlog": "^4.1.2" + } + }, + "@lerna/collect-updates": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.16.0.tgz", + "integrity": "sha512-HwAIl815X2TNlmcp28zCrSdXfoZWNP7GJPEqNWYk7xDJTYLqQ+SrmKUePjb3AMGBwYAraZSEJLbHdBpJ5+cHmQ==", + "dev": true, + "requires": { + "@lerna/child-process": "3.14.2", + "@lerna/describe-ref": "3.14.2", + "minimatch": "^3.0.4", + "npmlog": "^4.1.2", + "slash": "^2.0.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, + "@lerna/command": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.16.0.tgz", + "integrity": "sha512-u7tE4GC4/gfbPA9eQg+0ulnoJ+PMoMqomx033r/IxqZrHtmJR9+pF/37S0fsxJ2hX/RMFPC7c9Q/i8NEufSpdQ==", + "dev": true, + "requires": { + "@lerna/child-process": "3.14.2", + "@lerna/package-graph": "3.16.0", + "@lerna/project": "3.16.0", + "@lerna/validation-error": "3.13.0", + "@lerna/write-log-file": "3.13.0", + "dedent": "^0.7.0", + "execa": "^1.0.0", + "is-ci": "^2.0.0", + "lodash": "^4.17.14", + "npmlog": "^4.1.2" + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } @@ -2993,9 +3045,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "pify": { @@ -3023,14 +3075,14 @@ } }, "@lerna/create": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.18.0.tgz", - "integrity": "sha512-y9oS7ND5T13c+cCTJHa2Y9in02ppzyjsNynVWFuS40eIzZ3z058d9+3qSBt1nkbbQlVyfLoP6+bZPsjyzap5ig==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.16.0.tgz", + "integrity": "sha512-OZApR1Iz7awutbmj4sAArwhqCyKgcrnw9rH0aWAUrkYWrD1w4TwkvAcYAsfx5GpQGbLQwoXhoyyPwPfZRRWz3Q==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", - "@lerna/child-process": "3.16.5", - "@lerna/command": "3.18.0", + "@lerna/child-process": "3.14.2", + "@lerna/command": "3.16.0", "@lerna/npm-conf": "3.16.0", "@lerna/validation-error": "3.13.0", "camelcase": "^5.0.0", @@ -3066,9 +3118,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "pify": { @@ -3090,9 +3142,9 @@ "dev": true }, "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -3125,45 +3177,45 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true } } }, "@lerna/describe-ref": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.16.5.tgz", - "integrity": "sha512-c01+4gUF0saOOtDBzbLMFOTJDHTKbDFNErEY6q6i9QaXuzy9LNN62z+Hw4acAAZuJQhrVWncVathcmkkjvSVGw==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.14.2.tgz", + "integrity": "sha512-qa5pzDRK2oBQXNjyRmRnN7E8a78NMYfQjjlRFB0KNHMsT6mCiL9+8kIS39sSE2NqT8p7xVNo2r2KAS8R/m3CoQ==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", + "@lerna/child-process": "3.14.2", "npmlog": "^4.1.2" } }, "@lerna/diff": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.18.0.tgz", - "integrity": "sha512-3iLNlpurc2nV9k22w8ini2Zjm2UPo3xtQgWyqdA6eJjvge0+5AlNAWfPoV6cV+Hc1xDbJD2YDSFpZPJ1ZGilRw==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.16.0.tgz", + "integrity": "sha512-QUpVs5TPl8vBIne10/vyjUxanQBQQp7Lk3iaB8MnCysKr0O+oy7trWeFVDPEkBTCD177By7yPGyW5Yey1nCBbA==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", - "@lerna/command": "3.18.0", + "@lerna/child-process": "3.14.2", + "@lerna/command": "3.16.0", "@lerna/validation-error": "3.13.0", "npmlog": "^4.1.2" } }, "@lerna/exec": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.18.0.tgz", - "integrity": "sha512-hwkuzg1+38+pbzdZPhGtLIYJ59z498/BCNzR8d4/nfMYm8lFbw9RgJJajLcdbuJ9LJ08cZ93hf8OlzetL84TYg==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.16.0.tgz", + "integrity": "sha512-mH3O5NXf/O88jBaBBTUf+d56CUkxpg782s3Jxy7HWbVuSUULt3iMRPTh+zEXO5/555etsIVVDDyUR76meklrJA==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", - "@lerna/command": "3.18.0", - "@lerna/filter-options": "3.18.0", - "@lerna/run-topologically": "3.18.0", + "@lerna/child-process": "3.14.2", + "@lerna/command": "3.16.0", + "@lerna/filter-options": "3.16.0", + "@lerna/run-topologically": "3.16.0", "@lerna/validation-error": "3.13.0", "p-map": "^2.1.0" }, @@ -3177,22 +3229,20 @@ } }, "@lerna/filter-options": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.18.0.tgz", - "integrity": "sha512-UGVcixs3TGzD8XSmFSbwUVVQnAjaZ6Rmt8Vuq2RcR98ULkGB1LiGNMY89XaNBhaaA8vx7yQWiLmJi2AfmD63Qg==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.16.0.tgz", + "integrity": "sha512-InIi1fF8+PxpCwir9bIy+pGxrdE6hvN0enIs1eNGCVS1TTE8osNgiZXa838bMQ1yaEccdcnVX6Z03BNKd56kNg==", "dev": true, "requires": { - "@lerna/collect-updates": "3.18.0", - "@lerna/filter-packages": "3.18.0", - "dedent": "^0.7.0", - "figgy-pudding": "^3.5.1", - "npmlog": "^4.1.2" + "@lerna/collect-updates": "3.16.0", + "@lerna/filter-packages": "3.16.0", + "dedent": "^0.7.0" } }, "@lerna/filter-packages": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.18.0.tgz", - "integrity": "sha512-6/0pMM04bCHNATIOkouuYmPg6KH3VkPCIgTfQmdkPJTullERyEQfNUKikrefjxo1vHOoCACDpy65JYyKiAbdwQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.16.0.tgz", + "integrity": "sha512-eGFzQTx0ogkGDCnbTuXqssryR6ilp8+dcXt6B+aq1MaqL/vOJRZyqMm4TY3CUOUnzZCi9S2WWyMw3PnAJOF+kg==", "dev": true, "requires": { "@lerna/validation-error": "3.13.0", @@ -3221,9 +3271,9 @@ }, "dependencies": { "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "fs-extra": { @@ -3238,21 +3288,11 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -3263,14 +3303,14 @@ } }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", + "minipass": "^2.3.5", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -3278,20 +3318,20 @@ } }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true } } }, "@lerna/github-client": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.16.5.tgz", - "integrity": "sha512-rHQdn8Dv/CJrO3VouOP66zAcJzrHsm+wFuZ4uGAai2At2NkgKH+tpNhQy2H1PSC0Ezj9LxvdaHYrUzULqVK5Hw==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.16.0.tgz", + "integrity": "sha512-IVJjcKjkYaUEPJsDyAblHGEFFNKCRyMagbIDm14L7Ab94ccN6i4TKOqAFEJn2SJHYvKKBdp3Zj2zNlASOMe3DA==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", + "@lerna/child-process": "3.14.2", "@octokit/plugin-enterprise-rest": "^3.6.1", "@octokit/rest": "^16.28.4", "git-url-parse": "^11.1.2", @@ -3299,9 +3339,9 @@ }, "dependencies": { "@octokit/request": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.2.1.tgz", - "integrity": "sha512-onjQo4QKyiMAqLM6j3eH8vWw1LEfNCpoZUl6a+TrZVJM1wysBC8F0GhK9K/Vc9UsScSmVs2bstOVD34xpQ2wqQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.0.2.tgz", + "integrity": "sha512-z1BQr43g4kOL4ZrIVBMHwi68Yg9VbkRUyuAgqCp1rU3vbYa69+2gIld/+gHclw15bJWQnhqqyEb7h5a5EqgZ0A==", "dev": true, "requires": { "@octokit/endpoint": "^5.1.0", @@ -3310,16 +3350,16 @@ "is-plain-object": "^3.0.0", "node-fetch": "^2.3.0", "once": "^1.4.0", - "universal-user-agent": "^4.0.0" + "universal-user-agent": "^3.0.0" } }, "@octokit/rest": { - "version": "16.33.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.33.1.tgz", - "integrity": "sha512-lOQ+fJZwkeJ/1PRTdnY1uNja01aKOMioRhQfZtei64gZMXIX3EAfF4koMQMvoLFwsnVBu3ifj1JW1WAAKdXcnA==", + "version": "16.28.7", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.7.tgz", + "integrity": "sha512-cznFSLEhh22XD3XeqJw51OLSfyL2fcFKUO+v2Ep9MTAFfFLS1cK1Zwd1yEgQJmJoDnj4/vv3+fGGZweG+xsbIA==", "dev": true, "requires": { - "@octokit/request": "^5.2.0", + "@octokit/request": "^5.0.0", "@octokit/request-error": "^1.0.2", "atob-lite": "^2.0.0", "before-after-hook": "^2.0.0", @@ -3330,7 +3370,8 @@ "lodash.uniq": "^4.5.0", "octokit-pagination-methods": "^1.1.0", "once": "^1.4.0", - "universal-user-agent": "^4.0.0" + "universal-user-agent": "^3.0.0", + "url-template": "^2.0.8" } }, "before-after-hook": { @@ -3361,12 +3402,12 @@ "dev": true }, "universal-user-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", - "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz", + "integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==", "dev": true, "requires": { - "os-name": "^3.1.0" + "os-name": "^3.0.0" } } } @@ -3389,9 +3430,9 @@ "dev": true }, "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -3408,12 +3449,12 @@ "dev": true }, "@lerna/has-npm-version": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.5.tgz", - "integrity": "sha512-WL7LycR9bkftyqbYop5rEGJ9sRFIV55tSGmbN1HLrF9idwOCD7CLrT64t235t3t4O5gehDnwKI5h2U3oxTrF8Q==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.0.tgz", + "integrity": "sha512-TIY036dA9J8OyTrZq9J+it2DVKifL65k7hK8HhkUPpitJkw6jwbMObA/8D40LOGgWNPweJWqmlrTbRSwsR7DrQ==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", + "@lerna/child-process": "3.14.2", "semver": "^6.2.0" }, "dependencies": { @@ -3426,13 +3467,13 @@ } }, "@lerna/import": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.18.0.tgz", - "integrity": "sha512-2pYIkkBTZsEdccfc+dPsKZeSw3tBzKSyl0b2lGrfmNX2Y41qqOzsJCyI1WO1uvEIP8aOaLy4hPpqRIBe4ee7hw==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.16.0.tgz", + "integrity": "sha512-trsOmGHzw0rL/f8BLNvd+9PjoTkXq2Dt4/V2UCha254hMQaYutbxcYu8iKPxz9x86jSPlH7FpbTkkHXDsoY7Yg==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", - "@lerna/command": "3.18.0", + "@lerna/child-process": "3.14.2", + "@lerna/command": "3.16.0", "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", "@lerna/validation-error": "3.13.0", @@ -3453,21 +3494,21 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true } } }, "@lerna/init": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.18.0.tgz", - "integrity": "sha512-/vHpmXkMlSaJaq25v5K13mcs/2L7E32O6dSsEkHaZCDRiV2BOqsZng9jjbE/4ynfsWfLLlU9ZcydwG72C3I+mQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.16.0.tgz", + "integrity": "sha512-Ybol/x5xMtBgokx4j7/Y3u0ZmNh0NiSWzBFVaOs2NOJKvuqrWimF67DKVz7yYtTYEjtaMdug64ohFF4jcT/iag==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", - "@lerna/command": "3.18.0", + "@lerna/child-process": "3.14.2", + "@lerna/command": "3.16.0", "fs-extra": "^8.1.0", "p-map": "^2.1.0", "write-json-file": "^3.2.0" @@ -3485,9 +3526,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "p-map": { @@ -3499,14 +3540,14 @@ } }, "@lerna/link": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.18.0.tgz", - "integrity": "sha512-FbbIpH0EpsC+dpAbvxCoF3cn7F1MAyJjEa5Lh3XkDGATOlinMFuKCbmX0NLpOPQZ5zghvrui97cx+jz5F2IlHw==", + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.16.2.tgz", + "integrity": "sha512-eCPg5Lo8HT525fIivNoYF3vWghO3UgEVFdbsiPmhzwI7IQyZro5HWYzLtywSAdEog5XZpd2Bbn0CsoHWBB3gww==", "dev": true, "requires": { - "@lerna/command": "3.18.0", - "@lerna/package-graph": "3.18.0", - "@lerna/symlink-dependencies": "3.17.0", + "@lerna/command": "3.16.0", + "@lerna/package-graph": "3.16.0", + "@lerna/symlink-dependencies": "3.16.2", "p-map": "^2.1.0", "slash": "^2.0.0" }, @@ -3526,24 +3567,24 @@ } }, "@lerna/list": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.18.0.tgz", - "integrity": "sha512-mpB7Q6T+n2CaiPFz0LuOE+rXphDfHm0mKIwShnyS/XDcii8jXv+z9Iytj8p3rfCH2I1L80j2qL6jWzyGy/uzKA==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.16.0.tgz", + "integrity": "sha512-TkvstoPsgKqqQ0KfRumpsdMXfRSEhdXqOLq519XyI5IRWYxhoqXqfi8gG37UoBPhBNoe64japn5OjphF3rOmQA==", "dev": true, "requires": { - "@lerna/command": "3.18.0", - "@lerna/filter-options": "3.18.0", - "@lerna/listable": "3.18.0", + "@lerna/command": "3.16.0", + "@lerna/filter-options": "3.16.0", + "@lerna/listable": "3.16.0", "@lerna/output": "3.13.0" } }, "@lerna/listable": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.18.0.tgz", - "integrity": "sha512-9gLGKYNLSKeurD+sJ2RA+nz4Ftulr91U127gefz0RlmAPpYSjwcJkxwa0UfJvpQTXv9C7yzHLnn0BjyAQRjuew==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.16.0.tgz", + "integrity": "sha512-mtdAT2EEECqrJSDm/aXlOUFr1MRE4p6hppzY//Klp05CogQy6uGaKk+iKG5yyCLaOXFFZvG4HfO11CmoGSDWzw==", "dev": true, "requires": { - "@lerna/query-graph": "3.18.0", + "@lerna/query-graph": "3.16.0", "chalk": "^2.3.1", "columnify": "^1.5.4" } @@ -3579,9 +3620,9 @@ } }, "@lerna/npm-dist-tag": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.18.1.tgz", - "integrity": "sha512-vWkZh2T/O9OjPLDrba0BTWO7ug/C3sCwjw7Qyk1aEbxMBXB/eEJPqirwJTWT+EtRJQYB01ky3K8ZFOhElVyjLw==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.16.0.tgz", + "integrity": "sha512-MQrBkqJJB9+eNphuj9w90QPMOs4NQXMuSRk9NqzeFunOmdDopPCV0Q7IThSxEuWnhJ2n3B7G0vWUP7tNMPdqIQ==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3592,12 +3633,12 @@ } }, "@lerna/npm-install": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.5.tgz", - "integrity": "sha512-hfiKk8Eku6rB9uApqsalHHTHY+mOrrHeWEs+gtg7+meQZMTS3kzv4oVp5cBZigndQr3knTLjwthT/FX4KvseFg==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.0.tgz", + "integrity": "sha512-APUOIilZCzDzce92uLEwzt1r7AEMKT/hWA1ThGJL+PO9Rn8A95Km3o2XZAYG4W0hR+P4O2nSVuKbsjQtz8CjFQ==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", + "@lerna/child-process": "3.14.2", "@lerna/get-npm-exec-opts": "3.13.0", "fs-extra": "^8.1.0", "npm-package-arg": "^6.1.0", @@ -3618,9 +3659,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true } } @@ -3654,9 +3695,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "pify": { @@ -3668,12 +3709,12 @@ } }, "@lerna/npm-run-script": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.16.5.tgz", - "integrity": "sha512-1asRi+LjmVn3pMjEdpqKJZFT/3ZNpb+VVeJMwrJaV/3DivdNg7XlPK9LTrORuKU4PSvhdEZvJmSlxCKyDpiXsQ==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.14.2.tgz", + "integrity": "sha512-LbVFv+nvAoRTYLMrJlJ8RiakHXrLslL7Jp/m1R18vYrB8LYWA3ey+nz5Tel2OELzmjUiemAKZsD9h6i+Re5egg==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", + "@lerna/child-process": "3.14.2", "@lerna/get-npm-exec-opts": "3.13.0", "npmlog": "^4.1.2" } @@ -3714,30 +3755,20 @@ }, "dependencies": { "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", + "minipass": "^2.3.5", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -3745,9 +3776,9 @@ } }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true } } @@ -3764,9 +3795,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "load-json-file": { @@ -3807,9 +3838,9 @@ } }, "@lerna/package-graph": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.18.0.tgz", - "integrity": "sha512-BLYDHO5ihPh20i3zoXfLZ5ZWDCrPuGANgVhl7k5pCmRj90LCvT+C7V3zrw70fErGAfvkcYepMqxD+oBrAYwquQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.16.0.tgz", + "integrity": "sha512-A2mum/gNbv7zCtAwJqoxzqv89As73OQNK2MgSX1SHWya46qoxO9a9Z2c5lOFQ8UFN5ZxqWMfFYXRCz7qzwmFXw==", "dev": true, "requires": { "@lerna/prerelease-id-from-version": "3.16.0", @@ -3845,9 +3876,9 @@ } }, "@lerna/project": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.18.0.tgz", - "integrity": "sha512-+LDwvdAp0BurOAWmeHE3uuticsq9hNxBI0+FMHiIai8jrygpJGahaQrBYWpwbshbQyVLeQgx3+YJdW2TbEdFWA==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.16.0.tgz", + "integrity": "sha512-NrKcKK1EqXqhrGvslz6Q36+ZHuK3zlDhGdghRqnxDcHxMPT01NgLcmsnymmQ+gjMljuLRmvKYYCuHrknzX8VrA==", "dev": true, "requires": { "@lerna/package": "3.16.0", @@ -3877,18 +3908,18 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "import-fresh": { @@ -3978,22 +4009,22 @@ } }, "@lerna/publish": { - "version": "3.18.2", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.18.2.tgz", - "integrity": "sha512-lLQOjoaFv/gc9HtOCMRsOK6NIub8eHnnvmQARjXY/HayA8GuLaD2Px9xOu1L7il+Q0LlMU3wASB9Khy/CiHJUQ==", + "version": "3.16.4", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.16.4.tgz", + "integrity": "sha512-XZY+gRuF7/v6PDQwl7lvZaGWs8CnX6WIPIu+OCcyFPSL/rdWegdN7HieKBHskgX798qRQc2GrveaY7bNoTKXAw==", "dev": true, "requires": { "@evocateur/libnpmaccess": "^3.1.2", "@evocateur/npm-registry-fetch": "^4.0.0", "@evocateur/pacote": "^9.6.3", - "@lerna/check-working-tree": "3.16.5", - "@lerna/child-process": "3.16.5", - "@lerna/collect-updates": "3.18.0", - "@lerna/command": "3.18.0", - "@lerna/describe-ref": "3.16.5", + "@lerna/check-working-tree": "3.14.2", + "@lerna/child-process": "3.14.2", + "@lerna/collect-updates": "3.16.0", + "@lerna/command": "3.16.0", + "@lerna/describe-ref": "3.14.2", "@lerna/log-packed": "3.16.0", "@lerna/npm-conf": "3.16.0", - "@lerna/npm-dist-tag": "3.18.1", + "@lerna/npm-dist-tag": "3.16.0", "@lerna/npm-publish": "3.16.2", "@lerna/otplease": "3.16.0", "@lerna/output": "3.13.0", @@ -4002,9 +4033,9 @@ "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-topologically": "3.18.0", + "@lerna/run-topologically": "3.16.0", "@lerna/validation-error": "3.13.0", - "@lerna/version": "3.18.2", + "@lerna/version": "3.16.4", "figgy-pudding": "^3.5.1", "fs-extra": "^8.1.0", "npm-package-arg": "^6.1.0", @@ -4027,9 +4058,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "p-map": { @@ -4056,12 +4087,12 @@ } }, "@lerna/query-graph": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.18.0.tgz", - "integrity": "sha512-fgUhLx6V0jDuKZaKj562jkuuhrfVcjl5sscdfttJ8dXNVADfDz76nzzwLY0ZU7/0m69jDedohn5Fx5p7hDEVEg==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.16.0.tgz", + "integrity": "sha512-p0RO+xmHDO95ChJdWkcy9TNLysLkoDARXeRHzY5U54VCwl3Ot/2q8fMCVlA5UeGXDutEyyByl3URqEpcQCWI7Q==", "dev": true, "requires": { - "@lerna/package-graph": "3.18.0", + "@lerna/package-graph": "3.16.0", "figgy-pudding": "^3.5.1" } }, @@ -4088,36 +4119,36 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true } } }, "@lerna/rimraf-dir": { - "version": "3.16.5", - "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.16.5.tgz", - "integrity": "sha512-bQlKmO0pXUsXoF8lOLknhyQjOZsCc0bosQDoX4lujBXSWxHVTg1VxURtWf2lUjz/ACsJVDfvHZbDm8kyBk5okA==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.14.2.tgz", + "integrity": "sha512-eFNkZsy44Bu9v1Hrj5Zk6omzg8O9h/7W6QYK1TTUHeyrjTEwytaNQlqF0lrTLmEvq55sviV42NC/8P3M2cvq8Q==", "dev": true, "requires": { - "@lerna/child-process": "3.16.5", + "@lerna/child-process": "3.14.2", "npmlog": "^4.1.2", "path-exists": "^3.0.0", "rimraf": "^2.6.2" } }, "@lerna/run": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.18.0.tgz", - "integrity": "sha512-sblxHBZ9djaaG7wefPcfEicDqzrB7CP1m/jIB0JvPEQwG4C2qp++ewBpkjRw/mBtjtzg0t7v0nNMXzaWYrQckQ==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.16.0.tgz", + "integrity": "sha512-woTeLlB1OAAz4zzjdI6RyIxSGuxiUPHJZm89E1pDEPoWwtQV6HMdMgrsQd9ATsJ5Ez280HH4bF/LStAlqW8Ufg==", "dev": true, "requires": { - "@lerna/command": "3.18.0", - "@lerna/filter-options": "3.18.0", - "@lerna/npm-run-script": "3.16.5", + "@lerna/command": "3.16.0", + "@lerna/filter-options": "3.16.0", + "@lerna/npm-run-script": "3.14.2", "@lerna/output": "3.13.0", - "@lerna/run-topologically": "3.18.0", + "@lerna/run-topologically": "3.16.0", "@lerna/timer": "3.13.0", "@lerna/validation-error": "3.13.0", "p-map": "^2.1.0" @@ -4143,21 +4174,39 @@ "npmlog": "^4.1.2" } }, + "@lerna/run-parallel-batches": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/run-parallel-batches/-/run-parallel-batches-3.16.0.tgz", + "integrity": "sha512-2J/Nyv+MvogmQEfC7VcS21ifk7w0HVvzo2yOZRPvkCzGRu/rducxtB4RTcr58XCZ8h/Bt1aqQYKExu3c/3GXwg==", + "dev": true, + "requires": { + "p-map": "^2.1.0", + "p-map-series": "^1.0.0" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } + } + }, "@lerna/run-topologically": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.18.0.tgz", - "integrity": "sha512-lrfEewwuUMC3ioxf9Z9NdHUakN6ihekcPfdYbzR2slmdbjYKmIA5srkWdrK8NwOpQCAuekpOovH2s8X3FGEopg==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.16.0.tgz", + "integrity": "sha512-4Hlpv4zDtKWa5Z0tPkeu0sK+bxZEKgkNESMGmWrUCNfj7xwvAJurcraK8+a2Y0TFYwf0qjSLY/MzX+ZbJA3Cgw==", "dev": true, "requires": { - "@lerna/query-graph": "3.18.0", + "@lerna/query-graph": "3.16.0", "figgy-pudding": "^3.5.1", "p-queue": "^4.0.0" } }, "@lerna/symlink-binary": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.17.0.tgz", - "integrity": "sha512-RLpy9UY6+3nT5J+5jkM5MZyMmjNHxZIZvXLV+Q3MXrf7Eaa1hNqyynyj4RO95fxbS+EZc4XVSk25DGFQbcRNSQ==", + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.16.2.tgz", + "integrity": "sha512-kz9XVoFOGSF83gg4gBqH+mG6uxfJfTp8Uy+Cam40CvMiuzfODrGkjuBEFoM/uO2QOAwZvbQDYOBpKUa9ZxHS1Q==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", @@ -4178,9 +4227,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "p-map": { @@ -4192,14 +4241,14 @@ } }, "@lerna/symlink-dependencies": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.17.0.tgz", - "integrity": "sha512-KmjU5YT1bpt6coOmdFueTJ7DFJL4H1w5eF8yAQ2zsGNTtZ+i5SGFBWpb9AQaw168dydc3s4eu0W0Sirda+F59Q==", + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.16.2.tgz", + "integrity": "sha512-wnZqGJQ+Jvr1I3inxrkffrFZfmQI7Ta8gySw/UWCy95QtZWF/f5yk8zVIocCAsjzD0wgb3jJE3CFJ9W5iwWk1A==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", "@lerna/resolve-symlink": "3.16.0", - "@lerna/symlink-binary": "3.17.0", + "@lerna/symlink-binary": "3.16.2", "fs-extra": "^8.1.0", "p-finally": "^1.0.0", "p-map": "^2.1.0", @@ -4218,9 +4267,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "p-map": { @@ -4247,27 +4296,26 @@ } }, "@lerna/version": { - "version": "3.18.2", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.18.2.tgz", - "integrity": "sha512-nmCJpw3A2DoNGbjmvI5UB3ZwTQUayI8M/b3rOA6ZzYeGmoQmm2QBKun05aBRasqTuUo4XjSuas5CqHN+x4f8Ww==", + "version": "3.16.4", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.16.4.tgz", + "integrity": "sha512-ikhbMeIn5ljCtWTlHDzO4YvTmpGTX1lWFFIZ79Vd1TNyOr+OUuKLo/+p06mCl2WEdZu0W2s5E9oxfAAQbyDxEg==", "dev": true, "requires": { - "@lerna/check-working-tree": "3.16.5", - "@lerna/child-process": "3.16.5", - "@lerna/collect-updates": "3.18.0", - "@lerna/command": "3.18.0", + "@lerna/check-working-tree": "3.14.2", + "@lerna/child-process": "3.14.2", + "@lerna/collect-updates": "3.16.0", + "@lerna/command": "3.16.0", "@lerna/conventional-commits": "3.16.4", - "@lerna/github-client": "3.16.5", + "@lerna/github-client": "3.16.0", "@lerna/gitlab-client": "3.15.0", "@lerna/output": "3.13.0", "@lerna/prerelease-id-from-version": "3.16.0", "@lerna/prompt": "3.13.0", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-topologically": "3.18.0", + "@lerna/run-topologically": "3.16.0", "@lerna/validation-error": "3.13.0", "chalk": "^2.3.1", "dedent": "^0.7.0", - "load-json-file": "^5.3.0", "minimatch": "^3.0.4", "npmlog": "^4.1.2", "p-map": "^2.1.0", @@ -4276,51 +4324,15 @@ "p-waterfall": "^1.0.0", "semver": "^6.2.0", "slash": "^2.0.0", - "temp-write": "^3.4.0", - "write-json-file": "^3.2.0" + "temp-write": "^3.4.0" }, "dependencies": { - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", - "dev": true - }, - "load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" - } - }, "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -4332,12 +4344,6 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true } } }, @@ -4448,12 +4454,12 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "dev": true, "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -4471,9 +4477,9 @@ } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", "dev": true }, "@babel/template": { @@ -4488,26 +4494,26 @@ } }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/parser": "^7.6.2", + "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -4897,9 +4903,9 @@ } }, "@parcel/logger": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.1.tgz", - "integrity": "sha512-9NF3M6UVeP2udOBDILuoEHd8VrF4vQqoWHEafymO1pfSoOMfxrSJZw1MfyAAIUN/IFp9qjcpDCUbDZB+ioVevA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.0.tgz", + "integrity": "sha512-lIRfDg+junbFUUeU0QtHX00gKCgEsYHZydFKwrJ8dc0D+WE2SYT1FcVCgpPAfKYgtg0QQMns8E9vzT9UjH92PQ==", "dev": true, "requires": { "@parcel/workers": "^1.11.0", @@ -4938,13 +4944,13 @@ "dev": true }, "@parcel/watcher": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.1.tgz", - "integrity": "sha512-od+uCtCxC/KoNQAIE1vWx1YTyKYY+7CTrxBJPRh3cDWw/C0tCtlBMVlrbplscGoEpt6B27KhJDCv82PBxOERNA==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.0.tgz", + "integrity": "sha512-yijGiAqG7Tjf5WnFwOkiNWwerfZQDNABldiiqRDtr7vDWLO+F/DIncyB7tTcaD5Loevrr5mzzGo8Ntf3d2GIPg==", "dev": true, "requires": { "@parcel/utils": "^1.11.0", - "chokidar": "^2.1.5" + "chokidar": "^2.0.3" } }, "@parcel/workers": { @@ -5119,17 +5125,17 @@ } }, "@storybook/addon-a11y": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-5.2.4.tgz", - "integrity": "sha512-m7D78LiREpUzw7U+jiJXQXSsYoYZ+IkewBIxX5K15lh58AqTi0hD8DWHssgbi76GQwdaXKmMPIwI842dgPYobQ==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-5.2.3.tgz", + "integrity": "sha512-1N8hes5J3qyhCahHyFUXwiKif3JH892dzGalxc46jtvC0oCMM0r6lu+lj9J6THc15Oc8Icy9KJZuw4R0wRJl0Q==", "dev": true, "requires": { - "@storybook/addons": "5.2.4", - "@storybook/api": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/components": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/theming": "5.2.4", + "@storybook/addons": "5.2.3", + "@storybook/api": "5.2.3", + "@storybook/client-logger": "5.2.3", + "@storybook/components": "5.2.3", + "@storybook/core-events": "5.2.3", + "@storybook/theming": "5.2.3", "axe-core": "^3.3.2", "common-tags": "^1.8.0", "core-js": "^3.0.1", @@ -5171,9 +5177,9 @@ } }, "@storybook/addon-docs": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-5.2.4.tgz", - "integrity": "sha512-rfzoQUseb3G1WanQckjH85OXJJXMigod/YEEqJv68vo7GVY5PdVkOISy9nSldjrnwH6ikT3pcfJKPuHWRKAx/A==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-5.2.3.tgz", + "integrity": "sha512-xMg/LCUfVX1SNplaPbsNt9L78/QbxkR7pPpQuLjCvTAvzKkLNWNs8SlwM14ds/SfUNQ9EaCoAd1OQIdZrzrBRg==", "dev": true, "requires": { "@babel/generator": "^7.4.0", @@ -5182,12 +5188,12 @@ "@mdx-js/loader": "^1.1.0", "@mdx-js/mdx": "^1.1.0", "@mdx-js/react": "^1.0.27", - "@storybook/addons": "5.2.4", - "@storybook/api": "5.2.4", - "@storybook/components": "5.2.4", - "@storybook/router": "5.2.4", - "@storybook/source-loader": "5.2.4", - "@storybook/theming": "5.2.4", + "@storybook/addons": "5.2.3", + "@storybook/api": "5.2.3", + "@storybook/components": "5.2.3", + "@storybook/router": "5.2.3", + "@storybook/source-loader": "5.2.3", + "@storybook/theming": "5.2.3", "core-js": "^3.0.1", "global": "^4.3.2", "js-string-escape": "^1.0.1", @@ -5195,404 +5201,173 @@ "prop-types": "^15.7.2" } }, - "@storybook/addon-knobs": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-knobs/-/addon-knobs-5.2.4.tgz", - "integrity": "sha512-VYxbDARJs5RwTEOlcfa98tkDXLcRocB7QXLqt8wwCdXPIqkuoVeQLROXGYJm2NzSn49RyHPKUuVWnRhy34qBbQ==", + "@storybook/addon-storysource": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.2.3.tgz", + "integrity": "sha512-7t/oqRzD2QrGiqnUxU++jqgA8OVYByCFzeRHYcpoz84sd2vSy+110Me1OHj2ZHh1t+QOn8D0DJewe0QrycR56w==", "dev": true, "requires": { - "@storybook/addons": "5.2.4", - "@storybook/api": "5.2.4", - "@storybook/client-api": "5.2.4", - "@storybook/components": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/theming": "5.2.4", - "@types/react-color": "^3.0.1", - "copy-to-clipboard": "^3.0.8", + "@storybook/addons": "5.2.3", + "@storybook/components": "5.2.3", + "@storybook/router": "5.2.3", + "@storybook/source-loader": "5.2.3", + "@storybook/theming": "5.2.3", "core-js": "^3.0.1", - "escape-html": "^1.0.3", - "fast-deep-equal": "^2.0.1", - "global": "^4.3.2", - "lodash": "^4.17.11", + "estraverse": "^4.2.0", + "loader-utils": "^1.2.3", + "prettier": "^1.16.4", "prop-types": "^15.7.2", - "qs": "^6.6.0", - "react-color": "^2.17.0", - "react-lifecycles-compat": "^3.0.4", - "react-select": "^3.0.0" + "react-syntax-highlighter": "^8.0.1", + "regenerator-runtime": "^0.12.1", + "util-deprecate": "^1.0.2" }, "dependencies": { - "@storybook/addons": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.4.tgz", - "integrity": "sha512-Q+bnVlBA308qnELxnh18hBDRSUgltR9KbV537285dUL/okv/NC6n51mxJwIaG+ksBW2wU+5e6tqSayaKF3uHLw==", - "dev": true, - "requires": { - "@storybook/api": "5.2.4", - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/core-events": "5.2.4", - "core-js": "^3.0.1", - "global": "^4.3.2", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/api": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.4.tgz", - "integrity": "sha512-KqAB+NkHIHdwu749NDP+7i44jy1bFgpq7GTJlG+sx/XLZHQveK/8yn109g9bXHFth7SvdXI1+9GA/apzwBU/Mw==", - "dev": true, - "requires": { - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/router": "5.2.4", - "@storybook/theming": "5.2.4", - "core-js": "^3.0.1", - "fast-deep-equal": "^2.0.1", - "global": "^4.3.2", - "lodash": "^4.17.11", - "memoizerific": "^1.11.3", - "prop-types": "^15.6.2", - "react": "^16.8.3", - "semver": "^6.0.0", - "shallow-equal": "^1.1.0", - "store2": "^2.7.1", - "telejson": "^3.0.2", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/channel-postmessage": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.4.tgz", - "integrity": "sha512-ic7/Ho8z2/aOMjoEbr5p8rijOfO3SZdJnwMvDdUxrqvYq7yACZWidPo3w2+iBwQi9HLqEsWesP1c2doJBxVGRw==", - "dev": true, - "requires": { - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "core-js": "^3.0.1", - "global": "^4.3.2", - "telejson": "^3.0.2" - } - }, - "@storybook/channels": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.4.tgz", - "integrity": "sha512-/r39yEZ5QiGdiq95DhXBypdBo7urkD3Sp1WDyK48uGkZ0gdHWSPy3BBy8OJhEhfNz7nVisTiVIBr4gIrubKDjw==", - "dev": true, - "requires": { - "core-js": "^3.0.1" - } - }, - "@storybook/client-api": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.4.tgz", - "integrity": "sha512-SOwzEFHoNapURhNqdcI7HA76o5tkWvs2+2s++i/S7xsAd3KyefIVDOdqSMlAxJkxZb8Mlrb3UNRxlrpA8SZqNA==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.4", - "@storybook/channel-postmessage": "5.2.4", - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/router": "5.2.4", - "common-tags": "^1.8.0", - "core-js": "^3.0.1", - "eventemitter3": "^4.0.0", - "global": "^4.3.2", - "is-plain-object": "^3.0.0", - "lodash": "^4.17.11", - "memoizerific": "^1.11.3", - "qs": "^6.6.0", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/client-logger": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.4.tgz", - "integrity": "sha512-ofp6QQPQZBU+RvlAH5KpZRsfAFHecCZDnl/7YG6FwjHseJr3jHTYmBGGjJDMHFHq+Q7FGQu/yVb9lMFgoQ43QQ==", - "dev": true, - "requires": { - "core-js": "^3.0.1" - } - }, - "@storybook/components": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.4.tgz", - "integrity": "sha512-APhw+XGag0RTCRJ8eCWKVr8dLt9SRqnS8LtzcZJbokCYRxRTFzhmX2eVEE1v+d0gHib1/yh2COxOjMzv3m/rQA==", - "dev": true, - "requires": { - "@storybook/client-logger": "5.2.4", - "@storybook/theming": "5.2.4", - "@types/react-syntax-highlighter": "10.1.0", - "core-js": "^3.0.1", - "global": "^4.3.2", - "markdown-to-jsx": "^6.9.1", - "memoizerific": "^1.11.3", - "polished": "^3.3.1", - "popper.js": "^1.14.7", - "prop-types": "^15.7.2", - "react": "^16.8.3", - "react-dom": "^16.8.3", - "react-focus-lock": "^1.18.3", - "react-helmet-async": "^1.0.2", - "react-popper-tooltip": "^2.8.3", - "react-syntax-highlighter": "^8.0.1", - "react-textarea-autosize": "^7.1.0", - "simplebar-react": "^1.0.0-alpha.6" - } + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true }, - "@storybook/core-events": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.4.tgz", - "integrity": "sha512-nQknCmaz2S2HW6PSGcuFzve7Y1Js2Cb268vUG0ZMNtJZwFawqYc+KSQHqmOY0pVm8dyROTcWCudPA0k+hk6N5Q==", + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "core-js": "^3.0.1" + "minimist": "^1.2.0" } }, - "@storybook/router": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.4.tgz", - "integrity": "sha512-GL7eGdj5oYST0mE9fThJB9ye9tTTgrP+aP3okZ6MeMGtNytb7bmJRpAD2E4ouuPTQVppyHI5re8g/HUxUNOT1g==", + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "@reach/router": "^1.2.1", - "@types/reach__router": "^1.2.3", - "core-js": "^3.0.1", - "global": "^4.3.2", - "lodash": "^4.17.11", - "memoizerific": "^1.11.3", - "qs": "^6.6.0" - } - }, - "@storybook/theming": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.4.tgz", - "integrity": "sha512-2ZlqBrmnm8N0352Fnu2+GB3pEsHL4Eb2eKxV0VLLgkjJuAlm7CK6+I/e4ZknQWxwYm2pQj1y6ta68A62fGBYyA==", - "dev": true, - "requires": { - "@emotion/core": "^10.0.14", - "@emotion/styled": "^10.0.14", - "@storybook/client-logger": "5.2.4", - "common-tags": "^1.8.0", - "core-js": "^3.0.1", - "deep-object-diff": "^1.1.0", - "emotion-theming": "^10.0.14", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "polished": "^3.3.1", - "prop-types": "^15.7.2", - "resolve-from": "^5.0.0" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, - "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", - "dev": true - }, - "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", - "dev": true - }, - "qs": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz", - "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==", - "dev": true - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "shallow-equal": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.0.tgz", - "integrity": "sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==", - "dev": true - } - } - }, - "@storybook/addon-storysource": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.2.4.tgz", - "integrity": "sha512-zOJO4zt+Fj08GgegClDA6rU+VFyBb+mepfL5eJAqLtV6gSsprwZ1JNFVkyqhfrcr+vIhgRRWfuz/DDGmI+6bTQ==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.4", - "@storybook/components": "5.2.4", - "@storybook/router": "5.2.4", - "@storybook/source-loader": "5.2.4", - "@storybook/theming": "5.2.4", - "core-js": "^3.0.1", - "estraverse": "^4.2.0", - "loader-utils": "^1.2.3", - "prettier": "^1.16.4", - "prop-types": "^15.7.2", - "react-syntax-highlighter": "^8.0.1", - "regenerator-runtime": "^0.12.1", - "util-deprecate": "^1.0.2" - }, - "dependencies": { - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", - "dev": true - } - } - }, - "@storybook/addon-viewport": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-5.2.4.tgz", - "integrity": "sha512-R49wSaiouSVBYeus5Xibv+XXX9Nc3/rZ1NB5yIgj658aDeuB8WgkHbM3dKd/GrWeVZWv3o4CjW81ernd3f8sdw==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.4", - "@storybook/api": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/components": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/theming": "5.2.4", - "core-js": "^3.0.1", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "prop-types": "^15.7.2", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/addons": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.4.tgz", - "integrity": "sha512-Q+bnVlBA308qnELxnh18hBDRSUgltR9KbV537285dUL/okv/NC6n51mxJwIaG+ksBW2wU+5e6tqSayaKF3uHLw==", - "dev": true, - "requires": { - "@storybook/api": "5.2.4", - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/core-events": "5.2.4", - "core-js": "^3.0.1", - "global": "^4.3.2", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/api": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.4.tgz", - "integrity": "sha512-KqAB+NkHIHdwu749NDP+7i44jy1bFgpq7GTJlG+sx/XLZHQveK/8yn109g9bXHFth7SvdXI1+9GA/apzwBU/Mw==", - "dev": true, - "requires": { - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/router": "5.2.4", - "@storybook/theming": "5.2.4", - "core-js": "^3.0.1", - "fast-deep-equal": "^2.0.1", - "global": "^4.3.2", - "lodash": "^4.17.11", - "memoizerific": "^1.11.3", - "prop-types": "^15.6.2", - "react": "^16.8.3", - "semver": "^6.0.0", - "shallow-equal": "^1.1.0", - "store2": "^2.7.1", - "telejson": "^3.0.2", - "util-deprecate": "^1.0.2" - }, - "dependencies": { - "shallow-equal": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.0.tgz", - "integrity": "sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==", - "dev": true - } - } - }, - "@storybook/channel-postmessage": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.4.tgz", - "integrity": "sha512-ic7/Ho8z2/aOMjoEbr5p8rijOfO3SZdJnwMvDdUxrqvYq7yACZWidPo3w2+iBwQi9HLqEsWesP1c2doJBxVGRw==", - "dev": true, - "requires": { - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "core-js": "^3.0.1", - "global": "^4.3.2", - "telejson": "^3.0.2" - } - }, - "@storybook/channels": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.4.tgz", - "integrity": "sha512-/r39yEZ5QiGdiq95DhXBypdBo7urkD3Sp1WDyK48uGkZ0gdHWSPy3BBy8OJhEhfNz7nVisTiVIBr4gIrubKDjw==", - "dev": true, - "requires": { - "core-js": "^3.0.1" - } - }, - "@storybook/client-api": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.4.tgz", - "integrity": "sha512-SOwzEFHoNapURhNqdcI7HA76o5tkWvs2+2s++i/S7xsAd3KyefIVDOdqSMlAxJkxZb8Mlrb3UNRxlrpA8SZqNA==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.4", - "@storybook/channel-postmessage": "5.2.4", - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/router": "5.2.4", - "common-tags": "^1.8.0", - "core-js": "^3.0.1", - "eventemitter3": "^4.0.0", - "global": "^4.3.2", - "is-plain-object": "^3.0.0", - "lodash": "^4.17.11", - "memoizerific": "^1.11.3", - "qs": "^6.6.0", - "util-deprecate": "^1.0.2" - }, - "dependencies": { + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "dev": true + } + } + }, + "@storybook/addon-viewport": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-5.2.3.tgz", + "integrity": "sha512-YN0rQ6GrgDTAQv0KVhSJ/ZBQfEUerOTMsAt9MH9fCIgIfXmXc8BoqkL3DYhAhEPEKpzQkV+NwZyZcLCntXPdQg==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.3", + "@storybook/api": "5.2.3", + "@storybook/client-logger": "5.2.3", + "@storybook/components": "5.2.3", + "@storybook/core-events": "5.2.3", + "@storybook/theming": "5.2.3", + "core-js": "^3.0.1", + "global": "^4.3.2", + "memoizerific": "^1.11.3", + "prop-types": "^15.7.2", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/addons": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.3.tgz", + "integrity": "sha512-LTkUJB8ZDc4++yt9acNHNjlnGWCyNtP+NVYPDvg7zFOaMip21Pj4T0pg9UwYxdqrFBWz9tVz7DJeXroS3egXxg==", + "dev": true, + "requires": { + "@storybook/api": "5.2.3", + "@storybook/channels": "5.2.3", + "@storybook/client-logger": "5.2.3", + "@storybook/core-events": "5.2.3", + "core-js": "^3.0.1", + "global": "^4.3.2", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/api": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.3.tgz", + "integrity": "sha512-2csxa/d64rXy4Dwoc7YjbPeNUJRgcI/wJUo30CLujk2stEFzDnKeMPR1mlHMCIFDW+KDxJ28bW59VPxwrqJFjw==", + "dev": true, + "requires": { + "@storybook/channels": "5.2.3", + "@storybook/client-logger": "5.2.3", + "@storybook/core-events": "5.2.3", + "@storybook/router": "5.2.3", + "@storybook/theming": "5.2.3", + "core-js": "^3.0.1", + "fast-deep-equal": "^2.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "prop-types": "^15.6.2", + "react": "^16.8.3", + "semver": "^6.0.0", + "shallow-equal": "^1.1.0", + "store2": "^2.7.1", + "telejson": "^3.0.2", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "shallow-equal": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.0.tgz", + "integrity": "sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==", + "dev": true + } + } + }, + "@storybook/channel-postmessage": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.3.tgz", + "integrity": "sha512-ixlpr6aAYoRM72cKwEWU/W0rWzOn3mYqb/eUdIaz3Da5BtFGKm3yEFguII0l1my82uhMm5/d3UNfoh0rO3pUyg==", + "dev": true, + "requires": { + "@storybook/channels": "5.2.3", + "@storybook/client-logger": "5.2.3", + "core-js": "^3.0.1", + "global": "^4.3.2", + "telejson": "^3.0.2" + } + }, + "@storybook/channels": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.3.tgz", + "integrity": "sha512-13Mlb+XbE0mHXiLLHdg0w9byhRy/bE605U7U96PGQp2cwX4lf+4jpViO2mDCsndAFRc0+2hexXPTkwgzvZzq0A==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/client-api": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.3.tgz", + "integrity": "sha512-anXxcf2z+KQAk94xxdbeG1N6nTEWXj087XHQ22L3pOoX9TRzfG71UjL0/S7vj4EFUiXVHj8d6YUFwLb5LwpUIw==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.3", + "@storybook/channel-postmessage": "5.2.3", + "@storybook/channels": "5.2.3", + "@storybook/client-logger": "5.2.3", + "@storybook/core-events": "5.2.3", + "@storybook/router": "5.2.3", + "common-tags": "^1.8.0", + "core-js": "^3.0.1", + "eventemitter3": "^4.0.0", + "global": "^4.3.2", + "is-plain-object": "^3.0.0", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "util-deprecate": "^1.0.2" + }, + "dependencies": { "eventemitter3": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", @@ -5623,22 +5398,22 @@ } }, "@storybook/client-logger": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.4.tgz", - "integrity": "sha512-ofp6QQPQZBU+RvlAH5KpZRsfAFHecCZDnl/7YG6FwjHseJr3jHTYmBGGjJDMHFHq+Q7FGQu/yVb9lMFgoQ43QQ==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.3.tgz", + "integrity": "sha512-Z1irXW4jiFs7rClgqJqYOgg5op51ynV6dVuoIqxkSC0MrOG5s/VbX7T+ojGPXKyQWD4XYGw66Hnw9jouSfXL9g==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/components": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.4.tgz", - "integrity": "sha512-APhw+XGag0RTCRJ8eCWKVr8dLt9SRqnS8LtzcZJbokCYRxRTFzhmX2eVEE1v+d0gHib1/yh2COxOjMzv3m/rQA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.3.tgz", + "integrity": "sha512-EiWKa3xONP2BPxrssiRdvKELhF2tO14HVL131CCFY+Zg/ylExzWWWVSBun7vYcKhkI52K5lmvC1vFSsB6Gmlhw==", "dev": true, "requires": { - "@storybook/client-logger": "5.2.4", - "@storybook/theming": "5.2.4", + "@storybook/client-logger": "5.2.3", + "@storybook/theming": "5.2.3", "@types/react-syntax-highlighter": "10.1.0", "core-js": "^3.0.1", "global": "^4.3.2", @@ -5658,9 +5433,9 @@ } }, "@storybook/core": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-5.2.4.tgz", - "integrity": "sha512-r5kDgZETNawHxpsAPw+h+pRk6l/mJhsSHeDo9/OdYtYFW7lmk2gadViXOTM+6gIWc6vQ8y750bgkahmyIIY0nQ==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-5.2.3.tgz", + "integrity": "sha512-sktjYY8pH4kQGFRKjXwtwwShdG3ajjHkrnw8oh3R383MRPom7i9owx5yHHMuQedLCXIwAg84s2DzO01I2URTcg==", "dev": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.3.3", @@ -5668,15 +5443,15 @@ "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-transform-react-constant-elements": "^7.2.0", "@babel/preset-env": "^7.4.5", - "@storybook/addons": "5.2.4", - "@storybook/channel-postmessage": "5.2.4", - "@storybook/client-api": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/node-logger": "5.2.4", - "@storybook/router": "5.2.4", - "@storybook/theming": "5.2.4", - "@storybook/ui": "5.2.4", + "@storybook/addons": "5.2.3", + "@storybook/channel-postmessage": "5.2.3", + "@storybook/client-api": "5.2.3", + "@storybook/client-logger": "5.2.3", + "@storybook/core-events": "5.2.3", + "@storybook/node-logger": "5.2.3", + "@storybook/router": "5.2.3", + "@storybook/theming": "5.2.3", + "@storybook/ui": "5.2.3", "airbnb-js-shims": "^1 || ^2", "ansi-to-html": "^0.6.11", "autoprefixer": "^9.4.9", @@ -5744,12 +5519,12 @@ } }, "ansi-to-html": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.12.tgz", - "integrity": "sha512-qBkIqLW979675mP76yB7yVkzeAWtATegdnDQ0RA3CZzknx0yUlNxMSML4xFdBfTs2GWYFQ1FELfbGbVSPzJ+LA==", + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.11.tgz", + "integrity": "sha512-88XZtrcwrfkyn6fGstHnkaF1kl7hGtNCYh4vSmItgEV+6JnQHryDBf7udF4f2RhTRQmYvJvPcTtqgaqrxzc9oA==", "dev": true, "requires": { - "entities": "^1.1.2" + "entities": "^1.1.1" } }, "body-parser": { @@ -5808,12 +5583,6 @@ "ms": "2.0.0" } }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -6153,18 +5922,18 @@ } }, "@storybook/core-events": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.4.tgz", - "integrity": "sha512-nQknCmaz2S2HW6PSGcuFzve7Y1Js2Cb268vUG0ZMNtJZwFawqYc+KSQHqmOY0pVm8dyROTcWCudPA0k+hk6N5Q==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.3.tgz", + "integrity": "sha512-sZEv93yE1o+/UJdhtqQ6vo2EauZ90FjN/L8F7CR7iqDEZzqo9g77Idg9LSgcN3TAeXcGAWVSrPb1vkK7H96L2g==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/node-logger": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-5.2.4.tgz", - "integrity": "sha512-4OOzce02IAfrRv+Y7h3icyw6WIuDekpWF2eYjgYVVvAJYklCEwgeBTBCY0/2TJjPPTBDPUKHVP1Bdz3Vpci9pA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-5.2.3.tgz", + "integrity": "sha512-5p+5ltLdr7cZTSCG+vdIMDLHq5AAaL/CQ/bygjl+Rw/RSpvBO5Rg8hryszFyhogToHJbn2JinUbypLA+P6tcuQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6183,17 +5952,17 @@ } }, "@storybook/react": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-5.2.4.tgz", - "integrity": "sha512-AO0qwbD/2UGe5CrVizbaek+gCAPWkPVc0KUk38cT1mcuLpXwt1zZe7iHLQf2zOeBVSiBkPLOHrEtzDfnIJXKFQ==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-5.2.3.tgz", + "integrity": "sha512-7DLUkpwyPTyDHoih/AvFr2QXQAxzXQMVDvvR5r0J0oiffLWwrqshl1TL4b16YoFvel0ZPtUdrcei6knLXhg+Wg==", "dev": true, "requires": { "@babel/plugin-transform-react-constant-elements": "^7.2.0", "@babel/preset-flow": "^7.0.0", "@babel/preset-react": "^7.0.0", - "@storybook/addons": "5.2.4", - "@storybook/core": "5.2.4", - "@storybook/node-logger": "5.2.4", + "@storybook/addons": "5.2.3", + "@storybook/core": "5.2.3", + "@storybook/node-logger": "5.2.3", "@svgr/webpack": "^4.0.3", "@types/webpack-env": "^1.13.7", "babel-plugin-add-react-displayname": "^0.0.5", @@ -6221,9 +5990,9 @@ } }, "@storybook/router": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.4.tgz", - "integrity": "sha512-GL7eGdj5oYST0mE9fThJB9ye9tTTgrP+aP3okZ6MeMGtNytb7bmJRpAD2E4ouuPTQVppyHI5re8g/HUxUNOT1g==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.3.tgz", + "integrity": "sha512-sOu6y2GySaY82SdXfF3yOn0IJTKMqd2BDOSGEno7PWWtSenHFQWY+z99C9k0dLBTkjRes5tPcgm0OJ7RdQVRDQ==", "dev": true, "requires": { "@reach/router": "^1.2.1", @@ -6244,13 +6013,13 @@ } }, "@storybook/source-loader": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.2.4.tgz", - "integrity": "sha512-TXqJhj0oSnUp4w5dyh2sf3OXt/ShF9m7ceTzI8H8ZfuI8kljVsv+KvGdv+Q4f4jrO3br4Qz7bE9Wvp70i9BY1g==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.2.3.tgz", + "integrity": "sha512-4wKYslglYt/yC77zvRZ4OkmTVbnmnd98VMD99KP3Ap6IwkdxtGKIBTOOT36g6m0/1JaMFe+x7i+i9nbmK4hsDQ==", "dev": true, "requires": { - "@storybook/addons": "5.2.4", - "@storybook/router": "5.2.4", + "@storybook/addons": "5.2.3", + "@storybook/router": "5.2.3", "core-js": "^3.0.1", "estraverse": "^4.2.0", "global": "^4.3.2", @@ -6295,14 +6064,14 @@ } }, "@storybook/theming": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.4.tgz", - "integrity": "sha512-2ZlqBrmnm8N0352Fnu2+GB3pEsHL4Eb2eKxV0VLLgkjJuAlm7CK6+I/e4ZknQWxwYm2pQj1y6ta68A62fGBYyA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.3.tgz", + "integrity": "sha512-3/0bo8CaoaHDYZaexydpYcwP6WW8BKRqSQBGXJY9y0TLhwY2Who5nPX9XdOLyu9d7lN//PRZlt8JnZynuncxoQ==", "dev": true, "requires": { "@emotion/core": "^10.0.14", "@emotion/styled": "^10.0.14", - "@storybook/client-logger": "5.2.4", + "@storybook/client-logger": "5.2.3", "common-tags": "^1.8.0", "core-js": "^3.0.1", "deep-object-diff": "^1.1.0", @@ -6323,19 +6092,19 @@ } }, "@storybook/ui": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-5.2.4.tgz", - "integrity": "sha512-zsS43k1h4bWEW6oj9FNHlUL3niHoJJ8v7iqYbRtVM12rxrYhV3K8TGVG3LCuNB75i3Be0Myy+/RHA4x9kco08A==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.4", - "@storybook/api": "5.2.4", - "@storybook/channels": "5.2.4", - "@storybook/client-logger": "5.2.4", - "@storybook/components": "5.2.4", - "@storybook/core-events": "5.2.4", - "@storybook/router": "5.2.4", - "@storybook/theming": "5.2.4", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-5.2.3.tgz", + "integrity": "sha512-SNyo5oxupb105N4Rz8O5/iJMs/THrmdvP+vsN7CpOTxebM01rHyvk51cNUwHKG1QwlZmpXL8GbtWlbvqL2d/gQ==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.3", + "@storybook/api": "5.2.3", + "@storybook/channels": "5.2.3", + "@storybook/client-logger": "5.2.3", + "@storybook/components": "5.2.3", + "@storybook/core-events": "5.2.3", + "@storybook/router": "5.2.3", + "@storybook/theming": "5.2.3", "copy-to-clipboard": "^3.0.8", "core-js": "^3.0.1", "core-js-pure": "^3.0.1", @@ -6875,15 +6644,6 @@ "csstype": "^2.2.0" } }, - "@types/react-color": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.1.tgz", - "integrity": "sha512-J6mYm43Sid9y+OjZ7NDfJ2VVkeeuTPNVImNFITgQNXodHteKfl/t/5pAR5Z9buodZ2tCctsZjgiMlQOpfntakw==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@types/react-syntax-highlighter": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-10.1.0.tgz", @@ -6927,9 +6687,9 @@ } }, "@types/webpack-env": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.14.1.tgz", - "integrity": "sha512-0Ki9jAAhKDSuLDXOIMADg54Hu60SuBTEsWaJGGy5cV+SSUQ63J2a+RrYYGrErzz39fXzTibhKrAQJAb8M7PNcA==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.14.0.tgz", + "integrity": "sha512-Fv+0gYJzE/czLoRKq+gnXWr4yBpPM3tO3C8pDLFwqVKlMICQUq5OsxwwFZYDaVr7+L6mgNDp16iOcJHEz3J5RQ==", "dev": true }, "@types/yargs": { @@ -7207,10 +6967,6 @@ "core-js": "^3.1.4" } }, - "@wordpress/base-styles": { - "version": "file:packages/base-styles", - "dev": true - }, "@wordpress/blob": { "version": "file:packages/blob", "requires": { @@ -7228,7 +6984,6 @@ "@wordpress/data": "file:packages/data", "@wordpress/element": "file:packages/element", "@wordpress/i18n": "file:packages/i18n", - "@wordpress/plugins": "file:packages/plugins", "lodash": "^4.17.15" } }, @@ -7500,7 +7255,6 @@ "@wordpress/jest-console": "file:packages/jest-console", "@wordpress/jest-puppeteer-axe": "file:packages/jest-puppeteer-axe", "@wordpress/scripts": "file:packages/scripts", - "@wordpress/url": "file:packages/url", "expect-puppeteer": "^4.3.0", "lodash": "^4.17.15", "uuid": "^3.3.2" @@ -7850,8 +7604,8 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^4.0.3", - "puppeteer": "^1.20.0", + "npm-package-json-lint": "^3.6.0", + "puppeteer": "^1.19.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", "resolve-bin": "^0.4.0", @@ -8025,9 +7779,9 @@ "dev": true }, "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -8302,20 +8056,12 @@ } }, "ansi-to-html": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.12.tgz", - "integrity": "sha512-qBkIqLW979675mP76yB7yVkzeAWtATegdnDQ0RA3CZzknx0yUlNxMSML4xFdBfTs2GWYFQ1FELfbGbVSPzJ+LA==", + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.10.tgz", + "integrity": "sha512-znsY3gvsk4CiApWu1yVYF8Nx5Vy0FEe8B0YwyxdbCdErJu5lfKlRHB2twtUjR+dxR4WewTk2OP8XqTmWYnImOg==", "dev": true, "requires": { - "entities": "^1.1.2" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } + "entities": "^1.1.1" } }, "ansi-wrap": { @@ -8585,71 +8331,14 @@ } }, "array.prototype.flatmap": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.2.tgz", - "integrity": "sha512-ZZtPLE74KNE+0XcPv/vQmcivxN+8FhwOLvt2udHauO0aDEpsXDQrmd5HuJGpgPVyaV8HvkDPWnJ2iaem0oCKtA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz", + "integrity": "sha512-i18e2APdsiezkcqDyZor78Pbfjfds3S94dG6dgIV2ZASJaUf1N0dz2tGdrmwrmlZuNUgxH+wz6Z0zYVH2c5xzQ==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.15.0", + "define-properties": "^1.1.2", + "es-abstract": "^1.10.0", "function-bind": "^1.1.1" - }, - "dependencies": { - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "es-abstract": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", - "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - } - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - } } }, "arrify": { @@ -9857,12 +9546,12 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "dev": true, "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -9915,9 +9604,9 @@ } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", "dev": true }, "@babel/plugin-proposal-class-properties": { @@ -9952,9 +9641,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", - "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz", + "integrity": "sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -10024,9 +9713,9 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz", - "integrity": "sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz", + "integrity": "sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g==", "dev": true, "requires": { "regexpu-core": "^4.6.0" @@ -10121,19 +9810,6 @@ "semver": "^5.5.0" } }, - "@babel/preset-react": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", - "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-transform-react-display-name": "^7.0.0", - "@babel/plugin-transform-react-jsx": "^7.0.0", - "@babel/plugin-transform-react-jsx-self": "^7.0.0", - "@babel/plugin-transform-react-jsx-source": "^7.0.0" - } - }, "@babel/runtime": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", @@ -10155,26 +9831,26 @@ } }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/parser": "^7.6.2", + "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -10916,8 +10592,7 @@ "buffer-from": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" }, "buffer-xor": { "version": "1.0.3", @@ -11251,9 +10926,9 @@ } }, "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.1.tgz", + "integrity": "sha512-gfw3p2oQV2wEt+8VuMlNsPjCxDxvvgnm/kz+uATu805mWVF8IJN7uz9DN7iBz+RMJISmiVbCOBFs9qBGMjtPfQ==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -11267,20 +10942,599 @@ "normalize-path": "^3.0.0", "path-is-absolute": "^1.0.0", "readdirp": "^2.2.1", - "upath": "^1.1.1" + "upath": "^1.1.0" }, "dependencies": { + "fsevents": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true } } }, @@ -11519,6 +11773,12 @@ "is-supported-regexp-flag": "^1.0.0" } }, + "clones": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/clones/-/clones-1.2.0.tgz", + "integrity": "sha512-FXDYw4TjR8wgPZYui2LeTqWh1BLpfQ8lB6upMtlpDF6WlOOxghmTTxWyngdKTgozqBgKnHbTVwTE+hOHqAykuQ==", + "dev": true + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -11986,9 +12246,9 @@ "dev": true }, "conventional-changelog-angular": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.5.tgz", - "integrity": "sha512-RrkdWnL/TVyWV1ayWmSsrWorsTDqjL/VwG5ZSEneBQrd65ONcfeA1cW7FLtNweQyMiKOyriCMTKRSlk18DjTrw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz", + "integrity": "sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -12089,15 +12349,15 @@ "dev": true }, "conventional-changelog-writer": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.9.tgz", - "integrity": "sha512-2Y3QfiAM37WvDMjkVNaRtZgxVzWKj73HE61YQ/95T53yle+CRwTVSl6Gbv/lWVKXeZcM5af9n9TDVf0k7Xh+cw==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.7.tgz", + "integrity": "sha512-p/wzs9eYaxhFbrmX/mCJNwJuvvHR+j4Fd0SQa2xyAhYed6KBiZ780LvoqUUvsayP4R1DtC27czalGUhKV2oabw==", "dev": true, "requires": { "compare-func": "^1.3.1", "conventional-commits-filter": "^2.0.2", "dateformat": "^3.0.0", - "handlebars": "^4.4.0", + "handlebars": "^4.1.2", "json-stringify-safe": "^5.0.1", "lodash": "^4.2.1", "meow": "^4.0.0", @@ -12200,9 +12460,9 @@ } }, "conventional-commits-parser": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.5.tgz", - "integrity": "sha512-qVz9+5JwdJzsbt7JbJ6P7NOXBGt8CyLFJYSjKAuPSgO+5UGfcsbk9EMR+lI8Unlvx6qwIc2YDJlrGIfay2ehNA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.3.tgz", + "integrity": "sha512-KaA/2EeUkO4bKjinNfGUyqPTX/6w9JGshuQRik4r/wJz7rUw3+D3fDG6sZSEqJvKILzKXFQuFkpPLclcsAuZcg==", "dev": true, "requires": { "JSONStream": "^1.0.4", @@ -12861,9 +13121,9 @@ "dev": true }, "schema-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz", - "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", + "integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", "dev": true, "requires": { "ajv": "^6.10.2", @@ -13178,15 +13438,6 @@ "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==", "dev": true }, - "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", - "dev": true, - "requires": { - "cssom": "0.3.x" - } - }, "csstype": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz", @@ -13272,9 +13523,9 @@ "dev": true }, "deasync": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.15.tgz", - "integrity": "sha512-pxMaCYu8cQIbGkA4Y1R0PLSooPIpH1WgFBLeJ+zLxQgHfkZG86ViJSmZmONSjZJ/R3NjwkMcIWZAzpLB2G9/CA==", + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.14.tgz", + "integrity": "sha512-wN8sIuEqIwyQh72AG7oY6YQODCxIp1eXzEZlZznBuwDF8Q03Tdy9QNp1BNZXeadXoklNrw+Ip1fch+KXo/+ASw==", "dev": true, "requires": { "bindings": "~1.2.1", @@ -13845,15 +14096,6 @@ "utila": "~0.4" } }, - "dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.1.2" - } - }, "dom-scroll-into-view": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", @@ -13956,9 +14198,9 @@ } }, "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz", + "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=", "dev": true }, "dotenv-webpack": { @@ -14007,6 +14249,42 @@ "jsbn": "~0.1.0" } }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -14417,9 +14695,9 @@ "dev": true }, "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", "dev": true }, "es6-promisify": { @@ -15687,8 +15965,7 @@ "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" }, "figures": { "version": "2.0.0", @@ -16199,14 +16476,14 @@ "dev": true }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "dev": true, "optional": true, "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -16284,12 +16561,12 @@ "optional": true }, "debug": { - "version": "4.1.1", + "version": "2.6.9", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "deep-extend": { @@ -16460,31 +16737,24 @@ } }, "ms": { - "version": "2.1.1", + "version": "2.0.0", "bundled": true, "dev": true, "optional": true }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, "needle": { - "version": "2.3.0", + "version": "2.2.4", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "^4.1.0", + "debug": "^2.1.2", "iconv-lite": "^0.4.4", "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.12.0", + "version": "0.10.3", "bundled": true, "dev": true, "optional": true, @@ -16512,13 +16782,13 @@ } }, "npm-bundled": { - "version": "1.0.6", + "version": "1.0.5", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.4.1", + "version": "1.2.0", "bundled": true, "dev": true, "optional": true, @@ -16608,7 +16878,8 @@ "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true } @@ -16657,7 +16928,7 @@ "optional": true }, "semver": { - "version": "5.7.0", + "version": "5.6.0", "bundled": true, "dev": true, "optional": true @@ -17350,9 +17621,9 @@ } }, "glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -17874,153 +18145,19 @@ } }, "htmlnano": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.4.tgz", - "integrity": "sha512-wsg7+Hjyi1gHpMUixkeOjeRUNhBBTnEDB//kzvVHR+LUK4p+/31DAyE+pEACT0SQk3W0KE7Xdylk9+uNxdHXLg==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.3.tgz", + "integrity": "sha512-iS6T3J5gk2wInodbtMUyAU8sLYJOhuWDnIEd8lFRoHTypVGgawPHFEx2ZIK/XTErtDfwHBsrXeCwHAP8bdoSWw==", "dev": true, "requires": { - "cssnano": "^4.1.10", - "normalize-html-whitespace": "^1.0.0", + "cssnano": "^4.1.9", + "normalize-html-whitespace": "^0.2.0", "object-assign": "^4.0.1", - "posthtml": "^0.11.4", - "posthtml-render": "^1.1.5", - "svgo": "^1.2.2", - "terser": "^4.1.2", - "uncss": "^0.17.0" - }, - "dependencies": { - "css-select": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", - "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^2.1.2", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-tree": { - "version": "1.0.0-alpha.33", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", - "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", - "dev": true, - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.5.3" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", - "dev": true - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "object.values": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", - "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "svgo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", - "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.33", - "csso": "^3.5.1", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - } - }, - "terser": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz", - "integrity": "sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - } + "posthtml": "^0.11.3", + "posthtml-render": "^1.1.4", + "svgo": "^1.0.5", + "terser": "^3.16.1", + "uncss": "^0.16.2" } }, "htmlparser2": { @@ -18089,12 +18226,12 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.3.tgz", - "integrity": "sha512-Ytgnz23gm2DVftnzqRRz2dOXZbGd2uiajSw/95bPp6v53zPRspQjLm/AfBgqbJ2qfeRXWIOMVLpp86+/5yX39Q==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "agent-base": "^4.3.0", + "agent-base": "^4.1.0", "debug": "^3.1.0" } }, @@ -18524,9 +18661,9 @@ } }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -18561,8 +18698,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "in-publish": { "version": "2.0.0", @@ -18582,6 +18718,12 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -18626,9 +18768,9 @@ }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } @@ -19041,6 +19183,15 @@ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true }, + "is-path-inside": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.0.0.tgz", + "integrity": "sha512-OmUXvSq+P7aI/aRbl1dzwdlyLn8vW7Nr2/11S7y/dcLLgnQ89hgYJp7tfc+A5SRid3rNCLpruOp2CAV68/iOcA==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -20561,6 +20712,45 @@ "integrity": "sha512-O9SR2NVICx6rCqh1qsU91QZ5IoNa+2T1ROJ0OQlfvATKGmnjsAvg3r0E5ufPZ4a95jdKTPXhFWiE/sOZ7a5Rtg==", "dev": true }, + "js-beautify": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.9.1.tgz", + "integrity": "sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ==", + "dev": true, + "requires": { + "config-chain": "^1.1.12", + "editorconfig": "^0.15.2", + "glob": "^7.1.3", + "mkdirp": "~0.5.0", + "nopt": "~4.0.1" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, "js-levenshtein": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.3.tgz", @@ -20862,26 +21052,26 @@ "dev": true }, "lerna": { - "version": "3.18.2", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.18.2.tgz", - "integrity": "sha512-XznkKk2LY9HxaH+AtqyNZq7A0f9mMuv1OUeJBjJdl2oEZQPedWrmZNK6DuJNcyjjRJk6B9Xvb8eqIpe5aCHy1w==", - "dev": true, - "requires": { - "@lerna/add": "3.18.0", - "@lerna/bootstrap": "3.18.0", - "@lerna/changed": "3.18.2", - "@lerna/clean": "3.18.0", - "@lerna/cli": "3.18.0", - "@lerna/create": "3.18.0", - "@lerna/diff": "3.18.0", - "@lerna/exec": "3.18.0", - "@lerna/import": "3.18.0", - "@lerna/init": "3.18.0", - "@lerna/link": "3.18.0", - "@lerna/list": "3.18.0", - "@lerna/publish": "3.18.2", - "@lerna/run": "3.18.0", - "@lerna/version": "3.18.2", + "version": "3.16.4", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.16.4.tgz", + "integrity": "sha512-0HfwXIkqe72lBLZcNO9NMRfylh5Ng1l8tETgYQ260ZdHRbPuaLKE3Wqnd2YYRRkWfwPyEyZO8mZweBR+slVe1A==", + "dev": true, + "requires": { + "@lerna/add": "3.16.2", + "@lerna/bootstrap": "3.16.2", + "@lerna/changed": "3.16.4", + "@lerna/clean": "3.16.0", + "@lerna/cli": "3.13.0", + "@lerna/create": "3.16.0", + "@lerna/diff": "3.16.0", + "@lerna/exec": "3.16.0", + "@lerna/import": "3.16.0", + "@lerna/init": "3.16.0", + "@lerna/link": "3.16.2", + "@lerna/list": "3.16.0", + "@lerna/publish": "3.16.4", + "@lerna/run": "3.16.0", + "@lerna/version": "3.16.4", "import-local": "^2.0.0", "npmlog": "^4.1.2" } @@ -21803,15 +21993,15 @@ }, "dependencies": { "bluebird": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", - "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", "dev": true }, "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", + "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", "dev": true, "requires": { "bluebird": "^3.5.5", @@ -21832,15 +22022,15 @@ } }, "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -21852,9 +22042,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "lru-cache": { @@ -21895,9 +22085,9 @@ } }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -21928,9 +22118,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true } } @@ -22014,12 +22204,6 @@ "unquote": "^1.1.0" } }, - "material-colors": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", - "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==", - "dev": true - }, "mathml-tag-names": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.0.tgz", @@ -22130,12 +22314,6 @@ "resolved": "https://registry.npmjs.org/memize/-/memize-1.0.5.tgz", "integrity": "sha512-Dm8Jhb5kiC4+ynYsVR4QDXKt+o2dfqGuY4hE2x+XlXZkdndlT80bJxfcMv5QGp/FCy6MhG7f5ElpmKPFKOSEpg==" }, - "memoize-one": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", - "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==", - "dev": true - }, "memoizerific": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", @@ -23138,9 +23316,9 @@ } }, "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true }, "mime-db": { @@ -23463,6 +23641,13 @@ "thenify-all": "^1.0.0" } }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true, + "optional": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -23565,9 +23750,9 @@ } }, "node-addon-api": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", - "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.6.2.tgz", + "integrity": "sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA==", "dev": true }, "node-dir": { @@ -23640,9 +23825,9 @@ "dev": true }, "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", "dev": true, "requires": { "assert": "^1.1.1", @@ -23655,7 +23840,7 @@ "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", + "path-browserify": "0.0.0", "process": "^0.11.10", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", @@ -23667,7 +23852,7 @@ "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.11.0", - "vm-browserify": "^1.0.1" + "vm-browserify": "0.0.4" }, "dependencies": { "punycode": { @@ -24172,9 +24357,9 @@ } }, "normalize-html-whitespace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz", - "integrity": "sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-0.2.0.tgz", + "integrity": "sha1-EBci9kI1Ucdc24+dEE/4UNrx4Q4=", "dev": true }, "normalize-package-data": { @@ -24231,9 +24416,9 @@ "dev": true }, "npm-lifecycle": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.4.tgz", - "integrity": "sha512-tgs1PaucZwkxECGKhC/stbEgFyc3TGh2TJcg2CDr6jbvQRdteHNhmMeljRzpe4wgFAXQADoy1cSqqi7mtiAa5A==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.2.tgz", + "integrity": "sha512-nhfOcoTHrW1lJJlM2o77vTE2RWR4YOVyj7YzmY0y5itsMjEuoJHteio/ez0BliENEPsNxIUQgwhyEW9dShj3Ww==", "dev": true, "requires": { "byline": "^5.0.0", @@ -24247,31 +24432,21 @@ }, "dependencies": { "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, "node-gyp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.5.tgz", - "integrity": "sha512-WABl9s4/mqQdZneZHVWVG4TVr6QQJZUC6PAx47ITSk9lreZ1n+7Z9mMAIbA3vnO4J9W20P7LhCxtzfWsAD/KDw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.3.tgz", + "integrity": "sha512-z/JdtkFGUm0QaQUusvloyYuGDub3nUbOo5de1Fz57cM++osBTvQatBUSTlF1k/w8vFHPxxXW6zxGvkxXSpaBkQ==", "dev": true, "requires": { "env-paths": "^1.0.0", @@ -24283,7 +24458,7 @@ "request": "^2.87.0", "rimraf": "2", "semver": "~5.3.0", - "tar": "^4.4.12", + "tar": "^4.4.8", "which": "1" } }, @@ -24300,14 +24475,14 @@ "dev": true }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", + "minipass": "^2.3.5", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -24315,139 +24490,87 @@ } }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true } } }, "npm-package-arg": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", + "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", "dev": true, "requires": { - "hosted-git-info": "^2.7.1", + "hosted-git-info": "^2.6.0", "osenv": "^0.1.5", - "semver": "^5.6.0", + "semver": "^5.5.0", "validate-npm-package-name": "^3.0.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, "npm-package-json-lint": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-4.0.3.tgz", - "integrity": "sha512-cuvTR2l5dOjjlRR3a1CCp+mh2A2HyQRxydwdcYi0Z77NRlADpf7wF3Jf8XFLGZM7J6afXNRBofBjQ1UWFyOtKA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-3.6.0.tgz", + "integrity": "sha512-N1y3r0l0oN7mYnMfRzZvYF8+NvjIx+zkskRn3J7ofipJKGH4RDDKdEGP/mV1Crf5W8uUo3201VhJe04Q+v9erw==", "dev": true, "requires": { - "ajv": "^6.10.2", - "ajv-errors": "^1.0.1", + "ajv": "^6.9.2", "chalk": "^2.4.2", - "cosmiconfig": "^5.2.1", - "debug": "^4.1.1", - "globby": "^10.0.1", - "ignore": "^5.1.4", - "is-plain-obj": "^2.0.0", - "log-symbols": "^3.0.0", + "glob": "^7.1.3", + "ignore": "^5.0.5", + "is-path-inside": "^2.0.0", + "is-plain-obj": "^1.1.0", + "is-resolvable": "^1.1.0", + "log-symbols": "^2.2.0", "meow": "^5.0.0", - "plur": "^3.1.1", - "semver": "^6.3.0", - "strip-json-comments": "^3.0.1" + "plur": "^3.0.1", + "semver": "^5.6.0", + "strip-json-comments": "^2.0.1", + "validator": "^10.11.0" }, "dependencies": { - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "ajv": { + "version": "6.9.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz", + "integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==", "dev": true, "requires": { - "path-type": "^4.0.0" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "fast-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", - "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", - "dev": true - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true }, "glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -24458,135 +24581,23 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globby": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", - "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.0.0.tgz", - "integrity": "sha512-EYisGhpgSCwspmIuRHGjROWTon2Xp8Z7U03Wubk/bTL5TTRC5R1rGVgyjzBrk9+ULdH6cRD06KRcw/xfqhVYKQ==", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.0.5.tgz", + "integrity": "sha512-kOC8IUb8HSDMVcYrDVezCxpJkzSQWTAzf3olpKM6o9rM5zpojx23O0Fl8Wr4+qJ6ZbPEHqf1fdwev/DS7v7pmA==", "dev": true }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -24601,9 +24612,9 @@ } }, "npm-pick-manifest": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", - "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz", + "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -24612,9 +24623,9 @@ }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } @@ -24665,12 +24676,6 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, - "nwsapi": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", - "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", - "dev": true - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -25192,28 +25197,28 @@ } }, "parcel-bundler": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.4.tgz", - "integrity": "sha512-G+iZGGiPEXcRzw0fiRxWYCKxdt/F7l9a0xkiU4XbcVRJCSlBnioWEwJMutOCCpoQmaQtjB4RBHDGIHN85AIhLQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/core": "^7.4.4", - "@babel/generator": "^7.4.4", - "@babel/parser": "^7.4.4", - "@babel/plugin-transform-flow-strip-types": "^7.4.4", - "@babel/plugin-transform-modules-commonjs": "^7.4.4", - "@babel/plugin-transform-react-jsx": "^7.0.0", - "@babel/preset-env": "^7.4.4", - "@babel/runtime": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.3.tgz", + "integrity": "sha512-8bq6lj0hhQeGxD9f9xEkFMXQ3d8TIlf2+isKxoi9bciB0KVEILRGllaPkUgp++5t0anToBh9+tG6ZyInXOC1/A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0 <7.4.0", + "@babel/core": "^7.0.0 <7.4.0", + "@babel/generator": "^7.0.0 <7.4.0", + "@babel/parser": "^7.0.0 <7.4.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0 <7.4.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0 <7.4.0", + "@babel/plugin-transform-react-jsx": "^7.0.0 <7.4.0", + "@babel/preset-env": "^7.0.0 <7.4.0", + "@babel/runtime": "^7.0.0 <7.4.0", + "@babel/template": "^7.0.0 <7.4.0", + "@babel/traverse": "^7.0.0 <7.4.0", + "@babel/types": "^7.0.0 <7.4.0", "@iarna/toml": "^2.2.0", "@parcel/fs": "^1.11.0", - "@parcel/logger": "^1.11.1", + "@parcel/logger": "^1.11.0", "@parcel/utils": "^1.11.0", - "@parcel/watcher": "^1.12.1", + "@parcel/watcher": "^1.12.0", "@parcel/workers": "^1.11.0", "ansi-to-html": "^0.6.4", "babylon-walk": "^1.0.2", @@ -25222,14 +25227,12 @@ "clone": "^2.1.1", "command-exists": "^1.2.6", "commander": "^2.11.0", - "core-js": "^2.6.5", "cross-spawn": "^6.0.4", "css-modules-loader-core": "^1.1.0", "cssnano": "^4.0.0", "deasync": "^0.1.14", "dotenv": "^5.0.0", - "dotenv-expand": "^5.1.0", - "envinfo": "^7.3.1", + "dotenv-expand": "^4.2.0", "fast-glob": "^2.2.2", "filesize": "^3.6.0", "get-port": "^3.2.0", @@ -25250,7 +25253,7 @@ "posthtml-render": "^1.1.3", "resolve": "^1.4.0", "semver": "^5.4.1", - "serialize-to-js": "^3.0.0", + "serialize-to-js": "^1.1.1", "serve-static": "^1.12.4", "source-map": "0.6.1", "terser": "^3.7.3", @@ -25258,14 +25261,180 @@ "ws": "^5.1.1" }, "dependencies": { - "@babel/plugin-transform-flow-strip-types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz", - "integrity": "sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg==", + "@babel/core": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", + "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helpers": "^7.2.0", + "@babel/parser": "^7.3.4", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.3.4", + "@babel/types": "^7.3.4", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.3.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/parser": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", + "dev": true + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", + "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-flow": "^7.2.0" + "@babel/helper-simple-access": "^7.1.0" + } + }, + "@babel/preset-env": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.4.tgz", + "integrity": "sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.3.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.3.4", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.3.4", + "@babel/plugin-transform-classes": "^7.3.4", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.2.0", + "@babel/plugin-transform-dotall-regex": "^7.2.0", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.2.0", + "@babel/plugin-transform-function-name": "^7.2.0", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/plugin-transform-modules-systemjs": "^7.3.4", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", + "@babel/plugin-transform-new-target": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.3.4", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.2.0", + "browserslist": "^4.3.4", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.3.0" + } + }, + "@babel/runtime": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.4.tgz", + "integrity": "sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.12.0" + } + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "@babel/types": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" } }, "clone": { @@ -25274,12 +25443,6 @@ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", - "dev": true - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -25293,6 +25456,21 @@ "which": "^1.2.9" } }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -25302,16 +25480,28 @@ "minimist": "^1.2.0" } }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, "postcss-value-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "dev": true + }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true }, "source-map": { @@ -25439,9 +25629,9 @@ "dev": true }, "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, "path-dirname": { @@ -25461,6 +25651,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -25663,9 +25859,9 @@ } }, "plur": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", - "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plur/-/plur-3.0.1.tgz", + "integrity": "sha512-lJl0ojUynAM1BZn58Pas2WT/TXeC1+bS+UqShl0x9+49AtOn7DixRXVzaC8qrDOIxNDmepKnLuMTH7NQmkX0PA==", "dev": true, "requires": { "irregular-plurals": "^2.0.0" @@ -26632,13 +26828,36 @@ "dev": true }, "posthtml": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.6.tgz", - "integrity": "sha512-C2hrAPzmRdpuL3iH0TDdQ6XCc9M7Dcc3zEW5BLerY65G4tWWszwv6nG/ksi6ul5i2mx22ubdljgktXCtNkydkw==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.3.tgz", + "integrity": "sha512-quMHnDckt2DQ9lRi6bYLnuyBDnVzK+McHa8+ar4kTdYbWEo/92hREOu3h70ZirudOOp/my2b3r0m5YtxY52yrA==", "dev": true, "requires": { - "posthtml-parser": "^0.4.1", - "posthtml-render": "^1.1.5" + "object-assign": "^4.1.1", + "posthtml-parser": "^0.3.3", + "posthtml-render": "^1.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "posthtml-parser": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.3.3.tgz", + "integrity": "sha512-H/Z/yXGwl49A7hYQLV1iQ3h87NE0aZ/PMZhFwhw3lKeCAN+Ti4idrHvVvh4/GX10I7u77aQw+QB4vV5/Lzvv5A==", + "dev": true, + "requires": { + "htmlparser2": "^3.9.2", + "isobject": "^2.1.0", + "object-assign": "^4.1.1" + } + } } }, "posthtml-parser": { @@ -26652,9 +26871,9 @@ } }, "posthtml-render": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz", - "integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.4.tgz", + "integrity": "sha512-jL6eFIzoN3xUEvbo33OAkSDE2VIKU4JQ1wENOows1DpfnrdapR/K3Q1/fB43Mq7wQlcSgRm23nFrvoioufM7eA==", "dev": true }, "prelude-ls": { @@ -27057,9 +27276,9 @@ "dev": true }, "puppeteer": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", - "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.19.0.tgz", + "integrity": "sha512-2S6E6ygpoqcECaagDbBopoSOPDv0pAZvTbnBgUY+6hq0/XDFDOLEMNlHF/SKJlzcaZ9ckiKjKDuueWI3FN/WXw==", "dev": true, "requires": { "debug": "^4.1.0", @@ -27295,20 +27514,6 @@ "@babel/runtime": "^7.0.0" } }, - "react-color": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.3.tgz", - "integrity": "sha512-1dtO8LqAVotPIChlmo6kLtFS1FP89ll8/OiA8EcFRDR+ntcK+0ukJgByuIQHRtzvigf26dV5HklnxDIvhON9VQ==", - "dev": true, - "requires": { - "@icons/material": "^0.2.4", - "lodash": "^4.17.11", - "material-colors": "^1.2.1", - "prop-types": "^15.5.10", - "reactcss": "^1.2.0", - "tinycolor2": "^1.4.1" - } - }, "react-dates": { "version": "17.2.0", "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-17.2.0.tgz", @@ -27736,15 +27941,6 @@ "prop-types": "^15.6.1" } }, - "react-input-autosize": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz", - "integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==", - "dev": true, - "requires": { - "prop-types": "^15.5.8" - } - }, "react-is": { "version": "16.8.4", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", @@ -28339,9 +28535,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", - "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.2.tgz", + "integrity": "sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -28370,26 +28566,10 @@ "integrity": "sha512-ITw8t/HOFNose2yf1y9pPFSSeB9ISOq2JdHpuZvj/Qb+iSsLml8GkkHdDlURzieO7B3dFDtMrrneZLl3N5z/hg==", "dev": true }, - "react-select": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.0.8.tgz", - "integrity": "sha512-v9LpOhckLlRmXN5A6/mGGEft4FMrfaBFTGAnuPHcUgVId7Je42kTq9y0Z+Ye5z8/j0XDT3zUqza8gaRaI1PZIg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.4", - "@emotion/cache": "^10.0.9", - "@emotion/core": "^10.0.9", - "@emotion/css": "^10.0.9", - "memoize-one": "^5.0.0", - "prop-types": "^15.6.0", - "react-input-autosize": "^2.2.2", - "react-transition-group": "^2.2.1" - } - }, "react-sizeme": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-2.6.8.tgz", - "integrity": "sha512-eJKHV226d/S3st2He7bLIlY7FAmi2ItvZmUCmLLNjIvYjtiv58BksuFhTBQmvAxWaXZGb3Ao/44wfAS1voRdjA==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-2.6.7.tgz", + "integrity": "sha512-xCjPoBP5jmeW58TxIkcviMZqabZis7tTvDFWf0/Wa5XCgVWQTIe74NQBes2N1Kmp64GRLkpm60BaP0kk+v8aCQ==", "dev": true, "requires": { "element-resize-detector": "^1.1.15", @@ -28460,18 +28640,6 @@ "react-proxy": "^1.1.7" } }, - "react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "dev": true, - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - } - }, "react-with-direction": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.0.tgz", @@ -28507,15 +28675,6 @@ "global-cache": "^1.2.1" } }, - "reactcss": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", - "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", - "dev": true, - "requires": { - "lodash": "^4.0.1" - } - }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -28526,18 +28685,18 @@ } }, "read-cmd-shim": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.4.tgz", - "integrity": "sha512-Pqpl3qJ/QdOIjRYA0q5DND/gLvGOfpIz/fYVDGYpOXfW/lFrIttmLsBnd6IkyK10+JHU9zhsaudfvrQTBB9YFQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz", + "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=", "dev": true, "requires": { "graceful-fs": "^4.1.2" } }, "read-package-json": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.0.tgz", - "integrity": "sha512-KLhu8M1ZZNkMcrq1+0UJbR8Dii8KZUqB0Sha4mOx/bknfKI/fyrQVrG/YIt2UOtG667sD8+ee4EXMM91W9dC+A==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.13.tgz", + "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", "dev": true, "requires": { "glob": "^7.1.1", @@ -28799,6 +28958,202 @@ "safe-regex": "^1.1.0" } }, + "regexp-tree": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.1.tgz", + "integrity": "sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw==", + "dev": true, + "requires": { + "cli-table3": "^0.5.0", + "colors": "^1.1.2", + "yargs": "^12.0.5" + }, + "dependencies": { + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "regexp.prototype.flags": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", @@ -28922,12 +29277,12 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "dev": true, "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -28945,9 +29300,9 @@ } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", "dev": true }, "@babel/plugin-proposal-object-rest-spread": { @@ -28972,26 +29327,26 @@ } }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/parser": "^7.6.2", + "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -29580,6 +29935,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "safer-eval": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/safer-eval/-/safer-eval-1.3.5.tgz", + "integrity": "sha512-BJ//K2Y+EgCbOHEsDGS5YahYBcYy7JcFpKDo2ba5t4MnOGHYtk7HvQkcxTDFvjQvJ0CRcdas/PyF+gTTCay+3w==", + "dev": true, + "requires": { + "clones": "^1.2.0" + } + }, "sane": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", @@ -29792,15 +30156,6 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, - "saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", - "dev": true, - "requires": { - "xmlchars": "^2.1.1" - } - }, "scheduler": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", @@ -29910,10 +30265,14 @@ "dev": true }, "serialize-to-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.0.0.tgz", - "integrity": "sha512-WdGgi0jGnWCQXph2p3vkxceDnTfvfyXfYxherQMRcZjSaJzMQdMBAW6i0nojsBKIZ3fFOztZKKVbbm05VbIdRA==", - "dev": true + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-1.2.2.tgz", + "integrity": "sha512-mUc8vA5iJghe+O+3s0YDGFLMJcqitVFk787YKiv8a4sf6RX5W0u81b+gcHrp15O0fFa010dRBVZvwcKXOWsL9Q==", + "dev": true, + "requires": { + "js-beautify": "^1.8.9", + "safer-eval": "^1.3.0" + } }, "serve-favicon": { "version": "2.5.0", @@ -30133,6 +30492,12 @@ } } }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -30425,17 +30790,6 @@ "requires": { "agent-base": "~4.2.1", "socks": "~2.3.2" - }, - "dependencies": { - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - } } }, "sort-keys": { @@ -30450,8 +30804,7 @@ "source-list-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", - "dev": true + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==" }, "source-map": { "version": "0.5.7", @@ -31898,11 +32251,69 @@ "source-map-support": "~0.5.10" }, "dependencies": { + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "terser": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz", + "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "requires": { + "unique-slug": "^2.0.0" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" } } }, @@ -32769,146 +33180,42 @@ "dev": true }, "uncss": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.17.2.tgz", - "integrity": "sha512-hu2HquwDItuGDem4YsJROdAD8SknmWtM24zwhQax6J1se8tPjV1cnwPKhtjodzBaUhaL8Zb3hlGdZ2WAUpbAOg==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.16.2.tgz", + "integrity": "sha1-OyJpxZAS2nxmy+mPvt3e75TwZJw=", "dev": true, "requires": { - "commander": "^2.20.0", - "glob": "^7.1.4", - "is-absolute-url": "^3.0.1", - "is-html": "^1.1.0", - "jsdom": "^14.1.0", - "lodash": "^4.17.15", - "postcss": "^7.0.17", - "postcss-selector-parser": "6.0.2", - "request": "^2.88.0" + "commander": "^2.9.0", + "glob": "^7.0.3", + "is-absolute-url": "^2.0.0", + "is-html": "^1.0.0", + "jsdom": "^11.3.0", + "lodash": "^4.13.1", + "postcss": "^6.0.14", + "postcss-selector-parser": "3.1.1", + "request": "^2.72.0" }, "dependencies": { - "abab": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz", - "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==", - "dev": true - }, - "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", - "dev": true - }, - "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "dev": true, - "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - } - }, - "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - } - }, - "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", - "dev": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "jsdom": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", - "integrity": "sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "acorn": "^6.0.4", - "acorn-globals": "^4.3.0", - "array-equal": "^1.0.0", - "cssom": "^0.3.4", - "cssstyle": "^1.1.1", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.0", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.1.3", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.5.0", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^6.1.2", - "xml-name-validator": "^3.0.0" + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" } }, - "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", - "dev": true - }, - "postcss": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz", - "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==", + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" } }, "source-map": { @@ -32916,60 +33223,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } } } }, @@ -33094,7 +33347,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", - "dev": true, "requires": { "imurmurhash": "^0.1.4" } @@ -33261,6 +33513,12 @@ } } }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, "upper-case": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", @@ -33342,9 +33600,9 @@ "dev": true }, "schema-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz", - "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", + "integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", "dev": true, "requires": { "ajv": "^6.10.2", @@ -33427,9 +33685,9 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", + "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", "dev": true }, "validate-npm-package-license": { @@ -33451,6 +33709,12 @@ "builtins": "^1.0.3" } }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -33522,10 +33786,13 @@ "dev": true }, "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", - "dev": true + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } }, "w3c-hr-time": { "version": "1.0.1", @@ -33536,17 +33803,6 @@ "browser-process-hrtime": "^0.1.2" } }, - "w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", - "dev": true, - "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" - } - }, "wait-on": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.3.0.tgz", @@ -34517,9 +34773,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "make-dir": { @@ -34539,9 +34795,9 @@ "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } @@ -34630,12 +34886,6 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, "xmldoc": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-0.4.0.tgz", diff --git a/package.json b/package.json index 87179bff38b782..31d63d691e3b5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.8.0-rc.1", + "version": "6.6.0", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", @@ -72,24 +72,22 @@ "@babel/runtime-corejs3": "7.4.5", "@babel/traverse": "7.4.5", "@octokit/rest": "16.26.0", - "@storybook/addon-a11y": "5.2.4", - "@storybook/addon-docs": "5.2.4", - "@storybook/addon-knobs": "5.2.4", - "@storybook/addon-storysource": "5.2.4", - "@storybook/addon-viewport": "5.2.4", - "@storybook/react": "5.2.4", + "@storybook/addon-a11y": "5.2.3", + "@storybook/addon-docs": "5.2.3", + "@storybook/addon-storysource": "5.2.3", + "@storybook/addon-viewport": "5.2.3", + "@storybook/react": "5.2.3", "@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma", "@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot", "@wordpress/babel-preset-default": "file:packages/babel-preset-default", - "@wordpress/base-styles": "file:packages/base-styles", "@wordpress/browserslist-config": "file:packages/browserslist-config", "@wordpress/custom-templated-path-webpack-plugin": "file:packages/custom-templated-path-webpack-plugin", "@wordpress/dependency-extraction-webpack-plugin": "file:packages/dependency-extraction-webpack-plugin", "@wordpress/docgen": "file:packages/docgen", "@wordpress/e2e-test-utils": "file:packages/e2e-test-utils", "@wordpress/e2e-tests": "file:packages/e2e-tests", - "@wordpress/env": "file:packages/env", "@wordpress/eslint-plugin": "file:packages/eslint-plugin", + "@wordpress/env": "file:packages/env", "@wordpress/jest-console": "file:packages/jest-console", "@wordpress/jest-preset-default": "file:packages/jest-preset-default", "@wordpress/jest-puppeteer-axe": "file:packages/jest-puppeteer-axe", @@ -123,7 +121,7 @@ "jest-junit": "6.4.0", "jest-serializer-enzyme": "1.0.0", "jsdom": "11.12.0", - "lerna": "3.18.2", + "lerna": "3.16.4", "lint-staged": "9.2.5", "lodash": "4.17.15", "make-dir": "3.0.0", @@ -132,7 +130,7 @@ "mkdirp": "0.5.1", "node-sass": "4.12.0", "node-watch": "0.6.0", - "parcel-bundler": "1.12.4", + "parcel-bundler": "1.12.3", "postcss": "7.0.13", "progress": "2.0.3", "react": "16.9.0", @@ -155,6 +153,34 @@ "webpack": "4.41.0", "worker-farm": "1.7.0" }, + "npmPackageJsonLintConfig": { + "extends": "@wordpress/npm-package-json-lint-config", + "rules": { + "description-format": [ + "error", + { + "requireCapitalFirstLetter": true, + "requireEndingPeriod": true + } + ], + "require-publishConfig": "error", + "require-repository-directory": "error", + "valid-values-author": [ + "error", + [ + "The WordPress Contributors" + ] + ], + "valid-values-publishConfig": [ + "error", + [ + { + "access": "public" + } + ] + ] + } + }, "scripts": { "prebuild": "npm run check-engines", "clean:packages": "rimraf ./packages/*/build ./packages/*/build-module ./packages/*/build-style ./packages/*/node_modules", @@ -177,7 +203,7 @@ "lint-js": "wp-scripts lint-js", "lint-js:fix": "npm run lint-js -- --fix", "lint-php": "wp-scripts env lint-php", - "lint-pkg-json": "wp-scripts lint-pkg-json . 'packages/*/package.json'", + "lint-pkg-json": "wp-scripts lint-pkg-json ./packages", "lint-css": "wp-scripts lint-style '**/*.scss'", "lint-css:fix": "npm run lint-css -- --fix", "lint-types": "tsc", @@ -187,7 +213,9 @@ "publish:dev": "npm run build:packages && lerna publish --npm-tag next", "publish:prod": "npm run build:packages && lerna publish", "test": "npm run lint && npm run test-unit", + "pretest-e2e": "npm run env reinstall", "test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", + "test-e2e:local": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", "test-e2e:watch": "npm run test-e2e:local -- --watch", "test-performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js", "test-php": "npm run lint-php && npm run test-unit-php", @@ -199,7 +227,7 @@ "test-unit:native": "cd test/native/ && cross-env NODE_ENV=test jest --config ./jest.config.js", "test-unit:native:debug": "cd test/native/ && node --inspect ../../node_modules/.bin/jest --runInBand --config ./jest.config.js", "design-system:build": "npm run build:packages && build-storybook -c ./packages/components/storybook -o ./playground/dist/design-system/components", - "design-system:dev": "npm run build:packages && concurrently \"npm run dev:packages\" \"start-storybook -c ./packages/components/storybook\"", + "design-system:dev": "concurrently \"npm run dev:packages\" \"start-storybook -c ./packages/components/storybook\"", "playground:build": "npm run build:packages && parcel build playground/src/index.html -d playground/dist", "playground:dev": "concurrently \"npm run dev:packages\" \"parcel playground/src/index.html -d playground/dist\"", "preenv": "npm run check-engines", diff --git a/packages/a11y/package.json b/packages/a11y/package.json index eb2f11f3a971d8..546abcd609a520 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "2.5.1", + "version": "2.5.0", "description": "Accessibility (a11y) utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/annotations/package.json b/packages/annotations/package.json index 2f08cd7c0901bd..62608fae8a7b73 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/annotations", - "version": "1.7.2", + "version": "1.7.0", "description": "Annotate content in the Gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index 462c964c370c6b..26876a3e860239 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "3.6.3", + "version": "3.6.0", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/src/index.js b/packages/api-fetch/src/index.js index dc7dda91fa1e60..7535d2117b2f24 100644 --- a/packages/api-fetch/src/index.js +++ b/packages/api-fetch/src/index.js @@ -1,3 +1,8 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + /** * Internal dependencies */ @@ -8,8 +13,6 @@ import fetchAllMiddleware from './middlewares/fetch-all-middleware'; import namespaceEndpointMiddleware from './middlewares/namespace-endpoint'; import httpV1Middleware from './middlewares/http-v1'; import userLocaleMiddleware from './middlewares/user-locale'; -import mediaUploadMiddleware from './middlewares/media-upload'; -import { parseResponseAndNormalizeError, parseAndThrowError } from './utils/response'; /** * Default set of header values which should be sent with every request unless @@ -77,10 +80,48 @@ const defaultFetchHandler = ( nextOptions ) => { } ); + const parseResponse = ( response ) => { + if ( parse ) { + if ( response.status === 204 ) { + return null; + } + + return response.json ? response.json() : Promise.reject( response ); + } + + return response; + }; + return responsePromise .then( checkStatus ) - .catch( ( response ) => parseAndThrowError( response, parse ) ) - .then( ( response ) => parseResponseAndNormalizeError( response, parse ) ); + .then( parseResponse ) + .catch( ( response ) => { + if ( ! parse ) { + throw response; + } + + const invalidJsonError = { + code: 'invalid_json', + message: __( 'The response is not a valid JSON response.' ), + }; + + if ( ! response || ! response.json ) { + throw invalidJsonError; + } + + return response.json() + .catch( () => { + throw invalidJsonError; + } ) + .then( ( error ) => { + const unknownError = { + code: 'unknown_error', + message: __( 'An unknown error occurred.' ), + }; + + throw error || unknownError; + } ); + } ); }; let fetchHandler = defaultFetchHandler; @@ -138,6 +179,5 @@ apiFetch.createNonceMiddleware = createNonceMiddleware; apiFetch.createPreloadingMiddleware = createPreloadingMiddleware; apiFetch.createRootURLMiddleware = createRootURLMiddleware; apiFetch.fetchAllMiddleware = fetchAllMiddleware; -apiFetch.mediaUploadMiddleware = mediaUploadMiddleware; export default apiFetch; diff --git a/packages/api-fetch/src/middlewares/media-upload.js b/packages/api-fetch/src/middlewares/media-upload.js deleted file mode 100644 index 6772aaf3ded733..00000000000000 --- a/packages/api-fetch/src/middlewares/media-upload.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import { - parseAndThrowError, - parseResponseAndNormalizeError, -} from '../utils/response'; - -/** - * Middleware handling media upload failures and retries. - * - * @param {Object} options Fetch options. - * @param {Function} next [description] - * - * @return {*} The evaluated result of the remaining middleware chain. - */ -function mediaUploadMiddleware( options, next ) { - const isMediaUploadRequest = - ( options.path && options.path.indexOf( '/wp/v2/media' ) !== -1 ) || - ( options.url && options.url.indexOf( '/wp/v2/media' ) !== -1 ); - - if ( ! isMediaUploadRequest ) { - return next( options, next ); - } - let retries = 0; - const maxRetries = 5; - - const postProcess = ( attachmentId ) => { - retries++; - return next( { - path: `/wp/v2/media/${ attachmentId }/post-process`, - method: 'POST', - data: { action: 'create-image-subsizes' }, - parse: false, - } ) - .catch( () => { - if ( retries < maxRetries ) { - return postProcess( attachmentId ); - } - next( { - path: `/wp/v2/media/${ attachmentId }?force=true`, - method: 'DELETE', - } ); - - return Promise.reject(); - } ); - }; - - return next( { ...options, parse: false } ) - .catch( ( response ) => { - const attachmentId = response.headers.get( 'x-wp-upload-attachment-id' ); - if ( response.status >= 500 && response.status < 600 && attachmentId ) { - return postProcess( attachmentId ).catch( () => { - if ( options.parse !== false ) { - return Promise.reject( { - code: 'post_process', - message: __( 'Media upload failed. If this is a photo or a large image, please scale it down and try again.' ), - } ); - } - - return Promise.reject( response ); - } ); - } - return parseAndThrowError( response, options.parse ); - } ) - .then( ( response ) => parseResponseAndNormalizeError( response, options.parse ) ); -} - -export default mediaUploadMiddleware; diff --git a/packages/api-fetch/src/utils/response.js b/packages/api-fetch/src/utils/response.js deleted file mode 100644 index bb7b79ce2f8254..00000000000000 --- a/packages/api-fetch/src/utils/response.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Parses the apiFetch response. - * - * @param {Response} response - * @param {boolean} shouldParseResponse - * - * @return {Promise} Parsed response - */ -const parseResponse = ( response, shouldParseResponse = true ) => { - if ( shouldParseResponse ) { - if ( response.status === 204 ) { - return null; - } - - return response.json ? response.json() : Promise.reject( response ); - } - - return response; -}; - -const parseJsonAndNormalizeError = ( response ) => { - const invalidJsonError = { - code: 'invalid_json', - message: __( 'The response is not a valid JSON response.' ), - }; - - if ( ! response || ! response.json ) { - throw invalidJsonError; - } - - return response.json() - .catch( () => { - throw invalidJsonError; - } ); -}; - -/** - * Parses the apiFetch response properly and normalize response errors. - * - * @param {Response} response - * @param {boolean} shouldParseResponse - * - * @return {Promise} Parsed response. - */ -export const parseResponseAndNormalizeError = ( response, shouldParseResponse = true ) => { - return Promise.resolve( parseResponse( response, shouldParseResponse ) ) - .catch( ( res ) => parseAndThrowError( res, shouldParseResponse ) ); -}; - -export function parseAndThrowError( response, shouldParseResponse = true ) { - if ( ! shouldParseResponse ) { - throw response; - } - - return parseJsonAndNormalizeError( response ) - .then( ( error ) => { - const unknownError = { - code: 'unknown_error', - message: __( 'An unknown error occurred.' ), - }; - - throw error || unknownError; - } ); -} - diff --git a/packages/autop/package.json b/packages/autop/package.json index ef57d2a3a0516b..0f63cb48560d3c 100644 --- a/packages/autop/package.json +++ b/packages/autop/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/autop", - "version": "2.5.1", + "version": "2.5.0", "description": "WordPress's automatic paragraph functions `autop` and `removep`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index c02981fc1316cc..e8f3df29218a58 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-preset-default", - "version": "4.6.2", + "version": "4.6.0", "description": "Default Babel preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/base-styles/.npmrc b/packages/base-styles/.npmrc deleted file mode 100644 index 43c97e719a5a82..00000000000000 --- a/packages/base-styles/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/packages/base-styles/README.md b/packages/base-styles/README.md deleted file mode 100644 index 20945fd08acf8f..00000000000000 --- a/packages/base-styles/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Base Styles - -Base SCSS utilities and variables for WordPress. - -## Installation - -Install the module - -```bash -npm install @wordpress/base-styles --save-dev -``` - -## Use - -### SCSS utilities and variables - -In your application's SCSS file, include styles like so: - -```scss -@import "node_modules/@wordpress/base-styles/colors"; -@import "node_modules/@wordpress/base-styles/variables"; -@import "node_modules/@wordpress/base-styles/mixins"; -@import "node_modules/@wordpress/base-styles/breakpoints"; -@import "node_modules/@wordpress/base-styles/animations"; -@import "node_modules/@wordpress/base-styles/z-index"; -``` - -If you use [Webpack](https://webpack.js.org/) for your SCSS pipeline, you can use `~` to resolve to `node_modules`: - -```scss -@import "~@wordpress/base-styles/colors"; -``` - -To make that work with [`sass`](https://www.npmjs.com/package/sass) or [`node-sass`](https://www.npmjs.com/package/node-sass) NPM modules without Webpack, you'd have to use [includePaths option](https://sass-lang.com/documentation/js-api#includepaths): - -```json -{ - "includePaths": ["node_modules"] -} -``` - -### PostCSS color schemes - -To use color schemes with [`@wordpress/postcss-themes`](https://www.npmjs.com/package/@wordpress/postcss-themes), import them like so: - -```js -const { adminColorSchemes } = require( '@wordpress/base-styles' ); -const wpPostcss = require( '@wordpress/postcss-themes' )( adminColorSchemes ) -``` - -<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p> diff --git a/packages/base-styles/index.js b/packages/base-styles/index.js deleted file mode 100644 index bac5dede479a12..00000000000000 --- a/packages/base-styles/index.js +++ /dev/null @@ -1,60 +0,0 @@ -exports.adminColorSchemes = { - defaults: { - primary: '#0085ba', - secondary: '#11a0d2', - toggle: '#11a0d2', - button: '#007cba', - outlines: '#007cba', - }, - themes: { - 'admin-color-light': { - primary: '#0085ba', - secondary: '#c75726', - toggle: '#11a0d2', - button: '#0085ba', - outlines: '#007cba', - }, - 'admin-color-blue': { - primary: '#82b4cb', - secondary: '#d9ab59', - toggle: '#82b4cb', - button: '#d9ab59', - outlines: '#417e9B', - }, - 'admin-color-coffee': { - primary: '#c2a68c', - secondary: '#9fa47b', - toggle: '#c2a68c', - button: '#c2a68c', - outlines: '#59524c', - }, - 'admin-color-ectoplasm': { - primary: '#a7b656', - secondary: '#c77430', - toggle: '#a7b656', - button: '#a7b656', - outlines: '#523f6d', - }, - 'admin-color-midnight': { - primary: '#e14d43', - secondary: '#77a6b9', - toggle: '#77a6b9', - button: '#e14d43', - outlines: '#497b8d', - }, - 'admin-color-ocean': { - primary: '#a3b9a2', - secondary: '#a89d8a', - toggle: '#a3b9a2', - button: '#a3b9a2', - outlines: '#5e7d5e', - }, - 'admin-color-sunrise': { - primary: '#d1864a', - secondary: '#c8b03c', - toggle: '#c8b03c', - button: '#d1864a', - outlines: '#837425', - }, - }, -}; diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json deleted file mode 100644 index 9e54a1f0a86864..00000000000000 --- a/packages/base-styles/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "@wordpress/base-styles", - "version": "1.0.0-alpha.1", - "description": "Base SCSS utilities and variables for WordPress.", - "author": "The WordPress Contributors", - "license": "GPL-2.0-or-later", - "keywords": [ - "wordpress", - "sass", - "scss", - "css" - ], - "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/base-styles/README.md", - "repository": { - "type": "git", - "url": "https://github.com/WordPress/gutenberg.git", - "directory": "packages/base-styles" - }, - "bugs": { - "url": "https://github.com/WordPress/gutenberg/issues" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/packages/blob/package.json b/packages/blob/package.json index 4d04f47eb2a3c7..5d6682a3df85f1 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "2.5.1", + "version": "2.5.0", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 22ff8e4e8f8c2b..7c6af26534df97 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "1.0.3", + "version": "1.0.0", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -29,7 +29,6 @@ "@wordpress/data": "file:../data", "@wordpress/element": "file:../element", "@wordpress/i18n": "file:../i18n", - "@wordpress/plugins": "file:../plugins", "lodash": "^4.17.15" }, "publishConfig": { diff --git a/packages/block-directory/src/index.js b/packages/block-directory/src/index.js index 3af7027bf74d02..5c088e8d5928d3 100644 --- a/packages/block-directory/src/index.js +++ b/packages/block-directory/src/index.js @@ -2,4 +2,5 @@ * Internal dependencies */ import './store'; -import './plugins'; + +export { default as DownloadableBlocksPanel } from './components/downloadable-blocks-panel'; diff --git a/packages/block-directory/src/plugins/index.js b/packages/block-directory/src/plugins/index.js deleted file mode 100644 index 917b8567c2d87f..00000000000000 --- a/packages/block-directory/src/plugins/index.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * WordPress dependencies - */ -import { registerPlugin } from '@wordpress/plugins'; - -/** - * Internal dependencies - */ -import InserterMenuDownloadableBlocksPanel from './inserter-menu-downloadable-blocks-panel'; - -registerPlugin( 'block-directory', { - render() { - return <InserterMenuDownloadableBlocksPanel />; - }, -} ); diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 432d36a72ac70c..d9c7818065c0b5 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -82,14 +82,6 @@ _Related_ Undocumented declaration. -<a name="BlockBreadcrumb" href="#BlockBreadcrumb">#</a> **BlockBreadcrumb** - -Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. - -_Returns_ - -- `WPElement`: Block Breadcrumb. - <a name="BlockControls" href="#BlockControls">#</a> **BlockControls** Undocumented declaration. @@ -145,7 +137,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: Rendered element. <a name="BlockSelectionClearer" href="#BlockSelectionClearer">#</a> **BlockSelectionClearer** @@ -179,10 +171,6 @@ _Related_ Undocumented declaration. -<a name="ColorPaletteControl" href="#ColorPaletteControl">#</a> **ColorPaletteControl** - -Undocumented declaration. - <a name="ContrastChecker" href="#ContrastChecker">#</a> **ContrastChecker** Undocumented declaration. @@ -404,7 +392,6 @@ The default editor settings **experimentalEnableLegacyWidgetBlock boolean Whether the user has enabled the Legacy Widget Block **experimentalEnableMenuBlock boolean Whether the user has enabled the Menu Block **experimentalBlockDirectory boolean Whether the user has enabled the Block Directory - \_\_experimentalEnableFullSiteEditing boolean Whether the user has enabled Full Site Editing <a name="SkipToSelectedBlock" href="#SkipToSelectedBlock">#</a> **SkipToSelectedBlock** @@ -459,10 +446,6 @@ _Related_ - <https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/url-popover/README.md> -<a name="useBlockEditContext" href="#useBlockEditContext">#</a> **useBlockEditContext** - -Undocumented declaration. - <a name="Warning" href="#Warning">#</a> **Warning** Undocumented declaration. diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 9d9f00f675fb27..8517b2126deadd 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "3.2.3", + "version": "3.2.0", "description": "Generic block editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/src/components/autocomplete/index.native.js b/packages/block-editor/src/components/autocomplete/index.native.js deleted file mode 100644 index 461f67a0a4bcbe..00000000000000 --- a/packages/block-editor/src/components/autocomplete/index.native.js +++ /dev/null @@ -1 +0,0 @@ -export default () => null; diff --git a/packages/block-editor/src/components/block-breadcrumb/index.js b/packages/block-editor/src/components/block-breadcrumb/index.js deleted file mode 100644 index adc96ba4eb2d51..00000000000000 --- a/packages/block-editor/src/components/block-breadcrumb/index.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * WordPress dependencies - */ -import { Button } from '@wordpress/components'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import BlockTitle from '../block-title'; - -/** - * Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. - * - * @return {WPElement} Block Breadcrumb. - */ -const BlockBreadcrumb = function() { - const { selectBlock, clearSelectedBlock } = useDispatch( 'core/block-editor' ); - const { clientId, parents, hasSelection } = useSelect( ( select ) => { - const { - getSelectionStart, - getSelectedBlockClientId, - getBlockParents, - } = select( 'core/block-editor' ); - const selectedBlockClientId = getSelectedBlockClientId(); - return { - parents: getBlockParents( selectedBlockClientId ), - clientId: selectedBlockClientId, - hasSelection: !! getSelectionStart().clientId, - }; - }, [] ); - - /* - * Disable reason: The `list` ARIA role is redundant but - * Safari+VoiceOver won't announce the list otherwise. - */ - /* eslint-disable jsx-a11y/no-redundant-roles */ - return ( - <ul className="block-editor-block-breadcrumb" role="list" aria-label={ __( 'Block breadcrumb' ) }> - <li - className={ ! hasSelection ? 'block-editor-block-breadcrumb__current' : undefined } - aria-current={ ! hasSelection ? 'true' : undefined } - > - { hasSelection && ( - <Button - className="block-editor-block-breadcrumb__button" - isTertiary - onClick={ clearSelectedBlock } - > - { __( 'Document' ) } - </Button> - ) } - { ! hasSelection && __( 'Document' ) } - </li> - { parents.map( ( parentClientId ) => ( - <li key={ parentClientId }> - <Button - className="block-editor-block-breadcrumb__button" - isTertiary - onClick={ () => selectBlock( parentClientId ) } - > - <BlockTitle clientId={ parentClientId } /> - </Button> - </li> - ) ) } - { !! clientId && ( - <li className="block-editor-block-breadcrumb__current" aria-current="true"> - <BlockTitle clientId={ clientId } /> - </li> - ) } - </ul> - /* eslint-enable jsx-a11y/no-redundant-roles */ - ); -}; - -export default BlockBreadcrumb; diff --git a/packages/block-editor/src/components/block-breadcrumb/style.scss b/packages/block-editor/src/components/block-breadcrumb/style.scss deleted file mode 100644 index b20cdd273b2566..00000000000000 --- a/packages/block-editor/src/components/block-breadcrumb/style.scss +++ /dev/null @@ -1,41 +0,0 @@ -.block-editor-block-breadcrumb { - list-style: none; - padding: 0; - margin: 0; - - li { - display: inline-block; - margin: 0; - - &:not(:last-child)::after { - content: "\2192"; // This becomes →. - } - } -} - -.block-editor-block-breadcrumb__button.components-button { - height: $icon-button-size-small; - line-height: $icon-button-size-small; - padding: 0; - - &:hover { - text-decoration: underline; - } - - &:focus { - @include square-style__focus(); - outline-offset: -2px; - box-shadow: none; - } -} - -.block-editor-block-breadcrumb__current { - cursor: default; -} - -.block-editor-block-breadcrumb__button.components-button, -.block-editor-block-breadcrumb__current { - color: $dark-gray-500; - padding: 0 $grid-size; - font-size: inherit; -} diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index 08f2ac9f1dd6b1..863cdc3e5d6fa5 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -6,29 +6,19 @@ import { noop } from 'lodash'; /** * WordPress dependencies */ -import { createContext, useContext } from '@wordpress/element'; +import { createContext } from '@wordpress/element'; import { createHigherOrderComponent } from '@wordpress/compose'; -const Context = createContext( { +const { Consumer, Provider } = createContext( { name: '', isSelected: false, focusedElement: null, setFocusedElement: noop, clientId: null, } ); -const { Provider, Consumer } = Context; export { Provider as BlockEditContextProvider }; -/** - * A hook that returns the block edit context. - * - * @return {Object} Block edit context - */ -export function useBlockEditContext() { - return useContext( Context ); -} - /** * A Higher Order Component used to inject BlockEdit context to the * wrapped component. @@ -37,7 +27,7 @@ export function useBlockEditContext() { * expected to return object of props to * merge with the component's own props. * - * @return {WPComponent} Enhanced component with injected context as props. + * @return {Component} Enhanced component with injected context as props. */ export const withBlockEditContext = ( mapContextToProps ) => createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( @@ -56,9 +46,9 @@ export const withBlockEditContext = ( mapContextToProps ) => createHigherOrderCo * A Higher Order Component used to render conditionally the wrapped * component only when the BlockEdit has selected state set. * - * @param {WPComponent} OriginalComponent Component to wrap. + * @param {Component} OriginalComponent Component to wrap. * - * @return {WPComponent} Component which renders only when the BlockEdit is selected. + * @return {Component} Component which renders only when the BlockEdit is selected. */ export const ifBlockEditSelected = createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index 403a5cd87898e3..63c475a50692ff 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -12,7 +12,7 @@ import { Component } from '@wordpress/element'; * Internal dependencies */ import Edit from './edit'; -import { BlockEditContextProvider, useBlockEditContext } from './context'; +import { BlockEditContextProvider } from './context'; class BlockEdit extends Component { constructor() { @@ -44,4 +44,3 @@ class BlockEdit extends Component { } export default BlockEdit; -export { useBlockEditContext }; diff --git a/packages/block-editor/src/components/block-list/block-async-mode-provider.js b/packages/block-editor/src/components/block-list/block-async-mode-provider.js index 3cdde80050761c..aaa2e709db92c6 100644 --- a/packages/block-editor/src/components/block-list/block-async-mode-provider.js +++ b/packages/block-editor/src/components/block-list/block-async-mode-provider.js @@ -1,7 +1,10 @@ /** * WordPress dependencies */ -import { AsyncModeProvider, useSelect } from '@wordpress/data'; +import { + __experimentalAsyncModeProvider as AsyncModeProvider, + useSelect, +} from '@wordpress/data'; const BlockAsyncModeProvider = ( { children, clientId, isBlockInSelection } ) => { const isParentOfSelectedBlock = useSelect( ( select ) => { diff --git a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js index 7e09fe8de46f79..cdd54ffdcaca1b 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js +++ b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js @@ -10,23 +10,21 @@ import styles from './block-mobile-floating-toolbar.scss'; /** * WordPress dependencies */ -import { compose, withPreferredColorScheme } from '@wordpress/compose'; import { createSlotFill } from '@wordpress/components'; const { Fill, Slot } = createSlotFill( 'FloatingToolbar' ); -const FloatingToolbarFill = ( { children, getStylesFromColorScheme } ) => { +function FloatingToolbar( { children } ) { return ( <Fill> { ( { innerFloatingToolbar } ) => { - const fillStyle = getStylesFromColorScheme( styles.floatingToolbarFillColor, styles.floatingToolbarFillColorDark ); return ( <TouchableWithoutFeedback> <View // Issue: `FloatingToolbar` placed above the first item in group is not touchable on Android. // Temporary solution: Use `innerFloatingToolbar` to place `FloatingToolbar` over the first item in group. // TODO: `{ top: innerFloatingToolbar ? 0 : -44 }` along with `innerFloatingToolbar` should be removed once issue is fixed. - style={ [ fillStyle, styles.floatingToolbarFill, { top: innerFloatingToolbar ? 0 : -44 } ] } + style={ [ styles.floatingToolbarFill, { top: innerFloatingToolbar ? 0 : -44 } ] } >{ children } </View> </TouchableWithoutFeedback> @@ -35,9 +33,8 @@ const FloatingToolbarFill = ( { children, getStylesFromColorScheme } ) => { </Fill> ); -}; +} -const FloatingToolbar = compose( withPreferredColorScheme )( FloatingToolbarFill ); FloatingToolbar.Slot = Slot; export default FloatingToolbar; diff --git a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss index a9fbd1243e89ab..713633516fca23 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss +++ b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss @@ -1,4 +1,5 @@ .floatingToolbarFill { + background-color: $dark-gray-500; margin: auto; min-width: 100; max-height: $floating-toolbar-height; @@ -12,11 +13,3 @@ justify-content: center; align-self: center; } - -.floatingToolbarFillColor { - background-color: rgba(#1d2327, 0.85); -} - -.floatingToolbarFillColorDark { - background-color: rgba(#3c434a, 0.85); -} diff --git a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js b/packages/block-editor/src/components/block-list/block-mobile-toolbar.js index 8af64ec12c021b..f35a7add73641a 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js +++ b/packages/block-editor/src/components/block-list/block-mobile-toolbar.js @@ -9,11 +9,11 @@ import { ifViewportMatches } from '@wordpress/viewport'; import BlockMover from '../block-mover'; import VisualEditorInserter from '../inserter'; -function BlockMobileToolbar( { clientId, moverDirection } ) { +function BlockMobileToolbar( { clientId } ) { return ( <div className="editor-block-list__block-mobile-toolbar block-editor-block-list__block-mobile-toolbar"> <VisualEditorInserter /> - <BlockMover clientIds={ [ clientId ] } __experimentalOrientation={ moverDirection } /> + <BlockMover clientIds={ [ clientId ] } /> </div> ); } diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 48b5506e452f2f..777cb54933a80b 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -67,7 +67,6 @@ function BlockListBlock( { mode, isFocusMode, hasFixedToolbar, - moverDirection, isLocked, clientId, rootClientId, @@ -451,20 +450,6 @@ function BlockListBlock( { }; } const blockElementId = `block-${ clientId }`; - const blockMover = ( - <BlockMover - clientIds={ clientId } - blockElementId={ blockElementId } - isHidden={ ! isSelected } - isDraggable={ - isDraggable !== false && - ( ! isPartOfMultiSelection && isMovable ) - } - onDragStart={ onDragStart } - onDragEnd={ onDragEnd } - __experimentalOrientation={ moverDirection } - /> - ); // We wrap the BlockEdit component in a div that hides it when editing in // HTML mode. This allows us to render all of the ancillary pieces @@ -526,18 +511,22 @@ function BlockListBlock( { rootClientId={ rootClientId } /> { isFirstMultiSelected && ( - <BlockMultiControls - rootClientId={ rootClientId } - moverDirection={ moverDirection } - /> + <BlockMultiControls rootClientId={ rootClientId } /> ) } - <div - className={ classnames( - 'editor-block-list__block-edit block-editor-block-list__block-edit', - { 'has-mover-inside': moverDirection === 'horizontal' }, + <div className="editor-block-list__block-edit block-editor-block-list__block-edit"> + { shouldRenderMovers && ( + <BlockMover + clientIds={ clientId } + blockElementId={ blockElementId } + isHidden={ ! isSelected } + isDraggable={ + isDraggable !== false && + ( ! isPartOfMultiSelection && isMovable ) + } + onDragStart={ onDragStart } + onDragEnd={ onDragEnd } + /> ) } - > - { shouldRenderMovers && ( moverDirection === 'vertical' ) && blockMover } { shouldShowBreadcrumb && ( <BlockBreadcrumb clientId={ clientId } @@ -577,7 +566,6 @@ function BlockListBlock( { { isValid && mode === 'html' && ( <BlockHtml clientId={ clientId } /> ) } - { shouldRenderMovers && ( moverDirection === 'horizontal' ) && blockMover } { ! isValid && [ <BlockInvalidWarning key="invalid-warning" @@ -590,7 +578,7 @@ function BlockListBlock( { </BlockCrashBoundary> { !! hasError && <BlockCrashWarning /> } { shouldShowMobileToolbar && ( - <BlockMobileToolbar clientId={ clientId } moverDirection={ moverDirection } /> + <BlockMobileToolbar clientId={ clientId } /> ) } </IgnoreNestedEvents> </div> diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 70d8ff2435b907..456c5fad6ac2ab 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -25,7 +25,6 @@ import BlockEdit from '../block-edit'; import BlockInvalidWarning from './block-invalid-warning'; import BlockMobileToolbar from './block-mobile-toolbar'; import FloatingToolbar from './block-mobile-floating-toolbar'; -import Breadcrumbs from './breadcrumb'; import NavigateUpSVG from './nav-up-icon'; class BlockListBlock extends Component { @@ -137,7 +136,6 @@ class BlockListBlock extends Component { /> <View style={ styles.pipe } /> </Toolbar> - <Breadcrumbs clientId={ clientId } /> </FloatingToolbar> ) } <TouchableWithoutFeedback diff --git a/packages/block-editor/src/components/block-list/breadcrumb.js b/packages/block-editor/src/components/block-list/breadcrumb.js index b167149778843f..81f05b40bf7080 100644 --- a/packages/block-editor/src/components/block-list/breadcrumb.js +++ b/packages/block-editor/src/components/block-list/breadcrumb.js @@ -16,7 +16,7 @@ import BlockTitle from '../block-title'; * the root block. * * @param {string} props.clientId Client ID of block. - * @return {WPComponent} The component to be rendered. + * @return {WPElement} Block Breadcrumb. */ const BlockBreadcrumb = forwardRef( ( { clientId }, ref ) => { const { setNavigationMode } = useDispatch( 'core/block-editor' ); diff --git a/packages/block-editor/src/components/block-list/breadcrumb.native.js b/packages/block-editor/src/components/block-list/breadcrumb.native.js deleted file mode 100644 index 0bea56e4da6ddf..00000000000000 --- a/packages/block-editor/src/components/block-list/breadcrumb.native.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * WordPress dependencies - */ -import { Icon } from '@wordpress/components'; -import { withSelect } from '@wordpress/data'; -import { compose } from '@wordpress/compose'; -import { getBlockType } from '@wordpress/blocks'; - -/** - * External dependencies - */ -import { View, Text, TouchableOpacity } from 'react-native'; - -/** - * Internal dependencies - */ -import BlockTitle from '../block-title'; -import SubdirectorSVG from './subdirectory-icon'; - -import styles from './breadcrumb.scss'; - -const BlockBreadcrumb = ( { clientId, blockIcon, rootClientId, rootBlockIcon } ) => { - return ( - <View style={ styles.breadcrumbContainer }> - <TouchableOpacity style={ styles.button } onPress={ () => {/* Open BottomSheet with markup */} }> - { rootClientId && rootBlockIcon && ( - [ <Icon key="parent-icon" size={ 20 } icon={ rootBlockIcon.src } fill={ styles.icon.color } />, - <View key="subdirectory-icon" style={ styles.arrow }><SubdirectorSVG fill={ styles.arrow.color } /></View>, - ] - ) } - <Icon size={ 24 } icon={ blockIcon.src } fill={ styles.icon.color } /> - <Text style={ styles.breadcrumbTitle }><BlockTitle clientId={ clientId } /></Text> - </TouchableOpacity> - </View> - ); -}; - -export default compose( [ - withSelect( ( select, { clientId } ) => { - const { - getBlockRootClientId, - getBlockName, - } = select( 'core/block-editor' ); - - const blockName = getBlockName( clientId ); - const blockType = getBlockType( blockName ); - const blockIcon = blockType.icon; - - const rootClientId = getBlockRootClientId( clientId ); - - if ( ! rootClientId ) { - return { - clientId, - blockIcon, - }; - } - const rootBlockName = getBlockName( rootClientId ); - const rootBlockType = getBlockType( rootBlockName ); - const rootBlockIcon = rootBlockType.icon; - - return { - clientId, - blockIcon, - rootClientId, - rootBlockIcon, - }; - } ), -] )( BlockBreadcrumb ); diff --git a/packages/block-editor/src/components/block-list/breadcrumb.native.scss b/packages/block-editor/src/components/block-list/breadcrumb.native.scss deleted file mode 100644 index 8e9b103446291c..00000000000000 --- a/packages/block-editor/src/components/block-list/breadcrumb.native.scss +++ /dev/null @@ -1,28 +0,0 @@ -.breadcrumbContainer { - flex-direction: row; - align-items: center; - justify-content: flex-start; - padding-left: 5; - padding-right: 15; -} - -.breadcrumbTitle { - color: $white; - margin-left: 4; -} - -.icon { - color: $white; -} - -.button { - flex-direction: row; - align-items: center; -} - -.arrow { - color: $light-opacity-light-700; - margin-top: -4px; - margin-left: 4; - margin-right: 4; -} diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 54511ac941ecc4..25386d5039c12c 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -17,7 +17,7 @@ import { Component } from '@wordpress/element'; import { withSelect, withDispatch, - AsyncModeProvider, + __experimentalAsyncModeProvider as AsyncModeProvider, } from '@wordpress/data'; import { compose } from '@wordpress/compose'; @@ -195,7 +195,6 @@ class BlockList extends Component { className, blockClientIds, rootClientId, - __experimentalMoverDirection: moverDirection = 'vertical', isDraggable, selectedBlockClientId, multiSelectedBlockClientIds, @@ -228,7 +227,6 @@ class BlockList extends Component { blockRef={ this.setBlockRef } onSelectionStart={ this.onSelectionStart } isDraggable={ isDraggable } - moverDirection={ moverDirection } // This prop is explicitely computed and passed down // to avoid being impacted by the async mode diff --git a/packages/block-editor/src/components/block-list/multi-controls.js b/packages/block-editor/src/components/block-list/multi-controls.js index 2f49ca2ca0a3b4..e4dd88aeda030f 100644 --- a/packages/block-editor/src/components/block-list/multi-controls.js +++ b/packages/block-editor/src/components/block-list/multi-controls.js @@ -11,7 +11,6 @@ import BlockMover from '../block-mover'; function BlockListMultiControls( { multiSelectedBlockClientIds, isSelecting, - moverDirection, } ) { if ( isSelecting ) { return null; @@ -20,7 +19,6 @@ function BlockListMultiControls( { return ( <BlockMover clientIds={ multiSelectedBlockClientIds } - __experimentalOrientation={ moverDirection } /> ); } diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index e06667a0f914e7..761632c49d7c7f 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -101,9 +101,6 @@ .block-editor-block-list__block-edit { position: relative; - &.has-mover-inside > [data-block] { - display: flex; - } &::before { z-index: z-index(".block-editor-block-list__block-edit::before"); diff --git a/packages/block-editor/src/components/block-list/subdirectory-icon.js b/packages/block-editor/src/components/block-list/subdirectory-icon.js deleted file mode 100644 index 9da2bc4a1c88a9..00000000000000 --- a/packages/block-editor/src/components/block-list/subdirectory-icon.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * WordPress dependencies - */ -import { SVG, Path } from '@wordpress/components'; - -const Subdirectory = ( { ...extraProps } ) => ( - <SVG - xmlns="http://www.w3.org/2000/svg" - width={ 14 } - height={ 14 } - viewBox="0 0 20 20" - { ...extraProps } - > - <Path d="M19 15l-6 6-1.42-1.42L15.17 16H4V4h2v10h9.17l-3.59-3.58L13 9l6 6z" /> - </SVG> ) -; - -export default Subdirectory; diff --git a/packages/block-editor/src/components/block-mover/icons.js b/packages/block-editor/src/components/block-mover/icons.js index 2a15b8a6159d5d..06bf5601f439db 100644 --- a/packages/block-editor/src/components/block-mover/icons.js +++ b/packages/block-editor/src/components/block-mover/icons.js @@ -9,24 +9,12 @@ export const upArrow = ( </SVG> ); -export const leftArrow = ( - <SVG width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> - <Path d="M4.5 9l5.6-5.7 1.4 1.5L7.3 9l4.2 4.2-1.4 1.5L4.5 9z" /> - </SVG> -); - export const downArrow = ( <SVG width="18" height="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <Polygon points="9,13.5 14.7,7.9 13.2,6.5 9,10.7 4.8,6.5 3.3,7.9 " /> </SVG> ); -export const rightArrow = ( - <SVG width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> - <Path d="M13.5 9L7.9 3.3 6.5 4.8 10.7 9l-4.2 4.2 1.4 1.5L13.5 9z" /> - </SVG> -); - export const dragHandle = ( <SVG width="18" height="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <Path d="M13,8c0.6,0,1-0.4,1-1s-0.4-1-1-1s-1,0.4-1,1S12.4,8,13,8z M5,6C4.4,6,4,6.4,4,7s0.4,1,1,1s1-0.4,1-1S5.6,6,5,6z M5,10 diff --git a/packages/block-editor/src/components/block-mover/index.js b/packages/block-editor/src/components/block-mover/index.js index cd1f4483eceb16..dd09dc1c86b7c5 100644 --- a/packages/block-editor/src/components/block-mover/index.js +++ b/packages/block-editor/src/components/block-mover/index.js @@ -7,7 +7,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { __, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; import { IconButton } from '@wordpress/components'; import { getBlockType } from '@wordpress/blocks'; import { Component } from '@wordpress/element'; @@ -18,7 +18,7 @@ import { withInstanceId, compose } from '@wordpress/compose'; * Internal dependencies */ import { getBlockMoverDescription } from './mover-description'; -import { leftArrow, rightArrow, upArrow, downArrow, dragHandle } from './icons'; +import { upArrow, downArrow, dragHandle } from './icons'; import { IconDragHandle } from './drag-handle'; export class BlockMover extends Component { @@ -44,55 +44,24 @@ export class BlockMover extends Component { } render() { - const { onMoveUp, onMoveDown, __experimentalOrientation: orientation, isRTL, isFirst, isLast, isDraggable, onDragStart, onDragEnd, clientIds, blockElementId, blockType, firstIndex, isLocked, instanceId, isHidden, rootClientId } = this.props; + const { onMoveUp, onMoveDown, isFirst, isLast, isDraggable, onDragStart, onDragEnd, clientIds, blockElementId, blockType, firstIndex, isLocked, instanceId, isHidden, rootClientId } = this.props; const { isFocused } = this.state; const blocksCount = castArray( clientIds ).length; if ( isLocked || ( isFirst && isLast && ! rootClientId ) ) { return null; } - const getArrowIcon = ( moveDirection ) => { - if ( moveDirection === 'up' ) { - if ( orientation === 'horizontal' ) { - return isRTL ? rightArrow : leftArrow; - } - return upArrow; - } else if ( moveDirection === 'down' ) { - if ( orientation === 'horizontal' ) { - return isRTL ? leftArrow : rightArrow; - } - return downArrow; - } - return null; - }; - - const getMovementDirection = ( moveDirection ) => { - if ( moveDirection === 'up' ) { - if ( orientation === 'horizontal' ) { - return isRTL ? 'right' : 'left'; - } - return 'up'; - } else if ( moveDirection === 'down' ) { - if ( orientation === 'horizontal' ) { - return isRTL ? 'left' : 'right'; - } - return 'down'; - } - return null; - }; - // We emulate a disabled state because forcefully applying the `disabled` // attribute on the button while it has focus causes the screen to change // to an unfocused state (body as active element) without firing blur on, // the rendering parent, leaving it unable to react to focus out. return ( - <div className={ classnames( 'editor-block-mover block-editor-block-mover', { 'is-visible': isFocused || ! isHidden, 'is-horizontal': orientation === 'horizontal' } ) }> + <div className={ classnames( 'editor-block-mover block-editor-block-mover', { 'is-visible': isFocused || ! isHidden } ) }> <IconButton className="editor-block-mover__control block-editor-block-mover__control" onClick={ isFirst ? null : onMoveUp } - icon={ getArrowIcon( 'up' ) } - // translators: %s: Horizontal direction of block movement ( left, right ) - label={ sprintf( __( 'Move %s' ), getMovementDirection( 'up' ) ) } + icon={ upArrow } + label={ __( 'Move up' ) } aria-describedby={ `block-editor-block-mover__up-description-${ instanceId }` } aria-disabled={ isFirst } onFocus={ this.onFocus } @@ -110,9 +79,8 @@ export class BlockMover extends Component { <IconButton className="editor-block-mover__control block-editor-block-mover__control" onClick={ isLast ? null : onMoveDown } - icon={ getArrowIcon( 'down' ) } - // translators: %s: Horizontal direction of block movement ( left, right ) - label={ sprintf( __( 'Move %s' ), getMovementDirection( 'down' ) ) } + icon={ downArrow } + label={ __( 'Move down' ) } aria-describedby={ `block-editor-block-mover__down-description-${ instanceId }` } aria-disabled={ isLast } onFocus={ this.onFocus } @@ -127,8 +95,6 @@ export class BlockMover extends Component { isFirst, isLast, -1, - orientation, - isRTL, ) } </span> @@ -141,8 +107,6 @@ export class BlockMover extends Component { isFirst, isLast, 1, - orientation, - isRTL, ) } </span> @@ -161,17 +125,12 @@ export default compose( const blockOrder = getBlockOrder( rootClientId ); const firstIndex = getBlockIndex( firstClientId, rootClientId ); const lastIndex = getBlockIndex( last( normalizedClientIds ), rootClientId ); - const { getSettings } = select( 'core/block-editor' ); - const { - isRTL, - } = getSettings(); return { blockType: block ? getBlockType( block.name ) : null, isLocked: getTemplateLock( rootClientId ) === 'all', rootClientId, firstIndex, - isRTL, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, }; diff --git a/packages/block-editor/src/components/block-mover/mover-description.js b/packages/block-editor/src/components/block-mover/mover-description.js index d9a62de176d821..44174ce85534ca 100644 --- a/packages/block-editor/src/components/block-mover/mover-description.js +++ b/packages/block-editor/src/components/block-mover/mover-description.js @@ -14,30 +14,12 @@ import { __, _n, sprintf } from '@wordpress/i18n'; * @param {boolean} isLast This is the last block. * @param {number} dir Direction of movement (> 0 is considered to be going * down, < 0 is up). - * @param {string} orientation The orientation of the block movers, vertical or - * horizontal. - * @param {boolean} isRTL True if current writing system is right to left. * * @return {string} Label for the block movement controls. */ -export function getBlockMoverDescription( selectedCount, type, firstIndex, isFirst, isLast, dir, orientation, isRTL ) { +export function getBlockMoverDescription( selectedCount, type, firstIndex, isFirst, isLast, dir ) { const position = ( firstIndex + 1 ); - const getMovementDirection = ( moveDirection ) => { - if ( moveDirection === 'up' ) { - if ( orientation === 'horizontal' ) { - return isRTL ? 'right' : 'left'; - } - return 'up'; - } else if ( moveDirection === 'down' ) { - if ( orientation === 'horizontal' ) { - return isRTL ? 'left' : 'right'; - } - return 'down'; - } - return null; - }; - if ( selectedCount > 1 ) { return getMultiBlockMoverDescription( selectedCount, firstIndex, isFirst, isLast, dir ); } @@ -50,46 +32,35 @@ export function getBlockMoverDescription( selectedCount, type, firstIndex, isFir if ( dir > 0 && ! isLast ) { // moving down return sprintf( - // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: Direction of movement ( up, down, left, right ), 4: New position - __( 'Move %1$s block from position %2$d %3$s to position %4$d' ), + // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position + __( 'Move %1$s block from position %2$d down to position %3$d' ), type, position, - getMovementDirection( 'down' ), - ( position + 1 ), + ( position + 1 ) ); } if ( dir > 0 && isLast ) { // moving down, and is the last item - // translators: 1: Type of block (i.e. Text, Image etc), 2: Direction of movement ( up, down, left, right ) - return sprintf( - __( 'Block %1$s is at the end of the content and can’t be moved %2$s' ), - type, - getMovementDirection( 'down' ), - - ); + // translators: %s: Type of block (i.e. Text, Image etc) + return sprintf( __( 'Block %s is at the end of the content and can’t be moved down' ), type ); } if ( dir < 0 && ! isFirst ) { // moving up return sprintf( - // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: Direction of movement ( up, down, left, right ), 4: New position - __( 'Move %1$s block from position %2$d %3$s to position %4$d' ), + // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position + __( 'Move %1$s block from position %2$d up to position %3$d' ), type, position, - getMovementDirection( 'up' ), - ( position - 1 ), + ( position - 1 ) ); } if ( dir < 0 && isFirst ) { // moving up, and is the first item - // translators: 1: Type of block (i.e. Text, Image etc), 2: Direction of movement ( up, down, left, right ) - return sprintf( - __( 'Block %1$s is at the beginning of the content and can’t be moved %2$s' ), - type, - getMovementDirection( 'up' ), - ); + // translators: %s: Type of block (i.e. Text, Image etc) + return sprintf( __( 'Block %s is at the beginning of the content and can’t be moved up' ), type ); } } diff --git a/packages/block-editor/src/components/block-mover/style.scss b/packages/block-editor/src/components/block-mover/style.scss index 260d456c73d3c0..a506b3282fad42 100644 --- a/packages/block-editor/src/components/block-mover/style.scss +++ b/packages/block-editor/src/components/block-mover/style.scss @@ -1,4 +1,5 @@ .block-editor-block-mover { + @include break-small() { min-height: $empty-paragraph-height; opacity: 0; @@ -19,38 +20,13 @@ // 24px is the smallest size of a good pressable button. // With 3 pieces of side UI, that comes to a total of 72px. // To vertically center against a 56px paragraph, move upwards 72px - 56px / 2. - margin-top: -$grid-size; - } - - &.is-horizontal { - margin-top: 5px; // The height of the appender is 36px. This pushes down the mover to be centered according to that. - margin-right: $grid-size; - padding-right: 0; - min-height: auto; - width: ($icon-button-size-small * 2) + ($border-width * 2); - height: $icon-button-size-small + ($border-width * 2); - display: flex; - - .block-editor-block-mover__control { - width: $icon-button-size-small; - height: $icon-button-size-small; - - svg { - width: $icon-button-size-small; - padding: 3px; - } + // Don't do this for wide, fullwide, or mobile. + .block-editor-block-list__block:not([data-align="wide"]):not([data-align="full"]) & { + margin-top: -$grid-size; } } } -// Don't add negative vertical margin for wide, fullwide, or mobile. -// @todo: simplify this selector. -@include break-small() { - .block-editor-block-list__block:not([data-align="wide"]):not([data-align="full"]) .editor-block-mover:not(.is-horizontal) { - margin-top: 0; - } -} - // Mover icon buttons. .block-editor-block-mover__control { display: flex; diff --git a/packages/block-editor/src/components/block-navigation/list.js b/packages/block-editor/src/components/block-navigation/list.js index a0910caf5b41cc..0a34d24ff4e4b6 100644 --- a/packages/block-editor/src/components/block-navigation/list.js +++ b/packages/block-editor/src/components/block-navigation/list.js @@ -10,35 +10,12 @@ import classnames from 'classnames'; import { Button } from '@wordpress/components'; import { getBlockType } from '@wordpress/blocks'; import { __ } from '@wordpress/i18n'; -import { create, getTextContent } from '@wordpress/rich-text'; /** * Internal dependencies */ import BlockIcon from '../block-icon'; -/** - * Get the block display name, if it has one, or the block title if it doesn't. - * - * @param {Object} blockType The block type. - * @param {Object} attributes The values of the block's attributes - * - * @return {string} The display name value. - */ -function getBlockDisplayName( blockType, attributes ) { - const displayNameAttribute = blockType.__experimentalDisplayName; - - if ( ! displayNameAttribute || ! attributes[ displayNameAttribute ] ) { - return blockType.title; - } - - // Strip any formatting. - const richTextValue = create( { html: attributes[ displayNameAttribute ] } ); - const formatlessDisplayName = getTextContent( richTextValue ); - - return formatlessDisplayName; -} - export default function BlockNavigationList( { blocks, selectedBlockClientId, @@ -66,7 +43,7 @@ export default function BlockNavigationList( { onClick={ () => selectBlock( block.clientId ) } > <BlockIcon icon={ blockType.icon } showColors /> - { getBlockDisplayName( blockType, block.attributes ) } + { blockType.title } { isSelected && <span className="screen-reader-text">{ __( '(selected block)' ) }</span> } </Button> </div> diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index 00ae9233a12501..8a6692a422a6f7 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -137,7 +137,7 @@ export function BlockPreview( { blocks, viewportWidth = 700, padding, settings } * * @param {Array|Object} blocks A block instance (object) or an array of blocks to be previewed. * @param {number} viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700. - * @return {WPComponent} The component to be rendered. + * @return {WPElement} Rendered element. */ export default withSelect( ( select ) => { return { diff --git a/packages/block-editor/src/components/block-settings/container.native.js b/packages/block-editor/src/components/block-settings/container.native.js index 1b59377f29161c..c51a42b39de6d0 100644 --- a/packages/block-editor/src/components/block-settings/container.native.js +++ b/packages/block-editor/src/components/block-settings/container.native.js @@ -6,18 +6,12 @@ import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { InspectorControls } from '@wordpress/block-editor'; -/** - * Internal dependencies - */ -import styles from './container.native.scss'; - function BottomSheetSettings( { editorSidebarOpened, closeGeneralSidebar, ...props } ) { return ( <BottomSheet isVisible={ editorSidebarOpened } onClose={ closeGeneralSidebar } hideHeader - contentStyle={ styles.content } { ...props } > <InspectorControls.Slot /> diff --git a/packages/block-editor/src/components/block-settings/container.native.scss b/packages/block-editor/src/components/block-settings/container.native.scss deleted file mode 100644 index 2eed1c9e3f2d00..00000000000000 --- a/packages/block-editor/src/components/block-settings/container.native.scss +++ /dev/null @@ -1,4 +0,0 @@ -.content { - padding-left: 0; - padding-right: 0; -} diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index a6247b03d3177b..e83f34bc54eadd 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -49,8 +49,6 @@ .block-editor-block-toolbar__slot { // Required for IE11. display: inline-block; - // Fix for toolbar button misalignment on IE11 - line-height: 0; // IE11 doesn't read rules inside this query. They are applied only to modern browsers. @supports (position: sticky) { diff --git a/packages/block-editor/src/components/button-block-appender/index.js b/packages/block-editor/src/components/button-block-appender/index.js index 1cbbb5980903a2..7fd751165f5b45 100644 --- a/packages/block-editor/src/components/button-block-appender/index.js +++ b/packages/block-editor/src/components/button-block-appender/index.js @@ -6,8 +6,8 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Button, Icon, Tooltip } from '@wordpress/components'; -import { _x, sprintf } from '@wordpress/i18n'; +import { Button, Icon } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -21,31 +21,17 @@ function ButtonBlockAppender( { rootClientId, className } ) { <BlockDropZone rootClientId={ rootClientId } /> <Inserter rootClientId={ rootClientId } - renderToggle={ ( { onToggle, disabled, isOpen, blockTitle, hasSingleBlockType } ) => { - let label; - if ( hasSingleBlockType ) { - // translators: %s: the name of the block when there is only one - label = sprintf( _x( 'Add %s', 'directly add the only allowed block' ), blockTitle ); - } else { - label = _x( 'Add block', 'Generic label for block inserter button' ); - } - const isToggleButton = ! hasSingleBlockType; - return ( - <Tooltip text={ label }> - <Button - className={ classnames( className, 'block-editor-button-block-appender' ) } - onClick={ onToggle } - aria-haspopup={ isToggleButton ? 'true' : undefined } - aria-expanded={ isToggleButton ? isOpen : undefined } - disabled={ disabled } - label={ label } - > - <span className="screen-reader-text">{ label }</span> - <Icon icon="insert" /> - </Button> - </Tooltip> - ); - } } + renderToggle={ ( { onToggle, disabled, isOpen } ) => ( + <Button + className={ classnames( className, 'block-editor-button-block-appender' ) } + onClick={ onToggle } + aria-expanded={ isOpen } + disabled={ disabled } + > + <span className="screen-reader-text">{ __( 'Add Block' ) }</span> + <Icon icon="insert" /> + </Button> + ) } isAppender /> </> diff --git a/packages/block-editor/src/components/colors/index.js b/packages/block-editor/src/components/colors/index.js index cadb34a8c9aa37..f6b6fac984db89 100644 --- a/packages/block-editor/src/components/colors/index.js +++ b/packages/block-editor/src/components/colors/index.js @@ -7,4 +7,3 @@ export { createCustomColorsHOC, default as withColors, } from './with-colors'; -export { default as __experimentalUseColors } from './use-colors'; diff --git a/packages/block-editor/src/components/colors/use-colors.js b/packages/block-editor/src/components/colors/use-colors.js deleted file mode 100644 index d69ee1bdbadf9a..00000000000000 --- a/packages/block-editor/src/components/colors/use-colors.js +++ /dev/null @@ -1,226 +0,0 @@ -/** - * External dependencies - */ -import memoize from 'memize'; -import classnames from 'classnames'; -import { - camelCase, - kebabCase, - map, - startCase, -} from 'lodash'; - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { - useCallback, - useMemo, - Children, - cloneElement, -} from '@wordpress/element'; - -/** - * Internal dependencies - */ -import PanelColorSettings from '../panel-color-settings'; -import ContrastChecker from '../contrast-checker'; -import InspectorControls from '../inspector-controls'; -import { useBlockEditContext } from '../block-edit'; - -const ColorPanel = ( { - title, - colorSettings, - colorPanelProps, - contrastCheckerProps, - components, - panelChildren, -} ) => ( - <PanelColorSettings - title={ title } - initialOpen={ false } - colorSettings={ Object.values( colorSettings ) } - { ...colorPanelProps } - > - { contrastCheckerProps && - map( components, ( ( Component, key ) => ( - <ContrastChecker - key={ key } - textColor={ colorSettings[ key ].value } - { ...contrastCheckerProps } - /> - ) ) ) } - { typeof panelChildren === 'function' ? - panelChildren( components ) : - panelChildren } - </PanelColorSettings> -); -const InspectorControlsColorPanel = ( props ) => ( - <InspectorControls> - <ColorPanel { ...props } /> - </InspectorControls> -); - -export default function __experimentalUseColors( - colorConfigs, - { - panelTitle = __( 'Color Settings' ), - colorPanelProps, - contrastCheckerProps, - panelChildren, - } = { - panelTitle: __( 'Color Settings' ), - }, - deps = [] -) { - const { clientId } = useBlockEditContext(); - const { attributes, settingsColors } = useSelect( - ( select ) => { - const { getBlockAttributes, getSettings } = select( 'core/block-editor' ); - return { - attributes: getBlockAttributes( clientId ), - settingsColors: getSettings().colors, - }; - }, - [ clientId ] - ); - const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); - const setAttributes = useCallback( - ( newAttributes ) => updateBlockAttributes( clientId, newAttributes ), - [ updateBlockAttributes, clientId ] - ); - - const createComponent = useMemo( - () => - memoize( - ( name, property, className, color, colorValue, customColor ) => ( { - children, - className: componentClassName = '', - style: componentStyle = {}, - } ) => - // Clone children, setting the style property from the color configuration, - // if not already set explicitly through props. - Children.map( children, ( child ) => { - let colorStyle = {}; - if ( color ) { - colorStyle = { [ property ]: colorValue }; - } else if ( customColor ) { - colorStyle = { [ property ]: customColor }; - } - - return cloneElement( child, { - className: classnames( - componentClassName, - child.props.className, - { - [ `has-${ kebabCase( color ) }-${ kebabCase( property ) }` ]: color, - [ className || `has-${ kebabCase( name ) }` ]: color || customColor, - } - ), - style: { - ...colorStyle, - ...componentStyle, - ...( child.props.style || {} ), - }, - } ); - } ), - { maxSize: colorConfigs.length } - ), - [ colorConfigs.length ] - ); - const createSetColor = useMemo( - () => - memoize( - ( name, colors ) => ( newColor ) => { - const color = colors.find( ( _color ) => _color.color === newColor ); - setAttributes( { - [ color ? camelCase( `custom ${ name }` ) : name ]: undefined, - } ); - setAttributes( { - [ color ? name : camelCase( `custom ${ name }` ) ]: color ? - color.slug : - newColor, - } ); - }, - { - maxSize: colorConfigs.length, - } - ), - [ setAttributes, colorConfigs.length ] - ); - - return useMemo( () => { - const colorSettings = {}; - - const components = colorConfigs.reduce( ( acc, colorConfig ) => { - if ( typeof colorConfig === 'string' ) { - colorConfig = { name: colorConfig }; - } - const { - name, // E.g. 'backgroundColor'. - property = name, // E.g. 'backgroundColor'. - className, - - panelLabel = startCase( name ), // E.g. 'Background Color'. - componentName = panelLabel.replace( /\s/g, '' ), // E.g. 'BackgroundColor'. - - color = colorConfig.color, - colors = settingsColors, - } = { - ...colorConfig, - color: attributes[ colorConfig.name ], - }; - - // We memoize the non-primitives to avoid unnecessary updates - // when they are used as props for other components. - const _color = colors.find( ( __color ) => __color.slug === color ); - acc[ componentName ] = createComponent( - name, - property, - className, - color, - _color && _color.color, - attributes[ camelCase( `custom ${ name }` ) ] - ); - acc[ componentName ].displayName = componentName; - acc[ componentName ].color = color; - acc[ componentName ].setColor = createSetColor( name, colors ); - - colorSettings[ componentName ] = { - value: _color ? - _color.color : - attributes[ camelCase( `custom ${ name }` ) ], - onChange: acc[ componentName ].setColor, - label: panelLabel, - colors, - }; - // These settings will be spread over the `colors` in - // `colorPanelProps`, so we need to unset the key here, - // if not set to an actual value, to avoid overwriting - // an actual value in `colorPanelProps`. - if ( ! colors ) { - delete colorSettings[ componentName ].colors; - } - - return acc; - }, {} ); - - const wrappedColorPanelProps = { - title: panelTitle, - colorSettings, - colorPanelProps, - contrastCheckerProps, - components, - panelChildren, - }; - return { - ...components, - ColorPanel: <ColorPanel { ...wrappedColorPanelProps } />, - InspectorControlsColorPanel: ( - <InspectorControlsColorPanel { ...wrappedColorPanelProps } /> - ), - }; - }, [ attributes, setAttributes, ...deps ] ); -} diff --git a/packages/block-editor/src/components/colors/with-colors.js b/packages/block-editor/src/components/colors/with-colors.js index 4544c6c8c49e1e..b6f33b1b8590f7 100644 --- a/packages/block-editor/src/components/colors/with-colors.js +++ b/packages/block-editor/src/components/colors/with-colors.js @@ -49,7 +49,7 @@ const withEditorColorPalette = () => withSelect( ( select ) => { * @param {Array} colorTypes An array of color types (e.g. 'backgroundColor, borderColor). * @param {Function} withColorPalette A HOC for injecting the 'colors' prop into the WrappedComponent. * - * @return {WPComponent} The component that can be used as a HOC. + * @return {Component} The component that can be used as a HOC. */ function createColorHOC( colorTypes, withColorPalette ) { const colorMap = reduce( colorTypes, ( colorObject, colorType ) => { diff --git a/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap index 08a0f7df9efe74..9a09dae0d47674 100644 --- a/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap +++ b/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap @@ -29,7 +29,7 @@ exports[`DefaultBlockAppender should append a default block when input focused 1 rows={1} value="Start writing or type / to choose a block" /> - <WithSelect(WithDispatch(IfCondition(Inserter))) + <WithSelect(IfCondition(Inserter)) isAppender={true} position="top right" /> @@ -53,7 +53,7 @@ exports[`DefaultBlockAppender should match snapshot 1`] = ` rows={1} value="Start writing or type / to choose a block" /> - <WithSelect(WithDispatch(IfCondition(Inserter))) + <WithSelect(IfCondition(Inserter)) isAppender={true} position="top right" /> @@ -77,7 +77,7 @@ exports[`DefaultBlockAppender should optionally show without prompt 1`] = ` rows={1} value="" /> - <WithSelect(WithDispatch(IfCondition(Inserter))) + <WithSelect(IfCondition(Inserter)) isAppender={true} position="top right" /> diff --git a/packages/block-editor/src/components/gradient-picker/control.js b/packages/block-editor/src/components/gradient-picker/control.js index a0eeecc6facc25..73609ffdf17e27 100644 --- a/packages/block-editor/src/components/gradient-picker/control.js +++ b/packages/block-editor/src/components/gradient-picker/control.js @@ -3,27 +3,19 @@ * External dependencies */ import classnames from 'classnames'; -import { isEmpty } from 'lodash'; /** * WordPress dependencies */ import { BaseControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import GradientPicker from './'; -export default function( { className, label = __( 'Gradient Presets' ), ...props } ) { - const gradients = useSelect( ( select ) => ( - select( 'core/block-editor' ).getSettings().gradients - ) ); - if ( isEmpty( gradients ) ) { - return null; - } +export default function( { className, ...props } ) { return ( <BaseControl className={ classnames( @@ -32,11 +24,10 @@ export default function( { className, label = __( 'Gradient Presets' ), ...props ) } > <BaseControl.VisualLabel> - { label } + { __( 'Gradient Presets' ) } </BaseControl.VisualLabel> <GradientPicker className="block-editor-gradient-picker-control__gradient-picker-presets" - gradients={ gradients } { ...props } /> </BaseControl> diff --git a/packages/block-editor/src/components/gradient-picker/panel.js b/packages/block-editor/src/components/gradient-picker/panel.js deleted file mode 100644 index 2be91125cbc110..00000000000000 --- a/packages/block-editor/src/components/gradient-picker/panel.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * External dependencies - */ -import { isEmpty } from 'lodash'; - -/** - * WordPress dependencies - */ -import { useSelect } from '@wordpress/data'; -import { PanelBody } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import GradientPicker from './control'; - -export default function GradientPanel( props ) { - const gradients = useSelect( ( select ) => ( - select( 'core/block-editor' ).getSettings().gradients - ) ); - if ( isEmpty( gradients ) ) { - return null; - } - return ( - <PanelBody title={ __( 'Gradient' ) }> - <GradientPicker - { ...props } - /> - </PanelBody> - ); -} diff --git a/packages/block-editor/src/components/gradients/index.js b/packages/block-editor/src/components/gradients/index.js deleted file mode 100644 index b08be314861e03..00000000000000 --- a/packages/block-editor/src/components/gradients/index.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * External dependencies - */ -import { find } from 'lodash'; - -/** - * WordPress dependencies - */ -import { useCallback } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { useBlockEditContext } from '../block-edit'; - -export function __experimentalGetGradientClass( gradientSlug ) { - if ( ! gradientSlug ) { - return undefined; - } - return `has-${ gradientSlug }-gradient-background`; -} - -function getGradientValueBySlug( gradients, slug ) { - const gradient = find( gradients, [ 'slug', slug ] ); - return gradient && gradient.gradient; -} - -function getGradientSlugByValue( gradients, value ) { - const gradient = find( gradients, [ 'gradient', value ] ); - return gradient && gradient.slug; -} - -export function __experimentalUseGradient( { - gradientAttribute = 'gradient', - customGradientAttribute = 'customGradient', -} = {} ) { - const { clientId } = useBlockEditContext(); - - const { gradients, gradient, customGradient } = useSelect( ( select ) => { - const { getBlockAttributes, getSettings } = select( 'core/block-editor' ); - const attributes = getBlockAttributes( clientId ); - return { - gradient: attributes[ gradientAttribute ], - customGradient: attributes[ customGradientAttribute ], - gradients: getSettings().gradients, - }; - }, [ clientId ] ); - - const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); - const setGradient = useCallback( - ( newGradientValue ) => { - const slug = getGradientSlugByValue( gradients, newGradientValue ); - if ( slug ) { - updateBlockAttributes( clientId, { - [ gradientAttribute ]: slug, - [ customGradientAttribute ]: undefined, - } ); - return; - } - updateBlockAttributes( clientId, { - [ gradientAttribute ]: undefined, - [ customGradientAttribute ]: newGradientValue, - } ); - }, - [ gradients, clientId, updateBlockAttributes ] - ); - - const gradientClass = __experimentalGetGradientClass( gradient ); - let gradientValue; - if ( gradient ) { - gradientValue = getGradientValueBySlug( gradients, gradient ); - } else { - gradientValue = customGradient; - } - return { gradientClass, gradientValue, setGradient }; -} diff --git a/packages/block-editor/src/components/ignore-nested-events/index.js b/packages/block-editor/src/components/ignore-nested-events/index.js index 92bbe5ed44c639..2592ba3abd0527 100644 --- a/packages/block-editor/src/components/ignore-nested-events/index.js +++ b/packages/block-editor/src/components/ignore-nested-events/index.js @@ -20,7 +20,7 @@ import { Component, forwardRef, createElement } from '@wordpress/element'; * element should stop propagation but not invoke a callback handler, since it * would be assumed these are invoked by the child element. * - * @type {WPComponent} + * @type {Component} */ export class IgnoreNestedEvents extends Component { constructor() { diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 9b094396d9d8b0..6e9bb592378678 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -3,14 +3,12 @@ */ export * from './colors'; -export * from './gradients'; export * from './font-sizes'; export { default as AlignmentToolbar } from './alignment-toolbar'; export { default as Autocomplete } from './autocomplete'; export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; -export { default as BlockBreadcrumb } from './block-breadcrumb'; export { default as BlockControls } from './block-controls'; -export { default as BlockEdit, useBlockEditContext } from './block-edit'; +export { default as BlockEdit } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; export { default as BlockIcon } from './block-icon'; export { default as BlockNavigationDropdown } from './block-navigation/dropdown'; @@ -18,15 +16,12 @@ export { default as __experimentalBlockNavigationList } from './block-navigation export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar'; export { default as ButtonBlockerAppender } from './button-block-appender'; export { default as ColorPalette } from './color-palette'; -export { default as ColorPaletteControl } from './color-palette/control'; export { default as ContrastChecker } from './contrast-checker'; export { default as __experimentalGradientPicker } from './gradient-picker'; export { default as __experimentalGradientPickerControl } from './gradient-picker/control'; -export { default as __experimentalGradientPickerPanel } from './gradient-picker/panel'; export { default as InnerBlocks } from './inner-blocks'; export { default as InspectorAdvancedControls } from './inspector-advanced-controls'; export { default as InspectorControls } from './inspector-controls'; -export { default as __experimentalLinkControl } from './link-control'; export { default as MediaPlaceholder } from './media-placeholder'; export { default as MediaUpload } from './media-upload'; export { default as MediaUploadCheck } from './media-upload/check'; diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index 6baafd5d8f0bbe..b278e29d4555a9 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -1,7 +1,6 @@ // Block Creation Components -export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; export { default as BlockControls } from './block-controls'; -export { default as BlockEdit, useBlockEditContext } from './block-edit'; +export { default as BlockEdit } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; export { default as BlockIcon } from './block-icon'; export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar'; diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index ed147bfe736adf..35e1bf10b47ca2 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -107,7 +107,6 @@ class InnerBlocks extends Component { hasOverlay, renderAppender, template, - __experimentalMoverDirection: moverDirection, __experimentalTemplateOptions: templateOptions, __experimentalOnSelectTemplateOption: onSelectTemplateOption, __experimentalAllowTemplateOptionSkip: allowTemplateOptionSkip, @@ -132,7 +131,6 @@ class InnerBlocks extends Component { <BlockList rootClientId={ clientId } renderAppender={ renderAppender } - __experimentalMoverDirection={ moverDirection } /> ) } </div> diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index b9fd9dead4b377..5abb1ae4ef9230 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -1,46 +1,29 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; /** * WordPress dependencies */ -import { __, _x, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; import { Dropdown, IconButton } from '@wordpress/components'; import { Component } from '@wordpress/element'; -import { withDispatch, withSelect } from '@wordpress/data'; +import { withSelect } from '@wordpress/data'; import { compose, ifCondition } from '@wordpress/compose'; -import { - createBlock, - getBlockType, -} from '@wordpress/blocks'; /** * Internal dependencies */ import InserterMenu from './menu'; -const defaultRenderToggle = ( { onToggle, disabled, isOpen, blockTitle, hasSingleBlockType } ) => { - let label; - if ( hasSingleBlockType ) { - // translators: %s: the name of the block when there is only one - label = sprintf( _x( 'Add %s', 'directly add the only allowed block' ), blockTitle ); - } else { - label = _x( 'Add block', 'Generic label for block inserter button' ); - } - return ( - <IconButton - icon="insert" - label={ label } - labelPosition="bottom" - onClick={ onToggle } - className="editor-inserter__toggle block-editor-inserter__toggle" - aria-haspopup={ ! hasSingleBlockType ? 'true' : false } - aria-expanded={ ! hasSingleBlockType ? isOpen : false } - disabled={ disabled } - /> - ); -}; +const defaultRenderToggle = ( { onToggle, disabled, isOpen } ) => ( + <IconButton + icon="insert" + label={ __( 'Add block' ) } + labelPosition="bottom" + onClick={ onToggle } + className="editor-inserter__toggle block-editor-inserter__toggle" + aria-haspopup="true" + aria-expanded={ isOpen } + disabled={ disabled } + /> +); class Inserter extends Component { constructor() { @@ -73,12 +56,10 @@ class Inserter extends Component { renderToggle( { onToggle, isOpen } ) { const { disabled, - blockTitle, - hasSingleBlockType, renderToggle = defaultRenderToggle, } = this.props; - return renderToggle( { onToggle, isOpen, disabled, blockTitle, hasSingleBlockType } ); + return renderToggle( { onToggle, isOpen, disabled } ); } /** @@ -105,10 +86,8 @@ class Inserter extends Component { } render() { - const { position, hasSingleBlockType, insertOnlyAllowedBlock } = this.props; - if ( hasSingleBlockType ) { - return this.renderToggle( { onToggle: insertOnlyAllowedBlock } ); - } + const { position } = this.props; + return ( <Dropdown className="editor-inserter block-editor-inserter" @@ -126,71 +105,10 @@ class Inserter extends Component { export default compose( [ withSelect( ( select, { rootClientId } ) => { - const { - hasInserterItems, - __experimentalGetAllowedBlocks, - } = select( 'core/block-editor' ); - - const allowedBlocks = __experimentalGetAllowedBlocks( rootClientId ); + const { hasInserterItems } = select( 'core/block-editor' ); - const hasSingleBlockType = allowedBlocks && ( get( allowedBlocks, [ 'length' ], 0 ) === 1 ); - let allowedBlockType = false; - if ( hasSingleBlockType ) { - allowedBlockType = getBlockType( allowedBlocks ); - } return { hasItems: hasInserterItems( rootClientId ), - hasSingleBlockType, - blockTitle: allowedBlockType ? allowedBlockType.title : '', - allowedBlockType, - }; - } ), - withDispatch( ( dispatch, ownProps, { select } ) => { - return { - insertOnlyAllowedBlock() { - const { rootClientId, clientId, isAppender, destinationRootClientId } = ownProps; - const { - hasSingleBlockType, - allowedBlockType, - } = ownProps; - - if ( ! hasSingleBlockType ) { - return; - } - - function getInsertionIndex() { - const { - getBlockIndex, - getBlockSelectionEnd, - getBlockOrder, - } = select( 'core/block-editor' ); - - // If the clientId is defined, we insert at the position of the block. - if ( clientId ) { - return getBlockIndex( clientId, destinationRootClientId ); - } - - // If there a selected block, we insert after the selected block. - const end = getBlockSelectionEnd(); - if ( ! isAppender && end ) { - return getBlockIndex( end, destinationRootClientId ) + 1; - } - - // Otherwise, we insert at the end of the current rootClientId - return getBlockOrder( destinationRootClientId ).length; - } - - const { - insertBlock, - } = dispatch( 'core/block-editor' ); - - const blockToInsert = createBlock( allowedBlockType.name ); - insertBlock( - blockToInsert, - getInsertionIndex(), - rootClientId - ); - }, }; } ), ifCondition( ( { hasItems } ) => hasItems ), diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md deleted file mode 100644 index e21c29974301b1..00000000000000 --- a/packages/block-editor/src/components/link-control/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Link Control - -## Props - -### className - -- Type: `String` -- Required: Yes - -### currentLink - -- Type: `Object` -- Required: Yes - -### currentSettings - -- Type: `Object` -- Required: Yes - -### fetchSearchSuggestions - -- Type: `Function` -- Required: No - -## Event handlers - -### onClose - -- Type: `Function` -- Required: No - -### onKeyDown - -- Type: `Function` -- Required: No - -### onKeyPress - -- Type: `Function` -- Required: No - -### onLinkChange - -- Type: `Function` -- Required: No - -### onSettingChange - -- Type: `Function` -- Required: No diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js deleted file mode 100644 index afe72df4f2e93d..00000000000000 --- a/packages/block-editor/src/components/link-control/index.js +++ /dev/null @@ -1,249 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { isFunction, noop, startsWith } from 'lodash'; - -/** - * WordPress dependencies - */ -import { - Button, - ExternalLink, - Popover, -} from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; - -import { - useCallback, - useState, - useEffect, - Fragment, -} from '@wordpress/element'; - -import { - safeDecodeURI, - filterURLForDisplay, - isURL, - prependHTTP, - getProtocol, -} from '@wordpress/url'; - -import { withInstanceId, compose } from '@wordpress/compose'; -import { withSelect } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import LinkControlSettingsDrawer from './settings-drawer'; -import LinkControlSearchItem from './search-item'; -import LinkControlSearchInput from './search-input'; - -function LinkControl( { - className, - currentLink, - currentSettings, - fetchSearchSuggestions, - instanceId, - onClose = noop, - onKeyDown = noop, - onKeyPress = noop, - onLinkChange = noop, - onSettingsChange = { noop }, -} ) { - // State - const [ inputValue, setInputValue ] = useState( '' ); - const [ isEditingLink, setIsEditingLink ] = useState( false ); - - // Effects - useEffect( () => { - // If we have a link then stop editing mode - if ( currentLink ) { - setIsEditingLink( false ); - } else { - setIsEditingLink( true ); - } - }, [ currentLink ] ); - - // Handlers - - /** - * onChange LinkControlSearchInput event handler - * - * @param {string} value Current value returned by the search. - */ - const onInputChange = ( value = '' ) => { - setInputValue( value ); - }; - - // Utils - const startEditMode = () => { - if ( isFunction( onLinkChange ) ) { - onLinkChange(); - } - }; - - const closeLinkUI = () => { - resetInput(); - onClose(); - }; - - const resetInput = () => { - setInputValue( '' ); - }; - - const handleDirectEntry = ( value ) => { - let type = 'URL'; - - const protocol = getProtocol( value ) || ''; - - if ( protocol.includes( 'mailto' ) ) { - type = 'mailto'; - } - - if ( protocol.includes( 'tel' ) ) { - type = 'tel'; - } - - if ( startsWith( value, '#' ) ) { - type = 'internal'; - } - - return Promise.resolve( - [ { - id: '-1', - title: value, - url: type === 'URL' ? prependHTTP( value ) : value, - type, - } ] - ); - }; - - const handleEntitySearch = async ( value ) => { - const results = await Promise.all( [ - fetchSearchSuggestions( value ), - handleDirectEntry( value ), - ] ); - - const couldBeURL = ! value.includes( ' ' ); - - // If it's potentially a URL search then concat on a URL search suggestion - // just for good measure. That way once the actual results run out we always - // have a URL option to fallback on. - return couldBeURL ? results[ 0 ].concat( results[ 1 ] ) : results[ 0 ]; - }; - - // Effects - const getSearchHandler = useCallback( ( value ) => { - const protocol = getProtocol( value ) || ''; - const isMailto = protocol.includes( 'mailto' ); - const isInternal = startsWith( value, '#' ); - const isTel = protocol.includes( 'tel' ); - - const handleManualEntry = isInternal || isMailto || isTel || isURL( value ) || ( value && value.includes( 'www.' ) ); - - return ( handleManualEntry ) ? handleDirectEntry( value ) : handleEntitySearch( value ); - }, [ handleDirectEntry, fetchSearchSuggestions ] ); - - // Render Components - const renderSearchResults = ( { suggestionsListProps, buildSuggestionItemProps, suggestions, selectedSuggestion, isLoading } ) => { - const resultsListClasses = classnames( 'block-editor-link-control__search-results', { - 'is-loading': isLoading, - } ); - - const manualLinkEntryTypes = [ 'url', 'mailto', 'tel', 'internal' ]; - - return ( - <div className="block-editor-link-control__search-results-wrapper"> - <div { ...suggestionsListProps } className={ resultsListClasses }> - { suggestions.map( ( suggestion, index ) => ( - <LinkControlSearchItem - key={ `${ suggestion.id }-${ suggestion.type }` } - itemProps={ buildSuggestionItemProps( suggestion, index ) } - suggestion={ suggestion } - onClick={ () => onLinkChange( suggestion ) } - isSelected={ index === selectedSuggestion } - isURL={ manualLinkEntryTypes.includes( suggestion.type.toLowerCase() ) } - searchTerm={ inputValue } - /> - ) ) } - </div> - </div> - ); - }; - - return ( - <Popover - className={ classnames( 'block-editor-link-control', className ) } - onClose={ closeLinkUI } - position="bottom center" - focusOnMount="firstElement" - > - <div className="block-editor-link-control__popover-inner"> - <div className="block-editor-link-control__search"> - - { ( ! isEditingLink && currentLink ) && ( - <Fragment> - <p className="screen-reader-text" id={ `current-link-label-${ instanceId }` }> - { __( 'Currently selected' ) }: - </p> - <div - aria-labelledby={ `current-link-label-${ instanceId }` } - aria-selected="true" - className={ classnames( 'block-editor-link-control__search-item', { - 'is-current': true, - } ) } - > - <span className="block-editor-link-control__search-item-header"> - - <ExternalLink - className="block-editor-link-control__search-item-title" - href={ currentLink.url } - > - { currentLink.title } - </ExternalLink> - <span className="block-editor-link-control__search-item-info">{ filterURLForDisplay( safeDecodeURI( currentLink.url ) ) || '' }</span> - </span> - - <Button isDefault onClick={ startEditMode } className="block-editor-link-control__search-item-action block-editor-link-control__search-item-action--edit"> - { __( 'Change' ) } - </Button> - </div> - </Fragment> - ) } - - { isEditingLink && ( - <LinkControlSearchInput - value={ inputValue } - onChange={ onInputChange } - onSelect={ onLinkChange } - renderSuggestions={ renderSearchResults } - fetchSuggestions={ getSearchHandler } - onReset={ resetInput } - onKeyDown={ onKeyDown } - onKeyPress={ onKeyPress } - /> - ) } - - { ! isEditingLink && ( - <LinkControlSettingsDrawer settings={ currentSettings } onSettingChange={ onSettingsChange } /> - ) } - </div> - </div> - </Popover> - ); -} - -export default compose( - withInstanceId, - withSelect( ( select, ownProps ) => { - if ( ownProps.fetchSearchSuggestions && isFunction( ownProps.fetchSearchSuggestions ) ) { - return; - } - - const { getSettings } = select( 'core/block-editor' ); - return { - fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions, - }; - } ) -)( LinkControl ); diff --git a/packages/block-editor/src/components/link-control/search-input.js b/packages/block-editor/src/components/link-control/search-input.js deleted file mode 100644 index 84fd5db8359363..00000000000000 --- a/packages/block-editor/src/components/link-control/search-input.js +++ /dev/null @@ -1,69 +0,0 @@ - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { IconButton } from '@wordpress/components'; -import { ENTER } from '@wordpress/keycodes'; - -/** - * Internal dependencies - */ -import { URLInput } from '../'; - -const LinkControlSearchInput = ( { - value, - onChange, - onSelect, - renderSuggestions, - fetchSuggestions, - onReset, - onKeyDown, - onKeyPress, -} ) => { - const selectItemHandler = ( selection, suggestion ) => { - onChange( selection ); - - if ( suggestion ) { - onSelect( suggestion ); - } - }; - - const stopFormEventsPropagation = ( event ) => { - event.preventDefault(); - event.stopPropagation(); - }; - - return ( - <form onSubmit={ stopFormEventsPropagation }> - <URLInput - className="block-editor-link-control__search-input" - value={ value } - onChange={ selectItemHandler } - onKeyDown={ ( event ) => { - if ( event.keyCode === ENTER ) { - return; - } - onKeyDown( event ); - } } - onKeyPress={ onKeyPress } - placeholder={ __( 'Search or type url' ) } - __experimentalRenderSuggestions={ renderSuggestions } - __experimentalFetchLinkSuggestions={ fetchSuggestions } - __experimentalHandleURLSuggestions={ true } - /> - - <IconButton - disabled={ ! value.length } - type="reset" - label={ __( 'Reset' ) } - icon="no-alt" - className="block-editor-link-control__search-reset" - onClick={ onReset } - /> - - </form> - ); -}; - -export default LinkControlSearchInput; diff --git a/packages/block-editor/src/components/link-control/search-item.js b/packages/block-editor/src/components/link-control/search-item.js deleted file mode 100644 index 432b4bb3dff17a..00000000000000 --- a/packages/block-editor/src/components/link-control/search-item.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - -/** - * Internal dependencies - */ -import TextHighlight from './text-highlight'; - -/** - * WordPress dependencies - */ -import { safeDecodeURI } from '@wordpress/url'; -import { __ } from '@wordpress/i18n'; - -import { - Icon, -} from '@wordpress/components'; - -export const LinkControlSearchItem = ( { itemProps, suggestion, isSelected = false, onClick, isURL = false, searchTerm = '' } ) => { - return ( - <button - { ...itemProps } - onClick={ onClick } - className={ classnames( 'block-editor-link-control__search-item', { - 'is-selected': isSelected, - 'is-url': isURL, - 'is-entity': ! isURL, - } ) } - > - { isURL && ( - <Icon className="block-editor-link-control__search-item-icon" icon="admin-site-alt3" /> - ) } - <span className="block-editor-link-control__search-item-header"> - <span className="block-editor-link-control__search-item-title"> - <TextHighlight text={ suggestion.title } highlight={ searchTerm } /> - </span> - <span aria-hidden={ ! isURL } className="block-editor-link-control__search-item-info"> - { ! isURL && ( safeDecodeURI( suggestion.url ) || '' ) } - { isURL && ( - __( 'Press ENTER to add this link' ) - ) } - </span> - </span> - { suggestion.type && ( - <span className="block-editor-link-control__search-item-type">{ suggestion.type }</span> - ) } - </button> - ); -}; - -export default LinkControlSearchItem; - diff --git a/packages/block-editor/src/components/link-control/settings-drawer.js b/packages/block-editor/src/components/link-control/settings-drawer.js deleted file mode 100644 index 372426e4e821ff..00000000000000 --- a/packages/block-editor/src/components/link-control/settings-drawer.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * External dependencies - */ -import { partial } from 'lodash'; - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { - ToggleControl, -} from '@wordpress/components'; - -const LinkControlSettingsDrawer = ( { settings, onSettingChange } ) => { - if ( ! settings || settings.length ) { - return null; - } - - return ( - <div className="block-editor-link-control__settings"> - <ToggleControl - label={ __( 'Open in New Tab' ) } - onChange={ partial( onSettingChange, 'new-tab' ) } - checked={ settings[ 'new-tab' ] } /> - </div> - ); -}; - -export default LinkControlSettingsDrawer; diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss deleted file mode 100644 index 69f87d79fdfe3d..00000000000000 --- a/packages/block-editor/src/components/link-control/style.scss +++ /dev/null @@ -1,202 +0,0 @@ -.block-editor-link-control__search { - position: relative; - min-width: $modal-min-width; -} - -.block-editor-link-control__search .block-editor-link-control__search-input { - // Specificity overide - &.block-editor-link-control__search-input > input[type="text"] { - width: calc(100% - #{$grid-size-large*2}); - display: block; - padding: 11px $grid-size-large; - margin: $grid-size-large; - padding-right: 38px; // width of reset button - position: relative; - z-index: 1; - border: 1px solid #e1e1e1; - border-radius: $radius-round-rectangle; - - /* Fonts smaller than 16px causes mobile safari to zoom. */ - font-size: $mobile-text-min-font-size; - - @include break-small { - font-size: $default-font-size; - } - - &:focus { - @include input-style__focus(); - } - } -} - -.block-editor-link-control__search-reset { - position: absolute; - top: 19px; // has to be hard coded as form expands with search suggestions - right: 19px; // push away to avoid focus style obscuring input border - z-index: 10; -} - -.block-editor-link-control__search-results-wrapper { - position: relative; - margin-top: -$grid-size-large + 1px; - - &::before, - &::after { - content: ""; - position: absolute; - left: -1px; - right: $grid-size-large; // avoid overlaying scrollbars - display: block; - pointer-events: none; - z-index: 100; - } - - &::before { - height: $grid-size-large/2; - top: -1px; - bottom: auto; - background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); - } - - &::after { - height: 20px; - bottom: -1px; - top: auto; - background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%); - } -} - -.block-editor-link-control__search-results { - margin: 0; - padding: $grid-size-large/2 $grid-size-large; - max-height: 200px; - overflow-y: scroll; // allow results list to scroll - - &.is-loading { - opacity: 0.2; - } -} - -.block-editor-link-control__search-item { - position: relative; - display: flex; - align-items: center; - font-size: $default-font-size; - cursor: pointer; - background: $white; - width: 100%; - border: none; - text-align: left; - padding: 10px 15px; - border-radius: 5px; - - &:hover, - &:focus { - background-color: #e9e9e9; - } - - &.is-selected { - background: #f2f2f2; - - .block-editor-link-control__search-item-type { - background: #fff; - } - } - - &.is-current { - background: transparent; - border: 0; - width: 100%; - cursor: default; - padding: $grid-size-large; - padding-left: $grid-size-xlarge; - } - - .block-editor-link-control__search-item-header { - display: block; - margin-right: $grid-size-xlarge; - } - - .block-editor-link-control__search-item-icon { - margin-right: 1em; - min-width: 24px; - } - - .block-editor-link-control__search-item-info, - .block-editor-link-control__search-item-title { - text-overflow: ellipsis; - max-width: 230px; - overflow: hidden; - white-space: nowrap; - } - - .block-editor-link-control__search-item-title { - display: block; - margin-bottom: 0.2em; - font-weight: 500; - - mark { - font-weight: 700; - color: #000; - background-color: transparent; - } - - span { - font-weight: normal; - } - } - - .block-editor-link-control__search-item-info { - display: block; - color: #999; - font-size: 0.9em; - line-height: 1.3; - } - - .block-editor-link-control__search-item-type { - display: block; - padding: 3px 8px; - margin-left: auto; - font-size: 0.9em; - background-color: #f3f4f5; - border-radius: 2px; - } -} - -// Specificity overide -.block-editor-link-control__search-results div[role="menu"] > .block-editor-link-control__search-item.block-editor-link-control__search-item { - padding: 10px; -} - -.block-editor-link-control__settings { - border-top: 1px solid #e1e1e1; - margin: 0; - padding: $grid-size-large $grid-size-xlarge; - - :last-child { - margin-bottom: 0; - } -} - -.block-editor-link-control .block-editor-link-control__search-input .components-spinner { - display: block; - z-index: 100; - float: none; - - &.components-spinner { // Specificity overide - position: absolute; - top: 70px; - left: 50%; - right: auto; - bottom: auto; - margin: 0 auto 16px auto; - transform: translateX(-50%); - } - - -} - -.block-editor-link-control__search-item-action { - margin-left: auto; // push to far right hand side - flex-shrink: 0; -} diff --git a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap deleted file mode 100644 index df68c094eabc63..00000000000000 --- a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Basic rendering should display with required props 1`] = `"<span><div tabindex=\\"-1\\"><div><div><div class=\\"components-popover block-editor-link-control is-bottom is-center components-animate__appear is-from-top\\" style=\\"\\"><div class=\\"components-popover__content\\" tabindex=\\"-1\\"><div class=\\"block-editor-link-control__popover-inner\\"><div class=\\"block-editor-link-control__search\\"><form><div class=\\"editor-url-input block-editor-url-input block-editor-link-control__search-input\\"><input type=\\"text\\" aria-label=\\"URL\\" required=\\"\\" placeholder=\\"Search or type url\\" role=\\"combobox\\" aria-expanded=\\"false\\" aria-autocomplete=\\"list\\" aria-owns=\\"block-editor-url-input-suggestions-0\\" value=\\"\\"></div><button type=\\"reset\\" disabled=\\"\\" aria-label=\\"Reset\\" class=\\"components-button components-icon-button block-editor-link-control__search-reset\\"><svg aria-hidden=\\"true\\" role=\\"img\\" focusable=\\"false\\" class=\\"dashicon dashicons-no-alt\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"20\\" height=\\"20\\" viewBox=\\"0 0 20 20\\"><path d=\\"M14.95 6.46L11.41 10l3.54 3.54-1.41 1.41L10 11.42l-3.53 3.53-1.42-1.42L8.58 10 5.05 6.47l1.42-1.42L10 8.58l3.54-3.53z\\"></path></svg></button></form></div></div></div></div></div></div></div></span>"`; diff --git a/packages/block-editor/src/components/link-control/test/fixtures/index.js b/packages/block-editor/src/components/link-control/test/fixtures/index.js deleted file mode 100644 index fc974749c982b1..00000000000000 --- a/packages/block-editor/src/components/link-control/test/fixtures/index.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * External dependencies - */ -import { uniqueId } from 'lodash'; - -export const fauxEntitySuggestions = [ - { - id: uniqueId(), - title: 'Hello Page', - type: 'Page', - info: '2 days ago', - url: `?p=${ uniqueId() }`, - }, - { - id: uniqueId(), - title: 'Hello Post', - type: 'Post', - info: '19 days ago', - url: `?p=${ uniqueId() }`, - }, - { - id: uniqueId(), - title: 'Hello Another One', - type: 'Page', - info: '19 days ago', - url: `?p=${ uniqueId() }`, - }, - { - id: uniqueId(), - title: 'This is another Post with a much longer title just to be really annoying and to try and break the UI', - type: 'Post', - info: '1 month ago', - url: `?p=${ uniqueId() }`, - }, -]; - -// export const fetchFauxEntitySuggestions = async () => fauxEntitySuggestions; - -export const fetchFauxEntitySuggestions = () => { - return Promise.resolve( fauxEntitySuggestions ); -}; diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js deleted file mode 100644 index d6dc506c7687b8..00000000000000 --- a/packages/block-editor/src/components/link-control/test/index.js +++ /dev/null @@ -1,527 +0,0 @@ -/** - * External dependencies - */ -import { render, unmountComponentAtNode } from 'react-dom'; -import { act, Simulate } from 'react-dom/test-utils'; -import { first, last, nth } from 'lodash'; -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; -import { UP, DOWN, ENTER } from '@wordpress/keycodes'; -/** - * Internal dependencies - */ -import LinkControl from '../index'; -import { fauxEntitySuggestions, fetchFauxEntitySuggestions } from './fixtures'; - -function eventLoopTick() { - return new Promise( ( resolve ) => setImmediate( resolve ) ); -} - -let container = null; - -beforeEach( () => { - // setup a DOM element as a render target - container = document.createElement( 'div' ); - document.body.appendChild( container ); -} ); - -afterEach( () => { - // cleanup on exiting - unmountComponentAtNode( container ); - container.remove(); - container = null; -} ); - -describe( 'Basic rendering', () => { - it( 'should display with required props', () => { - act( () => { - render( - <LinkControl - />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // expect( searchInputLabel ).not.toBeNull(); - expect( searchInput ).not.toBeNull(); - - expect( container.innerHTML ).toMatchSnapshot(); - } ); -} ); - -describe( 'Searching for a link', () => { - it( 'should display loading UI when input is valid but search results have yet to be returned', async () => { - const searchTerm = 'Hello'; - - let resolver; - - const fauxRequest = () => new Promise( ( resolve ) => { - resolver = resolve; - } ); - - act( () => { - render( - <LinkControl - fetchSearchSuggestions={ fauxRequest } - />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - // fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - const searchResultElements = container.querySelectorAll( '[role="menu"] button[role="menuitem"]' ); - - let loadingUI = container.querySelector( '.components-spinner' ); - - expect( searchResultElements ).toHaveLength( 0 ); - - expect( loadingUI ).not.toBeNull(); - - act( () => { - resolver( fauxEntitySuggestions ); - } ); - - await eventLoopTick(); - - loadingUI = container.querySelector( '.components-spinner' ); - - expect( loadingUI ).toBeNull(); - } ); - - it( 'should display only search suggestions when current input value is not URL-like', async ( ) => { - const searchTerm = 'Hello world'; - const firstFauxSuggestion = first( fauxEntitySuggestions ); - - act( () => { - render( - <LinkControl - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - // fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - const firstSearchResultItemHTML = first( searchResultElements ).innerHTML; - const lastSearchResultItemHTML = last( searchResultElements ).innerHTML; - - expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length ); - - // Sanity check that a search suggestion shows up corresponding to the data - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( firstFauxSuggestion.title ) ); - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( firstFauxSuggestion.type ) ); - - // The fallback URL suggestion should not be shown when input is not URL-like - expect( lastSearchResultItemHTML ).not.toEqual( expect.stringContaining( 'URL' ) ); - } ); - - it.each( [ - [ 'couldbeurlorentitysearchterm' ], - [ 'ThisCouldAlsoBeAValidURL' ], - ] )( 'should display a URL suggestion as a default fallback for the search term "%s" which could potentially be a valid url.', async ( searchTerm ) => { - act( () => { - render( - <LinkControl - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - // fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - const lastSearchResultItemHTML = last( searchResultElements ).innerHTML; - const additionalDefaultFallbackURLSuggestionLength = 1; - - // We should see a search result for each of the expect search suggestions - // plus 1 additional one for the fallback URL suggestion - expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length + additionalDefaultFallbackURLSuggestionLength ); - - // The last item should be a URL search suggestion - expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); - expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( 'URL' ) ); - expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); - } ); - - it( 'should reset the input field and the search results when search term is cleared or reset', async ( ) => { - const searchTerm = 'Hello world'; - - act( () => { - render( - <LinkControl - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - />, container - ); - } ); - - let searchResultElements; - let searchInput; - - // Search Input UI - searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - // fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - - // Check we have definitely rendered some suggestions - expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length ); - - // Grab the reset button now it's available - const resetUI = container.querySelector( '[aria-label="Reset"]' ); - - act( () => { - Simulate.click( resetUI ); - } ); - - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - expect( searchInput.value ).toBe( '' ); - expect( searchResultElements ).toHaveLength( 0 ); - } ); -} ); - -describe( 'Manual link entry', () => { - it.each( [ - [ 'https://make.wordpress.org' ], // explicit https - [ 'http://make.wordpress.org' ], // explicit http - [ 'www.wordpress.org' ], // usage of "www" - ] )( 'should display a single suggestion result when the current input value is URL-like (eg: %s)', async ( searchTerm ) => { - act( () => { - render( - <LinkControl - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - // fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - const firstSearchResultItemHTML = searchResultElements[ 0 ].innerHTML; - const expectedResultsLength = 1; - - expect( searchResultElements ).toHaveLength( expectedResultsLength ); - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'URL' ) ); - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); - } ); - - describe( 'Alternative link protocols and formats', () => { - it.each( [ - [ 'mailto:example123456@wordpress.org', 'mailto' ], - [ 'tel:example123456@wordpress.org', 'tel' ], - [ '#internal-anchor', 'internal' ], - ] )( 'should recognise "%s" as a %s link and handle as manual entry by displaying a single suggestion', async ( searchTerm, searchType ) => { - act( () => { - render( - <LinkControl - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - // fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - const firstSearchResultItemHTML = searchResultElements[ 0 ].innerHTML; - const expectedResultsLength = 1; - - expect( searchResultElements ).toHaveLength( expectedResultsLength ); - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchType ) ); - expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); - } ); - } ); -} ); - -describe( 'Selecting links', () => { - it( 'should display a selected link corresponding to the provided "currentLink" prop', () => { - const selectedLink = first( fauxEntitySuggestions ); - - const LinkControlConsumer = () => { - const [ link ] = useState( selectedLink ); - - return ( - <LinkControl - currentLink={ link } - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - /> - ); - }; - - act( () => { - render( - <LinkControlConsumer />, container - ); - } ); - - // TODO: select by aria role or visible text - const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); - const currentLinkHTML = currentLink.innerHTML; - const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); - - expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); - expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.type ) ); - expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); - expect( currentLinkAnchor ).not.toBeNull(); - } ); - - it( 'should remove currently selected link and (re)display search UI when "Change" button is clicked', () => { - const selectedLink = first( fauxEntitySuggestions ); - - const LinkControlConsumer = () => { - const [ link, setLink ] = useState( selectedLink ); - - return ( - <LinkControl - currentLink={ link } - onLinkChange={ ( suggestion ) => setLink( suggestion ) } - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - /> - ); - }; - - act( () => { - render( - <LinkControlConsumer />, container - ); - } ); - - // TODO: select by aria role or visible text - let currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); - - const currentLinkBtn = currentLink.querySelector( 'button' ); - - // Simulate searching for a term - act( () => { - Simulate.click( currentLinkBtn ); - } ); - - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); - - // We should be back to showing the search input - expect( searchInput ).not.toBeNull(); - expect( currentLink ).toBeNull(); - } ); - - describe( 'Selection using mouse click', () => { - it.each( [ - [ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search - [ 'url', 'https://www.wordpress.org', { - id: '1', - title: 'https://www.wordpress.org', - url: 'https://www.wordpress.org', - type: 'URL', - } ], // url - ] )( 'should display a current selected link UI when a %s suggestion for the search "%s" is clicked', async ( type, searchTerm, selectedLink ) => { - const LinkControlConsumer = () => { - const [ link, setLink ] = useState( null ); - - return ( - <LinkControl - currentLink={ link } - onLinkChange={ ( suggestion ) => setLink( suggestion ) } - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - /> - ); - }; - - act( () => { - render( - <LinkControlConsumer />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - // fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - - const firstSearchSuggestion = first( searchResultElements ); - - // Simulate selecting the first of the search suggestions - act( () => { - Simulate.click( firstSearchSuggestion ); - } ); - - const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); - const currentLinkHTML = currentLink.innerHTML; - const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); - - // Check that this suggestion is now shown as selected - expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); - expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); - expect( currentLinkAnchor ).not.toBeNull(); - } ); - } ); - - describe( 'Selection using keyboard', () => { - it.each( [ - [ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search - [ 'url', 'https://www.wordpress.org', { - id: '1', - title: 'https://www.wordpress.org', - url: 'https://www.wordpress.org', - type: 'URL', - } ], // url - ] )( 'should display a current selected link UI when an %s suggestion for the search "%s" is selected using the keyboard', async ( type, searchTerm, selectedLink ) => { - const LinkControlConsumer = () => { - const [ link, setLink ] = useState( null ); - - return ( - <LinkControl - currentLink={ link } - onLinkChange={ ( suggestion ) => setLink( suggestion ) } - fetchSearchSuggestions={ fetchFauxEntitySuggestions } - /> - ); - }; - - act( () => { - render( - <LinkControlConsumer />, container - ); - } ); - - // Search Input UI - const searchInput = container.querySelector( 'input[aria-label="URL"]' ); - - // Simulate searching for a term - act( () => { - Simulate.change( searchInput, { target: { value: searchTerm } } ); - } ); - - //fetchFauxEntitySuggestions resolves on next "tick" of event loop - await eventLoopTick(); - - // Step down into the search results, highlighting the first result item - act( () => { - Simulate.keyDown( searchInput, { keyCode: DOWN } ); - } ); - - // TODO: select these by aria relationship to autocomplete rather than arbitary selector. - const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); - const firstSearchSuggestion = first( searchResultElements ); - const secondSearchSuggestion = nth( searchResultElements, 1 ); - - let selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); - - // We should have highlighted the first item using the keyboard - expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion ); - - // Only entity searches contain more than 1 suggestion - if ( type === 'entity' ) { - // Check we can go down again using the down arrow - act( () => { - Simulate.keyDown( searchInput, { keyCode: DOWN } ); - } ); - - selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); - - // We should have highlighted the first item using the keyboard - expect( selectedSearchResultElement ).toEqual( secondSearchSuggestion ); - - // Check we can go back up via up arrow - act( () => { - Simulate.keyDown( searchInput, { keyCode: UP } ); - } ); - - selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); - - // We should be back to highlighting the first search result again - expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion ); - } - - // Commit the selected item as the current link - act( () => { - Simulate.keyDown( searchInput, { keyCode: ENTER } ); - } ); - - // Check that the suggestion selected via is now shown as selected - const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); - const currentLinkHTML = currentLink.innerHTML; - const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); - - expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); - expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); - expect( currentLinkAnchor ).not.toBeNull(); - } ); - } ); -} ); diff --git a/packages/block-editor/src/components/link-control/text-highlight.js b/packages/block-editor/src/components/link-control/text-highlight.js deleted file mode 100644 index dc7b35a3d6d2bc..00000000000000 --- a/packages/block-editor/src/components/link-control/text-highlight.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * External dependencies - */ -import { escapeRegExp } from 'lodash'; - -/** - * WordPress dependencies - */ -import { - Fragment, -} from '@wordpress/element'; - -const TextHighlight = ( { text = '', highlight = '' } ) => { - if ( ! highlight.trim() ) { - return text; - } - - const regex = new RegExp( `(${ escapeRegExp( highlight ) })`, 'gi' ); - const parts = text.split( regex ); - return ( - <Fragment> - { parts.filter( ( part ) => part ).map( ( part, i ) => ( - regex.test( part ) ? <mark key={ i }>{ part }</mark> : <span key={ i }>{ part }</span> - ) ) } - </Fragment> - ); -}; - -export default TextHighlight; diff --git a/packages/block-editor/src/components/media-placeholder/README.md b/packages/block-editor/src/components/media-placeholder/README.md index 58140cf99e7215..b730b9af5cbc9c 100644 --- a/packages/block-editor/src/components/media-placeholder/README.md +++ b/packages/block-editor/src/components/media-placeholder/README.md @@ -155,9 +155,9 @@ The argument of the callback is an object containing the following properties: ### value -An object or an array of objects that contain media ID (`id` property) to be selected by default when opening the media library. +Media ID (or media IDs if multiple is true) to be selected by default when opening the media library. -- Type: `Object|Array` +- Type: `Number|Array` - Required: No - Platform: Web diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index d4e98de6179b12..d142d6d6c70008 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -429,7 +429,7 @@ const applyWithSelect = withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return { - mediaUpload: getSettings().mediaUpload, + mediaUpload: getSettings().__experimentalMediaUpload, }; } ); diff --git a/packages/block-editor/src/components/media-placeholder/styles.native.scss b/packages/block-editor/src/components/media-placeholder/styles.native.scss index 03c7c73b2edfc9..a0b7445debf66b 100644 --- a/packages/block-editor/src/components/media-placeholder/styles.native.scss +++ b/packages/block-editor/src/components/media-placeholder/styles.native.scss @@ -19,6 +19,10 @@ background-color: $background-dark-secondary; } +.emptyStateContainerDark { + background-color: $background-dark-secondary; +} + .emptyStateTitle { text-align: center; margin-top: 8; diff --git a/packages/block-editor/src/components/media-upload/check.js b/packages/block-editor/src/components/media-upload/check.js index c1fb3398020f4c..6f2903be5b1e10 100644 --- a/packages/block-editor/src/components/media-upload/check.js +++ b/packages/block-editor/src/components/media-upload/check.js @@ -14,6 +14,6 @@ export default withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return { - hasUploadPermissions: !! getSettings().mediaUpload, + hasUploadPermissions: !! getSettings().__experimentalMediaUpload, }; } )( MediaUploadCheck ); diff --git a/packages/block-editor/src/components/media-upload/index.js b/packages/block-editor/src/components/media-upload/index.js index 2318ef93d5e4f4..1cb3e511097276 100644 --- a/packages/block-editor/src/components/media-upload/index.js +++ b/packages/block-editor/src/components/media-upload/index.js @@ -8,7 +8,7 @@ import { withFilters } from '@wordpress/components'; * an integration with the core blocks that handle media files. By default it renders nothing but * it provides a way to have it overridden with the `editor.MediaUpload` filter. * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} Media upload element. */ const MediaUpload = () => null; diff --git a/packages/block-editor/src/components/media-upload/index.native.js b/packages/block-editor/src/components/media-upload/index.native.js index 2e1c3a9fcd8010..3d89091e94da3d 100644 --- a/packages/block-editor/src/components/media-upload/index.native.js +++ b/packages/block-editor/src/components/media-upload/index.native.js @@ -6,8 +6,6 @@ import { requestMediaPickFromMediaLibrary, requestMediaPickFromDeviceLibrary, requestMediaPickFromDeviceCamera, - getOtherMediaOptions, - requestOtherMediaPickFrom, } from 'react-native-gutenberg-bridge'; /** @@ -33,27 +31,7 @@ export class MediaUpload extends React.Component { this.onPickerPresent = this.onPickerPresent.bind( this ); this.onPickerChange = this.onPickerChange.bind( this ); this.onPickerSelect = this.onPickerSelect.bind( this ); - - this.state = { - otherMediaOptions: undefined, - }; - } - - componentDidMount() { - const { allowedTypes = [] } = this.props; - getOtherMediaOptions( allowedTypes, ( otherMediaOptions ) => { - const otherMediaOptionsWithIcons = otherMediaOptions.map( ( option ) => { - return { - icon: this.getChooseFromDeviceIcon(), - value: option.value, - label: option.label, - }; - } ); - - this.setState( { otherMediaOptions: otherMediaOptionsWithIcons } ); - } ); } - getTakeMediaLabel() { const { allowedTypes = [] } = this.props; @@ -120,26 +98,15 @@ export class MediaUpload extends React.Component { this.onPickerSelect( requestMediaPickFromDeviceCamera ); } else if ( value === MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_WORD_PRESS_LIBRARY ) { this.onPickerSelect( requestMediaPickFromMediaLibrary ); - } else { - const { onSelect, multiple = false } = this.props; - requestOtherMediaPickFrom( value, multiple, ( media ) => { - if ( ( multiple && media ) || ( media && media.id ) ) { - onSelect( media ); - } - } ); } } render() { - let mediaOptions = this.getMediaOptionsItems(); - - if ( this.state.otherMediaOptions ) { - mediaOptions = [ ...mediaOptions, ...this.state.otherMediaOptions ]; - } + const mediaOptions = this.getMediaOptionsItems(); const getMediaOptions = () => ( <Picker - hideCancelButton + hideCancelButton={ true } ref={ ( instance ) => this.picker = instance } options={ mediaOptions } onChange={ this.onPickerChange } diff --git a/packages/block-editor/src/components/provider/index.js b/packages/block-editor/src/components/provider/index.js index c2b29f13fa74ac..488dd6244d8c65 100644 --- a/packages/block-editor/src/components/provider/index.js +++ b/packages/block-editor/src/components/provider/index.js @@ -73,8 +73,8 @@ class BlockEditorProvider extends Component { * This needs to be done synchronously after state changes (instead of using * `componentDidUpdate`) in order to avoid batching these changes. * - * @param {WPDataRegistry} registry Registry from which block editor - * dispatch is to be overridden. + * @param {WPDataRegistry} registry Registry from which block editor + * dispatch is to be overriden. */ attachChangeObserver( registry ) { if ( this.unsubscribe ) { diff --git a/packages/block-editor/src/components/provider/index.native.js b/packages/block-editor/src/components/provider/index.native.js index fca4fab5ddbdee..8e2f2e677397b4 100644 --- a/packages/block-editor/src/components/provider/index.native.js +++ b/packages/block-editor/src/components/provider/index.native.js @@ -75,8 +75,8 @@ class BlockEditorProvider extends Component { * This needs to be done synchronously after state changes (instead of using * `componentDidUpdate`) in order to avoid batching these changes. * - * @param {WPDataRegistry} registry Registry from which block editor - * dispatch is to be overridden. + * @param {WPDataRegistry} registry Registry from which block editor + * dispatch is to be overriden. */ attachChangeObserver( registry ) { if ( this.unsubscribe ) { diff --git a/packages/block-editor/src/components/rich-text/file-paste-handler.js b/packages/block-editor/src/components/rich-text/file-paste-handler.js deleted file mode 100644 index eceeb069b263ff..00000000000000 --- a/packages/block-editor/src/components/rich-text/file-paste-handler.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * WordPress dependencies - */ -import { createBlobURL } from '@wordpress/blob'; - -export function filePasteHandler( files ) { - return files - .filter( ( { type } ) => /^image\/(?:jpe?g|png|gif)$/.test( type ) ) - .map( ( file ) => `<img src="${ createBlobURL( file ) }">` ) - .join( '' ); -} diff --git a/packages/block-editor/src/components/rich-text/file-paste-handler.native.js b/packages/block-editor/src/components/rich-text/file-paste-handler.native.js deleted file mode 100644 index 41402a0dcda68c..00000000000000 --- a/packages/block-editor/src/components/rich-text/file-paste-handler.native.js +++ /dev/null @@ -1,3 +0,0 @@ -export function filePasteHandler( files ) { - return files.map( ( url ) => `<img src="${ url }">` ).join( '' ); -} diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.js deleted file mode 100644 index fc857311706db3..00000000000000 --- a/packages/block-editor/src/components/rich-text/format-toolbar-container.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * WordPress dependencies - */ -import { Popover } from '@wordpress/components'; - -/** - * Internal dependencies - */ -import BlockFormatControls from '../block-format-controls'; -import FormatToolbar from './format-toolbar'; - -function getAnchorRect( anchorObj ) { - const { current } = anchorObj; - const rect = current.getBoundingClientRect(); - - // Add some space. - const buffer = 6; - - // Subtract padding if any. - let { paddingTop } = window.getComputedStyle( current ); - - paddingTop = parseInt( paddingTop, 10 ); - - return { - x: rect.left, - y: rect.top + paddingTop - buffer, - width: rect.width, - height: rect.height - paddingTop + buffer, - left: rect.left, - right: rect.right, - top: rect.top + paddingTop - buffer, - bottom: rect.bottom, - }; -} - -const FormatToolbarContainer = ( { inline, anchorObj } ) => { - if ( inline ) { - // Render in popover - return ( - <Popover - noArrow - position="top center" - focusOnMount={ false } - getAnchorRect={ () => getAnchorRect( anchorObj ) } - className="block-editor-rich-text__inline-format-toolbar" - > - <FormatToolbar /> - </Popover> - ); - } - // Render regular toolbar - return ( - <BlockFormatControls> - <FormatToolbar /> - </BlockFormatControls> - ); -}; - -export default FormatToolbarContainer; diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js deleted file mode 100644 index d37fe5bfee0f68..00000000000000 --- a/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Internal dependencies - */ -import BlockFormatControls from '../block-format-controls'; -import FormatToolbar from './format-toolbar'; - -const FormatToolbarContainer = () => { - // Render regular toolbar - return ( - <BlockFormatControls> - <FormatToolbar /> - </BlockFormatControls> - ); -}; - -export default FormatToolbarContainer; diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 53292f1402d5d7..b78e8c3a46ffc3 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -7,9 +7,9 @@ import { omit } from 'lodash'; /** * WordPress dependencies */ -import { RawHTML, Component, createRef, Platform } from '@wordpress/element'; +import { RawHTML, Component, createRef } from '@wordpress/element'; import { withDispatch, withSelect } from '@wordpress/data'; -import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; +import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform } from '@wordpress/blocks'; import { withInstanceId, compose } from '@wordpress/compose'; import { __experimentalRichText as RichText, @@ -25,7 +25,8 @@ import { toHTMLString, slice, } from '@wordpress/rich-text'; -import { withFilters } from '@wordpress/components'; +import { withFilters, Popover } from '@wordpress/components'; +import { createBlobURL } from '@wordpress/blob'; import deprecated from '@wordpress/deprecated'; import { isURL } from '@wordpress/url'; @@ -33,10 +34,10 @@ import { isURL } from '@wordpress/url'; * Internal dependencies */ import Autocomplete from '../autocomplete'; +import BlockFormatControls from '../block-format-controls'; +import FormatToolbar from './format-toolbar'; import { withBlockEditContext } from '../block-edit/context'; import { RemoveBrowserShortcuts } from './remove-browser-shortcuts'; -import { filePasteHandler } from './file-paste-handler'; -import FormatToolbarContainer from './format-toolbar-container'; const wrapperClasses = 'editor-rich-text block-editor-rich-text'; const classes = 'editor-rich-text__editable block-editor-rich-text__editable'; @@ -65,6 +66,7 @@ class RichTextWrapper extends Component { this.onPaste = this.onPaste.bind( this ); this.onDelete = this.onDelete.bind( this ); this.inputRule = this.inputRule.bind( this ); + this.getAnchorRect = this.getAnchorRect.bind( this ); } onEnter( { value, onChange, shiftKey } ) { @@ -122,7 +124,7 @@ class RichTextWrapper extends Component { } } - onPaste( { value, onChange, html, plainText, files } ) { + onPaste( { value, onChange, html, plainText, image } ) { const { onReplace, onSplit, @@ -132,18 +134,16 @@ class RichTextWrapper extends Component { __unstableEmbedURLOnPaste, } = this.props; - // Only process file if no HTML is present. - // Note: a pasted file may have the URL as plain text. - if ( files && files.length && ! html ) { + if ( image && ! html ) { + const file = image.getAsFile ? image.getAsFile() : image; const content = pasteHandler( { - HTML: filePasteHandler( files ), + HTML: `<img src="${ createBlobURL( file ) }">`, mode: 'BLOCKS', tagName, } ); // Allows us to ask for this information when we get a report. - // eslint-disable-next-line no-console - window.console.log( 'Received items:\n\n', files ); + window.console.log( 'Received item:\n\n', file ); if ( onReplace && isEmpty( value ) ) { onReplace( content ); @@ -303,6 +303,30 @@ class RichTextWrapper extends Component { return formattingControls.map( ( name ) => `core/${ name }` ); } + getAnchorRect() { + const { current } = this.ref; + const rect = current.getBoundingClientRect(); + + // Add some space. + const buffer = 6; + + // Subtract padding if any. + let { paddingTop } = window.getComputedStyle( current ); + + paddingTop = parseInt( paddingTop, 10 ); + + return { + x: rect.left, + y: rect.top + paddingTop - buffer, + width: rect.width, + height: rect.height - paddingTop + buffer, + left: rect.left, + right: rect.right, + top: rect.top + paddingTop - buffer, + bottom: rect.bottom, + }; + } + render() { const { children, @@ -400,7 +424,22 @@ class RichTextWrapper extends Component { { ( { isSelected, value, onChange, Editable } ) => <> { children && children( { value, onChange } ) } - { isSelected && hasFormats && ( <FormatToolbarContainer inline={ inlineToolbar } anchorObj={ this.ref } /> ) } + { isSelected && ! inlineToolbar && hasFormats && ( + <BlockFormatControls> + <FormatToolbar /> + </BlockFormatControls> + ) } + { isSelected && inlineToolbar && hasFormats && ( + <Popover + noArrow + position="top center" + focusOnMount={ false } + getAnchorRect={ this.getAnchorRect } + className="block-editor-rich-text__inline-format-toolbar" + > + <FormatToolbar /> + </Popover> + ) } { isSelected && <RemoveBrowserShortcuts /> } <Autocomplete onReplace={ onReplace } @@ -443,16 +482,7 @@ class RichTextWrapper extends Component { const RichTextContainer = compose( [ withInstanceId, - withBlockEditContext( ( { clientId, onCaretVerticalPositionChange, isSelected }, ownProps ) => { - if ( Platform.OS === 'web' ) { - return { clientId }; - } - return { - clientId, - blockIsSelected: ownProps.isSelected !== undefined ? ownProps.isSelected : isSelected, - onCaretVerticalPositionChange, - }; - } ), + withBlockEditContext( ( { clientId } ) => ( { clientId } ) ), withSelect( ( select, { clientId, instanceId, @@ -465,7 +495,6 @@ const RichTextContainer = compose( [ getSelectionEnd, getSettings, didAutomaticChange, - __unstableGetBlockWithoutInnerBlocks, } = select( 'core/block-editor' ); const selectionStart = getSelectionStart(); @@ -480,18 +509,6 @@ const RichTextContainer = compose( [ isSelected = selectionStart.clientId === clientId; } - let extraProps = {}; - if ( Platform.OS === 'native' ) { - // If the block of this RichText is unmodified then it's a candidate for replacing when adding a new block. - // In order to fix https://github.com/wordpress-mobile/gutenberg-mobile/issues/1126, let's blur on unmount in that case. - // This apparently assumes functionality the BlockHlder actually - const block = clientId && __unstableGetBlockWithoutInnerBlocks( clientId ); - const shouldBlurOnUnmount = block && isSelected && isUnmodifiedDefaultBlock( block ); - extraProps = { - shouldBlurOnUnmount, - }; - } - return { canUserUseUnfilteredHTML: __experimentalCanUserUseUnfilteredHTML, isCaretWithinFormattedText: isCaretWithinFormattedText(), @@ -499,7 +516,6 @@ const RichTextContainer = compose( [ selectionEnd: isSelected ? selectionEnd.offset : undefined, isSelected, didAutomaticChange: didAutomaticChange(), - ...extraProps, }; } ), withDispatch( ( dispatch, { diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js new file mode 100644 index 00000000000000..feab0f747a9229 --- /dev/null +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -0,0 +1,213 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { RawHTML } from '@wordpress/element'; +import { withDispatch, withSelect } from '@wordpress/data'; +import { pasteHandler, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; +import { withInstanceId, compose } from '@wordpress/compose'; +import { __experimentalRichText as RichText } from '@wordpress/rich-text'; + +/** + * Internal dependencies + */ +import Autocomplete from '../autocomplete'; +import BlockFormatControls from '../block-format-controls'; +import FormatToolbar from './format-toolbar'; +import { withBlockEditContext } from '../block-edit/context'; + +const wrapperClasses = 'editor-rich-text block-editor-rich-text'; +const classes = 'editor-rich-text__editable block-editor-rich-text__editable'; + +function RichTextWraper( { + children, + tagName, + value: originalValue, + onChange: originalOnChange, + selectionStart, + selectionEnd, + onSelectionChange, + multiline, + inlineToolbar, + wrapperClassName, + className, + autocompleters, + onReplace, + onRemove, + onMerge, + onSplit, + isCaretWithinFormattedText, + onEnterFormattedText, + onExitFormattedText, + canUserUseUnfilteredHTML, + isSelected: originalIsSelected, + onCreateUndoLevel, + placeholder, + // From experimental filter. + ...experimentalProps +} ) { + const adjustedValue = originalValue; + const adjustedOnChange = originalOnChange; + + return ( + <RichText + { ...experimentalProps } + value={ adjustedValue } + onChange={ adjustedOnChange } + selectionStart={ selectionStart } + selectionEnd={ selectionEnd } + onSelectionChange={ onSelectionChange } + tagName={ tagName } + wrapperClassName={ classnames( wrapperClasses, wrapperClassName ) } + className={ classnames( classes, className ) } + placeholder={ placeholder } + __unstableIsSelected={ originalIsSelected } + //__unstablePatterns={ getPatterns() } + //__unstableEnterPatterns={ getEnterPatterns() } + __unstablePasteHandler={ pasteHandler } + __unstableAutocomplete={ Autocomplete } + __unstableAutocompleters={ autocompleters } + __unstableOnReplace={ onReplace } + __unstableOnRemove={ onRemove } + __unstableOnMerge={ onMerge } + __unstableOnSplit={ onSplit } + __unstableMultiline={ multiline } + __unstableIsCaretWithinFormattedText={ isCaretWithinFormattedText } + __unstableOnEnterFormattedText={ onEnterFormattedText } + __unstableOnExitFormattedText={ onExitFormattedText } + __unstableCanUserUseUnfilteredHTML={ canUserUseUnfilteredHTML } + __unstableOnCreateUndoLevel={ onCreateUndoLevel } + > + { ( { isSelected, value, onChange } ) => + <View> + { children && children( { value, onChange } ) } + { isSelected && ! inlineToolbar && ( + <BlockFormatControls> + <FormatToolbar /> + </BlockFormatControls> + ) } + </View> + } + </RichText> + ); +} + +const RichTextContainer = compose( [ + withInstanceId, + withBlockEditContext( ( { clientId, onCaretVerticalPositionChange, isSelected }, ownProps ) => { + return { + clientId, + blockIsSelected: ownProps.isSelected !== undefined ? ownProps.isSelected : isSelected, + onCaretVerticalPositionChange, + }; + } ), + withSelect( ( select, { + clientId, + instanceId, + identifier = instanceId, + isSelected, + blockIsSelected, + } ) => { + const { getFormatTypes } = select( 'core/rich-text' ); + const { + getSelectionStart, + getSelectionEnd, + __unstableGetBlockWithoutInnerBlocks, + } = select( 'core/block-editor' ); + + const selectionStart = getSelectionStart(); + const selectionEnd = getSelectionEnd(); + + if ( isSelected === undefined ) { + isSelected = ( + selectionStart.clientId === clientId && + selectionStart.attributeKey === identifier + ); + } + + // If the block of this RichText is unmodified then it's a candidate for replacing when adding a new block. + // In order to fix https://github.com/wordpress-mobile/gutenberg-mobile/issues/1126, let's blur on unmount in that case. + // This apparently assumes functionality the BlockHlder actually + const block = clientId && __unstableGetBlockWithoutInnerBlocks( clientId ); + const shouldBlurOnUnmount = block && isSelected && isUnmodifiedDefaultBlock( block ); + + return { + formatTypes: getFormatTypes(), + selectionStart: isSelected ? selectionStart.offset : undefined, + selectionEnd: isSelected ? selectionEnd.offset : undefined, + isSelected, + blockIsSelected, + shouldBlurOnUnmount, + }; + } ), + withDispatch( ( dispatch, { + clientId, + instanceId, + identifier = instanceId, + } ) => { + const { + __unstableMarkLastChangeAsPersistent, + selectionChange, + } = dispatch( 'core/block-editor' ); + + return { + onCreateUndoLevel: __unstableMarkLastChangeAsPersistent, + onSelectionChange( start, end ) { + selectionChange( clientId, identifier, start, end ); + }, + }; + } ), +] )( RichTextWraper ); + +RichTextContainer.Content = ( { value, format, tagName: Tag, multiline, ...props } ) => { + let content; + let html = value; + let MultilineTag; + + if ( multiline === true || multiline === 'p' || multiline === 'li' ) { + MultilineTag = multiline === true ? 'p' : multiline; + } + + if ( ! html && MultilineTag ) { + html = `<${ MultilineTag }></${ MultilineTag }>`; + } + + switch ( format ) { + case 'string': + content = <RawHTML>{ html }</RawHTML>; + break; + } + + if ( Tag ) { + return <Tag { ...props }>{ content }</Tag>; + } + + return content; +}; + +RichTextContainer.isEmpty = ( value = '' ) => { + // Handle deprecated `children` and `node` sources. + if ( Array.isArray( value ) ) { + return ! value || value.length === 0; + } + + return value.length === 0; +}; + +RichTextContainer.Content.defaultProps = { + format: 'string', + value: '', +}; + +/** + * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/rich-text/README.md + */ +export default RichTextContainer; +export { RichTextShortcut } from './shortcut'; +export { RichTextToolbarButton } from './toolbar-button'; +export { __unstableRichTextInputEvent } from './input-event'; diff --git a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js index 9eee7b641a0e61..165566a5bbbd16 100644 --- a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js +++ b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js @@ -40,6 +40,6 @@ const SHORTCUTS_ELEMENT = ( * Component which registered keyboard event handlers to prevent default * behaviors for key combinations otherwise handled internally by RichText. * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} WordPress element. */ export const RemoveBrowserShortcuts = () => SHORTCUTS_ELEMENT; diff --git a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js deleted file mode 100644 index 43a4b030646db4..00000000000000 --- a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js +++ /dev/null @@ -1 +0,0 @@ -export const RemoveBrowserShortcuts = () => null; diff --git a/packages/block-editor/src/components/typewriter/index.js b/packages/block-editor/src/components/typewriter/index.js index d2869ab03b2c01..7600b2cd8747cd 100644 --- a/packages/block-editor/src/components/typewriter/index.js +++ b/packages/block-editor/src/components/typewriter/index.js @@ -100,7 +100,7 @@ class Typewriter extends Component { * Maintains the scroll position after a selection change caused by a * keyboard event. * - * @param {WPSyntheticEvent} event Synthetic keyboard event. + * @param {SyntheticEvent} event Synthetic keyboard event. */ maintainCaretPosition( { keyCode } ) { if ( ! this.isSelectionEligibleForScroll() ) { diff --git a/packages/block-editor/src/components/url-input/index.js b/packages/block-editor/src/components/url-input/index.js index 1c32d9c29eab34..9652df56c9da74 100644 --- a/packages/block-editor/src/components/url-input/index.js +++ b/packages/block-editor/src/components/url-input/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { throttle, isFunction } from 'lodash'; +import { throttle } from 'lodash'; import classnames from 'classnames'; import scrollIntoView from 'dom-scroll-into-view'; @@ -14,7 +14,6 @@ import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes'; import { Spinner, withSpokenMessages, Popover } from '@wordpress/components'; import { withInstanceId, withSafeTimeout, compose } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; -import { isURL } from '@wordpress/url'; // Since URLInput is rendered in the context of other inputs, but should be // considered a separate modal node, prevent keyboard events from propagating @@ -22,15 +21,12 @@ import { isURL } from '@wordpress/url'; const stopEventPropagation = ( event ) => event.stopPropagation(); class URLInput extends Component { - constructor( props ) { - super( props ); + constructor( { autocompleteRef } ) { + super( ...arguments ); this.onChange = this.onChange.bind( this ); this.onKeyDown = this.onKeyDown.bind( this ); - this.selectLink = this.selectLink.bind( this ); - this.handleOnClick = this.handleOnClick.bind( this ); - this.bindSuggestionNode = this.bindSuggestionNode.bind( this ); - this.autocompleteRef = props.autocompleteRef || createRef(); + this.autocompleteRef = autocompleteRef || createRef(); this.inputRef = createRef(); this.updateSuggestions = throttle( this.updateSuggestions.bind( this ), 200 ); @@ -49,7 +45,6 @@ class URLInput extends Component { // when already expanded if ( showSuggestions && selectedSuggestion !== null && ! this.scrollingIntoView ) { this.scrollingIntoView = true; - scrollIntoView( this.suggestionNodes[ selectedSuggestion ], this.autocompleteRef.current, { onlyScrollIfNeeded: true, } ); @@ -71,17 +66,14 @@ class URLInput extends Component { } updateSuggestions( value ) { - const { - __experimentalFetchLinkSuggestions: fetchLinkSuggestions, - __experimentalHandleURLSuggestions: handleURLSuggestions, - } = this.props; + const { fetchLinkSuggestions } = this.props; if ( ! fetchLinkSuggestions ) { return; } // Show the suggestions after typing at least 2 characters // and also for URLs - if ( value.length < 2 || ( ! handleURLSuggestions && isURL( value ) ) ) { + if ( value.length < 2 || /^https?:/.test( value ) ) { this.setState( { showSuggestions: false, selectedSuggestion: null, @@ -140,13 +132,9 @@ class URLInput extends Component { onKeyDown( event ) { const { showSuggestions, selectedSuggestion, suggestions, loading } = this.state; - // If the suggestions are not shown or loading, we shouldn't handle the arrow keys // We shouldn't preventDefault to allow block arrow keys navigation - if ( - ( ! showSuggestions || ! suggestions.length || loading ) && - this.props.value - ) { + if ( ! showSuggestions || ! suggestions.length || loading ) { // In the Windows version of Firefox the up and down arrows don't move the caret // within an input field like they do for Mac Firefox/Chrome/Safari. This causes // a form of focus trapping that is disruptive to the user experience. This disruption @@ -235,64 +223,19 @@ class URLInput extends Component { this.inputRef.current.focus(); } - static getDerivedStateFromProps( { value, disableSuggestions }, { showSuggestions, selectedSuggestion } ) { - let shouldShowSuggestions = showSuggestions; - - const hasValue = value && value.length; - - if ( ! hasValue ) { - shouldShowSuggestions = false; - } - - if ( disableSuggestions === true ) { - shouldShowSuggestions = false; - } - + static getDerivedStateFromProps( { disableSuggestions }, { showSuggestions } ) { return { - selectedSuggestion: hasValue ? selectedSuggestion : null, - showSuggestions: shouldShowSuggestions, + showSuggestions: disableSuggestions === true ? false : showSuggestions, }; } render() { - const { - instanceId, - className, - id, - isFullWidth, - hasBorder, - __experimentalRenderSuggestions: renderSuggestions, - placeholder = __( 'Paste URL or type to search' ), - value = '', - autoFocus = true, - } = this.props; - - const { - showSuggestions, - suggestions, - selectedSuggestion, - loading, - } = this.state; + const { value = '', autoFocus = true, instanceId, className, id, isFullWidth, hasBorder } = this.props; + const { showSuggestions, suggestions, selectedSuggestion, loading } = this.state; const suggestionsListboxId = `block-editor-url-input-suggestions-${ instanceId }`; const suggestionOptionIdPrefix = `block-editor-url-input-suggestion-${ instanceId }`; - const suggestionsListProps = { - id: suggestionsListboxId, - ref: this.autocompleteRef, - role: 'listbox', - }; - - const buildSuggestionItemProps = ( suggestion, index ) => { - return { - role: 'option', - tabIndex: '-1', - id: `${ suggestionOptionIdPrefix }-${ index }`, - ref: this.bindSuggestionNode( index ), - 'aria-selected': index === selectedSuggestion, - }; - }; - /* eslint-disable jsx-a11y/no-autofocus */ return ( <div className={ classnames( 'editor-url-input block-editor-url-input', className, { @@ -308,7 +251,7 @@ class URLInput extends Component { value={ value } onChange={ this.onChange } onInput={ stopEventPropagation } - placeholder={ placeholder } + placeholder={ __( 'Paste URL or type to search' ) } onKeyDown={ this.onKeyDown } role="combobox" aria-expanded={ showSuggestions } @@ -320,37 +263,34 @@ class URLInput extends Component { { ( loading ) && <Spinner /> } - { isFunction( renderSuggestions ) && showSuggestions && !! suggestions.length && renderSuggestions( { - suggestions, - selectedSuggestion, - suggestionsListProps, - buildSuggestionItemProps, - isLoading: loading, - handleSuggestionClick: this.handleOnClick, - } ) } - - { ! isFunction( renderSuggestions ) && showSuggestions && !! suggestions.length && + { showSuggestions && !! suggestions.length && <Popover position="bottom" noArrow focusOnMount={ false } > <div - { ...suggestionsListProps } className={ classnames( 'editor-url-input__suggestions', 'block-editor-url-input__suggestions', `${ className }__suggestions` ) } + id={ suggestionsListboxId } + ref={ this.autocompleteRef } + role="listbox" > { suggestions.map( ( suggestion, index ) => ( <button - { ...buildSuggestionItemProps( suggestion, index ) } key={ suggestion.id } + role="option" + tabIndex="-1" + id={ `${ suggestionOptionIdPrefix }-${ index }` } + ref={ this.bindSuggestionNode( index ) } className={ classnames( 'editor-url-input__suggestion block-editor-url-input__suggestion', { 'is-selected': index === selectedSuggestion, } ) } onClick={ () => this.handleOnClick( suggestion ) } + aria-selected={ index === selectedSuggestion } > { suggestion.title } </button> @@ -371,15 +311,10 @@ export default compose( withSafeTimeout, withSpokenMessages, withInstanceId, - withSelect( ( select, props ) => { - // If a link suggestions handler is already provided then - // bail - if ( isFunction( props.__experimentalFetchLinkSuggestions ) ) { - return; - } + withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return { - __experimentalFetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions, + fetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions, }; } ) )( URLInput ); diff --git a/packages/block-editor/src/hooks/anchor.js b/packages/block-editor/src/hooks/anchor.js index 5f8f1ca25879f5..9b78c39bbfeb02 100644 --- a/packages/block-editor/src/hooks/anchor.js +++ b/packages/block-editor/src/hooks/anchor.js @@ -56,9 +56,9 @@ export function addAttribute( settings ) { * Override the default edit UI to include a new block inspector control for * assigning the anchor ID, if block supports anchor. * - * @param {WPComponent} BlockEdit Original component. + * @param {Function|Component} BlockEdit Original component. * - * @return {WPComponent} Wrapped component. + * @return {string} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { diff --git a/packages/block-editor/src/hooks/custom-class-name.js b/packages/block-editor/src/hooks/custom-class-name.js index dfbceb627389cc..bac77a37ea42a2 100644 --- a/packages/block-editor/src/hooks/custom-class-name.js +++ b/packages/block-editor/src/hooks/custom-class-name.js @@ -47,9 +47,9 @@ export function addAttribute( settings ) { * Override the default edit UI to include a new block inspector control for * assigning the custom class name, if block supports custom class name. * - * @param {WPComponent} BlockEdit Original component. + * @param {Function|Component} BlockEdit Original component. * - * @return {WPComponent} Wrapped component. + * @return {string} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index 54233e3bda2e91..06eabc9f6f11f4 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -32,7 +32,6 @@ export const PREFERENCES_DEFAULTS = { * __experimentalEnableLegacyWidgetBlock boolean Whether the user has enabled the Legacy Widget Block * __experimentalEnableMenuBlock boolean Whether the user has enabled the Menu Block * __experimentalBlockDirectory boolean Whether the user has enabled the Block Directory - * __experimentalEnableFullSiteEditing boolean Whether the user has enabled Full Site Editing */ export const SETTINGS_DEFAULTS = { alignWide: false, @@ -153,98 +152,80 @@ export const SETTINGS_DEFAULTS = { __experimentalEnableLegacyWidgetBlock: false, __experimentalEnableMenuBlock: false, __experimentalBlockDirectory: false, - __experimentalEnableFullSiteEditing: false, gradients: [ { name: __( 'Vivid cyan blue to vivid purple' ), - gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', - slug: 'vivid-cyan-blue-to-vivid-purple', + gradient: 'linear-gradient(135deg, rgba(6, 147, 227, 1) 0%, rgb(155, 81, 224) 100%)', }, { name: __( 'Vivid green cyan to vivid cyan blue' ), - gradient: 'linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)', - slug: 'vivid-green-cyan-to-vivid-cyan-blue', + gradient: 'linear-gradient(135deg, rgba(0, 208, 132, 1) 0%, rgba(6, 147, 227, 1) 100%)', }, { name: __( 'Light green cyan to vivid green cyan' ), - gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', - slug: 'light-green-cyan-to-vivid-green-cyan', + gradient: 'linear-gradient(135deg, rgb(122, 220, 180) 0%, rgb(0, 208, 130) 100%)', }, { name: __( 'Luminous vivid amber to luminous vivid orange' ), - gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)', - slug: 'luminous-vivid-amber-to-luminous-vivid-orange', + gradient: 'linear-gradient(135deg, rgba(252, 185, 0, 1) 0%, rgba(255, 105, 0, 1) 100%)', }, { name: __( 'Luminous vivid orange to vivid red' ), - gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)', - slug: 'luminous-vivid-orange-to-vivid-red', + gradient: 'linear-gradient(135deg, rgba(255, 105, 0, 1) 0%, rgb(207, 46, 46) 100%)', }, { name: __( 'Very light gray to cyan bluish gray' ), - gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)', - slug: 'very-light-gray-to-cyan-bluish-gray', + gradient: 'linear-gradient(135deg, rgb(238, 238, 238) 0%, rgb(169, 184, 195)', }, // The following use new, customized colors. { name: __( 'Cool to warm spectrum' ), - gradient: 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)', - slug: 'cool-to-warm-spectrum', + gradient: 'linear-gradient(135deg, rgb(74, 234, 220), rgb(151, 120, 209), rgb(207, 42, 186), rgb(238, 44, 130), rgb(251, 105, 98),rgb(254, 248, 76)', }, { name: __( 'Blush light purple' ), - gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)', - slug: 'blush-light-purple', + gradient: 'linear-gradient(135deg, rgb(255, 206, 236), rgb(152, 150, 240)', }, { name: __( 'Blush bordeaux' ), - gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)', - slug: 'blush-bordeaux', + gradient: 'linear-gradient(135deg, rgb(254, 205, 165), rgb(254, 45, 45), rgb(107, 0, 62)', }, { name: __( 'Purple crush' ), - gradient: 'linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%)', - slug: 'purple-crush', + gradient: 'linear-gradient(135deg, rgb(52, 226, 228), rgb(71, 33, 251), rgb(171, 29, 254)', }, { name: __( 'Luminous dusk' ), - gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)', - slug: 'luminous-dusk', + gradient: 'linear-gradient(135deg, rgb(255, 203, 112), rgb(199, 81, 192), rgb(65, 88, 208)', }, { name: __( 'Hazy dawn' ), - gradient: 'linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%)', - slug: 'hazy-dawn', + gradient: 'linear-gradient(135deg, rgb(250, 172, 168), rgb(218, 208, 236)', }, { name: __( 'Pale ocean' ), - gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)', - slug: 'pale-ocean', + gradient: 'linear-gradient(135deg, rgb(255, 245, 203), rgb(182, 227, 212), rgb(51, 167, 181)', }, { name: __( 'Electric grass' ), - gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)', - slug: 'electric-grass', + gradient: 'linear-gradient(135deg, rgb(202, 248, 128), rgb(113, 206, 126)', }, { name: __( 'Subdued olive' ), - gradient: 'linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%)', - slug: 'subdued-olive', + gradient: 'linear-gradient(135deg, rgb(250, 250, 225), rgb(103, 166, 113)', }, { name: __( 'Atomic cream' ), - gradient: 'linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%)', - slug: 'atomic-cream', + gradient: 'linear-gradient(135deg, rgb(253, 215, 154), rgb(0, 74, 89)', }, { name: __( 'Nightshade' ), - gradient: 'linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%)', - slug: 'nightshade', + gradient: 'linear-gradient(135deg, rgb(51, 9, 104), rgb(49, 205, 207)', }, { name: __( 'Midnight' ), - gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)', - slug: 'midnight', + gradient: 'linear-gradient(135deg, rgb(2, 3, 129), rgb(40, 116, 252)', }, ], }; + diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 76bec295096bc3..d0dd7a69a15973 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -29,16 +29,6 @@ import { } from '@wordpress/blocks'; import { SVG, Rect, G, Path } from '@wordpress/components'; -/** - * A block selection object. - * - * @typedef {Object} WPBlockSelection - * - * @property {string} clientId A block client ID. - * @property {string} attributeKey A block attribute key. - * @property {number} offset A block attribute offset. - */ - // Module constants /** @@ -247,9 +237,9 @@ export const getGlobalBlockCount = createSelector( if ( ! blockName ) { return clientIds.length; } - return reduce( clientIds, ( accumulator, clientId ) => { + return reduce( clientIds, ( count, clientId ) => { const block = state.blocks.byClientId[ clientId ]; - return block.name === blockName ? accumulator + 1 : accumulator; + return block.name === blockName ? count + 1 : count; }, 0 ); }, ( state ) => [ @@ -291,6 +281,14 @@ export function getBlockCount( state, rootClientId ) { return getBlockOrder( state, rootClientId ).length; } +/** + * @typedef {WPBlockSelection} A block selection object. + * + * @property {string} clientId A block client ID. + * @property {string} attributeKey A block attribute key. + * @property {number} offset A block attribute offset. + */ + /** * Returns the current selection start block client ID, attribute key and text * offset. @@ -420,30 +418,6 @@ export function getBlockRootClientId( state, clientId ) { null; } -/** - * Given a block client ID, returns the list of all its parents from top to bottom. - * - * @param {Object} state Editor state. - * @param {string} clientId Block from which to find root client ID. - * - * @return {Array} ClientIDs of the parent blocks. - */ -export const getBlockParents = createSelector( - ( state, clientId ) => { - const parents = []; - let current = clientId; - while ( !! state.blocks.parents[ current ] ) { - current = state.blocks.parents[ current ]; - parents.push( current ); - } - - return parents.reverse(); - }, - ( state ) => [ - state.blocks.parents, - ] -); - /** * Given a block client ID, returns the root of the hierarchy from which the block is nested, return the block itself for root level blocks. * @@ -1149,9 +1123,9 @@ const canIncludeBlockTypeInInserter = ( state, blockType, rootClientId ) => { * @param {Object} state Editor state. * @param {?string} rootClientId Optional root client ID of block list. * - * @return {WPEditorInserterItem[]} Items that appear in inserter. + * @return {Editor.InserterItem[]} Items that appear in inserter. * - * @typedef {Object} WPEditorInserterItem + * @typedef {Object} Editor.InserterItem * @property {string} id Unique identifier for the item. * @property {string} name The type of block to create. * @property {Object} initialAttributes Attributes to pass to the newly created block. @@ -1310,22 +1284,6 @@ export const hasInserterItems = createSelector( ], ); -/** - * Returns the list of allowed inserter blocks for inner blocks children - * - * @param {Object} state Editor state. - * @param {?string} rootClientId Optional root client ID of block list. - * - * @return {Array?} The list of allowed block types or false. - */ -export const __experimentalGetAllowedBlocks = ( state, rootClientId = null ) => { - if ( ! rootClientId ) { - return false; - } - const { allowedBlocks } = getBlockListSettings( state, rootClientId ); - return allowedBlocks; -}; - /** * Returns the Block List settings of a block, if any exist. * diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 9c149f001cf7fa..8ebb2e487a4f29 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -3,7 +3,6 @@ @import "./components/block-inspector/style.scss"; @import "./components/block-list/style.scss"; @import "./components/block-list-appender/style.scss"; -@import "./components/block-breadcrumb/style.scss"; @import "./components/block-card/style.scss"; @import "./components/block-compare/style.scss"; @import "./components/block-mover/style.scss"; @@ -19,7 +18,6 @@ @import "./components/contrast-checker/style.scss"; @import "./components/default-block-appender/style.scss"; @import "./components/gradient-picker/control.scss"; -@import "./components/link-control/style.scss"; @import "./components/inner-blocks/style.scss"; @import "./components/inserter-with-shortcuts/style.scss"; @import "./components/inserter/style.scss"; diff --git a/packages/block-library/package.json b/packages/block-library/package.json index 8d4cd8ba268545..cf7b1171009db5 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "2.9.3", + "version": "2.9.0", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js index b048722a70ecf7..15387acbd90c7a 100644 --- a/packages/block-library/src/audio/edit.js +++ b/packages/block-library/src/audio/edit.js @@ -214,8 +214,10 @@ class AudioEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { mediaUpload } = getSettings(); - return { mediaUpload }; + const { __experimentalMediaUpload } = getSettings(); + return { + mediaUpload: __experimentalMediaUpload, + }; } ), withNotices, ] )( AudioEdit ); diff --git a/packages/block-library/src/button/block.json b/packages/block-library/src/button/block.json index bc35b9ff5ee32e..ff43c67db5e834 100644 --- a/packages/block-library/src/button/block.json +++ b/packages/block-library/src/button/block.json @@ -49,9 +49,6 @@ "borderRadius": { "type": "number" }, - "gradient": { - "type": "string" - }, "customGradient": { "type": "string" } diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index 11d1deef862cfd..17908484218091 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -8,6 +8,7 @@ import classnames from 'classnames'; */ import { __ } from '@wordpress/i18n'; import { + Component, useCallback, } from '@wordpress/element'; import { @@ -23,14 +24,13 @@ import { withFallbackStyles, } from '@wordpress/components'; import { - __experimentalGradientPickerPanel, - __experimentalUseGradient, + URLInput, + RichText, ContrastChecker, InspectorControls, - PanelColorSettings, - RichText, - URLInput, withColors, + PanelColorSettings, + __experimentalGradientPickerControl, } from '@wordpress/block-editor'; const { getComputedStyle } = window; @@ -74,163 +74,177 @@ function BorderPanel( { borderRadius = '', setAttributes } ) { ); } -function ButtonEdit( { - attributes, - backgroundColor, - textColor, - setBackgroundColor, - setTextColor, - fallbackBackgroundColor, - fallbackTextColor, - setAttributes, - className, - instanceId, - isSelected, -} ) { - const { - borderRadius, - linkTarget, - placeholder, - rel, - text, - title, - url, - } = attributes; - const onSetLinkRel = useCallback( - ( value ) => { - setAttributes( { rel: value } ); - }, - [ setAttributes ] - ); +class ButtonEdit extends Component { + constructor() { + super( ...arguments ); + this.nodeRef = null; + this.bindRef = this.bindRef.bind( this ); + this.onSetLinkRel = this.onSetLinkRel.bind( this ); + this.onToggleOpenInNewTab = this.onToggleOpenInNewTab.bind( this ); + } - const onToggleOpenInNewTab = useCallback( - ( value ) => { - const newLinkTarget = value ? '_blank' : undefined; - - let updatedRel = rel; - if ( newLinkTarget && ! rel ) { - updatedRel = NEW_TAB_REL; - } else if ( ! newLinkTarget && rel === NEW_TAB_REL ) { - updatedRel = undefined; - } - - setAttributes( { - linkTarget: newLinkTarget, - rel: updatedRel, - } ); - }, - [ rel, setAttributes ] - ); - const { - gradientClass, - gradientValue, - setGradient, - } = __experimentalUseGradient(); + bindRef( node ) { + if ( ! node ) { + return; + } + this.nodeRef = node; + } - const linkId = `wp-block-button__inline-link-${ instanceId }`; - return ( - <div className={ className } title={ title }> - <RichText - placeholder={ placeholder || __( 'Add text…' ) } - value={ text } - onChange={ ( value ) => setAttributes( { text: value } ) } - withoutInteractiveFormatting - className={ classnames( - 'wp-block-button__link', { - 'has-background': backgroundColor.color || gradientValue, - [ backgroundColor.class ]: ! gradientValue && backgroundColor.class, - 'has-text-color': textColor.color, - [ textColor.class ]: textColor.class, - [ gradientClass ]: gradientClass, - 'no-border-radius': borderRadius === 0, - } - ) } - style={ { - ...( ! backgroundColor.color && gradientValue ? - { background: gradientValue } : - { backgroundColor: backgroundColor.color } - ), - color: textColor.color, - borderRadius: borderRadius ? borderRadius + 'px' : undefined, - } } - /> - <BaseControl - label={ __( 'Link' ) } - className="wp-block-button__inline-link" - id={ linkId }> - <URLInput - className="wp-block-button__inline-link-input" - value={ url } - /* eslint-disable jsx-a11y/no-autofocus */ - // Disable Reason: The rule is meant to prevent enabling auto-focus, not disabling it. - autoFocus={ false } - /* eslint-enable jsx-a11y/no-autofocus */ - onChange={ ( value ) => setAttributes( { url: value } ) } - disableSuggestions={ ! isSelected } - id={ linkId } - isFullWidth - hasBorder - /> - </BaseControl> - <InspectorControls> - <PanelColorSettings - title={ __( 'Color Settings' ) } - colorSettings={ [ - { - value: backgroundColor.color, - onChange: ( newColor ) => { - setAttributes( { customGradient: undefined } ); - setBackgroundColor( newColor ); - }, - label: __( 'Background Color' ), - }, - { - value: textColor.color, - onChange: setTextColor, - label: __( 'Text Color' ), - }, - ] } - > - <ContrastChecker - { ...{ - // Text is considered large if font size is greater or equal to 18pt or 24px, - // currently that's not the case for button. - isLargeText: false, - textColor: textColor.color, - backgroundColor: backgroundColor.color, - fallbackBackgroundColor, - fallbackTextColor, - } } - /> - </PanelColorSettings> - <__experimentalGradientPickerPanel - onChange={ - ( newGradient ) => { - setGradient( newGradient ); - setBackgroundColor(); + onSetLinkRel( value ) { + this.props.setAttributes( { rel: value } ); + } + + onToggleOpenInNewTab( value ) { + const { rel } = this.props.attributes; + const linkTarget = value ? '_blank' : undefined; + + let updatedRel = rel; + if ( linkTarget && ! rel ) { + updatedRel = NEW_TAB_REL; + } else if ( ! linkTarget && rel === NEW_TAB_REL ) { + updatedRel = undefined; + } + + this.props.setAttributes( { + linkTarget, + rel: updatedRel, + } ); + } + + render() { + const { + attributes, + backgroundColor, + textColor, + setBackgroundColor, + setTextColor, + fallbackBackgroundColor, + fallbackTextColor, + setAttributes, + className, + instanceId, + isSelected, + } = this.props; + + const { + borderRadius, + linkTarget, + placeholder, + rel, + text, + title, + url, + customGradient, + } = attributes; + + const linkId = `wp-block-button__inline-link-${ instanceId }`; + + return ( + <div className={ className } title={ title } ref={ this.bindRef }> + <RichText + placeholder={ placeholder || __( 'Add text…' ) } + value={ text } + onChange={ ( value ) => setAttributes( { text: value } ) } + withoutInteractiveFormatting + className={ classnames( + 'wp-block-button__link', { + 'has-background': backgroundColor.color || customGradient, + [ backgroundColor.class ]: ! customGradient && backgroundColor.class, + 'has-text-color': textColor.color, + [ textColor.class ]: textColor.class, + 'no-border-radius': borderRadius === 0, } - } - value={ gradientValue } - /> - <BorderPanel - borderRadius={ borderRadius } - setAttributes={ setAttributes } + ) } + style={ { + backgroundColor: ! customGradient && backgroundColor.color, + background: customGradient, + color: textColor.color, + borderRadius: borderRadius ? borderRadius + 'px' : undefined, + } } /> - <PanelBody title={ __( 'Link settings' ) }> - <ToggleControl - label={ __( 'Open in new tab' ) } - onChange={ onToggleOpenInNewTab } - checked={ linkTarget === '_blank' } + <BaseControl + label={ __( 'Link' ) } + className="wp-block-button__inline-link" + id={ linkId }> + <URLInput + className="wp-block-button__inline-link-input" + value={ url } + /* eslint-disable jsx-a11y/no-autofocus */ + // Disable Reason: The rule is meant to prevent enabling auto-focus, not disabling it. + autoFocus={ false } + /* eslint-enable jsx-a11y/no-autofocus */ + onChange={ ( value ) => setAttributes( { url: value } ) } + disableSuggestions={ ! isSelected } + id={ linkId } + isFullWidth + hasBorder /> - <TextControl - label={ __( 'Link rel' ) } - value={ rel || '' } - onChange={ onSetLinkRel } + </BaseControl> + <InspectorControls> + <PanelColorSettings + title={ __( 'Color Settings' ) } + colorSettings={ [ + { + value: backgroundColor.color, + onChange: ( newColor ) => { + setAttributes( { customGradient: undefined } ); + setBackgroundColor( newColor ); + }, + label: __( 'Background Color' ), + }, + { + value: textColor.color, + onChange: setTextColor, + label: __( 'Text Color' ), + }, + ] } + > + <ContrastChecker + { ...{ + // Text is considered large if font size is greater or equal to 18pt or 24px, + // currently that's not the case for button. + isLargeText: false, + textColor: textColor.color, + backgroundColor: backgroundColor.color, + fallbackBackgroundColor, + fallbackTextColor, + } } + /> + </PanelColorSettings> + <PanelBody title={ __( 'Gradient' ) }> + <__experimentalGradientPickerControl + onChange={ + ( newGradient ) => { + setAttributes( { + customGradient: newGradient, + backgroundColor: undefined, + customBackgroundColor: undefined, + } ); + } + } + value={ customGradient } + /> + </PanelBody> + <BorderPanel + borderRadius={ borderRadius } + setAttributes={ setAttributes } /> - </PanelBody> - </InspectorControls> - </div> - ); + <PanelBody title={ __( 'Link settings' ) }> + <ToggleControl + label={ __( 'Open in new tab' ) } + onChange={ this.onToggleOpenInNewTab } + checked={ linkTarget === '_blank' } + /> + <TextControl + label={ __( 'Link rel' ) } + value={ rel || '' } + onChange={ this.onSetLinkRel } + /> + </PanelBody> + </InspectorControls> + </div> + ); + } } export default compose( [ diff --git a/packages/block-library/src/button/save.js b/packages/block-library/src/button/save.js index 59eaa9f201217e..bcf18ffc293242 100644 --- a/packages/block-library/src/button/save.js +++ b/packages/block-library/src/button/save.js @@ -9,7 +9,6 @@ import classnames from 'classnames'; import { RichText, getColorClassName, - __experimentalGetGradientClass, } from '@wordpress/block-editor'; export default function save( { attributes } ) { @@ -20,7 +19,6 @@ export default function save( { attributes } ) { customTextColor, customGradient, linkTarget, - gradient, rel, text, textColor, @@ -30,20 +28,18 @@ export default function save( { attributes } ) { const textClass = getColorClassName( 'color', textColor ); const backgroundClass = ! customGradient && getColorClassName( 'background-color', backgroundColor ); - const gradientClass = __experimentalGetGradientClass( gradient ); const buttonClasses = classnames( 'wp-block-button__link', { 'has-text-color': textColor || customTextColor, [ textClass ]: textClass, - 'has-background': backgroundColor || customBackgroundColor || customGradient || gradient, + 'has-background': backgroundColor || customBackgroundColor || customGradient, [ backgroundClass ]: backgroundClass, 'no-border-radius': borderRadius === 0, - [ gradientClass ]: gradientClass, } ); const buttonStyle = { + backgroundColor: backgroundClass || customGradient ? undefined : customBackgroundColor, background: customGradient ? customGradient : undefined, - backgroundColor: backgroundClass || customGradient || gradient ? undefined : customBackgroundColor, color: textClass ? undefined : customTextColor, borderRadius: borderRadius ? borderRadius + 'px' : undefined, }; diff --git a/packages/block-library/src/columns/deprecated.js b/packages/block-library/src/columns/deprecated.js index a344f72eaf69f3..56ffe5d90bc6a1 100644 --- a/packages/block-library/src/columns/deprecated.js +++ b/packages/block-library/src/columns/deprecated.js @@ -66,7 +66,7 @@ export default [ ) ); }, migrate( attributes, innerBlocks ) { - const columns = innerBlocks.reduce( ( accumulator, innerBlock ) => { + const columns = innerBlocks.reduce( ( result, innerBlock ) => { const { originalContent } = innerBlock; let columnIndex = getDeprecatedLayoutColumn( originalContent ); @@ -74,13 +74,13 @@ export default [ columnIndex = 0; } - if ( ! accumulator[ columnIndex ] ) { - accumulator[ columnIndex ] = []; + if ( ! result[ columnIndex ] ) { + result[ columnIndex ] = []; } - accumulator[ columnIndex ].push( innerBlock ); + result[ columnIndex ].push( innerBlock ); - return accumulator; + return result; }, [] ); const migratedInnerBlocks = columns.map( ( columnBlocks ) => ( diff --git a/packages/block-library/src/columns/editor.scss b/packages/block-library/src/columns/editor.scss index 60c6730fc2b088..dfa71f9f0589b3 100644 --- a/packages/block-library/src/columns/editor.scss +++ b/packages/block-library/src/columns/editor.scss @@ -12,6 +12,18 @@ } } +// Fullwide: show margin left/right to ensure there's room for the side UI. +// This is not a 1:1 preview with the front-end where these margins would presumably be zero. +[data-type="core/columns"][data-align="full"] .wp-block-columns > .editor-inner-blocks { + padding-left: $block-padding; + padding-right: $block-padding; + + @include break-small() { + padding-left: $block-container-side-padding; + padding-right: $block-container-side-padding; + } +} + .wp-block-columns { display: block; @@ -31,14 +43,7 @@ > [data-type="core/column"] > .editor-block-list__block-edit .block-core-columns { display: flex; flex-direction: column; - - // This flex rule fixes an issue in IE11. - flex: 1 1 auto; - - // IE11 does not support `position: sticky`, so we use it here to serve correct Flex rules to modern browsers. - @supports (position: sticky) { - flex: 1; - } + flex: 1 0 auto; } // Adjust the individual column block. @@ -176,10 +181,10 @@ div.block-core-columns.is-vertically-aligned-bottom { /** * Add extra padding when the parent block is selected, for easier interaction. */ -[data-type="core/columns"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -[data-type="core/columns"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -[data-type="core/column"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -[data-type="core/column"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks { +.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/columns"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/columns"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/column"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/column"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks { padding: $block-padding; // Negate this padding for the placeholder. @@ -188,16 +193,3 @@ div.block-core-columns.is-vertically-aligned-bottom { width: calc(100% + #{$block-padding * 2}); } } - - -// Fullwide: show margin left/right to ensure there's room for the side UI. -// This is not a 1:1 preview with the front-end where these margins would presumably be zero. -[data-type="core/columns"][data-align="full"] .wp-block-columns { - padding-left: $block-padding; - padding-right: $block-padding; - - @include break-small() { - padding-left: $block-container-side-padding; - padding-right: $block-container-side-padding; - } -} diff --git a/packages/block-library/src/columns/utils.js b/packages/block-library/src/columns/utils.js index a6773d469c98f7..77a0b7cf4375a8 100644 --- a/packages/block-library/src/columns/utils.js +++ b/packages/block-library/src/columns/utils.js @@ -87,9 +87,9 @@ export function getTotalColumnsWidth( blocks, totalBlockCount = blocks.length ) * @return {Object<string,number>} Column widths. */ export function getColumnWidths( blocks, totalBlockCount = blocks.length ) { - return blocks.reduce( ( accumulator, block ) => { + return blocks.reduce( ( result, block ) => { const width = getEffectiveColumnWidth( block, totalBlockCount ); - return Object.assign( accumulator, { [ block.clientId ]: width } ); + return Object.assign( result, { [ block.clientId ]: width } ); }, {} ); } diff --git a/packages/block-library/src/cover/block.json b/packages/block-library/src/cover/block.json index 67e87f54c8374b..957a8264ef6e6e 100644 --- a/packages/block-library/src/cover/block.json +++ b/packages/block-library/src/cover/block.json @@ -31,9 +31,6 @@ }, "minHeight": { "type": "number" - }, - "customGradient": { - "type": "string" } } } diff --git a/packages/block-library/src/cover/edit.js b/packages/block-library/src/cover/edit.js index 1bc69c5d9af860..1994f4a57e0713 100644 --- a/packages/block-library/src/cover/edit.js +++ b/packages/block-library/src/cover/edit.js @@ -39,8 +39,6 @@ import { PanelColorSettings, withColors, ColorPalette, - __experimentalGradientPickerControl, - __experimentalGradientPicker, } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; import { withDispatch } from '@wordpress/data'; @@ -112,7 +110,7 @@ const CoverHeightInput = withInstanceId( onBlur={ onBlurEvent } value={ temporaryInput !== null ? temporaryInput : value } min={ COVER_MIN_HEIGHT } - step="1" + step="10" /> </BaseControl> ); @@ -221,13 +219,12 @@ class CoverEdit extends Component { } = this.props; const { backgroundType, - customGradient, dimRatio, focalPoint, hasParallax, id, - minHeight, url, + minHeight, } = attributes; const onSelectMedia = ( media ) => { if ( ! media || ! media.url ) { @@ -285,20 +282,14 @@ class CoverEdit extends Component { minHeight: ( temporaryMinHeight || minHeight ), }; - if ( customGradient && ! url ) { - style.background = customGradient; - } - if ( focalPoint ) { style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`; } - const hasBackground = !! ( url || overlayColor.color || customGradient ); - const controls = ( <> <BlockControls> - { hasBackground && ( + { !! ( url || overlayColor.color ) && ( <> <MediaUploadCheck> <Toolbar> @@ -357,7 +348,7 @@ class CoverEdit extends Component { </PanelRow> </PanelBody> ) } - { hasBackground && ( + { ( url || overlayColor.color ) && ( <> <PanelBody title={ __( 'Dimensions' ) }> <CoverHeightInput @@ -376,28 +367,10 @@ class CoverEdit extends Component { initialOpen={ true } colorSettings={ [ { value: overlayColor.color, - onChange: ( ...args ) => { - setAttributes( { - customGradient: undefined, - } ); - setOverlayColor( ...args ); - }, + onChange: setOverlayColor, label: __( 'Overlay Color' ), } ] } > - <__experimentalGradientPickerControl - label={ __( 'Overlay Gradient' ) } - onChange={ - ( newGradient ) => { - setAttributes( { - customGradient: newGradient, - customOverlayColor: undefined, - overlayColor: undefined, - } ); - } - } - value={ customGradient } - /> { !! url && ( <RangeControl label={ __( 'Background Opacity' ) } @@ -416,7 +389,7 @@ class CoverEdit extends Component { </> ); - if ( ! hasBackground ) { + if ( ! ( url || overlayColor.color ) ) { const placeholderIcon = <BlockIcon icon={ icon } />; const label = __( 'Cover' ); @@ -436,29 +409,13 @@ class CoverEdit extends Component { notices={ noticeUI } onError={ this.onUploadError } > - <div - className="wp-block-cover__placeholder-background-options" - > - <ColorPalette - disableCustomColors={ true } - value={ overlayColor.color } - onChange={ setOverlayColor } - clearable={ false } - /> - <__experimentalGradientPicker - onChange={ - ( newGradient ) => { - setAttributes( { - customGradient: newGradient, - customOverlayColor: undefined, - overlayColor: undefined, - } ); - } - } - value={ customGradient } - clearable={ false } - /> - </div> + <ColorPalette + disableCustomColors={ true } + value={ overlayColor.color } + onChange={ setOverlayColor } + clearable={ false } + className="wp-block-cover__placeholder-color-palette" + /> </MediaPlaceholder> </> ); @@ -472,7 +429,6 @@ class CoverEdit extends Component { 'has-background-dim': dimRatio !== 0, 'has-parallax': hasParallax, [ overlayColor.class ]: overlayColor.class, - 'has-background-gradient': customGradient, } ); @@ -520,13 +476,6 @@ class CoverEdit extends Component { src={ url } /> ) } - { url && customGradient && dimRatio !== 0 && ( - <span - aria-hidden="true" - className="wp-block-cover__gradient-background" - style={ { background: customGradient } } - /> - ) } { VIDEO_BACKGROUND_TYPE === backgroundType && ( <video ref={ this.videoRef } diff --git a/packages/block-library/src/cover/editor.scss b/packages/block-library/src/cover/editor.scss index 906ffe172b9f9a..b40aed0a472b30 100644 --- a/packages/block-library/src/cover/editor.scss +++ b/packages/block-library/src/cover/editor.scss @@ -34,11 +34,10 @@ } } - .wp-block-cover__placeholder-background-options { + .wp-block-cover__placeholder-color-palette { // wraps about 6 color swatches max-width: 290px; margin-top: 1em; - width: 100%; } // Apply max-width to floated items that have no intrinsic width diff --git a/packages/block-library/src/cover/save.js b/packages/block-library/src/cover/save.js index 806be32a100f87..de057122a0f7b7 100644 --- a/packages/block-library/src/cover/save.js +++ b/packages/block-library/src/cover/save.js @@ -24,7 +24,6 @@ import { export default function save( { attributes } ) { const { backgroundType, - customGradient, customOverlayColor, dimRatio, focalPoint, @@ -43,9 +42,6 @@ export default function save( { attributes } ) { if ( focalPoint && ! hasParallax ) { style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`; } - if ( customGradient && ! url ) { - style.background = customGradient; - } style.minHeight = minHeight || undefined; const classes = classnames( @@ -54,19 +50,11 @@ export default function save( { attributes } ) { { 'has-background-dim': dimRatio !== 0, 'has-parallax': hasParallax, - 'has-background-gradient': customGradient, }, ); return ( <div className={ classes } style={ style }> - { url && customGradient && dimRatio !== 0 && ( - <span - aria-hidden="true" - className="wp-block-cover__gradient-background" - style={ { background: customGradient } } - /> - ) } { VIDEO_BACKGROUND_TYPE === backgroundType && url && ( <video className="wp-block-cover__video-background" autoPlay diff --git a/packages/block-library/src/cover/style.scss b/packages/block-library/src/cover/style.scss index 739742d1e62270..5cf70fabe760b3 100644 --- a/packages/block-library/src/cover/style.scss +++ b/packages/block-library/src/cover/style.scss @@ -30,33 +30,19 @@ &.has-background-dim::before { content: ""; - background-color: inherit; - } - - &.has-background-dim:not(.has-background-gradient)::before, - .wp-block-cover__gradient-background { position: absolute; top: 0; left: 0; bottom: 0; right: 0; - z-index: z-index(".wp-block-cover.has-background-dim::before"); - } - - &.has-background-dim:not(.has-background-gradient)::before, - & .wp-block-cover__gradient-background { + background-color: inherit; opacity: 0.5; + z-index: z-index(".wp-block-cover.has-background-dim::before"); } - @for $i from 1 through 10 { - &.has-background-dim.has-background-dim-#{ $i * 10 } { - &:not(.has-background-gradient)::before { - opacity: $i * 0.1; - } - .wp-block-cover__gradient-background { - opacity: $i * 0.1; - } + &.has-background-dim.has-background-dim-#{ $i * 10 }::before { + opacity: $i * 0.1; } } diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index 59569f4105ba2c..71d6eb65a27f53 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -17,6 +17,7 @@ @import "./latest-posts/editor.scss"; @import "./legacy-widget/editor.scss"; @import "./media-text/editor.scss"; +@import "./list/editor.scss"; @import "./more/editor.scss"; @import "./navigation-menu/editor.scss"; @import "./navigation-menu-item/editor.scss"; @@ -36,7 +37,6 @@ @import "./text-columns/editor.scss"; @import "./verse/editor.scss"; @import "./video/editor.scss"; -@import "./site-title/editor.scss"; /** * Import styles from internal editor components used by the blocks. diff --git a/packages/block-library/src/embed/test/__snapshots__/index.js.snap b/packages/block-library/src/embed/test/__snapshots__/index.js.snap index 2023cab5e5b65f..78923aa24c5f6b 100644 --- a/packages/block-library/src/embed/test/__snapshots__/index.js.snap +++ b/packages/block-library/src/embed/test/__snapshots__/index.js.snap @@ -61,7 +61,7 @@ exports[`core/embed block edit matches snapshot 1`] = ` > Learn more about embeds <span - class="components-visually-hidden" + class="screen-reader-text" > (opens in a new tab) </span> diff --git a/packages/block-library/src/file/edit.js b/packages/block-library/src/file/edit.js index 503345f8b14076..c6f6382a1336d4 100644 --- a/packages/block-library/src/file/edit.js +++ b/packages/block-library/src/file/edit.js @@ -257,11 +257,11 @@ export default compose( [ withSelect( ( select, props ) => { const { getMedia } = select( 'core' ); const { getSettings } = select( 'core/block-editor' ); - const { mediaUpload } = getSettings(); + const { __experimentalMediaUpload } = getSettings(); const { id } = props.attributes; return { media: id === undefined ? undefined : getMedia( id ), - mediaUpload, + mediaUpload: __experimentalMediaUpload, }; } ), withNotices, diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index d4f51b1565cffe..449711a356ea42 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -379,8 +379,13 @@ class GalleryEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { mediaUpload } = getSettings(); - return { mediaUpload }; + const { + __experimentalMediaUpload, + } = getSettings(); + + return { + mediaUpload: __experimentalMediaUpload, + }; } ), withNotices, ] )( GalleryEdit ); diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index 5931d95b5300ff..ae36e0aa74ac33 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -17,10 +17,8 @@ figure.wp-block-gallery { margin: 0; } -// Necessary to to override default editor ul styles. +// need to override default editor ul styles .blocks-gallery-grid.blocks-gallery-grid { - padding-left: 0; - margin-left: 0; margin-bottom: 0; } diff --git a/packages/block-library/src/group/index.js b/packages/block-library/src/group/index.js index 956ded85aa22a1..d3bcfb86dca119 100644 --- a/packages/block-library/src/group/index.js +++ b/packages/block-library/src/group/index.js @@ -97,9 +97,9 @@ export const settings = { const alignments = [ 'wide', 'full' ]; // Determine the widest setting of all the blocks to be grouped - const widestAlignment = blocks.reduce( ( accumulator, block ) => { + const widestAlignment = blocks.reduce( ( result, block ) => { const { align } = block.attributes; - return alignments.indexOf( align ) > alignments.indexOf( accumulator ) ? align : accumulator; + return alignments.indexOf( align ) > alignments.indexOf( result ) ? align : result; }, undefined ); // Clone the Blocks to be Grouped diff --git a/packages/block-library/src/heading/edit.js b/packages/block-library/src/heading/edit.js index 241a327bb42c1a..d500309a0c9aad 100644 --- a/packages/block-library/src/heading/edit.js +++ b/packages/block-library/src/heading/edit.js @@ -12,37 +12,49 @@ import HeadingToolbar from './heading-toolbar'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { PanelBody, withFallbackStyles } from '@wordpress/components'; +import { PanelBody } from '@wordpress/components'; +import { compose } from '@wordpress/compose'; import { createBlock } from '@wordpress/blocks'; import { AlignmentToolbar, BlockControls, InspectorControls, RichText, - __experimentalUseColors, + withColors, + PanelColorSettings, } from '@wordpress/block-editor'; +import { memo } from '@wordpress/element'; -/** - * Browser dependencies - */ -const { getComputedStyle } = window; +const HeadingColorUI = memo( + function( { + textColorValue, + setTextColor, + } ) { + return ( + <PanelColorSettings + title={ __( 'Color Settings' ) } + initialOpen={ false } + colorSettings={ [ + { + value: textColorValue, + onChange: setTextColor, + label: __( 'Text Color' ), + }, + ] } + /> + ); + } +); function HeadingEdit( { - backgroundColor, attributes, setAttributes, mergeBlocks, onReplace, className, + textColor, + setTextColor, } ) { - const { TextColor, InspectorControlsColorPanel } = __experimentalUseColors( - [ { name: 'textColor', property: 'color' } ], - { - contrastCheckerProps: { backgroundColor, isLargeText: true }, - }, - [] - ); - const { align, content, level, placeholder } = attributes; const tagName = 'h' + level; @@ -59,42 +71,43 @@ function HeadingEdit( { <p>{ __( 'Level' ) }</p> <HeadingToolbar isCollapsed={ false } minLevel={ 1 } maxLevel={ 7 } selectedLevel={ level } onChange={ ( newLevel ) => setAttributes( { level: newLevel } ) } /> </PanelBody> + <HeadingColorUI + setTextColor={ setTextColor } + textColorValue={ textColor.color } + /> </InspectorControls> - { InspectorControlsColorPanel } - <TextColor> - <RichText - identifier="content" - tagName={ tagName } - value={ content } - onChange={ ( value ) => setAttributes( { content: value } ) } - onMerge={ mergeBlocks } - onSplit={ ( value ) => { - if ( ! value ) { - return createBlock( 'core/paragraph' ); - } + <RichText + identifier="content" + tagName={ tagName } + value={ content } + onChange={ ( value ) => setAttributes( { content: value } ) } + onMerge={ mergeBlocks } + onSplit={ ( value ) => { + if ( ! value ) { + return createBlock( 'core/paragraph' ); + } - return createBlock( 'core/heading', { - ...attributes, - content: value, - } ); - } } - onReplace={ onReplace } - onRemove={ () => onReplace( [] ) } - className={ classnames( className, { - [ `has-text-align-${ align }` ]: align, - } ) } - placeholder={ placeholder || __( 'Write heading…' ) } - /> - </TextColor> + return createBlock( 'core/heading', { + ...attributes, + content: value, + } ); + } } + onReplace={ onReplace } + onRemove={ () => onReplace( [] ) } + className={ classnames( className, { + [ `has-text-align-${ align }` ]: align, + 'has-text-color': textColor.color, + [ textColor.class ]: textColor.class, + } ) } + placeholder={ placeholder || __( 'Write heading…' ) } + style={ { + color: textColor.color, + } } + /> </> ); } -export default withFallbackStyles( ( node ) => { - let backgroundColor = getComputedStyle( node ).backgroundColor; - while ( backgroundColor === 'rgba(0, 0, 0, 0)' && node.parentNode ) { - node = node.parentNode; - backgroundColor = getComputedStyle( node ).backgroundColor; - } - return { backgroundColor }; -} )( HeadingEdit ); +export default compose( [ + withColors( 'backgroundColor', { textColor: 'color' } ), +] )( HeadingEdit ); diff --git a/packages/block-library/src/image/constants.js b/packages/block-library/src/image/constants.js index ec8c41b8b09c31..cd5e82b323bed5 100644 --- a/packages/block-library/src/image/constants.js +++ b/packages/block-library/src/image/constants.js @@ -3,6 +3,6 @@ export const LINK_DESTINATION_NONE = 'none'; export const LINK_DESTINATION_MEDIA = 'media'; export const LINK_DESTINATION_ATTACHMENT = 'attachment'; export const LINK_DESTINATION_CUSTOM = 'custom'; -export const NEW_TAB_REL = [ 'noreferrer', 'noopener' ]; +export const NEW_TAB_REL = 'noreferrer noopener'; export const ALLOWED_MEDIA_TYPES = [ 'image' ]; export const DEFAULT_SIZE_SLUG = 'large'; diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index c5dfdc20b97148..b5779e71180e7d 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -25,6 +25,7 @@ import { NavigableMenu, PanelBody, Path, + Rect, ResizableBox, SelectControl, Spinner, @@ -69,9 +70,9 @@ import { speak } from '@wordpress/a11y'; * Internal dependencies */ import { createUpgradedEmbedBlock } from '../embed/util'; -import icon, { editImageIcon } from './icon'; +import icon from './icon'; import ImageSize from './image-size'; -import { getUpdatedLinkTargetSettings, removeNewTabRel } from './utils'; +import { getUpdatedLinkTargetSettings } from './utils'; /** * Module constants @@ -584,8 +585,8 @@ export class ImageEdit extends Component { sizeSlug, } = attributes; - const cleanRel = removeNewTabRel( rel ); const isExternal = isExternalImage( id, url ); + const editImageIcon = ( <SVG width={ 20 } height={ 20 } viewBox="0 0 20 20"><Rect x={ 11 } y={ 3 } width={ 7 } height={ 5 } rx={ 1 } /><Rect x={ 2 } y={ 12 } width={ 7 } height={ 5 } rx={ 1 } /><Path d="M13,12h1a3,3,0,0,1-3,3v2a5,5,0,0,0,5-5h1L15,9Z" /><Path d="M4,8H3l2,3L7,8H6A3,3,0,0,1,9,5V3A5,5,0,0,0,4,8Z" /></SVG> ); const controls = ( <BlockControls> <BlockAlignmentToolbar @@ -616,18 +617,18 @@ export class ImageEdit extends Component { onChange={ this.onSetNewTab } checked={ linkTarget === '_blank' } /> <TextControl - label={ __( 'Link Rel' ) } - value={ cleanRel || '' } - onChange={ this.onSetLinkRel } + label={ __( 'Link CSS Class' ) } + value={ linkClass || '' } onKeyPress={ stopPropagation } onKeyDown={ stopPropagationRelevantKeys } + onChange={ this.onSetLinkClass } /> <TextControl - label={ __( 'Link CSS Class' ) } - value={ linkClass || '' } + label={ __( 'Link Rel' ) } + value={ rel || '' } + onChange={ this.onSetLinkRel } onKeyPress={ stopPropagation } onKeyDown={ stopPropagationRelevantKeys } - onChange={ this.onSetLinkClass } /> </> } @@ -930,7 +931,7 @@ export default compose( [ const { getSettings } = select( 'core/block-editor' ); const { attributes: { id }, isSelected } = props; const { - mediaUpload, + __experimentalMediaUpload, imageSizes, isRTL, maxWidth, @@ -941,7 +942,7 @@ export default compose( [ maxWidth, isRTL, imageSizes, - mediaUpload, + mediaUpload: __experimentalMediaUpload, }; } ), withViewportMatch( { isLargeViewport: 'medium' } ), diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 1d9274c3754697..ce2c1affe275a5 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -9,7 +9,7 @@ import { requestImageFailedRetryDialog, requestImageUploadCancelDialog, } from 'react-native-gutenberg-bridge'; -import { isEmpty, map } from 'lodash'; +import { isEmpty } from 'lodash'; /** * WordPress dependencies @@ -17,12 +17,10 @@ import { isEmpty, map } from 'lodash'; import { TextControl, ToggleControl, - SelectControl, Icon, Toolbar, ToolbarButton, PanelBody, - PanelActions, } from '@wordpress/components'; import { @@ -33,7 +31,6 @@ import { MEDIA_TYPE_IMAGE, BlockControls, InspectorControls, - BlockAlignmentToolbar, } from '@wordpress/block-editor'; import { __, sprintf } from '@wordpress/i18n'; import { isURL } from '@wordpress/url'; @@ -44,7 +41,7 @@ import { withPreferredColorScheme } from '@wordpress/compose'; * Internal dependencies */ import styles from './styles.scss'; -import SvgIcon, { editImageIcon } from './icon'; +import SvgIcon from './icon'; import SvgIconRetry from './icon-retry'; import { getUpdatedLinkTargetSettings } from './utils'; @@ -53,19 +50,6 @@ import { LINK_DESTINATION_NONE, } from './constants'; -const IMAGE_SIZE_THUMBNAIL = 'thumbnail'; -const IMAGE_SIZE_MEDIUM = 'medium'; -const IMAGE_SIZE_LARGE = 'large'; -const IMAGE_SIZE_FULL_SIZE = 'full'; -const DEFAULT_SIZE_SLUG = IMAGE_SIZE_LARGE; -const sizeOptionLabels = { - [ IMAGE_SIZE_THUMBNAIL ]: __( 'Thumbnail' ), - [ IMAGE_SIZE_MEDIUM ]: __( 'Medium' ), - [ IMAGE_SIZE_LARGE ]: __( 'Large' ), - [ IMAGE_SIZE_FULL_SIZE ]: __( 'Full Size' ), -}; -const sizeOptions = map( sizeOptionLabels, ( label, option ) => ( { value: option, label } ) ); - // Default Image ratio 4:3 const IMAGE_ASPECT_RATIO = 4 / 3; @@ -86,11 +70,9 @@ export class ImageEdit extends React.Component { this.updateImageURL = this.updateImageURL.bind( this ); this.onSetLinkDestination = this.onSetLinkDestination.bind( this ); this.onSetNewTab = this.onSetNewTab.bind( this ); - this.onSetSizeSlug = this.onSetSizeSlug.bind( this ); this.onImagePressed = this.onImagePressed.bind( this ); this.onClearSettings = this.onClearSettings.bind( this ); this.onFocusCaption = this.onFocusCaption.bind( this ); - this.updateAlignment = this.updateAlignment.bind( this ); } componentDidMount() { @@ -104,18 +86,14 @@ export class ImageEdit extends React.Component { console.warn( 'Attributes has id with no url.' ); } - // Detect any pasted image and start an upload - if ( ! attributes.id && attributes.url && attributes.url.indexOf( 'file:' ) === 0 ) { - requestMediaImport( attributes.url, ( id, url ) => { - if ( url ) { - setAttributes( { id, url } ); - } - } ); - } - - // Make sure we mark any temporary images as failed if they failed while - // the editor wasn't open if ( attributes.id && attributes.url && ! isURL( attributes.url ) ) { + if ( attributes.url.indexOf( 'file:' ) === 0 ) { + requestMediaImport( attributes.url, ( id, url ) => { + if ( url ) { + setAttributes( { id, url } ); + } + } ); + } mediaUploadSync(); } } @@ -189,10 +167,6 @@ export class ImageEdit extends React.Component { this.props.setAttributes( { url, width: undefined, height: undefined } ); } - updateAlignment( nextAlign ) { - this.props.setAttributes( { align: nextAlign } ); - } - onSetLinkDestination( href ) { this.props.setAttributes( { linkDestination: LINK_DESTINATION_CUSTOM, @@ -205,19 +179,12 @@ export class ImageEdit extends React.Component { this.props.setAttributes( updatedLinkTarget ); } - onSetSizeSlug( sizeSlug ) { - this.props.setAttributes( { - sizeSlug, - } ); - } - onClearSettings() { this.props.setAttributes( { alt: '', linkDestination: LINK_DESTINATION_NONE, href: undefined, linkTarget: undefined, - sizeSlug: DEFAULT_SIZE_SLUG, rel: undefined, } ); } @@ -249,24 +216,17 @@ export class ImageEdit extends React.Component { render() { const { attributes, isSelected } = this.props; - const { align, url, height, width, alt, href, id, linkTarget, sizeSlug } = attributes; - - const actions = [ { label: __( 'Clear All Settings' ), onPress: this.onClearSettings } ]; + const { url, height, width, alt, href, id, linkTarget } = attributes; const getToolbarEditButton = ( open ) => ( <BlockControls> <Toolbar> <ToolbarButton title={ __( 'Edit image' ) } - icon={ editImageIcon } + icon="edit" onClick={ open } /> </Toolbar> - <BlockAlignmentToolbar - value={ align } - onChange={ this.updateAlignment } - isCollapsed={ false } - /> </BlockControls> ); @@ -289,26 +249,21 @@ export class ImageEdit extends React.Component { checked={ linkTarget === '_blank' } onChange={ this.onSetNewTab } /> - { // eslint-disable-next-line no-undef - __DEV__ && - <SelectControl - hideCancelButton - icon={ 'editor-expand' } - label={ __( 'Size' ) } - value={ sizeOptionLabels[ sizeSlug || DEFAULT_SIZE_SLUG ] } - onChangeValue={ ( newValue ) => this.onSetSizeSlug( newValue ) } - options={ sizeOptions } - /> } <TextControl icon={ 'editor-textcolor' } label={ __( 'Alt Text' ) } value={ alt || '' } valuePlaceholder={ __( 'None' ) } + separatorType={ 'fullWidth' } + onChange={ this.updateAlt } + /> + <TextControl + label={ __( 'Clear All Settings' ) } + labelStyle={ styles.clearSettingsButton } separatorType={ 'none' } - onChangeValue={ this.updateAlt } + onPress={ this.onClearSettings } /> </PanelBody> - <PanelActions actions={ actions } /> </InspectorControls> ); @@ -325,14 +280,6 @@ export class ImageEdit extends React.Component { ); } - const alignToFlex = { - left: 'flex-start', - center: 'center', - right: 'flex-end', - full: 'center', - wide: 'center', - }; - const imageContainerHeight = Dimensions.get( 'window' ).width / IMAGE_ASPECT_RATIO; const getImageComponent = ( openMediaOptions, getMediaOptions ) => ( <TouchableWithoutFeedback @@ -367,7 +314,7 @@ export class ImageEdit extends React.Component { ); return ( - <View style={ { flex: 1, alignSelf: alignToFlex[ align ] } } > + <View style={ { flex: 1 } } > { ! imageWidthWithinContainer && <View style={ [ styles.imageContainer, { height: imageContainerHeight } ] } > { this.getIcon( false ) } diff --git a/packages/block-library/src/image/icon.js b/packages/block-library/src/image/icon.js index 44f88783d24cfa..b029bab8fbe98a 100644 --- a/packages/block-library/src/image/icon.js +++ b/packages/block-library/src/image/icon.js @@ -1,8 +1,6 @@ /** * WordPress dependencies */ -import { Path, Rect, SVG } from '@wordpress/components'; +import { Path, SVG } from '@wordpress/components'; export default <SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><Path d="M0,0h24v24H0V0z" fill="none" /><Path d="m19 5v14h-14v-14h14m0-2h-14c-1.1 0-2 0.9-2 2v14c0 1.1 0.9 2 2 2h14c1.1 0 2-0.9 2-2v-14c0-1.1-0.9-2-2-2z" /><Path d="m14.14 11.86l-3 3.87-2.14-2.59-3 3.86h12l-3.86-5.14z" /></SVG>; - -export const editImageIcon = ( <SVG width={ 20 } height={ 20 } viewBox="0 0 20 20"><Rect x={ 11 } y={ 3 } width={ 7 } height={ 5 } rx={ 1 } /><Rect x={ 2 } y={ 12 } width={ 7 } height={ 5 } rx={ 1 } /><Path d="M13,12h1a3,3,0,0,1-3,3v2a5,5,0,0,0,5-5h1L15,9Z" /><Path d="M4,8H3l2,3L7,8H6A3,3,0,0,1,9,5V3A5,5,0,0,0,4,8Z" /></SVG> ); diff --git a/packages/block-library/src/image/save.js b/packages/block-library/src/image/save.js index b3976c76a8de85..01aff39769152b 100644 --- a/packages/block-library/src/image/save.js +++ b/packages/block-library/src/image/save.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import { isEmpty } from 'lodash'; /** * WordPress dependencies @@ -25,8 +24,6 @@ export default function save( { attributes } ) { sizeSlug, } = attributes; - const newRel = isEmpty( rel ) ? undefined : rel; - const classes = classnames( { [ `align${ align }` ]: align, [ `size-${ sizeSlug }` ]: sizeSlug, @@ -50,7 +47,7 @@ export default function save( { attributes } ) { className={ linkClass } href={ href } target={ linkTarget } - rel={ newRel } + rel={ rel } > { image } </a> diff --git a/packages/block-library/src/image/styles.native.scss b/packages/block-library/src/image/styles.native.scss index 24b20de69dc8f8..9c5a9cbf5c45e5 100644 --- a/packages/block-library/src/image/styles.native.scss +++ b/packages/block-library/src/image/styles.native.scss @@ -18,6 +18,10 @@ align-items: center; } +.clearSettingsButton { + color: $alert-red; +} + .modalIcon { width: 80px; height: 80px; @@ -40,13 +44,3 @@ .iconDark { fill: $white; } - -.content { - flex: 1; -} - -.contentCentered { - flex: 1; - justify-content: center; - align-items: center; -} diff --git a/packages/block-library/src/image/test/edit.native.js b/packages/block-library/src/image/test/edit.native.js index 9c21c10d90dbaf..d585f1f1396a9e 100644 --- a/packages/block-library/src/image/test/edit.native.js +++ b/packages/block-library/src/image/test/edit.native.js @@ -40,16 +40,16 @@ describe( 'Image Block', () => { instance.onSetNewTab( true ); - expect( setAttributes ).toHaveBeenCalledWith( { linkTarget: '_blank', rel: undefined } ); + expect( setAttributes ).toBeCalledWith( { linkTarget: '_blank', rel: NEW_TAB_REL } ); } ); it( 'unset link target', () => { - const component = renderer.create( getImageComponent( { linkTarget: '_blank', rel: NEW_TAB_REL.join( ' ' ) } ) ); + const component = renderer.create( getImageComponent( { linkTarget: '_blank', rel: NEW_TAB_REL } ) ); const instance = component.getInstance(); instance.onSetNewTab( false ); - expect( setAttributes ).toHaveBeenCalledWith( { linkTarget: undefined, rel: undefined } ); + expect( setAttributes ).toBeCalledWith( { linkTarget: undefined, rel: undefined } ); } ); } ); diff --git a/packages/block-library/src/image/utils.js b/packages/block-library/src/image/utils.js index 1e3e8a07fc3748..2cb9b8f5ca5c78 100644 --- a/packages/block-library/src/image/utils.js +++ b/packages/block-library/src/image/utils.js @@ -1,11 +1,3 @@ -/** - * External dependencies - */ -import { - isEmpty, - each, -} from 'lodash'; - /** * Internal dependencies */ @@ -20,30 +12,6 @@ export function calculatePreferedImageSize( image, container ) { return { width, height }; } -export function removeNewTabRel( currentRel ) { - let newRel = currentRel; - - if ( currentRel !== undefined && ! isEmpty( newRel ) ) { - if ( ! isEmpty( newRel ) ) { - each( NEW_TAB_REL, function( relVal ) { - const regExp = new RegExp( '\\b' + relVal + '\\b', 'gi' ); - newRel = newRel.replace( regExp, '' ); - } ); - - // Only trim if NEW_TAB_REL values was replaced. - if ( newRel !== currentRel ) { - newRel = newRel.trim(); - } - - if ( isEmpty( newRel ) ) { - newRel = undefined; - } - } - } - - return newRel; -} - /** * Helper to get the link target settings to be stored. * @@ -56,11 +24,11 @@ export function removeNewTabRel( currentRel ) { export function getUpdatedLinkTargetSettings( value, { rel } ) { const linkTarget = value ? '_blank' : undefined; - let updatedRel; - if ( ! linkTarget && ! rel ) { + let updatedRel = rel; + if ( linkTarget && ! rel ) { + updatedRel = NEW_TAB_REL; + } else if ( ! linkTarget && rel === NEW_TAB_REL ) { updatedRel = undefined; - } else { - updatedRel = removeNewTabRel( rel ); } return { diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index 3147ebcc0e9cdc..e49f68553b0a6f 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -62,9 +62,6 @@ import * as classic from './classic'; import * as socialLinks from './social-links'; import * as socialLink from './social-link'; -// Full Site Editing Blocks -import * as siteTitle from './site-title'; - /** * Function to register an individual block. * @@ -165,24 +162,14 @@ export const registerCoreBlocks = () => { * __experimentalRegisterExperimentalCoreBlocks( settings ); * ``` */ -export const __experimentalRegisterExperimentalCoreBlocks = - process.env.GUTENBERG_PHASE === 2 ? - ( settings ) => { - const { - __experimentalEnableLegacyWidgetBlock, - __experimentalEnableMenuBlock, - __experimentalEnableFullSiteEditing, - } = settings - - ;[ - __experimentalEnableLegacyWidgetBlock ? legacyWidget : null, - __experimentalEnableMenuBlock ? navigationMenu : null, - __experimentalEnableMenuBlock ? navigationMenuItem : null, - socialLinks, - ...socialLink.sites, +export const __experimentalRegisterExperimentalCoreBlocks = process.env.GUTENBERG_PHASE === 2 ? ( settings ) => { + const { __experimentalEnableLegacyWidgetBlock, __experimentalEnableMenuBlock } = settings; - // Register Full Site Editing Blocks. - ...( __experimentalEnableFullSiteEditing ? [ siteTitle ] : [] ), - ].forEach( registerBlock ); - } : - undefined; + [ + __experimentalEnableLegacyWidgetBlock ? legacyWidget : null, + __experimentalEnableMenuBlock ? navigationMenu : null, + __experimentalEnableMenuBlock ? navigationMenuItem : null, + socialLinks, + ...socialLink.sites, + ].forEach( registerBlock ); +} : undefined; diff --git a/packages/block-library/src/index.native.js b/packages/block-library/src/index.native.js index 0d06a9df9f11af..2702becc3a8c31 100644 --- a/packages/block-library/src/index.native.js +++ b/packages/block-library/src/index.native.js @@ -96,9 +96,9 @@ export const coreBlocks = [ textColumns, verse, video, -].reduce( ( accumulator, block ) => { - accumulator[ block.name ] = block; - return accumulator; +].reduce( ( memo, block ) => { + memo[ block.name ] = block; + return memo; }, {} ); /** diff --git a/packages/block-library/src/list/block.json b/packages/block-library/src/list/block.json index 71bca30f1a8ac3..3dcae3a6ae5c22 100644 --- a/packages/block-library/src/list/block.json +++ b/packages/block-library/src/list/block.json @@ -14,9 +14,6 @@ "__unstableMultilineWrapperTags": [ "ol", "ul" ], "default": "" }, - "type": { - "type": "string" - }, "start": { "type": "number" }, diff --git a/packages/block-library/src/list/edit.js b/packages/block-library/src/list/edit.js index 4373bbec0ce437..6a76a376f617d3 100644 --- a/packages/block-library/src/list/edit.js +++ b/packages/block-library/src/list/edit.js @@ -32,7 +32,7 @@ export default function ListEdit( { onReplace, className, } ) { - const { ordered, values, type, reversed, start } = attributes; + const { ordered, values, reversed, start } = attributes; const tagName = ordered ? 'ol' : 'ul'; const controls = ( { value, onChange } ) => ( @@ -124,13 +124,12 @@ export default function ListEdit( { className={ className } placeholder={ __( 'Write list…' ) } onMerge={ mergeBlocks } - onSplit={ ( value ) => createBlock( name, { ...attributes, values: value } ) } + onSplit={ ( value ) => createBlock( name, { ordered, values: value } ) } __unstableOnSplitMiddle={ () => createBlock( 'core/paragraph' ) } onReplace={ onReplace } onRemove={ () => onReplace( [] ) } start={ start } reversed={ reversed } - type={ type } > { controls } </RichText> diff --git a/packages/block-library/src/list/editor.scss b/packages/block-library/src/list/editor.scss new file mode 100644 index 00000000000000..fffff9ebaf6ee1 --- /dev/null +++ b/packages/block-library/src/list/editor.scss @@ -0,0 +1,5 @@ +.editor-styles-wrapper div[data-type="core/list"] ul, +.editor-styles-wrapper div[data-type="core/list"] ol { + padding-left: 1.3em; + margin-left: 1.3em; +} diff --git a/packages/block-library/src/list/save.js b/packages/block-library/src/list/save.js index 8cd1d3870148ba..18458c2c1ce5a5 100644 --- a/packages/block-library/src/list/save.js +++ b/packages/block-library/src/list/save.js @@ -4,14 +4,13 @@ import { RichText } from '@wordpress/block-editor'; export default function save( { attributes } ) { - const { ordered, values, type, reversed, start } = attributes; + const { ordered, values, reversed, start } = attributes; const tagName = ordered ? 'ol' : 'ul'; return ( <RichText.Content tagName={ tagName } value={ values } - type={ type } reversed={ reversed } start={ start } multiline="li" diff --git a/packages/block-library/src/list/transforms.js b/packages/block-library/src/list/transforms.js index da533e16f6f30c..baf09b1b945c6d 100644 --- a/packages/block-library/src/list/transforms.js +++ b/packages/block-library/src/list/transforms.js @@ -18,7 +18,7 @@ import { const listContentSchema = { ...getPhrasingContentSchema(), ul: {}, - ol: { attributes: [ 'type', 'start', 'reversed' ] }, + ol: { attributes: [ 'type' ] }, }; // Recursion is needed. @@ -77,35 +77,12 @@ const transforms = { ul: listContentSchema.ul, }, transform( node ) { - const attributes = { - ordered: node.nodeName === 'OL', - }; - - if ( attributes.ordered ) { - const type = node.getAttribute( 'type' ); - - if ( type ) { - attributes.type = type; - } - - if ( node.getAttribute( 'reversed' ) !== null ) { - attributes.reversed = true; - } - - const start = parseInt( node.getAttribute( 'start' ), 10 ); - - if ( - ! isNaN( start ) && - // start=1 only makes sense if the list is reversed. - ( start !== 1 || attributes.reversed ) - ) { - attributes.start = start; - } - } - return createBlock( 'core/list', { - ...getBlockAttributes( 'core/list', node.outerHTML ), - ...attributes, + ...getBlockAttributes( + 'core/list', + node.outerHTML + ), + ordered: node.nodeName === 'OL', } ); }, }, diff --git a/packages/block-library/src/media-text/media-container.native.js b/packages/block-library/src/media-text/media-container.native.js index fea6a9671965c4..39ff78799b14f5 100644 --- a/packages/block-library/src/media-text/media-container.native.js +++ b/packages/block-library/src/media-text/media-container.native.js @@ -3,6 +3,7 @@ */ import { View, ImageBackground, Text, TouchableWithoutFeedback } from 'react-native'; import { + requestMediaImport, mediaUploadSync, requestImageFailedRetryDialog, requestImageUploadCancelDialog, @@ -61,11 +62,17 @@ class MediaContainer extends Component { } componentDidMount() { - const { mediaId, mediaUrl } = this.props; - - // Make sure we mark any temporary images as failed if they failed while - // the editor wasn't open - if ( mediaId && mediaUrl && mediaUrl.indexOf( 'file:' ) === 0 ) { + const { mediaId, mediaUrl, onMediaUpdate, mediaType } = this.props; + + if ( mediaId && mediaUrl && ! isURL( mediaUrl ) ) { + if ( mediaUrl.indexOf( 'file:' ) === 0 && mediaType === MEDIA_TYPE_IMAGE ) { + // We don't want to call this for video because it is starting a media upload for the cover url + requestMediaImport( mediaUrl, ( id, url ) => { + if ( url ) { + onMediaUpdate( { id, url } ); + } + } ); + } mediaUploadSync(); } } @@ -154,8 +161,6 @@ class MediaContainer extends Component { const { finalWidth, finalHeight, imageWidthWithinContainer, isUploadFailed, retryMessage } = params; const opacity = isUploadInProgress ? 0.3 : 1; - const contentStyle = ! imageWidthWithinContainer ? styles.content : styles.contentCentered; - return ( <TouchableWithoutFeedback accessible={ ! isSelected } @@ -163,7 +168,7 @@ class MediaContainer extends Component { onLongPress={ openMediaOptions } disabled={ ! isSelected } > - <View style={ contentStyle }> + <View style={ styles.content }> { ! imageWidthWithinContainer && <View style={ styles.imageContainer }> { this.getIcon( false ) } diff --git a/packages/block-library/src/media-text/style.native.scss b/packages/block-library/src/media-text/style.native.scss index 27c972f6f8d6e7..06d29dc715dab7 100644 --- a/packages/block-library/src/media-text/style.native.scss +++ b/packages/block-library/src/media-text/style.native.scss @@ -32,12 +32,6 @@ flex: 1; } -.contentCentered { - flex: 1; - justify-content: center; - align-items: center; -} - .imageContainer { align-items: center; background-color: $gray-lighten-30; diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index 0aa4c3436d7dfe..cd4898a4e8c692 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -27,9 +27,6 @@ export class UnsupportedBlockEdit extends Component { const title = blockType ? blockType.settings.title : __( 'Unsupported' ); const titleStyle = getStylesFromColorScheme( styles.unsupportedBlockMessage, styles.unsupportedBlockMessageDark ); - const subTitleStyle = getStylesFromColorScheme( styles.unsupportedBlockSubtitle, styles.unsupportedBlockSubtitleDark ); - const subtitle = blockType ? <Text style={ subTitleStyle }>{ __( 'Unsupported' ) }</Text> : null; - const icon = blockType ? normalizeIconObject( blockType.settings.icon ) : 'admin-plugins'; const iconStyle = getStylesFromColorScheme( styles.unsupportedBlockIcon, styles.unsupportedBlockIconDark ); const iconClassName = 'unsupported-icon' + '-' + preferredColorScheme; @@ -37,7 +34,6 @@ export class UnsupportedBlockEdit extends Component { <View style={ getStylesFromColorScheme( styles.unsupportedBlock, styles.unsupportedBlockDark ) }> <Icon className={ iconClassName } icon={ icon && icon.src ? icon.src : icon } color={ iconStyle.color } /> <Text style={ titleStyle }>{ title }</Text> - { subtitle } </View> ); } diff --git a/packages/block-library/src/missing/style.native.scss b/packages/block-library/src/missing/style.native.scss index 5967ceb1e4d9fe..63cd4258cd23b0 100644 --- a/packages/block-library/src/missing/style.native.scss +++ b/packages/block-library/src/missing/style.native.scss @@ -27,24 +27,12 @@ } .unsupportedBlockMessage { - margin-top: 4; + margin-top: 2; text-align: center; color: $gray-dark; font-size: 14; - font-weight: 600; } .unsupportedBlockMessageDark { color: $white; } - -.unsupportedBlockSubtitle { - margin-top: 2; - text-align: center; - color: $gray-darken-20; - font-size: 12; -} - -.unsupportedBlockSubtitleDark { - color: $gray-20; -} diff --git a/packages/block-library/src/navigation-menu-item/block.json b/packages/block-library/src/navigation-menu-item/block.json index 20b33eca1f4a05..915c63931cb2be 100644 --- a/packages/block-library/src/navigation-menu-item/block.json +++ b/packages/block-library/src/navigation-menu-item/block.json @@ -5,6 +5,9 @@ "label": { "type": "string" }, + "destination": { + "type": "string" + }, "nofollow": { "type": "boolean", "default": false @@ -18,9 +21,6 @@ "opensInNewTab": { "type": "boolean", "default": false - }, - "url": { - "type": "string" } } } diff --git a/packages/block-library/src/navigation-menu-item/edit.js b/packages/block-library/src/navigation-menu-item/edit.js index 4d2258d08eb163..f4e456321347c6 100644 --- a/packages/block-library/src/navigation-menu-item/edit.js +++ b/packages/block-library/src/navigation-menu-item/edit.js @@ -1,140 +1,93 @@ /** * External dependencies */ -import classnames from 'classnames'; +import { invoke } from 'lodash'; /** * WordPress dependencies */ import { withSelect } from '@wordpress/data'; import { + Dropdown, ExternalLink, + IconButton, PanelBody, TextareaControl, TextControl, - Toolbar, ToggleControl, - ToolbarButton, } from '@wordpress/components'; -import { - LEFT, - RIGHT, - UP, - DOWN, - BACKSPACE, - ENTER, -} from '@wordpress/keycodes'; import { __ } from '@wordpress/i18n'; import { - BlockControls, InnerBlocks, InspectorControls, - URLPopover, + PlainText, } from '@wordpress/block-editor'; import { Fragment, + useCallback, useRef, - useState, } from '@wordpress/element'; +/** + * Internal dependencies + */ +import MenuItemActions from './menu-item-actions'; +const POPOVER_PROPS = { noArrow: true }; + function NavigationMenuItemEdit( { attributes, + clientId, isSelected, isParentOfSelectedBlock, setAttributes, } ) { const plainTextRef = useRef( null ); - const [ isLinkOpen, setIsLinkOpen ] = useState( false ); - const [ isEditingLink, setIsEditingLink ] = useState( false ); - const [ urlInput, setUrlInput ] = useState( null ); - - const inputValue = urlInput !== null ? urlInput : url; - - const onKeyDown = ( event ) => { - if ( [ LEFT, DOWN, RIGHT, UP, BACKSPACE, ENTER ].indexOf( event.keyCode ) > -1 ) { - // Stop the key event from propagating up to ObserveTyping.startTypingInTextField. - event.stopPropagation(); - } - }; - - const closeURLPopover = () => { - setIsEditingLink( false ); - setUrlInput( null ); - setIsLinkOpen( false ); - }; - - const autocompleteRef = useRef( null ); - - const onFocusOutside = ( event ) => { - const autocompleteElement = autocompleteRef.current; - if ( autocompleteElement && autocompleteElement.contains( event.target ) ) { - return; - } - closeURLPopover(); - }; - - const stopPropagation = ( event ) => { - event.stopPropagation(); - }; - - const { label, url } = attributes; + const onEditLableClicked = useCallback( + ( onClose ) => () => { + onClose(); + invoke( plainTextRef, [ 'current', 'textarea', 'focus' ] ); + }, + [ plainTextRef ] + ); let content; if ( isSelected ) { content = ( - <TextControl - ref={ plainTextRef } - className="wp-block-navigation-menu-item__field" - value={ label } - onChange={ ( labelValue ) => setAttributes( { label: labelValue } ) } - label={ __( 'Navigation Label' ) } - hideLabelFromVision={ true } - /> + <div className="wp-block-navigation-menu-item__edit-container"> + <PlainText + ref={ plainTextRef } + className="wp-block-navigation-menu-item__field" + value={ attributes.label } + onChange={ ( label ) => setAttributes( { label } ) } + aria-label={ __( 'Navigation Label' ) } + maxRows={ 1 } + /> + <Dropdown + contentClassName="wp-block-navigation-menu-item__dropdown-content" + position="bottom left" + popoverProps={ POPOVER_PROPS } + renderToggle={ ( { isOpen, onToggle } ) => ( + <IconButton + icon={ isOpen ? 'arrow-up-alt2' : 'arrow-down-alt2' } + label={ __( 'More options' ) } + onClick={ onToggle } + aria-expanded={ isOpen } + /> + ) } + renderContent={ ( { onClose } ) => ( + <MenuItemActions + clientId={ clientId } + destination={ attributes.destination } + onEditLableClicked={ onEditLableClicked( onClose ) } + /> + ) } + /> + </div> ); } else { - content = <div className="wp-block-navigation-menu-item__container"> - { label } - </div>; + content = attributes.label; } - return ( <Fragment> - <BlockControls> - <Toolbar> - <ToolbarButton - name="link" - icon="admin-links" - title={ __( 'Link' ) } - onClick={ () => setIsLinkOpen( ! isLinkOpen ) } - /> - { isLinkOpen && - <> - <URLPopover - className="wp-block-navigation-menu-item__inline-link-input" - onClose={ closeURLPopover } - onFocusOutside={ onFocusOutside } - > - { ( ! url || isEditingLink ) && - <URLPopover.LinkEditor - value={ inputValue } - onChangeInputValue={ setUrlInput } - onKeyPress={ stopPropagation } - onKeyDown={ onKeyDown } - onSubmit={ ( event ) => event.preventDefault() } - autocompleteRef={ autocompleteRef } - /> - } - { ( url && ! isEditingLink ) && - <URLPopover.LinkViewer - onKeyPress={ stopPropagation } - url={ url } - /> - } - - </URLPopover> - </> - } - </Toolbar> - </BlockControls> <InspectorControls> <PanelBody title={ __( 'Menu Settings' ) } @@ -185,12 +138,7 @@ function NavigationMenuItemEdit( { /> </PanelBody> </InspectorControls> - <div className={ classnames( - 'wp-block-navigation-menu-item', { - 'is-editing': isSelected || isParentOfSelectedBlock, - 'is-selected': isSelected, - } ) } - > + <div className="wp-block-navigation-menu-item"> { content } { ( isSelected || isParentOfSelectedBlock ) && <InnerBlocks diff --git a/packages/block-library/src/navigation-menu-item/editor.scss b/packages/block-library/src/navigation-menu-item/editor.scss index 8e6c06274129b1..2d801052ba4107 100644 --- a/packages/block-library/src/navigation-menu-item/editor.scss +++ b/packages/block-library/src/navigation-menu-item/editor.scss @@ -1,64 +1,39 @@ - -// Normalize menu items and edit containers, to look mostly the same. -.wp-block-navigation-menu-item__field .components-text-control__input.components-text-control__input, -.wp-block-navigation-menu-item__container { - border-radius: 0; - // Make it the same height as the appender to prevent a jump. Maybe revisit this. - line-height: $icon-button-size; - min-height: $icon-button-size; -} - -.wp-block-navigation-menu-item { - margin-right: $grid-size; - - // Provide a base menu item margin. - // This should be the same inside the field, - // and the edit container should compensate. - // This is to make sure the edit and view are the same. - padding: 0 $grid-size; -} +$menu-label-field-width: 140px; .wp-block-navigation-menu-item__edit-container { - display: flex; + display: grid; + grid-auto-columns: min-content; + grid-auto-flow: column; + align-items: center; white-space: nowrap; + border: 1px solid $light-gray-500; + // two pixes comes from two times one pixel border + width: $menu-label-field-width + $icon-button-size + 2px; + padding-left: 1px; +} - // Compensate for menu item base padding. - margin-left: -$grid-size; - - .wp-block-navigation-menu-item__field { - margin-right: $grid-size; - - // This should match the padding of the menu item. - padding: 0 $grid-size; - - // This make it look like an input field. - // We may want to not style this at all, but let's try this. - // We don't use the mixins because they increase the size of the input, which doesn't work with PlainText. - box-shadow: inset 0 0 0 1px $dark-gray-200; - transition: box-shadow 0.1s linear; - border-radius: $radius-round-rectangle; - @include reduce-motion("transition"); +.wp-block-navigation-menu-item__edit-container .wp-block-navigation-menu-item__field { + border-right: 1px solid $light-gray-500 !important; + width: $menu-label-field-width; + border: none; + border-radius: 0; + padding-left: $grid-size-large; - &:focus { - color: $dark-gray-900; - box-shadow: inset 0 0 0 2px $blue-medium-focus; + min-height: $icon-button-size - 1px; + line-height: $icon-button-size - 1px; - // Windows High Contrast mode will show this outline, but not the box-shadow. - outline: 2px solid transparent; - } + &, + &:focus { + color: $dark-gray-500; } } + .wp-block-navigation-menu-item { font-family: $editor-font; + color: #0073af; font-weight: bold; font-size: $text-editor-font-size; - background-color: var(--background-color-menu-link); - color: var(--color-menu-link); - - &:focus { - color: var(--color-menu-link); - } } .wp-block-navigation-menu-item__nofollow-external-link { @@ -67,7 +42,10 @@ // Separator .wp-block-navigation-menu-item__separator { - margin: $grid-size 0 $grid-size; + margin-top: $grid-size; + margin-bottom: $grid-size; + margin-left: 0; + margin-right: 0; border-top: $border-width solid $light-gray-500; } @@ -82,6 +60,10 @@ } .wp-block-navigation-menu .block-editor-block-list__block[data-type="core/navigation-menu-item"] { + & > .block-editor-block-list__block-edit > div[role="toolbar"] { + display: none; + } + & > .block-editor-block-list__insertion-point { display: none; } diff --git a/packages/block-library/src/navigation-menu-item/index.js b/packages/block-library/src/navigation-menu-item/index.js index 9a51131a86b41a..496ef92070428e 100644 --- a/packages/block-library/src/navigation-menu-item/index.js +++ b/packages/block-library/src/navigation-menu-item/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { Path, SVG } from '@wordpress/components'; + /** * Internal dependencies */ @@ -18,12 +18,10 @@ export const settings = { parent: [ 'core/navigation-menu' ], - icon: <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24"><Path d="M12 7.27l4.28 10.43-3.47-1.53-.81-.36-.81.36-3.47 1.53L12 7.27M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z" /></SVG>, + icon: 'admin-links', description: __( 'Add a page, link, or other item to your Navigation Menu.' ), - __experimentalDisplayName: 'label', - edit, save, }; diff --git a/packages/block-library/src/navigation-menu-item/menu-item-actions.js b/packages/block-library/src/navigation-menu-item/menu-item-actions.js new file mode 100644 index 00000000000000..6e39036bab408a --- /dev/null +++ b/packages/block-library/src/navigation-menu-item/menu-item-actions.js @@ -0,0 +1,111 @@ +/** + * WordPress dependencies + */ +import { + MenuItem, + NavigableMenu, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { withDispatch } from '@wordpress/data'; +import { compose } from '@wordpress/compose'; + +function MenuItemActions( { + destination, + moveLeft, + moveRight, + moveToEnd, + moveToStart, + onEditLableClicked, + remove, +} ) { + return ( + <NavigableMenu> + <MenuItem + icon="admin-links" + > + { destination } + </MenuItem> + <MenuItem + onClick={ onEditLableClicked } + icon="edit" + > + { __( 'Edit label text' ) } + </MenuItem> + <div className="wp-block-navigation-menu-item__separator" /> + <MenuItem + onClick={ moveToStart } + icon="arrow-up-alt2" + > + { __( 'Move to start' ) } + </MenuItem> + <MenuItem + onClick={ moveLeft } + icon="arrow-left-alt2" + > + { __( 'Move left' ) } + </MenuItem> + <MenuItem + onClick={ moveRight } + icon="arrow-right-alt2" + > + { __( 'Move right' ) } + </MenuItem> + <MenuItem + onClick={ moveToEnd } + icon="arrow-down-alt2" + > + { __( 'Move to end' ) } + </MenuItem> + <MenuItem + icon="arrow-left-alt2" + > + { __( 'Nest underneath…' ) } + </MenuItem> + <div className="navigation-menu-item__separator" /> + <MenuItem + onClick={ remove } + icon="trash" + > + { __( 'Remove from menu' ) } + </MenuItem> + </NavigableMenu> + ); +} + +export default compose( [ + withDispatch( ( dispatch, { clientId }, { select } ) => { + const { + getBlockOrder, + getBlockRootClientId, + } = select( 'core/block-editor' ); + const parentID = getBlockRootClientId( clientId ); + const { + moveBlocksDown, + moveBlocksUp, + moveBlockToPosition, + removeBlocks, + } = dispatch( 'core/block-editor' ); + return { + moveToStart() { + moveBlockToPosition( clientId, parentID, parentID, 0 ); + }, + moveRight() { + moveBlocksDown( clientId, parentID ); + }, + moveLeft() { + moveBlocksUp( clientId, parentID ); + }, + moveToEnd() { + moveBlockToPosition( + clientId, + parentID, + parentID, + getBlockOrder( parentID ).length - 1 + ); + }, + remove() { + removeBlocks( clientId ); + }, + }; + } ), +] )( MenuItemActions ); diff --git a/packages/block-library/src/navigation-menu/block-colors-selector.js b/packages/block-library/src/navigation-menu/block-colors-selector.js deleted file mode 100644 index 0c1c98b691ef4f..00000000000000 --- a/packages/block-library/src/navigation-menu/block-colors-selector.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { noop } from 'lodash'; - -/** - * WordPress dependencies - */ -import { IconButton, Dropdown, Toolbar } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { DOWN } from '@wordpress/keycodes'; -import { ColorPaletteControl, ContrastChecker } from '@wordpress/block-editor'; - -/** - * Color Selector Icon component. - * - * @return {*} React Icon component. - */ -const ColorSelectorIcon = ( { style } ) => - <div className="block-library-colors-selector__icon-container"> - <div - className="block-library-colors-selector__state-selection wp-block-navigation-menu-item" - style={ style } - > - Aa - </div> - </div>; - -/** - * Renders the Colors Selector Toolbar with the icon button. - * - * @param {Object} style - Colors style object. - * @return {*} React toggle button component. - */ -const renderToggleComponent = ( style ) => ( { onToggle, isOpen } ) => { - const openOnArrowDown = ( event ) => { - if ( ! isOpen && event.keyCode === DOWN ) { - event.preventDefault(); - event.stopPropagation(); - onToggle(); - } - }; - - return ( - <Toolbar> - <IconButton - className="components-icon-button components-toolbar__control block-library-colors-selector__toggle" - label={ __( 'Open Colors Selector' ) } - onClick={ onToggle } - onKeyDown={ openOnArrowDown } - icon={ <ColorSelectorIcon style={ style } /> } - /> - </Toolbar> - ); -}; - -const renderContent = ( { backgroundColor, textColor, onColorChange = noop } ) => ( () => { - const setColor = ( attr ) => ( value ) => onColorChange( { attr, value } ); - - return ( - <> - <div className="color-palette-controller-container"> - <ColorPaletteControl - value={ backgroundColor.color } - onChange={ setColor( 'backgroundColor' ) } - label={ __( 'Background Color' ) } - /> - </div> - - <div className="color-palette-controller-container"> - <ColorPaletteControl - value={ textColor.color } - onChange={ setColor( 'textColor' ) } - label={ __( 'Text Color' ) } - /> - </div> - - <ContrastChecker - textColor={ textColor.color } - backgroundColor={ backgroundColor.color } - isLargeText={ false } - /> - </> - ); -} ); - -export default ( { style, className, ...colorControlProps } ) => - <Dropdown - position="bottom right" - className={ classnames( 'block-library-colors-selector', className ) } - contentClassName="block-library-colors-selector__popover" - renderToggle={ renderToggleComponent( style ) } - renderContent={ renderContent( colorControlProps ) } - />; diff --git a/packages/block-library/src/navigation-menu/edit.js b/packages/block-library/src/navigation-menu/edit.js index fdb6fd7c2fa4db..5b4ad5ce475f9a 100644 --- a/packages/block-library/src/navigation-menu/edit.js +++ b/packages/block-library/src/navigation-menu/edit.js @@ -1,21 +1,14 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ import { Fragment, useMemo, - useEffect, } from '@wordpress/element'; import { InnerBlocks, InspectorControls, BlockControls, - withColors, } from '@wordpress/block-editor'; import { withSelect } from '@wordpress/data'; import { @@ -24,26 +17,19 @@ import { Spinner, Toolbar, } from '@wordpress/components'; -import { compose } from '@wordpress/compose'; - import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import useBlockNavigator from './use-block-navigator'; -import BlockColorsStyleSelector from './block-colors-selector'; function NavigationMenu( { attributes, + setAttributes, clientId, pages, isRequesting, - backgroundColor, - textColor, - setBackgroundColor, - setTextColor, - setAttributes, } ) { const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( clientId ); const defaultMenuItems = useMemo( @@ -53,74 +39,19 @@ function NavigationMenu( { } return pages.map( ( page ) => { return [ 'core/navigation-menu-item', - { label: page.title.rendered, url: page.permalink_template }, + { label: page.title.rendered, destination: page.permalink_template }, ]; } ); }, [ pages ] ); - const navigationMenuStyles = {}; - if ( textColor.color ) { - navigationMenuStyles[ '--color-menu-link' ] = textColor.color; - } - - if ( backgroundColor.color ) { - navigationMenuStyles[ '--background-color-menu-link' ] = backgroundColor.color; - } - - const navigationMenuClasses = classnames( - 'wp-block-navigation-menu', { - 'has-text-color': textColor.color, - 'has-background-color': backgroundColor.color, - } - ); - - /** - * Set the color type according to the given values. - * It propagate the color values into the attributes object. - * Both `backgroundColorValue` and `textColorValue` are - * using the inline styles. - * - * @param {Object} colorsData Arguments passed by BlockColorsStyleSelector onColorChange. - * @param {string} colorsData.attr Color attribute. - * @param {boolean} colorsData.value Color attribute value. - */ - const setColorType = ( { attr, value } ) => { - switch ( attr ) { - case 'backgroundColor': - setBackgroundColor( value ); - setAttributes( { backgroundColorValue: value } ); - break; - - case 'textColor': - setTextColor( value ); - setAttributes( { textColorValue: value } ); - break; - } - }; - - useEffect( () => { - // Set/Unset colors CSS classes. - setAttributes( { - backgroundColorCSSClass: backgroundColor.class ? backgroundColor.class : null, - textColorCSSClass: textColor.class ? textColor.class : null, - } ); - }, [ backgroundColor.class, textColor.class ] ); - return ( <Fragment> <BlockControls> <Toolbar> { navigatorToolbarButton } </Toolbar> - <BlockColorsStyleSelector - style={ navigationMenuStyles } - className={ navigationMenuClasses } - backgroundColor={ backgroundColor } - textColor={ textColor } - onColorChange={ setColorType } - /> </BlockControls> { navigatorModal } <InspectorControls> @@ -129,21 +60,23 @@ function NavigationMenu( { > <CheckboxControl value={ attributes.automaticallyAdd } - onChange={ ( automaticallyAdd ) => setAttributes( { automaticallyAdd } ) } + onChange={ ( automaticallyAdd ) => { + setAttributes( { automaticallyAdd } ); + } } label={ __( 'Automatically add new pages' ) } help={ __( 'Automatically add new top level pages to this menu.' ) } /> </PanelBody> </InspectorControls> - - <div className={ navigationMenuClasses } style={ navigationMenuStyles }> - { isRequesting && <Spinner /> } + <div className="wp-block-navigation-menu"> + { isRequesting && + <Spinner /> + } { pages && <InnerBlocks template={ defaultMenuItems ? defaultMenuItems : null } allowedBlocks={ [ 'core/navigation-menu-item' ] } templateInsertUpdatesSelection={ false } - __experimentalMoverDirection={ 'horizontal' } /> } </div> @@ -151,19 +84,17 @@ function NavigationMenu( { ); } -export default compose( [ - withColors( { backgroundColor: 'background-color', textColor: 'color' } ), - withSelect( ( select ) => { - const { getEntityRecords } = select( 'core' ); - const { isResolving } = select( 'core/data' ); - const filterDefaultPages = { - parent: 0, - order: 'asc', - orderby: 'id', - }; - return { - pages: getEntityRecords( 'postType', 'page', filterDefaultPages ), - isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ), - }; - } ), -] )( NavigationMenu ); +export default withSelect( ( select ) => { + const { getEntityRecords } = select( 'core' ); + const { isResolving } = select( 'core/data' ); + const filterDefaultPages = { + parent: 0, + order: 'asc', + orderby: 'id', + }; + return { + pages: getEntityRecords( 'postType', 'page', filterDefaultPages ), + isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ), + }; +} )( NavigationMenu ); + diff --git a/packages/block-library/src/navigation-menu/editor.scss b/packages/block-library/src/navigation-menu/editor.scss index cc663e7787a998..2238b2fae8dd7c 100644 --- a/packages/block-library/src/navigation-menu/editor.scss +++ b/packages/block-library/src/navigation-menu/editor.scss @@ -1,63 +1,9 @@ -// Reduce the paddings, margins, and UI of inner-blocks. -// @todo: eventually we may add a feature that lets a parent container absorb the block UI of a child block. -// When that happens, leverage that instead of the following overrides. -[data-type="core/navigation-menu"] { - // 1. Reset margins on immediate innerblocks container. - .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout { - margin-left: 0; - margin-right: 0; - } - - // 2. Remove paddings on subsequent immediate children. - .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout > .wp-block { - width: auto; - padding-left: 0; - padding-right: 0; - margin-left: 0; // something - } - - // 3. Remove margins on subsequent Edit container. - .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout > .wp-block > .block-editor-block-list__block-edit { - margin-left: 0; - margin-right: 0; - } - - // 4. Remove vertical margins on subsequent block container. - .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout .wp-block > .block-editor-block-list__block-edit > [data-block] { - margin-top: 0; - margin-bottom: 0; - } - - // Remove the dashed outlines for child blocks. - &.is-hovered .wp-block-navigation-menu .block-editor-block-list__block-edit::before, - &.is-selected .wp-block-navigation-menu .block-editor-block-list__block-edit::before, - &.has-child-selected .wp-block-navigation-menu .block-editor-block-list__block-edit::before { - border-color: transparent !important; // !important used to keep the selector from growing any more complex. - } - - // Hide the breadcrumb. - // Hide the sibling inserter. - .wp-block-navigation-menu .block-editor-block-list__insertion-point, - .wp-block-navigation-menu .block-editor-block-list__breadcrumb { - display: none; - } - - // Polish the Appender. - .wp-block-navigation-menu .block-list-appender { - margin: 0; - - .block-editor-button-block-appender { - padding: $grid-size; - outline: none; - background: none; - } - } -} - - .wp-block-navigation-menu .block-editor-block-list__layout, .wp-block-navigation-menu { display: flex; + grid-auto-columns: min-content; + grid-auto-flow: column; + align-items: top; white-space: nowrap; } @@ -66,99 +12,7 @@ } .wp-block-navigation-menu-item { - margin-left: $grid-size; - .wp-block-navigation-menu-item__link { + .wp-block-navigation-menu-item { margin-left: $grid-size-large; } } - -/** - * Colors Selector component - */ -$colors-selector-size: 22px; -.block-library-colors-selector { - width: auto; - - // Toolbar colors-selector button. - .block-library-colors-selector__toggle { - display: block; - margin: 0 auto; - padding: 3px; - width: auto; - } - - // Button container. - .block-library-colors-selector__icon-container { - width: 42px; - height: 30px; - position: relative; - margin: 0 auto; - padding: 3px; - display: flex; - align-items: center; - border-radius: 4px; - - // Add the button arrow. - &::after { - @include dropdown-arrow(); - } - - // Styling button states. - &:focus, - &:hover { - color: $dark-gray-500; - box-shadow: inset 0 0 0 1px $dark-gray-500, inset 0 0 0 2px #fff; - } - } - - // colors-selector - selection status. - .block-library-colors-selector__state-selection { - font-size: 11px; - font-style: normal; - font-family: inherit; - font-weight: 600; - - border-radius: $colors-selector-size / 2; - box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2); - - width: $colors-selector-size; - min-width: $colors-selector-size; - height: $colors-selector-size; - min-height: $colors-selector-size; - line-height: ($colors-selector-size - 2); - - background-color: var(--background-color-menu-link); - color: var(--color-menu-link); - } - - &:not(.has-background-color) .block-library-colors-selector__state-selection { - background-image: linear-gradient(135deg, rgba(0, 0, 0, 0.08) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.08) 50%, rgba(0, 0, 0, 0.08) 75%, transparent 75%, transparent 100%); - background-size: 12px 12px; - } -} - -// Colors Selector Popover. -$color-control-label-height: 20px; -.block-library-colors-selector__popover { - .color-palette-controller-container { - padding: 16px; - } - - .components-base-control__label { - height: $color-control-label-height; - line-height: $color-control-label-height; - } - - .component-color-indicator { - float: right; - margin-top: 2px; - } -} - -.block-editor-block-mover { - &.is-horizontal { - .block-editor-block-mover__control-drag-handle { - display: none; - } - } -} diff --git a/packages/block-library/src/navigation-menu/index.php b/packages/block-library/src/navigation-menu/index.php index b49a41a06aa11c..ba6348bd66e1b6 100644 --- a/packages/block-library/src/navigation-menu/index.php +++ b/packages/block-library/src/navigation-menu/index.php @@ -5,56 +5,6 @@ * @package gutenberg */ -/** - * Build an array with CSS classes and inline styles defining the colors - * which will be applied to the navigation menu markup in the front-end. - * - * @param array $attributes NavigationMenu block attributes. - * @return array Colors CSS classes and inline styles. - */ -function build_css_colors( $attributes ) { - // CSS classes. - $colors = array( - 'bg_css_classes' => '', - 'bg_inline_styles' => '', - 'text_css_classes' => '', - 'text_inline_styles' => '', - ); - - // Background color. - // Background color - has text color. - if ( array_key_exists( 'backgroundColor', $attributes ) ) { - $colors['bg_css_classes'] .= ' has-background-color'; - } - - // Background color - add custom CSS class. - if ( array_key_exists( 'backgroundColorCSSClass', $attributes ) ) { - $colors['bg_css_classes'] .= " {$attributes['backgroundColorCSSClass']}"; - - } elseif ( array_key_exists( 'customBackgroundColor', $attributes ) ) { - // Background color - or add inline `background-color` style. - $colors['bg_inline_styles'] = ' style="background-color: ' . esc_attr( $attributes['customBackgroundColor'] ) . ';"'; - } - - // Text color. - // Text color - has text color. - if ( array_key_exists( 'textColor', $attributes ) ) { - $colors['text_css_classes'] .= ' has-text-color'; - } - // Text color - add custom CSS class. - if ( array_key_exists( 'textColorCSSClass', $attributes ) ) { - $colors['text_css_classes'] .= " {$attributes['textColorCSSClass']}"; - - } elseif ( array_key_exists( 'customTextColor', $attributes ) ) { - // Text color - or add inline `color` style. - $colors['text_inline_styles'] = ' style="color: ' . esc_attr( $attributes['customTextColor'] ) . ';"'; - } - - $colors['bg_css_classes'] = esc_attr( trim( $colors['bg_css_classes'] ) ); - $colors['text_css_classes'] = esc_attr( trim( $colors['text_css_classes'] ) ); - - return $colors; -} /** * Renders the `core/navigation-menu` block on server. * @@ -65,45 +15,22 @@ function build_css_colors( $attributes ) { * @return string Returns the post content with the legacy widget added. */ function render_block_navigation_menu( $attributes, $content, $block ) { - // Inline computed colors. - $comp_inline_styles = ''; - if ( array_key_exists( 'backgroundColorValue', $attributes ) ) { - $comp_inline_styles .= ' background-color: ' . esc_attr( $attributes['backgroundColorValue'] ) . ';'; - } - - if ( array_key_exists( 'textColorValue', $attributes ) ) { - $comp_inline_styles .= ' color: ' . esc_attr( $attributes['textColorValue'] ) . ';'; - } - $comp_inline_styles = ! empty( $comp_inline_styles ) - ? ' style="' . esc_attr( trim( $comp_inline_styles ) ) . '"' - : ''; - - $colors = build_css_colors( $attributes ); - - return "<nav class='wp-block-navigation-menu' {$comp_inline_styles}>" . - build_navigation_menu_html( $block, $colors ) . - '</nav>'; + return '<nav class="wp-block-navigation-menu">' . build_navigation_menu_html( $block ) . '</nav>'; } /** * Walks the inner block structure and returns an HTML list for it. * - * @param array $block The block. - * @param array $colors Contains inline styles and CSS classes to apply to menu item. + * @param array $block The block. * * @return string Returns an HTML list from innerBlocks. */ -function build_navigation_menu_html( $block, $colors ) { +function build_navigation_menu_html( $block ) { $html = ''; foreach ( (array) $block['innerBlocks'] as $key => $menu_item ) { - - $html .= '<li class="wp-block-navigation-menu-item ' . $colors['bg_css_classes'] . '"' . $colors['bg_inline_styles'] . '>' . - '<a - class="wp-block-navigation-menu-item__link ' . $colors['text_css_classes'] . '" - ' . $colors['text_inline_styles']; - - if ( isset( $menu_item['attrs']['url'] ) ) { - $html .= ' href="' . $menu_item['attrs']['url'] . '"'; + $html .= '<li class="wp-block-navigation-menu-item"><a class="wp-block-navigation-menu-item"'; + if ( isset( $menu_item['attrs']['destination'] ) ) { + $html .= ' href="' . $menu_item['attrs']['destination'] . '"'; } if ( isset( $menu_item['attrs']['title'] ) ) { $html .= ' title="' . $menu_item['attrs']['title'] . '"'; @@ -115,7 +42,7 @@ class="wp-block-navigation-menu-item__link ' . $colors['text_css_classes'] . '" $html .= '</a>'; if ( count( (array) $menu_item['innerBlocks'] ) > 0 ) { - $html .= build_navigation_menu_html( $menu_item, $colors ); + $html .= build_navigation_menu_html( $menu_item ); } $html .= '</li>'; @@ -127,57 +54,18 @@ class="wp-block-navigation-menu-item__link ' . $colors['text_css_classes'] . '" * Register the navigation menu block. * * @uses render_block_navigation_menu() - * @throws WP_Error An WP_Error exception parsing the block definition. */ function register_block_core_navigation_menu() { - register_block_type( 'core/navigation-menu', array( 'category' => 'layout', 'attributes' => array( - 'className' => array( - 'type' => 'string', - ), - - 'automaticallyAdd' => array( + 'automaticallyAdd' => array( 'type' => 'boolean', 'default' => false, ), - - 'backgroundColor' => array( - 'type' => 'string', - ), - - 'textColor' => array( - 'type' => 'string', - ), - - 'backgroundColorValue' => array( - 'type' => 'string', - ), - - 'textColorValue' => array( - 'type' => 'string', - ), - - 'customBackgroundColor' => array( - 'type' => 'string', - ), - - 'customTextColor' => array( - 'type' => 'string', - ), - - 'backgroundColorCSSClass' => array( - 'type' => 'string', - ), - - 'textColorCSSClass' => array( - 'type' => 'string', - ), ), - 'render_callback' => 'render_block_navigation_menu', ) ); diff --git a/packages/block-library/src/navigation-menu/style.scss b/packages/block-library/src/navigation-menu/style.scss deleted file mode 100644 index 3c2222ef59f252..00000000000000 --- a/packages/block-library/src/navigation-menu/style.scss +++ /dev/null @@ -1,119 +0,0 @@ -.wp-block-navigation-menu { - - & > ul { - display: block; - list-style: none; - margin: 0; - max-width: none; - padding-left: 0; - position: relative; - - @include break-small { - display: flex; - flex-wrap: wrap; - } - - ul { - padding-left: 0; - } - - li { - position: relative; - z-index: 1; - - &:hover, - &:focus-within { - cursor: pointer; - z-index: 99999; - } - - // Submenu Display - &:hover > ul, - &:focus-within > ul, - & ul:hover, - & ul:focus { - visibility: visible; - opacity: 1; - display: block; - } - } - - & > li { - - & > a { - padding-left: 0; - - @include break-small { - padding-left: 16px; - } - } - - &:first-of-type > a { - padding-left: 0; - } - - &:last-of-type > a { - padding-right: 0; - } - } - - // Sub-menus Flyout - & > li > ul { - margin: 0; - position: absolute; - background: #fff; - box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.2); - left: 0; - top: 100%; - min-width: max-content; - opacity: 0; - transition: all 0.5s ease; - visibility: hidden; - - ul { - width: 100%; - } - } - } - - // Menu Link - a { - display: block; - padding: 16px; - } - - // Sub-menu depth indicators - ul ul { - - list-style: none; - margin-left: 0; - // Reset the counter for each UL - counter-reset: nested-list; - - li a { - - padding-top: 8px; - padding-bottom: 8px; - - &::before { - // Increment the dashes - counter-increment: nested-list; - // Insert dashes with spaces in between - content: "\2013\00a0" counters(nested-list, "\2013\00a0", none); - } - } - } - - // Top-level sub-menu indicators - & .has-sub-menu > a { - - &::after { - content: "\00a0\25BC"; - display: inline-block; - font-size: 0.6rem; - height: inherit; - width: inherit; - } - } - -} diff --git a/packages/block-library/src/site-title/block.json b/packages/block-library/src/site-title/block.json deleted file mode 100644 index a853cde2517b51..00000000000000 --- a/packages/block-library/src/site-title/block.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "core/site-title", - "category": "layout" -} diff --git a/packages/block-library/src/site-title/edit.js b/packages/block-library/src/site-title/edit.js deleted file mode 100644 index 0294fb82d17a18..00000000000000 --- a/packages/block-library/src/site-title/edit.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * WordPress dependencies - */ -import { - useEntityProp, - __experimentalUseEntitySaving, -} from '@wordpress/core-data'; -import { Button } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { RichText } from '@wordpress/block-editor'; - -export default function SiteTitleEdit() { - const [ title, setTitle ] = useEntityProp( 'root', 'site', 'title' ); - const [ isDirty, isSaving, save ] = __experimentalUseEntitySaving( - 'root', - 'site', - 'title' - ); - return ( - <> - <Button - isPrimary - className="wp-block-site-title__save-button" - disabled={ ! isDirty || ! title } - isBusy={ isSaving } - onClick={ save } - > - { __( 'Update' ) } - </Button> - <RichText - tagName="h1" - placeholder={ __( 'Site Title' ) } - value={ title } - onChange={ setTitle } - allowedFormats={ [] } - /> - </> - ); -} diff --git a/packages/block-library/src/site-title/editor.scss b/packages/block-library/src/site-title/editor.scss deleted file mode 100644 index f2b8359cf3790b..00000000000000 --- a/packages/block-library/src/site-title/editor.scss +++ /dev/null @@ -1,6 +0,0 @@ -.wp-block-site-title__save-button { - position: absolute; - right: 0; - top: 0; - z-index: z-index(".wp-block-site-title__save-button"); -} diff --git a/packages/block-library/src/site-title/icon.js b/packages/block-library/src/site-title/icon.js deleted file mode 100644 index 1ab74dec2c32d3..00000000000000 --- a/packages/block-library/src/site-title/icon.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * WordPress dependencies - */ -import { SVG, Path, Circle } from '@wordpress/components'; - -export default ( - <SVG xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"> - <Path fill="none" d="M0 0h24v24H0V0z" /> - <Path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zM7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 2.88-2.88 7.19-5 9.88C9.92 16.21 7 11.85 7 9z" /> - <Circle cx="12" cy="9" r="2.5" /> - </SVG> -); diff --git a/packages/block-library/src/site-title/index.js b/packages/block-library/src/site-title/index.js deleted file mode 100644 index 4b8fc50b86b34f..00000000000000 --- a/packages/block-library/src/site-title/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import metadata from './block.json'; -import icon from './icon'; -import edit from './edit'; - -const { name } = metadata; -export { metadata, name }; - -export const settings = { - title: __( 'Site Title' ), - icon, - edit, -}; diff --git a/packages/block-library/src/site-title/index.php b/packages/block-library/src/site-title/index.php deleted file mode 100644 index 6e5b5786436f09..00000000000000 --- a/packages/block-library/src/site-title/index.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * Server-side rendering of the `core/site-title` block. - * - * @package WordPress - */ - -/** - * Renders the `core/site-title` block on the server. - * - * @return string The render. - */ -function render_block_core_site_title() { - return sprintf( '<h1>%s</h1>', get_bloginfo( 'name' ) ); -} - -/** - * Registers the `core/site-title` block on the server. - */ -function register_block_core_site_title() { - register_block_type( - 'core/site-title', - array( - 'render_callback' => 'render_block_core_site_title', - ) - ); -} -add_action( 'init', 'register_block_core_site_title' ); diff --git a/packages/block-library/src/social-link/index.php b/packages/block-library/src/social-link/index.php index 86d83b685e21e8..4d04c9cd1c12c4 100644 --- a/packages/block-library/src/social-link/index.php +++ b/packages/block-library/src/social-link/index.php @@ -22,7 +22,7 @@ function render_core_social_link( $attributes ) { } $icon = core_social_link_get_icon( $site ); - return '<li class="wp-social-link wp-social-link-' . $site . '"><a href="' . esc_url( $url ) . '"> ' . $icon . '</a></li>'; + return '<li class="wp-social-link wp-social-link-' . $site . '"><a href="' . esc_attr( $url ) . '"> ' . $icon . '</a></li>'; } /** diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index 3fd7e3c2b8e041..433ef8cb3aa2f3 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -11,7 +11,6 @@ @import "./latest-comments/style.scss"; @import "./latest-posts/style.scss"; @import "./media-text/style.scss"; -@import "./navigation-menu/style.scss"; @import "./paragraph/style.scss"; @import "./pullquote/style.scss"; @import "./quote/style.scss"; @@ -130,82 +129,6 @@ .has-very-dark-gray-color { color: #313131; } - - // Gradients - // Our classes uses the same values we set for gradient value attributes, and we can not use spacing because of WP multi site kses rule. - /* stylelint-disable function-comma-space-after */ - .has-vivid-cyan-blue-to-vivid-purple-gradient-background { - background: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%); - } - - .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background { - background: linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%); - } - - .has-light-green-cyan-to-vivid-green-cyan-gradient-background { - background: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%); - } - - .has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background { - background: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%); - } - - .has-luminous-vivid-orange-to-vivid-red-gradient-background { - background: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%); - } - - .has-very-light-gray-to-cyan-bluish-gray-gradient-background { - background: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%); - } - - .has-cool-to-warm-spectrum-gradient-background { - background: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%); - } - - .has-blush-light-purple-gradient-background { - background: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%); - } - - .has-blush-bordeaux-gradient-background { - background: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%); - } - - .has-purple-crush-gradient-background { - background: linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%); - } - - .has-luminous-dusk-gradient-background { - background: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%); - } - - .has-hazy-dawn-gradient-background { - background: linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%); - } - - .has-pale-ocean-gradient-background { - background: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%); - } - - .has-electric-grass-gradient-background { - background: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%); - } - - .has-subdued-olive-gradient-background { - background: linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%); - } - - .has-atomic-cream-gradient-background { - background: linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%); - } - - .has-nightshade-gradient-background { - background: linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%); - } - - .has-midnight-gradient-background { - background: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%); - } - /* stylelint-enable function-comma-space-after */ } diff --git a/packages/block-library/src/table/edit.js b/packages/block-library/src/table/edit.js index 1599bb7e53f64f..b86c0e282d7f9b 100644 --- a/packages/block-library/src/table/edit.js +++ b/packages/block-library/src/table/edit.js @@ -40,6 +40,7 @@ import { deleteColumn, toggleSection, isEmptyTableSection, + isCellSelected, } from './state'; import icon from './icon'; @@ -434,6 +435,7 @@ export class TableEdit extends Component { } const Tag = `t${ name }`; + const { selectedCell } = this.state; return ( <Tag> @@ -445,21 +447,35 @@ export class TableEdit extends Component { rowIndex, columnIndex, }; + const isSelected = isCellSelected( cellLocation, selectedCell ); const cellClasses = classnames( { + 'is-selected': isSelected, [ `has-text-align-${ align }` ]: align, - }, 'wp-block-table__cell-content' ); + } ); + const richTextClassName = 'wp-block-table__cell-content'; return ( - <RichText - tagName={ CellTag } + <CellTag key={ columnIndex } className={ cellClasses } scope={ CellTag === 'th' ? scope : undefined } - value={ content } - onChange={ this.onChange } - unstableOnFocus={ this.createOnFocus( cellLocation ) } - /> + onClick={ ( event ) => { + // When a cell is selected, forward focus to the child RichText. This solves an issue where the + // user may click inside a cell, but outside of the RichText, resulting in nothing happening. + const richTextElement = event && event.target && event.target.querySelector( `.${ richTextClassName }` ); + if ( richTextElement ) { + richTextElement.focus(); + } + } } + > + <RichText + className={ richTextClassName } + value={ content } + onChange={ this.onChange } + unstableOnFocus={ this.createOnFocus( cellLocation ) } + /> + </CellTag> ); } ) } </tr> diff --git a/packages/block-library/src/table/editor.scss b/packages/block-library/src/table/editor.scss index 16002aa4dbaae1..f5dbb5f2643c04 100644 --- a/packages/block-library/src/table/editor.scss +++ b/packages/block-library/src/table/editor.scss @@ -36,6 +36,7 @@ td, th { + padding: 0; border: $border-width solid; } @@ -46,6 +47,9 @@ border-style: double; } + &__cell-content { + padding: 0.5em; + } // Extra specificity to override default Placeholder styles. &__placeholder-form.wp-block-table__placeholder-form { text-align: left; diff --git a/packages/block-library/src/video/edit.js b/packages/block-library/src/video/edit.js index d7b3cad0592602..6236e51a95c935 100644 --- a/packages/block-library/src/video/edit.js +++ b/packages/block-library/src/video/edit.js @@ -319,8 +319,10 @@ class VideoEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { mediaUpload } = getSettings(); - return { mediaUpload }; + const { __experimentalMediaUpload } = getSettings(); + return { + mediaUpload: __experimentalMediaUpload, + }; } ), withNotices, withInstanceId, diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json index 8f2695921aa110..924dc7e4ad552e 100644 --- a/packages/block-serialization-default-parser/package.json +++ b/packages/block-serialization-default-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-default-parser", - "version": "3.4.1", + "version": "3.4.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index 289e8b8e86afd4..28b1a0436de041 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-spec-parser", - "version": "3.3.1", + "version": "3.3.0", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 97a4e95676fc28..1af3f49adef88a 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -768,7 +768,7 @@ wrapped component. _Returns_ -- `WPComponent`: Enhanced component with injected BlockContent as prop. +- `Component`: Enhanced component with injected BlockContent as prop. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 30f3255b9188b7..3456e2386251e0 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "6.7.2", + "version": "6.7.0", "description": "Block API for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index e793800ecb1362..fae2e0e4da9c06 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -44,26 +44,26 @@ export function createBlock( name, attributes = {}, innerBlocks = [] ) { // Ensure attributes contains only values defined by block type, and merge // default values for missing attributes. - const sanitizedAttributes = reduce( blockType.attributes, ( accumulator, schema, key ) => { + const sanitizedAttributes = reduce( blockType.attributes, ( result, schema, key ) => { const value = attributes[ key ]; if ( undefined !== value ) { - accumulator[ key ] = value; + result[ key ] = value; } else if ( schema.hasOwnProperty( 'default' ) ) { - accumulator[ key ] = schema.default; + result[ key ] = schema.default; } if ( [ 'node', 'children' ].indexOf( schema.source ) !== -1 ) { // Ensure value passed is always an array, which we're expecting in // the RichText component to handle the deprecated value. - if ( typeof accumulator[ key ] === 'string' ) { - accumulator[ key ] = [ accumulator[ key ] ]; - } else if ( ! Array.isArray( accumulator[ key ] ) ) { - accumulator[ key ] = []; + if ( typeof result[ key ] === 'string' ) { + result[ key ] = [ result[ key ] ]; + } else if ( ! Array.isArray( result[ key ] ) ) { + result[ key ] = []; } } - return accumulator; + return result; }, {} ); const clientId = uuid(); diff --git a/packages/blocks/src/api/index.native.js b/packages/blocks/src/api/index.native.js new file mode 100644 index 00000000000000..b2cfd4963d2e81 --- /dev/null +++ b/packages/blocks/src/api/index.native.js @@ -0,0 +1,44 @@ +export { + cloneBlock, + createBlock, + switchToBlockType, +} from './factory'; +export { + default as parse, + getBlockAttributes, + parseWithAttributeSchema, +} from './parser'; +export { + default as serialize, + getBlockContent, + getBlockDefaultClassName, + getSaveContent, +} from './serializer'; +export { + registerBlockType, + unregisterBlockType, + getFreeformContentHandlerName, + setUnregisteredTypeHandlerName, + getUnregisteredTypeHandlerName, + getBlockType, + getBlockTypes, + getBlockSupport, + hasBlockSupport, + isReusableBlock, + getChildBlockNames, + hasChildBlocks, + hasChildBlocksWithInserterSupport, + setDefaultBlockName, + getDefaultBlockName, + setGroupingBlockName, +} from './registration'; +export { + isUnmodifiedDefaultBlock, + normalizeIconObject, +} from './utils'; +export { + doBlocksMatchTemplate, + synchronizeBlocksWithTemplate, +} from './templates'; +export { pasteHandler, getPhrasingContentSchema } from './raw-handling'; +export { default as children } from './children'; diff --git a/packages/blocks/src/api/parser.js b/packages/blocks/src/api/parser.js index 6300eac329f153..89b4f5ee5cc9f9 100644 --- a/packages/blocks/src/api/parser.js +++ b/packages/blocks/src/api/parser.js @@ -565,12 +565,12 @@ export function serializeBlockNode( blockNode, options = {} ) { * @return {Function} An implementation which parses the post content. */ const createParse = ( parseImplementation ) => - ( content ) => parseImplementation( content ).reduce( ( accumulator, blockNode ) => { + ( content ) => parseImplementation( content ).reduce( ( memo, blockNode ) => { const block = createBlockWithFallback( blockNode ); if ( block ) { - accumulator.push( block ); + memo.push( block ); } - return accumulator; + return memo; }, [] ); /** diff --git a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js index 4f3c3a2a810a99..5c5ef223298fe6 100644 --- a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js +++ b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { includes } from 'lodash'; - /** * WordPress dependencies */ @@ -16,7 +11,6 @@ export default function( node, doc ) { fontWeight, fontStyle, textDecorationLine, - textDecoration, verticalAlign, } = node.style; @@ -28,10 +22,7 @@ export default function( node, doc ) { wrap( doc.createElement( 'em' ), node ); } - // Some DOM implementations (Safari, JSDom) don't support - // style.textDecorationLine, so we check style.textDecoration as a - // fallback. - if ( textDecorationLine === 'line-through' || includes( textDecoration, 'line-through' ) ) { + if ( textDecorationLine === 'line-through' ) { wrap( doc.createElement( 's' ), node ); } diff --git a/packages/blocks/src/api/raw-handling/shortcode-converter.js b/packages/blocks/src/api/raw-handling/shortcode-converter.js index 10f1159c92cb0c..5385f0aed41502 100644 --- a/packages/blocks/src/api/raw-handling/shortcode-converter.js +++ b/packages/blocks/src/api/raw-handling/shortcode-converter.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { some, castArray, find, mapValues, pickBy, includes } from 'lodash'; +import { some, castArray, first, mapValues, pickBy, includes } from 'lodash'; /** * WordPress dependencies @@ -29,7 +29,7 @@ function segmentHTMLToShortcodeBlock( HTML, lastIndex = 0 ) { } const transformTags = castArray( transformation.tag ); - const transformTag = find( transformTags, ( tag ) => regexp( tag ).test( HTML ) ); + const transformTag = first( transformTags ); let match; diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 0d3dd7827680ec..024f9e9d55a3e3 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -60,11 +60,11 @@ import { DEPRECATED_ENTRY_KEYS } from './constants'; /** * Defined behavior of a block type. * - * @typedef {Object} WPBlock + * @typedef {Object} WPBlockType * - * @property {string} name Block type's namespaced name. - * @property {string} title Human-readable block type label. - * @property {string} category Block type category classification, + * @property {string} name Block type's namespaced name. + * @property {string} title Human-readable block type label. + * @property {string} category Block type category classification, * used in search interfaces to arrange * block types by category. * @property {WPBlockTypeIcon} [icon] Block type icon. @@ -74,7 +74,7 @@ import { DEPRECATED_ENTRY_KEYS } from './constants'; * @property {WPComponent} [save] Optional component describing * serialized markup structure of a * block type. - * @property {WPComponent} edit Component rendering an element to + * @property {WPComponent} edit Component rendering an element to * manipulate the attributes of a block * in the context of an editor. */ @@ -114,7 +114,7 @@ export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { / * @param {Object} settings Block settings. * * @return {?WPBlock} The block, if it has been successfully registered; - * otherwise `undefined`. + * otherwise `undefined`. */ export function registerBlockType( name, settings ) { settings = { @@ -234,7 +234,7 @@ export function registerBlockType( name, settings ) { * @param {string} name Block name. * * @return {?WPBlock} The previous block value, if it has been successfully - * unregistered; otherwise `undefined`. + * unregistered; otherwise `undefined`. */ export function unregisterBlockType( name ) { const oldBlock = select( 'core/blocks' ).getBlockType( name ); diff --git a/packages/blocks/src/api/serializer.js b/packages/blocks/src/api/serializer.js index d2dfbcab2d672b..1776a32e362999 100644 --- a/packages/blocks/src/api/serializer.js +++ b/packages/blocks/src/api/serializer.js @@ -85,9 +85,9 @@ export function getSaveElement( blockTypeOrName, attributes, innerBlocks = [] ) /** * Filters the props applied to the block save result element. * - * @param {Object} props Props applied to save element. - * @param {WPBlock} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {Object} props Props applied to save element. + * @param {WPBlockType} blockType Block type definition. + * @param {Object} attributes Block attributes. */ const props = applyFilters( 'blocks.getSaveContent.extraProps', @@ -104,9 +104,9 @@ export function getSaveElement( blockTypeOrName, attributes, innerBlocks = [] ) /** * Filters the save result of a block during serialization. * - * @param {WPElement} element Block save result. - * @param {WPBlock} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {WPElement} element Block save result. + * @param {WPBlockType} blockType Block type definition. + * @param {Object} attributes Block attributes. */ element = applyFilters( 'blocks.getSaveElement', element, blockType, attributes ); @@ -150,27 +150,28 @@ export function getSaveContent( blockTypeOrName, attributes, innerBlocks ) { * @return {Object<string,*>} Subset of attributes for comment serialization. */ export function getCommentAttributes( blockType, attributes ) { - return reduce( blockType.attributes, ( accumulator, attributeSchema, key ) => { + return reduce( blockType.attributes, ( result, attributeSchema, key ) => { const value = attributes[ key ]; + // Ignore undefined values. if ( undefined === value ) { - return accumulator; + return result; } // Ignore all attributes but the ones with an "undefined" source // "undefined" source refers to attributes saved in the block comment. if ( attributeSchema.source !== undefined ) { - return accumulator; + return result; } // Ignore default value. if ( 'default' in attributeSchema && attributeSchema.default === value ) { - return accumulator; + return result; } // Otherwise, include in comment set. - accumulator[ key ] = value; - return accumulator; + result[ key ] = value; + return result; }, {} ); } diff --git a/packages/blocks/src/block-content-provider/index.js b/packages/blocks/src/block-content-provider/index.js index 96b9a4d31bcd1b..352550a87be80f 100644 --- a/packages/blocks/src/block-content-provider/index.js +++ b/packages/blocks/src/block-content-provider/index.js @@ -26,7 +26,7 @@ const { Consumer, Provider } = createContext( () => {} ); * </BlockContentProvider> * ``` * - * @return {WPComponent} Element with BlockContent injected via context. + * @return {WPElement} Element with BlockContent injected via context. */ const BlockContentProvider = ( { children, innerBlocks } ) => { const BlockContent = () => { @@ -48,7 +48,7 @@ const BlockContentProvider = ( { children, innerBlocks } ) => { * A Higher Order Component used to inject BlockContent using context to the * wrapped component. * - * @return {WPComponent} Enhanced component with injected BlockContent as prop. + * @return {Component} Enhanced component with injected BlockContent as prop. */ export const withBlockContentContext = createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/components/package.json b/packages/components/package.json index c542fc3a79a7e0..d19667eca46cf5 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "8.3.2", + "version": "8.3.0", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/components/src/autocomplete/index.js b/packages/components/src/autocomplete/index.js index b12f97b30367ba..283ccd92633b04 100644 --- a/packages/components/src/autocomplete/index.js +++ b/packages/components/src/autocomplete/index.js @@ -91,7 +91,7 @@ import withSpokenMessages from '../higher-order/with-spoken-messages'; */ /** - * @typedef {Object} WPCompleter + * @typedef {Object} Completer * @property {string} name a way to identify a completer, useful for selective overriding. * @property {?string} className A class to apply to the popup menu. * @property {string} triggerPrefix the prefix that will display the menu. @@ -232,8 +232,8 @@ export class Autocomplete extends Component { /** * Load options for an autocompleter. * - * @param {WPCompleter} completer The autocompleter. - * @param {string} query The query, if any. + * @param {Completer} completer The autocompleter. + * @param {string} query The query, if any. */ loadOptions( completer, query ) { const { options } = completer; diff --git a/packages/components/src/button-group/stories/index.js b/packages/components/src/button-group/stories/index.js index 8b1a694691025c..1e1646e0268d15 100644 --- a/packages/components/src/button-group/stories/index.js +++ b/packages/components/src/button-group/stories/index.js @@ -4,7 +4,7 @@ import Button from '../../button'; import ButtonGroup from '../'; -export default { title: 'ButtonGroup', component: ButtonGroup }; +export default { title: 'Button Group', component: ButtonGroup }; export const _default = () => { const style = { margin: '0 4px' }; diff --git a/packages/components/src/button/stories/index.js b/packages/components/src/button/stories/index.js index b3c3b408c373ec..ae949a1cd72906 100644 --- a/packages/components/src/button/stories/index.js +++ b/packages/components/src/button/stories/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { text } from '@storybook/addon-knobs'; - /** * Internal dependencies */ @@ -10,78 +5,32 @@ import Button from '../'; export default { title: 'Button', component: Button }; -export const _default = () => { - const label = text( 'Label', 'Default Button' ); - - return ( - <Button>{ label }</Button> - ); -}; - -export const primary = () => { - const label = text( 'Label', 'Primary Button' ); - - return ( - <Button isPrimary>{ label }</Button> - ); -}; - -export const large = () => { - const label = text( 'Label', 'Large Button' ); - - return ( - <Button isLarge>{ label }</Button> - ); -}; - -export const largePrimary = () => { - const label = text( 'Label', 'Large Primary Button' ); - - return ( - <Button isPrimary isLarge>{ label }</Button> - ); -}; - -export const small = () => { - const label = text( 'Label', 'Small Button' ); - - return ( - <Button isSmall>{ label }</Button> - ); -}; +export const _default = () => <Button>Hello Button</Button>; -export const toggled = () => { - const label = text( 'Label', 'Toggled Button' ); +export const primary = () => <Button isPrimary>Hello Button</Button>; - return ( - <Button isToggled>{ label }</Button> - ); -}; +export const large = () => <Button isLarge>Hello Button</Button>; -export const disabled = () => { - const label = text( 'Label', 'Disabled Button' ); +export const largePrimary = () => ( + <Button isPrimary isLarge> + Hello Button + </Button> +); - return ( - <Button disabled>{ label }</Button> - ); -}; +export const small = () => <Button isSmall>Hello Button</Button>; -export const link = () => { - const label = text( 'Label', 'Link Button' ); +export const toggled = () => <Button isToggled>Hello Button</Button>; - return ( - <Button href="https://wordpress.org/" target="_blank"> - { label } - </Button> - ); -}; +export const disabled = () => <Button disabled>Hello Button</Button>; -export const disabledLink = () => { - const label = text( 'Label', 'Disabled Link Button' ); +export const link = () => ( + <Button href="https://wordpress.org/" target="_blank"> + Hello Button + </Button> +); - return ( - <Button href="https://wordpress.org/" target="_blank" disabled> - { label } - </Button> - ); -}; +export const disabledLink = () => ( + <Button href="https://wordpress.org/" target="_blank" disabled> + Hello Button + </Button> +); diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 2f62f199794eda..6d3f94a18a1c24 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -37,7 +37,7 @@ background: #f3f5f6; color: color(theme(button) shade(25%)); border-color: color(theme(button) shade(5%)); - box-shadow: 0 0 0 $border-width color(theme(button) shade(5%)); + box-shadow: 0 0 0 1px color(theme(button) shade(5%)); text-decoration: none; } @@ -54,7 +54,7 @@ color: #a0a5aa; border-color: #ddd; background: #f7f7f7; - text-shadow: 0 $border-width 0 #fff; + text-shadow: 0 1px 0 #fff; transform: none; opacity: 1; } @@ -76,7 +76,7 @@ &:focus:enabled { box-shadow: - 0 0 0 $border-width $white, + 0 0 0 1px $white, 0 0 0 3px color(theme(button)); } @@ -107,7 +107,7 @@ &:focus:enabled { box-shadow: - 0 0 0 $border-width $white, + 0 0 0 1px $white, 0 0 0 3px color(theme(button)); } } @@ -157,8 +157,8 @@ &:focus { color: #124964; box-shadow: - 0 0 0 $border-width #5b9dd9, - 0 0 2px $border-width rgba(30, 140, 190, 0.8); + 0 0 0 1px #5b9dd9, + 0 0 2px 1px rgba(30, 140, 190, 0.8); } } diff --git a/packages/components/src/checkbox-control/README.md b/packages/components/src/checkbox-control/README.md index b6245fbd036cd0..43165e8ae1b59c 100644 --- a/packages/components/src/checkbox-control/README.md +++ b/packages/components/src/checkbox-control/README.md @@ -56,16 +56,17 @@ If only a few child checkboxes are checked, the parent checkbox becomes a mixed Render an is author checkbox: ```jsx import { CheckboxControl } from '@wordpress/components'; -import { useState } from '@wordpress/element'; +import { withState } from '@wordpress/compose'; -const MyCheckboxControl = () => ( - const [ isChecked, setChecked ] = useState( true ); +const MyCheckboxControl = withState( { + isChecked: true, +} )( ( { isChecked, setState } ) => ( <CheckboxControl heading="User" label="Is author" help="Is the user a author or not?" checked={ isChecked } - onChange={ setChecked } + onChange={ ( isChecked ) => { setState( { isChecked } ) } } /> ) ); ``` diff --git a/packages/components/src/checkbox-control/stories/index.js b/packages/components/src/checkbox-control/stories/index.js deleted file mode 100644 index 40b48ccf3ef3a2..00000000000000 --- a/packages/components/src/checkbox-control/stories/index.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * External dependencies - */ -import { text } from '@storybook/addon-knobs'; - -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import CheckboxControl from '../'; - -export default { title: 'CheckboxControl', component: CheckboxControl }; - -const CheckboxControlWithState = ( { checked, ...props } ) => { - const [ isChecked, setChecked ] = useState( checked ); - - return ( - <CheckboxControl - { ...props } - checked={ isChecked } - onChange={ setChecked } - /> - ); -}; - -export const _default = () => { - const label = text( 'Label', 'Is author' ); - - return ( - <CheckboxControlWithState - label={ label } - checked - /> - ); -}; - -export const all = () => { - const heading = text( 'Heading', 'User' ); - const label = text( 'Label', 'Is author' ); - const help = text( 'Help', 'Is the user an author or not?' ); - - return ( - <CheckboxControlWithState - heading={ heading } - label={ label } - help={ help } - checked - /> - ); -}; diff --git a/packages/components/src/clipboard-button/stories/index.js b/packages/components/src/clipboard-button/stories/index.js index 7e0146448d56d5..25632614eb249d 100644 --- a/packages/components/src/clipboard-button/stories/index.js +++ b/packages/components/src/clipboard-button/stories/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { boolean, text } from '@storybook/addon-knobs'; - /** * WordPress dependencies */ @@ -13,30 +8,18 @@ import { useState } from '@wordpress/element'; */ import ClipboardButton from '../'; -export default { title: 'ClipboardButton', component: ClipboardButton }; - -const ClipboardButtonWithState = ( { copied, ...props } ) => { - const [ isCopied, setCopied ] = useState( copied ); +export default { title: 'Clipboard Button', component: ClipboardButton }; +export const _default = () => { + const [ copied, setCopied ] = useState( false ); return ( <ClipboardButton - { ...props } + isPrimary + text="Text" onCopy={ () => setCopied( true ) } onFinishCopy={ () => setCopied( false ) } > - { isCopied ? 'Copied!' : `Copy "${ props.text }"` } + { copied ? 'Copied!' : 'Copy "Text"' } </ClipboardButton> ); }; - -export const _default = () => { - const isPrimary = boolean( 'Is primary', true ); - const copyText = text( 'Text', 'Text' ); - - return ( - <ClipboardButtonWithState - isPrimary={ isPrimary } - text={ copyText } - /> - ); -}; diff --git a/packages/components/src/color-indicator/stories/index.js b/packages/components/src/color-indicator/stories/index.js index d14f180abbe25a..3e9400b0919c11 100644 --- a/packages/components/src/color-indicator/stories/index.js +++ b/packages/components/src/color-indicator/stories/index.js @@ -1,21 +1,13 @@ -/** - * External dependencies - */ -import { text } from '@storybook/addon-knobs'; - /** * Internal dependencies */ import ColorIndicator from '../'; export default { - title: 'ColorIndicator', + title: 'Color Indicator', component: ColorIndicator, }; -export const _default = () => { - const color = text( 'Color', '#0073aa' ); - return ( - <ColorIndicator colorValue={ color } /> - ); -}; +export const _default = () => ( + <ColorIndicator colorValue="#0073aa" /> +); diff --git a/packages/components/src/color-palette/stories/index.js b/packages/components/src/color-palette/stories/index.js deleted file mode 100644 index 3cc1f4f8ff66df..00000000000000 --- a/packages/components/src/color-palette/stories/index.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * External dependencies - */ -import { object } from '@storybook/addon-knobs'; - -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import ColorPalette from '../'; - -export default { title: 'ColorPalette', component: ColorPalette }; - -const ColorPaletteWithState = ( props ) => { - const [ color, setColor ] = useState( '#F00' ); - return ( - <ColorPalette - { ...props } - value={ color } - onChange={ setColor } - /> - ); -}; - -export const _default = () => { - const colors = [ - { name: 'red', color: '#f00' }, - { name: 'white', color: '#fff' }, - { name: 'blue', color: '#00f' }, - ]; - - return ( - <ColorPaletteWithState - colors={ colors } - /> - ); -}; - -export const withKnobs = () => { - const colors = [ - object( 'Red', { name: 'red', color: '#f00' } ), - object( 'White', { name: 'white', color: '#fff' } ), - object( 'Blue', { name: 'blue', color: '#00f' } ), - ]; - - return ( - <ColorPaletteWithState - colors={ colors } - /> - ); -}; - diff --git a/packages/components/src/color-picker/hue.js b/packages/components/src/color-picker/hue.js index 0c97020d89efdc..214df7e725bdc1 100644 --- a/packages/components/src/color-picker/hue.js +++ b/packages/components/src/color-picker/hue.js @@ -43,7 +43,6 @@ import { TAB } from '@wordpress/keycodes'; */ import { calculateHueChange } from './utils'; import KeyboardShortcuts from '../keyboard-shortcuts'; -import VisuallyHidden from '../visually-hidden'; export class Hue extends Component { constructor() { @@ -158,11 +157,12 @@ export class Hue extends Component { style={ pointerLocation } onKeyDown={ this.preventKeyEvents } /> - <VisuallyHidden as="p" + <p + className="components-color-picker__hue-description screen-reader-text" id={ `components-color-picker__hue-description-${ instanceId }` } > { __( 'Move the arrow left or right to change hue.' ) } - </VisuallyHidden> + </p> </div> { /* eslint-enable jsx-a11y/no-static-element-interactions */ } </div> diff --git a/packages/components/src/color-picker/inputs.js b/packages/components/src/color-picker/inputs.js index 42e77a31e71820..39817d13edb74f 100644 --- a/packages/components/src/color-picker/inputs.js +++ b/packages/components/src/color-picker/inputs.js @@ -17,7 +17,6 @@ import { pure } from '@wordpress/compose'; */ import IconButton from '../icon-button'; import TextControl from '../text-control'; -import VisuallyHidden from '../visually-hidden'; import { isValidHex } from './utils'; /* Wrapper for TextControl, only used to handle intermediate state while typing. */ @@ -176,9 +175,9 @@ export class Inputs extends Component { } else if ( this.state.view === 'rgb' ) { return ( <fieldset> - <VisuallyHidden as="legend"> + <legend className="screen-reader-text"> { __( 'Color value in RGB' ) } - </VisuallyHidden> + </legend> <div className="components-color-picker__inputs-fields"> <Input source={ this.state.view } @@ -229,9 +228,9 @@ export class Inputs extends Component { } else if ( this.state.view === 'hsl' ) { return ( <fieldset> - <VisuallyHidden as="legend"> + <legend className="screen-reader-text"> { __( 'Color value in HSL' ) } - </VisuallyHidden> + </legend> <div className="components-color-picker__inputs-fields"> <Input source={ this.state.view } diff --git a/packages/components/src/color-picker/saturation.js b/packages/components/src/color-picker/saturation.js index ae1f80333237d5..3bdd10bfcdfe28 100644 --- a/packages/components/src/color-picker/saturation.js +++ b/packages/components/src/color-picker/saturation.js @@ -43,7 +43,6 @@ import { compose, pure, withInstanceId } from '@wordpress/compose'; */ import { calculateSaturationChange } from './utils'; import KeyboardShortcuts from '../keyboard-shortcuts'; -import VisuallyHidden from '../visually-hidden'; export class Saturation extends Component { constructor( props ) { @@ -172,12 +171,13 @@ export class Saturation extends Component { style={ pointerLocation } onKeyDown={ this.preventKeyEvents } /> - <VisuallyHidden + <div + className="screen-reader-text" id={ `color-picker-saturation-${ instanceId }` }> { __( 'Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation.' ) } - </VisuallyHidden> + </div> </div> </KeyboardShortcuts> ); diff --git a/packages/components/src/color-picker/stories/index.js b/packages/components/src/color-picker/stories/index.js deleted file mode 100644 index 19bca39729d4f5..00000000000000 --- a/packages/components/src/color-picker/stories/index.js +++ /dev/null @@ -1,39 +0,0 @@ - -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import ColorPicker from '../'; - -export default { title: 'ColorPicker', component: ColorPicker }; - -const ColorPickerWithState = ( { ...props } ) => { - const [ color, setColor ] = useState( '#f00' ); - return ( - <ColorPicker - { ...props } - color={ color } - onChangeComplete={ ( value ) => setColor( value.hex ) } - /> - ); -}; - -export const _default = () => { - return ( - <ColorPickerWithState - disableAlpha - /> - ); -}; - -export const alphaEnabled = () => { - return ( - <ColorPickerWithState - disableAlpha={ false } - /> - ); -}; diff --git a/packages/components/src/color-picker/test/__snapshots__/index.js.snap b/packages/components/src/color-picker/test/__snapshots__/index.js.snap index a3713f860f3c01..5d61a24e5ac9e6 100644 --- a/packages/components/src/color-picker/test/__snapshots__/index.js.snap +++ b/packages/components/src/color-picker/test/__snapshots__/index.js.snap @@ -39,7 +39,7 @@ exports[`ColorPicker should commit changes to all views on blur 1`] = ` } /> <div - className="components-visually-hidden" + className="screen-reader-text" id="color-picker-saturation-2" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -99,7 +99,7 @@ exports[`ColorPicker should commit changes to all views on blur 1`] = ` tabIndex="0" /> <p - className="components-visually-hidden" + className="components-color-picker__hue-description screen-reader-text" id="components-color-picker__hue-description-2" > Move the arrow left or right to change hue. @@ -213,7 +213,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = DOWN 1`] = } /> <div - className="components-visually-hidden" + className="screen-reader-text" id="color-picker-saturation-4" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -273,7 +273,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = DOWN 1`] = tabIndex="0" /> <p - className="components-visually-hidden" + className="components-color-picker__hue-description screen-reader-text" id="components-color-picker__hue-description-4" > Move the arrow left or right to change hue. @@ -387,7 +387,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = ENTER 1`] = } /> <div - className="components-visually-hidden" + className="screen-reader-text" id="color-picker-saturation-5" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -447,7 +447,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = ENTER 1`] = tabIndex="0" /> <p - className="components-visually-hidden" + className="components-color-picker__hue-description screen-reader-text" id="components-color-picker__hue-description-5" > Move the arrow left or right to change hue. @@ -561,7 +561,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = UP 1`] = ` } /> <div - className="components-visually-hidden" + className="screen-reader-text" id="color-picker-saturation-3" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -621,7 +621,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = UP 1`] = ` tabIndex="0" /> <p - className="components-visually-hidden" + className="components-color-picker__hue-description screen-reader-text" id="components-color-picker__hue-description-3" > Move the arrow left or right to change hue. @@ -735,7 +735,7 @@ exports[`ColorPicker should only update input view for draft changes 1`] = ` } /> <div - className="components-visually-hidden" + className="screen-reader-text" id="color-picker-saturation-1" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -795,7 +795,7 @@ exports[`ColorPicker should only update input view for draft changes 1`] = ` tabIndex="0" /> <p - className="components-visually-hidden" + className="components-color-picker__hue-description screen-reader-text" id="components-color-picker__hue-description-1" > Move the arrow left or right to change hue. @@ -909,7 +909,7 @@ exports[`ColorPicker should render color picker 1`] = ` } /> <div - className="components-visually-hidden" + className="screen-reader-text" id="color-picker-saturation-0" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -969,7 +969,7 @@ exports[`ColorPicker should render color picker 1`] = ` tabIndex="0" /> <p - className="components-visually-hidden" + className="components-color-picker__hue-description screen-reader-text" id="components-color-picker__hue-description-0" > Move the arrow left or right to change hue. diff --git a/packages/components/src/dashicon/stories/index.js b/packages/components/src/dashicon/stories/index.js deleted file mode 100644 index 5ba7d7be98cbcb..00000000000000 --- a/packages/components/src/dashicon/stories/index.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * External dependencies - */ -import { number, text } from '@storybook/addon-knobs'; - -/** - * Internal dependencies - */ -import Dashicon from '../'; - -export default { title: 'Dashicon', component: Dashicon }; - -export const _default = () => { - const icon = text( 'Icon', 'wordpress' ); - const color = text( 'Color', '#0079AA' ); - const size = number( 'Size', 20 ); - - return ( - <Dashicon - icon={ icon } - color={ color } - size={ size } - /> - ); -}; diff --git a/packages/components/src/date-time/date.js b/packages/components/src/date-time/date.js index 7b1accff50227d..7361494a61e688 100644 --- a/packages/components/src/date-time/date.js +++ b/packages/components/src/date-time/date.js @@ -65,7 +65,7 @@ class DatePicker extends Component { * object representing now. If a null value is passed, return a null value. * * @param {?string} currentDate Date representing the currently selected date or null to signify no selection. - * @return {?moment.Moment} Moment object for selected date or null. + * @return {?Moment} Moment object for selected date or null. */ getMomentDate( currentDate ) { if ( null === currentDate ) { diff --git a/packages/components/src/date-time/index.js b/packages/components/src/date-time/index.js index bb7434d2e82ce3..97bd891cac9a7c 100644 --- a/packages/components/src/date-time/index.js +++ b/packages/components/src/date-time/index.js @@ -34,7 +34,7 @@ export class DateTimePicker extends Component { } render() { - const { currentDate, is12Hour, isInvalidDate, onChange } = this.props; + const { currentDate, is12Hour, onChange } = this.props; return ( <div className="components-datetime"> @@ -48,7 +48,6 @@ export class DateTimePicker extends Component { <DatePicker currentDate={ currentDate } onChange={ onChange } - isInvalidDate={ isInvalidDate } /> </> ) } diff --git a/packages/components/src/dimension-control/README.md b/packages/components/src/dimension-control/README.md deleted file mode 100644 index 435fdf4e73b046..00000000000000 --- a/packages/components/src/dimension-control/README.md +++ /dev/null @@ -1,120 +0,0 @@ -DimensionControl -============================= - -`DimensionControl` is a component designed to provide a UI to control spacing and/or dimensions. - -## Usage - -In a block's `edit` implementation, render a `<DimensionControl />` component. - - -```jsx -import { registerBlockType } from '@wordpress/blocks'; -import { __ } from '@wordpress/i18n'; -import { - DimensionControl, -} from '@wordpress/block-editor'; - -registerBlockType( 'my-plugin/my-block', { - // ... - - attributes: { - // other attributes here - // ... - - paddingSize: { - type: 'string', - }, - }, - - edit( { attributes, setAttributes, clientId } ) { - - const { paddingSize } = attributes; - - - const updateSpacing = ( dimension, size, device = '' ) => { - setAttributes( { - [ `${ dimension }${ device }` ]: size, - } ); - }; - - return ( - <DimensionControl - label={ __( 'Padding' ) } - icon={ 'desktop' } - onChange={ partialRight( updateSpacing, 'paddingSize' ) } - value={ paddingSize } - /> - ); - } -} ); -``` - -_Note:_ it is recommended to partially apply the value of the Block attribute to be updated (eg: `paddingSize`, `marginSize`...etc) to your callback functions. This avoids the need to unnecessarily couple the component to the Block attribute schema. - -_Note:_ by default, if you do not provide an initial `value` prop for the current dimension value, then no value will be selected (ie: there is no default dimension set). - -## Props - -### `label` -* **Type:** `String` -* **Default:** `undefined` -* **Required:** Yes - -The human readable label for the control. - -### `value` -* **Type:** `String` -* **Default:** `''` -* **Required:** No - -The current value of the dimension UI control. If provided the UI with automatically select the value. - -### `sizes` -* **Type:** `Array` -* **Default:** See `packages/block-editor/src/components/dimension-control/sizes.js` -* **Required:** No - -An optional array of size objects in the following shape: - -``` -[ - { - name: __( 'Small' ), - slug: 'small', - }, - { - name: __( 'Medium' ), - slug: 'small', - }, - // ...etc -] -``` - -By default a set of relative sizes (`small`, `medium`...etc) are provided. See `packages/block-editor/src/components/dimension-control/sizes.js`. - -### `icon` -* **Type:** `String` -* **Default:** `undefined` -* **Required:** No - -An optional dashicon to display before to the control label. - -### `onChange` -* **Type:** `Function` -* **Default:** `undefined` -* **Required:** No -* **Arguments:**: - - `size` - a string representing the selected size (eg: `medium`) - -A callback which is triggered when a spacing size value changes (is selected/clicked). - - -### `className` -* **Type:** `String` -* **Default:** `''` -* **Required:** No - -A string of classes to be added to the control component. - - diff --git a/packages/components/src/dimension-control/index.js b/packages/components/src/dimension-control/index.js deleted file mode 100644 index c69b80f5c49e02..00000000000000 --- a/packages/components/src/dimension-control/index.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { isFunction } from 'lodash'; - -/** - * WordPress dependencies - */ -/** - * Internal dependencies - */ -import { - Icon, - SelectControl, -} from '../'; -import { __ } from '@wordpress/i18n'; - -import { - Fragment, -} from '@wordpress/element'; - -/** - * Internal dependencies - */ -import sizesTable, { findSizeBySlug } from './sizes'; - -export function DimensionControl( props ) { - const { label, value, sizes = sizesTable, icon, onChange, className = '' } = props; - - const onChangeSpacingSize = ( val ) => { - const theSize = findSizeBySlug( sizes, val ); - - if ( ! theSize || value === theSize.slug ) { - onChange( undefined ); - } else if ( isFunction( onChange ) ) { - onChange( theSize.slug ); - } - }; - - const formatSizesAsOptions = ( theSizes ) => { - const options = theSizes.map( ( { name, slug } ) => ( { - label: name, - value: slug, - } ) ); - - return [ { - label: __( 'Default' ), - value: '', - } ].concat( options ); - }; - - const selectLabel = ( - <Fragment> - { icon && ( - <Icon - icon={ icon } - /> - ) } - { label } - </Fragment> - ); - - return ( - <SelectControl - className={ classnames( className, 'block-editor-dimension-control' ) } - label={ selectLabel } - hideLabelFromVision={ false } - value={ value } - onChange={ onChangeSpacingSize } - options={ formatSizesAsOptions( sizes ) } - /> - ); -} - -export default DimensionControl; diff --git a/packages/components/src/dimension-control/sizes.js b/packages/components/src/dimension-control/sizes.js deleted file mode 100644 index 41fa0717028725..00000000000000 --- a/packages/components/src/dimension-control/sizes.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Sizes - * - * defines the sizes used in dimension controls - * all hardcoded `size` values are based on the value of - * the Sass variable `$block-padding` from - * `packages/block-editor/src/components/dimension-control/sizes.js`. - */ - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - -/** - * Finds the correct size object from the provided sizes - * table by size slug (eg: `medium`) - * - * @param {Array} sizes containing objects for each size definition - * @param {string} slug a string representation of the size (eg: `medium`) - * @return {Object} the matching size definition - */ -export const findSizeBySlug = ( sizes, slug ) => sizes.find( ( size ) => slug === size.slug ); - -export default [ - { - name: __( 'None' ), - slug: 'none', - }, - { - name: __( 'Small' ), - slug: 'small', - }, - { - name: __( 'Medium' ), - slug: 'medium', - }, - { - name: __( 'Large' ), - slug: 'large', - }, { - name: __( 'Extra Large' ), - slug: 'xlarge', - }, -]; diff --git a/packages/components/src/dimension-control/style.scss b/packages/components/src/dimension-control/style.scss deleted file mode 100644 index 7f1481747dfe1a..00000000000000 --- a/packages/components/src/dimension-control/style.scss +++ /dev/null @@ -1,22 +0,0 @@ -.block-editor-dimension-control { - - .components-base-control__field { - display: flex; - align-items: center; - } - - .components-base-control__label { - display: flex; - align-items: center; - margin-right: 1em; - margin-bottom: 0; - - .dashicon { - margin-right: 0.5em; - } - } - - &.is-manual .components-base-control__label { - width: 10em; - } -} diff --git a/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap b/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap deleted file mode 100644 index c06662ee862c99..00000000000000 --- a/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap +++ /dev/null @@ -1,163 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DimensionControl rendering renders with custom sizes 1`] = ` -<WithInstanceId(SelectControl) - className="block-editor-dimension-control" - hideLabelFromVision={false} - label={ - <React.Fragment> - Custom Dimension - </React.Fragment> - } - onChange={[Function]} - options={ - Array [ - Object { - "label": "Default", - "value": "", - }, - Object { - "label": "Mini", - "value": "mini", - }, - Object { - "label": "Middle", - "value": "middle", - }, - Object { - "label": "Giant", - "value": "giant", - }, - ] - } -/> -`; - -exports[`DimensionControl rendering renders with defaults 1`] = ` -<WithInstanceId(SelectControl) - className="block-editor-dimension-control" - hideLabelFromVision={false} - label={ - <React.Fragment> - Padding - </React.Fragment> - } - onChange={[Function]} - options={ - Array [ - Object { - "label": "Default", - "value": "", - }, - Object { - "label": "None", - "value": "none", - }, - Object { - "label": "Small", - "value": "small", - }, - Object { - "label": "Medium", - "value": "medium", - }, - Object { - "label": "Large", - "value": "large", - }, - Object { - "label": "Extra Large", - "value": "xlarge", - }, - ] - } -/> -`; - -exports[`DimensionControl rendering renders with icon and custom icon label 1`] = ` -<WithInstanceId(SelectControl) - className="block-editor-dimension-control" - hideLabelFromVision={false} - label={ - <React.Fragment> - <Icon - icon="tablet" - /> - Margin - </React.Fragment> - } - onChange={[Function]} - options={ - Array [ - Object { - "label": "Default", - "value": "", - }, - Object { - "label": "None", - "value": "none", - }, - Object { - "label": "Small", - "value": "small", - }, - Object { - "label": "Medium", - "value": "medium", - }, - Object { - "label": "Large", - "value": "large", - }, - Object { - "label": "Extra Large", - "value": "xlarge", - }, - ] - } -/> -`; - -exports[`DimensionControl rendering renders with icon and default icon label 1`] = ` -<WithInstanceId(SelectControl) - className="block-editor-dimension-control" - hideLabelFromVision={false} - label={ - <React.Fragment> - <Icon - icon="tablet" - /> - Margin - </React.Fragment> - } - onChange={[Function]} - options={ - Array [ - Object { - "label": "Default", - "value": "", - }, - Object { - "label": "None", - "value": "none", - }, - Object { - "label": "Small", - "value": "small", - }, - Object { - "label": "Medium", - "value": "medium", - }, - Object { - "label": "Large", - "value": "large", - }, - Object { - "label": "Extra Large", - "value": "xlarge", - }, - ] - } -/> -`; diff --git a/packages/components/src/dimension-control/test/index.test.js b/packages/components/src/dimension-control/test/index.test.js deleted file mode 100644 index 0b053a493ee123..00000000000000 --- a/packages/components/src/dimension-control/test/index.test.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * External dependencies - */ -import { shallow, mount } from 'enzyme'; -import { uniqueId } from 'lodash'; - -/** - * Internal dependencies - */ -import { DimensionControl } from '../'; - -describe( 'DimensionControl', () => { - const onChangeHandler = jest.fn(); - - afterEach( () => { - onChangeHandler.mockClear(); - } ); - - describe( 'rendering', () => { - it( 'renders with defaults', () => { - const wrapper = shallow( - <DimensionControl - instanceId={ uniqueId() } - label={ 'Padding' } - /> - ); - expect( wrapper ).toMatchSnapshot(); - } ); - - it( 'renders with icon and default icon label', () => { - const wrapper = shallow( - <DimensionControl - instanceId={ uniqueId() } - label={ 'Margin' } - icon={ 'tablet' } - /> - ); - expect( wrapper ).toMatchSnapshot(); - } ); - - it( 'renders with icon and custom icon label', () => { - const wrapper = shallow( - <DimensionControl - instanceId={ uniqueId() } - label={ 'Margin' } - icon={ 'tablet' } - iconLabel={ 'Tablet Devices' } - /> - ); - expect( wrapper ).toMatchSnapshot(); - } ); - - it( 'renders with custom sizes', () => { - const customSizes = [ - { - name: 'Mini', - size: 1, - slug: 'mini', - }, - { - name: 'Middle', - size: 5, - slug: 'middle', - }, - { - name: 'Giant', - size: 10, - slug: 'giant', - }, - ]; - - const wrapper = shallow( - <DimensionControl - instanceId={ uniqueId() } - label={ 'Custom Dimension' } - sizes={ customSizes } - /> - ); - expect( wrapper ).toMatchSnapshot(); - } ); - } ); - - describe( 'callbacks', () => { - it( 'should call onChange handler with correct args on size change', () => { - const wrapper = mount( - <DimensionControl - instanceId={ uniqueId() } - label={ 'Padding' } - onChange={ onChangeHandler } - /> - ); - - wrapper.find( 'select' ).at( 0 ).simulate( 'change', { - target: { - value: 'small', - }, - } ); - - wrapper.find( 'select' ).at( 0 ).simulate( 'change', { - target: { - value: 'medium', - }, - } ); - - expect( onChangeHandler ).toHaveBeenCalledTimes( 2 ); - expect( onChangeHandler.mock.calls[ 0 ][ 0 ] ).toEqual( 'small' ); - expect( onChangeHandler.mock.calls[ 1 ][ 0 ] ).toEqual( 'medium' ); - } ); - - it( 'should call onChange handler with undefined value when no size is provided on change', () => { - const wrapper = mount( - <DimensionControl - instanceId={ uniqueId() } - label={ 'Padding' } - onChange={ onChangeHandler } - /> - ); - - wrapper.find( 'select' ).at( 0 ).simulate( 'change', { - target: { - value: '', // this happens when you select the "default" <option /> - }, - } ); - - expect( onChangeHandler ).toHaveBeenNthCalledWith( 1, undefined ); - } ); - } ); -} ); diff --git a/packages/components/src/draggable/stories/index.js b/packages/components/src/draggable/stories/index.js deleted file mode 100644 index fbe81321df7232..00000000000000 --- a/packages/components/src/draggable/stories/index.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import Draggable from '../'; -import Dashicon from '../../dashicon'; - -export default { title: 'Draggable', component: Draggable }; - -const Box = ( props ) => { - return ( - <div - { ...props } - style={ { - alignItems: 'center', - display: 'flex', - justifyContent: 'center', - width: 100, - height: 100, - background: '#ddd', - } } - /> - ); -}; - -const DraggalbeExample = () => { - const [ isDragging, setDragging ] = useState( false ); - - // Allow for the use of ID in the example - /* eslint-disable no-restricted-syntax */ - return ( - <div> - <p>Is Dragging? { isDragging ? 'Yes' : 'No' }</p> - <div id="draggable-example-box" style={ { display: 'inline-flex' } }> - <Draggable elementId="draggable-example-box"> - { ( { onDraggableStart, onDraggableEnd } ) => { - const handleOnDragStart = ( event ) => { - setDragging( true ); - onDraggableStart( event ); - }; - const handleOnDragEnd = ( event ) => { - setDragging( false ); - onDraggableEnd( event ); - }; - - return ( - <Box - onDragStart={ handleOnDragStart } - onDragEnd={ handleOnDragEnd } - draggable - > - <Dashicon icon="move" /> - </Box> - ); - } } - </Draggable> - </div> - </div> - ); - /* eslint-enable no-restricted-syntax */ -}; - -export const _default = () => { - return <DraggalbeExample />; -}; diff --git a/packages/components/src/external-link/index.js b/packages/components/src/external-link/index.js index cc9750a4b779c9..68bf56394b8f86 100644 --- a/packages/components/src/external-link/index.js +++ b/packages/components/src/external-link/index.js @@ -14,7 +14,6 @@ import { forwardRef } from '@wordpress/element'; * Internal dependencies */ import Dashicon from '../dashicon'; -import VisuallyHidden from '../visually-hidden'; export function ExternalLink( { href, children, className, rel = '', ...additionalProps }, ref ) { rel = uniq( compact( [ @@ -28,12 +27,12 @@ export function ExternalLink( { href, children, className, rel = '', ...addition // eslint-disable-next-line react/jsx-no-target-blank <a { ...additionalProps } className={ classes } href={ href } target="_blank" rel={ rel } ref={ ref }> { children } - <VisuallyHidden as="span"> + <span className="screen-reader-text"> { /* translators: accessibility text */ __( '(opens in a new tab)' ) } - </VisuallyHidden> + </span> <Dashicon icon="external" className="components-external-link__icon" /> </a> ); diff --git a/packages/components/src/external-link/stories/index.js b/packages/components/src/external-link/stories/index.js deleted file mode 100644 index 9abfa1af04ba9c..00000000000000 --- a/packages/components/src/external-link/stories/index.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * External dependencies - */ -import { text } from '@storybook/addon-knobs'; -/** - * Internal dependencies - */ -import ExternalLink from '../'; - -export default { title: 'ExternalLink', component: ExternalLink }; - -export const _default = () => { - const title = text( 'children', 'WordPress' ); - const href = text( 'href', 'https://wordpress.org' ); - - return <ExternalLink href={ href }>{ title }</ExternalLink>; -}; diff --git a/packages/components/src/font-size-picker/index.js b/packages/components/src/font-size-picker/index.js index 9fc6567865dbe4..a52f6ccd841d2f 100644 --- a/packages/components/src/font-size-picker/index.js +++ b/packages/components/src/font-size-picker/index.js @@ -60,7 +60,7 @@ function FontSizePicker( { }; return ( - <fieldset className="components-font-size-picker"> + <fieldset> <legend> { __( 'Font Size' ) } </legend> diff --git a/packages/components/src/font-size-picker/style.scss b/packages/components/src/font-size-picker/style.scss index d24d044952cdf6..2444087dcf30e3 100644 --- a/packages/components/src/font-size-picker/style.scss +++ b/packages/components/src/font-size-picker/style.scss @@ -38,9 +38,3 @@ } } -.components-font-size-picker { - border: 0; - padding: 0; - margin: 0; -} - diff --git a/packages/components/src/gradient-picker/index.js b/packages/components/src/gradient-picker/index.js index e8ab40f07ada2b..1a60de751646f3 100644 --- a/packages/components/src/gradient-picker/index.js +++ b/packages/components/src/gradient-picker/index.js @@ -19,7 +19,6 @@ export default function GradientPicker( { gradients, onChange, value, - clearable = true, } ) { const clearGradient = useCallback( () => onChange( undefined ), @@ -57,7 +56,7 @@ export default function GradientPicker( { <CircularOptionPicker className={ className } options={ gradientOptions } - actions={ clearable && ( + actions={ ( <CircularOptionPicker.ButtonAction onClick={ clearGradient }> { __( 'Clear' ) } </CircularOptionPicker.ButtonAction> diff --git a/packages/components/src/higher-order/with-focus-return/index.js b/packages/components/src/higher-order/with-focus-return/index.js index 6a411ad909af9f..2b504878bdf528 100644 --- a/packages/components/src/higher-order/with-focus-return/index.js +++ b/packages/components/src/higher-order/with-focus-return/index.js @@ -36,11 +36,11 @@ function isComponentLike( object ) { * when the component is unmounted. * * @param {(WPComponent|Object)} options The component to be enhanced with - * focus return behavior, or an object - * describing the component and the - * focus return characteristics. + * focus return behavior, or an object + * describing the component and the + * focus return characteristics. * - * @return {WPComponent} Component with the focus restauration behaviour. + * @return {Component} Component with the focus restauration behaviour. */ function withFocusReturn( options ) { // Normalize as overloaded form `withFocusReturn( options )( Component )` diff --git a/packages/components/src/higher-order/with-notices/index.js b/packages/components/src/higher-order/with-notices/index.js index 9097728b2921a8..49a44608039ce1 100644 --- a/packages/components/src/higher-order/with-notices/index.js +++ b/packages/components/src/higher-order/with-notices/index.js @@ -17,9 +17,8 @@ import NoticeList from '../../notice/list'; /** * Override the default edit UI to include notices if supported. * - * @param {WPComponent} OriginalComponent Original component. - * - * @return {WPComponent} Wrapped component. + * @param {Function|Component} OriginalComponent Original component. + * @return {Component} Wrapped component. */ export default createHigherOrderComponent( ( OriginalComponent ) => { return class WrappedBlockEdit extends Component { diff --git a/packages/components/src/higher-order/with-spoken-messages/index.js b/packages/components/src/higher-order/with-spoken-messages/index.js index 406d10bf0a245a..de17dc62aeb575 100644 --- a/packages/components/src/higher-order/with-spoken-messages/index.js +++ b/packages/components/src/higher-order/with-spoken-messages/index.js @@ -14,9 +14,9 @@ import { createHigherOrderComponent } from '@wordpress/compose'; * A Higher Order Component used to be provide a unique instance ID by * component. * - * @param {WPComponent} WrappedComponent The wrapped component. + * @param {WPElement} WrappedComponent The wrapped component. * - * @return {WPComponent} The component to be rendered. + * @return {Component} Component with an instanceId prop. */ export default createHigherOrderComponent( ( WrappedComponent ) => { return class extends Component { diff --git a/packages/components/src/icon-button/stories/index.js b/packages/components/src/icon-button/stories/index.js index b5c4275159dc5b..d093876a20e0a4 100644 --- a/packages/components/src/icon-button/stories/index.js +++ b/packages/components/src/icon-button/stories/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { text } from '@storybook/addon-knobs'; - /** * Internal dependencies */ @@ -10,17 +5,7 @@ import IconButton from '../'; export default { title: 'IconButton', component: IconButton }; -export const _default = () => { - const icon = text( 'Icon', 'ellipsis' ); - const label = text( 'Label', 'More' ); - - return ( - <IconButton - icon={ icon } - label={ label } - /> - ); -}; +export const _default = () => <IconButton icon="ellipsis" label="More" />; export const grouped = () => { const GroupContainer = ( { children } ) => ( diff --git a/packages/components/src/icon/stories/index.js b/packages/components/src/icon/stories/index.js index f2cd8bee1839b5..be4e9fed65787f 100644 --- a/packages/components/src/icon/stories/index.js +++ b/packages/components/src/icon/stories/index.js @@ -1,29 +1,19 @@ -/** - * External dependencies - */ -import { number, text } from '@storybook/addon-knobs'; - /** * Internal dependencies */ import Icon from '../'; -import { SVG, Path } from '../../primitives/svg'; +import { SVG, Path } from '../../'; export default { title: 'Icon', component: Icon }; const IconSizeLabel = ( { size } ) => <div style={ { fontSize: 12 } }>{ size }px</div>; -export const _default = () => { - const icon = text( 'Icon', 'screenoptions' ); - const size = number( 'Size', '24' ); - - return ( - <div> - <Icon icon={ icon } size={ size } /> - <IconSizeLabel size={ size } /> - </div> - ); -}; +export const _default = () => ( + <div> + <Icon icon="screenoptions" /> + <IconSizeLabel size={ 24 } /> + </div> +); export const sizes = () => { const iconSizes = [ 14, 16, 20, 24, 28, 32, 40, 48, 56 ]; diff --git a/packages/components/src/index.js b/packages/components/src/index.js index ac9694a49ba57b..8542a86ba9b659 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -12,7 +12,6 @@ export { default as ColorPalette } from './color-palette'; export { default as ColorPicker } from './color-picker'; export { default as Dashicon } from './dashicon'; export { DateTimePicker, DatePicker, TimePicker } from './date-time'; -export { default as __experimentalDimensionControl } from './dimension-control'; export { default as Disabled } from './disabled'; export { default as Draggable } from './draggable'; export { default as DropZone } from './drop-zone'; @@ -63,7 +62,6 @@ export { default as Toolbar } from './toolbar'; export { default as ToolbarButton } from './toolbar-button'; export { default as Tooltip } from './tooltip'; export { default as TreeSelect } from './tree-select'; -export { default as VisuallyHidden } from './visually-hidden'; export { default as IsolatedEventContainer } from './isolated-event-container'; export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot-fill'; diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index e9aec0ad2fb71c..c2c52ba08f0e58 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -1,7 +1,5 @@ // Components export * from './primitives'; -export { default as ColorIndicator } from './color-indicator'; -export { default as ColorPalette } from './color-palette'; export { default as Dashicon } from './dashicon'; export { default as Dropdown } from './dropdown'; export { default as Toolbar } from './toolbar'; @@ -13,7 +11,6 @@ export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot export { default as BaseControl } from './base-control'; export { default as TextareaControl } from './textarea-control'; export { default as PanelBody } from './panel/body'; -export { default as PanelActions } from './panel/actions'; export { default as Button } from './button'; export { default as TextControl } from './text-control'; export { default as ToggleControl } from './toggle-control'; diff --git a/packages/components/src/keyboard-shortcuts/index.native.js b/packages/components/src/keyboard-shortcuts/index.native.js deleted file mode 100644 index fab7b99261e3ae..00000000000000 --- a/packages/components/src/keyboard-shortcuts/index.native.js +++ /dev/null @@ -1,2 +0,0 @@ -const KeyboardShortcuts = () => null; -export default KeyboardShortcuts; diff --git a/packages/components/src/menu-item/index.js b/packages/components/src/menu-item/index.js index 3227659e6d10a8..b7cc7c8ca7a0bd 100644 --- a/packages/components/src/menu-item/index.js +++ b/packages/components/src/menu-item/index.js @@ -18,7 +18,7 @@ import IconButton from '../icon-button'; /** * Renders a generic menu item for use inside the more menu. * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} More menu item. */ export function MenuItem( { children, diff --git a/packages/components/src/mobile/bottom-sheet/cell.native.js b/packages/components/src/mobile/bottom-sheet/cell.native.js index 52ff00b6b5b856..af74a25e2cee82 100644 --- a/packages/components/src/mobile/bottom-sheet/cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/cell.native.js @@ -42,7 +42,6 @@ class BottomSheetCell extends Component { value, valuePlaceholder = '', icon, - leftAlign, labelStyle = {}, valueStyle = {}, onChangeValue, @@ -58,12 +57,8 @@ class BottomSheetCell extends Component { const isValueEditable = editable && onChangeValue !== undefined; const cellLabelStyle = getStylesFromColorScheme( styles.cellLabel, styles.cellTextDark ); const cellLabelCenteredStyle = getStylesFromColorScheme( styles.cellLabelCentered, styles.cellTextDark ); - const cellLabelLeftAlignNoIconStyle = getStylesFromColorScheme( styles.cellLabelLeftAlignNoIcon, styles.cellTextDark ); - const defaultMissingIconAndValue = leftAlign ? cellLabelLeftAlignNoIconStyle : cellLabelCenteredStyle; - const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : defaultMissingIconAndValue; - + const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : cellLabelCenteredStyle; const drawSeparator = ( separatorType && separatorType !== 'none' ) || separatorStyle === undefined; - const drawTopSeparator = drawSeparator && separatorType === 'topFullWidth'; const onCellPress = () => { if ( isValueEditable ) { @@ -92,7 +87,6 @@ class BottomSheetCell extends Component { case 'leftMargin': return leftMarginStyle; case 'fullWidth': - case 'topFullWidth': return defaultSeparatorStyle; case 'none': return undefined; @@ -171,9 +165,6 @@ class BottomSheetCell extends Component { onPress={ onCellPress } style={ { ...styles.clipToBounds, ...style } } > - { drawTopSeparator && ( - <View style={ separatorStyle() } /> - ) } <View style={ styles.cellContainer }> <View style={ styles.cellRowContainer }> { icon && ( @@ -182,14 +173,14 @@ class BottomSheetCell extends Component { <View style={ platformStyles.labelIconSeparator } /> </View> ) } - <Text numberOfLines={ 1 } style={ [ defaultLabelStyle, labelStyle ] }> + <Text numberOfLines={ 1 } style={ { ...defaultLabelStyle, ...labelStyle } }> { label } </Text> </View> { showValue && getValueComponent() } { children } </View> - { ! drawTopSeparator && ( + { drawSeparator && ( <View style={ separatorStyle() } /> ) } </TouchableOpacity> diff --git a/packages/components/src/mobile/bottom-sheet/index.native.js b/packages/components/src/mobile/bottom-sheet/index.native.js index 34d05a83974957..f17284b49e7306 100644 --- a/packages/components/src/mobile/bottom-sheet/index.native.js +++ b/packages/components/src/mobile/bottom-sheet/index.native.js @@ -19,7 +19,6 @@ import Button from './button'; import Cell from './cell'; import PickerCell from './picker-cell'; import SwitchCell from './switch-cell'; -import RangeCell from './range-cell'; import KeyboardAvoidingView from './keyboard-avoiding-view'; class BottomSheet extends Component { @@ -137,8 +136,6 @@ class BottomSheet extends Component { onBackdropPress={ this.props.onClose } onBackButtonPress={ this.props.onClose } onSwipe={ this.props.onClose } - onDismiss={ Platform.OS === 'ios' ? this.props.onDismiss : undefined } - onModalHide={ Platform.OS === 'android' ? this.props.onDismiss : undefined } swipeDirection="down" onMoveShouldSetResponder={ panResponder.panHandlers.onMoveShouldSetResponder } onMoveShouldSetResponderCapture={ panResponder.panHandlers.onMoveShouldSetResponderCapture } @@ -174,6 +171,5 @@ ThemedBottomSheet.Button = Button; ThemedBottomSheet.Cell = Cell; ThemedBottomSheet.PickerCell = PickerCell; ThemedBottomSheet.SwitchCell = SwitchCell; -ThemedBottomSheet.RangeCell = RangeCell; export default ThemedBottomSheet; diff --git a/packages/components/src/mobile/bottom-sheet/picker-cell.native.js b/packages/components/src/mobile/bottom-sheet/picker-cell.native.js index 12eae94c7d8919..50a775f25728b1 100644 --- a/packages/components/src/mobile/bottom-sheet/picker-cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/picker-cell.native.js @@ -7,7 +7,6 @@ import Picker from '../picker'; export default function BottomSheetPickerCell( props ) { const { options, - hideCancelButton, onChangeValue, ...cellProps } = props; @@ -25,8 +24,6 @@ export default function BottomSheetPickerCell( props ) { return ( <Cell onPress={ onCellPress } editable={ false } { ...cellProps } > <Picker - leftAlign - hideCancelButton={ hideCancelButton } ref={ ( instance ) => picker = instance } options={ options } onChange={ onChange } diff --git a/packages/components/src/mobile/bottom-sheet/range-cell.native.js b/packages/components/src/mobile/bottom-sheet/range-cell.native.js deleted file mode 100644 index 07b343e9ec0781..00000000000000 --- a/packages/components/src/mobile/bottom-sheet/range-cell.native.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * External dependencies - */ -import { Platform } from 'react-native'; - -/** - * Internal dependencies - */ -import Cell from './cell'; -import Slider from '../slider'; - -export default function BottomSheetRangeCell( props ) { - const { - value, - defaultValue, - onChangeValue, - minimumValue = 0, - maximumValue = 10, - disabled, - step = 1, - minimumTrackTintColor = '#00669b', - maximumTrackTintColor = Platform.OS === 'ios' ? '#e9eff3' : '#909090', - thumbTintColor = Platform.OS === 'ios' ? '#fff' : '#00669b', - ...cellProps - } = props; - - return ( - <Cell - editable={ false } - { ...cellProps } - > - <Slider - value={ value } - defaultValue={ defaultValue } - disabled={ disabled } - step={ step } - minimumValue={ minimumValue } - maximumValue={ maximumValue } - minimumTrackTintColor={ minimumTrackTintColor } - maximumTrackTintColor={ maximumTrackTintColor } - thumbTintColor={ thumbTintColor } - onChangeValue={ onChangeValue } - /> - </Cell> - ); -} diff --git a/packages/components/src/mobile/bottom-sheet/styles.native.scss b/packages/components/src/mobile/bottom-sheet/styles.native.scss index 86422f3228cac4..8f153715c16705 100644 --- a/packages/components/src/mobile/bottom-sheet/styles.native.scss +++ b/packages/components/src/mobile/bottom-sheet/styles.native.scss @@ -120,13 +120,6 @@ text-align: center; } -.cellLabelLeftAlignNoIcon { - font-size: 17px; - color: #2e4453; - flex: 1; - margin-left: 12px; -} - .cellValue { font-size: 17px; color: #2e4453; diff --git a/packages/components/src/mobile/picker/index.android.js b/packages/components/src/mobile/picker/index.android.js index 372378e0a2b3ed..3fad1cc2b23bf0 100644 --- a/packages/components/src/mobile/picker/index.android.js +++ b/packages/components/src/mobile/picker/index.android.js @@ -52,7 +52,6 @@ export default class Picker extends Component { <BottomSheet.Cell icon={ option.icon } key={ index } - leftAlign={ this.props.leftAlign } label={ option.label } separatorType={ 'none' } onPress={ () => this.onCellPress( option.value ) } diff --git a/packages/components/src/mobile/picker/index.ios.js b/packages/components/src/mobile/picker/index.ios.js index 9de17d1ff7060a..2cf9798b28e9c0 100644 --- a/packages/components/src/mobile/picker/index.ios.js +++ b/packages/components/src/mobile/picker/index.ios.js @@ -11,13 +11,12 @@ import { Component } from '@wordpress/element'; class Picker extends Component { presentPicker() { - const { options, onChange, title } = this.props; + const { options, onChange } = this.props; const labels = options.map( ( { label } ) => label ); const fullOptions = [ __( 'Cancel' ) ].concat( labels ); ActionSheetIOS.showActionSheetWithOptions( { - title, options: fullOptions, cancelButtonIndex: 0, }, diff --git a/packages/components/src/mobile/slider/index.native.js b/packages/components/src/mobile/slider/index.native.js deleted file mode 100644 index 111d9987e973db..00000000000000 --- a/packages/components/src/mobile/slider/index.native.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * External dependencies - */ -import { Slider as RNSlider, TextInput, View } from 'react-native'; - -/** - * WordPress dependencies - */ -import { Component } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import styles from './styles.scss'; - -class Slider extends Component { - constructor( props ) { - super( props ); - this.handleToggleFocus = this.handleToggleFocus.bind( this ); - this.handleChange = this.handleChange.bind( this ); - this.handleValueSave = this.handleValueSave.bind( this ); - this.handleReset = this.handleReset.bind( this ); - - const initialValue = this.validateInput( props.value || props.defaultValue || props.minimumValue ); - - this.state = { hasFocus: false, initialValue, sliderValue: initialValue }; - } - - componentDidUpdate( ) { - const reset = this.props.value === null; - if ( reset ) { - this.handleReset(); - } - } - - handleToggleFocus( validateInput = true ) { - const newState = { hasFocus: ! this.state.hasFocus }; - - if ( validateInput ) { - const sliderValue = this.validateInput( this.state.sliderValue ); - this.handleValueSave( sliderValue ); - } - - this.setState( newState ); - } - - validateInput( text ) { - const { minimumValue, maximumValue } = this.props; - if ( ! text ) { - return minimumValue; - } - if ( typeof text === 'number' ) { - return Math.min( Math.max( text, minimumValue ), maximumValue ); - } - return Math.min( Math.max( text.replace( /[^0-9]/g, '' ).replace( /^0+(?=\d)/, '' ), minimumValue ), maximumValue ); - } - - handleChange( text ) { - if ( ! isNaN( Number( text ) ) ) { - this.setState( { sliderValue: text } ); - } - } - - handleValueSave( text ) { - if ( ! isNaN( Number( text ) ) ) { - if ( this.props.onChangeValue ) { - this.props.onChangeValue( text ); - } - this.setState( { sliderValue: text } ); - } - } - - handleReset() { - this.handleValueSave( this.props.defaultValue || this.state.initialValue ); - } - - render() { - const { - minimumValue, - maximumValue, - disabled, - step, - minimumTrackTintColor, - maximumTrackTintColor, - thumbTintColor, - } = this.props; - - const { hasFocus, sliderValue } = this.state; - - return ( - <View style={ styles.sliderContainer }> - <RNSlider - value={ this.validateInput( sliderValue ) } - disabled={ disabled } - style={ styles.slider } - step={ step } - minimumValue={ minimumValue } - maximumValue={ maximumValue } - minimumTrackTintColor={ minimumTrackTintColor } - maximumTrackTintColor={ maximumTrackTintColor } - thumbTintColor={ thumbTintColor } - onValueChange={ this.handleChange } - onSlidingComplete={ this.handleValueSave } - /> - <TextInput - style={ [ styles.sliderTextInput, hasFocus ? styles.isSelected : {} ] } - onChangeText={ this.handleChange } - onFocus={ this.handleToggleFocus } - onBlur={ this.handleToggleFocus } - keyboardType="numeric" - value={ `${ sliderValue }` } - /> - </View> - ); - } -} - -export default Slider; diff --git a/packages/components/src/mobile/slider/styles.scss b/packages/components/src/mobile/slider/styles.scss deleted file mode 100644 index 326880b621807a..00000000000000 --- a/packages/components/src/mobile/slider/styles.scss +++ /dev/null @@ -1,27 +0,0 @@ -.sliderContainer { - flex: 1; - flex-direction: row; - align-content: center; - justify-content: space-evenly; -} - -.slider { - flex-grow: 1; -} - -.sliderTextInput { - width: 40px; - height: 25px; - align-self: center; - margin-left: 10px; - border-width: 1px; - border-radius: 4px; - border-color: $dark-gray-150; - padding-top: 0; - padding-bottom: 0; -} - -.isSelected { - border-width: 2px; - border-color: $blue-wordpress; -} diff --git a/packages/components/src/modal/index.js b/packages/components/src/modal/index.js index f4a64c289b4e7d..66d3421ee6ff5c 100644 --- a/packages/components/src/modal/index.js +++ b/packages/components/src/modal/index.js @@ -3,7 +3,7 @@ */ import { Component, createPortal } from '@wordpress/element'; import { withInstanceId } from '@wordpress/compose'; -import deprecated from '@wordpress/deprecated'; +import { deprecated } from '@wordpress/deprecated'; /** * Internal dependencies diff --git a/packages/components/src/panel/actions.native.js b/packages/components/src/panel/actions.native.js deleted file mode 100644 index 02031bf53cb857..00000000000000 --- a/packages/components/src/panel/actions.native.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * External dependencies - */ -import { View } from 'react-native'; - -/** - * WordPress dependencies - */ -import { - TextControl, -} from '@wordpress/components'; - -/** - * Internal dependencies - */ -import styles from './actions.scss'; - -function PanelActions( { actions } ) { - return ( - <View style={ styles.panelActionsContainer }> - { actions.map( ( { label, onPress } ) => { - return ( - <TextControl - label={ label } - separatorType="topFullWidth" - onPress={ onPress } - labelStyle={ styles.defaultLabelStyle } - key={ label } - /> - ); - } ) } - </View> - ); -} - -export default PanelActions; diff --git a/packages/components/src/panel/actions.native.scss b/packages/components/src/panel/actions.native.scss deleted file mode 100644 index ed226c13883be9..00000000000000 --- a/packages/components/src/panel/actions.native.scss +++ /dev/null @@ -1,7 +0,0 @@ -.panelActionsContainer { - padding-top: 24; -} - -.defaultLabelStyle { - color: $alert-red; -} diff --git a/packages/components/src/panel/body.native.js b/packages/components/src/panel/body.native.js index 314650f945278e..aeeccc77a06c19 100644 --- a/packages/components/src/panel/body.native.js +++ b/packages/components/src/panel/body.native.js @@ -1,16 +1,12 @@ /** * External dependencies */ -import { Text, View } from 'react-native'; +import { View } from 'react-native'; /** * WordPress dependencies */ import { Component } from '@wordpress/element'; -/** - * Internal dependencies - */ -import styles from './body.scss'; export class PanelBody extends Component { constructor( ) { @@ -19,11 +15,9 @@ export class PanelBody extends Component { } render() { - const { children, title } = this.props; - + const { children } = this.props; return ( - <View style={ styles.panelContainer }> - { title && <Text style={ styles.sectionHeaderText }>{ title }</Text> } + <View > { children } </View> ); diff --git a/packages/components/src/panel/body.native.scss b/packages/components/src/panel/body.native.scss deleted file mode 100644 index a30c4df4c15dfc..00000000000000 --- a/packages/components/src/panel/body.native.scss +++ /dev/null @@ -1,11 +0,0 @@ -.panelContainer { - padding: 0 16px; -} - -.sectionHeaderText { - color: #87a6bc; - padding-top: 24; - padding-bottom: 8; - font-size: 14; - font-weight: 500; -} diff --git a/packages/components/src/placeholder/README.md b/packages/components/src/placeholder/README.md index 9e5bf053417d0d..2a12363e7fde01 100644 --- a/packages/components/src/placeholder/README.md +++ b/packages/components/src/placeholder/README.md @@ -16,7 +16,7 @@ const MyPlaceholder = () => ( Name | Type | Default | Description --- | --- | --- | --- -`icon` | `string, WPElement` | `undefined` | If provided, renders an icon next to the label. +`icon` | `string, ReactElement` | `undefined` | If provided, renders an icon next to the label. `label` | `string` | `undefined` | Renders a label for the placeholder. `instructions` | `string` | `undefined` | Renders instruction text below label. `isColumnLayout` | `bool` | `false` | Changes placeholder children layout from flex-row to flex-column. diff --git a/packages/components/src/scroll-lock/index.js b/packages/components/src/scroll-lock/index.js index 1d6255d8c12ef9..0d600aac62f14d 100644 --- a/packages/components/src/scroll-lock/index.js +++ b/packages/components/src/scroll-lock/index.js @@ -12,7 +12,7 @@ import { Component } from '@wordpress/element'; * @param {Object} args Keyword args. * @param {HTMLDocument} args.htmlDocument The document to lock the scroll for. * @param {string} args.className The name of the class used to lock scrolling. - * @return {WPComponent} The bound ScrollLock component. + * @return {Component} The bound ScrollLock component. */ export function createScrollLockComponent( { htmlDocument = document, diff --git a/packages/components/src/scroll-lock/stories/index.js b/packages/components/src/scroll-lock/stories/index.js index 20ef27337fc787..865fb6a7e909b9 100644 --- a/packages/components/src/scroll-lock/stories/index.js +++ b/packages/components/src/scroll-lock/stories/index.js @@ -6,7 +6,7 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import Button from '../../button'; +import { Button } from '../../'; import ScrollLock from '../'; export default { title: 'ScrollLock', component: ScrollLock }; diff --git a/packages/components/src/spinner/stories/index.js b/packages/components/src/spinner/stories/index.js deleted file mode 100644 index 188f13e45273f4..00000000000000 --- a/packages/components/src/spinner/stories/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Internal dependencies - */ -import Spinner from '../'; - -export default { title: 'Spinner', component: Spinner }; - -export const _default = () => { - return ( - <Spinner /> - ); -}; diff --git a/packages/components/src/style.scss b/packages/components/src/style.scss index 7a62ba0534539d..6365bff68cf568 100644 --- a/packages/components/src/style.scss +++ b/packages/components/src/style.scss @@ -9,7 +9,6 @@ @import "./color-picker/style.scss"; @import "./dashicon/style.scss"; @import "./date-time/style.scss"; -@import "./dimension-control/style.scss"; @import "./disabled/style.scss"; @import "./draggable/style.scss"; @import "./drop-zone/style.scss"; @@ -45,4 +44,3 @@ @import "./toolbar/style.scss"; @import "./toolbar-button/style.scss"; @import "./tooltip/style.scss"; -@import "./visually-hidden/style.scss"; diff --git a/packages/components/src/toolbar/index.js b/packages/components/src/toolbar/index.js index bf9237eed1b624..ca41d32bb6e1b9 100644 --- a/packages/components/src/toolbar/index.js +++ b/packages/components/src/toolbar/index.js @@ -34,13 +34,13 @@ import ToolbarContainer from './toolbar-container'; * Either `controls` or `children` is required, otherwise this components * renders nothing. * - * @param {Object} props - * @param {Array} [props.controls] The controls to render in this toolbar. - * @param {WPElement} [props.children] Any other things to render inside the - * toolbar besides the controls. - * @param {string} [props.className] Class to set on the container div. + * @param {Object} props + * @param {Array} [props.controls] The controls to render in this toolbar. + * @param {ReactElement} [props.children] Any other things to render inside the + * toolbar besides the controls. + * @param {string} [props.className] Class to set on the container div. * - * @return {WPComponent} The rendered component. + * @return {ReactElement} The rendered toolbar. */ function Toolbar( { controls = [], children, className, isCollapsed, icon, label, ...otherProps } ) { if ( diff --git a/packages/components/src/visually-hidden/README.md b/packages/components/src/visually-hidden/README.md deleted file mode 100644 index 1f490f5134af26..00000000000000 --- a/packages/components/src/visually-hidden/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# VisuallyHidden - -A component used to render text intended to be visually hidden, but will show for alternate devices, for example a screen reader. - -### Usage - -```jsx -<VisuallyHidden> Show text for screenreader. </VisuallyHidden> -``` diff --git a/packages/components/src/visually-hidden/index.js b/packages/components/src/visually-hidden/index.js deleted file mode 100644 index b29c954c2cd9e1..00000000000000 --- a/packages/components/src/visually-hidden/index.js +++ /dev/null @@ -1,22 +0,0 @@ - -/** - * Internal dependencies - */ -import { renderAsRenderProps } from './utils'; - -/** - * VisuallyHidden component to render text out non-visually - * for use in devices such as a screen reader. - */ -function VisuallyHidden( { - as = 'div', - ...props -} ) { - return renderAsRenderProps( { - as, - className: 'components-visually-hidden', - ...props, - } ); -} -export default VisuallyHidden; - diff --git a/packages/components/src/visually-hidden/stories/index.js b/packages/components/src/visually-hidden/stories/index.js deleted file mode 100644 index 03b60ccc334126..00000000000000 --- a/packages/components/src/visually-hidden/stories/index.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Internal dependencies - */ -import VisuallyHidden from '../'; - -export default { title: 'VisuallyHidden', component: VisuallyHidden }; - -export const _default = () => ( - <> - <VisuallyHidden> - This should not show. - </VisuallyHidden> - <div> - This text will <VisuallyHidden as="span">but not inline </VisuallyHidden> always show. - </div> - </> -); diff --git a/packages/components/src/visually-hidden/style.scss b/packages/components/src/visually-hidden/style.scss deleted file mode 100644 index 02fec4486afa23..00000000000000 --- a/packages/components/src/visually-hidden/style.scss +++ /dev/null @@ -1,30 +0,0 @@ -.components-visually-hidden { - border: 0; - clip: rect(1px, 1px, 1px, 1px); - -webkit-clip-path: inset(50%); - clip-path: inset(50%); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; - word-wrap: normal !important; -} - -.components-visually-hidden:focus { - background-color: $light-gray-500; - clip: auto !important; - clip-path: none; - color: #444; - display: block; - font-size: 1em; - height: auto; - left: 5px; - line-height: normal; - padding: 15px 23px 14px; - text-decoration: none; - top: 5px; - width: auto; - z-index: 100000; -} diff --git a/packages/components/src/visually-hidden/utils.js b/packages/components/src/visually-hidden/utils.js deleted file mode 100644 index 07957708090ef0..00000000000000 --- a/packages/components/src/visually-hidden/utils.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Utility Functions - */ - -/** - * renderAsRenderProps is used to wrap a component and convert - * the passed property "as" either a string or component, to the - * rendered tag if a string, or component. - * - * See VisuallyHidden hidden for example. - * - * @param {string|Component} as A tag or component to render. - * @return {Component} The rendered component. - */ -function renderAsRenderProps( { as: Component = 'div', ...props } ) { - if ( typeof props.children === 'function' ) { - return props.children( props ); - } - return <Component { ...props } />; -} - -export { renderAsRenderProps }; diff --git a/packages/components/storybook/addons.js b/packages/components/storybook/addons.js index ccfec56c606dcc..d3fa048c75edf4 100644 --- a/packages/components/storybook/addons.js +++ b/packages/components/storybook/addons.js @@ -2,6 +2,5 @@ * External dependencies */ import '@storybook/addon-a11y/register'; -import '@storybook/addon-knobs/register'; import '@storybook/addon-storysource/register'; import '@storybook/addon-viewport/register'; diff --git a/packages/components/storybook/config.js b/packages/components/storybook/config.js index b2bfd74c3da6eb..eace300f3fc963 100644 --- a/packages/components/storybook/config.js +++ b/packages/components/storybook/config.js @@ -3,7 +3,6 @@ */ import { addDecorator, configure } from '@storybook/react'; import { withA11y } from '@storybook/addon-a11y'; -import { withKnobs } from '@storybook/addon-knobs'; /** * Internal dependencies @@ -11,7 +10,6 @@ import { withKnobs } from '@storybook/addon-knobs'; import '../build-style/style.css'; addDecorator( withA11y ); -addDecorator( withKnobs ); configure( [ require.context( '../docs', true, /\/.+\.mdx$/ ), diff --git a/packages/compose/README.md b/packages/compose/README.md index 7fcf12e07a7293..dc47f26e995652 100644 --- a/packages/compose/README.md +++ b/packages/compose/README.md @@ -163,11 +163,11 @@ component. _Parameters_ -- _WrappedComponent_ `WPComponent`: The wrapped component. +- _WrappedComponent_ `WPElement`: The wrapped component. _Returns_ -- `WPComponent`: Component with an instanceId prop. +- `Component`: Component with an instanceId prop. <a name="withSafeTimeout" href="#withSafeTimeout">#</a> **withSafeTimeout** @@ -176,11 +176,11 @@ that ought to be bound to a component's lifecycle. _Parameters_ -- _OriginalComponent_ `WPComponent`: Component requiring setTimeout +- _OriginalComponent_ `Component`: Component requiring setTimeout _Returns_ -- `WPComponent`: Wrapped component. +- `Component`: Wrapped component. <a name="withState" href="#withState">#</a> **withState** @@ -193,7 +193,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Wrapped component. +- `Component`: Wrapped component. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/compose/package.json b/packages/compose/package.json index 5ad5ed9d1bc786..827a0afb46eff7 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/compose", - "version": "3.7.2", + "version": "3.7.0", "description": "WordPress higher-order components (HOCs).", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -21,7 +21,6 @@ "main": "build/index.js", "module": "build-module/index.js", "react-native": "src/index", - "sideEffects": false, "dependencies": { "@babel/runtime": "^7.4.4", "@wordpress/element": "file:../element", diff --git a/packages/compose/src/higher-order/compose.js b/packages/compose/src/higher-order/compose.js deleted file mode 100644 index a166387821e7b3..00000000000000 --- a/packages/compose/src/higher-order/compose.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * External dependencies - */ -import { flowRight as compose } from 'lodash'; - -/** - * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function - * composition, where each successive invocation is supplied the return value of the previous. - * - * @param {...Function} hocs The HOC functions to invoke. - * - * @return {Function} Returns the new composite function. - */ -export default compose; diff --git a/packages/compose/src/higher-order/with-instance-id/index.js b/packages/compose/src/higher-order/with-instance-id/index.js index 960c6997e8671f..53c09ec56f8882 100644 --- a/packages/compose/src/higher-order/with-instance-id/index.js +++ b/packages/compose/src/higher-order/with-instance-id/index.js @@ -12,9 +12,9 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * A Higher Order Component used to be provide a unique instance ID by * component. * - * @param {WPComponent} WrappedComponent The wrapped component. + * @param {WPElement} WrappedComponent The wrapped component. * - * @return {WPComponent} Component with an instanceId prop. + * @return {Component} Component with an instanceId prop. */ export default createHigherOrderComponent( ( WrappedComponent ) => { let instances = 0; diff --git a/packages/compose/src/higher-order/with-safe-timeout/index.js b/packages/compose/src/higher-order/with-safe-timeout/index.js index 43d4e9e780d5b7..910dd94fddc19d 100644 --- a/packages/compose/src/higher-order/with-safe-timeout/index.js +++ b/packages/compose/src/higher-order/with-safe-timeout/index.js @@ -17,9 +17,9 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * A higher-order component used to provide and manage delayed function calls * that ought to be bound to a component's lifecycle. * - * @param {WPComponent} OriginalComponent Component requiring setTimeout + * @param {Component} OriginalComponent Component requiring setTimeout * - * @return {WPComponent} Wrapped component. + * @return {Component} Wrapped component. */ const withSafeTimeout = createHigherOrderComponent( ( OriginalComponent ) => { diff --git a/packages/compose/src/higher-order/with-state/index.js b/packages/compose/src/higher-order/with-state/index.js index 02db9392b39631..19e639043bd28b 100644 --- a/packages/compose/src/higher-order/with-state/index.js +++ b/packages/compose/src/higher-order/with-state/index.js @@ -14,7 +14,7 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * * @param {?Object} initialState Optional initial state of the component. * - * @return {WPComponent} Wrapped component. + * @return {Component} Wrapped component. */ export default function withState( initialState = {} ) { return createHigherOrderComponent( ( OriginalComponent ) => { diff --git a/packages/compose/src/index.js b/packages/compose/src/index.js index ab1ecf3564edbe..9ea31b2d351aba 100644 --- a/packages/compose/src/index.js +++ b/packages/compose/src/index.js @@ -1,8 +1,20 @@ +/** + * External dependencies + */ +import { flowRight } from 'lodash'; + // Utils export { default as createHigherOrderComponent } from './utils/create-higher-order-component'; -// Compose helper (aliased flowRight from Lodash) -export { default as compose } from './higher-order/compose'; +/** + * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function + * composition, where each successive invocation is supplied the return value of the previous. + * + * @param {...Function} hocs The HOC functions to invoke. + * + * @return {Function} Returns the new composite function. + */ +export { flowRight as compose }; // Higher-order components export { default as ifCondition } from './higher-order/if-condition'; diff --git a/packages/core-data/README.md b/packages/core-data/README.md index a2bb3ccbe6deeb..892a6e572a99be 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -106,7 +106,7 @@ a given URl has been received. _Parameters_ - _url_ `string`: URL to preview the embed for. -- _preview_ `*`: Preview data. +- _preview_ `Mixed`: Preview data. _Returns_ diff --git a/packages/core-data/package.json b/packages/core-data/package.json index 3c565d2bfc56c6..32fca25d8a2771 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "2.7.3", + "version": "2.7.0", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/core-data/src/actions.js b/packages/core-data/src/actions.js index a79aaba7e33d8f..dc77d54994ac0b 100644 --- a/packages/core-data/src/actions.js +++ b/packages/core-data/src/actions.js @@ -109,8 +109,8 @@ export function receiveThemeSupports( themeSupports ) { * Returns an action object used in signalling that the preview data for * a given URl has been received. * - * @param {string} url URL to preview the embed for. - * @param {*} preview Preview data. + * @param {string} url URL to preview the embed for. + * @param {Mixed} preview Preview data. * * @return {Object} Action object. */ diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js index b75d0e44632373..4ee2f6b715374f 100644 --- a/packages/core-data/src/entities.js +++ b/packages/core-data/src/entities.js @@ -12,7 +12,6 @@ import { apiFetch, select } from './controls'; export const DEFAULT_ENTITY_KEY = 'id'; export const defaultEntities = [ - { name: 'site', kind: 'root', baseURL: '/wp/v2/settings' }, { name: 'postType', kind: 'root', key: 'slug', baseURL: '/wp/v2/types' }, { name: 'media', kind: 'root', baseURL: '/wp/v2/media', plural: 'mediaItems' }, { name: 'taxonomy', kind: 'root', key: 'slug', baseURL: '/wp/v2/taxonomies', plural: 'taxonomies' }, diff --git a/packages/core-data/src/entity-provider.js b/packages/core-data/src/entity-provider.js index 50439f1b57ad65..7870e0217cc974 100644 --- a/packages/core-data/src/entity-provider.js +++ b/packages/core-data/src/entity-provider.js @@ -52,17 +52,6 @@ export default function EntityProvider( { kind, type, id, children } ) { return <Provider value={ id }>{ children }</Provider>; } -/** - * Hook that returns the ID for the nearest - * provided entity of the specified type. - * - * @param {string} kind The entity kind. - * @param {string} type The entity type. - */ -export function useEntityId( kind, type ) { - return useContext( getEntity( kind, type ).context ); -} - /** * Hook that returns the value and a setter for the * specified property of the nearest provided @@ -77,13 +66,11 @@ export function useEntityId( kind, type ) { * setter. */ export function useEntityProp( kind, type, prop ) { - const id = useEntityId( kind, type ); + const id = useContext( getEntity( kind, type ).context ); const value = useSelect( ( select ) => { - const { getEntityRecord, getEditedEntityRecord } = select( 'core' ); - getEntityRecord( kind, type, id ); // Trigger resolver. - const entity = getEditedEntityRecord( kind, type, id ); + const entity = select( 'core' ).getEditedEntityRecord( kind, type, id ); return entity && entity[ prop ]; }, [ kind, type, id, prop ] @@ -101,62 +88,3 @@ export function useEntityProp( kind, type, prop ) { return [ value, setValue ]; } - -/** - * Hook that returns whether the nearest provided - * entity of the specified type is dirty, saving, - * and a function to save it. - * - * The last, optional parameter is for scoping the - * selection to a single property or a list properties. - * - * By default, dirtyness detection and saving considers - * and handles all properties of an entity, but this - * last parameter lets you scope it to a single property - * or a list of properties for each instance of this hook. - * - * @param {string} kind The entity kind. - * @param {string} type The entity type. - * @param {string|[string]} [props] The property name or list of property names. - */ -export function __experimentalUseEntitySaving( kind, type, props ) { - const id = useEntityId( kind, type ); - - const [ isDirty, isSaving, edits ] = useSelect( - ( select ) => { - const { getEntityRecordNonTransientEdits, isSavingEntityRecord } = select( - 'core' - ); - const _edits = getEntityRecordNonTransientEdits( kind, type, id ); - const editKeys = Object.keys( _edits ); - return [ - props ? - editKeys.some( ( key ) => - typeof props === 'string' ? key === props : props.includes( key ) - ) : - editKeys.length > 0, - isSavingEntityRecord( kind, type, id ), - _edits, - ]; - }, - [ kind, type, id, props ] - ); - - const { saveEntityRecord } = useDispatch( 'core' ); - const save = useCallback( () => { - let filteredEdits = edits; - if ( typeof props === 'string' ) { - filteredEdits = { [ props ]: filteredEdits[ props ] }; - } else if ( props ) { - filteredEdits = filteredEdits.reduce( ( acc, key ) => { - if ( props.includes( key ) ) { - acc[ key ] = filteredEdits[ key ]; - } - return acc; - }, {} ); - } - saveEntityRecord( kind, type, { id, ...filteredEdits } ); - }, [ kind, type, id, props, edits ] ); - - return [ isDirty, isSaving, save ]; -} diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index bf12ac2e5096fb..2cdddb960e448b 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -49,9 +49,4 @@ registerStore( REDUCER_KEY, { resolvers: { ...resolvers, ...entityResolvers }, } ); -export { - default as EntityProvider, - useEntityId, - useEntityProp, - __experimentalUseEntitySaving, -} from './entity-provider'; +export { default as EntityProvider, useEntityProp } from './entity-provider'; diff --git a/packages/core-data/src/queried-data/reducer.js b/packages/core-data/src/queried-data/reducer.js index 36da4465bb922d..0c3256e9a8f987 100644 --- a/packages/core-data/src/queried-data/reducer.js +++ b/packages/core-data/src/queried-data/reducer.js @@ -74,10 +74,10 @@ function items( state = {}, action ) { const key = action.key || DEFAULT_ENTITY_KEY; return { ...state, - ...action.items.reduce( ( accumulator, value ) => { + ...action.items.reduce( ( acc, value ) => { const itemId = value[ key ]; - accumulator[ itemId ] = conservativeMapItem( state[ itemId ], value ); - return accumulator; + acc[ itemId ] = conservativeMapItem( state[ itemId ], value ); + return acc; }, {} ), }; } diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index 670cb4adf2a750..8edfdbf895cded 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -47,7 +47,7 @@ export function* getCurrentUser() { * @param {string} name Entity name. * @param {number} key Record's key */ -export function* getEntityRecord( kind, name, key = '' ) { +export function* getEntityRecord( kind, name, key ) { const entities = yield getKindEntities( kind ); const entity = find( entities, { kind, name } ); if ( ! entity ) { diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js index 3974d66c83b60b..4c61d59220843f 100644 --- a/packages/core-data/src/selectors.js +++ b/packages/core-data/src/selectors.js @@ -123,12 +123,12 @@ export const getRawEntityRecord = createSelector( const record = getEntityRecord( state, kind, name, key ); return ( record && - Object.keys( record ).reduce( ( accumulator, _key ) => { + Object.keys( record ).reduce( ( acc, _key ) => { // Because edits are the "raw" attribute values, // we return those from record selectors to make rendering, // comparisons, and joins with edits easier. - accumulator[ _key ] = get( record[ _key ], 'raw', record[ _key ] ); - return accumulator; + acc[ _key ] = get( record[ _key ], 'raw', record[ _key ] ); + return acc; }, {} ) ); }, diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json index 9b6d2724b43e45..8e74ef5a768b4c 100644 --- a/packages/data-controls/package.json +++ b/packages/data-controls/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data-controls", - "version": "1.3.3", + "version": "1.3.0", "description": "A set of common controls for the @wordpress/data api.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/README.md b/packages/data/README.md index 68dc1a48e1697a..a76019371e725a 100644 --- a/packages/data/README.md +++ b/packages/data/README.md @@ -251,46 +251,6 @@ Specific implementation differences from Redux and React Redux: <!-- START TOKEN(Autogenerated API docs) --> -<a name="AsyncModeProvider" href="#AsyncModeProvider">#</a> **AsyncModeProvider** - -Context Provider Component used to switch the data module component rerendering -between Sync and Async modes. - -_Usage_ - -```js -import { useSelect, AsyncModeProvider } from '@wordpress/data'; - -function BlockCount() { - const count = useSelect( ( select ) => { - return select( 'core/block-editor' ).getBlockCount() - } ); - - return count; -} - -function App() { - return ( - <AsyncModeProvider value={ true }> - <BlockCount /> - </AsyncModeProvider> - ); -} -``` - -In this example, the BlockCount component is rerendered asynchronously. -It means if a more critical task is being performed (like typing in an input), -the rerendering is delayed until the browser becomes IDLE. -It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. - -_Parameters_ - -- _props.value_ `boolean`: Enable Async Mode. - -_Returns_ - -- `WPComponent`: The component to be rendered. - <a name="combineReducers" href="#combineReducers">#</a> **combineReducers** The combineReducers helper function turns an object whose values are different @@ -733,7 +693,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Enhanced component with merged dispatcher props. +- `Component`: Enhanced component with merged dispatcher props. <a name="withRegistry" href="#withRegistry">#</a> **withRegistry** @@ -790,7 +750,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Enhanced component with merged state data props. +- `Component`: Enhanced component with merged state data props. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/data/package.json b/packages/data/package.json index 3812312f7dad8d..9eb21a7608146d 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data", - "version": "4.9.2", + "version": "4.9.0", "description": "Data module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/src/components/async-mode-provider/context.js b/packages/data/src/components/async-mode-provider/context.js index 88c98cb260b4a0..c0e59ef7138183 100644 --- a/packages/data/src/components/async-mode-provider/context.js +++ b/packages/data/src/components/async-mode-provider/context.js @@ -9,38 +9,4 @@ const { Consumer, Provider } = Context; export const AsyncModeConsumer = Consumer; -/** - * Context Provider Component used to switch the data module component rerendering - * between Sync and Async modes. - * - * @example - * - * ```js - * import { useSelect, AsyncModeProvider } from '@wordpress/data'; - * - * function BlockCount() { - * const count = useSelect( ( select ) => { - * return select( 'core/block-editor' ).getBlockCount() - * } ); - * - * return count; - * } - * - * function App() { - * return ( - * <AsyncModeProvider value={ true }> - * <BlockCount /> - * </AsyncModeProvider> - * ); - * } - * ``` - * - * In this example, the BlockCount component is rerendered asynchronously. - * It means if a more critical task is being performed (like typing in an input), - * the rerendering is delayed until the browser becomes IDLE. - * It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. - * - * @param {boolean} props.value Enable Async Mode. - * @return {WPComponent} The component to be rendered. - */ export default Provider; diff --git a/packages/data/src/components/with-dispatch/index.js b/packages/data/src/components/with-dispatch/index.js index 3e6c2194dec5f4..2247a253a189d5 100644 --- a/packages/data/src/components/with-dispatch/index.js +++ b/packages/data/src/components/with-dispatch/index.js @@ -85,7 +85,7 @@ import { useDispatchWithMap } from '../use-dispatch'; * returns an object with the same keys. For example, it should not contain * conditions under which a different value would be returned. * - * @return {WPComponent} Enhanced component with merged dispatcher props. + * @return {Component} Enhanced component with merged dispatcher props. */ const withDispatch = ( mapDispatchToProps ) => createHigherOrderComponent( ( WrappedComponent ) => ( ownProps ) => { diff --git a/packages/data/src/components/with-select/index.js b/packages/data/src/components/with-select/index.js index aeb86761494e44..f9659e7e865a8f 100644 --- a/packages/data/src/components/with-select/index.js +++ b/packages/data/src/components/with-select/index.js @@ -45,7 +45,7 @@ import useSelect from '../use-select'; * component and update automatically if the price of a hammer ever changes in * the store. * - * @return {WPComponent} Enhanced component with merged state data props. + * @return {Component} Enhanced component with merged state data props. */ const withSelect = ( mapSelectToProps ) => createHigherOrderComponent( ( WrappedComponent ) => pure( diff --git a/packages/data/src/factory.js b/packages/data/src/factory.js index bdc2f1519e60e5..2a10c7a8e7afc1 100644 --- a/packages/data/src/factory.js +++ b/packages/data/src/factory.js @@ -3,6 +3,10 @@ */ import defaultRegistry from './default-registry'; +/** + * @typedef {import('./registry').WPDataRegistry} WPDataRegistry + */ + /** * Mark a selector as a registry selector. * diff --git a/packages/data/src/index.js b/packages/data/src/index.js index c7ad8f67a7484d..8dd6893c5d9e01 100644 --- a/packages/data/src/index.js +++ b/packages/data/src/index.js @@ -19,7 +19,9 @@ export { } from './components/registry-provider'; export { default as useSelect } from './components/use-select'; export { useDispatch } from './components/use-dispatch'; -export { AsyncModeProvider } from './components/async-mode-provider'; +export { + AsyncModeProvider as __experimentalAsyncModeProvider, +} from './components/async-mode-provider'; export { createRegistry } from './registry'; export { createRegistrySelector, createRegistryControl } from './factory'; diff --git a/packages/data/src/namespace-store/index.js b/packages/data/src/namespace-store/index.js index bc41587569bbba..b3bd639fcddfa3 100644 --- a/packages/data/src/namespace-store/index.js +++ b/packages/data/src/namespace-store/index.js @@ -24,7 +24,7 @@ import * as metadataSelectors from './metadata/selectors'; import * as metadataActions from './metadata/actions'; /** - * @typedef {WPDataRegistry} WPDataRegistry + * @typedef {import('../registry').WPDataRegistry} WPDataRegistry */ /** diff --git a/packages/data/src/plugins/persistence/index.js b/packages/data/src/plugins/persistence/index.js index 871a7e56133594..a0c910f8a73bca 100644 --- a/packages/data/src/plugins/persistence/index.js +++ b/packages/data/src/plugins/persistence/index.js @@ -138,7 +138,7 @@ const persistencePlugin = function( registry, pluginOptions ) { // to leverage its behavior of returning the same object when none // of the property values changes. This allows a strict reference // equality to bypass a persistence set on an unchanging state. - const reducers = keys.reduce( ( accumulator, key ) => Object.assign( accumulator, { + const reducers = keys.reduce( ( result, key ) => Object.assign( result, { [ key ]: ( state, action ) => action.nextState[ key ], } ), {} ); diff --git a/packages/date/README.md b/packages/date/README.md index 96cbbba1b7239d..c4bad6ef1636e1 100644 --- a/packages/date/README.md +++ b/packages/date/README.md @@ -23,7 +23,7 @@ Formats a date (like `date()` in PHP), in the site's timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. _Returns_ @@ -36,7 +36,7 @@ Formats a date (like `date_i18n()` in PHP). _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. - _gmt_ `boolean`: True for GMT/UTC, false for site's timezone. _Returns_ @@ -50,7 +50,7 @@ Formats a date. Does not alter the date's timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. _Returns_ @@ -75,7 +75,7 @@ Formats a date (like `date()` in PHP), in the UTC timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. _Returns_ diff --git a/packages/date/src/index.js b/packages/date/src/index.js index 4537ec47284749..39b4425ea2da22 100644 --- a/packages/date/src/index.js +++ b/packages/date/src/index.js @@ -145,7 +145,7 @@ const formatMap = { /** * Gets the ordinal suffix. * - * @param {moment.Moment} momentDate Moment instance. + * @param {moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -160,7 +160,7 @@ const formatMap = { /** * Gets the day of the year (zero-indexed). * - * @param {moment.Moment} momentDate Moment instance. + * @param {moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -180,7 +180,7 @@ const formatMap = { /** * Gets the days in the month. * - * @param {moment.Moment} momentDate Moment instance. + * @param {moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -192,7 +192,7 @@ const formatMap = { /** * Gets whether the current year is a leap year. * - * @param {moment.Moment} momentDate Moment instance. + * @param {moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -209,7 +209,7 @@ const formatMap = { /** * Gets the current time in Swatch Internet Time (.beats). * - * @param {moment.Moment} momentDate Moment instance. + * @param {moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -240,7 +240,7 @@ const formatMap = { /** * Gets whether the timezone is in DST currently. * - * @param {moment.Moment} momentDate Moment instance. + * @param {moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -253,7 +253,7 @@ const formatMap = { /** * Gets the timezone offset in seconds. * - * @param {moment.Moment} momentDate Moment instance. + * @param {moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -273,10 +273,10 @@ const formatMap = { /** * Formats a date. Does not alter the date's timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -314,10 +314,10 @@ export function format( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date()` in PHP), in the site's timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -330,10 +330,10 @@ export function date( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date()` in PHP), in the UTC timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -345,12 +345,12 @@ export function gmdate( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date_i18n()` in PHP). * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, - * parsable by moment.js. - * @param {boolean} gmt True for GMT/UTC, false for - * site's timezone. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment|null)} dateValue Date object or string, + * parsable by moment.js. + * @param {boolean} gmt True for GMT/UTC, false for + * site's timezone. * * @return {string} Formatted date. */ diff --git a/packages/deprecated/package.json b/packages/deprecated/package.json index 7a0494fd4d54bb..654149a2f32208 100644 --- a/packages/deprecated/package.json +++ b/packages/deprecated/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/deprecated", - "version": "2.6.1", + "version": "2.6.0", "description": "Deprecation utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index ff4900eca80a02..33e1f9eca8283d 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "2.5.1", + "version": "2.5.0", "description": "Execute callback after the DOM is loaded.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom/package.json b/packages/dom/package.json index b335970b2113bc..e5f1b9297eec16 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom", - "version": "2.5.2", + "version": "2.5.0", "description": "DOM utilities module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md index 6d7c17d4e0c7e6..df00ecbe7c0ce2 100644 --- a/packages/e2e-test-utils/CHANGELOG.md +++ b/packages/e2e-test-utils/CHANGELOG.md @@ -1,9 +1,3 @@ -## Master - -### Breaking Changes -- The util function `enableExperimentalFeatures` was removed. It is now available for internal usage in the `e2e-tests` package. - - ## 2.0.0 (2019-05-21) ### Requirements diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index e01082057a82a8..d8b3263c2e6e99 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -191,7 +191,7 @@ _Parameters_ _Returns_ -- `?puppeteer.ElementHandle`: Object that represents an in-page DOM element. +- `?ElementHandle`: Object that represents an in-page DOM element. <a name="findSidebarPanelWithTitle" href="#findSidebarPanelWithTitle">#</a> **findSidebarPanelWithTitle** @@ -203,7 +203,7 @@ _Parameters_ _Returns_ -- `?puppeteer.ElementHandle`: Object that represents an in-page DOM element. +- `?ElementHandle`: Object that represents an in-page DOM element. <a name="getAllBlockInserterItemTitles" href="#getAllBlockInserterItemTitles">#</a> **getAllBlockInserterItemTitles** @@ -529,7 +529,7 @@ without the new dimensions being applied. _Parameters_ - _width_ `number`: Width of the window. -- _height_ `number`: Height of the window. +- _height_ `height`: Height of the window. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 6365c171aa416e..7ddd91f1b73974 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils", - "version": "2.4.3", + "version": "2.4.0", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/experimental-features.js b/packages/e2e-test-utils/src/enable-experimental-features.js similarity index 60% rename from packages/e2e-tests/experimental-features.js rename to packages/e2e-test-utils/src/enable-experimental-features.js index 4b06a761c865a0..be74f20f82fd92 100644 --- a/packages/e2e-tests/experimental-features.js +++ b/packages/e2e-test-utils/src/enable-experimental-features.js @@ -2,9 +2,18 @@ * WordPress dependencies */ import { addQueryArgs } from '@wordpress/url'; -import { visitAdminPage } from '@wordpress/e2e-test-utils'; -async function setExperimentalFeaturesState( features, enable ) { +/** + * Internal dependencies + */ +import { visitAdminPage } from './visit-admin-page'; + +/** + * Enables experimental features from the plugin settings section. + * + * @param {Array} features Array of {string} selectors of settings to enable. Assumes they can be enabled with one click. + */ +export async function enableExperimentalFeatures( features ) { const query = addQueryArgs( '', { page: 'gutenberg-experiments', } ); @@ -14,7 +23,7 @@ async function setExperimentalFeaturesState( features, enable ) { await page.waitForSelector( feature ); const checkedSelector = `${ feature }[checked=checked]`; const isChecked = !! ( await page.$( checkedSelector ) ); - if ( ( ! isChecked && enable ) || ( isChecked && ! enable ) ) { + if ( ! isChecked ) { await page.click( feature ); } } ) ); @@ -23,21 +32,3 @@ async function setExperimentalFeaturesState( features, enable ) { page.click( '#submit' ), ] ); } - -/** - * Enables experimental features from the plugin settings section. - * - * @param {Array} features Array of {string} selectors of settings to enable. Assumes they can be enabled with one click. - */ -export async function enableExperimentalFeatures( features ) { - await setExperimentalFeaturesState( features, true ); -} - -/** - * Disables experimental features from the plugin settings section. - * - * @param {Array} features Array of {string} selectors of settings to disable. Assumes they can be disabled with one click. - */ -export async function disableExperimentalFeatures( features ) { - await setExperimentalFeaturesState( features, false ); -} diff --git a/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js b/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js index 55fbf4c91c10f2..a4167fe6e2e6cd 100644 --- a/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js +++ b/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js @@ -8,7 +8,7 @@ import { first } from 'lodash'; * * @param {string} panelTitle The name of sidebar panel. * - * @return {?puppeteer.ElementHandle} Object that represents an in-page DOM element. + * @return {?ElementHandle} Object that represents an in-page DOM element. */ export async function findSidebarPanelToggleButtonWithTitle( panelTitle ) { return first( await page.$x( `//div[contains(@class,"edit-post-sidebar")]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ panelTitle }")]` ) ); diff --git a/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js b/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js index 2f1436c5b8de23..ff60dca5f00782 100644 --- a/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js +++ b/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js @@ -8,7 +8,7 @@ import { first } from 'lodash'; * * @param {string} panelTitle The name of sidebar panel. * - * @return {?puppeteer.ElementHandle} Object that represents an in-page DOM element. + * @return {?ElementHandle} Object that represents an in-page DOM element. */ export async function findSidebarPanelWithTitle( panelTitle ) { const classSelect = ( className ) => `[contains(concat(" ", @class, " "), " ${ className } ")]`; diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 40feec01014580..8fcf2b400c5853 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -11,6 +11,7 @@ export { createURL } from './create-url'; export { deactivatePlugin } from './deactivate-plugin'; export { disablePrePublishChecks } from './disable-pre-publish-checks'; export { dragAndResize } from './drag-and-resize'; +export { enableExperimentalFeatures } from './enable-experimental-features'; export { enablePageDialogAccept } from './enable-page-dialog-accept'; export { enablePrePublishChecks } from './enable-pre-publish-checks'; export { ensureSidebarOpened } from './ensure-sidebar-opened'; diff --git a/packages/e2e-test-utils/src/wait-for-window-dimensions.js b/packages/e2e-test-utils/src/wait-for-window-dimensions.js index 924a5c939b3da0..9b505cf3b12807 100644 --- a/packages/e2e-test-utils/src/wait-for-window-dimensions.js +++ b/packages/e2e-test-utils/src/wait-for-window-dimensions.js @@ -5,7 +5,7 @@ * https://github.com/GoogleChrome/puppeteer/issues/1751 * * @param {number} width Width of the window. - * @param {number} height Height of the window. + * @param {height} height Height of the window. */ export async function waitForWindowDimensions( width, height ) { await page diff --git a/packages/e2e-tests/config/performance-reporter.js b/packages/e2e-tests/config/performance-reporter.js index f7bb05666054d5..681bb60f41618e 100644 --- a/packages/e2e-tests/config/performance-reporter.js +++ b/packages/e2e-tests/config/performance-reporter.js @@ -6,7 +6,7 @@ function average( array ) { class PerformanceReporter { onRunComplete() { - const path = __dirname + '/../specs/performance/results.json'; + const path = __dirname + '/../specs/results.json'; if ( ! existsSync( path ) ) { return; diff --git a/packages/e2e-tests/fixtures/block-transforms.js b/packages/e2e-tests/fixtures/block-transforms.js index 454bf2aeb2bf22..ff297c84a5d3da 100644 --- a/packages/e2e-tests/fixtures/block-transforms.js +++ b/packages/e2e-tests/fixtures/block-transforms.js @@ -118,28 +118,6 @@ export const EXPECTED_TRANSFORMS = { ], originalBlock: 'Cover', }, - core__cover__gradient: { - availableTransforms: [ - 'Group', - 'Image', - 'Video', - ], - originalBlock: 'Cover', - }, - 'core__cover__gradient-image': { - availableTransforms: [ - 'Group', - 'Image', - ], - originalBlock: 'Cover', - }, - 'core__cover__gradient-video': { - availableTransforms: [ - 'Group', - 'Video', - ], - originalBlock: 'Cover', - }, core__cover__video: { availableTransforms: [ 'Group', @@ -447,12 +425,6 @@ export const EXPECTED_TRANSFORMS = { 'Group', ], }, - 'core__site-title': { - availableTransforms: [ - 'Group', - ], - originalBlock: 'Site Title', - }, 'core__social-link-amazon': { availableTransforms: [ 'Group', diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html deleted file mode 100644 index 6353eac851e882..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html +++ /dev/null @@ -1,10 +0,0 @@ -<!-- wp:cover {"url":"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=","dimRatio":30,"customGradient":"linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"} --> -<div class="wp-block-cover has-background-dim-30 has-background-dim has-background-gradient" style="background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)"> - <span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"></span> - <div class="wp-block-cover__inner-container"> - <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> - <p class="has-text-align-center has-large-font-size"> Cover! </p> - <!-- /wp:paragraph --> - </div> -</div> -<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json deleted file mode 100644 index 7752fa1da96f25..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - { - "clientId": "_clientId_0", - "name": "core/cover", - "isValid": true, - "attributes": { - "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", - "hasParallax": false, - "dimRatio": 30, - "backgroundType": "image", - "customGradient": "linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)" - }, - "innerBlocks": [ - { - "clientId": "_clientId_0", - "name": "core/paragraph", - "isValid": true, - "attributes": { - "align": "center", - "content": " Cover! ", - "dropCap": false, - "placeholder": "Write title…", - "fontSize": "large" - }, - "innerBlocks": [], - "originalContent": "<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>" - } - ], - "originalContent": "<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json deleted file mode 100644 index 07ab0aa6299bad..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json +++ /dev/null @@ -1,40 +0,0 @@ -[ - { - "blockName": "core/cover", - "attrs": { - "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", - "dimRatio": 30, - "customGradient": "linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)" - }, - "innerBlocks": [ - { - "blockName": "core/paragraph", - "attrs": { - "align": "center", - "placeholder": "Write title…", - "fontSize": "large" - }, - "innerBlocks": [], - "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>\n\t\t", - "innerContent": [ - "\n\t\t<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>\n\t\t" - ] - } - ], - "innerHTML": "\n<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", - "innerContent": [ - "\n<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", - null, - "\n\t</div>\n</div>\n" - ] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n", - "innerContent": [ - "\n" - ] - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html deleted file mode 100644 index 0fda894680f92b..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html +++ /dev/null @@ -1,5 +0,0 @@ -<!-- wp:cover {"url":"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=","dimRatio":30,"customGradient":"linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"} --> -<div class="wp-block-cover has-background-dim-30 has-background-dim has-background-gradient" style="background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)"><span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> -<p class="has-text-align-center has-large-font-size"> Cover! </p> -<!-- /wp:paragraph --></div></div> -<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html deleted file mode 100644 index 8da6141aa041ab..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html +++ /dev/null @@ -1,11 +0,0 @@ -<!-- wp:cover {"url":"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=","dimRatio":70,"backgroundType":"video","customGradient":"linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"} --> -<div class="wp-block-cover has-background-dim-70 has-background-dim has-background-gradient"> - <span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"></span> - <video class="wp-block-cover__video-background" autoplay muted loop src="data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="></video> - <div class="wp-block-cover__inner-container"> - <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> - <p class="has-text-align-center has-large-font-size">Cover!</p> - <!-- /wp:paragraph --> - </div> -</div> -<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json deleted file mode 100644 index 84cb314d0fcca6..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - { - "clientId": "_clientId_0", - "name": "core/cover", - "isValid": true, - "attributes": { - "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", - "hasParallax": false, - "dimRatio": 70, - "backgroundType": "video", - "customGradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)" - }, - "innerBlocks": [ - { - "clientId": "_clientId_0", - "name": "core/paragraph", - "isValid": true, - "attributes": { - "align": "center", - "content": "Cover!", - "dropCap": false, - "placeholder": "Write title…", - "fontSize": "large" - }, - "innerBlocks": [], - "originalContent": "<p class=\"has-text-align-center has-large-font-size\">Cover!</p>" - } - ], - "originalContent": "<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json deleted file mode 100644 index 3ad05dacbf1257..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json +++ /dev/null @@ -1,41 +0,0 @@ -[ - { - "blockName": "core/cover", - "attrs": { - "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", - "dimRatio": 70, - "backgroundType": "video", - "customGradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)" - }, - "innerBlocks": [ - { - "blockName": "core/paragraph", - "attrs": { - "align": "center", - "placeholder": "Write title…", - "fontSize": "large" - }, - "innerBlocks": [], - "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t", - "innerContent": [ - "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t" - ] - } - ], - "innerHTML": "\n<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", - "innerContent": [ - "\n<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", - null, - "\n\t</div>\n</div>\n" - ] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n", - "innerContent": [ - "\n" - ] - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html deleted file mode 100644 index 2bc567b4bf2e03..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html +++ /dev/null @@ -1,5 +0,0 @@ -<!-- wp:cover {"url":"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=","dimRatio":70,"backgroundType":"video","customGradient":"linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"} --> -<div class="wp-block-cover has-background-dim-70 has-background-dim has-background-gradient"><span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"></span><video class="wp-block-cover__video-background" autoplay muted loop src="data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="></video><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> -<p class="has-text-align-center has-large-font-size">Cover!</p> -<!-- /wp:paragraph --></div></div> -<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html deleted file mode 100644 index e3e7b9af44777a..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html +++ /dev/null @@ -1,9 +0,0 @@ -<!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"} --> -<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"> - <div class="wp-block-cover__inner-container"> - <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> - <p class="has-text-align-center has-large-font-size">Cover!</p> - <!-- /wp:paragraph --> - </div> -</div> -<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json deleted file mode 100644 index c280fe63d55ab1..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "clientId": "_clientId_0", - "name": "core/cover", - "isValid": true, - "attributes": { - "hasParallax": false, - "dimRatio": 50, - "backgroundType": "image", - "customGradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)" - }, - "innerBlocks": [ - { - "clientId": "_clientId_0", - "name": "core/paragraph", - "isValid": true, - "attributes": { - "align": "center", - "content": "Cover!", - "dropCap": false, - "placeholder": "Write title…", - "fontSize": "large" - }, - "innerBlocks": [], - "originalContent": "<p class=\"has-text-align-center has-large-font-size\">Cover!</p>" - } - ], - "originalContent": "<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json deleted file mode 100644 index 423586ba2681e6..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "blockName": "core/cover", - "attrs": { - "customGradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)" - }, - "innerBlocks": [ - { - "blockName": "core/paragraph", - "attrs": { - "align": "center", - "placeholder": "Write title…", - "fontSize": "large" - }, - "innerBlocks": [], - "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t", - "innerContent": [ - "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t" - ] - } - ], - "innerHTML": "\n<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", - "innerContent": [ - "\n<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", - null, - "\n\t</div>\n</div>\n" - ] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n", - "innerContent": [ - "\n" - ] - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html deleted file mode 100644 index 92615e65131f9b..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html +++ /dev/null @@ -1,5 +0,0 @@ -<!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"} --> -<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> -<p class="has-text-align-center has-large-font-size">Cover!</p> -<!-- /wp:paragraph --></div></div> -<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html index 0ad94205cbce05..c88644e748ebf8 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html @@ -1,2 +1,2 @@ -<!-- wp:navigation-menu-item {"label":"WordPress","url":"https://wordpress.org/"} --> +<!-- wp:navigation-menu-item {"label":"WordPress","destination":"https://wordpress.org/"} --> <!-- /wp:navigation-menu-item --> diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json index 4e5ae943cb9b4a..eb71bb8b929c4b 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json @@ -5,9 +5,9 @@ "isValid": true, "attributes": { "label": "WordPress", + "destination": "https://wordpress.org/", "nofollow": false, - "opensInNewTab": false, - "url": "https://wordpress.org/" + "opensInNewTab": false }, "innerBlocks": [], "originalContent": "" diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json index 2b03a8420038b8..8fa4f5340bb83d 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json @@ -3,7 +3,7 @@ "blockName": "core/navigation-menu-item", "attrs": { "label": "WordPress", - "url": "https://wordpress.org/" + "destination": "https://wordpress.org/" }, "innerBlocks": [], "innerHTML": "\n", diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html index ecf1f0ce7ad654..b5176129ef2460 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html @@ -1 +1 @@ -<!-- wp:navigation-menu-item {"label":"WordPress","url":"https://wordpress.org/"} /--> +<!-- wp:navigation-menu-item {"label":"WordPress","destination":"https://wordpress.org/"} /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.html b/packages/e2e-tests/fixtures/blocks/core__site-title.html deleted file mode 100644 index 3c42ebc0d2feb7..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__site-title.html +++ /dev/null @@ -1 +0,0 @@ -<!-- wp:site-title /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.json b/packages/e2e-tests/fixtures/blocks/core__site-title.json deleted file mode 100644 index 6070316cf41796..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__site-title.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "clientId": "_clientId_0", - "name": "core/site-title", - "isValid": true, - "attributes": {}, - "innerBlocks": [], - "originalContent": "" - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json b/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json deleted file mode 100644 index bc570f8255a124..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "blockName": "core/site-title", - "attrs": {}, - "innerBlocks": [], - "innerHTML": "", - "innerContent": [] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n", - "innerContent": [ - "\n" - ] - } -] diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html b/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html deleted file mode 100644 index 3c42ebc0d2feb7..00000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html +++ /dev/null @@ -1 +0,0 @@ -<!-- wp:site-title /--> diff --git a/packages/e2e-tests/jest.config.js b/packages/e2e-tests/jest.config.js index 22bccf74e3d1a1..2720488c7b36de 100644 --- a/packages/e2e-tests/jest.config.js +++ b/packages/e2e-tests/jest.config.js @@ -12,6 +12,6 @@ module.exports = { testPathIgnorePatterns: [ '/node_modules/', '/wordpress/', - 'e2e-tests/specs/performance/', + 'e2e-tests/specs/performance.test.js', ], }; diff --git a/packages/e2e-tests/jest.performance.config.js b/packages/e2e-tests/jest.performance.config.js index cc011820f08871..f8fe4cf8ff1ff6 100644 --- a/packages/e2e-tests/jest.performance.config.js +++ b/packages/e2e-tests/jest.performance.config.js @@ -1,7 +1,7 @@ module.exports = { ...require( '@wordpress/scripts/config/jest-e2e.config' ), testMatch: [ - '**/performance/*.test.js', + '**/performance.test.js', ], setupFiles: [ '<rootDir>/config/gutenberg-phase.js', diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index b3a75cf9f73145..1fe2ee6a9464ba 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "1.7.3", + "version": "1.7.0", "description": "End-To-End (E2E) tests for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -26,7 +26,6 @@ "@wordpress/jest-console": "file:../jest-console", "@wordpress/jest-puppeteer-axe": "file:../jest-puppeteer-axe", "@wordpress/scripts": "file:../scripts", - "@wordpress/url": "file:../url", "expect-puppeteer": "^4.3.0", "lodash": "^4.17.15", "uuid": "^3.3.2" diff --git a/packages/e2e-tests/specs/performance/.gitignore b/packages/e2e-tests/specs/.gitignore similarity index 100% rename from packages/e2e-tests/specs/performance/.gitignore rename to packages/e2e-tests/specs/.gitignore diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap b/packages/e2e-tests/specs/__snapshots__/adding-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/adding-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-deletion.test.js.snap b/packages/e2e-tests/specs/__snapshots__/block-deletion.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/block-deletion.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/block-deletion.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap b/packages/e2e-tests/specs/__snapshots__/block-grouping.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/block-grouping.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap b/packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap diff --git a/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap b/packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap similarity index 94% rename from packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap index f461a1a4412dec..dbe341ba42e76e 100644 --- a/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap +++ b/packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap @@ -20,30 +20,6 @@ exports[`Block transforms correctly transform block Cover in fixture core__cover <!-- /wp:image -->" `; -exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient into the Image block 1`] = ` -"<!-- wp:image --> -<figure class=\\"wp-block-image\\"><img alt=\\"\\"/></figure> -<!-- /wp:image -->" -`; - -exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient into the Video block 1`] = ` -"<!-- wp:video --> -<figure class=\\"wp-block-video\\"></figure> -<!-- /wp:video -->" -`; - -exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient-image into the Image block 1`] = ` -"<!-- wp:image --> -<figure class=\\"wp-block-image\\"><img src=\\"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=\\" alt=\\"\\"/></figure> -<!-- /wp:image -->" -`; - -exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient-video into the Video block 1`] = ` -"<!-- wp:video --> -<figure class=\\"wp-block-video\\"><video controls src=\\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\\"></video></figure> -<!-- /wp:video -->" -`; - exports[`Block transforms correctly transform block Cover in fixture core__cover__video into the Video block 1`] = ` "<!-- wp:video --> <figure class=\\"wp-block-video\\"><video controls src=\\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\\"></video></figure> diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/compatibility-classic-editor.test.js.snap b/packages/e2e-tests/specs/__snapshots__/compatibility-classic-editor.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/compatibility-classic-editor.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/compatibility-classic-editor.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/convert-block-type.test.js.snap b/packages/e2e-tests/specs/__snapshots__/convert-block-type.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/convert-block-type.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/convert-block-type.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap b/packages/e2e-tests/specs/__snapshots__/embedding.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/embedding.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/font-size-picker.test.js.snap b/packages/e2e-tests/specs/__snapshots__/font-size-picker.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/font-size-picker.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/font-size-picker.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap b/packages/e2e-tests/specs/__snapshots__/links.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/links.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/mentions.test.js.snap b/packages/e2e-tests/specs/__snapshots__/mentions.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/mentions.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/mentions.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap b/packages/e2e-tests/specs/__snapshots__/multi-block-selection.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/multi-block-selection.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap b/packages/e2e-tests/specs/__snapshots__/reusable-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/reusable-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap b/packages/e2e-tests/specs/__snapshots__/rich-text.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/rich-text.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/rtl.test.js.snap b/packages/e2e-tests/specs/__snapshots__/rtl.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/rtl.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/rtl.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/splitting-merging.test.js.snap b/packages/e2e-tests/specs/__snapshots__/splitting-merging.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/splitting-merging.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/splitting-merging.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/style-variation.test.js.snap b/packages/e2e-tests/specs/__snapshots__/style-variation.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/style-variation.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/style-variation.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/undo.test.js.snap b/packages/e2e-tests/specs/__snapshots__/undo.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/undo.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/undo.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/writing-flow.test.js.snap b/packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/writing-flow.test.js.snap rename to packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap diff --git a/packages/e2e-tests/specs/editor/various/a11y.test.js b/packages/e2e-tests/specs/a11y.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/a11y.test.js rename to packages/e2e-tests/specs/a11y.test.js diff --git a/packages/e2e-tests/specs/editor/various/adding-blocks.test.js b/packages/e2e-tests/specs/adding-blocks.test.js similarity index 98% rename from packages/e2e-tests/specs/editor/various/adding-blocks.test.js rename to packages/e2e-tests/specs/adding-blocks.test.js index ea79e31224e8e0..56e5976513746d 100644 --- a/packages/e2e-tests/specs/editor/various/adding-blocks.test.js +++ b/packages/e2e-tests/specs/adding-blocks.test.js @@ -17,7 +17,7 @@ describe( 'adding blocks', () => { /** * Given a Puppeteer ElementHandle, clicks below its bounding box. * - * @param {puppeteer.ElementHandle} elementHandle Element handle. + * @param {Puppeteer.ElementHandle} elementHandle Element handle. * * @return {Promise} Promise resolving when click occurs. */ diff --git a/packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js b/packages/e2e-tests/specs/adding-inline-tokens.test.js similarity index 93% rename from packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js rename to packages/e2e-tests/specs/adding-inline-tokens.test.js index b11077e70fb3d3..f028a73c3df931 100644 --- a/packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js +++ b/packages/e2e-tests/specs/adding-inline-tokens.test.js @@ -33,7 +33,7 @@ describe( 'adding inline tokens', () => { // Wait for media modal to appear and upload image. await page.waitForSelector( '.media-modal input[type=file]' ); const inputElement = await page.$( '.media-modal input[type=file]' ); - const testImagePath = path.join( __dirname, '..', '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); + const testImagePath = path.join( __dirname, '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); diff --git a/packages/e2e-tests/specs/editor/various/autosave.test.js b/packages/e2e-tests/specs/autosave.test.js similarity index 77% rename from packages/e2e-tests/specs/editor/various/autosave.test.js rename to packages/e2e-tests/specs/autosave.test.js index 3c966f15a0748d..9f97f0f1c3f291 100644 --- a/packages/e2e-tests/specs/editor/various/autosave.test.js +++ b/packages/e2e-tests/specs/autosave.test.js @@ -17,22 +17,13 @@ const AUTOSAVE_INTERVAL_SECONDS = 5; const AUTOSAVE_NOTICE_REMOTE = 'There is an autosave of this post that is more recent than the version below.'; const AUTOSAVE_NOTICE_LOCAL = 'The backup of this post in your browser is different from the version below.'; -// Save and wait for "Saved" to confirm save complete. Preserves focus in the -// editing area. async function saveDraftWithKeyboard() { - await page.waitForSelector( '.editor-post-save-draft' ); - await Promise.all( [ - page.waitForSelector( '.editor-post-saved-state.is-saved' ), - pressKeyWithModifier( 'primary', 'S' ), - ] ); + return pressKeyWithModifier( 'primary', 's' ); } async function sleep( durationInSeconds ) { - // Rule `no-restricted-syntax` recommends `waitForSelector` against - // `waitFor`, which isn't apt for the use case, when provided an integer, - // of waiting for a given amount of time. - // eslint-disable-next-line no-restricted-syntax - await page.waitFor( durationInSeconds * 1000 ); + return new Promise( ( resolve ) => + setTimeout( resolve, durationInSeconds * 1000 ) ); } async function clearSessionStorage() { @@ -162,11 +153,11 @@ describe( 'autosave', () => { } ); it( 'should clear local autosave after successful remote autosave', async () => { - // Edit, save draft, edit again await clickBlockAppender(); await page.keyboard.type( 'before save' ); - await saveDraftWithKeyboard(); - await page.keyboard.type( ' after save' ); + await saveDraft(); + + await page.keyboard.type( 'after save' ); // Trigger local autosave await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); @@ -178,52 +169,21 @@ describe( 'autosave', () => { } ); it( 'shouldn\'t clear local autosave if remote autosave fails', async () => { - // Edit, save draft, edit again await clickBlockAppender(); await page.keyboard.type( 'before save' ); - await saveDraftWithKeyboard(); - await page.keyboard.type( ' after save' ); + await saveDraft(); - // Trigger local autosave + await page.keyboard.type( 'after save' ); await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); - // Bring network down and attempt to autosave remotely toggleOfflineMode( true ); - await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).autosave() ); - expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); - } ); - it( 'should clear local autosave after successful save', async () => { - // Edit, save draft, edit again - await clickBlockAppender(); - await page.keyboard.type( 'before save' ); - await saveDraftWithKeyboard(); - await page.keyboard.type( ' after save' ); - - // Trigger local autosave - await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); - expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); - - await saveDraftWithKeyboard(); - expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 0 ); - } ); - - it( 'shouldn\'t clear local autosave if save fails', async () => { - // Edit, save draft, edit again - await clickBlockAppender(); - await page.keyboard.type( 'before save' ); - await saveDraftWithKeyboard(); - await page.keyboard.type( ' after save' ); - - // Trigger local autosave - await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); + // Trigger remote autosave + await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).autosave() ); expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); - // Bring network down and attempt to save - toggleOfflineMode( true ); - saveDraftWithKeyboard(); - expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + toggleOfflineMode( false ); } ); it( 'shouldn\'t conflict with server-side autosave', async () => { @@ -261,8 +221,7 @@ describe( 'autosave', () => { expect( notice ).toContain( AUTOSAVE_NOTICE_REMOTE ); } ); - afterEach( async () => { - toggleOfflineMode( false ); + afterAll( async () => { await clearSessionStorage(); } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/block-deletion.test.js b/packages/e2e-tests/specs/block-deletion.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/block-deletion.test.js rename to packages/e2e-tests/specs/block-deletion.test.js diff --git a/packages/e2e-tests/specs/editor/various/block-grouping.test.js b/packages/e2e-tests/specs/block-grouping.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/block-grouping.test.js rename to packages/e2e-tests/specs/block-grouping.test.js diff --git a/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js b/packages/e2e-tests/specs/block-hierarchy-navigation.test.js similarity index 99% rename from packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js rename to packages/e2e-tests/specs/block-hierarchy-navigation.test.js index efba2e1d6afc5e..2dc5dc1f6cc544 100644 --- a/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js +++ b/packages/e2e-tests/specs/block-hierarchy-navigation.test.js @@ -82,7 +82,6 @@ describe( 'Navigating the block hierarchy', () => { await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); - await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyTimes( 'Tab', 4 ); // Tweak the columns count by increasing it by one. diff --git a/packages/e2e-tests/specs/editor/various/block-mover.test.js b/packages/e2e-tests/specs/block-mover.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/block-mover.test.js rename to packages/e2e-tests/specs/block-mover.test.js diff --git a/packages/e2e-tests/specs/editor/various/block-switcher.test.js b/packages/e2e-tests/specs/block-switcher.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/block-switcher.test.js rename to packages/e2e-tests/specs/block-switcher.test.js diff --git a/packages/e2e-tests/specs/experimental/block-transforms.test.js b/packages/e2e-tests/specs/block-transforms.test.js similarity index 88% rename from packages/e2e-tests/specs/experimental/block-transforms.test.js rename to packages/e2e-tests/specs/block-transforms.test.js index bf6e5027b745e6..381facd4c00673 100644 --- a/packages/e2e-tests/specs/experimental/block-transforms.test.js +++ b/packages/e2e-tests/specs/block-transforms.test.js @@ -13,25 +13,18 @@ import { * WordPress dependencies */ import { - createNewPost, getAllBlocks, getAvailableBlockTransforms, getBlockSetting, getEditedPostContent, hasBlockSwitcher, - selectBlockByClientId, + createNewPost, + enableExperimentalFeatures, setPostContent, + selectBlockByClientId, transformBlockTo, } from '@wordpress/e2e-test-utils'; -/** - * Internal dependencies - */ -import { - enableExperimentalFeatures, - disableExperimentalFeatures, -} from '../../experimental-features'; - /** * Internal dependencies */ @@ -39,8 +32,8 @@ import { getAvailableBlockFixturesBasenames, getBlockFixtureHTML, getBlockFixtureParsedJSON, -} from '../../fixtures/'; -import { EXPECTED_TRANSFORMS } from '../../fixtures/block-transforms.js'; +} from '../fixtures/'; +import { EXPECTED_TRANSFORMS } from '../fixtures/block-transforms.js'; /* * Returns true if the fileBase refers to a fixture of a block @@ -107,11 +100,7 @@ describe( 'Block transforms', () => { const transformStructure = {}; beforeAll( async () => { - await enableExperimentalFeatures( [ - '#gutenberg-widget-experiments', - '#gutenberg-menu-block', - '#gutenberg-full-site-editing', - ] ); + await enableExperimentalFeatures( [ '#gutenberg-widget-experiments', '#gutenberg-menu-block' ] ); await createNewPost(); for ( const fileBase of fileBasenames ) { @@ -127,16 +116,6 @@ describe( 'Block transforms', () => { } } ); - afterAll( - async () => { - await disableExperimentalFeatures( [ - '#gutenberg-widget-experiments', - '#gutenberg-menu-block', - '#gutenberg-full-site-editing', - ] ); - } - ); - it( 'should contain the expected transforms', async () => { const transforms = mapValues( pickBy( diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/button.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/button.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/button.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/button.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/classic.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/classic.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/classic.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/classic.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/code.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/code.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/code.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/code.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/group.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/group.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/heading.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/heading.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/heading.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/heading.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/html.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/html.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/html.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/html.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap similarity index 98% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap index b1e178aa10b710..001c5b93e0edd3 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap +++ b/packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap @@ -80,12 +80,6 @@ exports[`List can undo asterisk transform 1`] = ` <!-- /wp:paragraph -->" `; -exports[`List first empty list item is graciously removed 1`] = ` -"<!-- wp:list --> -<ul><li>2</li></ul> -<!-- /wp:list -->" -`; - exports[`List should be immeadiately saved on indentation 1`] = ` "<!-- wp:list --> <ul><li>one<ul><li></li></ul></li></ul> diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/preformatted.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/preformatted.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/preformatted.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/preformatted.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/quote.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/quote.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/quote.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/quote.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/separator.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/separator.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/separator.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/separator.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/spacer.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/spacer.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/spacer.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/spacer.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap b/packages/e2e-tests/specs/blocks/__snapshots__/table.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap rename to packages/e2e-tests/specs/blocks/__snapshots__/table.test.js.snap diff --git a/packages/e2e-tests/specs/editor/blocks/button.test.js b/packages/e2e-tests/specs/blocks/button.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/button.test.js rename to packages/e2e-tests/specs/blocks/button.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/classic.test.js b/packages/e2e-tests/specs/blocks/classic.test.js similarity index 95% rename from packages/e2e-tests/specs/editor/blocks/classic.test.js rename to packages/e2e-tests/specs/blocks/classic.test.js index 29170335d900f1..29d1605f0874b5 100644 --- a/packages/e2e-tests/specs/editor/blocks/classic.test.js +++ b/packages/e2e-tests/specs/blocks/classic.test.js @@ -49,7 +49,7 @@ describe( 'Classic', () => { // Wait for media modal to appear and upload image. await page.waitForSelector( '.media-modal input[type=file]' ); const inputElement = await page.$( '.media-modal input[type=file]' ); - const testImagePath = path.join( __dirname, '..', '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); + const testImagePath = path.join( __dirname, '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); diff --git a/packages/e2e-tests/specs/editor/blocks/code.test.js b/packages/e2e-tests/specs/blocks/code.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/code.test.js rename to packages/e2e-tests/specs/blocks/code.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/columns.test.js b/packages/e2e-tests/specs/blocks/columns.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/columns.test.js rename to packages/e2e-tests/specs/blocks/columns.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/group.test.js b/packages/e2e-tests/specs/blocks/group.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/group.test.js rename to packages/e2e-tests/specs/blocks/group.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/heading.test.js b/packages/e2e-tests/specs/blocks/heading.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/heading.test.js rename to packages/e2e-tests/specs/blocks/heading.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/html.test.js b/packages/e2e-tests/specs/blocks/html.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/html.test.js rename to packages/e2e-tests/specs/blocks/html.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/list.test.js b/packages/e2e-tests/specs/blocks/list.test.js similarity index 97% rename from packages/e2e-tests/specs/editor/blocks/list.test.js rename to packages/e2e-tests/specs/blocks/list.test.js index 9e3086295413e9..7fa889baa0cdd3 100644 --- a/packages/e2e-tests/specs/editor/blocks/list.test.js +++ b/packages/e2e-tests/specs/blocks/list.test.js @@ -478,16 +478,4 @@ describe( 'List', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); - - it( 'first empty list item is graciously removed', async () => { - await clickBlockAppender(); - await page.keyboard.type( '* 1' ); - await page.keyboard.press( 'Enter' ); - await page.keyboard.type( '2' ); - await page.keyboard.press( 'ArrowUp' ); - await page.keyboard.press( 'Backspace' ); - await page.keyboard.press( 'Backspace' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - } ); } ); diff --git a/packages/e2e-tests/specs/editor/blocks/preformatted.test.js b/packages/e2e-tests/specs/blocks/preformatted.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/preformatted.test.js rename to packages/e2e-tests/specs/blocks/preformatted.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/quote.test.js b/packages/e2e-tests/specs/blocks/quote.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/quote.test.js rename to packages/e2e-tests/specs/blocks/quote.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/separator.test.js b/packages/e2e-tests/specs/blocks/separator.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/separator.test.js rename to packages/e2e-tests/specs/blocks/separator.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/spacer.test.js b/packages/e2e-tests/specs/blocks/spacer.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/blocks/spacer.test.js rename to packages/e2e-tests/specs/blocks/spacer.test.js diff --git a/packages/e2e-tests/specs/editor/blocks/table.test.js b/packages/e2e-tests/specs/blocks/table.test.js similarity index 94% rename from packages/e2e-tests/specs/editor/blocks/table.test.js rename to packages/e2e-tests/specs/blocks/table.test.js index 790ba0cd1ad7d6..15267da90cb185 100644 --- a/packages/e2e-tests/specs/editor/blocks/table.test.js +++ b/packages/e2e-tests/specs/blocks/table.test.js @@ -70,7 +70,7 @@ describe( 'Table', () => { await clickButton( createButtonLabel ); // Click the first cell and add some text. - await page.click( 'td' ); + await page.click( '.wp-block-table__cell-content' ); await page.keyboard.type( 'This' ); // Tab to the next cell and add some text. @@ -114,13 +114,13 @@ describe( 'Table', () => { await headerSwitch[ 0 ].click(); await footerSwitch[ 0 ].click(); - await page.click( 'thead th' ); + await page.click( 'thead .wp-block-table__cell-content' ); await page.keyboard.type( 'header' ); - await page.click( 'tbody td' ); + await page.click( 'tbody .wp-block-table__cell-content' ); await page.keyboard.type( 'body' ); - await page.click( 'tfoot td' ); + await page.click( 'tfoot .wp-block-table__cell-content' ); await page.keyboard.type( 'footer' ); // Expect the table to have a header, body and footer with written content. @@ -146,7 +146,7 @@ describe( 'Table', () => { await headerSwitch[ 0 ].click(); await footerSwitch[ 0 ].click(); - await page.click( 'td' ); + await page.click( '.wp-block-table__cell-content' ); // Add a column. await clickBlockToolbarButton( 'Edit table' ); @@ -155,7 +155,7 @@ describe( 'Table', () => { // Expect the table to have 3 columns across the header, body and footer. expect( await getEditedPostContent() ).toMatchSnapshot(); - await page.click( 'td' ); + await page.click( '.wp-block-table__cell-content' ); // Delete a column. await clickBlockToolbarButton( 'Edit table' ); @@ -177,7 +177,7 @@ describe( 'Table', () => { await clickButton( createButtonLabel ); // Click the first cell and add some text. Don't align. - const cells = await page.$$( 'td,th' ); + const cells = await page.$$( '.wp-block-table__cell-content' ); await cells[ 0 ].click(); await page.keyboard.type( 'None' ); @@ -212,7 +212,7 @@ describe( 'Table', () => { await fixedWidthSwitch.click(); // Add multiple new lines to the first cell to make it taller. - await page.click( 'td' ); + await page.click( '.wp-block-table__cell-content' ); await page.keyboard.type( '\n\n\n\n' ); // Get the bounding client rect for the second cell. diff --git a/packages/e2e-tests/specs/editor/various/change-detection.test.js b/packages/e2e-tests/specs/change-detection.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/change-detection.test.js rename to packages/e2e-tests/specs/change-detection.test.js diff --git a/packages/e2e-tests/specs/editor/various/compatibility-classic-editor.test.js b/packages/e2e-tests/specs/compatibility-classic-editor.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/compatibility-classic-editor.test.js rename to packages/e2e-tests/specs/compatibility-classic-editor.test.js diff --git a/packages/e2e-tests/specs/editor/various/convert-block-type.test.js b/packages/e2e-tests/specs/convert-block-type.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/convert-block-type.test.js rename to packages/e2e-tests/specs/convert-block-type.test.js diff --git a/packages/e2e-tests/specs/editor/various/datepicker.test.js b/packages/e2e-tests/specs/datepicker.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/datepicker.test.js rename to packages/e2e-tests/specs/datepicker.test.js diff --git a/packages/e2e-tests/specs/local/demo.test.js b/packages/e2e-tests/specs/demo.test.js similarity index 100% rename from packages/e2e-tests/specs/local/demo.test.js rename to packages/e2e-tests/specs/demo.test.js diff --git a/packages/e2e-tests/specs/editor/various/editor-modes.test.js b/packages/e2e-tests/specs/editor-modes.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/editor-modes.test.js rename to packages/e2e-tests/specs/editor-modes.test.js diff --git a/packages/e2e-tests/specs/editor/various/embedding.test.js b/packages/e2e-tests/specs/embedding.test.js similarity index 87% rename from packages/e2e-tests/specs/editor/various/embedding.test.js rename to packages/e2e-tests/specs/embedding.test.js index 0a986702075bec..878e540967a4f1 100644 --- a/packages/e2e-tests/specs/editor/various/embedding.test.js +++ b/packages/e2e-tests/specs/embedding.test.js @@ -271,4 +271,33 @@ describe( 'Embedding content', () => { // Check the block has become a WordPress block. await page.waitForSelector( '.wp-block-embed-wordpress' ); } ); + + it.skip( 'should transform from video to embed block when YouTube URL is pasted', async () => { + await clickBlockAppender(); + await insertBlock( 'Video' ); + await page.click( '.editor-media-placeholder__url-input-container button' ); + await page.keyboard.type( 'https://www.youtube.com/watch?v=lXMskKTw3Bc' ); + await page.keyboard.press( 'Enter' ); + await page.waitForSelector( '.wp-block-embed-youtube' ); + } ); + + it.skip( 'should transform from image to embed block when Instagram URL is pasted', async () => { + await clickBlockAppender(); + await page.keyboard.type( '/image' ); + await page.keyboard.press( 'Enter' ); + await page.click( '.editor-media-placeholder__url-input-container button' ); + await page.keyboard.type( 'https://www.instagram.com/p/Bvl97o2AK6x/' ); + await page.keyboard.press( 'Enter' ); + await page.waitForSelector( '.wp-block-embed-instagram' ); + } ); + + it.skip( 'should transform from audio to embed block when Soundcloud URL is pasted', async () => { + await clickBlockAppender(); + await page.keyboard.type( '/audio' ); + await page.keyboard.press( 'Enter' ); + await page.click( '.editor-media-placeholder__url-input-container button' ); + await page.keyboard.type( 'https://soundcloud.com/a-boogie-wit-da-hoodie/swervin' ); + await page.keyboard.press( 'Enter' ); + await page.waitForSelector( '.wp-block-embed-soundcloud' ); + } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/font-size-picker.test.js b/packages/e2e-tests/specs/font-size-picker.test.js similarity index 97% rename from packages/e2e-tests/specs/editor/various/font-size-picker.test.js rename to packages/e2e-tests/specs/font-size-picker.test.js index 0fb98caa4f5d29..a80a81b46442d3 100644 --- a/packages/e2e-tests/specs/editor/various/font-size-picker.test.js +++ b/packages/e2e-tests/specs/font-size-picker.test.js @@ -75,8 +75,8 @@ describe( 'Font Size Picker', () => { // Clear the custom font size input. await page.click( '.blocks-font-size .components-range-control__number' ); - await pressKeyTimes( 'ArrowRight', 5 ); - await pressKeyTimes( 'Backspace', 5 ); + await pressKeyTimes( 'ArrowRight', 4 ); + await pressKeyTimes( 'Backspace', 4 ); // Ensure content matches snapshot. const content = await getEditedPostContent(); diff --git a/packages/e2e-tests/specs/editor/various/fullscreen-mode.test.js b/packages/e2e-tests/specs/fullscreen-mode.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/fullscreen-mode.test.js rename to packages/e2e-tests/specs/fullscreen-mode.test.js diff --git a/packages/e2e-tests/specs/editor/various/invalid-block.test.js b/packages/e2e-tests/specs/invalid-block.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/invalid-block.test.js rename to packages/e2e-tests/specs/invalid-block.test.js diff --git a/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js rename to packages/e2e-tests/specs/keyboard-navigable-blocks.test.js diff --git a/packages/e2e-tests/specs/editor/various/links.test.js b/packages/e2e-tests/specs/links.test.js similarity index 80% rename from packages/e2e-tests/specs/editor/various/links.test.js rename to packages/e2e-tests/specs/links.test.js index ce9aaeab186799..f7e78a7b68a1e2 100644 --- a/packages/e2e-tests/specs/editor/various/links.test.js +++ b/packages/e2e-tests/specs/links.test.js @@ -266,6 +266,87 @@ describe( 'Links', () => { 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.skip( '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. + await createNewPost(); + await clickBlockAppender(); + await page.keyboard.type( 'This is Gutenberg' ); + await pressKeyWithModifier( 'shiftAlt', 'ArrowLeft' ); + await page.click( 'button[aria-label="Link"]' ); + + // Wait for the URL field to auto-focus + await waitForAutoFocus(); + + await page.keyboard.type( titleText ); + const suggestionXPath = `//*[contains(@class, "block-editor-url-input__suggestion")]//button[contains(text(), '${ titleText }')]`; + await page.waitForXPath( suggestionXPath ); + const autocompleteSuggestions = await page.$x( suggestionXPath ); + + // Expect there to be some autocomplete suggestions. + expect( autocompleteSuggestions ).toHaveLength( 1 ); + + const firstSuggestion = autocompleteSuggestions[ 0 ]; + + // Expect that clicking on the autocomplete suggestion doesn't dismiss the link popover. + await firstSuggestion.click(); + expect( await page.$( '.block-editor-url-popover' ) ).not.toBeNull(); + + // Expect the url input value to have been updated with the post url. + const inputValue = await page.evaluate( () => document.querySelector( '.block-editor-url-input input[aria-label="URL"]' ).value ); + expect( inputValue ).toEqual( postURL ); + + // Expect the link to apply correctly. + // Note - have avoided using snapshots here since the link url can't be determined ahead of time. + await page.click( 'button[aria-label="Apply"]' ); + const linkHref = await page.evaluate( () => document.querySelector( '.block-editor-format-toolbar__link-container-value' ).href ); + expect( linkHref ).toEqual( postURL ); + } ); + + // Test for regressions of https://github.com/WordPress/gutenberg/issues/10496. + // This test isn't reliable on Travis and fails from time to time. + // See: https://github.com/WordPress/gutenberg/pull/15211. + it.skip( 'allows autocomplete suggestions to be navigated with the keyboard', async () => { + const titleText = 'Test post keyboard'; + const postURL = await createPostWithTitle( titleText ); + + await createNewPost(); + 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 pressKeyWithModifier( 'shiftAlt', 'ArrowLeft' ); + + // Press Cmd+K to insert a link + await pressKeyWithModifier( 'primary', 'K' ); + + // Wait for the URL field to auto-focus + await waitForAutoFocus(); + + await page.keyboard.type( titleText ); + await page.waitForSelector( '.block-editor-url-input__suggestion' ); + const autocompleteSuggestions = await page.$x( `//*[contains(@class, "block-editor-url-input__suggestion")]//button[contains(text(), '${ titleText }')]` ); + + // Expect there to be some autocomplete suggestions. + expect( autocompleteSuggestions ).toHaveLength( 1 ); + + // 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( '.block-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( '.block-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 ); diff --git a/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js b/packages/e2e-tests/specs/manage-reusable-blocks.test.js similarity index 93% rename from packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js rename to packages/e2e-tests/specs/manage-reusable-blocks.test.js index 9d17922f519f39..37340d669f5a74 100644 --- a/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js +++ b/packages/e2e-tests/specs/manage-reusable-blocks.test.js @@ -32,7 +32,7 @@ describe( 'Managing reusable blocks', () => { await importButton.click(); // Select the file to upload - const testReusableBlockFile = path.join( __dirname, '..', '..', '..', 'assets', 'greeting-reusable-block.json' ); + const testReusableBlockFile = path.join( __dirname, '..', 'assets', 'greeting-reusable-block.json' ); const input = await page.$( '.list-reusable-blocks-import-form input' ); await input.uploadFile( testReusableBlockFile ); diff --git a/packages/e2e-tests/specs/editor/various/mentions.test.js b/packages/e2e-tests/specs/mentions.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/mentions.test.js rename to packages/e2e-tests/specs/mentions.test.js diff --git a/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js b/packages/e2e-tests/specs/multi-block-selection.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/multi-block-selection.test.js rename to packages/e2e-tests/specs/multi-block-selection.test.js diff --git a/packages/e2e-tests/specs/editor/various/navigable-toolbar.test.js b/packages/e2e-tests/specs/navigable-toolbar.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/navigable-toolbar.test.js rename to packages/e2e-tests/specs/navigable-toolbar.test.js diff --git a/packages/e2e-tests/specs/editor/various/new-post-default-content.test.js b/packages/e2e-tests/specs/new-post-default-content.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/new-post-default-content.test.js rename to packages/e2e-tests/specs/new-post-default-content.test.js diff --git a/packages/e2e-tests/specs/editor/various/new-post.test.js b/packages/e2e-tests/specs/new-post.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/new-post.test.js rename to packages/e2e-tests/specs/new-post.test.js diff --git a/packages/e2e-tests/specs/editor/various/nux.test.js b/packages/e2e-tests/specs/nux.test.js similarity index 56% rename from packages/e2e-tests/specs/editor/various/nux.test.js rename to packages/e2e-tests/specs/nux.test.js index d3ca54af511763..659263cea35335 100644 --- a/packages/e2e-tests/specs/editor/various/nux.test.js +++ b/packages/e2e-tests/specs/nux.test.js @@ -2,7 +2,10 @@ * WordPress dependencies */ import { + clickBlockAppender, + clickOnMoreMenuItem, createNewPost, + saveDraft, toggleScreenOption, } from '@wordpress/e2e-test-utils'; @@ -107,4 +110,71 @@ describe( 'New User Experience (NUX)', () => { areTipsEnabled = await getTipsEnabled( page ); expect( areTipsEnabled ).toEqual( true ); } ); + + // TODO: This test should be enabled once + // https://github.com/WordPress/gutenberg/issues/7458 is fixed. + it.skip( 'should show tips as disabled if all tips have been shown', async () => { + await clickAllTips( page ); + + // Open the "More" menu to check the "Show Tips" element. + await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' ); + const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="false"]' ); + + expect( showTipsButton ).toHaveLength( 1 ); + } ); + + // TODO: This test should be enabled once + // https://github.com/WordPress/gutenberg/issues/7458 is fixed. + it.skip( 'should reset tips if all tips have been shown and show tips was unchecked', async () => { + const { numberOfTips } = await clickAllTips( page ); + + // Click again to re-enable tips; they should appear. + await clickOnMoreMenuItem( 'Show Tips' ); + + // Open the "More" menu to check the "Show Tips" element. + await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' ); + const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="true"]' ); + + expect( showTipsButton ).toHaveLength( 1 ); + + // Tips should re-appear on the page. + const nuxTipElements = await page.$$( '.nux-dot-tip' ); + expect( nuxTipElements ).toHaveLength( 1 ); + + // Tips should be enabled again. + const areTipsEnabled = await getTipsEnabled( page ); + expect( areTipsEnabled ).toEqual( true ); + + // Dismissed tips should be reset and ready to be shown again. + const resetTips = await getTips( page ); + const newNumberOfTips = resetTips.tipIds.length; + expect( newNumberOfTips ).toHaveLength( numberOfTips ); + } ); + + // TODO: This test should be enabled once + // https://github.com/WordPress/gutenberg/issues/7753 is fixed. + // See: https://github.com/WordPress/gutenberg/issues/7753#issuecomment-403952816 + it.skip( 'should show tips if "Show tips" was disabled on a draft and then enabled', async () => { + // Click the "Show tips" button (enabled by default) to disable tips. + await clickOnMoreMenuItem( 'Show Tips' ); + + // Let's type something so there's content in this post. + await page.click( '.editor-post-title__input' ); + await page.keyboard.type( 'Post title' ); + await clickBlockAppender(); + await page.keyboard.type( 'Post content goes here.' ); + await saveDraft(); + + // Refresh the page; tips should be disabled. + await page.reload(); + let nuxTipElements = await page.$$( '.nux-dot-tip' ); + expect( nuxTipElements ).toHaveLength( 0 ); + + // Clicking should re-enable tips. + await clickOnMoreMenuItem( 'Show Tips' ); + + // Tips should re-appear on the page. + nuxTipElements = await page.$$( '.nux-dot-tip' ); + expect( nuxTipElements ).toHaveLength( 1 ); + } ); } ); diff --git a/packages/e2e-tests/specs/performance/performance.test.js b/packages/e2e-tests/specs/performance.test.js similarity index 95% rename from packages/e2e-tests/specs/performance/performance.test.js rename to packages/e2e-tests/specs/performance.test.js index 6246dfb4dc0d38..174bf2c6ab1301 100644 --- a/packages/e2e-tests/specs/performance/performance.test.js +++ b/packages/e2e-tests/specs/performance.test.js @@ -20,7 +20,7 @@ function readFile( filePath ) { describe( 'Performance', () => { it( '1000 paragraphs', async () => { - const html = readFile( join( __dirname, '../../assets/large-post.html' ) ); + const html = readFile( join( __dirname, '../assets/large-post.html' ) ); await createNewPost(); await page.evaluate( ( _html ) => { diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/align-hook.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/align-hook.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/container-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/container-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/cpt-locking.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/cpt-locking.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/deprecated-node-matcher.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/deprecated-node-matcher.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/deprecated-node-matcher.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/deprecated-node-matcher.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/format-api.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/format-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/format-api.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/format-api.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/hooks-api.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/hooks-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/hooks-api.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/hooks-api.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/meta-attribute-block.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/meta-attribute-block.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/meta-attribute-block.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/meta-attribute-block.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/plugins-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/plugins-api.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/templates.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/templates.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap b/packages/e2e-tests/specs/plugins/__snapshots__/wp-editor-meta-box.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap rename to packages/e2e-tests/specs/plugins/__snapshots__/wp-editor-meta-box.test.js.snap diff --git a/packages/e2e-tests/specs/editor/plugins/align-hook.test.js b/packages/e2e-tests/specs/plugins/align-hook.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/align-hook.test.js rename to packages/e2e-tests/specs/plugins/align-hook.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/allowed-blocks.test.js b/packages/e2e-tests/specs/plugins/allowed-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/allowed-blocks.test.js rename to packages/e2e-tests/specs/plugins/allowed-blocks.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/annotations.test.js b/packages/e2e-tests/specs/plugins/annotations.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/annotations.test.js rename to packages/e2e-tests/specs/plugins/annotations.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/block-icons.test.js b/packages/e2e-tests/specs/plugins/block-icons.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/block-icons.test.js rename to packages/e2e-tests/specs/plugins/block-icons.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/container-blocks.test.js b/packages/e2e-tests/specs/plugins/container-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/container-blocks.test.js rename to packages/e2e-tests/specs/plugins/container-blocks.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/cpt-locking.test.js b/packages/e2e-tests/specs/plugins/cpt-locking.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/cpt-locking.test.js rename to packages/e2e-tests/specs/plugins/cpt-locking.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js b/packages/e2e-tests/specs/plugins/custom-taxonomies.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js rename to packages/e2e-tests/specs/plugins/custom-taxonomies.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/deprecated-node-matcher.test.js b/packages/e2e-tests/specs/plugins/deprecated-node-matcher.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/deprecated-node-matcher.test.js rename to packages/e2e-tests/specs/plugins/deprecated-node-matcher.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/format-api.test.js b/packages/e2e-tests/specs/plugins/format-api.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/format-api.test.js rename to packages/e2e-tests/specs/plugins/format-api.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/hooks-api.test.js b/packages/e2e-tests/specs/plugins/hooks-api.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/hooks-api.test.js rename to packages/e2e-tests/specs/plugins/hooks-api.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/inner-blocks-allowed-blocks.test.js b/packages/e2e-tests/specs/plugins/inner-blocks-allowed-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/inner-blocks-allowed-blocks.test.js rename to packages/e2e-tests/specs/plugins/inner-blocks-allowed-blocks.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/innerblocks-locking-all-embed.js b/packages/e2e-tests/specs/plugins/innerblocks-locking-all-embed.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/innerblocks-locking-all-embed.js rename to packages/e2e-tests/specs/plugins/innerblocks-locking-all-embed.js diff --git a/packages/e2e-tests/specs/editor/plugins/meta-attribute-block.test.js b/packages/e2e-tests/specs/plugins/meta-attribute-block.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/meta-attribute-block.test.js rename to packages/e2e-tests/specs/plugins/meta-attribute-block.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js b/packages/e2e-tests/specs/plugins/meta-boxes.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js rename to packages/e2e-tests/specs/plugins/meta-boxes.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/nonce.test.js b/packages/e2e-tests/specs/plugins/nonce.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/nonce.test.js rename to packages/e2e-tests/specs/plugins/nonce.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/plugins-api.test.js b/packages/e2e-tests/specs/plugins/plugins-api.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/plugins-api.test.js rename to packages/e2e-tests/specs/plugins/plugins-api.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/templates.test.js b/packages/e2e-tests/specs/plugins/templates.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/plugins/templates.test.js rename to packages/e2e-tests/specs/plugins/templates.test.js diff --git a/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js b/packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js similarity index 76% rename from packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js rename to packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js index 32286764092f17..74dd45374e946d 100644 --- a/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js +++ b/packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js @@ -8,7 +8,9 @@ import { publishPost, } from '@wordpress/e2e-test-utils'; -describe( 'WP Editor Meta Boxes', () => { +// This test isn't reliable on Travis and fails from time to time. +// See: https://github.com/WordPress/gutenberg/pull/15211. +describe.skip( 'WP Editor Meta Boxes', () => { beforeAll( async () => { await activatePlugin( 'gutenberg-test-plugin-wp-editor-meta-box' ); await createNewPost(); @@ -23,7 +25,7 @@ describe( 'WP Editor Meta Boxes', () => { await page.type( '.editor-post-title__input', 'Hello Meta' ); // Type something - await expect( page ).toClick( '#test_tinymce_id-html' ); + await page.click( '#test_tinymce_id-html' ); await page.type( '#test_tinymce_id', 'Typing in a metabox' ); await page.click( '#test_tinymce_id-tmce' ); @@ -31,8 +33,7 @@ describe( 'WP Editor Meta Boxes', () => { await page.reload(); - await expect( page ).toClick( '#test_tinymce_id-html' ); - await page.waitForSelector( '#test_tinymce_id' ); + await page.click( '#test_tinymce_id-html' ); const content = await page.$eval( '#test_tinymce_id', ( textarea ) => textarea.value diff --git a/packages/e2e-tests/specs/editor/various/popovers.test.js b/packages/e2e-tests/specs/popovers.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/popovers.test.js rename to packages/e2e-tests/specs/popovers.test.js diff --git a/packages/e2e-tests/specs/editor/various/post-visibility.test.js b/packages/e2e-tests/specs/post-visibility.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/post-visibility.test.js rename to packages/e2e-tests/specs/post-visibility.test.js diff --git a/packages/e2e-tests/specs/editor/various/preferences.test.js b/packages/e2e-tests/specs/preferences.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/preferences.test.js rename to packages/e2e-tests/specs/preferences.test.js diff --git a/packages/e2e-tests/specs/editor/various/preview.test.js b/packages/e2e-tests/specs/preview.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/preview.test.js rename to packages/e2e-tests/specs/preview.test.js diff --git a/packages/e2e-tests/specs/editor/various/publish-button.test.js b/packages/e2e-tests/specs/publish-button.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/publish-button.test.js rename to packages/e2e-tests/specs/publish-button.test.js diff --git a/packages/e2e-tests/specs/editor/various/publish-panel.test.js b/packages/e2e-tests/specs/publish-panel.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/publish-panel.test.js rename to packages/e2e-tests/specs/publish-panel.test.js diff --git a/packages/e2e-tests/specs/editor/various/publishing.test.js b/packages/e2e-tests/specs/publishing.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/publishing.test.js rename to packages/e2e-tests/specs/publishing.test.js diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/reusable-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/reusable-blocks.test.js rename to packages/e2e-tests/specs/reusable-blocks.test.js diff --git a/packages/e2e-tests/specs/editor/various/rich-text.test.js b/packages/e2e-tests/specs/rich-text.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/rich-text.test.js rename to packages/e2e-tests/specs/rich-text.test.js diff --git a/packages/e2e-tests/specs/editor/various/rtl.test.js b/packages/e2e-tests/specs/rtl.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/rtl.test.js rename to packages/e2e-tests/specs/rtl.test.js diff --git a/packages/e2e-tests/specs/editor/various/scheduling.test.js b/packages/e2e-tests/specs/scheduling.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/scheduling.test.js rename to packages/e2e-tests/specs/scheduling.test.js diff --git a/packages/e2e-tests/specs/editor/various/shortcut-help.test.js b/packages/e2e-tests/specs/shortcut-help.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/shortcut-help.test.js rename to packages/e2e-tests/specs/shortcut-help.test.js diff --git a/packages/e2e-tests/specs/editor/various/sidebar-permalink-panel.test.js b/packages/e2e-tests/specs/sidebar-permalink-panel.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/sidebar-permalink-panel.test.js rename to packages/e2e-tests/specs/sidebar-permalink-panel.test.js diff --git a/packages/e2e-tests/specs/editor/various/sidebar.test.js b/packages/e2e-tests/specs/sidebar.test.js similarity index 99% rename from packages/e2e-tests/specs/editor/various/sidebar.test.js rename to packages/e2e-tests/specs/sidebar.test.js index c86900f308f1e1..d0768f916f0f63 100644 --- a/packages/e2e-tests/specs/editor/various/sidebar.test.js +++ b/packages/e2e-tests/specs/sidebar.test.js @@ -91,7 +91,6 @@ describe( 'Sidebar', () => { await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); - await pressKeyWithModifier( 'ctrl', '`' ); // Tab lands at first (presumed selected) option "Document". await page.keyboard.press( 'Tab' ); diff --git a/packages/e2e-tests/specs/editor/various/splitting-merging.test.js b/packages/e2e-tests/specs/splitting-merging.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/splitting-merging.test.js rename to packages/e2e-tests/specs/splitting-merging.test.js diff --git a/packages/e2e-tests/specs/editor/various/style-variation.test.js b/packages/e2e-tests/specs/style-variation.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/style-variation.test.js rename to packages/e2e-tests/specs/style-variation.test.js diff --git a/packages/e2e-tests/specs/editor/various/taxonomies.test.js b/packages/e2e-tests/specs/taxonomies.test.js similarity index 83% rename from packages/e2e-tests/specs/editor/various/taxonomies.test.js rename to packages/e2e-tests/specs/taxonomies.test.js index 4ed0ef3945fe61..791fd79b12f8d4 100644 --- a/packages/e2e-tests/specs/editor/various/taxonomies.test.js +++ b/packages/e2e-tests/specs/taxonomies.test.js @@ -1,14 +1,9 @@ -/** - * External dependencies - */ -import { random } from 'lodash'; - /** * WordPress dependencies */ import { - createNewPost, findSidebarPanelWithTitle, + createNewPost, openDocumentSettingsSidebar, publishPost, } from '@wordpress/e2e-test-utils'; @@ -55,25 +50,22 @@ describe( 'Taxonomies', () => { }, tagsPanel, TAG_TOKEN_SELECTOR ); }; - const openSidebarPanelWithTitle = async ( title ) => { - const panel = await page.waitForXPath( - `//div[contains(@class,"edit-post-sidebar")]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ title }")]` - ); - await panel.click(); - }; - it( 'should be able to open the categories panel and create a new main category if the user has the right capabilities', async () => { await createNewPost(); await openDocumentSettingsSidebar(); - await openSidebarPanelWithTitle( 'Categories' ); + const categoriesPanel = await findSidebarPanelWithTitle( 'Categories' ); + expect( categoriesPanel ).toBeDefined(); // If the user has no permission to add a new category finish the test. if ( ! ( await canCreatTermInTaxonomy( 'categories' ) ) ) { return; } + // Open the categories panel. + await categoriesPanel.click( 'button' ); + await page.waitForSelector( 'button.editor-post-taxonomies__hierarchical-terms-add' ); // Click add new category button. @@ -116,18 +108,27 @@ describe( 'Taxonomies', () => { expect( selectedCategories[ 0 ] ).toEqual( 'z rand category 1' ); } ); - it( 'should be able to open the tags panel and create a new tag if the user has the right capabilities', async () => { + // This test isn't reliable locally because repeated execution of the test triggers 400 network + // because of the tag's duplication. Also, it randomly doesn't add a new tag after pressing enter. + // See: https://github.com/WordPress/gutenberg/pull/15211. + it.skip( 'should be able to open the tags panel and create a new tag if the user has the right capabilities', async () => { await createNewPost(); await openDocumentSettingsSidebar(); - await openSidebarPanelWithTitle( 'Tags' ); + const tagsPanel = await findSidebarPanelWithTitle( 'Tags' ); + + //expect( await page.evaluate( ( el ) => el.outerHTML, tagsPanel ) ).toEqual( 'tag1 ok' ); + expect( tagsPanel ).toBeDefined(); // If the user has no permission to add a new tag finish the test. if ( ! ( await canCreatTermInTaxonomy( 'tags' ) ) ) { return; } + // Open the tags panel. + await tagsPanel.click( 'button' ); + // At the start there are no tag tokens expect( await page.$$( @@ -135,16 +136,13 @@ describe( 'Taxonomies', () => { ) ).toHaveLength( 0 ); - const tagsPanel = await findSidebarPanelWithTitle( 'Tags' ); const tagInput = await tagsPanel.$( '.components-form-token-field__input' ); // Click the tag input field. await tagInput.click(); - const tagName = 'tag-' + random( 1, Number.MAX_SAFE_INTEGER ); - // Type the category name in the field. - await tagInput.type( tagName ); + await tagInput.type( 'tag1' ); // Press enter to create a new tag. await tagInput.press( 'Enter' ); @@ -156,7 +154,7 @@ describe( 'Taxonomies', () => { // The post should only contain the tag we added. expect( tags ).toHaveLength( 1 ); - expect( tags[ 0 ] ).toEqual( tagName ); + expect( tags[ 0 ] ).toEqual( 'tag1' ); // Type something in the title so we can publish the post. await page.type( '.editor-post-title__input', 'Hello World' ); @@ -174,6 +172,6 @@ describe( 'Taxonomies', () => { // The tag selection was persisted after the publish process. expect( tags ).toHaveLength( 1 ); - expect( tags[ 0 ] ).toEqual( tagName ); + expect( tags[ 0 ] ).toEqual( 'tag1' ); } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/typewriter.test.js b/packages/e2e-tests/specs/typewriter.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/typewriter.test.js rename to packages/e2e-tests/specs/typewriter.test.js diff --git a/packages/e2e-tests/specs/editor/various/undo.test.js b/packages/e2e-tests/specs/undo.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/undo.test.js rename to packages/e2e-tests/specs/undo.test.js diff --git a/packages/e2e-tests/specs/editor/various/writing-flow.test.js b/packages/e2e-tests/specs/writing-flow.test.js similarity index 100% rename from packages/e2e-tests/specs/editor/various/writing-flow.test.js rename to packages/e2e-tests/specs/writing-flow.test.js diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index c1d1576e310bc5..69dd699b23426e 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -1,4 +1,4 @@ -## 3.8.2 +## Master ### Bug Fixes diff --git a/packages/edit-post/README.md b/packages/edit-post/README.md index 0a9441a55b101f..3b7b01a53e6dd3 100644 --- a/packages/edit-post/README.md +++ b/packages/edit-post/README.md @@ -92,13 +92,13 @@ _Parameters_ - _props_ `Object`: Component props. - _props.allowedBlocks_ `[Array]`: An array containing a list of block names for which the item should be shown. If not present, it'll be rendered for any block. If multiple blocks are selected, it'll be shown if and only if all of them are in the whitelist. -- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. +- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. - _props.label_ `string`: The menu item text. - _props.onClick_ `Function`: Callback function to be executed when the user click the menu item. _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: The WPElement to be rendered. <a name="PluginDocumentSettingPanel" href="#PluginDocumentSettingPanel">#</a> **PluginDocumentSettingPanel** @@ -149,11 +149,11 @@ _Parameters_ - _props.name_ `[string]`: The machine-friendly name for the panel. - _props.className_ `[string]`: An optional class name added to the row. - _props.title_ `[string]`: The title of the panel -- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: The WPElement to be rendered. <a name="PluginMoreMenuItem" href="#PluginMoreMenuItem">#</a> **PluginMoreMenuItem** @@ -206,13 +206,13 @@ _Parameters_ - _props_ `Object`: Component properties. - _props.href_ `[string]`: When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor. -- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. +- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. - _props.onClick_ `[Function]`: The callback function to be executed when the user clicks the menu item. - _props.other_ `[...*]`: Any additional props are passed through to the underlying [MenuItem](/packages/components/src/menu-item/README.md) component. _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: The element to be rendered. <a name="PluginPostPublishPanel" href="#PluginPostPublishPanel">#</a> **PluginPostPublishPanel** @@ -261,11 +261,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the panel. - _props.title_ `[string]`: Title displayed at the top of the panel. - _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened. -- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: The WPElement to be rendered. <a name="PluginPostStatusInfo" href="#PluginPostStatusInfo">#</a> **PluginPostStatusInfo** @@ -312,7 +312,7 @@ _Parameters_ _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: The WPElement to be rendered. <a name="PluginPrePublishPanel" href="#PluginPrePublishPanel">#</a> **PluginPrePublishPanel** @@ -361,11 +361,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the panel. - _props.title_ `[string]`: Title displayed at the top of the panel. - _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened. -- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: The WPElement to be rendered. <a name="PluginSidebar" href="#PluginSidebar">#</a> **PluginSidebar** @@ -432,11 +432,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the sidebar body. - _props.title_ `string`: Title displayed at the top of the sidebar. - _props.isPinnable_ `[boolean]`: Whether to allow to pin sidebar to toolbar. -- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPComponent`: Plugin sidebar component. +- `WPElement`: Plugin sidebar component. <a name="PluginSidebarMoreMenuItem" href="#PluginSidebarMoreMenuItem">#</a> **PluginSidebarMoreMenuItem** @@ -482,11 +482,11 @@ _Parameters_ - _props_ `Object`: Component props. - _props.target_ `string`: A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar. -- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. +- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: The element to be rendered. <a name="reinitializeEditor" href="#reinitializeEditor">#</a> **reinitializeEditor** diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json index a73c2d52ac105b..98fd08247be8f0 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "3.8.3", + "version": "3.8.0", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js index 938805e057406b..8503692c289b07 100644 --- a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js +++ b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js @@ -35,7 +35,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => ! Array.isArray( a * * @param {Object} props Component props. * @param {Array} [props.allowedBlocks] An array containing a list of block names for which the item should be shown. If not present, it'll be rendered for any block. If multiple blocks are selected, it'll be shown if and only if all of them are in the whitelist. - * @param {WPBlockTypeIconRender} [props.icon] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. + * @param {string|Element} [props.icon] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. * @param {string} props.label The menu item text. * @param {Function} props.onClick Callback function to be executed when the user click the menu item. * @@ -81,7 +81,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => ! Array.isArray( a * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} The WPElement to be rendered. */ const PluginBlockSettingsMenuItem = ( { allowedBlocks, icon, label, onClick, small, role } ) => ( <PluginBlockSettingsMenuGroup> diff --git a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js index 08a5bef83b35eb..e29ec22e90a208 100644 --- a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js @@ -32,7 +32,7 @@ const PluginMoreMenuItem = ( { onClick = noop, ...props } ) => ( * * @param {Object} props Component properties. * @param {string} [props.href] When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor. - * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. + * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. * @param {Function} [props.onClick=noop] The callback function to be executed when the user clicks the menu item. * @param {...*} [props.other] Any additional props are passed through to the underlying [MenuItem](/packages/components/src/menu-item/README.md) component. * @@ -78,7 +78,7 @@ const PluginMoreMenuItem = ( { onClick = noop, ...props } ) => ( * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} The element to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js index c1f4ff42ae98aa..e1849f2e7890ed 100644 --- a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js @@ -28,7 +28,7 @@ const PluginSidebarMoreMenuItem = ( { children, icon, isSelected, onClick } ) => * * @param {Object} props Component props. * @param {string} props.target A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar. - * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. + * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. * * @example <caption>ES5</caption> * ```js @@ -64,7 +64,7 @@ const PluginSidebarMoreMenuItem = ( { children, icon, isSelected, onClick } ) => * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} The element to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index 65a94ba8ad72d0..64699eeab73a2d 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -91,7 +91,7 @@ &.editor-post-publish-button, &.editor-post-publish-panel__toggle { margin: 2px; - height: 34px; + height: 33px; line-height: 32px; font-size: $default-font-size; } @@ -105,17 +105,13 @@ } } - // These paddings actually duplicate existing rules from button component. - // But they are duplicated so as to provide smaller paddings to fit the buttons on mobile. &.editor-post-preview, &.editor-post-publish-button, &.editor-post-publish-panel__toggle { - padding-left: 5px; - padding-right: 5px; + padding: 0 5px 2px; @include break-small() { - padding-left: 12px; - padding-right: 12px; + padding: 0 12px 2px; } } diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index b8cb779603410c..e29011c8cec529 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -21,7 +21,6 @@ import { EditorNotices, PostPublishPanel, } from '@wordpress/editor'; -import { BlockBreadcrumb } from '@wordpress/block-editor'; import { withDispatch, withSelect } from '@wordpress/data'; import { PluginArea } from '@wordpress/plugins'; import { withViewportMatch } from '@wordpress/viewport'; @@ -60,7 +59,7 @@ function Layout( { } ) { const sidebarIsOpened = editorSidebarOpened || pluginSidebarOpened || publishSidebarOpened; - const className = classnames( 'edit-post-layout', 'is-mode-' + mode, { + const className = classnames( 'edit-post-layout', { 'is-sidebar-opened': sidebarIsOpened, 'has-fixed-toolbar': hasFixedToolbar, 'has-metaboxes': hasActiveMetaboxes, @@ -81,7 +80,7 @@ function Layout( { <LocalAutosaveMonitor /> <Header /> <div - className="edit-post-layout__content edit-post-layout__scrollable-container" + className="edit-post-layout__content" role="region" /* translators: accessibility text for the content landmark region. */ aria-label={ __( 'Editor content' ) } @@ -100,19 +99,7 @@ function Layout( { <div className="edit-post-layout__metaboxes"> <MetaBoxes location="advanced" /> </div> - { isMobileViewport && sidebarIsOpened && <ScrollLock /> } </div> - { isRichEditingEnabled && mode === 'visual' && ( - <div - className="edit-post-layout__footer" - role="region" - /* translators: accessibility text for the content landmark region. */ - aria-label={ __( 'Editor footer' ) } - tabIndex="-1" - > - <BlockBreadcrumb /> - </div> - ) } { publishSidebarOpened ? ( <PostPublishPanel { ...publishLandmarkProps } @@ -137,6 +124,9 @@ function Layout( { </div> <SettingsSidebar /> <Sidebar.Slot /> + { + isMobileViewport && sidebarIsOpened && <ScrollLock /> + } </> ) } <Popover.Slot /> diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss index 40e49f9df3b355..43996d98f8c8f0 100644 --- a/packages/edit-post/src/components/layout/style.scss +++ b/packages/edit-post/src/components/layout/style.scss @@ -54,7 +54,7 @@ // Because the body element scrolls the navigation sidebar, we have to use position fixed here. // Otherwise you would scroll the editing canvas out of view when you scroll the sidebar. position: fixed; - bottom: $footer-height; + bottom: 0; left: 0; right: 0; @@ -70,12 +70,6 @@ // Because we are beyond the medium breakpoint, we only have to worry about folded, auto-folded, and default. margin-left: $admin-sidebar-width; - // Make room for the footer - .edit-post-layout.is-mode-visual & { - bottom: $footer-height; - min-height: calc(100% - #{ $header-height + $admin-bar-height + $footer-height }); - } - // Auto fold is when on smaller breakpoints, nav menu auto colllapses. body.auto-fold & { margin-left: $admin-sidebar-width-collapsed; @@ -110,6 +104,31 @@ } } + // Pad the scroll box so content on the bottom can be scrolled up. + padding-bottom: 50vh; + @include break-small { + padding-bottom: 0; + } + + // On mobile the main content (html or body) area has to scroll. + // If, like we do on the desktop, scroll an element (.edit-post-layout__content) you can invoke + // the overscroll bounce on the non-scrolling container, causing for a frustrating scrolling experience. + // The following rule enables this scrolling beyond the mobile breakpoint, because on the desktop + // breakpoints scrolling an isolated element helps avoid scroll bleed. + @include break-small() { + overflow-y: auto; + } + -webkit-overflow-scrolling: touch; + + // This rule ensures that if you've scrolled to the end of a container, + // then pause, then keep scrolling downwards, the browser doesn't try to scroll + // the parent element, usually invoking a "bounce" effect and then preventing you + // from scrolling upwards until you pause again. + // This is only necessary beyond the small breakpoint because that's when the scroll container changes. + @include break-small() { + overscroll-behavior-y: none; + } + .edit-post-visual-editor { flex: 1 1 auto; @@ -215,51 +234,3 @@ } } } - -.edit-post-layout__footer { - display: none; - z-index: z-index(".edit-post-layout__footer"); - - // Stretch to mimic outline padding on desktop. - @include break-medium() { - display: flex; - position: fixed; - bottom: 0; - right: 0; - background: $white; - height: $footer-height; - padding: 0 $grid-size; - align-items: center; - border-top: $border-width solid $light-gray-500; - font-size: $default-font-size; - box-sizing: border-box; - } -} -@include editor-left(".edit-post-layout__footer"); - -.edit-post-layout__scrollable-container { - // On mobile the main content (html or body) area has to scroll. - // If, like we do on the desktop, scroll an element (.edit-post-layout__content) you can invoke - // the overscroll bounce on the non-scrolling container, causing for a frustrating scrolling experience. - // The following rule enables this scrolling beyond the mobile breakpoint, because on the desktop - // breakpoints scrolling an isolated element helps avoid scroll bleed. - @include break-small() { - overflow-y: auto; - } - -webkit-overflow-scrolling: touch; - - // This rule ensures that if you've scrolled to the end of a container, - // then pause, then keep scrolling downwards, the browser doesn't try to scroll - // the parent element, usually invoking a "bounce" effect and then preventing you - // from scrolling upwards until you pause again. - // This is only necessary beyond the small breakpoint because that's when the scroll container changes. - @include break-small() { - overscroll-behavior-y: none; - } - - // Pad the scroll box so content on the bottom can be scrolled up. - padding-bottom: 50vh; - @include break-small { - padding-bottom: 0; - } -} diff --git a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss index 184835a024c35c..b86d15952683b0 100644 --- a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss +++ b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss @@ -81,25 +81,6 @@ .is-hidden { display: none; } - - - // Until checkboxes WordPress-wide are updated to match the new style, - // checkboxes used in metaboxes have to be slightly unstyled here. - // @todo: remove this entire rule once checkboxes are the same everywhere. - // See: https://github.com/WordPress/gutenberg/issues/18053 - .postbox-container .postbox input[type="checkbox"], - .postbox-container .postbox input[type="radio"] { - border: $border-width solid $dark-gray-300; - - &:checked { - background: $white; - border-color: $dark-gray-300; - } - - &::before { - margin: -3px -4px; - } - } } .edit-post-meta-boxes-area__clear { diff --git a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js index 62a651c7f0c24e..ef10b4ed77ef30 100644 --- a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js @@ -48,7 +48,7 @@ const PluginDocumentSettingFill = ( { isEnabled, panelName, opened, onToggle, cl * @param {string} [props.name] The machine-friendly name for the panel. * @param {string} [props.className] An optional class name added to the row. * @param {string} [props.title] The title of the panel - * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -89,7 +89,7 @@ const PluginDocumentSettingFill = ( { isEnabled, panelName, opened, onToggle, cl * registerPlugin( 'document-setting-test', { render: MyDocumentSettingTest } ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} The WPElement to be rendered. */ const PluginDocumentSettingPanel = compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js index b1c53372857023..a84124905d7d46 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js @@ -27,7 +27,7 @@ const PluginPostPublishPanelFill = ( { children, className, title, initialOpen = * @param {string} [props.className] An optional class name added to the panel. * @param {string} [props.title] Title displayed at the top of the panel. * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. When no title is provided it is always opened. - * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -65,7 +65,7 @@ const PluginPostPublishPanelFill = ( { children, className, title, initialOpen = * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} The WPElement to be rendered. */ const PluginPostPublishPanel = compose( diff --git a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js b/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js index 2d149639130eda..e099fa232e84f6 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js @@ -49,7 +49,7 @@ export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' ); * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} The WPElement to be rendered. */ const PluginPostStatusInfo = ( { children, className } ) => ( <Fill> diff --git a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js index 13863b24f16d50..4a3b02fba2803b 100644 --- a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js @@ -18,19 +18,16 @@ const PluginPrePublishPanelFill = ( { children, className, title, initialOpen = </PanelBody> </Fill> ); - /** * Renders provided content to the pre-publish side panel in the publish flow * (side panel that opens when a user first pushes "Publish" from the main editor). * - * @param {Object} props Component props. - * @param {string} [props.className] An optional class name added to the panel. - * @param {string} [props.title] Title displayed at the top of the panel. - * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. - * When no title is provided it is always opened. - * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) - * icon slug string, or an SVG WP element, to be rendered when - * the sidebar is pinned to toolbar. + * @param {Object} props Component props. + * @param {string} [props.className] An optional class name added to the panel. + * @param {string} [props.title] Title displayed at the top of the panel. + * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. When no title is provided it is always opened. + * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * * @example <caption>ES5</caption> * ```js @@ -68,7 +65,7 @@ const PluginPrePublishPanelFill = ( { children, className, title, initialOpen = * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} The WPElement to be rendered. */ const PluginPrePublishPanel = compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js index 7c03f172b009fb..5303de703b30b9 100644 --- a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js @@ -82,7 +82,7 @@ function PluginSidebar( props ) { * @param {string} [props.className] An optional class name added to the sidebar body. * @param {string} props.title Title displayed at the top of the sidebar. * @param {boolean} [props.isPinnable=true] Whether to allow to pin sidebar to toolbar. - * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -129,7 +129,7 @@ function PluginSidebar( props ) { * ); * ``` * - * @return {WPComponent} Plugin sidebar component. + * @return {WPElement} Plugin sidebar component. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/post-slug/index.js b/packages/edit-post/src/components/sidebar/post-slug/index.js deleted file mode 100644 index fe539a38decce6..00000000000000 --- a/packages/edit-post/src/components/sidebar/post-slug/index.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * WordPress dependencies - */ -import { PanelRow } from '@wordpress/components'; -import { PostSlug as PostSlugForm, PostSlugCheck } from '@wordpress/editor'; - -export function PostSlug() { - return ( - <PostSlugCheck> - <PanelRow> - <PostSlugForm /> - </PanelRow> - </PostSlugCheck> - ); -} - -export default PostSlug; diff --git a/packages/edit-post/src/components/sidebar/post-slug/style.scss b/packages/edit-post/src/components/sidebar/post-slug/style.scss deleted file mode 100644 index b031424164dcec..00000000000000 --- a/packages/edit-post/src/components/sidebar/post-slug/style.scss +++ /dev/null @@ -1,4 +0,0 @@ -.editor-post-slug__input { - margin: -5px 0; - padding: 2px; -} diff --git a/packages/edit-post/src/components/sidebar/post-status/index.js b/packages/edit-post/src/components/sidebar/post-status/index.js index b9d50676f7141a..a3403a8209c9e5 100644 --- a/packages/edit-post/src/components/sidebar/post-status/index.js +++ b/packages/edit-post/src/components/sidebar/post-status/index.js @@ -14,7 +14,6 @@ import PostTrash from '../post-trash'; import PostSchedule from '../post-schedule'; import PostSticky from '../post-sticky'; import PostAuthor from '../post-author'; -import PostSlug from '../post-slug'; import PostFormat from '../post-format'; import PostPendingStatus from '../post-pending-status'; import PluginPostStatusInfo from '../plugin-post-status-info'; @@ -35,7 +34,6 @@ function PostStatus( { isOpened, onTogglePanel } ) { <PostFormat /> <PostSticky /> <PostPendingStatus /> - <PostSlug /> <PostAuthor /> { fills } <PostTrash /> diff --git a/packages/edit-post/src/components/sidebar/style.scss b/packages/edit-post/src/components/sidebar/style.scss index 50ddd2efedbde5..740355cf636f75 100644 --- a/packages/edit-post/src/components/sidebar/style.scss +++ b/packages/edit-post/src/components/sidebar/style.scss @@ -22,10 +22,6 @@ @include break-medium() { top: $admin-bar-height + $header-height; - .edit-post-layout.is-mode-visual & { - bottom: $footer-height; - } - body.is-fullscreen-mode & { top: $header-height; } diff --git a/packages/edit-post/src/components/text-editor/style.scss b/packages/edit-post/src/components/text-editor/style.scss index f7696bb4ee1959..234eb46917b247 100644 --- a/packages/edit-post/src/components/text-editor/style.scss +++ b/packages/edit-post/src/components/text-editor/style.scss @@ -1,5 +1,30 @@ +.edit-post-text-editor__body { + padding-top: $grid-size * 5; + + @include break-small() { + padding-top: ($grid-size * 5) + $admin-bar-height-big; + } + + @include break-medium() { + padding-top: $grid-size * 5; + + body.is-fullscreen-mode & { + padding-top: $grid-size * 5; + } + } +} + .edit-post-text-editor { width: 100%; + max-width: calc(100% - #{$grid-size-large * 2}); + margin-left: $grid-size-large; + margin-right: $grid-size-large; + + @include break-small() { + max-width: $content-width; + margin-left: auto; + margin-right: auto; + } // Always show outlines in code editor .editor-post-title__block { @@ -42,41 +67,34 @@ } } + .editor-post-text-editor { + padding: $block-padding; + min-height: 200px; + line-height: 1.8; + } + // Make room for toolbar. padding-top: $block-controls-height + $grid-size; -} - -// Exit Code Editor toolbar. -.edit-post-text-editor__toolbar { - position: absolute; - top: $grid-size; - left: 0; - right: 0; - height: $block-controls-height; - line-height: $block-controls-height; - padding: 0 $grid-size 0 $grid-size-large; - display: flex; - - h2 { - margin: 0 auto 0 0; - font-size: $default-font-size; - color: $dark-gray-500; - } - .components-icon-button svg { - order: 1; - } -} + // Exit Code Editor toolbar. + .edit-post-text-editor__toolbar { + position: absolute; + top: $grid-size; + left: 0; + right: 0; + height: $block-controls-height; + line-height: $block-controls-height; + padding: 0 $grid-size 0 $grid-size-large; + display: flex; -.edit-post-text-editor__body { - max-width: calc(100% - #{$grid-size-large * 2}); - margin-left: $grid-size-large; - margin-right: $grid-size-large; - padding-top: $grid-size * 5; + h2 { + margin: 0 auto 0 0; + font-size: $default-font-size; + color: $dark-gray-500; + } - @include break-small() { - max-width: $content-width; - margin-left: auto; - margin-right: auto; + .components-icon-button svg { + order: 1; + } } } diff --git a/packages/edit-post/src/hooks/validate-multiple-use/index.js b/packages/edit-post/src/hooks/validate-multiple-use/index.js index 54a502603c2064..ea2958949f7e2d 100644 --- a/packages/edit-post/src/hooks/validate-multiple-use/index.js +++ b/packages/edit-post/src/hooks/validate-multiple-use/index.js @@ -28,9 +28,9 @@ const enhance = compose( * "original" block is not the current one. Thus, an inexisting * `originalBlockClientId` prop signals that the block is valid. * - * @param {WPComponent} WrappedBlockEdit A filtered BlockEdit instance. + * @param {Component} WrappedBlockEdit A filtered BlockEdit instance. * - * @return {WPComponent} Enhanced component with merged state data props. + * @return {Component} Enhanced component with merged state data props. */ withSelect( ( select, block ) => { const multiple = hasBlockSupport( block.name, 'multiple', true ); diff --git a/packages/edit-post/src/store/selectors.js b/packages/edit-post/src/store/selectors.js index fff04ac721fe37..2430ee41087232 100644 --- a/packages/edit-post/src/store/selectors.js +++ b/packages/edit-post/src/store/selectors.js @@ -78,9 +78,9 @@ export function getPreferences( state ) { * * @param {Object} state Global application state. * @param {string} preferenceKey Preference Key. - * @param {*} defaultValue Default Value. + * @param {Mixed} defaultValue Default Value. * - * @return {*} Preference Value. + * @return {Mixed} Preference Value. */ export function getPreference( state, preferenceKey, defaultValue ) { const preferences = getPreferences( state ); diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index 94fcfa7ac60fe6..6403380ff54601 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -1,5 +1,3 @@ -$footer-height: $icon-button-size-small; - @import "./components/fullscreen-mode/style.scss"; @import "./components/header/style.scss"; @import "./components/header/fullscreen-mode-close/style.scss"; @@ -15,7 +13,6 @@ $footer-height: $icon-button-size-small; @import "./components/sidebar/post-author/style.scss"; @import "./components/sidebar/post-link/style.scss"; @import "./components/sidebar/post-schedule/style.scss"; -@import "./components/sidebar/post-slug/style.scss"; @import "./components/sidebar/post-status/style.scss"; @import "./components/sidebar/post-visibility/style.scss"; @import "./components/sidebar/settings-header/style.scss"; diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index 37dd6972b49627..e5ba0beff046e2 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "0.7.3", + "version": "0.7.0", "private": true, "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", diff --git a/packages/edit-widgets/src/components/widget-area/index.js b/packages/edit-widgets/src/components/widget-area/index.js index 11e162d2874d9d..e22c880f50cf22 100644 --- a/packages/edit-widgets/src/components/widget-area/index.js +++ b/packages/edit-widgets/src/components/widget-area/index.js @@ -42,7 +42,7 @@ function getBlockEditorSettings( blockEditorSettings, hasUploadPermissions ) { }; return { ...blockEditorSettings, - mediaUpload: mediaUploadBlockEditor, + __experimentalMediaUpload: mediaUploadBlockEditor, }; } diff --git a/packages/editor/package.json b/packages/editor/package.json index 9ddc2a6d1951ae..22e78a023ca3f6 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "9.7.3", + "version": "9.7.0", "description": "Building blocks for WordPress editors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/editor/src/components/autocompleters/block.js b/packages/editor/src/components/autocompleters/block.js index 5311d01ec2b749..70860643ae096b 100644 --- a/packages/editor/src/components/autocompleters/block.js +++ b/packages/editor/src/components/autocompleters/block.js @@ -27,7 +27,7 @@ function defaultGetBlockInsertionParentClientId() { * @param {string} rootClientId Client ID of the block for which to retrieve * inserter items. * - * @return {Array<WPEditorInserterItem>} The inserter items for the specified + * @return {Array<Editor.InserterItem>} The inserter items for the specified * parent. */ function defaultGetInserterItems( rootClientId ) { @@ -68,7 +68,7 @@ const fetchReusableBlocks = once( () => { /** * Creates a blocks repeater for replacing the current block with a selected block type. * - * @return {WPCompleter} A blocks completer. + * @return {Completer} A blocks completer. */ export function createBlockCompleter( { // Allow store-based selectors to be overridden for unit test. @@ -119,6 +119,6 @@ export function createBlockCompleter( { /** * Creates a blocks repeater for replacing the current block with a selected block type. * - * @return {WPCompleter} A blocks completer. + * @return {Completer} A blocks completer. */ export default createBlockCompleter(); diff --git a/packages/editor/src/components/autocompleters/user.js b/packages/editor/src/components/autocompleters/user.js index 1dea163ee16443..e3965a33f28d6f 100644 --- a/packages/editor/src/components/autocompleters/user.js +++ b/packages/editor/src/components/autocompleters/user.js @@ -6,7 +6,7 @@ import apiFetch from '@wordpress/api-fetch'; /** * A user mentions completer. * - * @type {WPCompleter} + * @type {Completer} */ export default { name: 'users', diff --git a/packages/editor/src/components/index.js b/packages/editor/src/components/index.js index d5af7f4ff443bf..fed6f633ffbfd0 100644 --- a/packages/editor/src/components/index.js +++ b/packages/editor/src/components/index.js @@ -42,8 +42,6 @@ export { default as PostSavedState } from './post-saved-state'; export { default as PostSchedule } from './post-schedule'; export { default as PostScheduleCheck } from './post-schedule/check'; export { default as PostScheduleLabel } from './post-schedule/label'; -export { default as PostSlug } from './post-slug'; -export { default as PostSlugCheck } from './post-slug/check'; export { default as PostSticky } from './post-sticky'; export { default as PostStickyCheck } from './post-sticky/check'; export { default as PostSwitchToDraftButton } from './post-switch-to-draft-button'; diff --git a/packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js b/packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js similarity index 89% rename from packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js rename to packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js index 9fb2cc8105dc0b..d19d76ba42ad84 100644 --- a/packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js +++ b/packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js @@ -7,13 +7,9 @@ import { debounce } from 'lodash'; * WordPress dependencies */ import { __experimentalInserterMenuExtension } from '@wordpress/block-editor'; +import { DownloadableBlocksPanel } from '@wordpress/block-directory'; import { useState } from '@wordpress/element'; -/** - * Internal dependencies - */ -import DownloadableBlocksPanel from '../../components/downloadable-blocks-panel'; - function InserterMenuDownloadableBlocksPanel() { const [ debouncedFilterValue, setFilterValue ] = useState( '' ); diff --git a/packages/editor/src/components/local-autosave-monitor/index.js b/packages/editor/src/components/local-autosave-monitor/index.js index 9dbd94aab5f56d..59be30218f20cd 100644 --- a/packages/editor/src/components/local-autosave-monitor/index.js +++ b/packages/editor/src/components/local-autosave-monitor/index.js @@ -130,12 +130,7 @@ function useAutosavePurge() { const lastIsAutosaving = useRef( isAutosaving ); useEffect( () => { - if ( - ! didError && ( - ( lastIsAutosaving.current && ! isAutosaving ) || - ( lastIsDirty.current && ! isDirty ) - ) - ) { + if ( lastIsAutosaving.current && ! isAutosaving && ! didError ) { localAutosaveClear( postId ); } diff --git a/packages/editor/src/components/post-publish-button/index.js b/packages/editor/src/components/post-publish-button/index.js index ac195d4de86ce6..1513dfbfbb414f 100644 --- a/packages/editor/src/components/post-publish-button/index.js +++ b/packages/editor/src/components/post-publish-button/index.js @@ -113,7 +113,6 @@ export class PostPublishButton extends Component { return ( <div> <Button - isLarge ref={ this.buttonNode } { ...componentProps } > diff --git a/packages/editor/src/components/post-slug/check.js b/packages/editor/src/components/post-slug/check.js deleted file mode 100644 index 6b243bd6b9f641..00000000000000 --- a/packages/editor/src/components/post-slug/check.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Internal dependencies - */ -import PostTypeSupportCheck from '../post-type-support-check'; - -export default function PostSlugCheck( { children } ) { - return ( - <PostTypeSupportCheck supportKeys="slug">{ children }</PostTypeSupportCheck> - ); -} diff --git a/packages/editor/src/components/post-slug/index.js b/packages/editor/src/components/post-slug/index.js deleted file mode 100644 index 9a9b2200e72be0..00000000000000 --- a/packages/editor/src/components/post-slug/index.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * WordPress dependencies - */ -import { withDispatch, withSelect } from '@wordpress/data'; -import { Component } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; -import { withInstanceId, compose } from '@wordpress/compose'; -import { safeDecodeURIComponent } from '@wordpress/url'; - -/** - * Internal dependencies - */ -import PostSlugCheck from './check'; -import { cleanForSlug } from '../../utils/url'; - -export class PostSlug extends Component { - constructor( { postSlug, postTitle, postID } ) { - super( ...arguments ); - - this.state = { - editedSlug: safeDecodeURIComponent( postSlug ) || cleanForSlug( postTitle ) || postID, - }; - - this.setSlug = this.setSlug.bind( this ); - } - - setSlug( event ) { - const { postSlug, onUpdateSlug } = this.props; - const { value } = event.target; - - const editedSlug = cleanForSlug( value ); - - if ( editedSlug === postSlug ) { - return; - } - - onUpdateSlug( editedSlug ); - } - - render() { - const { instanceId } = this.props; - const { editedSlug } = this.state; - - const inputId = 'editor-post-slug-' + instanceId; - - return ( - <PostSlugCheck> - <label htmlFor={ inputId }>{ __( 'Slug' ) }</label> - <input - type="text" - id={ inputId } - value={ editedSlug } - onChange={ ( event ) => this.setState( { editedSlug: event.target.value } ) } - onBlur={ this.setSlug } - className="editor-post-slug__input" - /> - </PostSlugCheck> - ); - } -} - -export default compose( [ - withSelect( ( select ) => { - const { - getCurrentPost, - getEditedPostAttribute, - } = select( 'core/editor' ); - - const { id } = getCurrentPost(); - return { - postSlug: getEditedPostAttribute( 'slug' ), - postTitle: getEditedPostAttribute( 'title' ), - postID: id, - }; - } ), - withDispatch( ( dispatch ) => { - const { editPost } = dispatch( 'core/editor' ); - return { - onUpdateSlug( slug ) { - editPost( { slug } ); - }, - }; - } ), - withInstanceId, -] )( PostSlug ); diff --git a/packages/editor/src/components/post-slug/test/check.js b/packages/editor/src/components/post-slug/test/check.js deleted file mode 100644 index 90fe356236adbc..00000000000000 --- a/packages/editor/src/components/post-slug/test/check.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - -/** - * Internal dependencies - */ -import PostSlugCheck from '../check'; - -describe( 'PostSlugCheck', () => { - it( 'should render control', () => { - const wrapper = shallow( - <PostSlugCheck> - slug - </PostSlugCheck> - ); - - expect( wrapper.type() ).not.toBe( null ); - } ); -} ); diff --git a/packages/editor/src/components/post-slug/test/index.js b/packages/editor/src/components/post-slug/test/index.js deleted file mode 100644 index cf25f25e0fe377..00000000000000 --- a/packages/editor/src/components/post-slug/test/index.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - -/** - * Internal dependencies - */ -import { PostSlug } from '../'; - -describe( 'PostSlug', () => { - describe( '#render()', () => { - it( 'should update internal slug', () => { - const wrapper = shallow( - <PostSlug - postSlug="index" /> - ); - - wrapper.find( 'input' ).simulate( 'change', { - target: { - value: 'single-post', - }, - } ); - - expect( wrapper.state().editedSlug ).toEqual( 'single-post' ); - } ); - - it( 'should update slug', () => { - const onUpdateSlug = jest.fn(); - const wrapper = shallow( - <PostSlug - postSlug="index" - onUpdateSlug={ onUpdateSlug } /> - ); - - wrapper.find( 'input' ).simulate( 'blur', { - target: { - value: 'single-post', - }, - } ); - - expect( onUpdateSlug ).toHaveBeenCalledWith( 'single-post' ); - } ); - } ); -} ); diff --git a/packages/editor/src/components/post-taxonomies/flat-term-selector.js b/packages/editor/src/components/post-taxonomies/flat-term-selector.js index 06db56eef101f5..3b4c1c8a0c2926 100644 --- a/packages/editor/src/components/post-taxonomies/flat-term-selector.js +++ b/packages/editor/src/components/post-taxonomies/flat-term-selector.js @@ -128,13 +128,13 @@ class FlatTermSelector extends Component { } updateSelectedTerms( terms = [] ) { - const selectedTerms = terms.reduce( ( accumulator, termId ) => { + const selectedTerms = terms.reduce( ( result, termId ) => { const termObject = find( this.state.availableTerms, ( term ) => term.id === termId ); if ( termObject ) { - accumulator.push( termObject.name ); + result.push( termObject.name ); } - return accumulator; + return result; }, [] ); this.setState( { selectedTerms, diff --git a/packages/editor/src/components/post-type-support-check/index.js b/packages/editor/src/components/post-type-support-check/index.js index 7aae5e6abb0362..8096e4ccf7f8d9 100644 --- a/packages/editor/src/components/post-type-support-check/index.js +++ b/packages/editor/src/components/post-type-support-check/index.js @@ -12,14 +12,14 @@ import { withSelect } from '@wordpress/data'; * A component which renders its own children only if the current editor post * type supports one of the given `supportKeys` prop. * - * @param {Object} props Props. - * @param {string} [props.postType] Current post type. - * @param {WPElement} props.children Children to be rendered if post - * type supports. - * @param {(string|string[])} props.supportKeys String or string array of keys - * to test. + * @param {Object} props + * @param {string} [props.postType] Current post type. + * @param {WPElement} props.children Children to be rendered if post + * type supports. + * @param {(string|string[])} props.supportKeys String or string array of keys + * to test. * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} Rendered element. */ export function PostTypeSupportCheck( { postType, children, supportKeys } ) { let isSupported = true; diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 37eb46ff235b52..c386f02097167b 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { map, pick, defaultTo } from 'lodash'; +import { map, pick, defaultTo, differenceBy, isEqual, noop } from 'lodash'; import memize from 'memize'; /** @@ -16,6 +16,7 @@ import { BlockEditorProvider, transformStyles } from '@wordpress/block-editor'; import apiFetch from '@wordpress/api-fetch'; import { addQueryArgs } from '@wordpress/url'; import { decodeEntities } from '@wordpress/html-entities'; +import { unregisterBlockType } from '@wordpress/blocks'; /** * Internal dependencies @@ -24,6 +25,7 @@ import withRegistryProvider from './with-registry-provider'; import { mediaUpload } from '../../utils'; import ReusableBlocksButtons from '../reusable-blocks-buttons'; import ConvertToGroupButtons from '../convert-to-group-buttons'; +import InserterMenuDownloadableBlocksPanel from '../inserter-menu-downloadable-blocks-panel'; const fetchLinkSuggestions = async ( search ) => { const posts = await apiFetch( { @@ -38,10 +40,11 @@ const fetchLinkSuggestions = async ( search ) => { id: post.id, url: post.url, title: decodeEntities( post.title ) || __( '(no title)' ), - type: post.subtype || post.type, } ) ); }; +const UNINSTALL_ERROR_NOTICE_ID = 'block-uninstall-error'; + class EditorProvider extends Component { constructor( props ) { super( ...arguments ); @@ -106,11 +109,10 @@ class EditorProvider extends Component { '__experimentalEnableLegacyWidgetBlock', '__experimentalEnableMenuBlock', '__experimentalBlockDirectory', - '__experimentalEnableFullSiteEditing', 'showInserterHelpPanel', ] ), - mediaUpload: hasUploadPermissions ? mediaUpload : undefined, __experimentalReusableBlocks: reusableBlocks, + __experimentalMediaUpload: hasUploadPermissions ? mediaUpload : undefined, __experimentalFetchLinkSuggestions: fetchLinkSuggestions, __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML, }; @@ -138,6 +140,21 @@ class EditorProvider extends Component { if ( this.props.settings !== prevProps.settings ) { this.props.updateEditorSettings( this.props.settings ); } + + // When a block is installed from the inserter and is unused, + // it is removed when saving the post. + // Todo: move this to the edit-post package into a separate component. + if ( ! isEqual( this.props.downloadableBlocksToUninstall, prevProps.downloadableBlocksToUninstall ) ) { + this.props.downloadableBlocksToUninstall.forEach( ( blockType ) => { + this.props.uninstallBlock( blockType, noop, () => { + this.props.createWarningNotice( + __( 'Block previews can\'t uninstall.' ), { + id: UNINSTALL_ERROR_NOTICE_ID, + } ); + } ); + unregisterBlockType( blockType.name ); + } ); + } } componentWillUnmount() { @@ -170,20 +187,19 @@ class EditorProvider extends Component { ); return ( - <EntityProvider kind="root" type="site"> - <EntityProvider kind="postType" type={ post.type } id={ post.id }> - <BlockEditorProvider - value={ blocks } - onInput={ resetEditorBlocksWithoutUndoLevel } - onChange={ resetEditorBlocks } - settings={ editorSettings } - useSubRegistry={ false } - > - { children } - <ReusableBlocksButtons /> - <ConvertToGroupButtons /> - </BlockEditorProvider> - </EntityProvider> + <EntityProvider kind="postType" type={ post.type } id={ post.id }> + <BlockEditorProvider + value={ blocks } + onInput={ resetEditorBlocksWithoutUndoLevel } + onChange={ resetEditorBlocks } + settings={ editorSettings } + useSubRegistry={ false } + > + { children } + <ReusableBlocksButtons /> + <ConvertToGroupButtons /> + { editorSettings.__experimentalBlockDirectory && <InserterMenuDownloadableBlocksPanel /> } + </BlockEditorProvider> </EntityProvider> ); } @@ -199,6 +215,10 @@ export default compose( [ __experimentalGetReusableBlocks, } = select( 'core/editor' ); const { canUser } = select( 'core' ); + const { getInstalledBlockTypes } = select( 'core/block-directory' ); + const { getBlocks } = select( 'core/block-editor' ); + + const downloadableBlocksToUninstall = differenceBy( getInstalledBlockTypes(), getBlocks(), 'name' ); return { canUserUseUnfilteredHTML: canUserUseUnfilteredHTML(), @@ -206,6 +226,7 @@ export default compose( [ blocks: getEditorBlocks(), reusableBlocks: __experimentalGetReusableBlocks(), hasUploadPermissions: defaultTo( canUser( 'create', 'media' ), true ), + downloadableBlocksToUninstall, }; } ), withDispatch( ( dispatch ) => { @@ -217,6 +238,7 @@ export default compose( [ __experimentalTearDownEditor, } = dispatch( 'core/editor' ); const { createWarningNotice } = dispatch( 'core/notices' ); + const { uninstallBlock } = dispatch( 'core/block-directory' ); return { setupEditor, @@ -230,6 +252,7 @@ export default compose( [ } ); }, tearDownEditor: __experimentalTearDownEditor, + uninstallBlock, }; } ), ] )( EditorProvider ); diff --git a/packages/editor/src/editor-styles.scss b/packages/editor/src/editor-styles.scss index 978b34a61deaf3..c44e3d87a32299 100644 --- a/packages/editor/src/editor-styles.scss +++ b/packages/editor/src/editor-styles.scss @@ -104,8 +104,6 @@ ul, ol { margin-bottom: $default-block-margin; padding: inherit; - padding-left: 1.3em; - margin-left: 1.3em; // Remove bottom margin from nested lists. ul, diff --git a/packages/editor/src/store/actions.native.js b/packages/editor/src/store/actions.native.js index 0154c92324640e..17733a0e47b408 100644 --- a/packages/editor/src/store/actions.native.js +++ b/packages/editor/src/store/actions.native.js @@ -21,7 +21,9 @@ export function togglePostTitleSelection( isSelected = true ) { /** * Action generator used in signalling that the post should autosave. + * + * @param {Object?} options Extra flags to identify the autosave. */ -export function* autosave() { +export function* autosave( ) { RNReactNativeGutenbergBridge.editorDidAutosave(); } diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 0bf0ddf3f1bb38..7014d8a3b1fe56 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -210,8 +210,8 @@ export function postLock( state = { isLocked: false }, action ) { * * When post saving is locked, the post cannot be published or updated. * - * @param {PostLockState} state Current state. - * @param {Object} action Dispatched action. + * @param {PostSavingLockState} state Current state. + * @param {Object} action Dispatched action. * * @return {PostLockState} Updated state. */ @@ -231,8 +231,8 @@ export function postSavingLock( state = {}, action ) { * * When post autosaving is locked, the post will not autosave. * - * @param {PostLockState} state Current state. - * @param {Object} action Dispatched action. + * @param {PostAutosavingLockState} state Current state. + * @param {Object} action Dispatched action. * * @return {PostLockState} Updated state. */ diff --git a/packages/element/README.md b/packages/element/README.md index fb0c8089fae2b1..0b96812eacb539 100755 --- a/packages/element/README.md +++ b/packages/element/README.md @@ -148,8 +148,8 @@ _Related_ _Parameters_ -- _child_ `WPElement`: Any renderable child, such as an element, string, or fragment. -- _container_ `HTMLElement`: DOM node into which element should be rendered. +- _component_ `Component`: Component +- _target_ `Element`: DOM node into which element should be rendered <a name="createRef" href="#createRef">#</a> **createRef** @@ -163,11 +163,12 @@ _Returns_ <a name="findDOMNode" href="#findDOMNode">#</a> **findDOMNode** -Finds the dom node of a React component. +Finds the dom node of a React component _Parameters_ -- _component_ `WPComponent`: Component's instance. +- _component_ `Component`: component's instance +- _target_ `Element`: DOM node into which element should be rendered <a name="forwardRef" href="#forwardRef">#</a> **forwardRef** @@ -202,7 +203,7 @@ _Returns_ <a name="isValidElement" href="#isValidElement">#</a> **isValidElement** -Checks if an object is a valid WPElement. +Checks if an object is a valid WPElement _Parameters_ @@ -224,30 +225,6 @@ _Related_ - <https://reactjs.org/docs/react-api.html#reactmemo> -<a name="Platform" href="#Platform">#</a> **Platform** - -Component used to detect the current Platform being used. -Use Platform.OS === 'web' to detect if running on web enviroment. - -This is the same concept as the React Native implementation. - -_Related_ - -- <https://facebook.github.io/react-native/docs/platform-specific-code#platform-module> - -Here is an example of how to use the select method: - -_Usage_ - -```js -import { Platform } from '@wordpress/element'; - -const placeholderLabel = Platform.select( { - native: __( 'Add media' ), - web: __( 'Drag images, upload new ones or select files from your library.' ), -} ); -``` - <a name="RawHTML" href="#RawHTML">#</a> **RawHTML** Component used as equivalent of Fragment with unescaped HTML, in cases where @@ -263,7 +240,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Dangerously-rendering component. +- `WPElement`: Dangerously-rendering element. <a name="render" href="#render">#</a> **render** @@ -271,8 +248,8 @@ Renders a given element into the target DOM node. _Parameters_ -- _element_ `WPElement`: Element to render. -- _target_ `HTMLElement`: DOM node into which element should be rendered. +- _element_ `WPElement`: Element to render +- _target_ `Element`: DOM node into which element should be rendered <a name="renderToString" href="#renderToString">#</a> **renderToString** diff --git a/packages/element/package.json b/packages/element/package.json index c7e4ac61ff491c..187e80d149b4a5 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/element", - "version": "2.8.2", + "version": "2.8.0", "description": "Element React module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/element/src/index.js b/packages/element/src/index.js index ad8bae6eff98b0..d9d4bf87ecf05d 100644 --- a/packages/element/src/index.js +++ b/packages/element/src/index.js @@ -1,6 +1,5 @@ export * from './react'; export * from './react-platform'; export * from './utils'; -export { default as Platform } from './platform'; export { default as renderToString } from './serialize'; export { default as RawHTML } from './raw-html'; diff --git a/packages/element/src/platform.android.js b/packages/element/src/platform.android.js deleted file mode 100644 index 4f0da0cab9c683..00000000000000 --- a/packages/element/src/platform.android.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * External dependencies - */ -import { Platform as OriginalPlatform } from 'react-native'; - -const Platform = { - ...OriginalPlatform, - select: ( spec ) => { - if ( 'android' in spec ) { - return spec.android; - } else if ( 'native' in spec ) { - return spec.native; - } - return spec.default; - }, -}; - -export default Platform; diff --git a/packages/element/src/platform.ios.js b/packages/element/src/platform.ios.js deleted file mode 100644 index bbadff1f193319..00000000000000 --- a/packages/element/src/platform.ios.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * External dependencies - */ -import { Platform as OriginalPlatform } from 'react-native'; - -const Platform = { - ...OriginalPlatform, - select: ( spec ) => { - if ( 'ios' in spec ) { - return spec.ios; - } else if ( 'native' in spec ) { - return spec.native; - } - return spec.default; - }, -}; - -export default Platform; diff --git a/packages/element/src/platform.js b/packages/element/src/platform.js deleted file mode 100644 index 328f5523b6f95f..00000000000000 --- a/packages/element/src/platform.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Parts of this source were derived and modified from react-native-web, - * released under the MIT license. - * - * Copyright (c) 2016-present, Nicolas Gallagher. - * Copyright (c) 2015-present, Facebook, Inc. - * - */ -const Platform = { - OS: 'web', - select: ( spec ) => ( 'web' in spec ? spec.web : spec.default ), -}; -/** - * Component used to detect the current Platform being used. - * Use Platform.OS === 'web' to detect if running on web enviroment. - * - * This is the same concept as the React Native implementation. - * - * @see https://facebook.github.io/react-native/docs/platform-specific-code#platform-module - * - * Here is an example of how to use the select method: - * @example - * ```js - * import { Platform } from '@wordpress/element'; - * - * const placeholderLabel = Platform.select( { - * native: __( 'Add media' ), - * web: __( 'Drag images, upload new ones or select files from your library.' ), - * } ); - * ``` - */ -export default Platform; diff --git a/packages/element/src/raw-html.js b/packages/element/src/raw-html.js index 0f56060e3057b6..2fa3618c417d88 100644 --- a/packages/element/src/raw-html.js +++ b/packages/element/src/raw-html.js @@ -13,7 +13,7 @@ import { createElement } from './react'; * @param {string} props.children HTML to render. * @param {Object} props.props Any additonal props to be set on the containing div. * - * @return {WPComponent} Dangerously-rendering component. + * @return {WPElement} Dangerously-rendering element. */ export default function RawHTML( { children, ...props } ) { // The DIV wrapper will be stripped by serializer, unless there are diff --git a/packages/element/src/react-platform.js b/packages/element/src/react-platform.js index 44a3422ed79773..e4ca37da7e11bc 100644 --- a/packages/element/src/react-platform.js +++ b/packages/element/src/react-platform.js @@ -13,24 +13,24 @@ import { * * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235 * - * @param {WPElement} child Any renderable child, such as an element, - * string, or fragment. - * @param {HTMLElement} container DOM node into which element should be rendered. + * @param {Component} component Component + * @param {Element} target DOM node into which element should be rendered */ export { createPortal }; /** - * Finds the dom node of a React component. + * Finds the dom node of a React component * - * @param {WPComponent} component Component's instance. + * @param {Component} component component's instance + * @param {Element} target DOM node into which element should be rendered */ export { findDOMNode }; /** * Renders a given element into the target DOM node. * - * @param {WPElement} element Element to render. - * @param {HTMLElement} target DOM node into which element should be rendered. + * @param {WPElement} element Element to render + * @param {Element} target DOM node into which element should be rendered */ export { render }; diff --git a/packages/element/src/react.js b/packages/element/src/react.js index 2776f514b329e5..561776257f388e 100644 --- a/packages/element/src/react.js +++ b/packages/element/src/react.js @@ -28,24 +28,6 @@ import { } from 'react'; import { isString } from 'lodash'; -/** - * Object containing a React element. - * - * @typedef {react.ReactElement} WPElement - */ - -/** - * Object containing a React component. - * - * @typedef {react.Component} WPComponent - */ - -/** - * Object containing a React synthetic event. - * - * @typedef {react.SyntheticEvent} WPSyntheticEvent - */ - /** * Object that provides utilities for dealing with React children. */ @@ -81,8 +63,8 @@ export { createContext }; * * @param {?(string|Function)} type Tag name or element creator * @param {Object} props Element properties, either attribute - * set to apply to DOM node or values to - * pass through to element creator + * set to apply to DOM node or values to + * pass through to element creator * @param {...WPElement} children Descendant elements * * @return {WPElement} Element. @@ -117,7 +99,7 @@ export { forwardRef }; export { Fragment }; /** - * Checks if an object is a valid WPElement. + * Checks if an object is a valid WPElement * * @param {Object} objectToCheck The object to be checked. * @@ -203,7 +185,7 @@ export { Suspense }; * @return {Array} The concatenated value. */ export function concatChildren( ...childrenArguments ) { - return childrenArguments.reduce( ( accumulator, children, i ) => { + return childrenArguments.reduce( ( result, children, i ) => { Children.forEach( children, ( child, j ) => { if ( child && 'string' !== typeof child ) { child = cloneElement( child, { @@ -211,10 +193,10 @@ export function concatChildren( ...childrenArguments ) { } ); } - accumulator.push( child ); + result.push( child ); } ); - return accumulator; + return result; }, [] ); } diff --git a/packages/element/src/test/platform.js b/packages/element/src/test/platform.js deleted file mode 100644 index fc98f4e19b22a9..00000000000000 --- a/packages/element/src/test/platform.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; -/** - * Internal dependencies - */ -import Platform from '../platform'; - -describe( 'Platform', () => { - it( 'is chooses the right thing', () => { - const element = Platform.select( { - web: shallow( <div></div> ), - native: shallow( <button></button> ), - } ); - - expect( element.type() ).toBe( 'div' ); - } ); -} ); diff --git a/packages/element/src/test/platform.native.js b/packages/element/src/test/platform.native.js deleted file mode 100644 index da6717d66409e0..00000000000000 --- a/packages/element/src/test/platform.native.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; -/** - * Internal dependencies - */ -import Platform from '../platform'; - -describe( 'Platform', () => { - it( 'is chooses the right thing', () => { - const element = Platform.select( { - web: shallow( <div></div> ), - native: shallow( <button></button> ), - } ); - - expect( element.type() ).toBe( 'button' ); - } ); -} ); diff --git a/packages/env/.npmrc b/packages/env/.npmrc deleted file mode 100644 index 43c97e719a5a82..00000000000000 --- a/packages/env/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/packages/env/README.md b/packages/env/README.md index 1f06dabf9ce710..45736ee1fa29bb 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -7,7 +7,7 @@ ```sh $ npm -g i @wordpress/env -$ cd path/to/plugin-or-theme # WordPress install will be in path/to/plugin-or-theme-wordpress. +$ cd path/to/gutenberg # WordPress install will be in path/to/gutenberg-wordpress. $ wp-env --help @@ -15,10 +15,8 @@ wp-env <command> Commands: wp-env start [ref] Starts WordPress for development on port 8888 - (​http://localhost:8888​) (override with - WP_ENV_PORT) and tests on port 8889 - (​http://localhost:8889​) (override with - WP_ENV_TESTS_PORT). If the current working + (​http://localhost:8888​) and tests on port 8889 + (​http://localhost:8889​). If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately. @@ -36,11 +34,10 @@ Options: ```sh wp-env start [ref] -Starts WordPress for development on port 8888 (​http://localhost:8888​) -(override with WP_ENV_PORT) and tests on port 8889 (​http://localhost:8889​) -(override with WP_ENV_TESTS_PORT). If the current working directory is a plugin -and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted -appropiately. +Starts WordPress for development on port 8888 (​http://localhost:8888​) and +tests on port 8889 (​http://localhost:8889​). If the current working directory +is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be +mounted appropiately. Positionals: ref A `https://github.com/WordPress/WordPress` git repo branch or commit for @@ -66,5 +63,3 @@ Positionals: environment Which environments' databases to clean. [string] [choices: "all", "development", "tests"] [default: "tests"] ``` - -<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p> diff --git a/packages/env/lib/cli.js b/packages/env/lib/cli.js index 98dc1ecb42ce26..6f134afd9ae421 100644 --- a/packages/env/lib/cli.js +++ b/packages/env/lib/cli.js @@ -46,10 +46,10 @@ module.exports = function cli() { chalk`Starts WordPress for development on port {bold.underline ${ terminalLink( '8888', 'http://localhost:8888' - ) }} (override with WP_ENV_PORT) and tests on port {bold.underline ${ terminalLink( + ) }} and tests on port {bold.underline ${ terminalLink( '8889', 'http://localhost:8889' - ) }} (override with WP_ENV_TESTS_PORT). If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately.` + ) }}. If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately.` ), ( args ) => { args.positional( 'ref', { diff --git a/packages/env/lib/create-docker-compose-config.js b/packages/env/lib/create-docker-compose-config.js index f5971723148b57..7a3dfc7d33b6aa 100644 --- a/packages/env/lib/create-docker-compose-config.js +++ b/packages/env/lib/create-docker-compose-config.js @@ -1,18 +1,17 @@ module.exports = function createDockerComposeConfig( - cwd, - cwdName, - cwdTestsPath, - context + pluginPath, + pluginName, + pluginTestsPath ) { const commonVolumes = ` - - ${ cwd }/:/var/www/html/wp-content/${ context.type }s/${ cwdName }/ - - ${ cwd }${ cwdTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ - - ${ cwd }${ cwdTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ cwdName }-test-plugins/`; + - ${ pluginPath }/:/var/www/html/wp-content/plugins/${ pluginName }/ + - ${ pluginPath }${ pluginTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ + - ${ pluginPath }${ pluginTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ pluginName }-test-plugins/`; const volumes = ` - - ${ cwd }/../${ cwdName }-wordpress/:/var/www/html/${ commonVolumes }`; + - ${ pluginPath }/../${ pluginName }-wordpress/:/var/www/html/${ commonVolumes }`; const testsVolumes = ` - tests-wordpress:/var/www/html/${ commonVolumes }`; - return `version: '2.1' + return `version: '2' volumes: tests-wordpress: services: @@ -29,7 +28,7 @@ services: WORDPRESS_DB_PASSWORD: password image: wordpress ports: - - \${WP_ENV_PORT:-8888}:80 + - 8888:80 volumes:${ volumes } wordpress-cli: depends_on: @@ -45,7 +44,7 @@ services: WORDPRESS_DB_PASSWORD: password image: wordpress ports: - - \${WP_ENV_TESTS_PORT:-8889}:80 + - 8889:80 volumes:${ testsVolumes } tests-wordpress-cli: depends_on: diff --git a/packages/env/lib/detect-context.js b/packages/env/lib/detect-context.js deleted file mode 100644 index afc23f6dd5f6f3..00000000000000 --- a/packages/env/lib/detect-context.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; -/** - * External dependencies - */ -const util = require( 'util' ); -const fs = require( 'fs' ); -const stream = require( 'stream' ); -const path = require( 'path' ); - -/** - * Promisified dependencies - */ -const readDir = util.promisify( fs.readdir ); -const finished = util.promisify( stream.finished ); - -module.exports = async function detectContext() { - const context = {}; - - // Race multiple file read streams against each other until - // a plugin or theme header is found. - const files = ( await readDir( './' ) ).filter( - ( file ) => path.extname( file ) === '.php' || path.basename( file ) === 'style.css' - ); - const streams = []; - for ( const file of files ) { - const fileStream = fs.createReadStream( file, 'utf8' ); - fileStream.on( 'data', ( text ) => { - const [ , type ] = text.match( /(Plugin|Theme) Name: .*[\r\n]/ ) || []; - if ( type ) { - context.type = type.toLowerCase(); - - // Stop the creation of new streams by mutating the iterated array. We can't `break`, because we are inside a function. - files.splice( 0 ); - fileStream.destroy(); - streams.forEach( ( otherFileStream ) => otherFileStream.destroy() ); - } - } ); - streams.push( fileStream ); - } - await Promise.all( - streams.map( ( fileStream ) => finished( fileStream ).catch( () => {} ) ) - ); - - return context; -}; diff --git a/packages/env/lib/env.js b/packages/env/lib/env.js index c2ba83ac24c221..159bb2ac2fc45f 100644 --- a/packages/env/lib/env.js +++ b/packages/env/lib/env.js @@ -11,13 +11,12 @@ const wait = require( 'util' ).promisify( setTimeout ); /** * Internal dependencies */ -const detectContext = require( './detect-context' ); const createDockerComposeConfig = require( './create-docker-compose-config' ); // Config Variables -const cwd = process.cwd(); -const cwdName = path.basename( cwd ); -const cwdTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; +const pluginPath = process.cwd(); +const pluginName = path.basename( pluginPath ); +const pluginTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; const dockerComposeOptions = { config: path.join( __dirname, 'docker-compose.yml' ), }; @@ -31,22 +30,18 @@ const wpCliRun = ( command, isTests = false ) => ); const setupSite = ( isTests = false ) => wpCliRun( - `wp core install --url=localhost:${ - isTests ? - process.env.WP_ENV_TESTS_PORT || 8889 : - process.env.WP_ENV_PORT || 8888 - } --title=${ cwdName } --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, + `wp core install --url=localhost:888${ + isTests ? '9' : '8' + } --title=Gutenberg --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, isTests ); -const activateContext = ( context, isTests = false ) => - wpCliRun( `wp ${ context.type } activate ${ cwdName }`, isTests ); +const activatePlugin = ( isTests = false ) => + wpCliRun( `wp plugin activate ${ pluginName }`, isTests ); const resetDatabase = ( isTests = false ) => wpCliRun( 'wp db reset --yes', isTests ); module.exports = { async start( { ref, spinner = {} } ) { - const context = await detectContext(); - spinner.text = `Downloading WordPress@${ ref } 0/100%.`; const gitFetchOptions = { fetchOpts: { @@ -67,7 +62,7 @@ module.exports = { }; // Clone or get the repo. - const repoPath = `../${ cwdName }-wordpress/`; + const repoPath = `../${ pluginName }-wordpress/`; const repo = await NodeGit.Clone( 'https://github.com/WordPress/WordPress.git', repoPath, @@ -97,10 +92,10 @@ module.exports = { } spinner.text = `Downloading WordPress@${ ref } 100/100%.`; - spinner.text = `Starting WordPress@${ ref }.`; + spinner.text = `Installing WordPress@${ ref }.`; fs.writeFileSync( dockerComposeOptions.config, - createDockerComposeConfig( cwd, cwdName, cwdTestsPath, context ) + createDockerComposeConfig( pluginPath, pluginName, pluginTestsPath ) ); // These will bring up the database container, @@ -124,14 +119,11 @@ module.exports = { .catch( retryableSiteSetup ) .catch( retryableSiteSetup ); - await Promise.all( [ - activateContext( context ), - activateContext( context, true ), - ] ); + await Promise.all( [ activatePlugin(), activatePlugin( true ) ] ); // Remove dangling containers and finish. await dockerCompose.rm( dockerComposeOptions ); - spinner.text = `Started WordPress@${ ref }.`; + spinner.text = `Installed WordPress@${ ref }.`; }, async stop( { spinner = {} } ) { @@ -141,8 +133,6 @@ module.exports = { }, async clean( { environment, spinner } ) { - const context = await detectContext(); - const description = `${ environment } environment${ environment === 'all' ? 's' : '' }`; @@ -154,7 +144,7 @@ module.exports = { tasks.push( resetDatabase() .then( setupSite ) - .then( activateContext.bind( null, context ) ) + .then( activatePlugin ) .catch( () => {} ) ); } @@ -162,7 +152,7 @@ module.exports = { tasks.push( resetDatabase( true ) .then( setupSite.bind( null, true ) ) - .then( activateContext.bind( null, context, true ) ) + .then( activatePlugin.bind( null, true ) ) .catch( () => {} ) ); } diff --git a/packages/env/package.json b/packages/env/package.json index 19f0fe52cdc047..6be0539b3725cf 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/env", - "version": "0.0.0", + "version": "1.0.0", "description": "A zero-config, self contained local WordPress environment for development and testing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/env/test/cli.js b/packages/env/tests/cli.test.js similarity index 100% rename from packages/env/test/cli.js rename to packages/env/tests/cli.test.js diff --git a/packages/escape-html/package.json b/packages/escape-html/package.json index 19d4e1d0b895c5..b93e62d2a76e42 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "1.5.1", + "version": "1.5.0", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/eslint-plugin/configs/jsdoc.js b/packages/eslint-plugin/configs/jsdoc.js index 8e0935dc316881..614816cb734a21 100644 --- a/packages/eslint-plugin/configs/jsdoc.js +++ b/packages/eslint-plugin/configs/jsdoc.js @@ -1,55 +1,5 @@ -/** - * External dependencies - */ const globals = require( 'globals' ); -/** - * The temporary list of types defined in Gutenberg which are whitelisted to avoid - * ESLint warnings. It should be removed once importing is going to be implemented - * in the tool which generates public APIs from JSDoc comments. Related issue to - * fix the root cause `@wordpress/docgen`: - * https://github.com/WordPress/gutenberg/issues/18045. - */ -const temporaryWordPressInternalTypes = [ - 'WPBlockChildren', - 'WPBlockNode', - 'WPBlockSelection', - 'WPBlockSerializationOptions', - 'WPBlock', - 'WPBlockTypeIcon', - 'WPBlockTypeIconRender', - 'WPBlockTypeIconDescriptor', - 'WPDataPersistencePluginOptions', - 'WPDataPlugin', - 'WPDataRegistry', - 'WPComponent', - 'WPCompleter', - 'WPElement', - 'WPFormat', - 'WPEditorInserterItem', - 'WPNotice', - 'WPNoticeAction', - 'WPPlugin', - 'WPShortcode', - 'WPShortcodeAttrs', - 'WPShortcodeMatch', - 'WPSyntheticEvent', -]; - -/** - * The temporary list of external types used in Gutenberg which are whitelisted - * to avoid ESLint warnings. It's similar to `wordpressInternalTypes` and it - * should be removed once the related issues is fixed: - * https://github.com/WordPress/gutenberg/issues/18045 - */ -const temporaryExternalTypes = [ - 'DOMHighResTimeStamp', - 'espree', - 'moment', - 'puppeteer', - 'react', -]; - /** * Helpful utilities that are globally defined and known to the TypeScript compiler. * @@ -100,8 +50,6 @@ module.exports = { // generally refer to window-level event listeners and are not a valid type to reference (e.g. `onclick`). ...Object.keys( globals.browser ).filter( ( k ) => /^[A-Z]/.test( k ) ), ...typescriptUtilityTypes, - ...temporaryWordPressInternalTypes, - ...temporaryExternalTypes, 'void', ], } ], diff --git a/packages/format-library/package.json b/packages/format-library/package.json index e7385c46bd2bfc..50605fb08b7508 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "1.9.3", + "version": "1.9.0", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/src/image/style.scss b/packages/format-library/src/image/style.scss index 5209377f6448e4..93bfc96ae7a166 100644 --- a/packages/format-library/src/image/style.scss +++ b/packages/format-library/src/image/style.scss @@ -2,11 +2,8 @@ display: flex; .components-icon-button { + height: $icon-button-size + $grid-size + $grid-size; align-self: flex-end; - height: $grid-size * 4 - ($border-width * 2); - margin-bottom: $grid-size; - margin-right: $grid-size; - padding: 0 6px; } } @@ -18,13 +15,7 @@ min-width: 150px; max-width: 500px; - &.components-base-control { - .components-base-control__field { - margin-bottom: 0; - } - - .components-base-control__label { - display: block; - } + &.components-base-control .components-base-control__field { + margin-bottom: 0; } } diff --git a/packages/is-shallow-equal/package.json b/packages/is-shallow-equal/package.json index a164a7cdbb44f8..3fabae7a1d053d 100644 --- a/packages/is-shallow-equal/package.json +++ b/packages/is-shallow-equal/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/is-shallow-equal", - "version": "1.6.1", + "version": "1.6.0", "description": "Test for shallow equality between two objects or arrays.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/jest-puppeteer-axe/src/index.js b/packages/jest-puppeteer-axe/src/index.js index 7bba05d8965d28..336cec9bcf8161 100644 --- a/packages/jest-puppeteer-axe/src/index.js +++ b/packages/jest-puppeteer-axe/src/index.js @@ -53,13 +53,13 @@ function formatViolations( violations ) { * * @see https://github.com/dequelabs/axe-puppeteer * - * @param {puppeteer.Page} page Puppeteer's page instance. - * @param {?Object} params Optional Axe API options. - * @param {?string|Array} params.include CSS selector(s) to add to the list of elements - * to include in analysis. - * @param {?string|Array} params.exclude CSS selector(s) to add to the list of elements - * to exclude from analysis. - * @param {?Array} params.disabledRules The list of Axe rules to skip from verification. + * @param {Page} page Puppeteer's page instance. + * @param {?Object} params Optional Axe API options. + * @param {?string|Array} params.include CSS selector(s) to add to the list of elements + * to include in analysis. + * @param {?string|Array} params.exclude CSS selector(s) to add to the list of elements + * to exclude from analysis. + * @param {?Array} params.disabledRules The list of Axe rules to skip from verification. * * @return {Object} A matcher object with two keys `pass` and `message`. */ diff --git a/packages/keycodes/package.json b/packages/keycodes/package.json index a62da6c45f89ba..ba8a5cbe103060 100644 --- a/packages/keycodes/package.json +++ b/packages/keycodes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keycodes", - "version": "2.6.2", + "version": "2.6.0", "description": "Keycodes utilities for WordPress. Used to check for keyboard events across browsers/operating systems.", "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 54c7773292205d..6df9f6a7b996a0 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.8.3", + "version": "1.8.0", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/media-utils/package.json b/packages/media-utils/package.json index 7d6af3e41f63ba..90ecc22a60a0c6 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/media-utils", - "version": "1.2.3", + "version": "1.2.0", "description": "WordPress Media Upload Utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/media-utils/src/components/media-upload/index.js b/packages/media-utils/src/components/media-upload/index.js index eac379f9ebb68d..0ba3db65fd43b1 100644 --- a/packages/media-utils/src/components/media-upload/index.js +++ b/packages/media-utils/src/components/media-upload/index.js @@ -125,6 +125,9 @@ class MediaUpload extends Component { } else { const frameConfig = { title, + button: { + text: __( 'Select' ), + }, multiple, }; if ( !! allowedTypes ) { diff --git a/packages/notices/package.json b/packages/notices/package.json index 6840e145531d50..ed582e8ca7dc50 100644 --- a/packages/notices/package.json +++ b/packages/notices/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/notices", - "version": "1.8.2", + "version": "1.8.0", "description": "State management for notices.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/notices/src/store/actions.js b/packages/notices/src/store/actions.js index 0fed89a60e0f31..f1771b6ca8ae2f 100644 --- a/packages/notices/src/store/actions.js +++ b/packages/notices/src/store/actions.js @@ -8,17 +8,6 @@ import { uniqueId } from 'lodash'; */ import { DEFAULT_CONTEXT, DEFAULT_STATUS } from './constants'; -/** - * @typedef {Object} WPNoticeAction Object describing a user action option associated with a notice. - * - * @property {string} label Message to use as action label. - * @property {?string} url Optional URL of resource if action incurs - * browser navigation. - * @property {?Function} onClick Optional function to invoke when action is - * triggered by user. - * - */ - /** * Yields action objects used in signalling that a notice is to be created. * diff --git a/packages/notices/src/store/selectors.js b/packages/notices/src/store/selectors.js index 358a159aa8dc66..3a0bc75ad0f02a 100644 --- a/packages/notices/src/store/selectors.js +++ b/packages/notices/src/store/selectors.js @@ -38,6 +38,17 @@ const DEFAULT_NOTICES = []; * */ +/** + * @typedef {Object} WPNoticeAction Object describing a user action option associated with a notice. + * + * @property {string} label Message to use as action label. + * @property {?string} url Optional URL of resource if action incurs + * browser navigation. + * @property {?Function} onClick Optional function to invoke when action is + * triggered by user. + * + */ + /** * Returns all notices as an array, optionally for a given context. Defaults to * the global context. diff --git a/packages/nux/package.json b/packages/nux/package.json index 913a16112bc36a..858ddc289df131 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "3.7.2", + "version": "3.7.0", "description": "NUX (New User eXperience) module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/src/store/selectors.js b/packages/nux/src/store/selectors.js index 58decf89455191..9225bd97077eee 100644 --- a/packages/nux/src/store/selectors.js +++ b/packages/nux/src/store/selectors.js @@ -7,7 +7,7 @@ import { includes, difference, keys, has } from 'lodash'; /** * An object containing information about a guide. * - * @typedef {Object} NUXGuideInfo + * @typedef {Object} NUX.GuideInfo * @property {string[]} tipIds Which tips the guide contains. * @property {?string} currentTipId The guide's currently showing tip. * @property {?string} nextTipId The guide's next tip to show. @@ -20,7 +20,7 @@ import { includes, difference, keys, has } from 'lodash'; * @param {Object} state Global application state. * @param {string} tipId The tip to query. * - * @return {?NUXGuideInfo} Information about the associated guide. + * @return {?NUX.GuideInfo} Information about the associated guide. */ export const getAssociatedGuide = createSelector( ( state, tipId ) => { diff --git a/packages/plugins/README.md b/packages/plugins/README.md index 9bf049e1bc6abc..2875c76b0fa8da 100644 --- a/packages/plugins/README.md +++ b/packages/plugins/README.md @@ -26,7 +26,7 @@ _Parameters_ _Returns_ -- `?WPPlugin`: Plugin setting. +- `?Object`: Plugin setting. <a name="getPlugins" href="#getPlugins">#</a> **getPlugins** @@ -34,7 +34,7 @@ Returns all registered plugins. _Returns_ -- `Array<WPPlugin>`: Plugin settings. +- `Array`: Plugin settings. <a name="PluginArea" href="#PluginArea">#</a> **PluginArea** @@ -71,7 +71,7 @@ const Layout = () => ( _Returns_ -- `WPComponent`: The component to be rendered. +- `WPElement`: Plugin area. <a name="registerPlugin" href="#registerPlugin">#</a> **registerPlugin** @@ -143,12 +143,14 @@ registerPlugin( 'plugin-name', { _Parameters_ -- _name_ `string`: A string identifying the plugin.Must be unique across all registered plugins. -- _settings_ `WPPlugin`: The settings for this plugin. +- _name_ `string`: A string identifying the plugin. Must be unique across all registered plugins. +- _settings_ `Object`: The settings for this plugin. +- _settings.icon_ `(string|WPElement|Function)`: An icon to be shown in the UI. It can be a slug of the Dashicon, or an element (or function returning an element) if you choose to render your own SVG. +- _settings.render_ `Function`: A component containing the UI elements to be rendered. _Returns_ -- `WPPlugin`: The final plugin settings object. +- `Object`: The final plugin settings object. <a name="unregisterPlugin" href="#unregisterPlugin">#</a> **unregisterPlugin** @@ -189,7 +191,7 @@ _Parameters_ _Returns_ -- `WPComponent`: Enhanced component with injected context as props. +- `Component`: Enhanced component with injected context as props. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 3c8ca7edfcb63e..f935e31b1b3de5 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/plugins", - "version": "2.7.2", + "version": "2.7.0", "description": "Plugins module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/plugins/src/api/index.js b/packages/plugins/src/api/index.js index 5e8fe1d19c851d..6e6ea102a80ffd 100644 --- a/packages/plugins/src/api/index.js +++ b/packages/plugins/src/api/index.js @@ -10,22 +10,6 @@ import { applyFilters, doAction } from '@wordpress/hooks'; */ import { isFunction } from 'lodash'; -/** - * Defined behavior of a plugin type. - * - * @typedef {Object} WPPlugin - * - * @property {string} name A string identifying the plugin. Must be - * unique across all registered plugins. - * unique across all registered plugins. - * @property {string|WPElement|Function} icon An icon to be shown in the UI. It can - * be a slug of the Dashicon, or an element - * (or function returning an element) if you - * choose to render your own SVG. - * @property {Function} render A component containing the UI elements - * to be rendered. - */ - /** * Plugin definitions keyed by plugin name. * @@ -36,9 +20,11 @@ const plugins = {}; /** * Registers a plugin to the editor. * - * @param {string} name A string identifying the plugin.Must be - * unique across all registered plugins. - * @param {WPPlugin} settings The settings for this plugin. + * @param {string} name A string identifying the plugin. Must be unique across all registered plugins. + * @param {Object} settings The settings for this plugin. + * @param {string|WPElement|Function} settings.icon An icon to be shown in the UI. It can be a slug of the Dashicon, + * or an element (or function returning an element) if you choose to render your own SVG. + * @param {Function} settings.render A component containing the UI elements to be rendered. * * @example <caption>ES5</caption> * ```js @@ -104,7 +90,7 @@ const plugins = {}; * } ); * ``` * - * @return {WPPlugin} The final plugin settings object. + * @return {Object} The final plugin settings object. */ export function registerPlugin( name, settings ) { if ( typeof settings !== 'object' ) { @@ -195,7 +181,7 @@ export function unregisterPlugin( name ) { * * @param {string} name Plugin name. * - * @return {?WPPlugin} Plugin setting. + * @return {?Object} Plugin setting. */ export function getPlugin( name ) { return plugins[ name ]; @@ -204,7 +190,7 @@ export function getPlugin( name ) { /** * Returns all registered plugins. * - * @return {WPPlugin[]} Plugin settings. + * @return {Array} Plugin settings. */ export function getPlugins() { return Object.values( plugins ); diff --git a/packages/plugins/src/components/plugin-area/index.js b/packages/plugins/src/components/plugin-area/index.js index e03e5458d50ef4..1cf6f15b528795 100644 --- a/packages/plugins/src/components/plugin-area/index.js +++ b/packages/plugins/src/components/plugin-area/index.js @@ -47,7 +47,7 @@ import { getPlugins } from '../../api'; * ); * ``` * - * @return {WPComponent} The component to be rendered. + * @return {WPElement} Plugin area. */ class PluginArea extends Component { constructor() { diff --git a/packages/plugins/src/components/plugin-context/index.js b/packages/plugins/src/components/plugin-context/index.js index 586891c67eb4ee..75fb1b8f1dea01 100644 --- a/packages/plugins/src/components/plugin-context/index.js +++ b/packages/plugins/src/components/plugin-context/index.js @@ -19,7 +19,7 @@ export { Provider as PluginContextProvider }; * expected to return object of props to * merge with the component's own props. * - * @return {WPComponent} Enhanced component with injected context as props. + * @return {Component} Enhanced component with injected context as props. */ export const withPluginContext = ( mapContextToProps ) => createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/priority-queue/package.json b/packages/priority-queue/package.json index de49d37c2fe9c3..16f8dbd988281f 100644 --- a/packages/priority-queue/package.json +++ b/packages/priority-queue/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/priority-queue", - "version": "1.3.1", + "version": "1.3.0", "description": "Generic browser priority queue.", "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 29e53534cf6cd8..ee2c7d728eac8a 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/redux-routine", - "version": "3.6.2", + "version": "3.6.0", "description": "Redux middleware for generator coroutines.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index e911c714792064..46a78502ff3ed4 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -216,7 +216,11 @@ behavior. _Parameters_ - _name_ `string`: Format name. -- _settings_ `WPFormat`: Format settings. +- _settings_ `Object`: Format settings. +- _settings.tagName_ `string`: The HTML tag this format will wrap the selection with. +- _settings.className_ `[string]`: A class to match the format. +- _settings.title_ `string`: Name of the format. +- _settings.edit_ `Function`: Should return a component for the user to interact with the new registered format. _Returns_ diff --git a/packages/rich-text/package.json b/packages/rich-text/package.json index 4cf3ef016ddaf3..544d69294e90e4 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/rich-text", - "version": "3.7.2", + "version": "3.7.0", "description": "Rich text value and manipulation API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/rich-text/src/component/index.js b/packages/rich-text/src/component/index.js index c3112d3337fb78..c82feae869d1e7 100644 --- a/packages/rich-text/src/component/index.js +++ b/packages/rich-text/src/component/index.js @@ -35,7 +35,6 @@ import { indentListItems } from '../indent-list-items'; import { getActiveFormats } from '../get-active-formats'; import { updateFormats } from '../update-formats'; import { removeLineSeparator } from '../remove-line-separator'; -import { isEmptyLine } from '../is-empty'; /** * Browser dependencies @@ -205,7 +204,7 @@ class RichText extends Component { * * Saves the pasted data as plain text in `pastedPlainText`. * - * @param {ClipboardEvent} event The paste event. + * @param {PasteEvent} event The paste event. */ onPaste( event ) { const { formatTypes, onPaste } = this.props; @@ -259,32 +258,18 @@ class RichText extends Component { } if ( onPaste ) { - files = Array.from( files ); - - Array.from( items ).forEach( ( item ) => { - if ( ! item.getAsFile ) { - return; - } - - const file = item.getAsFile(); - - if ( ! file ) { - return; - } - - const { name, type, size } = file; - - if ( ! find( files, { name, type, size } ) ) { - files.push( file ); - } - } ); + // Only process file if no HTML is present. + // Note: a pasted file may have the URL as plain text. + const image = find( [ ...items, ...files ], ( { type } ) => + /^image\/(?:jpe?g|png|gif)$/.test( type ) + ); onPaste( { value: this.removeEditorOnlyFormats( record ), onChange: this.onChange, html, plainText, - files, + image, } ); } } @@ -352,7 +337,7 @@ class RichText extends Component { /** * Handle input on the next selection change event. * - * @param {WPSyntheticEvent} event Synthetic input event. + * @param {SyntheticEvent} event Synthetic input event. */ onInput( event ) { // For Input Method Editor (IME), used in Chinese, Japanese, and Korean @@ -452,7 +437,7 @@ class RichText extends Component { * native events, `keyup`, `mouseup` and `touchend` synthetic events, and * animation frames after the `focus` event. * - * @param {Event|WPSyntheticEvent|DOMHighResTimeStamp} event + * @param {Event|SyntheticEvent|DOMHighResTimeStamp} event */ onSelectionChange( event ) { if ( @@ -594,7 +579,7 @@ class RichText extends Component { * - delete content if everything is selected, * - trigger the onDelete prop when selection is uncollapsed and at an edge. * - * @param {WPSyntheticEvent} event A synthetic keyboard event. + * @param {SyntheticEvent} event A synthetic keyboard event. */ handleDelete( event ) { const { keyCode } = event; @@ -619,30 +604,21 @@ class RichText extends Component { const { start, end, text } = value; const isReverse = keyCode === BACKSPACE; - // Always handle full content deletion ourselves. - if ( start === 0 && end !== 0 && end === text.length ) { - this.onChange( remove( value ) ); - event.preventDefault(); - return; - } - if ( multilineTag ) { - let newValue; - - // Check to see if we should remove the first item if empty. - if ( isReverse && value.start === 0 && value.end === 0 && isEmptyLine( value ) ) { - newValue = removeLineSeparator( value, ! isReverse ); - } else { - newValue = removeLineSeparator( value, isReverse ); - } - + const newValue = removeLineSeparator( value, isReverse ); if ( newValue ) { this.onChange( newValue ); event.preventDefault(); - return; } } + // Always handle full content deletion ourselves. + if ( start === 0 && end !== 0 && end === text.length ) { + this.onChange( remove( value ) ); + event.preventDefault(); + return; + } + // Only process delete if the key press occurs at an uncollapsed edge. if ( ! onDelete || @@ -661,7 +637,7 @@ class RichText extends Component { /** * Triggers the `onEnter` prop on keydown. * - * @param {WPSyntheticEvent} event A synthetic keyboard event. + * @param {SyntheticEvent} event A synthetic keyboard event. */ handleEnter( event ) { if ( event.keyCode !== ENTER ) { @@ -686,7 +662,7 @@ class RichText extends Component { /** * Indents list items on space keydown. * - * @param {WPSyntheticEvent} event A synthetic keyboard event. + * @param {SyntheticEvent} event A synthetic keyboard event. */ handleSpace( event ) { const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; @@ -723,7 +699,7 @@ class RichText extends Component { * navigation is handled separately to move correctly around format * boundaries. * - * @param {WPSyntheticEvent} event A synthetic keyboard event. + * @param {SyntheticEvent} event A synthetic keyboard event. */ handleHorizontalNavigation( event ) { const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; @@ -829,7 +805,7 @@ class RichText extends Component { * Select object when they are clicked. The browser will not set any * selection when clicking e.g. an image. * - * @param {WPSyntheticEvent} event Synthetic mousedown or touchstart event. + * @param {SyntheticEvent} event Synthetic mousedown or touchstart event. */ onPointerDown( event ) { const { target } = event; diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 34a1b03fe24ef2..09ac451ed56d23 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -30,7 +30,10 @@ import { getActiveFormat } from '../get-active-format'; import { getActiveFormats } from '../get-active-formats'; import { isEmpty, isEmptyLine } from '../is-empty'; import { create } from '../create'; +import { split } from '../split'; import { toHTMLString } from '../to-html-string'; +import { insert } from '../insert'; +import { insertLineSeparator } from '../insert-line-separator'; import { removeLineSeparator } from '../remove-line-separator'; import { isCollapsed } from '../is-collapsed'; import { remove } from '../remove'; @@ -40,6 +43,28 @@ const unescapeSpaces = ( text ) => { return text.replace( /&nbsp;|&#160;/gi, ' ' ); }; +/** + * Calls {@link pasteHandler} with a fallback to plain text when HTML processing + * results in errors + * + * @param {Function} originalPasteHandler The original handler function + * @param {Object} [options] The options to pass to {@link pasteHandler} + * + * @return {Array|string} A list of blocks or a string, depending on + * `handlerMode`. + */ +const saferPasteHandler = ( originalPasteHandler, options ) => { + try { + return originalPasteHandler( options ); + } catch ( error ) { + window.console.log( 'Pasting HTML failed:', error ); + window.console.log( 'HTML:', options.HTML ); + window.console.log( 'Falling back to plain text.' ); + // fallback to plain text + return originalPasteHandler( { ...options, HTML: '' } ); + } +}; + const gutenbergFormatNamesToAztec = { 'core/bold': 'bold', 'core/italic': 'italic', @@ -47,7 +72,7 @@ const gutenbergFormatNamesToAztec = { }; export class RichText extends Component { - constructor( { value, selectionStart, selectionEnd, __unstableMultilineTag: multiline } ) { + constructor( { value, __unstableMultiline: multiline, selectionStart, selectionEnd } ) { super( ...arguments ); this.isMultiline = false; @@ -59,12 +84,12 @@ export class RichText extends Component { if ( this.multilineTag === 'li' ) { this.multilineWrapperTags = [ 'ul', 'ol' ]; } - + this.onSplit = this.onSplit.bind( this ); this.isIOS = Platform.OS === 'ios'; this.createRecord = this.createRecord.bind( this ); this.onChange = this.onChange.bind( this ); - this.handleEnter = this.handleEnter.bind( this ); - this.handleDelete = this.handleDelete.bind( this ); + this.onEnter = this.onEnter.bind( this ); + this.onBackspace = this.onBackspace.bind( this ); this.onPaste = this.onPaste.bind( this ); this.onFocus = this.onFocus.bind( this ); this.onBlur = this.onBlur.bind( this ); @@ -144,6 +169,63 @@ export class RichText extends Component { return { ...value, start, end }; } + /** + * Signals to the RichText owner that the block can be replaced with two + * blocks as a result of splitting the block by pressing enter, or with + * blocks as a result of splitting the block by pasting block content in the + * instance. + * + * @param {Object} record The rich text value to split. + * @param {Array} pastedBlocks The pasted blocks to insert, if any. + */ + onSplit( record, pastedBlocks = [] ) { + const { + __unstableOnReplace: onReplace, + __unstableOnSplit: onSplit, + __unstableOnSplitMiddle: onSplitMiddle, + } = this.props; + + if ( ! onReplace || ! onSplit ) { + return; + } + + const blocks = []; + const [ before, after ] = split( record ); + const hasPastedBlocks = pastedBlocks.length > 0; + + // Create a block with the content before the caret if there's no pasted + // blocks, or if there are pasted blocks and the value is not empty. + // We do not want a leading empty block on paste, but we do if split + // with e.g. the enter key. + if ( ! hasPastedBlocks || ! isEmpty( before ) ) { + blocks.push( onSplit( this.valueToFormat( before ) ) ); + } + + if ( hasPastedBlocks ) { + blocks.push( ...pastedBlocks ); + } else if ( onSplitMiddle ) { + blocks.push( onSplitMiddle() ); + } + + // If there's pasted blocks, append a block with the content after the + // caret. Otherwise, do append and empty block if there is no + // `onSplitMiddle` prop, but if there is and the content is empty, the + // middle block is enough to set focus in. + if ( hasPastedBlocks || ! onSplitMiddle || ! isEmpty( after ) ) { + blocks.push( onSplit( this.valueToFormat( after ) ) ); + } + + // If there are pasted blocks, set the selection to the last one. + // Otherwise, set the selection to the second block. + const indexToSelect = hasPastedBlocks ? blocks.length - 1 : 1; + // The onSplit event can cause a content update event for this block. Such event should + // definitely be processed by our native components, since they have no knowledge of + // how the split works. Setting lastEventCount to undefined forces the native component to + // always update when provided with new content. + this.lastEventCount = undefined; + onReplace( blocks, indexToSelect ); + } + valueToFormat( value ) { // remove the outer root tags return this.removeRootTagsProduceByAztec( toHTMLString( { @@ -163,7 +245,6 @@ export class RichText extends Component { } onFormatChange( record ) { - this.getRecord( record ); const { start, end, activeFormats = [] } = record; const changeHandlers = pickBy( this.props, ( v, key ) => key.startsWith( 'format_on_change_functions_' ) @@ -265,67 +346,92 @@ export class RichText extends Component { this.lastAztecEventType = 'content size change'; } - handleEnter( event ) { - const { onEnter } = this.props; - - if ( ! onEnter ) { + onEnter( event ) { + if ( this.props.onEnter ) { + this.props.onEnter(); return; } + const { + __unstableOnReplace: onReplace, + __unstableOnSplit: onSplit, + } = this.props; - onEnter( { - value: this.createRecord(), - onChange: this.onFormatChange, - shiftKey: event.shiftKey, - } ); + this.lastEventCount = event.nativeEvent.eventCount; + this.comesFromAztec = true; + this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; + + const canSplit = onReplace && onSplit; + const currentRecord = this.createRecord(); + if ( this.multilineTag ) { + if ( event.shiftKey ) { + this.needsSelectionUpdate = true; + const insertedLineBreak = { ...insert( currentRecord, '\n' ) }; + this.onFormatChange( insertedLineBreak ); + } else if ( canSplit && isEmptyLine( currentRecord ) ) { + this.onSplit( currentRecord ); + } else { + this.needsSelectionUpdate = true; + const insertedLineSeparator = { ...insertLineSeparator( currentRecord ) }; + this.onFormatChange( insertedLineSeparator ); + } + } else if ( event.shiftKey || ! onSplit ) { + this.needsSelectionUpdate = true; + const insertedLineBreak = { ...insert( currentRecord, '\n' ) }; + this.onFormatChange( insertedLineBreak ); + } else { + this.onSplit( currentRecord ); + } this.lastAztecEventType = 'input'; } - handleDelete( event ) { + onBackspace( event ) { + const { + __unstableOnMerge: onMerge, + __unstableOnRemove: onRemove, + onChange, + } = this.props; + if ( ! onMerge && ! onRemove ) { + return; + } + const keyCode = BACKSPACE; // TODO : should we differentiate BACKSPACE and DELETE? const isReverse = keyCode === BACKSPACE; - const { onDelete, __unstableMultilineTag: multilineTag } = this.props; - const { activeFormats = [] } = this.state; this.lastEventCount = event.nativeEvent.eventCount; this.comesFromAztec = true; this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; const value = this.createRecord(); - const { start, end, text } = value; + const { start, end } = value; let newValue; // Always handle full content deletion ourselves. - if ( start === 0 && end !== 0 && end >= text.length ) { - newValue = remove( value ); - this.onFormatChange( newValue ); - event.preventDefault(); + if ( start === 0 && end !== 0 && end >= value.text.length ) { + newValue = remove( value, start, end ); + onChange( newValue ); return; } - if ( multilineTag ) { - if ( isReverse && value.start === 0 && value.end === 0 && isEmptyLine( value ) ) { - newValue = removeLineSeparator( value, ! isReverse ); - } else { - newValue = removeLineSeparator( value, isReverse ); - } + if ( this.multilineTag ) { + newValue = removeLineSeparator( value, keyCode === BACKSPACE ); if ( newValue ) { this.onFormatChange( newValue ); - event.preventDefault(); return; } } - // Only process delete if the key press occurs at an uncollapsed edge. - if ( - ! onDelete || - ! isCollapsed( value ) || - activeFormats.length || - ( isReverse && start !== 0 ) || - ( ! isReverse && end !== text.length ) - ) { - return; + const empty = this.isEmpty(); + + if ( onMerge ) { + onMerge( ! isReverse ); } - onDelete( { isReverse, value } ); + // Only handle remove on Backspace. This serves dual-purpose of being + // an intentional user interaction distinguishing between Backspace and + // Delete to remove the empty field, but also to avoid merge & remove + // causing destruction of two fields (merge, then removed merged). + if ( onRemove && empty && isReverse ) { + onRemove( ! isReverse ); + } event.preventDefault(); this.lastAztecEventType = 'input'; @@ -338,7 +444,10 @@ export class RichText extends Component { */ onPaste( event ) { const { - onPaste, + tagName, + __unstablePasteHandler: pasteHandler, + __unstableOnReplace: onReplace, + __unstableOnSplit: onSplit, onChange, } = this.props; @@ -347,6 +456,30 @@ export class RichText extends Component { event.preventDefault(); + // Only process file if no HTML is present. + // Note: a pasted file may have the URL as plain text. + if ( files && files.length > 0 ) { + const uploadId = Number.MAX_SAFE_INTEGER; + let html = ''; + files.forEach( ( file ) => { + html += `<img src="${ file }" class="wp-image-${ uploadId }">`; + } ); + const content = pasteHandler( { + HTML: html, + mode: 'BLOCKS', + tagName, + } ); + const shouldReplace = onReplace && this.isEmpty(); + + if ( shouldReplace ) { + onReplace( content ); + } else { + this.onSplit( currentRecord, content ); + } + + return; + } + // There is a selection, check if a URL is pasted. if ( ! isCollapsed( currentRecord ) ) { const trimmedText = ( pastedHtml || pastedText ).replace( /<[^>]+>/g, '' ) @@ -370,14 +503,46 @@ export class RichText extends Component { } } - if ( onPaste ) { - onPaste( { - value: currentRecord, - onChange: this.onFormatChange, - html: pastedHtml, - plainText: pastedText, - files, - } ); + const shouldReplace = this.props.onReplace && this.isEmpty(); + + let mode = 'INLINE'; + + if ( shouldReplace ) { + mode = 'BLOCKS'; + } else if ( onSplit ) { + mode = 'AUTO'; + } + + const pastedContent = saferPasteHandler( pasteHandler, { + HTML: pastedHtml, + plainText: pastedText, + mode, + tagName: this.props.tagName, + canUserUseUnfilteredHTML: this.props.canUserUseUnfilteredHTML, + } ); + + if ( typeof pastedContent === 'string' ) { + const recordToInsert = create( { html: pastedContent } ); + const resultingRecord = insert( currentRecord, recordToInsert ); + const resultingContent = this.valueToFormat( resultingRecord ); + + this.lastEventCount = undefined; + this.value = resultingContent; + + // explicitly set selection after inline paste + this.onSelectionChange( resultingRecord.start, resultingRecord.end ); + + onChange( this.value ); + } else if ( onSplit ) { + if ( ! pastedContent.length ) { + return; + } + + if ( shouldReplace ) { + onReplace( pastedContent ); + } else { + this.onSplit( currentRecord, pastedContent ); + } } } @@ -594,7 +759,7 @@ export class RichText extends Component { this.lastEventCount = undefined; // force a refresh on the native side value = ''; } - // On android if content is empty we need to send no content or else the placeholder will not show. + // On android if content is empty we need to send no content or else the placeholder with not show. if ( ! this.isIOS && value === '' ) { return value; } @@ -687,8 +852,8 @@ export class RichText extends Component { onChange={ this.onChange } onFocus={ this.onFocus } onBlur={ this.onBlur } - onEnter={ this.handleEnter } - onBackspace={ this.handleDelete } + onEnter={ this.onEnter } + onBackspace={ this.onBackspace } onPaste={ this.onPaste } activeFormats={ this.getActiveFormatNames( record ) } onContentSizeChange={ this.onContentSizeChange } diff --git a/packages/rich-text/src/component/test/index.native.js b/packages/rich-text/src/component/test/index.native.js index 22ee6b118bb2d2..6b2bc12f855ffa 100644 --- a/packages/rich-text/src/component/test/index.native.js +++ b/packages/rich-text/src/component/test/index.native.js @@ -1,8 +1,17 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + /** * Internal dependencies */ import { RichText } from '../index'; +const getStylesFromColorScheme = () => { + return { color: 'white' }; +}; + describe( 'RichText Native', () => { let richText; @@ -24,4 +33,29 @@ describe( 'RichText Native', () => { expect( richText.willTrimSpaces( html ) ).toBe( false ); } ); } ); + + describe( 'Adds new line on Enter', () => { + let newValue; + const wrapper = shallow( <RichText + rootTagsToEliminate={ [ 'p' ] } + value="" + onChange={ ( value ) => { + newValue = value; + } } + formatTypes={ [] } + onSelectionChange={ jest.fn() } + getStylesFromColorScheme={ getStylesFromColorScheme } + /> ); + + const event = { + nativeEvent: { + eventCount: 0, + }, + }; + wrapper.instance().onEnter( event ); + + it( ' Adds <br> tag to content after pressing Enter key', () => { + expect( newValue ).toEqual( '<br>' ); + } ); + } ); } ); diff --git a/packages/rich-text/src/register-format-type.js b/packages/rich-text/src/register-format-type.js index 84a158167b860f..e6efc99f5fec97 100644 --- a/packages/rich-text/src/register-format-type.js +++ b/packages/rich-text/src/register-format-type.js @@ -10,25 +10,16 @@ import { select, dispatch, withSelect, withDispatch } from '@wordpress/data'; import { addFilter } from '@wordpress/hooks'; import { compose } from '@wordpress/compose'; -/** - * @typedef {Object} WPFormat - * - * @property {string} name A string identifying the format. Must be - * unique across all registered formats. - * @property {string} tagName The HTML tag this format will wrap the - * selection with. - * @property {string} [className] A class to match the format. - * @property {string} title Name of the format. - * @property {Function} edit Should return a component for the user to - * interact with the new registered format. - */ - /** * Registers a new format provided a unique name and an object defining its * behavior. * * @param {string} name Format name. - * @param {WPFormat} settings Format settings. + * @param {Object} settings Format settings. + * @param {string} settings.tagName The HTML tag this format will wrap the selection with. + * @param {string} [settings.className] A class to match the format. + * @param {string} settings.title Name of the format. + * @param {Function} settings.edit Should return a component for the user to interact with the new registered format. * * @return {WPFormat|undefined} The format, if it has been successfully registered; * otherwise `undefined`. diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js index 604ca0c518ec8a..fe97f00d245f53 100644 --- a/packages/rich-text/src/test/helpers/index.js +++ b/packages/rich-text/src/test/helpers/index.js @@ -4,7 +4,7 @@ import { ZWNBSP } from '../../special-characters'; export function getSparseArrayLength( array ) { - return array.reduce( ( accumulator ) => accumulator + 1, 0 ); + return array.reduce( ( i ) => i + 1, 0 ); } const em = { type: 'em' }; diff --git a/packages/rich-text/src/to-dom.js b/packages/rich-text/src/to-dom.js index 730a38587114c4..9d7aed3cfdfd00 100644 --- a/packages/rich-text/src/to-dom.js +++ b/packages/rich-text/src/to-dom.js @@ -67,7 +67,7 @@ function getNodeByPath( node, path ) { * each call to `createEmpty`. Therefore, you should not hold a reference to * the value to operate upon asynchronously, as it may have unexpected results. * - * @return {Object} RichText tree. + * @return {WPRichTextTree} RichText tree. */ const createEmpty = () => createElement( document, '' ); diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 66d7acb086a16b..96e7ae747107c8 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -1,15 +1,5 @@ ## Master -### Breaking Changes - -- The bundled `npm-package-json-lint` dependency has been updated from requiring `^3.6.0` to requiring `^4.0.3` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). Please see the [migration guide](https://npmpackagejsonlint.org/docs/en/v3-to-v4). Note: `npmPackageJsonLintConfig` prop in the `package.json` file needs to be renamed to `npmpackagejsonlint`. - -### New Features - -- The bundled `puppeteer` dependency has been updated from requiring `^1.19.0` to requiring `^1.20.0` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). It uses Chromium v78 instead of Chromium v77. - -## 5.1.0 - ### New Features - The bundled `webpack` dependency has been updated from requiring `4.8.3` to requiring `^4.41.0` ([#17746](https://github.com/WordPress/gutenberg/pull/17746)). diff --git a/packages/scripts/package.json b/packages/scripts/package.json index cc64a8fb5a713d..70d180fb0e2514 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/scripts", - "version": "5.1.0", + "version": "5.0.0", "description": "Collection of reusable scripts for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", @@ -50,8 +50,8 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^4.0.3", - "puppeteer": "^1.20.0", + "npm-package-json-lint": "^3.6.0", + "puppeteer": "^1.19.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", "resolve-bin": "^0.4.0", diff --git a/packages/scripts/scripts/lint-pkg-json.js b/packages/scripts/scripts/lint-pkg-json.js index 53e9c42b366437..487a8191067dbc 100644 --- a/packages/scripts/scripts/lint-pkg-json.js +++ b/packages/scripts/scripts/lint-pkg-json.js @@ -25,8 +25,6 @@ const hasLintConfig = hasArgInCLI( '-c' ) || hasArgInCLI( '--configFile' ) || hasProjectFile( '.npmpackagejsonlintrc.json' ) || hasProjectFile( 'npmpackagejsonlint.config.js' ) || - hasPackageProp( 'npmpackagejsonlint' ) || - // npm-package-json-lint v3.x used a different prop name. hasPackageProp( 'npmPackageJsonLintConfig' ); const defaultConfigArgs = ! hasLintConfig ? diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index 39941d137650bf..99aa8807a8bf6c 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "1.3.3", + "version": "1.3.0", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/package.json b/packages/url/package.json index bc1e8bf3587eb0..9c0b1bcaeba066 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "2.8.2", + "version": "2.8.0", "description": "WordPress URL utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/src/index.js b/packages/url/src/index.js index 2b549d6ba1dc4e..b4fa34efac51a6 100644 --- a/packages/url/src/index.js +++ b/packages/url/src/index.js @@ -360,10 +360,6 @@ export function removeQueryArgs( url, ...args ) { * @return {string} The updated URL. */ export function prependHTTP( url ) { - if ( ! url ) { - return url; - } - url = url.trim(); if ( ! USABLE_HREF_REGEXP.test( url ) && ! EMAIL_REGEXP.test( url ) ) { return 'http://' + url; diff --git a/packages/viewport/package.json b/packages/viewport/package.json index 5cedb8e675caa4..5dd1af95cbe842 100644 --- a/packages/viewport/package.json +++ b/packages/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/viewport", - "version": "2.8.2", + "version": "2.8.0", "description": "Viewport module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/wordcount/package.json b/packages/wordcount/package.json index 7664cf8b99a0fc..7201fbdc9760bc 100644 --- a/packages/wordcount/package.json +++ b/packages/wordcount/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/wordcount", - "version": "2.6.2", + "version": "2.6.0", "description": "WordPress word count utility.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/phpunit/class-override-script-test.php b/phpunit/class-override-script-test.php index 074de00b649ba6..034fa2f25a618b 100644 --- a/phpunit/class-override-script-test.php +++ b/phpunit/class-override-script-test.php @@ -28,10 +28,7 @@ function tearDown() { * Tests that script is localized. */ function test_localizes_script() { - global $wp_scripts; - gutenberg_override_script( - $wp_scripts, 'gutenberg-dummy-script', 'https://example.com/', array( 'dependency' ), @@ -39,6 +36,7 @@ function test_localizes_script() { false ); + global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-dummy-script', 'registered' ); $this->assertEquals( array( 'dependency', 'wp-i18n' ), $script->deps ); } @@ -47,10 +45,7 @@ function test_localizes_script() { * Tests that script properties are overridden. */ function test_replaces_registered_properties() { - global $wp_scripts; - gutenberg_override_script( - $wp_scripts, 'gutenberg-dummy-script', 'https://example.com/updated', array( 'updated-dependency' ), @@ -58,21 +53,19 @@ function test_replaces_registered_properties() { true ); + global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-dummy-script', 'registered' ); $this->assertEquals( 'https://example.com/updated', $script->src ); $this->assertEquals( array( 'updated-dependency', 'wp-i18n' ), $script->deps ); $this->assertEquals( 'updated-version', $script->ver ); - $this->assertTrue( $script->args ); + $this->assertEquals( 1, $script->extra['group'] ); } /** * Tests that new script registers normally if no handle by the name. */ function test_registers_new_script() { - global $wp_scripts; - gutenberg_override_script( - $wp_scripts, 'gutenberg-second-dummy-script', 'https://example.com/', array( 'dependency' ), @@ -80,10 +73,11 @@ function test_registers_new_script() { true ); + global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-second-dummy-script', 'registered' ); $this->assertEquals( 'https://example.com/', $script->src ); $this->assertEquals( array( 'dependency', 'wp-i18n' ), $script->deps ); $this->assertEquals( 'version', $script->ver ); - $this->assertTrue( $script->args ); + $this->assertEquals( 1, $script->extra['group'] ); } } diff --git a/playground/.sassrc b/playground/.sassrc deleted file mode 100644 index 4f704b80b310a5..00000000000000 --- a/playground/.sassrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "includePaths": [ - "node_modules" - ] -} diff --git a/playground/src/index.js b/playground/src/index.js index 66815d8a027256..b74e30091c1739 100644 --- a/playground/src/index.js +++ b/playground/src/index.js @@ -8,12 +8,10 @@ import { BlockEditorKeyboardShortcuts, BlockEditorProvider, BlockList, - BlockInspector, WritingFlow, ObserveTyping, } from '@wordpress/block-editor'; import { - Button, Popover, SlotFillProvider, DropZoneProvider, @@ -42,9 +40,6 @@ function App() { <Fragment> <div className="playground__header"> <h1 className="playground__logo">Gutenberg Playground</h1> - <Button isLarge href="design-system/components" target="_blank"> - Design System Components - </Button> </div> <div className="playground__body"> <SlotFillProvider> @@ -54,9 +49,6 @@ function App() { onInput={ updateBlocks } onChange={ updateBlocks } > - <div className="playground__sidebar"> - <BlockInspector /> - </div> <div className="editor-styles-wrapper"> <BlockEditorKeyboardShortcuts /> <WritingFlow> @@ -75,4 +67,7 @@ function App() { } registerCoreBlocks(); -render( <App />, document.querySelector( '#app' ) ); +render( + <App />, + document.querySelector( '#app' ) +); diff --git a/playground/src/style.scss b/playground/src/style.scss index b6fd8395ac08e8..63a330e00a2d6f 100644 --- a/playground/src/style.scss +++ b/playground/src/style.scss @@ -1,40 +1,17 @@ -@import "~@wordpress/base-styles/colors"; -@import "~@wordpress/base-styles/variables"; -@import "~@wordpress/base-styles/mixins"; -@import "~@wordpress/base-styles/breakpoints"; -@import "~@wordpress/base-styles/animations"; -@import "~@wordpress/base-styles/z-index"; +@import "../../assets/stylesheets/colors"; +@import "../../assets/stylesheets/variables"; +@import "../../assets/stylesheets/mixins"; +@import "../../assets/stylesheets/breakpoints"; +@import "../../assets/stylesheets/animations"; +@import "../../assets/stylesheets/z-index"; @import "./reset"; @import "./editor-styles"; -$playground-header-height: 95px; .playground__header { - align-items: center; - border-bottom: 1px solid #ddd; - display: flex; - justify-content: space-between; padding: 20px; - height: $playground-header-height; -} - -.playground__sidebar { - position: fixed; - top: $playground-header-height; - right: 0; - bottom: 0; - width: $sidebar-width; - border-left: $border-width solid $light-gray-500; - height: auto; - overflow: auto; - -webkit-overflow-scrolling: touch; - - // Temporarily disable the sidebar on mobile - display: none; - @include break-small() { - display: block; - } + border-bottom: 1px solid #ddd; } .playground__logo { @@ -43,9 +20,6 @@ $playground-header-height: 95px; } .playground__body { - @include break-small() { - width: calc(100% - #{$sidebar-width}); - } padding-top: 20px; img { diff --git a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap index 97c607d4d94866..29b4c95f5806b0 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap @@ -72,13 +72,3 @@ exports[`rawHandler should convert a caption shortcode with link 1`] = ` <figure class=\\"wp-block-image alignnone\\"><a href=\\"http://build.wordpress-develop.test/wp-content/uploads/2011/07/100_5478.jpg\\"><img src=\\"http://build.wordpress-develop.test/wp-content/uploads/2011/07/100_5478.jpg?w=604\\" alt=\\"Bell on Wharf\\" class=\\"wp-image-754\\"/></a><figcaption>Bell on wharf in San Francisco</figcaption></figure> <!-- /wp:image -->" `; - -exports[`rawHandler should convert a list with attributes 1`] = ` -"<!-- wp:list {\\"ordered\\":true,\\"type\\":\\"i\\",\\"start\\":2,\\"reversed\\":true} --> -<ol type=\\"i\\" reversed start=\\"2\\"><li>1 - <ol start=\\"2\\" reversed=\\"\\" type=\\"i\\"> - <li>1</li> - </ol> - </li></ol> -<!-- /wp:list -->" -`; diff --git a/test/integration/blocks-raw-handling.test.js b/test/integration/blocks-raw-handling.test.js index 228c6588ef96b5..fda576a042cbb3 100644 --- a/test/integration/blocks-raw-handling.test.js +++ b/test/integration/blocks-raw-handling.test.js @@ -287,9 +287,4 @@ describe( 'rawHandler', () => { const HTML = readFile( path.join( __dirname, 'fixtures/shortcode-caption-with-caption-link.html' ) ); expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); } ); - - it( 'should convert a list with attributes', () => { - const HTML = readFile( path.join( __dirname, 'fixtures/list-with-attributes.html' ) ); - expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); - } ); } ); diff --git a/test/integration/fixtures/google-docs-out.html b/test/integration/fixtures/google-docs-out.html index 54a1e07ac1349a..576b2cd7fda73f 100644 --- a/test/integration/fixtures/google-docs-out.html +++ b/test/integration/fixtures/google-docs-out.html @@ -7,7 +7,7 @@ <h2>This is a <em>heading</em></h2> <!-- /wp:heading --> <!-- wp:paragraph --> -<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, <s>strikethrough</s>, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> +<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, strikethrough, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> <!-- /wp:paragraph --> <!-- wp:list --> diff --git a/test/integration/fixtures/google-docs-with-comments-out.html b/test/integration/fixtures/google-docs-with-comments-out.html index 54a1e07ac1349a..576b2cd7fda73f 100644 --- a/test/integration/fixtures/google-docs-with-comments-out.html +++ b/test/integration/fixtures/google-docs-with-comments-out.html @@ -7,7 +7,7 @@ <h2>This is a <em>heading</em></h2> <!-- /wp:heading --> <!-- wp:paragraph --> -<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, <s>strikethrough</s>, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> +<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, strikethrough, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> <!-- /wp:paragraph --> <!-- wp:list --> diff --git a/test/integration/fixtures/list-with-attributes.html b/test/integration/fixtures/list-with-attributes.html deleted file mode 100644 index 7114d2da756938..00000000000000 --- a/test/integration/fixtures/list-with-attributes.html +++ /dev/null @@ -1,7 +0,0 @@ -<ol start="2" reversed type="i"> - <li>1 - <ol start="2" reversed type="i"> - <li>1</li> - </ol> - </li> -</ol> diff --git a/test/integration/fixtures/ms-word-out.html b/test/integration/fixtures/ms-word-out.html index 47f7cab83ae73f..427e12686ad625 100644 --- a/test/integration/fixtures/ms-word-out.html +++ b/test/integration/fixtures/ms-word-out.html @@ -24,8 +24,8 @@ <h2>This is a heading level 2</h2> <ul><li>A</li><li>Bulleted<ul><li>Indented</li></ul></li><li>List</li></ul> <!-- /wp:list --> -<!-- wp:list {"ordered":true,"type":"1"} --> -<ol type="1"><li>One</li><li>Two</li><li>Three</li></ol> +<!-- wp:list {"ordered":true} --> +<ol><li>One</li><li>Two</li><li>Three</li></ol> <!-- /wp:list --> <!-- wp:table --> diff --git a/test/integration/full-content/full-content.test.js b/test/integration/full-content/full-content.test.js index cab70d134b3720..1a50c84a834503 100644 --- a/test/integration/full-content/full-content.test.js +++ b/test/integration/full-content/full-content.test.js @@ -49,11 +49,7 @@ function normalizeParsedBlocks( blocks ) { describe( 'full post content fixture', () => { beforeAll( () => { unstable__bootstrapServerSideBlockDefinitions( require( './server-registered.json' ) ); - const settings = { - __experimentalEnableLegacyWidgetBlock: true, - __experimentalEnableMenuBlock: true, - __experimentalEnableFullSiteEditing: true, - }; + const settings = { __experimentalEnableLegacyWidgetBlock: true, __experimentalEnableMenuBlock: true }; // Load all hooks that modify blocks require( '../../../packages/editor/src/hooks' ); registerCoreBlocks(); diff --git a/test/integration/full-content/server-registered.json b/test/integration/full-content/server-registered.json index 9d17c64f5d6ba5..e11fe0283b44a5 100644 --- a/test/integration/full-content/server-registered.json +++ b/test/integration/full-content/server-registered.json @@ -1 +1 @@ -{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/navigation-menu":{"category":"layout","attributes":{"automaticallyAdd":{"type":"boolean","default":false}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/social-link-amazon":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"amazon"}}},"core\/social-link-bandcamp":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"bandcamp"}}},"core\/social-link-behance":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"behance"}}},"core\/social-link-chain":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"chain"}}},"core\/social-link-codepen":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"codepen"}}},"core\/social-link-deviantart":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"deviantart"}}},"core\/social-link-dribbble":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"dribbble"}}},"core\/social-link-dropbox":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"dropbox"}}},"core\/social-link-etsy":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"etsy"}}},"core\/social-link-facebook":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"facebook"}}},"core\/social-link-feed":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"feed"}}},"core\/social-link-fivehundredpx":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"fivehundredpx"}}},"core\/social-link-flickr":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"flickr"}}},"core\/social-link-foursquare":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"foursquare"}}},"core\/social-link-goodreads":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"goodreads"}}},"core\/social-link-google":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"google"}}},"core\/social-link-github":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"github"}}},"core\/social-link-instagram":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"instagram"}}},"core\/social-link-lastfm":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"lastfm"}}},"core\/social-link-linkedin":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"linkedin"}}},"core\/social-link-mail":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"mail"}}},"core\/social-link-mastodon":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"mastodon"}}},"core\/social-link-meetup":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"meetup"}}},"core\/social-link-medium":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"medium"}}},"core\/social-link-pinterest":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"pinterest"}}},"core\/social-link-pocket":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"pocket"}}},"core\/social-link-reddit":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"reddit"}}},"core\/social-link-skype":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"skype"}}},"core\/social-link-snapchat":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"snapchat"}}},"core\/social-link-soundcloud":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"soundcloud"}}},"core\/social-link-spotify":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"spotify"}}},"core\/social-link-tumblr":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"tumblr"}}},"core\/social-link-twitch":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"twitch"}}},"core\/social-link-twitter":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"twitter"}}},"core\/social-link-vimeo":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"vimeo"}}},"core\/social-link-vk":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"vk"}}},"core\/social-link-wordpress":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"wordpress"}}},"core\/social-link-yelp":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"yelp"}}},"core\/social-link-youtube":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"youtube"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file +{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/navigation-menu":{"category":"layout","attributes":{"automaticallyAdd":{"type":"boolean","default":false}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file diff --git a/test/integration/shortcode-converter.test.js b/test/integration/shortcode-converter.test.js index 1b0ce7c30947d9..2f0e5ab632fa74 100644 --- a/test/integration/shortcode-converter.test.js +++ b/test/integration/shortcode-converter.test.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { registerCoreBlocks } from '@wordpress/block-library'; -import { createBlock, registerBlockType } from '@wordpress/blocks'; +import { createBlock } from '@wordpress/blocks'; /** * Internal dependencies @@ -12,34 +12,6 @@ import segmentHTMLToShortcodeBlock from '../../packages/blocks/src/api/raw-handl describe( 'segmentHTMLToShortcodeBlock', () => { beforeAll( () => { registerCoreBlocks(); - registerBlockType( 'test/gallery', { - title: 'Test Gallery', - category: 'common', - attributes: { - ids: { - type: 'array', - default: [], - }, - }, - transforms: { - from: [ - { - type: 'shortcode', - tag: [ 'my-gallery', 'my-bunch-of-images' ], - attributes: { - ids: { - type: 'array', - shortcode: ( { named: { ids } } ) => - ids.split( ',' ).map( ( id ) => ( - parseInt( id, 10 ) - ) ), - }, - }, - }, - ], - }, - save: () => null, - } ); } ); it( 'should convert a standalone shortcode between two paragraphs', () => { @@ -129,15 +101,4 @@ describe( 'segmentHTMLToShortcodeBlock', () => { expect( transformed[ 8 ] ).toEqual( '</p>' ); expect( transformed ).toHaveLength( 9 ); } ); - - it( 'should convert regardless of shortcode alias', () => { - const original = `<p>[my-gallery ids="1,2,3"]</p> -<p>[my-bunch-of-images ids="4,5,6"]</p>`; - const transformed = segmentHTMLToShortcodeBlock( original, 0 ); - expect( transformed[ 0 ] ).toBe( '<p>' ); - expect( transformed[ 1 ] ).toHaveProperty( 'name', 'test/gallery' ); - expect( transformed[ 2 ] ).toBe( '</p>\n<p>' ); - expect( transformed[ 3 ] ).toHaveProperty( 'name', 'test/gallery' ); - expect( transformed[ 4 ] ).toBe( '</p>' ); - } ); } ); diff --git a/test/native/setup.js b/test/native/setup.js index f1e507f38ba399..60fe7194c0aa60 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -19,8 +19,6 @@ jest.mock( 'react-native-gutenberg-bridge', () => { requestMediaPickFromMediaLibrary: jest.fn(), requestMediaPickFromDeviceLibrary: jest.fn(), requestMediaPickFromDeviceCamera: jest.fn(), - getOtherMediaOptions: jest.fn(), - requestOtherMediaPickFrom: jest.fn(), }; } ); From f29261d9e4884dc5e2b46a71ed40d9093df33b50 Mon Sep 17 00:00:00 2001 From: Ryan Welcher <ryan.welcher@10up.com> Date: Mon, 14 Oct 2019 11:43:43 -0400 Subject: [PATCH 010/113] Adds correct escaping for urls (#17932) --- packages/block-library/src/social-link/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/social-link/index.php b/packages/block-library/src/social-link/index.php index 4d04c9cd1c12c4..86d83b685e21e8 100644 --- a/packages/block-library/src/social-link/index.php +++ b/packages/block-library/src/social-link/index.php @@ -22,7 +22,7 @@ function render_core_social_link( $attributes ) { } $icon = core_social_link_get_icon( $site ); - return '<li class="wp-social-link wp-social-link-' . $site . '"><a href="' . esc_attr( $url ) . '"> ' . $icon . '</a></li>'; + return '<li class="wp-social-link wp-social-link-' . $site . '"><a href="' . esc_url( $url ) . '"> ' . $icon . '</a></li>'; } /** From b972e54ac0d8209610002313af7704f681802d3a Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Mon, 14 Oct 2019 19:52:15 +0100 Subject: [PATCH 011/113] Add an apiFetch middleware to automatically handle media upload failures (#17858) * Add an apiFetch middleware to automatically handle media upload failures * Remove the attachement on failures * Handle errors properly * limit the media upload middleware to the 500 responses * Fix the error handling and unit tests * Api Fetch: Check for 502s and parse uncaught errors in Media Upload middleware. --- lib/client-assets.php | 3 +- packages/api-fetch/src/index.js | 50 ++----------- .../api-fetch/src/middlewares/media-upload.js | 74 +++++++++++++++++++ packages/api-fetch/src/utils/response.js | 70 ++++++++++++++++++ 4 files changed, 151 insertions(+), 46 deletions(-) create mode 100644 packages/api-fetch/src/middlewares/media-upload.js create mode 100644 packages/api-fetch/src/utils/response.js diff --git a/lib/client-assets.php b/lib/client-assets.php index 327e2f436897f2..c4c63ecf7474f7 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -244,7 +244,8 @@ function gutenberg_register_scripts_and_styles() { sprintf( 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . - 'wp.apiFetch.nonceEndpoint = "%s";', + 'wp.apiFetch.nonceEndpoint = "%s";' . + 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) ), diff --git a/packages/api-fetch/src/index.js b/packages/api-fetch/src/index.js index 7535d2117b2f24..dc7dda91fa1e60 100644 --- a/packages/api-fetch/src/index.js +++ b/packages/api-fetch/src/index.js @@ -1,8 +1,3 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ @@ -13,6 +8,8 @@ import fetchAllMiddleware from './middlewares/fetch-all-middleware'; import namespaceEndpointMiddleware from './middlewares/namespace-endpoint'; import httpV1Middleware from './middlewares/http-v1'; import userLocaleMiddleware from './middlewares/user-locale'; +import mediaUploadMiddleware from './middlewares/media-upload'; +import { parseResponseAndNormalizeError, parseAndThrowError } from './utils/response'; /** * Default set of header values which should be sent with every request unless @@ -80,48 +77,10 @@ const defaultFetchHandler = ( nextOptions ) => { } ); - const parseResponse = ( response ) => { - if ( parse ) { - if ( response.status === 204 ) { - return null; - } - - return response.json ? response.json() : Promise.reject( response ); - } - - return response; - }; - return responsePromise .then( checkStatus ) - .then( parseResponse ) - .catch( ( response ) => { - if ( ! parse ) { - throw response; - } - - const invalidJsonError = { - code: 'invalid_json', - message: __( 'The response is not a valid JSON response.' ), - }; - - if ( ! response || ! response.json ) { - throw invalidJsonError; - } - - return response.json() - .catch( () => { - throw invalidJsonError; - } ) - .then( ( error ) => { - const unknownError = { - code: 'unknown_error', - message: __( 'An unknown error occurred.' ), - }; - - throw error || unknownError; - } ); - } ); + .catch( ( response ) => parseAndThrowError( response, parse ) ) + .then( ( response ) => parseResponseAndNormalizeError( response, parse ) ); }; let fetchHandler = defaultFetchHandler; @@ -179,5 +138,6 @@ apiFetch.createNonceMiddleware = createNonceMiddleware; apiFetch.createPreloadingMiddleware = createPreloadingMiddleware; apiFetch.createRootURLMiddleware = createRootURLMiddleware; apiFetch.fetchAllMiddleware = fetchAllMiddleware; +apiFetch.mediaUploadMiddleware = mediaUploadMiddleware; export default apiFetch; diff --git a/packages/api-fetch/src/middlewares/media-upload.js b/packages/api-fetch/src/middlewares/media-upload.js new file mode 100644 index 00000000000000..b7a14d6b5b050a --- /dev/null +++ b/packages/api-fetch/src/middlewares/media-upload.js @@ -0,0 +1,74 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { + parseAndThrowError, + parseResponseAndNormalizeError, +} from '../utils/response'; + +/** + * Middleware handling media upload failures and retries. + * + * @param {Object} options Fetch options. + * @param {Function} next [description] + * + * @return {*} The evaluated result of the remaining middleware chain. + */ +function mediaUploadMiddleware( options, next ) { + const isMediaUploadRequest = + ( options.path && options.path.indexOf( '/wp/v2/media' ) !== -1 ) || + ( options.url && options.url.indexOf( '/wp/v2/media' ) !== -1 ); + + if ( ! isMediaUploadRequest ) { + return next( options, next ); + } + let retries = 0; + const maxRetries = 5; + + const postProcess = ( attachmentId ) => { + retries++; + return next( { + path: `/wp/v2/media/${ attachmentId }/post-process`, + method: 'POST', + data: { action: 'create-image-subsizes' }, + parse: false, + } ) + .catch( () => { + if ( retries < maxRetries ) { + return postProcess( attachmentId ); + } + next( { + path: `/wp/v2/media/${ attachmentId }?force=true`, + method: 'DELETE', + } ); + + return Promise.reject(); + } ); + }; + + return next( { ...options, parse: false } ) + .catch( ( response ) => { + const attachmentId = response.headers.get( 'x-wp-upload-attachment-id' ); + if ( ( response.status === 500 || response.status === 502 ) && attachmentId ) { + return postProcess( attachmentId ).catch( () => { + if ( options.parse !== false ) { + return Promise.reject( { + code: 'post_process', + message: __( 'Media upload failed. If this is a photo or a large image, please scale it down and try again.' ), + } ); + } + + return Promise.reject( response ); + } ); + } + return parseAndThrowError( response, options.parse ); + } ) + .then( ( response ) => parseResponseAndNormalizeError( response, options.parse ) ); +} + +export default mediaUploadMiddleware; diff --git a/packages/api-fetch/src/utils/response.js b/packages/api-fetch/src/utils/response.js new file mode 100644 index 00000000000000..bb7b79ce2f8254 --- /dev/null +++ b/packages/api-fetch/src/utils/response.js @@ -0,0 +1,70 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Parses the apiFetch response. + * + * @param {Response} response + * @param {boolean} shouldParseResponse + * + * @return {Promise} Parsed response + */ +const parseResponse = ( response, shouldParseResponse = true ) => { + if ( shouldParseResponse ) { + if ( response.status === 204 ) { + return null; + } + + return response.json ? response.json() : Promise.reject( response ); + } + + return response; +}; + +const parseJsonAndNormalizeError = ( response ) => { + const invalidJsonError = { + code: 'invalid_json', + message: __( 'The response is not a valid JSON response.' ), + }; + + if ( ! response || ! response.json ) { + throw invalidJsonError; + } + + return response.json() + .catch( () => { + throw invalidJsonError; + } ); +}; + +/** + * Parses the apiFetch response properly and normalize response errors. + * + * @param {Response} response + * @param {boolean} shouldParseResponse + * + * @return {Promise} Parsed response. + */ +export const parseResponseAndNormalizeError = ( response, shouldParseResponse = true ) => { + return Promise.resolve( parseResponse( response, shouldParseResponse ) ) + .catch( ( res ) => parseAndThrowError( res, shouldParseResponse ) ); +}; + +export function parseAndThrowError( response, shouldParseResponse = true ) { + if ( ! shouldParseResponse ) { + throw response; + } + + return parseJsonAndNormalizeError( response ) + .then( ( error ) => { + const unknownError = { + code: 'unknown_error', + message: __( 'An unknown error occurred.' ), + }; + + throw error || unknownError; + } ); +} + From 7666524f8d34f076a63cb3ea3b9664b845c6e800 Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Mon, 14 Oct 2019 20:03:33 +0100 Subject: [PATCH 012/113] Fix: Gradient presets to verify some MU kses rules (#17940) --- packages/block-editor/src/store/defaults.js | 36 ++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index 06eabc9f6f11f4..abc68fa5bf411f 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -155,76 +155,76 @@ export const SETTINGS_DEFAULTS = { gradients: [ { name: __( 'Vivid cyan blue to vivid purple' ), - gradient: 'linear-gradient(135deg, rgba(6, 147, 227, 1) 0%, rgb(155, 81, 224) 100%)', + gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', }, { name: __( 'Vivid green cyan to vivid cyan blue' ), - gradient: 'linear-gradient(135deg, rgba(0, 208, 132, 1) 0%, rgba(6, 147, 227, 1) 100%)', + gradient: 'linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)', }, { name: __( 'Light green cyan to vivid green cyan' ), - gradient: 'linear-gradient(135deg, rgb(122, 220, 180) 0%, rgb(0, 208, 130) 100%)', + gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', }, { name: __( 'Luminous vivid amber to luminous vivid orange' ), - gradient: 'linear-gradient(135deg, rgba(252, 185, 0, 1) 0%, rgba(255, 105, 0, 1) 100%)', + gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)', }, { name: __( 'Luminous vivid orange to vivid red' ), - gradient: 'linear-gradient(135deg, rgba(255, 105, 0, 1) 0%, rgb(207, 46, 46) 100%)', + gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)', }, { name: __( 'Very light gray to cyan bluish gray' ), - gradient: 'linear-gradient(135deg, rgb(238, 238, 238) 0%, rgb(169, 184, 195)', + gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)', }, // The following use new, customized colors. { name: __( 'Cool to warm spectrum' ), - gradient: 'linear-gradient(135deg, rgb(74, 234, 220), rgb(151, 120, 209), rgb(207, 42, 186), rgb(238, 44, 130), rgb(251, 105, 98),rgb(254, 248, 76)', + gradient: 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)', }, { name: __( 'Blush light purple' ), - gradient: 'linear-gradient(135deg, rgb(255, 206, 236), rgb(152, 150, 240)', + gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)', }, { name: __( 'Blush bordeaux' ), - gradient: 'linear-gradient(135deg, rgb(254, 205, 165), rgb(254, 45, 45), rgb(107, 0, 62)', + gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)', }, { name: __( 'Purple crush' ), - gradient: 'linear-gradient(135deg, rgb(52, 226, 228), rgb(71, 33, 251), rgb(171, 29, 254)', + gradient: 'linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%)', }, { name: __( 'Luminous dusk' ), - gradient: 'linear-gradient(135deg, rgb(255, 203, 112), rgb(199, 81, 192), rgb(65, 88, 208)', + gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)', }, { name: __( 'Hazy dawn' ), - gradient: 'linear-gradient(135deg, rgb(250, 172, 168), rgb(218, 208, 236)', + gradient: 'linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%)', }, { name: __( 'Pale ocean' ), - gradient: 'linear-gradient(135deg, rgb(255, 245, 203), rgb(182, 227, 212), rgb(51, 167, 181)', + gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)', }, { name: __( 'Electric grass' ), - gradient: 'linear-gradient(135deg, rgb(202, 248, 128), rgb(113, 206, 126)', + gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)', }, { name: __( 'Subdued olive' ), - gradient: 'linear-gradient(135deg, rgb(250, 250, 225), rgb(103, 166, 113)', + gradient: 'linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%)', }, { name: __( 'Atomic cream' ), - gradient: 'linear-gradient(135deg, rgb(253, 215, 154), rgb(0, 74, 89)', + gradient: 'linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%)', }, { name: __( 'Nightshade' ), - gradient: 'linear-gradient(135deg, rgb(51, 9, 104), rgb(49, 205, 207)', + gradient: 'linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%)', }, { name: __( 'Midnight' ), - gradient: 'linear-gradient(135deg, rgb(2, 3, 129), rgb(40, 116, 252)', + gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)', }, ], }; From cdf3ff3b3e43add56411941ff52836c13690ea01 Mon Sep 17 00:00:00 2001 From: epiqueras <epiquerass@gmail.com> Date: Mon, 14 Oct 2019 12:19:47 -0700 Subject: [PATCH 013/113] Bump plugin version to 6.7.0-rc.1 --- 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 53333e55831917..a0248b5bc3fa8b 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: 6.6.0 + * Version: 6.7.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index eca7bdfbb2a7ef..d4020914acd3a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.6.0", + "version": "6.7.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 31d63d691e3b5c..89175f6b3dd0a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.6.0", + "version": "6.7.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", From c2f6170360aad2674d5892f8fc741ef90b5d0bf4 Mon Sep 17 00:00:00 2001 From: Krystyna Lopez <49209351+lozinska@users.noreply.github.com> Date: Tue, 15 Oct 2019 02:30:36 -0400 Subject: [PATCH 014/113] Code Style: Change name of accumulated variables when using reduce function (#17893) * Fix issue-7378 - change name of accumulated variables when using reduce function * fix issue-7378 - update variables names * fix issue-7378 - update variables names --- packages/block-editor/src/store/selectors.js | 4 ++-- packages/block-library/src/columns/deprecated.js | 10 +++++----- packages/block-library/src/columns/utils.js | 4 ++-- packages/block-library/src/group/index.js | 4 ++-- packages/block-library/src/index.native.js | 6 +++--- packages/blocks/src/api/factory.js | 16 ++++++++-------- packages/blocks/src/api/parser.js | 6 +++--- packages/blocks/src/api/serializer.js | 13 ++++++------- packages/core-data/src/queried-data/reducer.js | 6 +++--- packages/core-data/src/selectors.js | 6 +++--- packages/data/src/plugins/persistence/index.js | 2 +- .../post-taxonomies/flat-term-selector.js | 6 +++--- packages/element/src/react.js | 6 +++--- packages/rich-text/src/test/helpers/index.js | 2 +- 14 files changed, 45 insertions(+), 46 deletions(-) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d0dd7a69a15973..7f03542fd841da 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -237,9 +237,9 @@ export const getGlobalBlockCount = createSelector( if ( ! blockName ) { return clientIds.length; } - return reduce( clientIds, ( count, clientId ) => { + return reduce( clientIds, ( accumulator, clientId ) => { const block = state.blocks.byClientId[ clientId ]; - return block.name === blockName ? count + 1 : count; + return block.name === blockName ? accumulator + 1 : accumulator; }, 0 ); }, ( state ) => [ diff --git a/packages/block-library/src/columns/deprecated.js b/packages/block-library/src/columns/deprecated.js index 56ffe5d90bc6a1..a344f72eaf69f3 100644 --- a/packages/block-library/src/columns/deprecated.js +++ b/packages/block-library/src/columns/deprecated.js @@ -66,7 +66,7 @@ export default [ ) ); }, migrate( attributes, innerBlocks ) { - const columns = innerBlocks.reduce( ( result, innerBlock ) => { + const columns = innerBlocks.reduce( ( accumulator, innerBlock ) => { const { originalContent } = innerBlock; let columnIndex = getDeprecatedLayoutColumn( originalContent ); @@ -74,13 +74,13 @@ export default [ columnIndex = 0; } - if ( ! result[ columnIndex ] ) { - result[ columnIndex ] = []; + if ( ! accumulator[ columnIndex ] ) { + accumulator[ columnIndex ] = []; } - result[ columnIndex ].push( innerBlock ); + accumulator[ columnIndex ].push( innerBlock ); - return result; + return accumulator; }, [] ); const migratedInnerBlocks = columns.map( ( columnBlocks ) => ( diff --git a/packages/block-library/src/columns/utils.js b/packages/block-library/src/columns/utils.js index 77a0b7cf4375a8..a6773d469c98f7 100644 --- a/packages/block-library/src/columns/utils.js +++ b/packages/block-library/src/columns/utils.js @@ -87,9 +87,9 @@ export function getTotalColumnsWidth( blocks, totalBlockCount = blocks.length ) * @return {Object<string,number>} Column widths. */ export function getColumnWidths( blocks, totalBlockCount = blocks.length ) { - return blocks.reduce( ( result, block ) => { + return blocks.reduce( ( accumulator, block ) => { const width = getEffectiveColumnWidth( block, totalBlockCount ); - return Object.assign( result, { [ block.clientId ]: width } ); + return Object.assign( accumulator, { [ block.clientId ]: width } ); }, {} ); } diff --git a/packages/block-library/src/group/index.js b/packages/block-library/src/group/index.js index d3bcfb86dca119..956ded85aa22a1 100644 --- a/packages/block-library/src/group/index.js +++ b/packages/block-library/src/group/index.js @@ -97,9 +97,9 @@ export const settings = { const alignments = [ 'wide', 'full' ]; // Determine the widest setting of all the blocks to be grouped - const widestAlignment = blocks.reduce( ( result, block ) => { + const widestAlignment = blocks.reduce( ( accumulator, block ) => { const { align } = block.attributes; - return alignments.indexOf( align ) > alignments.indexOf( result ) ? align : result; + return alignments.indexOf( align ) > alignments.indexOf( accumulator ) ? align : accumulator; }, undefined ); // Clone the Blocks to be Grouped diff --git a/packages/block-library/src/index.native.js b/packages/block-library/src/index.native.js index 2702becc3a8c31..0d06a9df9f11af 100644 --- a/packages/block-library/src/index.native.js +++ b/packages/block-library/src/index.native.js @@ -96,9 +96,9 @@ export const coreBlocks = [ textColumns, verse, video, -].reduce( ( memo, block ) => { - memo[ block.name ] = block; - return memo; +].reduce( ( accumulator, block ) => { + accumulator[ block.name ] = block; + return accumulator; }, {} ); /** diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index fae2e0e4da9c06..e793800ecb1362 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -44,26 +44,26 @@ export function createBlock( name, attributes = {}, innerBlocks = [] ) { // Ensure attributes contains only values defined by block type, and merge // default values for missing attributes. - const sanitizedAttributes = reduce( blockType.attributes, ( result, schema, key ) => { + const sanitizedAttributes = reduce( blockType.attributes, ( accumulator, schema, key ) => { const value = attributes[ key ]; if ( undefined !== value ) { - result[ key ] = value; + accumulator[ key ] = value; } else if ( schema.hasOwnProperty( 'default' ) ) { - result[ key ] = schema.default; + accumulator[ key ] = schema.default; } if ( [ 'node', 'children' ].indexOf( schema.source ) !== -1 ) { // Ensure value passed is always an array, which we're expecting in // the RichText component to handle the deprecated value. - if ( typeof result[ key ] === 'string' ) { - result[ key ] = [ result[ key ] ]; - } else if ( ! Array.isArray( result[ key ] ) ) { - result[ key ] = []; + if ( typeof accumulator[ key ] === 'string' ) { + accumulator[ key ] = [ accumulator[ key ] ]; + } else if ( ! Array.isArray( accumulator[ key ] ) ) { + accumulator[ key ] = []; } } - return result; + return accumulator; }, {} ); const clientId = uuid(); diff --git a/packages/blocks/src/api/parser.js b/packages/blocks/src/api/parser.js index 89b4f5ee5cc9f9..6300eac329f153 100644 --- a/packages/blocks/src/api/parser.js +++ b/packages/blocks/src/api/parser.js @@ -565,12 +565,12 @@ export function serializeBlockNode( blockNode, options = {} ) { * @return {Function} An implementation which parses the post content. */ const createParse = ( parseImplementation ) => - ( content ) => parseImplementation( content ).reduce( ( memo, blockNode ) => { + ( content ) => parseImplementation( content ).reduce( ( accumulator, blockNode ) => { const block = createBlockWithFallback( blockNode ); if ( block ) { - memo.push( block ); + accumulator.push( block ); } - return memo; + return accumulator; }, [] ); /** diff --git a/packages/blocks/src/api/serializer.js b/packages/blocks/src/api/serializer.js index 1776a32e362999..98b3928962a44b 100644 --- a/packages/blocks/src/api/serializer.js +++ b/packages/blocks/src/api/serializer.js @@ -150,28 +150,27 @@ export function getSaveContent( blockTypeOrName, attributes, innerBlocks ) { * @return {Object<string,*>} Subset of attributes for comment serialization. */ export function getCommentAttributes( blockType, attributes ) { - return reduce( blockType.attributes, ( result, attributeSchema, key ) => { + return reduce( blockType.attributes, ( accumulator, attributeSchema, key ) => { const value = attributes[ key ]; - // Ignore undefined values. if ( undefined === value ) { - return result; + return accumulator; } // Ignore all attributes but the ones with an "undefined" source // "undefined" source refers to attributes saved in the block comment. if ( attributeSchema.source !== undefined ) { - return result; + return accumulator; } // Ignore default value. if ( 'default' in attributeSchema && attributeSchema.default === value ) { - return result; + return accumulator; } // Otherwise, include in comment set. - result[ key ] = value; - return result; + accumulator[ key ] = value; + return accumulator; }, {} ); } diff --git a/packages/core-data/src/queried-data/reducer.js b/packages/core-data/src/queried-data/reducer.js index 0c3256e9a8f987..36da4465bb922d 100644 --- a/packages/core-data/src/queried-data/reducer.js +++ b/packages/core-data/src/queried-data/reducer.js @@ -74,10 +74,10 @@ function items( state = {}, action ) { const key = action.key || DEFAULT_ENTITY_KEY; return { ...state, - ...action.items.reduce( ( acc, value ) => { + ...action.items.reduce( ( accumulator, value ) => { const itemId = value[ key ]; - acc[ itemId ] = conservativeMapItem( state[ itemId ], value ); - return acc; + accumulator[ itemId ] = conservativeMapItem( state[ itemId ], value ); + return accumulator; }, {} ), }; } diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js index 4c61d59220843f..3974d66c83b60b 100644 --- a/packages/core-data/src/selectors.js +++ b/packages/core-data/src/selectors.js @@ -123,12 +123,12 @@ export const getRawEntityRecord = createSelector( const record = getEntityRecord( state, kind, name, key ); return ( record && - Object.keys( record ).reduce( ( acc, _key ) => { + Object.keys( record ).reduce( ( accumulator, _key ) => { // Because edits are the "raw" attribute values, // we return those from record selectors to make rendering, // comparisons, and joins with edits easier. - acc[ _key ] = get( record[ _key ], 'raw', record[ _key ] ); - return acc; + accumulator[ _key ] = get( record[ _key ], 'raw', record[ _key ] ); + return accumulator; }, {} ) ); }, diff --git a/packages/data/src/plugins/persistence/index.js b/packages/data/src/plugins/persistence/index.js index a0c910f8a73bca..871a7e56133594 100644 --- a/packages/data/src/plugins/persistence/index.js +++ b/packages/data/src/plugins/persistence/index.js @@ -138,7 +138,7 @@ const persistencePlugin = function( registry, pluginOptions ) { // to leverage its behavior of returning the same object when none // of the property values changes. This allows a strict reference // equality to bypass a persistence set on an unchanging state. - const reducers = keys.reduce( ( result, key ) => Object.assign( result, { + const reducers = keys.reduce( ( accumulator, key ) => Object.assign( accumulator, { [ key ]: ( state, action ) => action.nextState[ key ], } ), {} ); diff --git a/packages/editor/src/components/post-taxonomies/flat-term-selector.js b/packages/editor/src/components/post-taxonomies/flat-term-selector.js index 3b4c1c8a0c2926..06db56eef101f5 100644 --- a/packages/editor/src/components/post-taxonomies/flat-term-selector.js +++ b/packages/editor/src/components/post-taxonomies/flat-term-selector.js @@ -128,13 +128,13 @@ class FlatTermSelector extends Component { } updateSelectedTerms( terms = [] ) { - const selectedTerms = terms.reduce( ( result, termId ) => { + const selectedTerms = terms.reduce( ( accumulator, termId ) => { const termObject = find( this.state.availableTerms, ( term ) => term.id === termId ); if ( termObject ) { - result.push( termObject.name ); + accumulator.push( termObject.name ); } - return result; + return accumulator; }, [] ); this.setState( { selectedTerms, diff --git a/packages/element/src/react.js b/packages/element/src/react.js index 561776257f388e..722085de1fc776 100644 --- a/packages/element/src/react.js +++ b/packages/element/src/react.js @@ -185,7 +185,7 @@ export { Suspense }; * @return {Array} The concatenated value. */ export function concatChildren( ...childrenArguments ) { - return childrenArguments.reduce( ( result, children, i ) => { + return childrenArguments.reduce( ( accumulator, children, i ) => { Children.forEach( children, ( child, j ) => { if ( child && 'string' !== typeof child ) { child = cloneElement( child, { @@ -193,10 +193,10 @@ export function concatChildren( ...childrenArguments ) { } ); } - result.push( child ); + accumulator.push( child ); } ); - return result; + return accumulator; }, [] ); } diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js index fe97f00d245f53..604ca0c518ec8a 100644 --- a/packages/rich-text/src/test/helpers/index.js +++ b/packages/rich-text/src/test/helpers/index.js @@ -4,7 +4,7 @@ import { ZWNBSP } from '../../special-characters'; export function getSparseArrayLength( array ) { - return array.reduce( ( i ) => i + 1, 0 ); + return array.reduce( ( accumulator ) => accumulator + 1, 0 ); } const em = { type: 'em' }; From 8b9ffec7d6412e8546e971159d07d08a1e333b04 Mon Sep 17 00:00:00 2001 From: Michael Joseph Panaga <donmhico@gmail.com> Date: Tue, 15 Oct 2019 15:32:43 +0800 Subject: [PATCH 015/113] Fix:Image Block: Hide 'noreferrer' and 'noopener' in Link Rel (#17398) * Update the regex used when removing NEW_TAB_REL and add trimming (+2 squashed commits) Squashed commits: [cf71759c3] Accessibility:Image Block:Link Editor: Move Link Rel field below Open new tab toggle [310a23c33] Fix:Image Block:Link Editor: Hide 'noreferrer' and 'noopener' in Link Rel field * post rebases fixes Co-authored-by: Jorge Costa <jorge.costa@developer.pt> --- packages/block-library/src/image/constants.js | 2 +- packages/block-library/src/image/edit.js | 15 +++---- packages/block-library/src/image/save.js | 5 ++- packages/block-library/src/image/utils.js | 40 +++++++++++++++++-- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/image/constants.js b/packages/block-library/src/image/constants.js index cd5e82b323bed5..ec8c41b8b09c31 100644 --- a/packages/block-library/src/image/constants.js +++ b/packages/block-library/src/image/constants.js @@ -3,6 +3,6 @@ export const LINK_DESTINATION_NONE = 'none'; export const LINK_DESTINATION_MEDIA = 'media'; export const LINK_DESTINATION_ATTACHMENT = 'attachment'; export const LINK_DESTINATION_CUSTOM = 'custom'; -export const NEW_TAB_REL = 'noreferrer noopener'; +export const NEW_TAB_REL = [ 'noreferrer', 'noopener' ]; export const ALLOWED_MEDIA_TYPES = [ 'image' ]; export const DEFAULT_SIZE_SLUG = 'large'; diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index b5779e71180e7d..fe51a775c4d271 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -72,7 +72,7 @@ import { speak } from '@wordpress/a11y'; import { createUpgradedEmbedBlock } from '../embed/util'; import icon from './icon'; import ImageSize from './image-size'; -import { getUpdatedLinkTargetSettings } from './utils'; +import { getUpdatedLinkTargetSettings, removeNewTabRel } from './utils'; /** * Module constants @@ -585,6 +585,7 @@ export class ImageEdit extends Component { sizeSlug, } = attributes; + const cleanRel = removeNewTabRel( rel ); const isExternal = isExternalImage( id, url ); const editImageIcon = ( <SVG width={ 20 } height={ 20 } viewBox="0 0 20 20"><Rect x={ 11 } y={ 3 } width={ 7 } height={ 5 } rx={ 1 } /><Rect x={ 2 } y={ 12 } width={ 7 } height={ 5 } rx={ 1 } /><Path d="M13,12h1a3,3,0,0,1-3,3v2a5,5,0,0,0,5-5h1L15,9Z" /><Path d="M4,8H3l2,3L7,8H6A3,3,0,0,1,9,5V3A5,5,0,0,0,4,8Z" /></SVG> ); const controls = ( @@ -617,18 +618,18 @@ export class ImageEdit extends Component { onChange={ this.onSetNewTab } checked={ linkTarget === '_blank' } /> <TextControl - label={ __( 'Link CSS Class' ) } - value={ linkClass || '' } + label={ __( 'Link Rel' ) } + value={ cleanRel || '' } + onChange={ this.onSetLinkRel } onKeyPress={ stopPropagation } onKeyDown={ stopPropagationRelevantKeys } - onChange={ this.onSetLinkClass } /> <TextControl - label={ __( 'Link Rel' ) } - value={ rel || '' } - onChange={ this.onSetLinkRel } + label={ __( 'Link CSS Class' ) } + value={ linkClass || '' } onKeyPress={ stopPropagation } onKeyDown={ stopPropagationRelevantKeys } + onChange={ this.onSetLinkClass } /> </> } diff --git a/packages/block-library/src/image/save.js b/packages/block-library/src/image/save.js index 01aff39769152b..b3976c76a8de85 100644 --- a/packages/block-library/src/image/save.js +++ b/packages/block-library/src/image/save.js @@ -2,6 +2,7 @@ * External dependencies */ import classnames from 'classnames'; +import { isEmpty } from 'lodash'; /** * WordPress dependencies @@ -24,6 +25,8 @@ export default function save( { attributes } ) { sizeSlug, } = attributes; + const newRel = isEmpty( rel ) ? undefined : rel; + const classes = classnames( { [ `align${ align }` ]: align, [ `size-${ sizeSlug }` ]: sizeSlug, @@ -47,7 +50,7 @@ export default function save( { attributes } ) { className={ linkClass } href={ href } target={ linkTarget } - rel={ rel } + rel={ newRel } > { image } </a> diff --git a/packages/block-library/src/image/utils.js b/packages/block-library/src/image/utils.js index 2cb9b8f5ca5c78..1e3e8a07fc3748 100644 --- a/packages/block-library/src/image/utils.js +++ b/packages/block-library/src/image/utils.js @@ -1,3 +1,11 @@ +/** + * External dependencies + */ +import { + isEmpty, + each, +} from 'lodash'; + /** * Internal dependencies */ @@ -12,6 +20,30 @@ export function calculatePreferedImageSize( image, container ) { return { width, height }; } +export function removeNewTabRel( currentRel ) { + let newRel = currentRel; + + if ( currentRel !== undefined && ! isEmpty( newRel ) ) { + if ( ! isEmpty( newRel ) ) { + each( NEW_TAB_REL, function( relVal ) { + const regExp = new RegExp( '\\b' + relVal + '\\b', 'gi' ); + newRel = newRel.replace( regExp, '' ); + } ); + + // Only trim if NEW_TAB_REL values was replaced. + if ( newRel !== currentRel ) { + newRel = newRel.trim(); + } + + if ( isEmpty( newRel ) ) { + newRel = undefined; + } + } + } + + return newRel; +} + /** * Helper to get the link target settings to be stored. * @@ -24,11 +56,11 @@ export function calculatePreferedImageSize( image, container ) { export function getUpdatedLinkTargetSettings( value, { rel } ) { const linkTarget = value ? '_blank' : undefined; - let updatedRel = rel; - if ( linkTarget && ! rel ) { - updatedRel = NEW_TAB_REL; - } else if ( ! linkTarget && rel === NEW_TAB_REL ) { + let updatedRel; + if ( ! linkTarget && ! rel ) { updatedRel = undefined; + } else { + updatedRel = removeNewTabRel( rel ); } return { From a14acb56455b8661940cb75d3670e9f19baab52a Mon Sep 17 00:00:00 2001 From: Zebulan Stanphill <zebulanstanphill@protonmail.com> Date: Tue, 15 Oct 2019 04:11:22 -0500 Subject: [PATCH 016/113] Change Cover block min height input step size to 1 (#17927) --- packages/block-library/src/cover/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/cover/edit.js b/packages/block-library/src/cover/edit.js index 1994f4a57e0713..04d3f61220bbf0 100644 --- a/packages/block-library/src/cover/edit.js +++ b/packages/block-library/src/cover/edit.js @@ -110,7 +110,7 @@ const CoverHeightInput = withInstanceId( onBlur={ onBlurEvent } value={ temporaryInput !== null ? temporaryInput : value } min={ COVER_MIN_HEIGHT } - step="10" + step="1" /> </BaseControl> ); From 1a699c420fbd09742881f72da712627dc91ba2ea Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Tue, 15 Oct 2019 14:09:36 +0100 Subject: [PATCH 017/113] chore(release): publish - @wordpress/a11y@2.5.1 - @wordpress/annotations@1.7.2 - @wordpress/api-fetch@3.6.2 - @wordpress/autop@2.5.1 - @wordpress/babel-preset-default@4.6.2 - @wordpress/blob@2.5.1 - @wordpress/block-directory@1.0.2 - @wordpress/block-editor@3.2.2 - @wordpress/block-library@2.9.2 - @wordpress/block-serialization-default-parser@3.4.1 - @wordpress/block-serialization-spec-parser@3.3.1 - @wordpress/blocks@6.7.2 - @wordpress/components@8.3.2 - @wordpress/compose@3.7.2 - @wordpress/core-data@2.7.2 - @wordpress/data-controls@1.3.2 - @wordpress/data@4.9.2 - @wordpress/deprecated@2.6.1 - @wordpress/dom-ready@2.5.1 - @wordpress/dom@2.5.2 - @wordpress/e2e-test-utils@2.4.2 - @wordpress/e2e-tests@1.7.2 - @wordpress/edit-post@3.8.2 - @wordpress/edit-widgets@0.7.2 - @wordpress/editor@9.7.2 - @wordpress/element@2.8.2 - @wordpress/escape-html@1.5.1 - @wordpress/format-library@1.9.2 - @wordpress/is-shallow-equal@1.6.1 - @wordpress/keycodes@2.6.2 - @wordpress/list-reusable-blocks@1.8.2 - @wordpress/media-utils@1.2.2 - @wordpress/notices@1.8.2 - @wordpress/nux@3.7.2 - @wordpress/plugins@2.7.2 - @wordpress/priority-queue@1.3.1 - @wordpress/redux-routine@3.6.2 - @wordpress/rich-text@3.7.2 - @wordpress/scripts@5.1.0 - @wordpress/server-side-render@1.3.2 - @wordpress/url@2.8.1 - @wordpress/viewport@2.8.2 - @wordpress/wordcount@2.6.2 --- packages/a11y/package.json | 2 +- packages/annotations/package.json | 2 +- packages/api-fetch/package.json | 2 +- packages/autop/package.json | 2 +- packages/babel-preset-default/package.json | 2 +- packages/blob/package.json | 2 +- packages/block-directory/package.json | 2 +- packages/block-editor/package.json | 2 +- packages/block-library/package.json | 2 +- packages/block-serialization-default-parser/package.json | 2 +- packages/block-serialization-spec-parser/package.json | 2 +- packages/blocks/package.json | 2 +- packages/components/package.json | 2 +- packages/compose/package.json | 2 +- packages/core-data/package.json | 2 +- packages/data-controls/package.json | 2 +- packages/data/package.json | 2 +- packages/deprecated/package.json | 2 +- packages/dom-ready/package.json | 2 +- packages/dom/package.json | 2 +- packages/e2e-test-utils/package.json | 2 +- packages/e2e-tests/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/edit-widgets/package.json | 2 +- packages/editor/package.json | 2 +- packages/element/package.json | 2 +- packages/escape-html/package.json | 2 +- packages/format-library/package.json | 2 +- packages/is-shallow-equal/package.json | 2 +- packages/keycodes/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/media-utils/package.json | 2 +- packages/notices/package.json | 2 +- packages/nux/package.json | 2 +- packages/plugins/package.json | 2 +- packages/priority-queue/package.json | 2 +- packages/redux-routine/package.json | 2 +- packages/rich-text/package.json | 2 +- packages/scripts/package.json | 2 +- packages/server-side-render/package.json | 2 +- packages/url/package.json | 2 +- packages/viewport/package.json | 2 +- packages/wordcount/package.json | 2 +- 43 files changed, 43 insertions(+), 43 deletions(-) diff --git a/packages/a11y/package.json b/packages/a11y/package.json index 546abcd609a520..eb2f11f3a971d8 100644 --- a/packages/a11y/package.json +++ b/packages/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/a11y", - "version": "2.5.0", + "version": "2.5.1", "description": "Accessibility (a11y) utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/annotations/package.json b/packages/annotations/package.json index 62608fae8a7b73..2f08cd7c0901bd 100644 --- a/packages/annotations/package.json +++ b/packages/annotations/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/annotations", - "version": "1.7.0", + "version": "1.7.2", "description": "Annotate content in the Gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index 26876a3e860239..f14917b7b78003 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "3.6.0", + "version": "3.6.2", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/autop/package.json b/packages/autop/package.json index 0f63cb48560d3c..ef57d2a3a0516b 100644 --- a/packages/autop/package.json +++ b/packages/autop/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/autop", - "version": "2.5.0", + "version": "2.5.1", "description": "WordPress's automatic paragraph functions `autop` and `removep`.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/babel-preset-default/package.json b/packages/babel-preset-default/package.json index e8f3df29218a58..c02981fc1316cc 100644 --- a/packages/babel-preset-default/package.json +++ b/packages/babel-preset-default/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/babel-preset-default", - "version": "4.6.0", + "version": "4.6.2", "description": "Default Babel preset for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blob/package.json b/packages/blob/package.json index 5d6682a3df85f1..4d04f47eb2a3c7 100644 --- a/packages/blob/package.json +++ b/packages/blob/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blob", - "version": "2.5.0", + "version": "2.5.1", "description": "Blob utilities for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 7c6af26534df97..d27e666e95a5c7 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "1.0.0", + "version": "1.0.2", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 8517b2126deadd..eaa7f50ceaf831 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "3.2.0", + "version": "3.2.2", "description": "Generic block editor.", "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 cf7b1171009db5..253fb60bdb6916 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "2.9.0", + "version": "2.9.2", "description": "Block library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-default-parser/package.json b/packages/block-serialization-default-parser/package.json index 924dc7e4ad552e..8f2695921aa110 100644 --- a/packages/block-serialization-default-parser/package.json +++ b/packages/block-serialization-default-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-default-parser", - "version": "3.4.0", + "version": "3.4.1", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index 28b1a0436de041..289e8b8e86afd4 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-serialization-spec-parser", - "version": "3.3.0", + "version": "3.3.1", "description": "Block serialization specification parser for WordPress posts.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 3456e2386251e0..30f3255b9188b7 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/blocks", - "version": "6.7.0", + "version": "6.7.2", "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 d19667eca46cf5..c542fc3a79a7e0 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/components", - "version": "8.3.0", + "version": "8.3.2", "description": "UI components for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/compose/package.json b/packages/compose/package.json index 827a0afb46eff7..045f193d1e5311 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/compose", - "version": "3.7.0", + "version": "3.7.2", "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 32fca25d8a2771..759d4df2d70b65 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "2.7.0", + "version": "2.7.2", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json index 8e74ef5a768b4c..e4a8154ac73f25 100644 --- a/packages/data-controls/package.json +++ b/packages/data-controls/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data-controls", - "version": "1.3.0", + "version": "1.3.2", "description": "A set of common controls for the @wordpress/data api.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data/package.json b/packages/data/package.json index 9eb21a7608146d..3812312f7dad8d 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data", - "version": "4.9.0", + "version": "4.9.2", "description": "Data module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/deprecated/package.json b/packages/deprecated/package.json index 654149a2f32208..7a0494fd4d54bb 100644 --- a/packages/deprecated/package.json +++ b/packages/deprecated/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/deprecated", - "version": "2.6.0", + "version": "2.6.1", "description": "Deprecation utility for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json index 33e1f9eca8283d..ff4900eca80a02 100644 --- a/packages/dom-ready/package.json +++ b/packages/dom-ready/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom-ready", - "version": "2.5.0", + "version": "2.5.1", "description": "Execute callback after the DOM is loaded.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/dom/package.json b/packages/dom/package.json index e5f1b9297eec16..b335970b2113bc 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/dom", - "version": "2.5.0", + "version": "2.5.2", "description": "DOM utilities module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index 7ddd91f1b73974..ab343497e14905 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils", - "version": "2.4.0", + "version": "2.4.2", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index 1fe2ee6a9464ba..aea246540c45b7 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "1.7.0", + "version": "1.7.2", "description": "End-To-End (E2E) tests 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 98fd08247be8f0..389d9d8f7c1848 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "3.8.0", + "version": "3.8.2", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index e5ba0beff046e2..f9b184f97cd986 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "0.7.0", + "version": "0.7.2", "private": true, "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", diff --git a/packages/editor/package.json b/packages/editor/package.json index 22e78a023ca3f6..98ad243772f9a1 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "9.7.0", + "version": "9.7.2", "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 187e80d149b4a5..c7e4ac61ff491c 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/element", - "version": "2.8.0", + "version": "2.8.2", "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 b93e62d2a76e42..19d4e1d0b895c5 100644 --- a/packages/escape-html/package.json +++ b/packages/escape-html/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/escape-html", - "version": "1.5.0", + "version": "1.5.1", "description": "Escape HTML utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index 50605fb08b7508..b9b6dbfa8156fc 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "1.9.0", + "version": "1.9.2", "description": "Format library for the WordPress editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/is-shallow-equal/package.json b/packages/is-shallow-equal/package.json index 3fabae7a1d053d..a164a7cdbb44f8 100644 --- a/packages/is-shallow-equal/package.json +++ b/packages/is-shallow-equal/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/is-shallow-equal", - "version": "1.6.0", + "version": "1.6.1", "description": "Test for shallow equality between two objects or arrays.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/keycodes/package.json b/packages/keycodes/package.json index ba8a5cbe103060..a62da6c45f89ba 100644 --- a/packages/keycodes/package.json +++ b/packages/keycodes/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/keycodes", - "version": "2.6.0", + "version": "2.6.2", "description": "Keycodes utilities for WordPress. Used to check for keyboard events across browsers/operating systems.", "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 6df9f6a7b996a0..4edf08437583de 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.8.0", + "version": "1.8.2", "description": "Adding Export/Import support to the reusable blocks listing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/media-utils/package.json b/packages/media-utils/package.json index 90ecc22a60a0c6..d406276cbdeeec 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/media-utils", - "version": "1.2.0", + "version": "1.2.2", "description": "WordPress Media Upload Utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/notices/package.json b/packages/notices/package.json index ed582e8ca7dc50..6840e145531d50 100644 --- a/packages/notices/package.json +++ b/packages/notices/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/notices", - "version": "1.8.0", + "version": "1.8.2", "description": "State management for notices.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/nux/package.json b/packages/nux/package.json index 858ddc289df131..913a16112bc36a 100644 --- a/packages/nux/package.json +++ b/packages/nux/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/nux", - "version": "3.7.0", + "version": "3.7.2", "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 f935e31b1b3de5..3c8ca7edfcb63e 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/plugins", - "version": "2.7.0", + "version": "2.7.2", "description": "Plugins module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/priority-queue/package.json b/packages/priority-queue/package.json index 16f8dbd988281f..de49d37c2fe9c3 100644 --- a/packages/priority-queue/package.json +++ b/packages/priority-queue/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/priority-queue", - "version": "1.3.0", + "version": "1.3.1", "description": "Generic browser priority queue.", "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 ee2c7d728eac8a..29e53534cf6cd8 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/redux-routine", - "version": "3.6.0", + "version": "3.6.2", "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 544d69294e90e4..4cf3ef016ddaf3 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/rich-text", - "version": "3.7.0", + "version": "3.7.2", "description": "Rich text value and manipulation API.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 70d180fb0e2514..fe37347258d872 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/scripts", - "version": "5.0.0", + "version": "5.1.0", "description": "Collection of reusable scripts for WordPress development.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index 99aa8807a8bf6c..f0bd3ab7efbfa9 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "1.3.0", + "version": "1.3.2", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/package.json b/packages/url/package.json index 9c0b1bcaeba066..456006fb1370a3 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "2.8.0", + "version": "2.8.1", "description": "WordPress URL utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/viewport/package.json b/packages/viewport/package.json index 5dd1af95cbe842..5cedb8e675caa4 100644 --- a/packages/viewport/package.json +++ b/packages/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/viewport", - "version": "2.8.0", + "version": "2.8.2", "description": "Viewport module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/wordcount/package.json b/packages/wordcount/package.json index 7201fbdc9760bc..7664cf8b99a0fc 100644 --- a/packages/wordcount/package.json +++ b/packages/wordcount/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/wordcount", - "version": "2.6.0", + "version": "2.6.2", "description": "WordPress word count utility.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 76958c4754337167c48997ac84d3734521db7aae Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Tue, 15 Oct 2019 14:14:37 +0100 Subject: [PATCH 018/113] Update changelogs after the npm release --- packages/edit-post/CHANGELOG.md | 2 +- packages/scripts/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/edit-post/CHANGELOG.md b/packages/edit-post/CHANGELOG.md index 69dd699b23426e..c1d1576e310bc5 100644 --- a/packages/edit-post/CHANGELOG.md +++ b/packages/edit-post/CHANGELOG.md @@ -1,4 +1,4 @@ -## Master +## 3.8.2 ### Bug Fixes diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 96e7ae747107c8..3d137bfb2b9fbc 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -1,4 +1,4 @@ -## Master +## 5.1.0 ### New Features From b3a552a2e7eaf19172d5a788f07186ece47596fe Mon Sep 17 00:00:00 2001 From: Glen Davies <glendaviesnz@users.noreply.github.com> Date: Wed, 16 Oct 2019 20:54:48 +1300 Subject: [PATCH 019/113] Prevent prependHttp from failing if url is not defined (#17928) * Check that url is defined before passing into prependHttp * Shift check from component to url lib --- packages/url/src/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/url/src/index.js b/packages/url/src/index.js index b4fa34efac51a6..2b549d6ba1dc4e 100644 --- a/packages/url/src/index.js +++ b/packages/url/src/index.js @@ -360,6 +360,10 @@ export function removeQueryArgs( url, ...args ) { * @return {string} The updated URL. */ export function prependHTTP( url ) { + if ( ! url ) { + return url; + } + url = url.trim(); if ( ! USABLE_HREF_REGEXP.test( url ) && ! EMAIL_REGEXP.test( url ) ) { return 'http://' + url; From 8f707849c11920643339966197aa4521795beea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <wp@iseulde.com> Date: Wed, 16 Oct 2019 09:57:47 +0200 Subject: [PATCH 020/113] List block: move default style (#17958) --- packages/block-library/src/editor.scss | 1 - packages/block-library/src/list/editor.scss | 5 ----- packages/editor/src/editor-styles.scss | 2 ++ 3 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 packages/block-library/src/list/editor.scss diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index 71d6eb65a27f53..bc75754474b294 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -17,7 +17,6 @@ @import "./latest-posts/editor.scss"; @import "./legacy-widget/editor.scss"; @import "./media-text/editor.scss"; -@import "./list/editor.scss"; @import "./more/editor.scss"; @import "./navigation-menu/editor.scss"; @import "./navigation-menu-item/editor.scss"; diff --git a/packages/block-library/src/list/editor.scss b/packages/block-library/src/list/editor.scss deleted file mode 100644 index fffff9ebaf6ee1..00000000000000 --- a/packages/block-library/src/list/editor.scss +++ /dev/null @@ -1,5 +0,0 @@ -.editor-styles-wrapper div[data-type="core/list"] ul, -.editor-styles-wrapper div[data-type="core/list"] ol { - padding-left: 1.3em; - margin-left: 1.3em; -} diff --git a/packages/editor/src/editor-styles.scss b/packages/editor/src/editor-styles.scss index c44e3d87a32299..978b34a61deaf3 100644 --- a/packages/editor/src/editor-styles.scss +++ b/packages/editor/src/editor-styles.scss @@ -104,6 +104,8 @@ ul, ol { margin-bottom: $default-block-margin; padding: inherit; + padding-left: 1.3em; + margin-left: 1.3em; // Remove bottom margin from nested lists. ul, From b50391d3fd5201e72943cd78863a9ff9142431de Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Wed, 16 Oct 2019 01:35:10 -0700 Subject: [PATCH 021/113] Storybook: Add stories for Checkbox control component (#17891) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add checkbox control stories for Storybook * Update README example to match story, useState * Apply suggestions from code review 👍 Co-Authored-By: Enrique Piqueras <epiqueras@users.noreply.github.com> * Update story to match README * Add variants for heading, label, help * Update packages/components/src/checkbox-control/README.md Co-Authored-By: Grzegorz (Greg) Ziółkowski <grzegorz@gziolo.pl> * Add Knobs addon to Storybook * Move storybook addon to dev-dependencies * Solve lint dependency by excluding stories, dont need in package.json * Apply suggestions from code review Co-Authored-By: Enrique Piqueras <epiqueras@users.noreply.github.com> * Update with story level decorators * Switch back to global withKnobs, per story not working * Change the name of the example in ChecboxControl story * Try with the uppercase name of the component exported from stories --- .eslintrc.js | 2 +- package-lock.json | 889 +++++++++++++----- package.json | 13 +- .../components/src/checkbox-control/README.md | 9 +- .../src/checkbox-control/stories/index.js | 43 + packages/components/storybook/addons.js | 1 + packages/components/storybook/config.js | 3 +- 7 files changed, 704 insertions(+), 256 deletions(-) create mode 100644 packages/components/src/checkbox-control/stories/index.js diff --git a/.eslintrc.js b/.eslintrc.js index b1a6b834b53aff..43e259b40c7b7e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -123,7 +123,7 @@ module.exports = { '**/*.@(android|ios|native).js', '**/benchmark/**/*.js', '**/@(__mocks__|__tests__|test)/**/*.js', - '**/storybook/**/*.js', + '**/@(storybook|stories)/**/*.js', ], }, { diff --git a/package-lock.json b/package-lock.json index d4020914acd3a0..14914f59f2eaa3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -383,12 +383,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -430,32 +430,32 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -1044,9 +1044,9 @@ } }, "@babel/plugin-transform-react-constant-elements": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.6.0.tgz", - "integrity": "sha512-np/nPuII8DHOZWB3u8u+NSeKlEz0eBrOlnVksIQog4C9NGVzXO+NLxMcXn4Eu4GMFzOw2W6Tyo6L3+Wv8z9Y5w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.6.3.tgz", + "integrity": "sha512-1/YogSSU7Tby9rq2VCmhuRg+6pxsHy2rI7w/oo8RKoBt6uBUFG+mk6x13kK+FY1/ggN92HAfg7ADd1v1+NCOKg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", @@ -1325,9 +1325,9 @@ } }, "@babel/preset-react": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", - "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.6.3.tgz", + "integrity": "sha512-07yQhmkZmRAfwREYIQgW0HEwMY9GBJVuPY4Q12UC72AbfaawuupVWa8zQs2tlL+yun45Nv/1KreII/0PLfEsgA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1357,12 +1357,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -1404,15 +1404,15 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/plugin-transform-typescript": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.0.tgz", - "integrity": "sha512-yzw7EopOOr6saONZ3KA3lpizKnWRTe+rfBqg4AmQbSow7ik7fqmzrfIqt053osLwLE2AaTqGinLM2tl6+M/uog==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz", + "integrity": "sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ==", "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.6.0", @@ -1421,26 +1421,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -2227,6 +2227,12 @@ "integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==", "dev": true }, + "@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", + "dev": true + }, "@jest/console": { "version": "24.7.1", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", @@ -4454,12 +4460,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -4477,9 +4483,9 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/template": { @@ -4494,26 +4500,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -5125,17 +5131,17 @@ } }, "@storybook/addon-a11y": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-5.2.3.tgz", - "integrity": "sha512-1N8hes5J3qyhCahHyFUXwiKif3JH892dzGalxc46jtvC0oCMM0r6lu+lj9J6THc15Oc8Icy9KJZuw4R0wRJl0Q==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-5.2.4.tgz", + "integrity": "sha512-m7D78LiREpUzw7U+jiJXQXSsYoYZ+IkewBIxX5K15lh58AqTi0hD8DWHssgbi76GQwdaXKmMPIwI842dgPYobQ==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/theming": "5.2.4", "axe-core": "^3.3.2", "common-tags": "^1.8.0", "core-js": "^3.0.1", @@ -5177,9 +5183,9 @@ } }, "@storybook/addon-docs": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-5.2.3.tgz", - "integrity": "sha512-xMg/LCUfVX1SNplaPbsNt9L78/QbxkR7pPpQuLjCvTAvzKkLNWNs8SlwM14ds/SfUNQ9EaCoAd1OQIdZrzrBRg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-5.2.4.tgz", + "integrity": "sha512-rfzoQUseb3G1WanQckjH85OXJJXMigod/YEEqJv68vo7GVY5PdVkOISy9nSldjrnwH6ikT3pcfJKPuHWRKAx/A==", "dev": true, "requires": { "@babel/generator": "^7.4.0", @@ -5188,12 +5194,12 @@ "@mdx-js/loader": "^1.1.0", "@mdx-js/mdx": "^1.1.0", "@mdx-js/react": "^1.0.27", - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/source-loader": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/source-loader": "5.2.4", + "@storybook/theming": "5.2.4", "core-js": "^3.0.1", "global": "^4.3.2", "js-string-escape": "^1.0.1", @@ -5201,17 +5207,248 @@ "prop-types": "^15.7.2" } }, + "@storybook/addon-knobs": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-knobs/-/addon-knobs-5.2.4.tgz", + "integrity": "sha512-VYxbDARJs5RwTEOlcfa98tkDXLcRocB7QXLqt8wwCdXPIqkuoVeQLROXGYJm2NzSn49RyHPKUuVWnRhy34qBbQ==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/client-api": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/theming": "5.2.4", + "@types/react-color": "^3.0.1", + "copy-to-clipboard": "^3.0.8", + "core-js": "^3.0.1", + "escape-html": "^1.0.3", + "fast-deep-equal": "^2.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", + "prop-types": "^15.7.2", + "qs": "^6.6.0", + "react-color": "^2.17.0", + "react-lifecycles-compat": "^3.0.4", + "react-select": "^3.0.0" + }, + "dependencies": { + "@storybook/addons": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.4.tgz", + "integrity": "sha512-Q+bnVlBA308qnELxnh18hBDRSUgltR9KbV537285dUL/okv/NC6n51mxJwIaG+ksBW2wU+5e6tqSayaKF3uHLw==", + "dev": true, + "requires": { + "@storybook/api": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "core-js": "^3.0.1", + "global": "^4.3.2", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/api": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.4.tgz", + "integrity": "sha512-KqAB+NkHIHdwu749NDP+7i44jy1bFgpq7GTJlG+sx/XLZHQveK/8yn109g9bXHFth7SvdXI1+9GA/apzwBU/Mw==", + "dev": true, + "requires": { + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", + "core-js": "^3.0.1", + "fast-deep-equal": "^2.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "prop-types": "^15.6.2", + "react": "^16.8.3", + "semver": "^6.0.0", + "shallow-equal": "^1.1.0", + "store2": "^2.7.1", + "telejson": "^3.0.2", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/channel-postmessage": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.4.tgz", + "integrity": "sha512-ic7/Ho8z2/aOMjoEbr5p8rijOfO3SZdJnwMvDdUxrqvYq7yACZWidPo3w2+iBwQi9HLqEsWesP1c2doJBxVGRw==", + "dev": true, + "requires": { + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "core-js": "^3.0.1", + "global": "^4.3.2", + "telejson": "^3.0.2" + } + }, + "@storybook/channels": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.4.tgz", + "integrity": "sha512-/r39yEZ5QiGdiq95DhXBypdBo7urkD3Sp1WDyK48uGkZ0gdHWSPy3BBy8OJhEhfNz7nVisTiVIBr4gIrubKDjw==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/client-api": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.4.tgz", + "integrity": "sha512-SOwzEFHoNapURhNqdcI7HA76o5tkWvs2+2s++i/S7xsAd3KyefIVDOdqSMlAxJkxZb8Mlrb3UNRxlrpA8SZqNA==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/channel-postmessage": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "common-tags": "^1.8.0", + "core-js": "^3.0.1", + "eventemitter3": "^4.0.0", + "global": "^4.3.2", + "is-plain-object": "^3.0.0", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/client-logger": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.4.tgz", + "integrity": "sha512-ofp6QQPQZBU+RvlAH5KpZRsfAFHecCZDnl/7YG6FwjHseJr3jHTYmBGGjJDMHFHq+Q7FGQu/yVb9lMFgoQ43QQ==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/components": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.4.tgz", + "integrity": "sha512-APhw+XGag0RTCRJ8eCWKVr8dLt9SRqnS8LtzcZJbokCYRxRTFzhmX2eVEE1v+d0gHib1/yh2COxOjMzv3m/rQA==", + "dev": true, + "requires": { + "@storybook/client-logger": "5.2.4", + "@storybook/theming": "5.2.4", + "@types/react-syntax-highlighter": "10.1.0", + "core-js": "^3.0.1", + "global": "^4.3.2", + "markdown-to-jsx": "^6.9.1", + "memoizerific": "^1.11.3", + "polished": "^3.3.1", + "popper.js": "^1.14.7", + "prop-types": "^15.7.2", + "react": "^16.8.3", + "react-dom": "^16.8.3", + "react-focus-lock": "^1.18.3", + "react-helmet-async": "^1.0.2", + "react-popper-tooltip": "^2.8.3", + "react-syntax-highlighter": "^8.0.1", + "react-textarea-autosize": "^7.1.0", + "simplebar-react": "^1.0.0-alpha.6" + } + }, + "@storybook/core-events": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.4.tgz", + "integrity": "sha512-nQknCmaz2S2HW6PSGcuFzve7Y1Js2Cb268vUG0ZMNtJZwFawqYc+KSQHqmOY0pVm8dyROTcWCudPA0k+hk6N5Q==", + "dev": true, + "requires": { + "core-js": "^3.0.1" + } + }, + "@storybook/router": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.4.tgz", + "integrity": "sha512-GL7eGdj5oYST0mE9fThJB9ye9tTTgrP+aP3okZ6MeMGtNytb7bmJRpAD2E4ouuPTQVppyHI5re8g/HUxUNOT1g==", + "dev": true, + "requires": { + "@reach/router": "^1.2.1", + "@types/reach__router": "^1.2.3", + "core-js": "^3.0.1", + "global": "^4.3.2", + "lodash": "^4.17.11", + "memoizerific": "^1.11.3", + "qs": "^6.6.0" + } + }, + "@storybook/theming": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.4.tgz", + "integrity": "sha512-2ZlqBrmnm8N0352Fnu2+GB3pEsHL4Eb2eKxV0VLLgkjJuAlm7CK6+I/e4ZknQWxwYm2pQj1y6ta68A62fGBYyA==", + "dev": true, + "requires": { + "@emotion/core": "^10.0.14", + "@emotion/styled": "^10.0.14", + "@storybook/client-logger": "5.2.4", + "common-tags": "^1.8.0", + "core-js": "^3.0.1", + "deep-object-diff": "^1.1.0", + "emotion-theming": "^10.0.14", + "global": "^4.3.2", + "memoizerific": "^1.11.3", + "polished": "^3.3.1", + "prop-types": "^15.7.2", + "resolve-from": "^5.0.0" + } + }, + "eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + }, + "qs": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz", + "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "shallow-equal": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.0.tgz", + "integrity": "sha512-Z21pVxR4cXsfwpMKMhCEIO1PCi5sp7KEp+CmOpBQ+E8GpHwKOw2sEzk7sgblM3d/j4z4gakoWEoPcjK0VJQogA==", + "dev": true + } + } + }, "@storybook/addon-storysource": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.2.3.tgz", - "integrity": "sha512-7t/oqRzD2QrGiqnUxU++jqgA8OVYByCFzeRHYcpoz84sd2vSy+110Me1OHj2ZHh1t+QOn8D0DJewe0QrycR56w==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.2.4.tgz", + "integrity": "sha512-zOJO4zt+Fj08GgegClDA6rU+VFyBb+mepfL5eJAqLtV6gSsprwZ1JNFVkyqhfrcr+vIhgRRWfuz/DDGmI+6bTQ==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/source-loader": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/source-loader": "5.2.4", + "@storybook/theming": "5.2.4", "core-js": "^3.0.1", "estraverse": "^4.2.0", "loader-utils": "^1.2.3", @@ -5257,17 +5494,17 @@ } }, "@storybook/addon-viewport": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-5.2.3.tgz", - "integrity": "sha512-YN0rQ6GrgDTAQv0KVhSJ/ZBQfEUerOTMsAt9MH9fCIgIfXmXc8BoqkL3DYhAhEPEKpzQkV+NwZyZcLCntXPdQg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-5.2.4.tgz", + "integrity": "sha512-R49wSaiouSVBYeus5Xibv+XXX9Nc3/rZ1NB5yIgj658aDeuB8WgkHbM3dKd/GrWeVZWv3o4CjW81ernd3f8sdw==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/theming": "5.2.4", "core-js": "^3.0.1", "global": "^4.3.2", "memoizerific": "^1.11.3", @@ -5276,31 +5513,31 @@ } }, "@storybook/addons": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.3.tgz", - "integrity": "sha512-LTkUJB8ZDc4++yt9acNHNjlnGWCyNtP+NVYPDvg7zFOaMip21Pj4T0pg9UwYxdqrFBWz9tVz7DJeXroS3egXxg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.2.4.tgz", + "integrity": "sha512-Q+bnVlBA308qnELxnh18hBDRSUgltR9KbV537285dUL/okv/NC6n51mxJwIaG+ksBW2wU+5e6tqSayaKF3uHLw==", "dev": true, "requires": { - "@storybook/api": "5.2.3", - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", + "@storybook/api": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", "core-js": "^3.0.1", "global": "^4.3.2", "util-deprecate": "^1.0.2" } }, "@storybook/api": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.3.tgz", - "integrity": "sha512-2csxa/d64rXy4Dwoc7YjbPeNUJRgcI/wJUo30CLujk2stEFzDnKeMPR1mlHMCIFDW+KDxJ28bW59VPxwrqJFjw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.2.4.tgz", + "integrity": "sha512-KqAB+NkHIHdwu749NDP+7i44jy1bFgpq7GTJlG+sx/XLZHQveK/8yn109g9bXHFth7SvdXI1+9GA/apzwBU/Mw==", "dev": true, "requires": { - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", "core-js": "^3.0.1", "fast-deep-equal": "^2.0.1", "global": "^4.3.2", @@ -5324,39 +5561,39 @@ } }, "@storybook/channel-postmessage": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.3.tgz", - "integrity": "sha512-ixlpr6aAYoRM72cKwEWU/W0rWzOn3mYqb/eUdIaz3Da5BtFGKm3yEFguII0l1my82uhMm5/d3UNfoh0rO3pUyg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.2.4.tgz", + "integrity": "sha512-ic7/Ho8z2/aOMjoEbr5p8rijOfO3SZdJnwMvDdUxrqvYq7yACZWidPo3w2+iBwQi9HLqEsWesP1c2doJBxVGRw==", "dev": true, "requires": { - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", "core-js": "^3.0.1", "global": "^4.3.2", "telejson": "^3.0.2" } }, "@storybook/channels": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.3.tgz", - "integrity": "sha512-13Mlb+XbE0mHXiLLHdg0w9byhRy/bE605U7U96PGQp2cwX4lf+4jpViO2mDCsndAFRc0+2hexXPTkwgzvZzq0A==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.2.4.tgz", + "integrity": "sha512-/r39yEZ5QiGdiq95DhXBypdBo7urkD3Sp1WDyK48uGkZ0gdHWSPy3BBy8OJhEhfNz7nVisTiVIBr4gIrubKDjw==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/client-api": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.3.tgz", - "integrity": "sha512-anXxcf2z+KQAk94xxdbeG1N6nTEWXj087XHQ22L3pOoX9TRzfG71UjL0/S7vj4EFUiXVHj8d6YUFwLb5LwpUIw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.2.4.tgz", + "integrity": "sha512-SOwzEFHoNapURhNqdcI7HA76o5tkWvs2+2s++i/S7xsAd3KyefIVDOdqSMlAxJkxZb8Mlrb3UNRxlrpA8SZqNA==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/channel-postmessage": "5.2.3", - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/router": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/channel-postmessage": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", "common-tags": "^1.8.0", "core-js": "^3.0.1", "eventemitter3": "^4.0.0", @@ -5398,22 +5635,22 @@ } }, "@storybook/client-logger": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.3.tgz", - "integrity": "sha512-Z1irXW4jiFs7rClgqJqYOgg5op51ynV6dVuoIqxkSC0MrOG5s/VbX7T+ojGPXKyQWD4XYGw66Hnw9jouSfXL9g==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.2.4.tgz", + "integrity": "sha512-ofp6QQPQZBU+RvlAH5KpZRsfAFHecCZDnl/7YG6FwjHseJr3jHTYmBGGjJDMHFHq+Q7FGQu/yVb9lMFgoQ43QQ==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/components": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.3.tgz", - "integrity": "sha512-EiWKa3xONP2BPxrssiRdvKELhF2tO14HVL131CCFY+Zg/ylExzWWWVSBun7vYcKhkI52K5lmvC1vFSsB6Gmlhw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.2.4.tgz", + "integrity": "sha512-APhw+XGag0RTCRJ8eCWKVr8dLt9SRqnS8LtzcZJbokCYRxRTFzhmX2eVEE1v+d0gHib1/yh2COxOjMzv3m/rQA==", "dev": true, "requires": { - "@storybook/client-logger": "5.2.3", - "@storybook/theming": "5.2.3", + "@storybook/client-logger": "5.2.4", + "@storybook/theming": "5.2.4", "@types/react-syntax-highlighter": "10.1.0", "core-js": "^3.0.1", "global": "^4.3.2", @@ -5433,9 +5670,9 @@ } }, "@storybook/core": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-5.2.3.tgz", - "integrity": "sha512-sktjYY8pH4kQGFRKjXwtwwShdG3ajjHkrnw8oh3R383MRPom7i9owx5yHHMuQedLCXIwAg84s2DzO01I2URTcg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-5.2.4.tgz", + "integrity": "sha512-r5kDgZETNawHxpsAPw+h+pRk6l/mJhsSHeDo9/OdYtYFW7lmk2gadViXOTM+6gIWc6vQ8y750bgkahmyIIY0nQ==", "dev": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.3.3", @@ -5443,15 +5680,15 @@ "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-transform-react-constant-elements": "^7.2.0", "@babel/preset-env": "^7.4.5", - "@storybook/addons": "5.2.3", - "@storybook/channel-postmessage": "5.2.3", - "@storybook/client-api": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/node-logger": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/theming": "5.2.3", - "@storybook/ui": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/channel-postmessage": "5.2.4", + "@storybook/client-api": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/node-logger": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", + "@storybook/ui": "5.2.4", "airbnb-js-shims": "^1 || ^2", "ansi-to-html": "^0.6.11", "autoprefixer": "^9.4.9", @@ -5519,12 +5756,12 @@ } }, "ansi-to-html": { - "version": "0.6.11", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.11.tgz", - "integrity": "sha512-88XZtrcwrfkyn6fGstHnkaF1kl7hGtNCYh4vSmItgEV+6JnQHryDBf7udF4f2RhTRQmYvJvPcTtqgaqrxzc9oA==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.12.tgz", + "integrity": "sha512-qBkIqLW979675mP76yB7yVkzeAWtATegdnDQ0RA3CZzknx0yUlNxMSML4xFdBfTs2GWYFQ1FELfbGbVSPzJ+LA==", "dev": true, "requires": { - "entities": "^1.1.1" + "entities": "^1.1.2" } }, "body-parser": { @@ -5583,6 +5820,12 @@ "ms": "2.0.0" } }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -5922,18 +6165,18 @@ } }, "@storybook/core-events": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.3.tgz", - "integrity": "sha512-sZEv93yE1o+/UJdhtqQ6vo2EauZ90FjN/L8F7CR7iqDEZzqo9g77Idg9LSgcN3TAeXcGAWVSrPb1vkK7H96L2g==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.2.4.tgz", + "integrity": "sha512-nQknCmaz2S2HW6PSGcuFzve7Y1Js2Cb268vUG0ZMNtJZwFawqYc+KSQHqmOY0pVm8dyROTcWCudPA0k+hk6N5Q==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/node-logger": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-5.2.3.tgz", - "integrity": "sha512-5p+5ltLdr7cZTSCG+vdIMDLHq5AAaL/CQ/bygjl+Rw/RSpvBO5Rg8hryszFyhogToHJbn2JinUbypLA+P6tcuQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-5.2.4.tgz", + "integrity": "sha512-4OOzce02IAfrRv+Y7h3icyw6WIuDekpWF2eYjgYVVvAJYklCEwgeBTBCY0/2TJjPPTBDPUKHVP1Bdz3Vpci9pA==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -5952,17 +6195,17 @@ } }, "@storybook/react": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-5.2.3.tgz", - "integrity": "sha512-7DLUkpwyPTyDHoih/AvFr2QXQAxzXQMVDvvR5r0J0oiffLWwrqshl1TL4b16YoFvel0ZPtUdrcei6knLXhg+Wg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-5.2.4.tgz", + "integrity": "sha512-AO0qwbD/2UGe5CrVizbaek+gCAPWkPVc0KUk38cT1mcuLpXwt1zZe7iHLQf2zOeBVSiBkPLOHrEtzDfnIJXKFQ==", "dev": true, "requires": { "@babel/plugin-transform-react-constant-elements": "^7.2.0", "@babel/preset-flow": "^7.0.0", "@babel/preset-react": "^7.0.0", - "@storybook/addons": "5.2.3", - "@storybook/core": "5.2.3", - "@storybook/node-logger": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/core": "5.2.4", + "@storybook/node-logger": "5.2.4", "@svgr/webpack": "^4.0.3", "@types/webpack-env": "^1.13.7", "babel-plugin-add-react-displayname": "^0.0.5", @@ -5990,9 +6233,9 @@ } }, "@storybook/router": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.3.tgz", - "integrity": "sha512-sOu6y2GySaY82SdXfF3yOn0IJTKMqd2BDOSGEno7PWWtSenHFQWY+z99C9k0dLBTkjRes5tPcgm0OJ7RdQVRDQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.2.4.tgz", + "integrity": "sha512-GL7eGdj5oYST0mE9fThJB9ye9tTTgrP+aP3okZ6MeMGtNytb7bmJRpAD2E4ouuPTQVppyHI5re8g/HUxUNOT1g==", "dev": true, "requires": { "@reach/router": "^1.2.1", @@ -6013,13 +6256,13 @@ } }, "@storybook/source-loader": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.2.3.tgz", - "integrity": "sha512-4wKYslglYt/yC77zvRZ4OkmTVbnmnd98VMD99KP3Ap6IwkdxtGKIBTOOT36g6m0/1JaMFe+x7i+i9nbmK4hsDQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.2.4.tgz", + "integrity": "sha512-TXqJhj0oSnUp4w5dyh2sf3OXt/ShF9m7ceTzI8H8ZfuI8kljVsv+KvGdv+Q4f4jrO3br4Qz7bE9Wvp70i9BY1g==", "dev": true, "requires": { - "@storybook/addons": "5.2.3", - "@storybook/router": "5.2.3", + "@storybook/addons": "5.2.4", + "@storybook/router": "5.2.4", "core-js": "^3.0.1", "estraverse": "^4.2.0", "global": "^4.3.2", @@ -6064,14 +6307,14 @@ } }, "@storybook/theming": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.3.tgz", - "integrity": "sha512-3/0bo8CaoaHDYZaexydpYcwP6WW8BKRqSQBGXJY9y0TLhwY2Who5nPX9XdOLyu9d7lN//PRZlt8JnZynuncxoQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.2.4.tgz", + "integrity": "sha512-2ZlqBrmnm8N0352Fnu2+GB3pEsHL4Eb2eKxV0VLLgkjJuAlm7CK6+I/e4ZknQWxwYm2pQj1y6ta68A62fGBYyA==", "dev": true, "requires": { "@emotion/core": "^10.0.14", "@emotion/styled": "^10.0.14", - "@storybook/client-logger": "5.2.3", + "@storybook/client-logger": "5.2.4", "common-tags": "^1.8.0", "core-js": "^3.0.1", "deep-object-diff": "^1.1.0", @@ -6092,19 +6335,19 @@ } }, "@storybook/ui": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-5.2.3.tgz", - "integrity": "sha512-SNyo5oxupb105N4Rz8O5/iJMs/THrmdvP+vsN7CpOTxebM01rHyvk51cNUwHKG1QwlZmpXL8GbtWlbvqL2d/gQ==", - "dev": true, - "requires": { - "@storybook/addons": "5.2.3", - "@storybook/api": "5.2.3", - "@storybook/channels": "5.2.3", - "@storybook/client-logger": "5.2.3", - "@storybook/components": "5.2.3", - "@storybook/core-events": "5.2.3", - "@storybook/router": "5.2.3", - "@storybook/theming": "5.2.3", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-5.2.4.tgz", + "integrity": "sha512-zsS43k1h4bWEW6oj9FNHlUL3niHoJJ8v7iqYbRtVM12rxrYhV3K8TGVG3LCuNB75i3Be0Myy+/RHA4x9kco08A==", + "dev": true, + "requires": { + "@storybook/addons": "5.2.4", + "@storybook/api": "5.2.4", + "@storybook/channels": "5.2.4", + "@storybook/client-logger": "5.2.4", + "@storybook/components": "5.2.4", + "@storybook/core-events": "5.2.4", + "@storybook/router": "5.2.4", + "@storybook/theming": "5.2.4", "copy-to-clipboard": "^3.0.8", "core-js": "^3.0.1", "core-js-pure": "^3.0.1", @@ -6644,6 +6887,15 @@ "csstype": "^2.2.0" } }, + "@types/react-color": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.1.tgz", + "integrity": "sha512-J6mYm43Sid9y+OjZ7NDfJ2VVkeeuTPNVImNFITgQNXodHteKfl/t/5pAR5Z9buodZ2tCctsZjgiMlQOpfntakw==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-syntax-highlighter": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-10.1.0.tgz", @@ -6687,9 +6939,9 @@ } }, "@types/webpack-env": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.14.0.tgz", - "integrity": "sha512-Fv+0gYJzE/czLoRKq+gnXWr4yBpPM3tO3C8pDLFwqVKlMICQUq5OsxwwFZYDaVr7+L6mgNDp16iOcJHEz3J5RQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.14.1.tgz", + "integrity": "sha512-0Ki9jAAhKDSuLDXOIMADg54Hu60SuBTEsWaJGGy5cV+SSUQ63J2a+RrYYGrErzz39fXzTibhKrAQJAb8M7PNcA==", "dev": true }, "@types/yargs": { @@ -8331,14 +8583,71 @@ } }, "array.prototype.flatmap": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz", - "integrity": "sha512-i18e2APdsiezkcqDyZor78Pbfjfds3S94dG6dgIV2ZASJaUf1N0dz2tGdrmwrmlZuNUgxH+wz6Z0zYVH2c5xzQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.2.tgz", + "integrity": "sha512-ZZtPLE74KNE+0XcPv/vQmcivxN+8FhwOLvt2udHauO0aDEpsXDQrmd5HuJGpgPVyaV8HvkDPWnJ2iaem0oCKtA==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.10.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.15.0", "function-bind": "^1.1.1" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", + "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + } } }, "arrify": { @@ -9546,12 +9855,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -9604,9 +9913,9 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/plugin-proposal-class-properties": { @@ -9641,9 +9950,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz", - "integrity": "sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", + "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -9713,9 +10022,9 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz", - "integrity": "sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz", + "integrity": "sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw==", "dev": true, "requires": { "regexpu-core": "^4.6.0" @@ -9810,6 +10119,19 @@ "semver": "^5.5.0" } }, + "@babel/preset-react": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", + "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0" + } + }, "@babel/runtime": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", @@ -9831,26 +10153,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -13121,9 +13443,9 @@ "dev": true }, "schema-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", - "integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz", + "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==", "dev": true, "requires": { "ajv": "^6.10.2", @@ -14096,6 +14418,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2" + } + }, "dom-scroll-into-view": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", @@ -22204,6 +22535,12 @@ "unquote": "^1.1.0" } }, + "material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==", + "dev": true + }, "mathml-tag-names": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.0.tgz", @@ -22314,6 +22651,12 @@ "resolved": "https://registry.npmjs.org/memize/-/memize-1.0.5.tgz", "integrity": "sha512-Dm8Jhb5kiC4+ynYsVR4QDXKt+o2dfqGuY4hE2x+XlXZkdndlT80bJxfcMv5QGp/FCy6MhG7f5ElpmKPFKOSEpg==" }, + "memoize-one": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", + "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==", + "dev": true + }, "memoizerific": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", @@ -27514,6 +27857,20 @@ "@babel/runtime": "^7.0.0" } }, + "react-color": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.3.tgz", + "integrity": "sha512-1dtO8LqAVotPIChlmo6kLtFS1FP89ll8/OiA8EcFRDR+ntcK+0ukJgByuIQHRtzvigf26dV5HklnxDIvhON9VQ==", + "dev": true, + "requires": { + "@icons/material": "^0.2.4", + "lodash": "^4.17.11", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + } + }, "react-dates": { "version": "17.2.0", "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-17.2.0.tgz", @@ -27941,6 +28298,15 @@ "prop-types": "^15.6.1" } }, + "react-input-autosize": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz", + "integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==", + "dev": true, + "requires": { + "prop-types": "^15.5.8" + } + }, "react-is": { "version": "16.8.4", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", @@ -28535,9 +28901,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.2.tgz", - "integrity": "sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", "dev": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -28566,10 +28932,26 @@ "integrity": "sha512-ITw8t/HOFNose2yf1y9pPFSSeB9ISOq2JdHpuZvj/Qb+iSsLml8GkkHdDlURzieO7B3dFDtMrrneZLl3N5z/hg==", "dev": true }, + "react-select": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.0.8.tgz", + "integrity": "sha512-v9LpOhckLlRmXN5A6/mGGEft4FMrfaBFTGAnuPHcUgVId7Je42kTq9y0Z+Ye5z8/j0XDT3zUqza8gaRaI1PZIg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@emotion/cache": "^10.0.9", + "@emotion/core": "^10.0.9", + "@emotion/css": "^10.0.9", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^2.2.2", + "react-transition-group": "^2.2.1" + } + }, "react-sizeme": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-2.6.7.tgz", - "integrity": "sha512-xCjPoBP5jmeW58TxIkcviMZqabZis7tTvDFWf0/Wa5XCgVWQTIe74NQBes2N1Kmp64GRLkpm60BaP0kk+v8aCQ==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-2.6.8.tgz", + "integrity": "sha512-eJKHV226d/S3st2He7bLIlY7FAmi2ItvZmUCmLLNjIvYjtiv58BksuFhTBQmvAxWaXZGb3Ao/44wfAS1voRdjA==", "dev": true, "requires": { "element-resize-detector": "^1.1.15", @@ -28640,6 +29022,18 @@ "react-proxy": "^1.1.7" } }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "dev": true, + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "react-with-direction": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.0.tgz", @@ -28675,6 +29069,15 @@ "global-cache": "^1.2.1" } }, + "reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "dev": true, + "requires": { + "lodash": "^4.0.1" + } + }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -29277,12 +29680,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -29300,9 +29703,9 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/plugin-proposal-object-rest-spread": { @@ -29327,26 +29730,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -33600,9 +34003,9 @@ "dev": true }, "schema-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", - "integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz", + "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==", "dev": true, "requires": { "ajv": "^6.10.2", diff --git a/package.json b/package.json index 89175f6b3dd0a8..ae658d2473c986 100644 --- a/package.json +++ b/package.json @@ -72,11 +72,12 @@ "@babel/runtime-corejs3": "7.4.5", "@babel/traverse": "7.4.5", "@octokit/rest": "16.26.0", - "@storybook/addon-a11y": "5.2.3", - "@storybook/addon-docs": "5.2.3", - "@storybook/addon-storysource": "5.2.3", - "@storybook/addon-viewport": "5.2.3", - "@storybook/react": "5.2.3", + "@storybook/addon-a11y": "5.2.4", + "@storybook/addon-docs": "5.2.4", + "@storybook/addon-knobs": "5.2.4", + "@storybook/addon-storysource": "5.2.4", + "@storybook/addon-viewport": "5.2.4", + "@storybook/react": "5.2.4", "@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma", "@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot", "@wordpress/babel-preset-default": "file:packages/babel-preset-default", @@ -86,8 +87,8 @@ "@wordpress/docgen": "file:packages/docgen", "@wordpress/e2e-test-utils": "file:packages/e2e-test-utils", "@wordpress/e2e-tests": "file:packages/e2e-tests", - "@wordpress/eslint-plugin": "file:packages/eslint-plugin", "@wordpress/env": "file:packages/env", + "@wordpress/eslint-plugin": "file:packages/eslint-plugin", "@wordpress/jest-console": "file:packages/jest-console", "@wordpress/jest-preset-default": "file:packages/jest-preset-default", "@wordpress/jest-puppeteer-axe": "file:packages/jest-puppeteer-axe", diff --git a/packages/components/src/checkbox-control/README.md b/packages/components/src/checkbox-control/README.md index 43165e8ae1b59c..b6245fbd036cd0 100644 --- a/packages/components/src/checkbox-control/README.md +++ b/packages/components/src/checkbox-control/README.md @@ -56,17 +56,16 @@ If only a few child checkboxes are checked, the parent checkbox becomes a mixed Render an is author checkbox: ```jsx import { CheckboxControl } from '@wordpress/components'; -import { withState } from '@wordpress/compose'; +import { useState } from '@wordpress/element'; -const MyCheckboxControl = withState( { - isChecked: true, -} )( ( { isChecked, setState } ) => ( +const MyCheckboxControl = () => ( + const [ isChecked, setChecked ] = useState( true ); <CheckboxControl heading="User" label="Is author" help="Is the user a author or not?" checked={ isChecked } - onChange={ ( isChecked ) => { setState( { isChecked } ) } } + onChange={ setChecked } /> ) ); ``` diff --git a/packages/components/src/checkbox-control/stories/index.js b/packages/components/src/checkbox-control/stories/index.js new file mode 100644 index 00000000000000..184abbfe8b1614 --- /dev/null +++ b/packages/components/src/checkbox-control/stories/index.js @@ -0,0 +1,43 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import CheckboxControl from '../'; + +export default { title: 'Checkbox Control', component: CheckboxControl }; + +export const _default = () => { + const [ isChecked, setChecked ] = useState( true ); + return ( + <CheckboxControl + label="Is author" + checked={ isChecked } + onChange={ setChecked } + /> + ); +}; + +export const All = () => { + const [ isChecked, setChecked ] = useState( true ); + const heading = text( 'Heading', 'User' ); + const label = text( 'Label', 'Is author' ); + const help = text( 'Help', 'Is the user an author or not?' ); + return ( + <CheckboxControl + heading={ heading } + label={ label } + help={ help } + checked={ isChecked } + onChange={ setChecked } + /> + ); +}; diff --git a/packages/components/storybook/addons.js b/packages/components/storybook/addons.js index d3fa048c75edf4..ccfec56c606dcc 100644 --- a/packages/components/storybook/addons.js +++ b/packages/components/storybook/addons.js @@ -2,5 +2,6 @@ * External dependencies */ import '@storybook/addon-a11y/register'; +import '@storybook/addon-knobs/register'; import '@storybook/addon-storysource/register'; import '@storybook/addon-viewport/register'; diff --git a/packages/components/storybook/config.js b/packages/components/storybook/config.js index eace300f3fc963..6b75e0111b27d8 100644 --- a/packages/components/storybook/config.js +++ b/packages/components/storybook/config.js @@ -3,13 +3,14 @@ */ import { addDecorator, configure } from '@storybook/react'; import { withA11y } from '@storybook/addon-a11y'; - +import { withKnobs } from '@storybook/addon-knobs'; /** * Internal dependencies */ import '../build-style/style.css'; addDecorator( withA11y ); +addDecorator( withKnobs ); configure( [ require.context( '../docs', true, /\/.+\.mdx$/ ), From 1e089dba0c572bd7dd71f37aa1c4759cd6aaf81b Mon Sep 17 00:00:00 2001 From: Cameron Voell <cameronvoell@gmail.com> Date: Wed, 16 Oct 2019 04:00:34 -0700 Subject: [PATCH 022/113] RNMobile Add size options to mobile image block (#17245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [RNMobile] Native mobile release v1.11.0 (#17181) * [RNMobile] Fix crash when adding separator * Build: remove global install of latest npm since we want to use the paired node/npm version (#17134) * Build: remove global install of latest npm since we want to use the paired node/npm version * Also update travis to remove --latest-npm flag * [RNMobile] Try dark mode (iOS) (#17067) * Adding dark mode component implemented on list and list block * Adding DarkMode handling to RichText, ToolBar and SafeArea * Mobile: Using DarkMode as HOC * iOS DarkMode: Modified colors on block list and block container * iOS DarkMode: Improved Header Toolbar colors * iOS DarkMode: Removing background from buttons * iOS DarkMode warning and unsupported * iOS DarkMode: MediaPlaceholder * iOS DarkMode: BottomSheets * iOS DarkMode: Inserter * iOS DarkMode: DefaultBlockAppender * iOS DarkMode: PostTite * Update hardcoded colors with variables * iOS DarkMode: Fix bottom-sheet cell value color * iOS DarkMode: More - PageBreak - Add Block Here * iOS DarkMode: Better text color * iOS Darkmode: Code block * iOS DarkMode: HTML View * iOS DarkMode: Improve colors on SafeArea * Fix toolbar not avoiding keyboard regression * Fix native unit tests * Fix gutenberg-mobile unit tests * Adding RNDarkMode mocks * RNMobile: Fix crash when viewing HTML on iOS * [RNMobile] Remove toolbar from html view * [RNMobile] Fix MaxListenersExceededWarning caused by dark-mode event emitter (#17186) * Fix MaxListenersExceededWarning caused by dark-mode event emitter * Checking for setMaxListeners trying to avoid CI error * Adding remove listener to DarkMode HOC * DarkMode: Binding this.onModeChanged to `this` * DarkMode: Adding conditional needed to pass UI Tests on CI * Fix focus title on new posts regression (#17180) * BottomSheet: Setting DashIcon color directly when theme is default (light) (#17193) * Activate Travis CI on rnmobile/master branch (#17229) * Added ability to update image size options (sizeSlug) through a new InspectorControl Cell that leads to a Picker. * Added a style for Size Inspector Controls cell to align it will other cells that have icons. * Add native support for the MediaText block (#16305) * First working version of the MediaText component for native mobile * Fix adding a block to an innerblock list * Disable mediaText on production * MediaText native: improve editor visuals * Move BlockToolbar from BlockList to Layout * Remove BlockEditorProvider from BlockList and add native version of EditorProvider to Editor. Plus support InsertionPoint and BlockListAppender * Update BlockMover for native to hide if locked or if it's the only block * Make the vertical align button work, add more styling options for toolbar buttons * Make sure registerCoreBlocks does not break in production * Copy docblock comment from the web version for registerCoreBlocks * Fix focusing on the media placeholder * Only support adding image for now * Update usage of MediaPlaceholder in MediaContainer * Enable autoScroll for just the out most block list * Fix JS Unit tests * Roll back to IconButton refactor and fix tests * Fix BlockVerticalAlignmentToolbar buttons style on mobile * Fix thing for web and ensure ariaPressed is always passed down * Use AriaPressed directly to style SVG on mobile * Update snapshots * Swtiched to react-native Modal onDismiss property for signaling Picker is ready to show * Added a prop for catching modal dismissal on Android. (onDismiss is iOS only and onModalHide works on Android but breaks on iOS) * Added icon for Inspector Controls size option. Removed style we no longer need. * Added title to size option iOS ActionSheet and left alignstyle to size options BottomSheet * MediaUpload and MediaPlaceholder unify props (#17145) * Unify media placeholder and upload props within media-text (#17268) * [RNMobile] Fix dismiss keyboard button for the post title (#17260) * Set unused functions to undefined instead of false in BottomSheet Modal props * Recover border colors (#17269) * [RNMobile] Insure tapping at end of post inserts at end Previously, tapping at the end of the post would insert a block immediately after the currently selected block. In addition, this commit is cleaning out a few unusued props in the block-list file. * Support group block on mobile (#17251) * First working version of the MediaText component for native mobile * Fix adding a block to an innerblock list * Disable mediaText on production * MediaText native: improve editor visuals * Move BlockToolbar from BlockList to Layout * Remove BlockEditorProvider from BlockList and add native version of EditorProvider to Editor. Plus support InsertionPoint and BlockListAppender * Update BlockMover for native to hide if locked or if it's the only block * Make the vertical align button work, add more styling options for toolbar buttons * Make sure registerCoreBlocks does not break in production * Copy docblock comment from the web version for registerCoreBlocks * Fix focusing on the media placeholder * Only support adding image for now * Update usage of MediaPlaceholder in MediaContainer * Enable autoScroll for just the out most block list * Fix JS Unit tests * Roll back to IconButton refactor and fix tests * Fix BlockVerticalAlignmentToolbar buttons style on mobile * Fix thing for web and ensure ariaPressed is always passed down * Use AriaPressed directly to style SVG on mobile * Update snapshots * Support group block on mobile * Extend shouldShowInsertionPoint condition to be false when group is selected * Code refactor * Update package-lock * Removing old style reference. * Moved Picker for image size options into new ImageSizePicker component. Cleaned up sizeOptionLabels. * Updated total left margin on Android Image size options to be 24 px instead of 28 px * Image Size options hidden behind __DEV__ flag * Remove redundant bg color within button appender (#17325) * [RNMobile] DarkMode improvements (#17309) * Remove the need to import `useStyle` and pass the theme prop on every instance that `withStyle` is used * Implement dark-mode refactor on all components * Fix broken native tests * Fix default block appender background color on DarkMode * DarkMode: Make `useStyle` a class function * Cleaned up default true properties and replaced code with lodash map. * Updated to use BottomSheetPickerCell. Eliminated code, but size options now open over top inspector controls menu. * Added leftalign to PickerCell. * [RNMobile] Add autosave to mobile apps (#17329) * [RNMobile] Fix crash when adding separator * Build: remove global install of latest npm since we want to use the paired node/npm version (#17134) * Build: remove global install of latest npm since we want to use the paired node/npm version * Also update travis to remove --latest-npm flag * [RNMobile] Try dark mode (iOS) (#17067) * Adding dark mode component implemented on list and list block * Adding DarkMode handling to RichText, ToolBar and SafeArea * Mobile: Using DarkMode as HOC * iOS DarkMode: Modified colors on block list and block container * iOS DarkMode: Improved Header Toolbar colors * iOS DarkMode: Removing background from buttons * iOS DarkMode warning and unsupported * iOS DarkMode: MediaPlaceholder * iOS DarkMode: BottomSheets * iOS DarkMode: Inserter * iOS DarkMode: DefaultBlockAppender * iOS DarkMode: PostTite * Update hardcoded colors with variables * iOS DarkMode: Fix bottom-sheet cell value color * iOS DarkMode: More - PageBreak - Add Block Here * iOS DarkMode: Better text color * iOS Darkmode: Code block * iOS DarkMode: HTML View * iOS DarkMode: Improve colors on SafeArea * Fix toolbar not avoiding keyboard regression * Fix native unit tests * Fix gutenberg-mobile unit tests * Adding RNDarkMode mocks * RNMobile: Fix crash when viewing HTML on iOS * [RNMobile] Remove toolbar from html view * [RNMobile] Fix MaxListenersExceededWarning caused by dark-mode event emitter (#17186) * Fix MaxListenersExceededWarning caused by dark-mode event emitter * Checking for setMaxListeners trying to avoid CI error * Adding remove listener to DarkMode HOC * DarkMode: Binding this.onModeChanged to `this` * DarkMode: Adding conditional needed to pass UI Tests on CI * Fix focus title on new posts regression (#17180) * BottomSheet: Setting DashIcon color directly when theme is default (light) (#17193) * Add a preliminary version of the AutosaveMonitor for mobile that calls the "bridge" and asks the native side to save the content * Add autosave mock function for tests * Fix merge conflicts * Fix lint * Re-add autosave on mobile that was removed erroneously during import-merge from rnmobile/master * Remove native variant of AutosaveMonitor and introduces changes at editor store level * Default to false for `isEditedPostAutosaveable` on mobile. There was a typo in the returing value on the previous commit. * Make sure to consider edits to the Title when checking if auto-save is needed * Fix lint * Add isAppender functionality on mobile (#17195) * Add isAppender functionality on mobile * refactor isAppender conditions * Replace dropZoneUIOnly in favour of showMediaSelectionUI * deprecate dropZoneUIOnly and add disableMediaSelection prop * Update test * Refactor tests and change prop name * Remove redundant empty lines * Refactor conditions inside MediaPlaceholder * Update block-editor CHANGELOG * Update packages/block-editor/CHANGELOG.md Co-Authored-By: Grzegorz (Greg) Ziółkowski <grzegorz@gziolo.pl> * Autosave monitor - Make the mobile editor ping the native at each keystroke, since the deboucing logic is already well defined in the apps. (#17548) * [RNMobile] Refactor Dark Mode HOC (#17552) * [RNMobile] Refactor the Dark Mode HOC to fix naming antipatterns * Fix lint errors * Add .native.js suffix to usePreferredColorScheme * Update usage of theme props renamed to preferredColorScheme * Update usage of theme props renamed to preferredColorScheme * Add missing heading levels to the UI (H4, H5, H6) (#17533) * Fix lint issue (#17598) * Fix list filter on paste for RN mobile. (#17550) * Fix method for RN mobile. * Use array.From instead of slice. * Remove comment and use Array.from directly * Convert from NodeList spreadable to Array.from * Fix lint errors. * Fix documentation examples to use Array.from * Add empty line. * [RNMobile] Move MediaUploadPorgress to its own component folder (#17392) * Move MediaUploadPorgress to its own component folder (native) * MediaUploadProgress - Fix import to code standards * MediaUploadProgress readme * Mobile - MediaUploadProgress README update * Rnmobile/fix link editing on start (#17631) * Don't try to clear links if text is clean. * Commented LinkUI removal test when no URL. * Don't try to remove link if we are at start of link and no actual selection is * Re-implementing https://github.com/WordPress/gutenberg/pull/17802, affected by merge. Fixed extra space and unused code. * Fixing lint error, trailing space. --- .../media-placeholder/styles.native.scss | 4 --- .../components/media-upload/index.native.js | 2 +- .../block-library/src/image/edit.native.js | 36 +++++++++++++++++-- .../src/mobile/bottom-sheet/cell.native.js | 6 +++- .../src/mobile/bottom-sheet/index.native.js | 2 ++ .../mobile/bottom-sheet/picker-cell.native.js | 3 ++ .../mobile/bottom-sheet/styles.native.scss | 7 ++++ .../src/mobile/picker/index.android.js | 1 + .../components/src/mobile/picker/index.ios.js | 3 +- 9 files changed, 55 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/media-placeholder/styles.native.scss b/packages/block-editor/src/components/media-placeholder/styles.native.scss index a0b7445debf66b..03c7c73b2edfc9 100644 --- a/packages/block-editor/src/components/media-placeholder/styles.native.scss +++ b/packages/block-editor/src/components/media-placeholder/styles.native.scss @@ -19,10 +19,6 @@ background-color: $background-dark-secondary; } -.emptyStateContainerDark { - background-color: $background-dark-secondary; -} - .emptyStateTitle { text-align: center; margin-top: 8; diff --git a/packages/block-editor/src/components/media-upload/index.native.js b/packages/block-editor/src/components/media-upload/index.native.js index 3d89091e94da3d..77f125fb35f91a 100644 --- a/packages/block-editor/src/components/media-upload/index.native.js +++ b/packages/block-editor/src/components/media-upload/index.native.js @@ -106,7 +106,7 @@ export class MediaUpload extends React.Component { const getMediaOptions = () => ( <Picker - hideCancelButton={ true } + hideCancelButton ref={ ( instance ) => this.picker = instance } options={ mediaOptions } onChange={ this.onPickerChange } diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index ce2c1affe275a5..3e08ed18a2361d 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -9,7 +9,7 @@ import { requestImageFailedRetryDialog, requestImageUploadCancelDialog, } from 'react-native-gutenberg-bridge'; -import { isEmpty } from 'lodash'; +import { isEmpty, map } from 'lodash'; /** * WordPress dependencies @@ -17,6 +17,7 @@ import { isEmpty } from 'lodash'; import { TextControl, ToggleControl, + SelectControl, Icon, Toolbar, ToolbarButton, @@ -50,6 +51,19 @@ import { LINK_DESTINATION_NONE, } from './constants'; +const IMAGE_SIZE_THUMBNAIL = 'thumbnail'; +const IMAGE_SIZE_MEDIUM = 'medium'; +const IMAGE_SIZE_LARGE = 'large'; +const IMAGE_SIZE_FULL_SIZE = 'full'; +const DEFAULT_SIZE_SLUG = IMAGE_SIZE_LARGE; +const sizeOptionLabels = { + [ IMAGE_SIZE_THUMBNAIL ]: __( 'Thumbnail' ), + [ IMAGE_SIZE_MEDIUM ]: __( 'Medium' ), + [ IMAGE_SIZE_LARGE ]: __( 'Large' ), + [ IMAGE_SIZE_FULL_SIZE ]: __( 'Full Size' ), +}; +const sizeOptions = map( sizeOptionLabels, ( label, option ) => ( { value: option, label } ) ); + // Default Image ratio 4:3 const IMAGE_ASPECT_RATIO = 4 / 3; @@ -70,6 +84,7 @@ export class ImageEdit extends React.Component { this.updateImageURL = this.updateImageURL.bind( this ); this.onSetLinkDestination = this.onSetLinkDestination.bind( this ); this.onSetNewTab = this.onSetNewTab.bind( this ); + this.onSetSizeSlug = this.onSetSizeSlug.bind( this ); this.onImagePressed = this.onImagePressed.bind( this ); this.onClearSettings = this.onClearSettings.bind( this ); this.onFocusCaption = this.onFocusCaption.bind( this ); @@ -179,12 +194,19 @@ export class ImageEdit extends React.Component { this.props.setAttributes( updatedLinkTarget ); } + onSetSizeSlug( sizeSlug ) { + this.props.setAttributes( { + sizeSlug, + } ); + } + onClearSettings() { this.props.setAttributes( { alt: '', linkDestination: LINK_DESTINATION_NONE, href: undefined, linkTarget: undefined, + sizeSlug: DEFAULT_SIZE_SLUG, rel: undefined, } ); } @@ -216,7 +238,7 @@ export class ImageEdit extends React.Component { render() { const { attributes, isSelected } = this.props; - const { url, height, width, alt, href, id, linkTarget } = attributes; + const { url, height, width, alt, href, id, linkTarget, sizeSlug } = attributes; const getToolbarEditButton = ( open ) => ( <BlockControls> @@ -249,6 +271,16 @@ export class ImageEdit extends React.Component { checked={ linkTarget === '_blank' } onChange={ this.onSetNewTab } /> + { // eslint-disable-next-line no-undef + __DEV__ && + <SelectControl + hideCancelButton + icon={ 'editor-expand' } + label={ __( 'Size' ) } + value={ sizeOptionLabels[ sizeSlug || DEFAULT_SIZE_SLUG ] } + onChangeValue={ ( newValue ) => this.onSetSizeSlug( newValue ) } + options={ sizeOptions } + /> } <TextControl icon={ 'editor-textcolor' } label={ __( 'Alt Text' ) } diff --git a/packages/components/src/mobile/bottom-sheet/cell.native.js b/packages/components/src/mobile/bottom-sheet/cell.native.js index af74a25e2cee82..5c97e762f3d480 100644 --- a/packages/components/src/mobile/bottom-sheet/cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/cell.native.js @@ -42,6 +42,7 @@ class BottomSheetCell extends Component { value, valuePlaceholder = '', icon, + leftAlign, labelStyle = {}, valueStyle = {}, onChangeValue, @@ -57,7 +58,10 @@ class BottomSheetCell extends Component { const isValueEditable = editable && onChangeValue !== undefined; const cellLabelStyle = getStylesFromColorScheme( styles.cellLabel, styles.cellTextDark ); const cellLabelCenteredStyle = getStylesFromColorScheme( styles.cellLabelCentered, styles.cellTextDark ); - const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : cellLabelCenteredStyle; + const cellLabelLeftAlignNoIconStyle = getStylesFromColorScheme( styles.cellLabelLeftAlignNoIcon, styles.cellTextDark ); + const defaultMissingIconAndValue = leftAlign ? cellLabelLeftAlignNoIconStyle : cellLabelCenteredStyle; + const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : defaultMissingIconAndValue; + const drawSeparator = ( separatorType && separatorType !== 'none' ) || separatorStyle === undefined; const onCellPress = () => { diff --git a/packages/components/src/mobile/bottom-sheet/index.native.js b/packages/components/src/mobile/bottom-sheet/index.native.js index f17284b49e7306..4de3335189dce8 100644 --- a/packages/components/src/mobile/bottom-sheet/index.native.js +++ b/packages/components/src/mobile/bottom-sheet/index.native.js @@ -136,6 +136,8 @@ class BottomSheet extends Component { onBackdropPress={ this.props.onClose } onBackButtonPress={ this.props.onClose } onSwipe={ this.props.onClose } + onDismiss={ Platform.OS === 'ios' ? this.props.onDismiss : undefined } + onModalHide={ Platform.OS === 'android' ? this.props.onDismiss : undefined } swipeDirection="down" onMoveShouldSetResponder={ panResponder.panHandlers.onMoveShouldSetResponder } onMoveShouldSetResponderCapture={ panResponder.panHandlers.onMoveShouldSetResponderCapture } diff --git a/packages/components/src/mobile/bottom-sheet/picker-cell.native.js b/packages/components/src/mobile/bottom-sheet/picker-cell.native.js index 50a775f25728b1..12eae94c7d8919 100644 --- a/packages/components/src/mobile/bottom-sheet/picker-cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/picker-cell.native.js @@ -7,6 +7,7 @@ import Picker from '../picker'; export default function BottomSheetPickerCell( props ) { const { options, + hideCancelButton, onChangeValue, ...cellProps } = props; @@ -24,6 +25,8 @@ export default function BottomSheetPickerCell( props ) { return ( <Cell onPress={ onCellPress } editable={ false } { ...cellProps } > <Picker + leftAlign + hideCancelButton={ hideCancelButton } ref={ ( instance ) => picker = instance } options={ options } onChange={ onChange } diff --git a/packages/components/src/mobile/bottom-sheet/styles.native.scss b/packages/components/src/mobile/bottom-sheet/styles.native.scss index 8f153715c16705..86422f3228cac4 100644 --- a/packages/components/src/mobile/bottom-sheet/styles.native.scss +++ b/packages/components/src/mobile/bottom-sheet/styles.native.scss @@ -120,6 +120,13 @@ text-align: center; } +.cellLabelLeftAlignNoIcon { + font-size: 17px; + color: #2e4453; + flex: 1; + margin-left: 12px; +} + .cellValue { font-size: 17px; color: #2e4453; diff --git a/packages/components/src/mobile/picker/index.android.js b/packages/components/src/mobile/picker/index.android.js index 3fad1cc2b23bf0..372378e0a2b3ed 100644 --- a/packages/components/src/mobile/picker/index.android.js +++ b/packages/components/src/mobile/picker/index.android.js @@ -52,6 +52,7 @@ export default class Picker extends Component { <BottomSheet.Cell icon={ option.icon } key={ index } + leftAlign={ this.props.leftAlign } label={ option.label } separatorType={ 'none' } onPress={ () => this.onCellPress( option.value ) } diff --git a/packages/components/src/mobile/picker/index.ios.js b/packages/components/src/mobile/picker/index.ios.js index 2cf9798b28e9c0..9de17d1ff7060a 100644 --- a/packages/components/src/mobile/picker/index.ios.js +++ b/packages/components/src/mobile/picker/index.ios.js @@ -11,12 +11,13 @@ import { Component } from '@wordpress/element'; class Picker extends Component { presentPicker() { - const { options, onChange } = this.props; + const { options, onChange, title } = this.props; const labels = options.map( ( { label } ) => label ); const fullOptions = [ __( 'Cancel' ) ].concat( labels ); ActionSheetIOS.showActionSheetWithOptions( { + title, options: fullOptions, cancelButtonIndex: 0, }, From fb6dee80e07042745858f38978445de0e6273eee Mon Sep 17 00:00:00 2001 From: Joen Asmussen <joen@automattic.com> Date: Wed, 16 Oct 2019 13:39:45 +0200 Subject: [PATCH 023/113] Improve columns flex rule, round 2. (#17968) --- packages/block-library/src/columns/editor.scss | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/columns/editor.scss b/packages/block-library/src/columns/editor.scss index dfa71f9f0589b3..2045a1e12e9659 100644 --- a/packages/block-library/src/columns/editor.scss +++ b/packages/block-library/src/columns/editor.scss @@ -43,7 +43,14 @@ > [data-type="core/column"] > .editor-block-list__block-edit .block-core-columns { display: flex; flex-direction: column; - flex: 1 0 auto; + + // This flex rule fixes an issue in IE11. + flex: 1 1 auto; + + // IE11 does not support `position: sticky`, so we use it here to serve correct Flex rules to modern browsers. + @supports (position: sticky) { + flex: 1; + } } // Adjust the individual column block. From f71a7d1c3d84481b46eb05a260703981ff71f6d8 Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Wed, 16 Oct 2019 12:48:10 +0100 Subject: [PATCH 024/113] Bump plugin version to 6.7.0 --- 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 a0248b5bc3fa8b..397d62dbb343f7 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: 6.7.0-rc.1 + * Version: 6.7.0 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 14914f59f2eaa3..b0800b864bd84a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.7.0-rc.1", + "version": "6.7.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ae658d2473c986..013c7e69214101 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.7.0-rc.1", + "version": "6.7.0", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", From 5a055336832730a91c1e1579e8261dd6075cd176 Mon Sep 17 00:00:00 2001 From: Dan Phiffer <dan@phiffer.org> Date: Wed, 16 Oct 2019 09:01:42 -0400 Subject: [PATCH 025/113] Small changes to Git Workflow docs (#17662) * :information_desk_person: add 'upstream' remote * :bug: origin / remote --- docs/contributors/git-workflow.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/contributors/git-workflow.md b/docs/contributors/git-workflow.md index 7f1499bc7de34a..5fe7a79d556fa3 100644 --- a/docs/contributors/git-workflow.md +++ b/docs/contributors/git-workflow.md @@ -36,12 +36,23 @@ To sum it up, you need to fetch any new changes in the repository, rebase your b ```sh git fetch git rebase master -git push --force-with-lease your-branch-name +git push --force-with-lease origin your-branch-name ``` ## Keeping Your Fork Up To Date -Working on pull request starts with forking the Gutenberg repository, your separate working copy. Which can easily go out of sync as new pull requests are merged into the main repository. Here your working repository is a `fork` and the main Gutenberg repository is `upstream`. When working on new pull request you should always update your fork before you do `git checkout -b my-new-branch` to work on a feature or fix. +Working on pull request starts with forking the Gutenberg repository, your separate working copy. Which can easily go out of sync as new pull requests are merged into the main repository. Here your working repository is a `fork` and the main Gutenberg repository is `upstream`. When working on new pull request you should always update your fork before you do `git checkout -b my-new-branch` to work on a feature or fix. + +You will need to add an `upstream` remote in order to keep your fork updated. + +```sh +git remote add origin upstream https://github.com/WordPress/gutenberg.git +git remote -v +origin git@github.com:your-account/gutenberg.git (fetch) +origin git@github.com:your-account/gutenberg.git (push) +upstream https://github.com/WordPress/gutenberg.git (fetch) +upstream https://github.com/WordPress/gutenberg.git (push) +``` To sync your fork you need to fetch the upstream changes and merge them into your fork. These are the corresponding commands: @@ -57,7 +68,7 @@ This will update you local copy to update your fork on github push your changes git push ``` -The above commands will update your `master` branch from _upstream_. To update any other branch replace `master` with the respective branch name. +The above commands will update your `master` branch from _upstream_. To update any other branch replace `master` with the respective branch name. ## References From e5ecca57be4a068f16d7cfdcdd41ad888b50ffa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Wed, 16 Oct 2019 16:55:17 +0200 Subject: [PATCH 026/113] Codeowners: Remove gziolo from some folders (#17971) I get too many notifications. --- .github/CODEOWNERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 33d5a864d489d8..c6d9694eae9b62 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,7 +40,7 @@ /packages/custom-templated-path-webpack-plugin @ntwb @nerrad @ajitbohra /packages/docgen @nosolosw /packages/e2e-test-utils @gziolo @ntwb @nerrad @ajitbohra -/packages/e2e-tests @gziolo @ntwb @nerrad @ajitbohra @talldan +/packages/e2e-tests @ntwb @nerrad @ajitbohra @talldan /packages/eslint-plugin @gziolo @ntwb @nerrad @ajitbohra /packages/jest-console @gziolo @ntwb @nerrad @ajitbohra /packages/jest-preset-default @gziolo @ntwb @nerrad @ajitbohra @@ -51,9 +51,9 @@ /packages/scripts @youknowriad @gziolo @ntwb @nerrad @ajitbohra # UI Components -/packages/components @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @chrisvanpatten -/packages/compose @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan -/packages/element @youknowriad @gziolo @ajitbohra @jaymanpandya @jorgefilipecosta @talldan +/packages/components @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @chrisvanpatten +/packages/compose @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan +/packages/element @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan /packages/notices @ajitbohra @jaymanpandya @jorgefilipecosta @talldan /packages/nux @ajitbohra @jaymanpandya @jorgefilipecosta @talldan @noisysocks /packages/viewport @youknowriad @ajitbohra @jaymanpandya @jorgefilipecosta @talldan From 7a2298b98989a77de67acbf66c426e248a23bf9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Wed, 16 Oct 2019 22:35:07 +0200 Subject: [PATCH 027/113] Fix: Invalid import statement for deprecated in the modal component (#17969) * Fix: Invalid import statement for deprecated in the modal component * Font Size Picker: Update E2E test to work with new Core changes. --- packages/components/src/modal/index.js | 2 +- packages/e2e-tests/specs/font-size-picker.test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/src/modal/index.js b/packages/components/src/modal/index.js index 66d3421ee6ff5c..f4a64c289b4e7d 100644 --- a/packages/components/src/modal/index.js +++ b/packages/components/src/modal/index.js @@ -3,7 +3,7 @@ */ import { Component, createPortal } from '@wordpress/element'; import { withInstanceId } from '@wordpress/compose'; -import { deprecated } from '@wordpress/deprecated'; +import deprecated from '@wordpress/deprecated'; /** * Internal dependencies diff --git a/packages/e2e-tests/specs/font-size-picker.test.js b/packages/e2e-tests/specs/font-size-picker.test.js index a80a81b46442d3..0fb98caa4f5d29 100644 --- a/packages/e2e-tests/specs/font-size-picker.test.js +++ b/packages/e2e-tests/specs/font-size-picker.test.js @@ -75,8 +75,8 @@ describe( 'Font Size Picker', () => { // Clear the custom font size input. await page.click( '.blocks-font-size .components-range-control__number' ); - await pressKeyTimes( 'ArrowRight', 4 ); - await pressKeyTimes( 'Backspace', 4 ); + await pressKeyTimes( 'ArrowRight', 5 ); + await pressKeyTimes( 'Backspace', 5 ); // Ensure content matches snapshot. const content = await getEditedPostContent(); From 56a27599d72718df787338dfb47cb0b39c39f4d8 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Wed, 16 Oct 2019 14:37:16 -0700 Subject: [PATCH 028/113] Add empty line (#17981) --- packages/components/storybook/config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/components/storybook/config.js b/packages/components/storybook/config.js index 6b75e0111b27d8..b2bfd74c3da6eb 100644 --- a/packages/components/storybook/config.js +++ b/packages/components/storybook/config.js @@ -4,6 +4,7 @@ import { addDecorator, configure } from '@storybook/react'; import { withA11y } from '@storybook/addon-a11y'; import { withKnobs } from '@storybook/addon-knobs'; + /** * Internal dependencies */ From f94dadb5b562308795a85398db2681f42bda6c6b Mon Sep 17 00:00:00 2001 From: Daniel Richards <daniel.richards@automattic.com> Date: Thu, 17 Oct 2019 07:38:45 +0800 Subject: [PATCH 029/113] Try setting a block display name for the Block Navigator. (#17519) * Really simple first attempt at showing a display name in the navigator * Strip any RichText formatting * Add display name for navigation menu item block * Refactor to use displayNameAttribute property * Change name of displayName options --- .../src/components/block-navigation/list.js | 25 ++++++++++++++++++- .../src/navigation-menu-item/index.js | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-navigation/list.js b/packages/block-editor/src/components/block-navigation/list.js index 0a34d24ff4e4b6..a0910caf5b41cc 100644 --- a/packages/block-editor/src/components/block-navigation/list.js +++ b/packages/block-editor/src/components/block-navigation/list.js @@ -10,12 +10,35 @@ import classnames from 'classnames'; import { Button } from '@wordpress/components'; import { getBlockType } from '@wordpress/blocks'; import { __ } from '@wordpress/i18n'; +import { create, getTextContent } from '@wordpress/rich-text'; /** * Internal dependencies */ import BlockIcon from '../block-icon'; +/** + * Get the block display name, if it has one, or the block title if it doesn't. + * + * @param {Object} blockType The block type. + * @param {Object} attributes The values of the block's attributes + * + * @return {string} The display name value. + */ +function getBlockDisplayName( blockType, attributes ) { + const displayNameAttribute = blockType.__experimentalDisplayName; + + if ( ! displayNameAttribute || ! attributes[ displayNameAttribute ] ) { + return blockType.title; + } + + // Strip any formatting. + const richTextValue = create( { html: attributes[ displayNameAttribute ] } ); + const formatlessDisplayName = getTextContent( richTextValue ); + + return formatlessDisplayName; +} + export default function BlockNavigationList( { blocks, selectedBlockClientId, @@ -43,7 +66,7 @@ export default function BlockNavigationList( { onClick={ () => selectBlock( block.clientId ) } > <BlockIcon icon={ blockType.icon } showColors /> - { blockType.title } + { getBlockDisplayName( blockType, block.attributes ) } { isSelected && <span className="screen-reader-text">{ __( '(selected block)' ) }</span> } </Button> </div> diff --git a/packages/block-library/src/navigation-menu-item/index.js b/packages/block-library/src/navigation-menu-item/index.js index 496ef92070428e..b61f3699e12b5c 100644 --- a/packages/block-library/src/navigation-menu-item/index.js +++ b/packages/block-library/src/navigation-menu-item/index.js @@ -22,6 +22,8 @@ export const settings = { description: __( 'Add a page, link, or other item to your Navigation Menu.' ), + __experimentalDisplayName: 'label', + edit, save, }; From 207bf752e961bbe33fbb84ee8b5840d0a0b54cd2 Mon Sep 17 00:00:00 2001 From: jbinda <jakub.binda@gmail.com> Date: Thu, 17 Oct 2019 09:56:30 +0200 Subject: [PATCH 030/113] [RNMobile] add RangeControl mobile implementation (slider) (#17282) * add RangeCell --- .../src/mobile/bottom-sheet/index.native.js | 2 + .../mobile/bottom-sheet/range-cell.native.js | 46 +++++++ .../src/mobile/slider/index.native.js | 118 ++++++++++++++++++ .../components/src/mobile/slider/styles.scss | 27 ++++ 4 files changed, 193 insertions(+) create mode 100644 packages/components/src/mobile/bottom-sheet/range-cell.native.js create mode 100644 packages/components/src/mobile/slider/index.native.js create mode 100644 packages/components/src/mobile/slider/styles.scss diff --git a/packages/components/src/mobile/bottom-sheet/index.native.js b/packages/components/src/mobile/bottom-sheet/index.native.js index 4de3335189dce8..34d05a83974957 100644 --- a/packages/components/src/mobile/bottom-sheet/index.native.js +++ b/packages/components/src/mobile/bottom-sheet/index.native.js @@ -19,6 +19,7 @@ import Button from './button'; import Cell from './cell'; import PickerCell from './picker-cell'; import SwitchCell from './switch-cell'; +import RangeCell from './range-cell'; import KeyboardAvoidingView from './keyboard-avoiding-view'; class BottomSheet extends Component { @@ -173,5 +174,6 @@ ThemedBottomSheet.Button = Button; ThemedBottomSheet.Cell = Cell; ThemedBottomSheet.PickerCell = PickerCell; ThemedBottomSheet.SwitchCell = SwitchCell; +ThemedBottomSheet.RangeCell = RangeCell; export default ThemedBottomSheet; diff --git a/packages/components/src/mobile/bottom-sheet/range-cell.native.js b/packages/components/src/mobile/bottom-sheet/range-cell.native.js new file mode 100644 index 00000000000000..07b343e9ec0781 --- /dev/null +++ b/packages/components/src/mobile/bottom-sheet/range-cell.native.js @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import { Platform } from 'react-native'; + +/** + * Internal dependencies + */ +import Cell from './cell'; +import Slider from '../slider'; + +export default function BottomSheetRangeCell( props ) { + const { + value, + defaultValue, + onChangeValue, + minimumValue = 0, + maximumValue = 10, + disabled, + step = 1, + minimumTrackTintColor = '#00669b', + maximumTrackTintColor = Platform.OS === 'ios' ? '#e9eff3' : '#909090', + thumbTintColor = Platform.OS === 'ios' ? '#fff' : '#00669b', + ...cellProps + } = props; + + return ( + <Cell + editable={ false } + { ...cellProps } + > + <Slider + value={ value } + defaultValue={ defaultValue } + disabled={ disabled } + step={ step } + minimumValue={ minimumValue } + maximumValue={ maximumValue } + minimumTrackTintColor={ minimumTrackTintColor } + maximumTrackTintColor={ maximumTrackTintColor } + thumbTintColor={ thumbTintColor } + onChangeValue={ onChangeValue } + /> + </Cell> + ); +} diff --git a/packages/components/src/mobile/slider/index.native.js b/packages/components/src/mobile/slider/index.native.js new file mode 100644 index 00000000000000..111d9987e973db --- /dev/null +++ b/packages/components/src/mobile/slider/index.native.js @@ -0,0 +1,118 @@ +/** + * External dependencies + */ +import { Slider as RNSlider, TextInput, View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import styles from './styles.scss'; + +class Slider extends Component { + constructor( props ) { + super( props ); + this.handleToggleFocus = this.handleToggleFocus.bind( this ); + this.handleChange = this.handleChange.bind( this ); + this.handleValueSave = this.handleValueSave.bind( this ); + this.handleReset = this.handleReset.bind( this ); + + const initialValue = this.validateInput( props.value || props.defaultValue || props.minimumValue ); + + this.state = { hasFocus: false, initialValue, sliderValue: initialValue }; + } + + componentDidUpdate( ) { + const reset = this.props.value === null; + if ( reset ) { + this.handleReset(); + } + } + + handleToggleFocus( validateInput = true ) { + const newState = { hasFocus: ! this.state.hasFocus }; + + if ( validateInput ) { + const sliderValue = this.validateInput( this.state.sliderValue ); + this.handleValueSave( sliderValue ); + } + + this.setState( newState ); + } + + validateInput( text ) { + const { minimumValue, maximumValue } = this.props; + if ( ! text ) { + return minimumValue; + } + if ( typeof text === 'number' ) { + return Math.min( Math.max( text, minimumValue ), maximumValue ); + } + return Math.min( Math.max( text.replace( /[^0-9]/g, '' ).replace( /^0+(?=\d)/, '' ), minimumValue ), maximumValue ); + } + + handleChange( text ) { + if ( ! isNaN( Number( text ) ) ) { + this.setState( { sliderValue: text } ); + } + } + + handleValueSave( text ) { + if ( ! isNaN( Number( text ) ) ) { + if ( this.props.onChangeValue ) { + this.props.onChangeValue( text ); + } + this.setState( { sliderValue: text } ); + } + } + + handleReset() { + this.handleValueSave( this.props.defaultValue || this.state.initialValue ); + } + + render() { + const { + minimumValue, + maximumValue, + disabled, + step, + minimumTrackTintColor, + maximumTrackTintColor, + thumbTintColor, + } = this.props; + + const { hasFocus, sliderValue } = this.state; + + return ( + <View style={ styles.sliderContainer }> + <RNSlider + value={ this.validateInput( sliderValue ) } + disabled={ disabled } + style={ styles.slider } + step={ step } + minimumValue={ minimumValue } + maximumValue={ maximumValue } + minimumTrackTintColor={ minimumTrackTintColor } + maximumTrackTintColor={ maximumTrackTintColor } + thumbTintColor={ thumbTintColor } + onValueChange={ this.handleChange } + onSlidingComplete={ this.handleValueSave } + /> + <TextInput + style={ [ styles.sliderTextInput, hasFocus ? styles.isSelected : {} ] } + onChangeText={ this.handleChange } + onFocus={ this.handleToggleFocus } + onBlur={ this.handleToggleFocus } + keyboardType="numeric" + value={ `${ sliderValue }` } + /> + </View> + ); + } +} + +export default Slider; diff --git a/packages/components/src/mobile/slider/styles.scss b/packages/components/src/mobile/slider/styles.scss new file mode 100644 index 00000000000000..326880b621807a --- /dev/null +++ b/packages/components/src/mobile/slider/styles.scss @@ -0,0 +1,27 @@ +.sliderContainer { + flex: 1; + flex-direction: row; + align-content: center; + justify-content: space-evenly; +} + +.slider { + flex-grow: 1; +} + +.sliderTextInput { + width: 40px; + height: 25px; + align-self: center; + margin-left: 10px; + border-width: 1px; + border-radius: 4px; + border-color: $dark-gray-150; + padding-top: 0; + padding-bottom: 0; +} + +.isSelected { + border-width: 2px; + border-color: $blue-wordpress; +} From b13a6fc292f91bf3545164b434bf64ad03d2c184 Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Thu, 17 Oct 2019 13:54:39 +0100 Subject: [PATCH 031/113] Split e2e tests into multiple folders (#17990) --- packages/e2e-tests/jest.config.js | 2 +- packages/e2e-tests/jest.performance.config.js | 2 +- .../{ => editor}/blocks/__snapshots__/button.test.js.snap | 0 .../{ => editor}/blocks/__snapshots__/classic.test.js.snap | 0 .../specs/{ => editor}/blocks/__snapshots__/code.test.js.snap | 0 .../{ => editor}/blocks/__snapshots__/group.test.js.snap | 0 .../{ => editor}/blocks/__snapshots__/heading.test.js.snap | 0 .../specs/{ => editor}/blocks/__snapshots__/html.test.js.snap | 0 .../specs/{ => editor}/blocks/__snapshots__/list.test.js.snap | 0 .../blocks/__snapshots__/preformatted.test.js.snap | 0 .../{ => editor}/blocks/__snapshots__/quote.test.js.snap | 0 .../{ => editor}/blocks/__snapshots__/separator.test.js.snap | 0 .../{ => editor}/blocks/__snapshots__/spacer.test.js.snap | 0 .../{ => editor}/blocks/__snapshots__/table.test.js.snap | 0 packages/e2e-tests/specs/{ => editor}/blocks/button.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/classic.test.js | 2 +- packages/e2e-tests/specs/{ => editor}/blocks/code.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/columns.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/group.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/heading.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/html.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/list.test.js | 0 .../e2e-tests/specs/{ => editor}/blocks/preformatted.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/quote.test.js | 0 .../e2e-tests/specs/{ => editor}/blocks/separator.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/spacer.test.js | 0 packages/e2e-tests/specs/{ => editor}/blocks/table.test.js | 0 .../plugins/__snapshots__/align-hook.test.js.snap | 0 .../plugins/__snapshots__/container-blocks.test.js.snap | 0 .../plugins/__snapshots__/cpt-locking.test.js.snap | 0 .../__snapshots__/deprecated-node-matcher.test.js.snap | 0 .../plugins/__snapshots__/format-api.test.js.snap | 0 .../{ => editor}/plugins/__snapshots__/hooks-api.test.js.snap | 0 .../plugins/__snapshots__/meta-attribute-block.test.js.snap | 0 .../plugins/__snapshots__/plugins-api.test.js.snap | 0 .../{ => editor}/plugins/__snapshots__/templates.test.js.snap | 0 .../plugins/__snapshots__/wp-editor-meta-box.test.js.snap | 0 .../e2e-tests/specs/{ => editor}/plugins/align-hook.test.js | 0 .../specs/{ => editor}/plugins/allowed-blocks.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/annotations.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/block-icons.test.js | 0 .../specs/{ => editor}/plugins/container-blocks.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/cpt-locking.test.js | 0 .../specs/{ => editor}/plugins/custom-taxonomies.test.js | 0 .../{ => editor}/plugins/deprecated-node-matcher.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/format-api.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/hooks-api.test.js | 0 .../{ => editor}/plugins/inner-blocks-allowed-blocks.test.js | 0 .../{ => editor}/plugins/innerblocks-locking-all-embed.js | 0 .../specs/{ => editor}/plugins/meta-attribute-block.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/meta-boxes.test.js | 0 packages/e2e-tests/specs/{ => editor}/plugins/nonce.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/plugins-api.test.js | 0 .../e2e-tests/specs/{ => editor}/plugins/templates.test.js | 0 .../specs/{ => editor}/plugins/wp-editor-meta-box.test.js | 0 .../various}/__snapshots__/adding-blocks.test.js.snap | 0 .../various}/__snapshots__/block-deletion.test.js.snap | 0 .../various}/__snapshots__/block-grouping.test.js.snap | 0 .../__snapshots__/block-hierarchy-navigation.test.js.snap | 0 .../__snapshots__/compatibility-classic-editor.test.js.snap | 0 .../various}/__snapshots__/convert-block-type.test.js.snap | 0 .../{ => editor/various}/__snapshots__/embedding.test.js.snap | 0 .../various}/__snapshots__/font-size-picker.test.js.snap | 0 .../{ => editor/various}/__snapshots__/links.test.js.snap | 0 .../{ => editor/various}/__snapshots__/mentions.test.js.snap | 0 .../various}/__snapshots__/multi-block-selection.test.js.snap | 0 .../various}/__snapshots__/reusable-blocks.test.js.snap | 0 .../{ => editor/various}/__snapshots__/rich-text.test.js.snap | 0 .../specs/{ => editor/various}/__snapshots__/rtl.test.js.snap | 0 .../various}/__snapshots__/splitting-merging.test.js.snap | 0 .../various}/__snapshots__/style-variation.test.js.snap | 0 .../{ => editor/various}/__snapshots__/undo.test.js.snap | 0 .../various}/__snapshots__/writing-flow.test.js.snap | 0 packages/e2e-tests/specs/{ => editor/various}/a11y.test.js | 0 .../specs/{ => editor/various}/adding-blocks.test.js | 0 .../specs/{ => editor/various}/adding-inline-tokens.test.js | 2 +- .../e2e-tests/specs/{ => editor/various}/autosave.test.js | 0 .../specs/{ => editor/various}/block-deletion.test.js | 0 .../specs/{ => editor/various}/block-grouping.test.js | 0 .../{ => editor/various}/block-hierarchy-navigation.test.js | 0 .../e2e-tests/specs/{ => editor/various}/block-mover.test.js | 0 .../specs/{ => editor/various}/block-switcher.test.js | 0 .../specs/{ => editor/various}/change-detection.test.js | 0 .../{ => editor/various}/compatibility-classic-editor.test.js | 0 .../specs/{ => editor/various}/convert-block-type.test.js | 0 .../e2e-tests/specs/{ => editor/various}/datepicker.test.js | 0 .../e2e-tests/specs/{ => editor/various}/editor-modes.test.js | 0 .../e2e-tests/specs/{ => editor/various}/embedding.test.js | 0 .../specs/{ => editor/various}/font-size-picker.test.js | 0 .../specs/{ => editor/various}/fullscreen-mode.test.js | 0 .../specs/{ => editor/various}/invalid-block.test.js | 0 .../{ => editor/various}/keyboard-navigable-blocks.test.js | 0 packages/e2e-tests/specs/{ => editor/various}/links.test.js | 0 .../specs/{ => editor/various}/manage-reusable-blocks.test.js | 2 +- .../e2e-tests/specs/{ => editor/various}/mentions.test.js | 0 .../specs/{ => editor/various}/multi-block-selection.test.js | 0 .../specs/{ => editor/various}/navigable-toolbar.test.js | 0 .../{ => editor/various}/new-post-default-content.test.js | 0 .../e2e-tests/specs/{ => editor/various}/new-post.test.js | 0 packages/e2e-tests/specs/{ => editor/various}/nux.test.js | 0 .../e2e-tests/specs/{ => editor/various}/popovers.test.js | 0 .../specs/{ => editor/various}/post-visibility.test.js | 0 .../e2e-tests/specs/{ => editor/various}/preferences.test.js | 0 packages/e2e-tests/specs/{ => editor/various}/preview.test.js | 0 .../specs/{ => editor/various}/publish-button.test.js | 0 .../specs/{ => editor/various}/publish-panel.test.js | 0 .../e2e-tests/specs/{ => editor/various}/publishing.test.js | 0 .../specs/{ => editor/various}/reusable-blocks.test.js | 0 .../e2e-tests/specs/{ => editor/various}/rich-text.test.js | 0 packages/e2e-tests/specs/{ => editor/various}/rtl.test.js | 0 .../e2e-tests/specs/{ => editor/various}/scheduling.test.js | 0 .../specs/{ => editor/various}/shortcut-help.test.js | 0 .../{ => editor/various}/sidebar-permalink-panel.test.js | 0 packages/e2e-tests/specs/{ => editor/various}/sidebar.test.js | 0 .../specs/{ => editor/various}/splitting-merging.test.js | 0 .../specs/{ => editor/various}/style-variation.test.js | 0 .../e2e-tests/specs/{ => editor/various}/taxonomies.test.js | 0 .../e2e-tests/specs/{ => editor/various}/typewriter.test.js | 0 packages/e2e-tests/specs/{ => editor/various}/undo.test.js | 0 .../e2e-tests/specs/{ => editor/various}/writing-flow.test.js | 0 .../__snapshots__/block-transforms.test.js.snap | 0 .../specs/{ => experimental}/block-transforms.test.js | 4 ++-- packages/e2e-tests/specs/{ => local}/demo.test.js | 0 packages/e2e-tests/specs/{ => performance}/.gitignore | 0 .../e2e-tests/specs/{ => performance}/performance.test.js | 0 125 files changed, 7 insertions(+), 7 deletions(-) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/button.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/classic.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/code.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/group.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/heading.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/html.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/list.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/preformatted.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/quote.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/separator.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/spacer.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/__snapshots__/table.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/button.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/classic.test.js (95%) rename packages/e2e-tests/specs/{ => editor}/blocks/code.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/columns.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/group.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/heading.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/html.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/list.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/preformatted.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/quote.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/separator.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/spacer.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/blocks/table.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/align-hook.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/container-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/cpt-locking.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/deprecated-node-matcher.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/format-api.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/hooks-api.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/meta-attribute-block.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/plugins-api.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/templates.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/__snapshots__/wp-editor-meta-box.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/align-hook.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/allowed-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/annotations.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/block-icons.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/container-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/cpt-locking.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/custom-taxonomies.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/deprecated-node-matcher.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/format-api.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/hooks-api.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/inner-blocks-allowed-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/innerblocks-locking-all-embed.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/meta-attribute-block.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/meta-boxes.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/nonce.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/plugins-api.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/templates.test.js (100%) rename packages/e2e-tests/specs/{ => editor}/plugins/wp-editor-meta-box.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/adding-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/block-deletion.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/block-grouping.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/block-hierarchy-navigation.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/compatibility-classic-editor.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/convert-block-type.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/embedding.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/font-size-picker.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/links.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/mentions.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/multi-block-selection.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/reusable-blocks.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/rich-text.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/rtl.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/splitting-merging.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/style-variation.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/undo.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/__snapshots__/writing-flow.test.js.snap (100%) rename packages/e2e-tests/specs/{ => editor/various}/a11y.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/adding-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/adding-inline-tokens.test.js (93%) rename packages/e2e-tests/specs/{ => editor/various}/autosave.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-deletion.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-grouping.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-hierarchy-navigation.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-mover.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/block-switcher.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/change-detection.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/compatibility-classic-editor.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/convert-block-type.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/datepicker.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/editor-modes.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/embedding.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/font-size-picker.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/fullscreen-mode.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/invalid-block.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/keyboard-navigable-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/links.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/manage-reusable-blocks.test.js (93%) rename packages/e2e-tests/specs/{ => editor/various}/mentions.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/multi-block-selection.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/navigable-toolbar.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/new-post-default-content.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/new-post.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/nux.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/popovers.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/post-visibility.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/preferences.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/preview.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/publish-button.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/publish-panel.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/publishing.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/reusable-blocks.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/rich-text.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/rtl.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/scheduling.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/shortcut-help.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/sidebar-permalink-panel.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/sidebar.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/splitting-merging.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/style-variation.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/taxonomies.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/typewriter.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/undo.test.js (100%) rename packages/e2e-tests/specs/{ => editor/various}/writing-flow.test.js (100%) rename packages/e2e-tests/specs/{ => experimental}/__snapshots__/block-transforms.test.js.snap (100%) rename packages/e2e-tests/specs/{ => experimental}/block-transforms.test.js (97%) rename packages/e2e-tests/specs/{ => local}/demo.test.js (100%) rename packages/e2e-tests/specs/{ => performance}/.gitignore (100%) rename packages/e2e-tests/specs/{ => performance}/performance.test.js (100%) diff --git a/packages/e2e-tests/jest.config.js b/packages/e2e-tests/jest.config.js index 2720488c7b36de..22bccf74e3d1a1 100644 --- a/packages/e2e-tests/jest.config.js +++ b/packages/e2e-tests/jest.config.js @@ -12,6 +12,6 @@ module.exports = { testPathIgnorePatterns: [ '/node_modules/', '/wordpress/', - 'e2e-tests/specs/performance.test.js', + 'e2e-tests/specs/performance/', ], }; diff --git a/packages/e2e-tests/jest.performance.config.js b/packages/e2e-tests/jest.performance.config.js index f8fe4cf8ff1ff6..cc011820f08871 100644 --- a/packages/e2e-tests/jest.performance.config.js +++ b/packages/e2e-tests/jest.performance.config.js @@ -1,7 +1,7 @@ module.exports = { ...require( '@wordpress/scripts/config/jest-e2e.config' ), testMatch: [ - '**/performance.test.js', + '**/performance/*.test.js', ], setupFiles: [ '<rootDir>/config/gutenberg-phase.js', diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/button.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/button.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/button.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/button.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/classic.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/classic.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/classic.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/classic.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/code.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/code.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/code.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/code.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/group.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/group.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/group.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/heading.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/heading.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/heading.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/heading.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/html.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/html.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/html.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/html.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/preformatted.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/preformatted.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/preformatted.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/preformatted.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/quote.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/quote.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/quote.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/quote.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/separator.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/separator.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/separator.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/separator.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/spacer.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/spacer.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/spacer.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/spacer.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/__snapshots__/table.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/blocks/__snapshots__/table.test.js.snap rename to packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap diff --git a/packages/e2e-tests/specs/blocks/button.test.js b/packages/e2e-tests/specs/editor/blocks/button.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/button.test.js rename to packages/e2e-tests/specs/editor/blocks/button.test.js diff --git a/packages/e2e-tests/specs/blocks/classic.test.js b/packages/e2e-tests/specs/editor/blocks/classic.test.js similarity index 95% rename from packages/e2e-tests/specs/blocks/classic.test.js rename to packages/e2e-tests/specs/editor/blocks/classic.test.js index 29d1605f0874b5..29170335d900f1 100644 --- a/packages/e2e-tests/specs/blocks/classic.test.js +++ b/packages/e2e-tests/specs/editor/blocks/classic.test.js @@ -49,7 +49,7 @@ describe( 'Classic', () => { // Wait for media modal to appear and upload image. await page.waitForSelector( '.media-modal input[type=file]' ); const inputElement = await page.$( '.media-modal input[type=file]' ); - const testImagePath = path.join( __dirname, '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); + const testImagePath = path.join( __dirname, '..', '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); diff --git a/packages/e2e-tests/specs/blocks/code.test.js b/packages/e2e-tests/specs/editor/blocks/code.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/code.test.js rename to packages/e2e-tests/specs/editor/blocks/code.test.js diff --git a/packages/e2e-tests/specs/blocks/columns.test.js b/packages/e2e-tests/specs/editor/blocks/columns.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/columns.test.js rename to packages/e2e-tests/specs/editor/blocks/columns.test.js diff --git a/packages/e2e-tests/specs/blocks/group.test.js b/packages/e2e-tests/specs/editor/blocks/group.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/group.test.js rename to packages/e2e-tests/specs/editor/blocks/group.test.js diff --git a/packages/e2e-tests/specs/blocks/heading.test.js b/packages/e2e-tests/specs/editor/blocks/heading.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/heading.test.js rename to packages/e2e-tests/specs/editor/blocks/heading.test.js diff --git a/packages/e2e-tests/specs/blocks/html.test.js b/packages/e2e-tests/specs/editor/blocks/html.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/html.test.js rename to packages/e2e-tests/specs/editor/blocks/html.test.js diff --git a/packages/e2e-tests/specs/blocks/list.test.js b/packages/e2e-tests/specs/editor/blocks/list.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/list.test.js rename to packages/e2e-tests/specs/editor/blocks/list.test.js diff --git a/packages/e2e-tests/specs/blocks/preformatted.test.js b/packages/e2e-tests/specs/editor/blocks/preformatted.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/preformatted.test.js rename to packages/e2e-tests/specs/editor/blocks/preformatted.test.js diff --git a/packages/e2e-tests/specs/blocks/quote.test.js b/packages/e2e-tests/specs/editor/blocks/quote.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/quote.test.js rename to packages/e2e-tests/specs/editor/blocks/quote.test.js diff --git a/packages/e2e-tests/specs/blocks/separator.test.js b/packages/e2e-tests/specs/editor/blocks/separator.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/separator.test.js rename to packages/e2e-tests/specs/editor/blocks/separator.test.js diff --git a/packages/e2e-tests/specs/blocks/spacer.test.js b/packages/e2e-tests/specs/editor/blocks/spacer.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/spacer.test.js rename to packages/e2e-tests/specs/editor/blocks/spacer.test.js diff --git a/packages/e2e-tests/specs/blocks/table.test.js b/packages/e2e-tests/specs/editor/blocks/table.test.js similarity index 100% rename from packages/e2e-tests/specs/blocks/table.test.js rename to packages/e2e-tests/specs/editor/blocks/table.test.js diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/align-hook.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/align-hook.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/align-hook.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/container-blocks.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/container-blocks.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/cpt-locking.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/cpt-locking.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/deprecated-node-matcher.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/deprecated-node-matcher.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/deprecated-node-matcher.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/deprecated-node-matcher.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/format-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/format-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/format-api.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/format-api.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/hooks-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/hooks-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/hooks-api.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/hooks-api.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/meta-attribute-block.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/meta-attribute-block.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/meta-attribute-block.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/meta-attribute-block.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/plugins-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/plugins-api.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/templates.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/templates.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/templates.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/__snapshots__/wp-editor-meta-box.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/plugins/__snapshots__/wp-editor-meta-box.test.js.snap rename to packages/e2e-tests/specs/editor/plugins/__snapshots__/wp-editor-meta-box.test.js.snap diff --git a/packages/e2e-tests/specs/plugins/align-hook.test.js b/packages/e2e-tests/specs/editor/plugins/align-hook.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/align-hook.test.js rename to packages/e2e-tests/specs/editor/plugins/align-hook.test.js diff --git a/packages/e2e-tests/specs/plugins/allowed-blocks.test.js b/packages/e2e-tests/specs/editor/plugins/allowed-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/allowed-blocks.test.js rename to packages/e2e-tests/specs/editor/plugins/allowed-blocks.test.js diff --git a/packages/e2e-tests/specs/plugins/annotations.test.js b/packages/e2e-tests/specs/editor/plugins/annotations.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/annotations.test.js rename to packages/e2e-tests/specs/editor/plugins/annotations.test.js diff --git a/packages/e2e-tests/specs/plugins/block-icons.test.js b/packages/e2e-tests/specs/editor/plugins/block-icons.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/block-icons.test.js rename to packages/e2e-tests/specs/editor/plugins/block-icons.test.js diff --git a/packages/e2e-tests/specs/plugins/container-blocks.test.js b/packages/e2e-tests/specs/editor/plugins/container-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/container-blocks.test.js rename to packages/e2e-tests/specs/editor/plugins/container-blocks.test.js diff --git a/packages/e2e-tests/specs/plugins/cpt-locking.test.js b/packages/e2e-tests/specs/editor/plugins/cpt-locking.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/cpt-locking.test.js rename to packages/e2e-tests/specs/editor/plugins/cpt-locking.test.js diff --git a/packages/e2e-tests/specs/plugins/custom-taxonomies.test.js b/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/custom-taxonomies.test.js rename to packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js diff --git a/packages/e2e-tests/specs/plugins/deprecated-node-matcher.test.js b/packages/e2e-tests/specs/editor/plugins/deprecated-node-matcher.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/deprecated-node-matcher.test.js rename to packages/e2e-tests/specs/editor/plugins/deprecated-node-matcher.test.js diff --git a/packages/e2e-tests/specs/plugins/format-api.test.js b/packages/e2e-tests/specs/editor/plugins/format-api.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/format-api.test.js rename to packages/e2e-tests/specs/editor/plugins/format-api.test.js diff --git a/packages/e2e-tests/specs/plugins/hooks-api.test.js b/packages/e2e-tests/specs/editor/plugins/hooks-api.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/hooks-api.test.js rename to packages/e2e-tests/specs/editor/plugins/hooks-api.test.js diff --git a/packages/e2e-tests/specs/plugins/inner-blocks-allowed-blocks.test.js b/packages/e2e-tests/specs/editor/plugins/inner-blocks-allowed-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/inner-blocks-allowed-blocks.test.js rename to packages/e2e-tests/specs/editor/plugins/inner-blocks-allowed-blocks.test.js diff --git a/packages/e2e-tests/specs/plugins/innerblocks-locking-all-embed.js b/packages/e2e-tests/specs/editor/plugins/innerblocks-locking-all-embed.js similarity index 100% rename from packages/e2e-tests/specs/plugins/innerblocks-locking-all-embed.js rename to packages/e2e-tests/specs/editor/plugins/innerblocks-locking-all-embed.js diff --git a/packages/e2e-tests/specs/plugins/meta-attribute-block.test.js b/packages/e2e-tests/specs/editor/plugins/meta-attribute-block.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/meta-attribute-block.test.js rename to packages/e2e-tests/specs/editor/plugins/meta-attribute-block.test.js diff --git a/packages/e2e-tests/specs/plugins/meta-boxes.test.js b/packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/meta-boxes.test.js rename to packages/e2e-tests/specs/editor/plugins/meta-boxes.test.js diff --git a/packages/e2e-tests/specs/plugins/nonce.test.js b/packages/e2e-tests/specs/editor/plugins/nonce.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/nonce.test.js rename to packages/e2e-tests/specs/editor/plugins/nonce.test.js diff --git a/packages/e2e-tests/specs/plugins/plugins-api.test.js b/packages/e2e-tests/specs/editor/plugins/plugins-api.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/plugins-api.test.js rename to packages/e2e-tests/specs/editor/plugins/plugins-api.test.js diff --git a/packages/e2e-tests/specs/plugins/templates.test.js b/packages/e2e-tests/specs/editor/plugins/templates.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/templates.test.js rename to packages/e2e-tests/specs/editor/plugins/templates.test.js diff --git a/packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js b/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js similarity index 100% rename from packages/e2e-tests/specs/plugins/wp-editor-meta-box.test.js rename to packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js diff --git a/packages/e2e-tests/specs/__snapshots__/adding-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/adding-blocks.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/adding-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/block-deletion.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-deletion.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/block-deletion.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/block-deletion.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/block-grouping.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/block-grouping.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/block-grouping.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/block-hierarchy-navigation.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/compatibility-classic-editor.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/compatibility-classic-editor.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/compatibility-classic-editor.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/compatibility-classic-editor.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/convert-block-type.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/convert-block-type.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/convert-block-type.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/convert-block-type.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/embedding.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/embedding.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/embedding.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/font-size-picker.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/font-size-picker.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/font-size-picker.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/font-size-picker.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/links.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/links.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/links.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/mentions.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/mentions.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/mentions.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/mentions.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/multi-block-selection.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/multi-block-selection.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/reusable-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/reusable-blocks.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/rich-text.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/rich-text.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/rich-text.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/rtl.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/rtl.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/rtl.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/rtl.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/splitting-merging.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/splitting-merging.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/splitting-merging.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/splitting-merging.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/style-variation.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/style-variation.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/style-variation.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/style-variation.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/undo.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/undo.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/undo.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/undo.test.js.snap diff --git a/packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/writing-flow.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/writing-flow.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/writing-flow.test.js.snap diff --git a/packages/e2e-tests/specs/a11y.test.js b/packages/e2e-tests/specs/editor/various/a11y.test.js similarity index 100% rename from packages/e2e-tests/specs/a11y.test.js rename to packages/e2e-tests/specs/editor/various/a11y.test.js diff --git a/packages/e2e-tests/specs/adding-blocks.test.js b/packages/e2e-tests/specs/editor/various/adding-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/adding-blocks.test.js rename to packages/e2e-tests/specs/editor/various/adding-blocks.test.js diff --git a/packages/e2e-tests/specs/adding-inline-tokens.test.js b/packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js similarity index 93% rename from packages/e2e-tests/specs/adding-inline-tokens.test.js rename to packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js index f028a73c3df931..b11077e70fb3d3 100644 --- a/packages/e2e-tests/specs/adding-inline-tokens.test.js +++ b/packages/e2e-tests/specs/editor/various/adding-inline-tokens.test.js @@ -33,7 +33,7 @@ describe( 'adding inline tokens', () => { // Wait for media modal to appear and upload image. await page.waitForSelector( '.media-modal input[type=file]' ); const inputElement = await page.$( '.media-modal input[type=file]' ); - const testImagePath = path.join( __dirname, '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); + const testImagePath = path.join( __dirname, '..', '..', '..', 'assets', '10x10_e2e_test_image_z9T8jK.png' ); const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); diff --git a/packages/e2e-tests/specs/autosave.test.js b/packages/e2e-tests/specs/editor/various/autosave.test.js similarity index 100% rename from packages/e2e-tests/specs/autosave.test.js rename to packages/e2e-tests/specs/editor/various/autosave.test.js diff --git a/packages/e2e-tests/specs/block-deletion.test.js b/packages/e2e-tests/specs/editor/various/block-deletion.test.js similarity index 100% rename from packages/e2e-tests/specs/block-deletion.test.js rename to packages/e2e-tests/specs/editor/various/block-deletion.test.js diff --git a/packages/e2e-tests/specs/block-grouping.test.js b/packages/e2e-tests/specs/editor/various/block-grouping.test.js similarity index 100% rename from packages/e2e-tests/specs/block-grouping.test.js rename to packages/e2e-tests/specs/editor/various/block-grouping.test.js diff --git a/packages/e2e-tests/specs/block-hierarchy-navigation.test.js b/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js similarity index 100% rename from packages/e2e-tests/specs/block-hierarchy-navigation.test.js rename to packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js diff --git a/packages/e2e-tests/specs/block-mover.test.js b/packages/e2e-tests/specs/editor/various/block-mover.test.js similarity index 100% rename from packages/e2e-tests/specs/block-mover.test.js rename to packages/e2e-tests/specs/editor/various/block-mover.test.js diff --git a/packages/e2e-tests/specs/block-switcher.test.js b/packages/e2e-tests/specs/editor/various/block-switcher.test.js similarity index 100% rename from packages/e2e-tests/specs/block-switcher.test.js rename to packages/e2e-tests/specs/editor/various/block-switcher.test.js diff --git a/packages/e2e-tests/specs/change-detection.test.js b/packages/e2e-tests/specs/editor/various/change-detection.test.js similarity index 100% rename from packages/e2e-tests/specs/change-detection.test.js rename to packages/e2e-tests/specs/editor/various/change-detection.test.js diff --git a/packages/e2e-tests/specs/compatibility-classic-editor.test.js b/packages/e2e-tests/specs/editor/various/compatibility-classic-editor.test.js similarity index 100% rename from packages/e2e-tests/specs/compatibility-classic-editor.test.js rename to packages/e2e-tests/specs/editor/various/compatibility-classic-editor.test.js diff --git a/packages/e2e-tests/specs/convert-block-type.test.js b/packages/e2e-tests/specs/editor/various/convert-block-type.test.js similarity index 100% rename from packages/e2e-tests/specs/convert-block-type.test.js rename to packages/e2e-tests/specs/editor/various/convert-block-type.test.js diff --git a/packages/e2e-tests/specs/datepicker.test.js b/packages/e2e-tests/specs/editor/various/datepicker.test.js similarity index 100% rename from packages/e2e-tests/specs/datepicker.test.js rename to packages/e2e-tests/specs/editor/various/datepicker.test.js diff --git a/packages/e2e-tests/specs/editor-modes.test.js b/packages/e2e-tests/specs/editor/various/editor-modes.test.js similarity index 100% rename from packages/e2e-tests/specs/editor-modes.test.js rename to packages/e2e-tests/specs/editor/various/editor-modes.test.js diff --git a/packages/e2e-tests/specs/embedding.test.js b/packages/e2e-tests/specs/editor/various/embedding.test.js similarity index 100% rename from packages/e2e-tests/specs/embedding.test.js rename to packages/e2e-tests/specs/editor/various/embedding.test.js diff --git a/packages/e2e-tests/specs/font-size-picker.test.js b/packages/e2e-tests/specs/editor/various/font-size-picker.test.js similarity index 100% rename from packages/e2e-tests/specs/font-size-picker.test.js rename to packages/e2e-tests/specs/editor/various/font-size-picker.test.js diff --git a/packages/e2e-tests/specs/fullscreen-mode.test.js b/packages/e2e-tests/specs/editor/various/fullscreen-mode.test.js similarity index 100% rename from packages/e2e-tests/specs/fullscreen-mode.test.js rename to packages/e2e-tests/specs/editor/various/fullscreen-mode.test.js diff --git a/packages/e2e-tests/specs/invalid-block.test.js b/packages/e2e-tests/specs/editor/various/invalid-block.test.js similarity index 100% rename from packages/e2e-tests/specs/invalid-block.test.js rename to packages/e2e-tests/specs/editor/various/invalid-block.test.js diff --git a/packages/e2e-tests/specs/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/keyboard-navigable-blocks.test.js rename to packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js diff --git a/packages/e2e-tests/specs/links.test.js b/packages/e2e-tests/specs/editor/various/links.test.js similarity index 100% rename from packages/e2e-tests/specs/links.test.js rename to packages/e2e-tests/specs/editor/various/links.test.js diff --git a/packages/e2e-tests/specs/manage-reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js similarity index 93% rename from packages/e2e-tests/specs/manage-reusable-blocks.test.js rename to packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js index 37340d669f5a74..9d17922f519f39 100644 --- a/packages/e2e-tests/specs/manage-reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js @@ -32,7 +32,7 @@ describe( 'Managing reusable blocks', () => { await importButton.click(); // Select the file to upload - const testReusableBlockFile = path.join( __dirname, '..', 'assets', 'greeting-reusable-block.json' ); + const testReusableBlockFile = path.join( __dirname, '..', '..', '..', 'assets', 'greeting-reusable-block.json' ); const input = await page.$( '.list-reusable-blocks-import-form input' ); await input.uploadFile( testReusableBlockFile ); diff --git a/packages/e2e-tests/specs/mentions.test.js b/packages/e2e-tests/specs/editor/various/mentions.test.js similarity index 100% rename from packages/e2e-tests/specs/mentions.test.js rename to packages/e2e-tests/specs/editor/various/mentions.test.js diff --git a/packages/e2e-tests/specs/multi-block-selection.test.js b/packages/e2e-tests/specs/editor/various/multi-block-selection.test.js similarity index 100% rename from packages/e2e-tests/specs/multi-block-selection.test.js rename to packages/e2e-tests/specs/editor/various/multi-block-selection.test.js diff --git a/packages/e2e-tests/specs/navigable-toolbar.test.js b/packages/e2e-tests/specs/editor/various/navigable-toolbar.test.js similarity index 100% rename from packages/e2e-tests/specs/navigable-toolbar.test.js rename to packages/e2e-tests/specs/editor/various/navigable-toolbar.test.js diff --git a/packages/e2e-tests/specs/new-post-default-content.test.js b/packages/e2e-tests/specs/editor/various/new-post-default-content.test.js similarity index 100% rename from packages/e2e-tests/specs/new-post-default-content.test.js rename to packages/e2e-tests/specs/editor/various/new-post-default-content.test.js diff --git a/packages/e2e-tests/specs/new-post.test.js b/packages/e2e-tests/specs/editor/various/new-post.test.js similarity index 100% rename from packages/e2e-tests/specs/new-post.test.js rename to packages/e2e-tests/specs/editor/various/new-post.test.js diff --git a/packages/e2e-tests/specs/nux.test.js b/packages/e2e-tests/specs/editor/various/nux.test.js similarity index 100% rename from packages/e2e-tests/specs/nux.test.js rename to packages/e2e-tests/specs/editor/various/nux.test.js diff --git a/packages/e2e-tests/specs/popovers.test.js b/packages/e2e-tests/specs/editor/various/popovers.test.js similarity index 100% rename from packages/e2e-tests/specs/popovers.test.js rename to packages/e2e-tests/specs/editor/various/popovers.test.js diff --git a/packages/e2e-tests/specs/post-visibility.test.js b/packages/e2e-tests/specs/editor/various/post-visibility.test.js similarity index 100% rename from packages/e2e-tests/specs/post-visibility.test.js rename to packages/e2e-tests/specs/editor/various/post-visibility.test.js diff --git a/packages/e2e-tests/specs/preferences.test.js b/packages/e2e-tests/specs/editor/various/preferences.test.js similarity index 100% rename from packages/e2e-tests/specs/preferences.test.js rename to packages/e2e-tests/specs/editor/various/preferences.test.js diff --git a/packages/e2e-tests/specs/preview.test.js b/packages/e2e-tests/specs/editor/various/preview.test.js similarity index 100% rename from packages/e2e-tests/specs/preview.test.js rename to packages/e2e-tests/specs/editor/various/preview.test.js diff --git a/packages/e2e-tests/specs/publish-button.test.js b/packages/e2e-tests/specs/editor/various/publish-button.test.js similarity index 100% rename from packages/e2e-tests/specs/publish-button.test.js rename to packages/e2e-tests/specs/editor/various/publish-button.test.js diff --git a/packages/e2e-tests/specs/publish-panel.test.js b/packages/e2e-tests/specs/editor/various/publish-panel.test.js similarity index 100% rename from packages/e2e-tests/specs/publish-panel.test.js rename to packages/e2e-tests/specs/editor/various/publish-panel.test.js diff --git a/packages/e2e-tests/specs/publishing.test.js b/packages/e2e-tests/specs/editor/various/publishing.test.js similarity index 100% rename from packages/e2e-tests/specs/publishing.test.js rename to packages/e2e-tests/specs/editor/various/publishing.test.js diff --git a/packages/e2e-tests/specs/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js similarity index 100% rename from packages/e2e-tests/specs/reusable-blocks.test.js rename to packages/e2e-tests/specs/editor/various/reusable-blocks.test.js diff --git a/packages/e2e-tests/specs/rich-text.test.js b/packages/e2e-tests/specs/editor/various/rich-text.test.js similarity index 100% rename from packages/e2e-tests/specs/rich-text.test.js rename to packages/e2e-tests/specs/editor/various/rich-text.test.js diff --git a/packages/e2e-tests/specs/rtl.test.js b/packages/e2e-tests/specs/editor/various/rtl.test.js similarity index 100% rename from packages/e2e-tests/specs/rtl.test.js rename to packages/e2e-tests/specs/editor/various/rtl.test.js diff --git a/packages/e2e-tests/specs/scheduling.test.js b/packages/e2e-tests/specs/editor/various/scheduling.test.js similarity index 100% rename from packages/e2e-tests/specs/scheduling.test.js rename to packages/e2e-tests/specs/editor/various/scheduling.test.js diff --git a/packages/e2e-tests/specs/shortcut-help.test.js b/packages/e2e-tests/specs/editor/various/shortcut-help.test.js similarity index 100% rename from packages/e2e-tests/specs/shortcut-help.test.js rename to packages/e2e-tests/specs/editor/various/shortcut-help.test.js diff --git a/packages/e2e-tests/specs/sidebar-permalink-panel.test.js b/packages/e2e-tests/specs/editor/various/sidebar-permalink-panel.test.js similarity index 100% rename from packages/e2e-tests/specs/sidebar-permalink-panel.test.js rename to packages/e2e-tests/specs/editor/various/sidebar-permalink-panel.test.js diff --git a/packages/e2e-tests/specs/sidebar.test.js b/packages/e2e-tests/specs/editor/various/sidebar.test.js similarity index 100% rename from packages/e2e-tests/specs/sidebar.test.js rename to packages/e2e-tests/specs/editor/various/sidebar.test.js diff --git a/packages/e2e-tests/specs/splitting-merging.test.js b/packages/e2e-tests/specs/editor/various/splitting-merging.test.js similarity index 100% rename from packages/e2e-tests/specs/splitting-merging.test.js rename to packages/e2e-tests/specs/editor/various/splitting-merging.test.js diff --git a/packages/e2e-tests/specs/style-variation.test.js b/packages/e2e-tests/specs/editor/various/style-variation.test.js similarity index 100% rename from packages/e2e-tests/specs/style-variation.test.js rename to packages/e2e-tests/specs/editor/various/style-variation.test.js diff --git a/packages/e2e-tests/specs/taxonomies.test.js b/packages/e2e-tests/specs/editor/various/taxonomies.test.js similarity index 100% rename from packages/e2e-tests/specs/taxonomies.test.js rename to packages/e2e-tests/specs/editor/various/taxonomies.test.js diff --git a/packages/e2e-tests/specs/typewriter.test.js b/packages/e2e-tests/specs/editor/various/typewriter.test.js similarity index 100% rename from packages/e2e-tests/specs/typewriter.test.js rename to packages/e2e-tests/specs/editor/various/typewriter.test.js diff --git a/packages/e2e-tests/specs/undo.test.js b/packages/e2e-tests/specs/editor/various/undo.test.js similarity index 100% rename from packages/e2e-tests/specs/undo.test.js rename to packages/e2e-tests/specs/editor/various/undo.test.js diff --git a/packages/e2e-tests/specs/writing-flow.test.js b/packages/e2e-tests/specs/editor/various/writing-flow.test.js similarity index 100% rename from packages/e2e-tests/specs/writing-flow.test.js rename to packages/e2e-tests/specs/editor/various/writing-flow.test.js diff --git a/packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap b/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/__snapshots__/block-transforms.test.js.snap rename to packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap diff --git a/packages/e2e-tests/specs/block-transforms.test.js b/packages/e2e-tests/specs/experimental/block-transforms.test.js similarity index 97% rename from packages/e2e-tests/specs/block-transforms.test.js rename to packages/e2e-tests/specs/experimental/block-transforms.test.js index 381facd4c00673..16cc6890581dd6 100644 --- a/packages/e2e-tests/specs/block-transforms.test.js +++ b/packages/e2e-tests/specs/experimental/block-transforms.test.js @@ -32,8 +32,8 @@ import { getAvailableBlockFixturesBasenames, getBlockFixtureHTML, getBlockFixtureParsedJSON, -} from '../fixtures/'; -import { EXPECTED_TRANSFORMS } from '../fixtures/block-transforms.js'; +} from '../../fixtures/'; +import { EXPECTED_TRANSFORMS } from '../../fixtures/block-transforms.js'; /* * Returns true if the fileBase refers to a fixture of a block diff --git a/packages/e2e-tests/specs/demo.test.js b/packages/e2e-tests/specs/local/demo.test.js similarity index 100% rename from packages/e2e-tests/specs/demo.test.js rename to packages/e2e-tests/specs/local/demo.test.js diff --git a/packages/e2e-tests/specs/.gitignore b/packages/e2e-tests/specs/performance/.gitignore similarity index 100% rename from packages/e2e-tests/specs/.gitignore rename to packages/e2e-tests/specs/performance/.gitignore diff --git a/packages/e2e-tests/specs/performance.test.js b/packages/e2e-tests/specs/performance/performance.test.js similarity index 100% rename from packages/e2e-tests/specs/performance.test.js rename to packages/e2e-tests/specs/performance/performance.test.js From 6d28e63d0d53e34f100cf087448c7accce86e425 Mon Sep 17 00:00:00 2001 From: Enrique Piqueras <epiqueras@users.noreply.github.com> Date: Thu, 17 Oct 2019 07:53:52 -0700 Subject: [PATCH 032/113] Playground: Add link to components storybook. (#17982) --- playground/src/index.js | 9 +++++---- playground/src/style.scss | 5 ++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/playground/src/index.js b/playground/src/index.js index b74e30091c1739..ea5b149fedde1c 100644 --- a/playground/src/index.js +++ b/playground/src/index.js @@ -12,6 +12,7 @@ import { ObserveTyping, } from '@wordpress/block-editor'; import { + Button, Popover, SlotFillProvider, DropZoneProvider, @@ -40,6 +41,9 @@ function App() { <Fragment> <div className="playground__header"> <h1 className="playground__logo">Gutenberg Playground</h1> + <Button isLarge href="design-system/components" target="_blank"> + Design System Components + </Button> </div> <div className="playground__body"> <SlotFillProvider> @@ -67,7 +71,4 @@ function App() { } registerCoreBlocks(); -render( - <App />, - document.querySelector( '#app' ) -); +render( <App />, document.querySelector( '#app' ) ); diff --git a/playground/src/style.scss b/playground/src/style.scss index 63a330e00a2d6f..43d7a0460ab0e7 100644 --- a/playground/src/style.scss +++ b/playground/src/style.scss @@ -10,8 +10,11 @@ .playground__header { - padding: 20px; + align-items: center; border-bottom: 1px solid #ddd; + display: flex; + justify-content: space-between; + padding: 20px; } .playground__logo { From 208cc9f0d3626c81bc9f7cda61c86c2c0c1bd7ce Mon Sep 17 00:00:00 2001 From: Luke Walczak <lukasz.walczak.pwr@gmail.com> Date: Thu, 17 Oct 2019 17:17:33 +0200 Subject: [PATCH 033/113] Fix image native test (#17989) --- packages/block-library/src/image/test/edit.native.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/image/test/edit.native.js b/packages/block-library/src/image/test/edit.native.js index d585f1f1396a9e..9c21c10d90dbaf 100644 --- a/packages/block-library/src/image/test/edit.native.js +++ b/packages/block-library/src/image/test/edit.native.js @@ -40,16 +40,16 @@ describe( 'Image Block', () => { instance.onSetNewTab( true ); - expect( setAttributes ).toBeCalledWith( { linkTarget: '_blank', rel: NEW_TAB_REL } ); + expect( setAttributes ).toHaveBeenCalledWith( { linkTarget: '_blank', rel: undefined } ); } ); it( 'unset link target', () => { - const component = renderer.create( getImageComponent( { linkTarget: '_blank', rel: NEW_TAB_REL } ) ); + const component = renderer.create( getImageComponent( { linkTarget: '_blank', rel: NEW_TAB_REL.join( ' ' ) } ) ); const instance = component.getInstance(); instance.onSetNewTab( false ); - expect( setAttributes ).toBeCalledWith( { linkTarget: undefined, rel: undefined } ); + expect( setAttributes ).toHaveBeenCalledWith( { linkTarget: undefined, rel: undefined } ); } ); } ); From 7017152306f71486d0d65362f545252f560cb55f Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Fri, 18 Oct 2019 09:59:46 +0100 Subject: [PATCH 034/113] Update: Refactor button edit to use a functional component (#18006) --- packages/block-library/src/button/edit.js | 315 ++++++++++------------ 1 file changed, 149 insertions(+), 166 deletions(-) diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index 17908484218091..33ebe079c5e892 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -8,7 +8,6 @@ import classnames from 'classnames'; */ import { __ } from '@wordpress/i18n'; import { - Component, useCallback, } from '@wordpress/element'; import { @@ -74,177 +73,161 @@ function BorderPanel( { borderRadius = '', setAttributes } ) { ); } -class ButtonEdit extends Component { - constructor() { - super( ...arguments ); - this.nodeRef = null; - this.bindRef = this.bindRef.bind( this ); - this.onSetLinkRel = this.onSetLinkRel.bind( this ); - this.onToggleOpenInNewTab = this.onToggleOpenInNewTab.bind( this ); - } - - bindRef( node ) { - if ( ! node ) { - return; - } - this.nodeRef = node; - } - - onSetLinkRel( value ) { - this.props.setAttributes( { rel: value } ); - } - - onToggleOpenInNewTab( value ) { - const { rel } = this.props.attributes; - const linkTarget = value ? '_blank' : undefined; - - let updatedRel = rel; - if ( linkTarget && ! rel ) { - updatedRel = NEW_TAB_REL; - } else if ( ! linkTarget && rel === NEW_TAB_REL ) { - updatedRel = undefined; - } - - this.props.setAttributes( { - linkTarget, - rel: updatedRel, - } ); - } - - render() { - const { - attributes, - backgroundColor, - textColor, - setBackgroundColor, - setTextColor, - fallbackBackgroundColor, - fallbackTextColor, - setAttributes, - className, - instanceId, - isSelected, - } = this.props; - - const { - borderRadius, - linkTarget, - placeholder, - rel, - text, - title, - url, - customGradient, - } = attributes; +function ButtonEdit( { + attributes, + backgroundColor, + textColor, + setBackgroundColor, + setTextColor, + fallbackBackgroundColor, + fallbackTextColor, + setAttributes, + className, + instanceId, + isSelected, +} ) { + const { + borderRadius, + linkTarget, + placeholder, + rel, + text, + title, + url, + customGradient, + } = attributes; + const onSetLinkRel = useCallback( + ( value ) => { + setAttributes( { rel: value } ); + }, + [ setAttributes ] + ); - const linkId = `wp-block-button__inline-link-${ instanceId }`; + const onToggleOpenInNewTab = useCallback( + ( value ) => { + const newLinkTarget = value ? '_blank' : undefined; + + let updatedRel = rel; + if ( newLinkTarget && ! rel ) { + updatedRel = NEW_TAB_REL; + } else if ( ! newLinkTarget && rel === NEW_TAB_REL ) { + updatedRel = undefined; + } + + setAttributes( { + linkTarget: newLinkTarget, + rel: updatedRel, + } ); + }, + [ rel, setAttributes ] + ); - return ( - <div className={ className } title={ title } ref={ this.bindRef }> - <RichText - placeholder={ placeholder || __( 'Add text…' ) } - value={ text } - onChange={ ( value ) => setAttributes( { text: value } ) } - withoutInteractiveFormatting - className={ classnames( - 'wp-block-button__link', { - 'has-background': backgroundColor.color || customGradient, - [ backgroundColor.class ]: ! customGradient && backgroundColor.class, - 'has-text-color': textColor.color, - [ textColor.class ]: textColor.class, - 'no-border-radius': borderRadius === 0, - } - ) } - style={ { - backgroundColor: ! customGradient && backgroundColor.color, - background: customGradient, - color: textColor.color, - borderRadius: borderRadius ? borderRadius + 'px' : undefined, - } } + const linkId = `wp-block-button__inline-link-${ instanceId }`; + return ( + <div className={ className } title={ title }> + <RichText + placeholder={ placeholder || __( 'Add text…' ) } + value={ text } + onChange={ ( value ) => setAttributes( { text: value } ) } + withoutInteractiveFormatting + className={ classnames( + 'wp-block-button__link', { + 'has-background': backgroundColor.color || customGradient, + [ backgroundColor.class ]: ! customGradient && backgroundColor.class, + 'has-text-color': textColor.color, + [ textColor.class ]: textColor.class, + 'no-border-radius': borderRadius === 0, + } + ) } + style={ { + backgroundColor: ! customGradient && backgroundColor.color, + background: customGradient, + color: textColor.color, + borderRadius: borderRadius ? borderRadius + 'px' : undefined, + } } + /> + <BaseControl + label={ __( 'Link' ) } + className="wp-block-button__inline-link" + id={ linkId }> + <URLInput + className="wp-block-button__inline-link-input" + value={ url } + /* eslint-disable jsx-a11y/no-autofocus */ + // Disable Reason: The rule is meant to prevent enabling auto-focus, not disabling it. + autoFocus={ false } + /* eslint-enable jsx-a11y/no-autofocus */ + onChange={ ( value ) => setAttributes( { url: value } ) } + disableSuggestions={ ! isSelected } + id={ linkId } + isFullWidth + hasBorder /> - <BaseControl - label={ __( 'Link' ) } - className="wp-block-button__inline-link" - id={ linkId }> - <URLInput - className="wp-block-button__inline-link-input" - value={ url } - /* eslint-disable jsx-a11y/no-autofocus */ - // Disable Reason: The rule is meant to prevent enabling auto-focus, not disabling it. - autoFocus={ false } - /* eslint-enable jsx-a11y/no-autofocus */ - onChange={ ( value ) => setAttributes( { url: value } ) } - disableSuggestions={ ! isSelected } - id={ linkId } - isFullWidth - hasBorder - /> - </BaseControl> - <InspectorControls> - <PanelColorSettings - title={ __( 'Color Settings' ) } - colorSettings={ [ - { - value: backgroundColor.color, - onChange: ( newColor ) => { - setAttributes( { customGradient: undefined } ); - setBackgroundColor( newColor ); - }, - label: __( 'Background Color' ), - }, - { - value: textColor.color, - onChange: setTextColor, - label: __( 'Text Color' ), + </BaseControl> + <InspectorControls> + <PanelColorSettings + title={ __( 'Color Settings' ) } + colorSettings={ [ + { + value: backgroundColor.color, + onChange: ( newColor ) => { + setAttributes( { customGradient: undefined } ); + setBackgroundColor( newColor ); }, - ] } - > - <ContrastChecker - { ...{ - // Text is considered large if font size is greater or equal to 18pt or 24px, - // currently that's not the case for button. - isLargeText: false, - textColor: textColor.color, - backgroundColor: backgroundColor.color, - fallbackBackgroundColor, - fallbackTextColor, - } } - /> - </PanelColorSettings> - <PanelBody title={ __( 'Gradient' ) }> - <__experimentalGradientPickerControl - onChange={ - ( newGradient ) => { - setAttributes( { - customGradient: newGradient, - backgroundColor: undefined, - customBackgroundColor: undefined, - } ); - } + label: __( 'Background Color' ), + }, + { + value: textColor.color, + onChange: setTextColor, + label: __( 'Text Color' ), + }, + ] } + > + <ContrastChecker + { ...{ + // Text is considered large if font size is greater or equal to 18pt or 24px, + // currently that's not the case for button. + isLargeText: false, + textColor: textColor.color, + backgroundColor: backgroundColor.color, + fallbackBackgroundColor, + fallbackTextColor, + } } + /> + </PanelColorSettings> + <PanelBody title={ __( 'Gradient' ) }> + <__experimentalGradientPickerControl + onChange={ + ( newGradient ) => { + setAttributes( { + customGradient: newGradient, + backgroundColor: undefined, + customBackgroundColor: undefined, + } ); } - value={ customGradient } - /> - </PanelBody> - <BorderPanel - borderRadius={ borderRadius } - setAttributes={ setAttributes } + } + value={ customGradient } + /> + </PanelBody> + <BorderPanel + borderRadius={ borderRadius } + setAttributes={ setAttributes } + /> + <PanelBody title={ __( 'Link settings' ) }> + <ToggleControl + label={ __( 'Open in new tab' ) } + onChange={ onToggleOpenInNewTab } + checked={ linkTarget === '_blank' } /> - <PanelBody title={ __( 'Link settings' ) }> - <ToggleControl - label={ __( 'Open in new tab' ) } - onChange={ this.onToggleOpenInNewTab } - checked={ linkTarget === '_blank' } - /> - <TextControl - label={ __( 'Link rel' ) } - value={ rel || '' } - onChange={ this.onSetLinkRel } - /> - </PanelBody> - </InspectorControls> - </div> - ); - } + <TextControl + label={ __( 'Link rel' ) } + value={ rel || '' } + onChange={ onSetLinkRel } + /> + </PanelBody> + </InspectorControls> + </div> + ); } export default compose( [ From 30d3e982d619ad6b185871f305b66c89766e5686 Mon Sep 17 00:00:00 2001 From: Jarda Snajdr <jsnajdr@gmail.com> Date: Fri, 18 Oct 2019 12:29:40 +0200 Subject: [PATCH 035/113] Optimize exports of the wp/compose package (#17945) Adds `sideEffects:false` to `package.json` so that unused exports can be optimized away by the bundler. Moves the `compose` definition (i.e., reexport from Lodash) to its own module, so that we don't pull in Lodash just by importing something from `@wordpress/compose`. After this patch, one needs to import `compose` explicitly to trigger the Lodash import. --- packages/compose/package.json | 1 + packages/compose/src/higher-order/compose.js | 14 ++++++++++++++ packages/compose/src/index.js | 16 ++-------------- 3 files changed, 17 insertions(+), 14 deletions(-) create mode 100644 packages/compose/src/higher-order/compose.js diff --git a/packages/compose/package.json b/packages/compose/package.json index 045f193d1e5311..5ad5ed9d1bc786 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -21,6 +21,7 @@ "main": "build/index.js", "module": "build-module/index.js", "react-native": "src/index", + "sideEffects": false, "dependencies": { "@babel/runtime": "^7.4.4", "@wordpress/element": "file:../element", diff --git a/packages/compose/src/higher-order/compose.js b/packages/compose/src/higher-order/compose.js new file mode 100644 index 00000000000000..a166387821e7b3 --- /dev/null +++ b/packages/compose/src/higher-order/compose.js @@ -0,0 +1,14 @@ +/** + * External dependencies + */ +import { flowRight as compose } from 'lodash'; + +/** + * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function + * composition, where each successive invocation is supplied the return value of the previous. + * + * @param {...Function} hocs The HOC functions to invoke. + * + * @return {Function} Returns the new composite function. + */ +export default compose; diff --git a/packages/compose/src/index.js b/packages/compose/src/index.js index 9ea31b2d351aba..ab1ecf3564edbe 100644 --- a/packages/compose/src/index.js +++ b/packages/compose/src/index.js @@ -1,20 +1,8 @@ -/** - * External dependencies - */ -import { flowRight } from 'lodash'; - // Utils export { default as createHigherOrderComponent } from './utils/create-higher-order-component'; -/** - * Composes multiple higher-order components into a single higher-order component. Performs right-to-left function - * composition, where each successive invocation is supplied the return value of the previous. - * - * @param {...Function} hocs The HOC functions to invoke. - * - * @return {Function} Returns the new composite function. - */ -export { flowRight as compose }; +// Compose helper (aliased flowRight from Lodash) +export { default as compose } from './higher-order/compose'; // Higher-order components export { default as ifCondition } from './higher-order/if-condition'; From fba1f85b18fe15452763229f1c8435b371c21ae9 Mon Sep 17 00:00:00 2001 From: Luke Walczak <lukasz.walczak.pwr@gmail.com> Date: Fri, 18 Oct 2019 13:04:21 +0200 Subject: [PATCH 036/113] [RNMobile] Introduce grouping in the block settings inspector (#17703) * Intrdouce groupin in the block settings inspector * Adjust PanelBody to design * Adjust padding when section doesnt have title * Rewirte arrow function to function * Fix lint issue * Create a PanelActions component for handling action buttons in the block settings inspector * Remove useless separator type and fix typo * Refactor after CR * Correct label styles * Fix overriding mechanism on label style --- .../block-settings/container.native.js | 6 ++++ .../block-settings/container.native.scss | 4 +++ .../block-library/src/image/edit.native.js | 12 +++---- .../src/image/styles.native.scss | 4 --- packages/components/src/index.native.js | 1 + .../src/mobile/bottom-sheet/cell.native.js | 9 +++-- .../components/src/panel/actions.native.js | 36 +++++++++++++++++++ .../components/src/panel/actions.native.scss | 7 ++++ packages/components/src/panel/body.native.js | 12 +++++-- .../components/src/panel/body.native.scss | 11 ++++++ 10 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 packages/block-editor/src/components/block-settings/container.native.scss create mode 100644 packages/components/src/panel/actions.native.js create mode 100644 packages/components/src/panel/actions.native.scss create mode 100644 packages/components/src/panel/body.native.scss diff --git a/packages/block-editor/src/components/block-settings/container.native.js b/packages/block-editor/src/components/block-settings/container.native.js index c51a42b39de6d0..1b59377f29161c 100644 --- a/packages/block-editor/src/components/block-settings/container.native.js +++ b/packages/block-editor/src/components/block-settings/container.native.js @@ -6,12 +6,18 @@ import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { InspectorControls } from '@wordpress/block-editor'; +/** + * Internal dependencies + */ +import styles from './container.native.scss'; + function BottomSheetSettings( { editorSidebarOpened, closeGeneralSidebar, ...props } ) { return ( <BottomSheet isVisible={ editorSidebarOpened } onClose={ closeGeneralSidebar } hideHeader + contentStyle={ styles.content } { ...props } > <InspectorControls.Slot /> diff --git a/packages/block-editor/src/components/block-settings/container.native.scss b/packages/block-editor/src/components/block-settings/container.native.scss new file mode 100644 index 00000000000000..2eed1c9e3f2d00 --- /dev/null +++ b/packages/block-editor/src/components/block-settings/container.native.scss @@ -0,0 +1,4 @@ +.content { + padding-left: 0; + padding-right: 0; +} diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 3e08ed18a2361d..be86e880ff2a77 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -22,6 +22,7 @@ import { Toolbar, ToolbarButton, PanelBody, + PanelActions, } from '@wordpress/components'; import { @@ -240,6 +241,8 @@ export class ImageEdit extends React.Component { const { attributes, isSelected } = this.props; const { url, height, width, alt, href, id, linkTarget, sizeSlug } = attributes; + const actions = [ { label: __( 'Clear All Settings' ), onPress: this.onClearSettings } ]; + const getToolbarEditButton = ( open ) => ( <BlockControls> <Toolbar> @@ -286,16 +289,11 @@ export class ImageEdit extends React.Component { label={ __( 'Alt Text' ) } value={ alt || '' } valuePlaceholder={ __( 'None' ) } - separatorType={ 'fullWidth' } - onChange={ this.updateAlt } - /> - <TextControl - label={ __( 'Clear All Settings' ) } - labelStyle={ styles.clearSettingsButton } separatorType={ 'none' } - onPress={ this.onClearSettings } + onChangeValue={ this.updateAlt } /> </PanelBody> + <PanelActions actions={ actions } /> </InspectorControls> ); diff --git a/packages/block-library/src/image/styles.native.scss b/packages/block-library/src/image/styles.native.scss index 9c5a9cbf5c45e5..731e7e9e26312c 100644 --- a/packages/block-library/src/image/styles.native.scss +++ b/packages/block-library/src/image/styles.native.scss @@ -18,10 +18,6 @@ align-items: center; } -.clearSettingsButton { - color: $alert-red; -} - .modalIcon { width: 80px; height: 80px; diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index c2c52ba08f0e58..3fada7034deeb2 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -11,6 +11,7 @@ export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot export { default as BaseControl } from './base-control'; export { default as TextareaControl } from './textarea-control'; export { default as PanelBody } from './panel/body'; +export { default as PanelActions } from './panel/actions'; export { default as Button } from './button'; export { default as TextControl } from './text-control'; export { default as ToggleControl } from './toggle-control'; diff --git a/packages/components/src/mobile/bottom-sheet/cell.native.js b/packages/components/src/mobile/bottom-sheet/cell.native.js index 5c97e762f3d480..52ff00b6b5b856 100644 --- a/packages/components/src/mobile/bottom-sheet/cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/cell.native.js @@ -63,6 +63,7 @@ class BottomSheetCell extends Component { const defaultLabelStyle = showValue || icon !== undefined ? cellLabelStyle : defaultMissingIconAndValue; const drawSeparator = ( separatorType && separatorType !== 'none' ) || separatorStyle === undefined; + const drawTopSeparator = drawSeparator && separatorType === 'topFullWidth'; const onCellPress = () => { if ( isValueEditable ) { @@ -91,6 +92,7 @@ class BottomSheetCell extends Component { case 'leftMargin': return leftMarginStyle; case 'fullWidth': + case 'topFullWidth': return defaultSeparatorStyle; case 'none': return undefined; @@ -169,6 +171,9 @@ class BottomSheetCell extends Component { onPress={ onCellPress } style={ { ...styles.clipToBounds, ...style } } > + { drawTopSeparator && ( + <View style={ separatorStyle() } /> + ) } <View style={ styles.cellContainer }> <View style={ styles.cellRowContainer }> { icon && ( @@ -177,14 +182,14 @@ class BottomSheetCell extends Component { <View style={ platformStyles.labelIconSeparator } /> </View> ) } - <Text numberOfLines={ 1 } style={ { ...defaultLabelStyle, ...labelStyle } }> + <Text numberOfLines={ 1 } style={ [ defaultLabelStyle, labelStyle ] }> { label } </Text> </View> { showValue && getValueComponent() } { children } </View> - { drawSeparator && ( + { ! drawTopSeparator && ( <View style={ separatorStyle() } /> ) } </TouchableOpacity> diff --git a/packages/components/src/panel/actions.native.js b/packages/components/src/panel/actions.native.js new file mode 100644 index 00000000000000..02031bf53cb857 --- /dev/null +++ b/packages/components/src/panel/actions.native.js @@ -0,0 +1,36 @@ +/** + * External dependencies + */ +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { + TextControl, +} from '@wordpress/components'; + +/** + * Internal dependencies + */ +import styles from './actions.scss'; + +function PanelActions( { actions } ) { + return ( + <View style={ styles.panelActionsContainer }> + { actions.map( ( { label, onPress } ) => { + return ( + <TextControl + label={ label } + separatorType="topFullWidth" + onPress={ onPress } + labelStyle={ styles.defaultLabelStyle } + key={ label } + /> + ); + } ) } + </View> + ); +} + +export default PanelActions; diff --git a/packages/components/src/panel/actions.native.scss b/packages/components/src/panel/actions.native.scss new file mode 100644 index 00000000000000..ed226c13883be9 --- /dev/null +++ b/packages/components/src/panel/actions.native.scss @@ -0,0 +1,7 @@ +.panelActionsContainer { + padding-top: 24; +} + +.defaultLabelStyle { + color: $alert-red; +} diff --git a/packages/components/src/panel/body.native.js b/packages/components/src/panel/body.native.js index aeeccc77a06c19..314650f945278e 100644 --- a/packages/components/src/panel/body.native.js +++ b/packages/components/src/panel/body.native.js @@ -1,12 +1,16 @@ /** * External dependencies */ -import { View } from 'react-native'; +import { Text, View } from 'react-native'; /** * WordPress dependencies */ import { Component } from '@wordpress/element'; +/** + * Internal dependencies + */ +import styles from './body.scss'; export class PanelBody extends Component { constructor( ) { @@ -15,9 +19,11 @@ export class PanelBody extends Component { } render() { - const { children } = this.props; + const { children, title } = this.props; + return ( - <View > + <View style={ styles.panelContainer }> + { title && <Text style={ styles.sectionHeaderText }>{ title }</Text> } { children } </View> ); diff --git a/packages/components/src/panel/body.native.scss b/packages/components/src/panel/body.native.scss new file mode 100644 index 00000000000000..a30c4df4c15dfc --- /dev/null +++ b/packages/components/src/panel/body.native.scss @@ -0,0 +1,11 @@ +.panelContainer { + padding: 0 16px; +} + +.sectionHeaderText { + color: #87a6bc; + padding-top: 24; + padding-bottom: 8; + font-size: 14; + font-weight: 500; +} From f772aede279b2eafb0793078b433304468d1989f Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Fri, 18 Oct 2019 14:41:57 +0100 Subject: [PATCH 037/113] Fix the performance tests (#18020) --- packages/e2e-tests/config/performance-reporter.js | 2 +- packages/e2e-tests/specs/performance/performance.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/config/performance-reporter.js b/packages/e2e-tests/config/performance-reporter.js index 681bb60f41618e..f7bb05666054d5 100644 --- a/packages/e2e-tests/config/performance-reporter.js +++ b/packages/e2e-tests/config/performance-reporter.js @@ -6,7 +6,7 @@ function average( array ) { class PerformanceReporter { onRunComplete() { - const path = __dirname + '/../specs/results.json'; + const path = __dirname + '/../specs/performance/results.json'; if ( ! existsSync( path ) ) { return; diff --git a/packages/e2e-tests/specs/performance/performance.test.js b/packages/e2e-tests/specs/performance/performance.test.js index 174bf2c6ab1301..6246dfb4dc0d38 100644 --- a/packages/e2e-tests/specs/performance/performance.test.js +++ b/packages/e2e-tests/specs/performance/performance.test.js @@ -20,7 +20,7 @@ function readFile( filePath ) { describe( 'Performance', () => { it( '1000 paragraphs', async () => { - const html = readFile( join( __dirname, '../assets/large-post.html' ) ); + const html = readFile( join( __dirname, '../../assets/large-post.html' ) ); await createNewPost(); await page.evaluate( ( _html ) => { From 181042ac4be04fd6775f95f85cd3e3a7c8aa2a91 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Fri, 18 Oct 2019 06:45:25 -0700 Subject: [PATCH 038/113] Storybook: Add knobs to ColorIndicator (#18015) * Add knobs to ColorIndicator * Lint: new line --- .../src/color-indicator/stories/index.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/components/src/color-indicator/stories/index.js b/packages/components/src/color-indicator/stories/index.js index 3e9400b0919c11..d14f180abbe25a 100644 --- a/packages/components/src/color-indicator/stories/index.js +++ b/packages/components/src/color-indicator/stories/index.js @@ -1,13 +1,21 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ import ColorIndicator from '../'; export default { - title: 'Color Indicator', + title: 'ColorIndicator', component: ColorIndicator, }; -export const _default = () => ( - <ColorIndicator colorValue="#0073aa" /> -); +export const _default = () => { + const color = text( 'Color', '#0073aa' ); + return ( + <ColorIndicator colorValue={ color } /> + ); +}; From fb283f092c43c093955cb65e25a26e405e1308e5 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Fri, 18 Oct 2019 13:14:43 -0700 Subject: [PATCH 039/113] Add dashicon component to storybook (#18027) --- .../components/src/dashicon/stories/index.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 packages/components/src/dashicon/stories/index.js diff --git a/packages/components/src/dashicon/stories/index.js b/packages/components/src/dashicon/stories/index.js new file mode 100644 index 00000000000000..5ba7d7be98cbcb --- /dev/null +++ b/packages/components/src/dashicon/stories/index.js @@ -0,0 +1,25 @@ +/** + * External dependencies + */ +import { number, text } from '@storybook/addon-knobs'; + +/** + * Internal dependencies + */ +import Dashicon from '../'; + +export default { title: 'Dashicon', component: Dashicon }; + +export const _default = () => { + const icon = text( 'Icon', 'wordpress' ); + const color = text( 'Color', '#0079AA' ); + const size = number( 'Size', 20 ); + + return ( + <Dashicon + icon={ icon } + color={ color } + size={ size } + /> + ); +}; From db2235d69be5401858794b9465d94a1906dbaae6 Mon Sep 17 00:00:00 2001 From: Joen Asmussen <joen@automattic.com> Date: Sat, 19 Oct 2019 10:56:02 +0200 Subject: [PATCH 040/113] Fix Publish Button!!! (#18016) Fixes #18004 and thank science, that was driving me insane ever since you pointed it out. This PR does a couple of things: 1. It adds `isLarge` to the Publish button. It was there for Preview, but not Publish. 2. It simplifies a little CSS as a result of that. 3. It also tweaks the button height as defined for the two preview publish buttons. --- packages/components/src/button/style.scss | 12 ++++++------ packages/edit-post/src/components/header/style.scss | 10 +++++++--- .../src/components/post-publish-button/index.js | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/components/src/button/style.scss b/packages/components/src/button/style.scss index 6d3f94a18a1c24..2f62f199794eda 100644 --- a/packages/components/src/button/style.scss +++ b/packages/components/src/button/style.scss @@ -37,7 +37,7 @@ background: #f3f5f6; color: color(theme(button) shade(25%)); border-color: color(theme(button) shade(5%)); - box-shadow: 0 0 0 1px color(theme(button) shade(5%)); + box-shadow: 0 0 0 $border-width color(theme(button) shade(5%)); text-decoration: none; } @@ -54,7 +54,7 @@ color: #a0a5aa; border-color: #ddd; background: #f7f7f7; - text-shadow: 0 1px 0 #fff; + text-shadow: 0 $border-width 0 #fff; transform: none; opacity: 1; } @@ -76,7 +76,7 @@ &:focus:enabled { box-shadow: - 0 0 0 1px $white, + 0 0 0 $border-width $white, 0 0 0 3px color(theme(button)); } @@ -107,7 +107,7 @@ &:focus:enabled { box-shadow: - 0 0 0 1px $white, + 0 0 0 $border-width $white, 0 0 0 3px color(theme(button)); } } @@ -157,8 +157,8 @@ &:focus { color: #124964; box-shadow: - 0 0 0 1px #5b9dd9, - 0 0 2px 1px rgba(30, 140, 190, 0.8); + 0 0 0 $border-width #5b9dd9, + 0 0 2px $border-width rgba(30, 140, 190, 0.8); } } diff --git a/packages/edit-post/src/components/header/style.scss b/packages/edit-post/src/components/header/style.scss index 64699eeab73a2d..65a94ba8ad72d0 100644 --- a/packages/edit-post/src/components/header/style.scss +++ b/packages/edit-post/src/components/header/style.scss @@ -91,7 +91,7 @@ &.editor-post-publish-button, &.editor-post-publish-panel__toggle { margin: 2px; - height: 33px; + height: 34px; line-height: 32px; font-size: $default-font-size; } @@ -105,13 +105,17 @@ } } + // These paddings actually duplicate existing rules from button component. + // But they are duplicated so as to provide smaller paddings to fit the buttons on mobile. &.editor-post-preview, &.editor-post-publish-button, &.editor-post-publish-panel__toggle { - padding: 0 5px 2px; + padding-left: 5px; + padding-right: 5px; @include break-small() { - padding: 0 12px 2px; + padding-left: 12px; + padding-right: 12px; } } diff --git a/packages/editor/src/components/post-publish-button/index.js b/packages/editor/src/components/post-publish-button/index.js index 1513dfbfbb414f..ac195d4de86ce6 100644 --- a/packages/editor/src/components/post-publish-button/index.js +++ b/packages/editor/src/components/post-publish-button/index.js @@ -113,6 +113,7 @@ export class PostPublishButton extends Component { return ( <div> <Button + isLarge ref={ this.buttonNode } { ...componentProps } > From bf3b7f9d0a6a4a8000ad1a64df7e2e38c19d587f Mon Sep 17 00:00:00 2001 From: Phoebe Gao <phgao1994@gmail.com> Date: Sat, 19 Oct 2019 05:25:19 -0700 Subject: [PATCH 041/113] Update MediaPlaceholder README.md (#17980) * Update MediaPlaceholder README.md This change updates the readme to properly document the `value` property. See issue here: https://github.com/WordPress/gutenberg/issues/17967 * Update MediaUpload README.md --- .../block-editor/src/components/media-placeholder/README.md | 4 ++-- packages/block-editor/src/components/media-upload/README.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/media-placeholder/README.md b/packages/block-editor/src/components/media-placeholder/README.md index b730b9af5cbc9c..58140cf99e7215 100644 --- a/packages/block-editor/src/components/media-placeholder/README.md +++ b/packages/block-editor/src/components/media-placeholder/README.md @@ -155,9 +155,9 @@ The argument of the callback is an object containing the following properties: ### value -Media ID (or media IDs if multiple is true) to be selected by default when opening the media library. +An object or an array of objects that contain media ID (`id` property) to be selected by default when opening the media library. -- Type: `Number|Array` +- Type: `Object|Array` - Required: No - Platform: Web diff --git a/packages/block-editor/src/components/media-upload/README.md b/packages/block-editor/src/components/media-upload/README.md index d445348fa0b15d..ea09687102ec07 100644 --- a/packages/block-editor/src/components/media-upload/README.md +++ b/packages/block-editor/src/components/media-upload/README.md @@ -38,7 +38,7 @@ function MyMediaUploader() { <MediaUpload onSelect={ ( media ) => console.log( 'selected ' + media.length ) } allowedTypes={ ALLOWED_MEDIA_TYPES } - value={ mediaId } + value={ media } render={ ( { open } ) => ( <Button onClick={ open }> Open Media Library @@ -76,9 +76,9 @@ Whether to allow multiple selections or not. ### value -Media ID (or media IDs if multiple is true) to be selected by default when opening the media library. +An object or an array of objects that contain media ID (`id` property) to be selected by default when opening the media library. -- Type: `Number|Array` +- Type: `Object|Array` - Required: No - Platform: Web From c671a3857f5094b446728a7b4996a78419687f55 Mon Sep 17 00:00:00 2001 From: Anthony Burchell <anthony.burchell@wpengine.com> Date: Sun, 20 Oct 2019 20:05:13 -0500 Subject: [PATCH 042/113] removes decleration of Select button (#18007) --- packages/media-utils/src/components/media-upload/index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/media-utils/src/components/media-upload/index.js b/packages/media-utils/src/components/media-upload/index.js index 0ba3db65fd43b1..eac379f9ebb68d 100644 --- a/packages/media-utils/src/components/media-upload/index.js +++ b/packages/media-utils/src/components/media-upload/index.js @@ -125,9 +125,6 @@ class MediaUpload extends Component { } else { const frameConfig = { title, - button: { - text: __( 'Select' ), - }, multiple, }; if ( !! allowedTypes ) { From 952659bd93683f7262a516a6f802bcea448b9ca1 Mon Sep 17 00:00:00 2001 From: Matthew Kevins <mkevins@users.noreply.github.com> Date: Mon, 21 Oct 2019 11:27:54 +1000 Subject: [PATCH 043/113] Fix MediaUpload README value prop description (#18039) --- packages/block-editor/src/components/media-upload/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/media-upload/README.md b/packages/block-editor/src/components/media-upload/README.md index ea09687102ec07..d445348fa0b15d 100644 --- a/packages/block-editor/src/components/media-upload/README.md +++ b/packages/block-editor/src/components/media-upload/README.md @@ -38,7 +38,7 @@ function MyMediaUploader() { <MediaUpload onSelect={ ( media ) => console.log( 'selected ' + media.length ) } allowedTypes={ ALLOWED_MEDIA_TYPES } - value={ media } + value={ mediaId } render={ ( { open } ) => ( <Button onClick={ open }> Open Media Library @@ -76,9 +76,9 @@ Whether to allow multiple selections or not. ### value -An object or an array of objects that contain media ID (`id` property) to be selected by default when opening the media library. +Media ID (or media IDs if multiple is true) to be selected by default when opening the media library. -- Type: `Object|Array` +- Type: `Number|Array` - Required: No - Platform: Web From 563ac7916fae4cd4f6aa17edae34c9449429e835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Mon, 21 Oct 2019 12:03:13 +0200 Subject: [PATCH 044/113] Tests: Clean up skipped e2e tests (#18003) --- package.json | 2 - .../editor/plugins/wp-editor-meta-box.test.js | 9 +-- .../specs/editor/various/embedding.test.js | 29 ------- .../specs/editor/various/links.test.js | 81 ------------------- .../specs/editor/various/nux.test.js | 70 ---------------- .../specs/editor/various/taxonomies.test.js | 42 +++++----- 6 files changed, 26 insertions(+), 207 deletions(-) diff --git a/package.json b/package.json index 013c7e69214101..473a7bfe852317 100644 --- a/package.json +++ b/package.json @@ -214,9 +214,7 @@ "publish:dev": "npm run build:packages && lerna publish --npm-tag next", "publish:prod": "npm run build:packages && lerna publish", "test": "npm run lint && npm run test-unit", - "pretest-e2e": "npm run env reinstall", "test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", - "test-e2e:local": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", "test-e2e:watch": "npm run test-e2e:local -- --watch", "test-performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js", "test-php": "npm run lint-php && npm run test-unit-php", diff --git a/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js b/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js index 74dd45374e946d..32286764092f17 100644 --- a/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js +++ b/packages/e2e-tests/specs/editor/plugins/wp-editor-meta-box.test.js @@ -8,9 +8,7 @@ import { publishPost, } from '@wordpress/e2e-test-utils'; -// This test isn't reliable on Travis and fails from time to time. -// See: https://github.com/WordPress/gutenberg/pull/15211. -describe.skip( 'WP Editor Meta Boxes', () => { +describe( 'WP Editor Meta Boxes', () => { beforeAll( async () => { await activatePlugin( 'gutenberg-test-plugin-wp-editor-meta-box' ); await createNewPost(); @@ -25,7 +23,7 @@ describe.skip( 'WP Editor Meta Boxes', () => { await page.type( '.editor-post-title__input', 'Hello Meta' ); // Type something - await page.click( '#test_tinymce_id-html' ); + await expect( page ).toClick( '#test_tinymce_id-html' ); await page.type( '#test_tinymce_id', 'Typing in a metabox' ); await page.click( '#test_tinymce_id-tmce' ); @@ -33,7 +31,8 @@ describe.skip( 'WP Editor Meta Boxes', () => { await page.reload(); - await page.click( '#test_tinymce_id-html' ); + await expect( page ).toClick( '#test_tinymce_id-html' ); + await page.waitForSelector( '#test_tinymce_id' ); const content = await page.$eval( '#test_tinymce_id', ( textarea ) => textarea.value diff --git a/packages/e2e-tests/specs/editor/various/embedding.test.js b/packages/e2e-tests/specs/editor/various/embedding.test.js index 878e540967a4f1..0a986702075bec 100644 --- a/packages/e2e-tests/specs/editor/various/embedding.test.js +++ b/packages/e2e-tests/specs/editor/various/embedding.test.js @@ -271,33 +271,4 @@ describe( 'Embedding content', () => { // Check the block has become a WordPress block. await page.waitForSelector( '.wp-block-embed-wordpress' ); } ); - - it.skip( 'should transform from video to embed block when YouTube URL is pasted', async () => { - await clickBlockAppender(); - await insertBlock( 'Video' ); - await page.click( '.editor-media-placeholder__url-input-container button' ); - await page.keyboard.type( 'https://www.youtube.com/watch?v=lXMskKTw3Bc' ); - await page.keyboard.press( 'Enter' ); - await page.waitForSelector( '.wp-block-embed-youtube' ); - } ); - - it.skip( 'should transform from image to embed block when Instagram URL is pasted', async () => { - await clickBlockAppender(); - await page.keyboard.type( '/image' ); - await page.keyboard.press( 'Enter' ); - await page.click( '.editor-media-placeholder__url-input-container button' ); - await page.keyboard.type( 'https://www.instagram.com/p/Bvl97o2AK6x/' ); - await page.keyboard.press( 'Enter' ); - await page.waitForSelector( '.wp-block-embed-instagram' ); - } ); - - it.skip( 'should transform from audio to embed block when Soundcloud URL is pasted', async () => { - await clickBlockAppender(); - await page.keyboard.type( '/audio' ); - await page.keyboard.press( 'Enter' ); - await page.click( '.editor-media-placeholder__url-input-container button' ); - await page.keyboard.type( 'https://soundcloud.com/a-boogie-wit-da-hoodie/swervin' ); - await page.keyboard.press( 'Enter' ); - await page.waitForSelector( '.wp-block-embed-soundcloud' ); - } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/links.test.js b/packages/e2e-tests/specs/editor/various/links.test.js index f7e78a7b68a1e2..ce9aaeab186799 100644 --- a/packages/e2e-tests/specs/editor/various/links.test.js +++ b/packages/e2e-tests/specs/editor/various/links.test.js @@ -266,87 +266,6 @@ describe( 'Links', () => { 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.skip( '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. - await createNewPost(); - await clickBlockAppender(); - await page.keyboard.type( 'This is Gutenberg' ); - await pressKeyWithModifier( 'shiftAlt', 'ArrowLeft' ); - await page.click( 'button[aria-label="Link"]' ); - - // Wait for the URL field to auto-focus - await waitForAutoFocus(); - - await page.keyboard.type( titleText ); - const suggestionXPath = `//*[contains(@class, "block-editor-url-input__suggestion")]//button[contains(text(), '${ titleText }')]`; - await page.waitForXPath( suggestionXPath ); - const autocompleteSuggestions = await page.$x( suggestionXPath ); - - // Expect there to be some autocomplete suggestions. - expect( autocompleteSuggestions ).toHaveLength( 1 ); - - const firstSuggestion = autocompleteSuggestions[ 0 ]; - - // Expect that clicking on the autocomplete suggestion doesn't dismiss the link popover. - await firstSuggestion.click(); - expect( await page.$( '.block-editor-url-popover' ) ).not.toBeNull(); - - // Expect the url input value to have been updated with the post url. - const inputValue = await page.evaluate( () => document.querySelector( '.block-editor-url-input input[aria-label="URL"]' ).value ); - expect( inputValue ).toEqual( postURL ); - - // Expect the link to apply correctly. - // Note - have avoided using snapshots here since the link url can't be determined ahead of time. - await page.click( 'button[aria-label="Apply"]' ); - const linkHref = await page.evaluate( () => document.querySelector( '.block-editor-format-toolbar__link-container-value' ).href ); - expect( linkHref ).toEqual( postURL ); - } ); - - // Test for regressions of https://github.com/WordPress/gutenberg/issues/10496. - // This test isn't reliable on Travis and fails from time to time. - // See: https://github.com/WordPress/gutenberg/pull/15211. - it.skip( 'allows autocomplete suggestions to be navigated with the keyboard', async () => { - const titleText = 'Test post keyboard'; - const postURL = await createPostWithTitle( titleText ); - - await createNewPost(); - 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 pressKeyWithModifier( 'shiftAlt', 'ArrowLeft' ); - - // Press Cmd+K to insert a link - await pressKeyWithModifier( 'primary', 'K' ); - - // Wait for the URL field to auto-focus - await waitForAutoFocus(); - - await page.keyboard.type( titleText ); - await page.waitForSelector( '.block-editor-url-input__suggestion' ); - const autocompleteSuggestions = await page.$x( `//*[contains(@class, "block-editor-url-input__suggestion")]//button[contains(text(), '${ titleText }')]` ); - - // Expect there to be some autocomplete suggestions. - expect( autocompleteSuggestions ).toHaveLength( 1 ); - - // 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( '.block-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( '.block-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 ); diff --git a/packages/e2e-tests/specs/editor/various/nux.test.js b/packages/e2e-tests/specs/editor/various/nux.test.js index 659263cea35335..d3ca54af511763 100644 --- a/packages/e2e-tests/specs/editor/various/nux.test.js +++ b/packages/e2e-tests/specs/editor/various/nux.test.js @@ -2,10 +2,7 @@ * WordPress dependencies */ import { - clickBlockAppender, - clickOnMoreMenuItem, createNewPost, - saveDraft, toggleScreenOption, } from '@wordpress/e2e-test-utils'; @@ -110,71 +107,4 @@ describe( 'New User Experience (NUX)', () => { areTipsEnabled = await getTipsEnabled( page ); expect( areTipsEnabled ).toEqual( true ); } ); - - // TODO: This test should be enabled once - // https://github.com/WordPress/gutenberg/issues/7458 is fixed. - it.skip( 'should show tips as disabled if all tips have been shown', async () => { - await clickAllTips( page ); - - // Open the "More" menu to check the "Show Tips" element. - await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' ); - const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="false"]' ); - - expect( showTipsButton ).toHaveLength( 1 ); - } ); - - // TODO: This test should be enabled once - // https://github.com/WordPress/gutenberg/issues/7458 is fixed. - it.skip( 'should reset tips if all tips have been shown and show tips was unchecked', async () => { - const { numberOfTips } = await clickAllTips( page ); - - // Click again to re-enable tips; they should appear. - await clickOnMoreMenuItem( 'Show Tips' ); - - // Open the "More" menu to check the "Show Tips" element. - await page.click( '.edit-post-more-menu [aria-label="More tools & options"]' ); - const showTipsButton = await page.$x( '//button[contains(text(), "Show Tips")][@aria-pressed="true"]' ); - - expect( showTipsButton ).toHaveLength( 1 ); - - // Tips should re-appear on the page. - const nuxTipElements = await page.$$( '.nux-dot-tip' ); - expect( nuxTipElements ).toHaveLength( 1 ); - - // Tips should be enabled again. - const areTipsEnabled = await getTipsEnabled( page ); - expect( areTipsEnabled ).toEqual( true ); - - // Dismissed tips should be reset and ready to be shown again. - const resetTips = await getTips( page ); - const newNumberOfTips = resetTips.tipIds.length; - expect( newNumberOfTips ).toHaveLength( numberOfTips ); - } ); - - // TODO: This test should be enabled once - // https://github.com/WordPress/gutenberg/issues/7753 is fixed. - // See: https://github.com/WordPress/gutenberg/issues/7753#issuecomment-403952816 - it.skip( 'should show tips if "Show tips" was disabled on a draft and then enabled', async () => { - // Click the "Show tips" button (enabled by default) to disable tips. - await clickOnMoreMenuItem( 'Show Tips' ); - - // Let's type something so there's content in this post. - await page.click( '.editor-post-title__input' ); - await page.keyboard.type( 'Post title' ); - await clickBlockAppender(); - await page.keyboard.type( 'Post content goes here.' ); - await saveDraft(); - - // Refresh the page; tips should be disabled. - await page.reload(); - let nuxTipElements = await page.$$( '.nux-dot-tip' ); - expect( nuxTipElements ).toHaveLength( 0 ); - - // Clicking should re-enable tips. - await clickOnMoreMenuItem( 'Show Tips' ); - - // Tips should re-appear on the page. - nuxTipElements = await page.$$( '.nux-dot-tip' ); - expect( nuxTipElements ).toHaveLength( 1 ); - } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/taxonomies.test.js b/packages/e2e-tests/specs/editor/various/taxonomies.test.js index 791fd79b12f8d4..4ed0ef3945fe61 100644 --- a/packages/e2e-tests/specs/editor/various/taxonomies.test.js +++ b/packages/e2e-tests/specs/editor/various/taxonomies.test.js @@ -1,9 +1,14 @@ +/** + * External dependencies + */ +import { random } from 'lodash'; + /** * WordPress dependencies */ import { - findSidebarPanelWithTitle, createNewPost, + findSidebarPanelWithTitle, openDocumentSettingsSidebar, publishPost, } from '@wordpress/e2e-test-utils'; @@ -50,22 +55,25 @@ describe( 'Taxonomies', () => { }, tagsPanel, TAG_TOKEN_SELECTOR ); }; + const openSidebarPanelWithTitle = async ( title ) => { + const panel = await page.waitForXPath( + `//div[contains(@class,"edit-post-sidebar")]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ title }")]` + ); + await panel.click(); + }; + it( 'should be able to open the categories panel and create a new main category if the user has the right capabilities', async () => { await createNewPost(); await openDocumentSettingsSidebar(); - const categoriesPanel = await findSidebarPanelWithTitle( 'Categories' ); - expect( categoriesPanel ).toBeDefined(); + await openSidebarPanelWithTitle( 'Categories' ); // If the user has no permission to add a new category finish the test. if ( ! ( await canCreatTermInTaxonomy( 'categories' ) ) ) { return; } - // Open the categories panel. - await categoriesPanel.click( 'button' ); - await page.waitForSelector( 'button.editor-post-taxonomies__hierarchical-terms-add' ); // Click add new category button. @@ -108,27 +116,18 @@ describe( 'Taxonomies', () => { expect( selectedCategories[ 0 ] ).toEqual( 'z rand category 1' ); } ); - // This test isn't reliable locally because repeated execution of the test triggers 400 network - // because of the tag's duplication. Also, it randomly doesn't add a new tag after pressing enter. - // See: https://github.com/WordPress/gutenberg/pull/15211. - it.skip( 'should be able to open the tags panel and create a new tag if the user has the right capabilities', async () => { + it( 'should be able to open the tags panel and create a new tag if the user has the right capabilities', async () => { await createNewPost(); await openDocumentSettingsSidebar(); - const tagsPanel = await findSidebarPanelWithTitle( 'Tags' ); - - //expect( await page.evaluate( ( el ) => el.outerHTML, tagsPanel ) ).toEqual( 'tag1 ok' ); - expect( tagsPanel ).toBeDefined(); + await openSidebarPanelWithTitle( 'Tags' ); // If the user has no permission to add a new tag finish the test. if ( ! ( await canCreatTermInTaxonomy( 'tags' ) ) ) { return; } - // Open the tags panel. - await tagsPanel.click( 'button' ); - // At the start there are no tag tokens expect( await page.$$( @@ -136,13 +135,16 @@ describe( 'Taxonomies', () => { ) ).toHaveLength( 0 ); + const tagsPanel = await findSidebarPanelWithTitle( 'Tags' ); const tagInput = await tagsPanel.$( '.components-form-token-field__input' ); // Click the tag input field. await tagInput.click(); + const tagName = 'tag-' + random( 1, Number.MAX_SAFE_INTEGER ); + // Type the category name in the field. - await tagInput.type( 'tag1' ); + await tagInput.type( tagName ); // Press enter to create a new tag. await tagInput.press( 'Enter' ); @@ -154,7 +156,7 @@ describe( 'Taxonomies', () => { // The post should only contain the tag we added. expect( tags ).toHaveLength( 1 ); - expect( tags[ 0 ] ).toEqual( 'tag1' ); + expect( tags[ 0 ] ).toEqual( tagName ); // Type something in the title so we can publish the post. await page.type( '.editor-post-title__input', 'Hello World' ); @@ -172,6 +174,6 @@ describe( 'Taxonomies', () => { // The tag selection was persisted after the publish process. expect( tags ).toHaveLength( 1 ); - expect( tags[ 0 ] ).toEqual( 'tag1' ); + expect( tags[ 0 ] ).toEqual( tagName ); } ); } ); From bf60a077465f4908e843d2537d8c31b6a11c7cfa Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Mon, 21 Oct 2019 11:20:33 +0100 Subject: [PATCH 045/113] chore(release): publish - @wordpress/api-fetch@3.6.3 - @wordpress/block-directory@1.0.3 - @wordpress/block-editor@3.2.3 - @wordpress/block-library@2.9.3 - @wordpress/core-data@2.7.3 - @wordpress/data-controls@1.3.3 - @wordpress/e2e-test-utils@2.4.3 - @wordpress/e2e-tests@1.7.3 - @wordpress/edit-post@3.8.3 - @wordpress/edit-widgets@0.7.3 - @wordpress/editor@9.7.3 - @wordpress/format-library@1.9.3 - @wordpress/list-reusable-blocks@1.8.3 - @wordpress/media-utils@1.2.3 - @wordpress/server-side-render@1.3.3 - @wordpress/url@2.8.2 --- packages/api-fetch/package.json | 2 +- packages/block-directory/package.json | 2 +- packages/block-editor/package.json | 2 +- packages/block-library/package.json | 2 +- packages/core-data/package.json | 2 +- packages/data-controls/package.json | 2 +- packages/e2e-test-utils/package.json | 2 +- packages/e2e-tests/package.json | 2 +- packages/edit-post/package.json | 2 +- packages/edit-widgets/package.json | 2 +- packages/editor/package.json | 2 +- packages/format-library/package.json | 2 +- packages/list-reusable-blocks/package.json | 2 +- packages/media-utils/package.json | 2 +- packages/server-side-render/package.json | 2 +- packages/url/package.json | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/api-fetch/package.json b/packages/api-fetch/package.json index f14917b7b78003..462c964c370c6b 100644 --- a/packages/api-fetch/package.json +++ b/packages/api-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/api-fetch", - "version": "3.6.2", + "version": "3.6.3", "description": "Utility to make WordPress REST API requests.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index d27e666e95a5c7..7736869f8100cd 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-directory", - "version": "1.0.2", + "version": "1.0.3", "description": "Extend editor with block directory features to search, download and install blocks.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index eaa7f50ceaf831..9d9f00f675fb27 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-editor", - "version": "3.2.2", + "version": "3.2.3", "description": "Generic block editor.", "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 253fb60bdb6916..8d4cd8ba268545 100644 --- a/packages/block-library/package.json +++ b/packages/block-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/block-library", - "version": "2.9.2", + "version": "2.9.3", "description": "Block library for the WordPress editor.", "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 759d4df2d70b65..3c565d2bfc56c6 100644 --- a/packages/core-data/package.json +++ b/packages/core-data/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/core-data", - "version": "2.7.2", + "version": "2.7.3", "description": "Access to and manipulation of core WordPress entities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json index e4a8154ac73f25..9b6d2724b43e45 100644 --- a/packages/data-controls/package.json +++ b/packages/data-controls/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/data-controls", - "version": "1.3.2", + "version": "1.3.3", "description": "A set of common controls for the @wordpress/data api.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index ab343497e14905..6365c171aa416e 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-test-utils", - "version": "2.4.2", + "version": "2.4.3", "description": "End-To-End (E2E) test utils for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index aea246540c45b7..6517b0042a9b67 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/e2e-tests", - "version": "1.7.2", + "version": "1.7.3", "description": "End-To-End (E2E) tests 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 389d9d8f7c1848..a73c2d52ac105b 100644 --- a/packages/edit-post/package.json +++ b/packages/edit-post/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-post", - "version": "3.8.2", + "version": "3.8.3", "description": "Edit Post module for WordPress.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json index f9b184f97cd986..37dd6972b49627 100644 --- a/packages/edit-widgets/package.json +++ b/packages/edit-widgets/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/edit-widgets", - "version": "0.7.2", + "version": "0.7.3", "private": true, "description": "Widgets Page module for WordPress..", "author": "The WordPress Contributors", diff --git a/packages/editor/package.json b/packages/editor/package.json index 98ad243772f9a1..9ddc2a6d1951ae 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/editor", - "version": "9.7.2", + "version": "9.7.3", "description": "Building blocks for WordPress editors.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/format-library/package.json b/packages/format-library/package.json index b9b6dbfa8156fc..e7385c46bd2bfc 100644 --- a/packages/format-library/package.json +++ b/packages/format-library/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/format-library", - "version": "1.9.2", + "version": "1.9.3", "description": "Format library for the WordPress editor.", "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 4edf08437583de..54c7773292205d 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.8.2", + "version": "1.8.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/media-utils/package.json b/packages/media-utils/package.json index d406276cbdeeec..7d6af3e41f63ba 100644 --- a/packages/media-utils/package.json +++ b/packages/media-utils/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/media-utils", - "version": "1.2.2", + "version": "1.2.3", "description": "WordPress Media Upload Utils.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/server-side-render/package.json b/packages/server-side-render/package.json index f0bd3ab7efbfa9..39941d137650bf 100644 --- a/packages/server-side-render/package.json +++ b/packages/server-side-render/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/server-side-render", - "version": "1.3.2", + "version": "1.3.3", "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", diff --git a/packages/url/package.json b/packages/url/package.json index 456006fb1370a3..bc1e8bf3587eb0 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/url", - "version": "2.8.1", + "version": "2.8.2", "description": "WordPress URL utilities.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 0c8da5b39d25d9b223239daf744ecc7091e74b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Tue, 22 Oct 2019 11:15:11 +0200 Subject: [PATCH 046/113] Chore: Fix issues related to Node 12 becoming LTS (#18054) * Chore: Fix issues related to Node 12 becoming LTS * Include the root package.json file in the linting This commit also moves the npm-package-json-lint config to the standalone file. * Add changelog entries to @wordpress/scripts package --- .npmpackagejsonlintrc.json | 39 + package-lock.json | 2701 ++++++++++----------- package.json | 36 +- packages/scripts/CHANGELOG.md | 10 + packages/scripts/package.json | 4 +- packages/scripts/scripts/lint-pkg-json.js | 2 + 6 files changed, 1389 insertions(+), 1403 deletions(-) create mode 100644 .npmpackagejsonlintrc.json diff --git a/.npmpackagejsonlintrc.json b/.npmpackagejsonlintrc.json new file mode 100644 index 00000000000000..daab51fa30d456 --- /dev/null +++ b/.npmpackagejsonlintrc.json @@ -0,0 +1,39 @@ +{ + "extends": "@wordpress/npm-package-json-lint-config", + "rules": { + "description-format": [ + "error", + { + "requireCapitalFirstLetter": true, + "requireEndingPeriod": true + } + ], + "prefer-no-devDependencies": "error", + "require-publishConfig": "error", + "require-repository-directory": "error", + "valid-values-author": [ + "error", + [ + "The WordPress Contributors" + ] + ], + "valid-values-publishConfig": [ + "error", + [ + { + "access": "public" + } + ] + ] + }, + "overrides": [ + { + "patterns": [ "./package.json" ], + "rules": { + "require-publishConfig": "off", + "require-repository-directory": "off", + "prefer-no-devDependencies": "off" + } + } + ] +} diff --git a/package-lock.json b/package-lock.json index b0800b864bd84a..5ac18b619edc25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -986,15 +986,6 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.4.tgz", - "integrity": "sha512-Ki+Y9nXBlKfhD+LXaRS7v95TtTGYRAf9Y1rTDiE75zf8YQz4GDaWRXosMfJBXxnk88mGFjWdCRIeqDbon7spYA==", - "dev": true, - "requires": { - "regexp-tree": "^0.1.0" - } - }, "@babel/plugin-transform-new-target": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", @@ -1895,9 +1886,9 @@ } }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "ssri": { @@ -1936,25 +1927,27 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "@evocateur/pacote": { - "version": "9.6.3", - "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.3.tgz", - "integrity": "sha512-ExqNqcbdHQprEgKnY/uQz7WRtyHRbQxRl4JnVkSkmtF8qffRrF9K+piZKNLNSkRMOT/3H0e3IP44QVCHaXMWOQ==", + "version": "9.6.5", + "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.5.tgz", + "integrity": "sha512-EI552lf0aG2nOV8NnZpTxNo2PcXKPmDbF9K8eCBFQdIZwHNGN/mi815fxtmUMa2wTa1yndotICIDt/V0vpEx2w==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", "bluebird": "^3.5.3", - "cacache": "^12.0.0", + "cacache": "^12.0.3", + "chownr": "^1.1.2", "figgy-pudding": "^3.5.1", "get-stream": "^4.1.0", "glob": "^7.1.4", + "infer-owner": "^1.0.4", "lru-cache": "^5.1.1", "make-fetch-happen": "^5.0.0", "minimatch": "^3.0.4", @@ -1964,7 +1957,7 @@ "normalize-package-data": "^2.5.0", "npm-package-arg": "^6.1.0", "npm-packlist": "^1.4.4", - "npm-pick-manifest": "^2.2.3", + "npm-pick-manifest": "^3.0.0", "osenv": "^0.1.5", "promise-inflight": "^1.0.1", "promise-retry": "^1.1.1", @@ -1979,15 +1972,15 @@ }, "dependencies": { "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", "dev": true }, "cacache": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", - "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", "dev": true, "requires": { "bluebird": "^3.5.5", @@ -2008,9 +2001,9 @@ } }, "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "get-stream": { @@ -2023,9 +2016,9 @@ } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2037,9 +2030,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "lru-cache": { @@ -2107,9 +2100,9 @@ } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" @@ -2122,9 +2115,9 @@ "dev": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "ssri": { @@ -2137,18 +2130,30 @@ } }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } } }, "unique-filename": { @@ -2167,9 +2172,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } @@ -2488,15 +2493,15 @@ } }, "@lerna/add": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.16.2.tgz", - "integrity": "sha512-RAAaF8aODPogj2Ge9Wj3uxPFIBGpog9M+HwSuq03ZnkkO831AmasCTJDqV+GEpl1U2DvnhZQEwHpWmTT0uUeEw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.18.0.tgz", + "integrity": "sha512-Z5EaQbBnJn1LEPb0zb0Q2o9T8F8zOnlCsj6JYpY6aSke17UUT7xx0QMN98iBK+ueUHKjN/vdFdYlNCYRSIdujA==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", - "@lerna/bootstrap": "3.16.2", - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", + "@lerna/bootstrap": "3.18.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", "@lerna/npm-conf": "3.16.0", "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", @@ -2519,34 +2524,23 @@ } } }, - "@lerna/batch-packages": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.16.0.tgz", - "integrity": "sha512-7AdMkANpubY/FKFI01im01tlx6ygOBJ/0JcixMUWoWP/7Ds3SWQF22ID6fbBr38jUWptYLDs2fagtTDL7YUPuA==", - "dev": true, - "requires": { - "@lerna/package-graph": "3.16.0", - "npmlog": "^4.1.2" - } - }, "@lerna/bootstrap": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.16.2.tgz", - "integrity": "sha512-I+gs7eh6rv9Vyd+CwqL7sftRfOOsSzCle8cv/CGlMN7/p7EAVhxEdAw8SYoHIKHzipXszuqqy1Y3opyleD0qdA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.18.0.tgz", + "integrity": "sha512-3DZKWIaKvr7sUImoKqSz6eqn84SsOVMnA5QHwgzXiQjoeZ/5cg9x2r+Xj3+3w/lvLoh0j8U2GNtrIaPNis4bKQ==", "dev": true, "requires": { - "@lerna/batch-packages": "3.16.0", - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/has-npm-version": "3.16.0", - "@lerna/npm-install": "3.16.0", - "@lerna/package-graph": "3.16.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/has-npm-version": "3.16.5", + "@lerna/npm-install": "3.16.5", + "@lerna/package-graph": "3.18.0", "@lerna/pulse-till-done": "3.13.0", - "@lerna/rimraf-dir": "3.14.2", + "@lerna/rimraf-dir": "3.16.5", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-parallel-batches": "3.16.0", - "@lerna/symlink-binary": "3.16.2", - "@lerna/symlink-dependencies": "3.16.2", + "@lerna/run-topologically": "3.18.0", + "@lerna/symlink-binary": "3.17.0", + "@lerna/symlink-dependencies": "3.17.0", "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", "get-port": "^4.2.0", @@ -2582,33 +2576,33 @@ } }, "@lerna/changed": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.16.4.tgz", - "integrity": "sha512-NCD7XkK744T23iW0wqKEgF4R9MYmReUbyHCZKopFnsNpQdqumc3SOIvQUAkKCP6hQJmYvxvOieoVgy/CVDpZ5g==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.18.2.tgz", + "integrity": "sha512-xVnFuj4A6Avxem+8R+KOuKDxfnxp1S5tM5nwsh7n3IhCN5Ga7YINV/JgPhrwgcpqPCVBvAowkilghT/I0r6wUw==", "dev": true, "requires": { - "@lerna/collect-updates": "3.16.0", - "@lerna/command": "3.16.0", - "@lerna/listable": "3.16.0", + "@lerna/collect-updates": "3.18.0", + "@lerna/command": "3.18.0", + "@lerna/listable": "3.18.0", "@lerna/output": "3.13.0", - "@lerna/version": "3.16.4" + "@lerna/version": "3.18.2" } }, "@lerna/check-working-tree": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.14.2.tgz", - "integrity": "sha512-7safqxM/MYoAoxZxulUDtIJIbnBIgo0PB/FHytueG+9VaX7GMnDte2Bt1EKa0dz2sAyQdmQ3Q8ZXpf/6JDjaeg==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.16.5.tgz", + "integrity": "sha512-xWjVBcuhvB8+UmCSb5tKVLB5OuzSpw96WEhS2uz6hkWVa/Euh1A0/HJwn2cemyK47wUrCQXtczBUiqnq9yX5VQ==", "dev": true, "requires": { - "@lerna/collect-uncommitted": "3.14.2", - "@lerna/describe-ref": "3.14.2", + "@lerna/collect-uncommitted": "3.16.5", + "@lerna/describe-ref": "3.16.5", "@lerna/validation-error": "3.13.0" } }, "@lerna/child-process": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.14.2.tgz", - "integrity": "sha512-xnq+W5yQb6RkwI0p16ZQnrn6HkloH/MWTw4lGE1nKsBLAUbmSU5oTE93W1nrG0X3IMF/xWc9UYvNdUGMWvZZ4w==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.16.5.tgz", + "integrity": "sha512-vdcI7mzei9ERRV4oO8Y1LHBZ3A5+ampRKg1wq5nutLsUA4mEBN6H7JqjWOMY9xZemv6+kATm2ofjJ3lW5TszQg==", "dev": true, "requires": { "chalk": "^2.3.1", @@ -2664,24 +2658,24 @@ } }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "@lerna/clean": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.16.0.tgz", - "integrity": "sha512-5P9U5Y19WmYZr7UAMGXBpY7xCRdlR7zhHy8MAPDKVx70rFIBS6nWXn5n7Kntv74g7Lm1gJ2rsiH5tj1OPcRJgg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.18.0.tgz", + "integrity": "sha512-BiwBELZNkarRQqj+v5NPB1aIzsOX+Y5jkZ9a5UbwHzEdBUQ5lQa0qaMLSOve/fSkaiZQxe6qnTyatN75lOcDMg==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", - "@lerna/rimraf-dir": "3.14.2", + "@lerna/rimraf-dir": "3.16.5", "p-map": "^2.1.0", "p-map-series": "^1.0.0", "p-waterfall": "^1.0.0" @@ -2696,49 +2690,38 @@ } }, "@lerna/cli": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.13.0.tgz", - "integrity": "sha512-HgFGlyCZbYaYrjOr3w/EsY18PdvtsTmDfpUQe8HwDjXlPeCCUgliZjXLOVBxSjiOvPeOSwvopwIHKWQmYbwywg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.18.0.tgz", + "integrity": "sha512-AwDyfGx7fxJgeaZllEuyJ9LZ6Tdv9yqRD9RX762yCJu+PCAFvB9bp6OYuRSGli7QQgM0CuOYnSg4xVNOmuGKDA==", "dev": true, "requires": { "@lerna/global-options": "3.13.0", "dedent": "^0.7.0", "npmlog": "^4.1.2", - "yargs": "^12.0.1" + "yargs": "^14.2.0" }, "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, "find-up": { @@ -2750,30 +2733,12 @@ "locate-path": "^3.0.0" } }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -2784,44 +2749,10 @@ "path-exists": "^3.0.0" } }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -2842,46 +2773,72 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.0.tgz", + "integrity": "sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg==", "dev": true, "requires": { - "cliui": "^4.0.0", + "cliui": "^5.0.0", "decamelize": "^1.2.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^15.0.0" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -2891,25 +2848,25 @@ } }, "@lerna/collect-uncommitted": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.14.2.tgz", - "integrity": "sha512-4EkQu4jIOdNL2BMzy/N0ydHB8+Z6syu6xiiKXOoFl0WoWU9H1jEJCX4TH7CmVxXL1+jcs8FIS2pfQz4oew99Eg==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.16.5.tgz", + "integrity": "sha512-ZgqnGwpDZiWyzIQVZtQaj9tRizsL4dUOhuOStWgTAw1EMe47cvAY2kL709DzxFhjr6JpJSjXV5rZEAeU3VE0Hg==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "chalk": "^2.3.1", "figgy-pudding": "^3.5.1", "npmlog": "^4.1.2" } }, "@lerna/collect-updates": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.16.0.tgz", - "integrity": "sha512-HwAIl815X2TNlmcp28zCrSdXfoZWNP7GJPEqNWYk7xDJTYLqQ+SrmKUePjb3AMGBwYAraZSEJLbHdBpJ5+cHmQ==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.18.0.tgz", + "integrity": "sha512-LJMKgWsE/var1RSvpKDIxS8eJ7POADEc0HM3FQiTpEczhP6aZfv9x3wlDjaHpZm9MxJyQilqxZcasRANmRcNgw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/describe-ref": "3.14.2", + "@lerna/child-process": "3.16.5", + "@lerna/describe-ref": "3.16.5", "minimatch": "^3.0.4", "npmlog": "^4.1.2", "slash": "^2.0.0" @@ -2924,14 +2881,14 @@ } }, "@lerna/command": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.16.0.tgz", - "integrity": "sha512-u7tE4GC4/gfbPA9eQg+0ulnoJ+PMoMqomx033r/IxqZrHtmJR9+pF/37S0fsxJ2hX/RMFPC7c9Q/i8NEufSpdQ==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.18.0.tgz", + "integrity": "sha512-JQ0TGzuZc9Ky8xtwtSLywuvmkU8X62NTUT3rMNrUykIkOxBaO+tE0O98u2yo/9BYOeTRji9IsjKZEl5i9Qt0xQ==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/package-graph": "3.16.0", - "@lerna/project": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/package-graph": "3.18.0", + "@lerna/project": "3.18.0", "@lerna/validation-error": "3.13.0", "@lerna/write-log-file": "3.13.0", "dedent": "^0.7.0", @@ -2941,12 +2898,6 @@ "npmlog": "^4.1.2" }, "dependencies": { - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2984,15 +2935,6 @@ "pump": "^3.0.0" } }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -3004,9 +2946,9 @@ } }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -3051,9 +2993,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "pify": { @@ -3081,14 +3023,14 @@ } }, "@lerna/create": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.16.0.tgz", - "integrity": "sha512-OZApR1Iz7awutbmj4sAArwhqCyKgcrnw9rH0aWAUrkYWrD1w4TwkvAcYAsfx5GpQGbLQwoXhoyyPwPfZRRWz3Q==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.18.0.tgz", + "integrity": "sha512-y9oS7ND5T13c+cCTJHa2Y9in02ppzyjsNynVWFuS40eIzZ3z058d9+3qSBt1nkbbQlVyfLoP6+bZPsjyzap5ig==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "@lerna/npm-conf": "3.16.0", "@lerna/validation-error": "3.13.0", "camelcase": "^5.0.0", @@ -3124,9 +3066,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "pify": { @@ -3148,9 +3090,9 @@ "dev": true }, "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -3183,45 +3125,45 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } }, "@lerna/describe-ref": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.14.2.tgz", - "integrity": "sha512-qa5pzDRK2oBQXNjyRmRnN7E8a78NMYfQjjlRFB0KNHMsT6mCiL9+8kIS39sSE2NqT8p7xVNo2r2KAS8R/m3CoQ==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.16.5.tgz", + "integrity": "sha512-c01+4gUF0saOOtDBzbLMFOTJDHTKbDFNErEY6q6i9QaXuzy9LNN62z+Hw4acAAZuJQhrVWncVathcmkkjvSVGw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "npmlog": "^4.1.2" } }, "@lerna/diff": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.16.0.tgz", - "integrity": "sha512-QUpVs5TPl8vBIne10/vyjUxanQBQQp7Lk3iaB8MnCysKr0O+oy7trWeFVDPEkBTCD177By7yPGyW5Yey1nCBbA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.18.0.tgz", + "integrity": "sha512-3iLNlpurc2nV9k22w8ini2Zjm2UPo3xtQgWyqdA6eJjvge0+5AlNAWfPoV6cV+Hc1xDbJD2YDSFpZPJ1ZGilRw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "@lerna/validation-error": "3.13.0", "npmlog": "^4.1.2" } }, "@lerna/exec": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.16.0.tgz", - "integrity": "sha512-mH3O5NXf/O88jBaBBTUf+d56CUkxpg782s3Jxy7HWbVuSUULt3iMRPTh+zEXO5/555etsIVVDDyUR76meklrJA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.18.0.tgz", + "integrity": "sha512-hwkuzg1+38+pbzdZPhGtLIYJ59z498/BCNzR8d4/nfMYm8lFbw9RgJJajLcdbuJ9LJ08cZ93hf8OlzetL84TYg==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/run-topologically": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/run-topologically": "3.18.0", "@lerna/validation-error": "3.13.0", "p-map": "^2.1.0" }, @@ -3235,20 +3177,22 @@ } }, "@lerna/filter-options": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.16.0.tgz", - "integrity": "sha512-InIi1fF8+PxpCwir9bIy+pGxrdE6hvN0enIs1eNGCVS1TTE8osNgiZXa838bMQ1yaEccdcnVX6Z03BNKd56kNg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.18.0.tgz", + "integrity": "sha512-UGVcixs3TGzD8XSmFSbwUVVQnAjaZ6Rmt8Vuq2RcR98ULkGB1LiGNMY89XaNBhaaA8vx7yQWiLmJi2AfmD63Qg==", "dev": true, "requires": { - "@lerna/collect-updates": "3.16.0", - "@lerna/filter-packages": "3.16.0", - "dedent": "^0.7.0" + "@lerna/collect-updates": "3.18.0", + "@lerna/filter-packages": "3.18.0", + "dedent": "^0.7.0", + "figgy-pudding": "^3.5.1", + "npmlog": "^4.1.2" } }, "@lerna/filter-packages": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.16.0.tgz", - "integrity": "sha512-eGFzQTx0ogkGDCnbTuXqssryR6ilp8+dcXt6B+aq1MaqL/vOJRZyqMm4TY3CUOUnzZCi9S2WWyMw3PnAJOF+kg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.18.0.tgz", + "integrity": "sha512-6/0pMM04bCHNATIOkouuYmPg6KH3VkPCIgTfQmdkPJTullERyEQfNUKikrefjxo1vHOoCACDpy65JYyKiAbdwQ==", "dev": true, "requires": { "@lerna/validation-error": "3.13.0", @@ -3277,9 +3221,9 @@ }, "dependencies": { "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "fs-extra": { @@ -3294,11 +3238,21 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -3309,14 +3263,14 @@ } }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -3324,20 +3278,20 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "@lerna/github-client": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.16.0.tgz", - "integrity": "sha512-IVJjcKjkYaUEPJsDyAblHGEFFNKCRyMagbIDm14L7Ab94ccN6i4TKOqAFEJn2SJHYvKKBdp3Zj2zNlASOMe3DA==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.16.5.tgz", + "integrity": "sha512-rHQdn8Dv/CJrO3VouOP66zAcJzrHsm+wFuZ4uGAai2At2NkgKH+tpNhQy2H1PSC0Ezj9LxvdaHYrUzULqVK5Hw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "@octokit/plugin-enterprise-rest": "^3.6.1", "@octokit/rest": "^16.28.4", "git-url-parse": "^11.1.2", @@ -3345,9 +3299,9 @@ }, "dependencies": { "@octokit/request": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.0.2.tgz", - "integrity": "sha512-z1BQr43g4kOL4ZrIVBMHwi68Yg9VbkRUyuAgqCp1rU3vbYa69+2gIld/+gHclw15bJWQnhqqyEb7h5a5EqgZ0A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.2.1.tgz", + "integrity": "sha512-onjQo4QKyiMAqLM6j3eH8vWw1LEfNCpoZUl6a+TrZVJM1wysBC8F0GhK9K/Vc9UsScSmVs2bstOVD34xpQ2wqQ==", "dev": true, "requires": { "@octokit/endpoint": "^5.1.0", @@ -3356,16 +3310,16 @@ "is-plain-object": "^3.0.0", "node-fetch": "^2.3.0", "once": "^1.4.0", - "universal-user-agent": "^3.0.0" + "universal-user-agent": "^4.0.0" } }, "@octokit/rest": { - "version": "16.28.7", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.7.tgz", - "integrity": "sha512-cznFSLEhh22XD3XeqJw51OLSfyL2fcFKUO+v2Ep9MTAFfFLS1cK1Zwd1yEgQJmJoDnj4/vv3+fGGZweG+xsbIA==", + "version": "16.33.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.33.1.tgz", + "integrity": "sha512-lOQ+fJZwkeJ/1PRTdnY1uNja01aKOMioRhQfZtei64gZMXIX3EAfF4koMQMvoLFwsnVBu3ifj1JW1WAAKdXcnA==", "dev": true, "requires": { - "@octokit/request": "^5.0.0", + "@octokit/request": "^5.2.0", "@octokit/request-error": "^1.0.2", "atob-lite": "^2.0.0", "before-after-hook": "^2.0.0", @@ -3376,8 +3330,7 @@ "lodash.uniq": "^4.5.0", "octokit-pagination-methods": "^1.1.0", "once": "^1.4.0", - "universal-user-agent": "^3.0.0", - "url-template": "^2.0.8" + "universal-user-agent": "^4.0.0" } }, "before-after-hook": { @@ -3408,12 +3361,12 @@ "dev": true }, "universal-user-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz", - "integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", + "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", "dev": true, "requires": { - "os-name": "^3.0.0" + "os-name": "^3.1.0" } } } @@ -3436,9 +3389,9 @@ "dev": true }, "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -3455,12 +3408,12 @@ "dev": true }, "@lerna/has-npm-version": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.0.tgz", - "integrity": "sha512-TIY036dA9J8OyTrZq9J+it2DVKifL65k7hK8HhkUPpitJkw6jwbMObA/8D40LOGgWNPweJWqmlrTbRSwsR7DrQ==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.5.tgz", + "integrity": "sha512-WL7LycR9bkftyqbYop5rEGJ9sRFIV55tSGmbN1HLrF9idwOCD7CLrT64t235t3t4O5gehDnwKI5h2U3oxTrF8Q==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "semver": "^6.2.0" }, "dependencies": { @@ -3473,13 +3426,13 @@ } }, "@lerna/import": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.16.0.tgz", - "integrity": "sha512-trsOmGHzw0rL/f8BLNvd+9PjoTkXq2Dt4/V2UCha254hMQaYutbxcYu8iKPxz9x86jSPlH7FpbTkkHXDsoY7Yg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.18.0.tgz", + "integrity": "sha512-2pYIkkBTZsEdccfc+dPsKZeSw3tBzKSyl0b2lGrfmNX2Y41qqOzsJCyI1WO1uvEIP8aOaLy4hPpqRIBe4ee7hw==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", "@lerna/validation-error": "3.13.0", @@ -3500,21 +3453,21 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } }, "@lerna/init": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.16.0.tgz", - "integrity": "sha512-Ybol/x5xMtBgokx4j7/Y3u0ZmNh0NiSWzBFVaOs2NOJKvuqrWimF67DKVz7yYtTYEjtaMdug64ohFF4jcT/iag==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.18.0.tgz", + "integrity": "sha512-/vHpmXkMlSaJaq25v5K13mcs/2L7E32O6dSsEkHaZCDRiV2BOqsZng9jjbE/4ynfsWfLLlU9ZcydwG72C3I+mQ==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", - "@lerna/command": "3.16.0", + "@lerna/child-process": "3.16.5", + "@lerna/command": "3.18.0", "fs-extra": "^8.1.0", "p-map": "^2.1.0", "write-json-file": "^3.2.0" @@ -3532,9 +3485,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -3546,14 +3499,14 @@ } }, "@lerna/link": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.16.2.tgz", - "integrity": "sha512-eCPg5Lo8HT525fIivNoYF3vWghO3UgEVFdbsiPmhzwI7IQyZro5HWYzLtywSAdEog5XZpd2Bbn0CsoHWBB3gww==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.18.0.tgz", + "integrity": "sha512-FbbIpH0EpsC+dpAbvxCoF3cn7F1MAyJjEa5Lh3XkDGATOlinMFuKCbmX0NLpOPQZ5zghvrui97cx+jz5F2IlHw==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/package-graph": "3.16.0", - "@lerna/symlink-dependencies": "3.16.2", + "@lerna/command": "3.18.0", + "@lerna/package-graph": "3.18.0", + "@lerna/symlink-dependencies": "3.17.0", "p-map": "^2.1.0", "slash": "^2.0.0" }, @@ -3573,24 +3526,24 @@ } }, "@lerna/list": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.16.0.tgz", - "integrity": "sha512-TkvstoPsgKqqQ0KfRumpsdMXfRSEhdXqOLq519XyI5IRWYxhoqXqfi8gG37UoBPhBNoe64japn5OjphF3rOmQA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.18.0.tgz", + "integrity": "sha512-mpB7Q6T+n2CaiPFz0LuOE+rXphDfHm0mKIwShnyS/XDcii8jXv+z9Iytj8p3rfCH2I1L80j2qL6jWzyGy/uzKA==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/listable": "3.16.0", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/listable": "3.18.0", "@lerna/output": "3.13.0" } }, "@lerna/listable": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.16.0.tgz", - "integrity": "sha512-mtdAT2EEECqrJSDm/aXlOUFr1MRE4p6hppzY//Klp05CogQy6uGaKk+iKG5yyCLaOXFFZvG4HfO11CmoGSDWzw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.18.0.tgz", + "integrity": "sha512-9gLGKYNLSKeurD+sJ2RA+nz4Ftulr91U127gefz0RlmAPpYSjwcJkxwa0UfJvpQTXv9C7yzHLnn0BjyAQRjuew==", "dev": true, "requires": { - "@lerna/query-graph": "3.16.0", + "@lerna/query-graph": "3.18.0", "chalk": "^2.3.1", "columnify": "^1.5.4" } @@ -3626,9 +3579,9 @@ } }, "@lerna/npm-dist-tag": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.16.0.tgz", - "integrity": "sha512-MQrBkqJJB9+eNphuj9w90QPMOs4NQXMuSRk9NqzeFunOmdDopPCV0Q7IThSxEuWnhJ2n3B7G0vWUP7tNMPdqIQ==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.18.1.tgz", + "integrity": "sha512-vWkZh2T/O9OjPLDrba0BTWO7ug/C3sCwjw7Qyk1aEbxMBXB/eEJPqirwJTWT+EtRJQYB01ky3K8ZFOhElVyjLw==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3639,12 +3592,12 @@ } }, "@lerna/npm-install": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.0.tgz", - "integrity": "sha512-APUOIilZCzDzce92uLEwzt1r7AEMKT/hWA1ThGJL+PO9Rn8A95Km3o2XZAYG4W0hR+P4O2nSVuKbsjQtz8CjFQ==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.5.tgz", + "integrity": "sha512-hfiKk8Eku6rB9uApqsalHHTHY+mOrrHeWEs+gtg7+meQZMTS3kzv4oVp5cBZigndQr3knTLjwthT/FX4KvseFg==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "@lerna/get-npm-exec-opts": "3.13.0", "fs-extra": "^8.1.0", "npm-package-arg": "^6.1.0", @@ -3665,9 +3618,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } @@ -3701,9 +3654,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "pify": { @@ -3715,12 +3668,12 @@ } }, "@lerna/npm-run-script": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.14.2.tgz", - "integrity": "sha512-LbVFv+nvAoRTYLMrJlJ8RiakHXrLslL7Jp/m1R18vYrB8LYWA3ey+nz5Tel2OELzmjUiemAKZsD9h6i+Re5egg==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.16.5.tgz", + "integrity": "sha512-1asRi+LjmVn3pMjEdpqKJZFT/3ZNpb+VVeJMwrJaV/3DivdNg7XlPK9LTrORuKU4PSvhdEZvJmSlxCKyDpiXsQ==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "@lerna/get-npm-exec-opts": "3.13.0", "npmlog": "^4.1.2" } @@ -3761,20 +3714,30 @@ }, "dependencies": { "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -3782,9 +3745,9 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } @@ -3801,9 +3764,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "load-json-file": { @@ -3844,9 +3807,9 @@ } }, "@lerna/package-graph": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.16.0.tgz", - "integrity": "sha512-A2mum/gNbv7zCtAwJqoxzqv89As73OQNK2MgSX1SHWya46qoxO9a9Z2c5lOFQ8UFN5ZxqWMfFYXRCz7qzwmFXw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.18.0.tgz", + "integrity": "sha512-BLYDHO5ihPh20i3zoXfLZ5ZWDCrPuGANgVhl7k5pCmRj90LCvT+C7V3zrw70fErGAfvkcYepMqxD+oBrAYwquQ==", "dev": true, "requires": { "@lerna/prerelease-id-from-version": "3.16.0", @@ -3882,9 +3845,9 @@ } }, "@lerna/project": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.16.0.tgz", - "integrity": "sha512-NrKcKK1EqXqhrGvslz6Q36+ZHuK3zlDhGdghRqnxDcHxMPT01NgLcmsnymmQ+gjMljuLRmvKYYCuHrknzX8VrA==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.18.0.tgz", + "integrity": "sha512-+LDwvdAp0BurOAWmeHE3uuticsq9hNxBI0+FMHiIai8jrygpJGahaQrBYWpwbshbQyVLeQgx3+YJdW2TbEdFWA==", "dev": true, "requires": { "@lerna/package": "3.16.0", @@ -3914,18 +3877,18 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "import-fresh": { @@ -4015,22 +3978,22 @@ } }, "@lerna/publish": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.16.4.tgz", - "integrity": "sha512-XZY+gRuF7/v6PDQwl7lvZaGWs8CnX6WIPIu+OCcyFPSL/rdWegdN7HieKBHskgX798qRQc2GrveaY7bNoTKXAw==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.18.2.tgz", + "integrity": "sha512-lLQOjoaFv/gc9HtOCMRsOK6NIub8eHnnvmQARjXY/HayA8GuLaD2Px9xOu1L7il+Q0LlMU3wASB9Khy/CiHJUQ==", "dev": true, "requires": { "@evocateur/libnpmaccess": "^3.1.2", "@evocateur/npm-registry-fetch": "^4.0.0", "@evocateur/pacote": "^9.6.3", - "@lerna/check-working-tree": "3.14.2", - "@lerna/child-process": "3.14.2", - "@lerna/collect-updates": "3.16.0", - "@lerna/command": "3.16.0", - "@lerna/describe-ref": "3.14.2", + "@lerna/check-working-tree": "3.16.5", + "@lerna/child-process": "3.16.5", + "@lerna/collect-updates": "3.18.0", + "@lerna/command": "3.18.0", + "@lerna/describe-ref": "3.16.5", "@lerna/log-packed": "3.16.0", "@lerna/npm-conf": "3.16.0", - "@lerna/npm-dist-tag": "3.16.0", + "@lerna/npm-dist-tag": "3.18.1", "@lerna/npm-publish": "3.16.2", "@lerna/otplease": "3.16.0", "@lerna/output": "3.13.0", @@ -4039,9 +4002,9 @@ "@lerna/prompt": "3.13.0", "@lerna/pulse-till-done": "3.13.0", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-topologically": "3.16.0", + "@lerna/run-topologically": "3.18.0", "@lerna/validation-error": "3.13.0", - "@lerna/version": "3.16.4", + "@lerna/version": "3.18.2", "figgy-pudding": "^3.5.1", "fs-extra": "^8.1.0", "npm-package-arg": "^6.1.0", @@ -4064,9 +4027,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -4093,12 +4056,12 @@ } }, "@lerna/query-graph": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.16.0.tgz", - "integrity": "sha512-p0RO+xmHDO95ChJdWkcy9TNLysLkoDARXeRHzY5U54VCwl3Ot/2q8fMCVlA5UeGXDutEyyByl3URqEpcQCWI7Q==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.18.0.tgz", + "integrity": "sha512-fgUhLx6V0jDuKZaKj562jkuuhrfVcjl5sscdfttJ8dXNVADfDz76nzzwLY0ZU7/0m69jDedohn5Fx5p7hDEVEg==", "dev": true, "requires": { - "@lerna/package-graph": "3.16.0", + "@lerna/package-graph": "3.18.0", "figgy-pudding": "^3.5.1" } }, @@ -4125,36 +4088,36 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true } } }, "@lerna/rimraf-dir": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.14.2.tgz", - "integrity": "sha512-eFNkZsy44Bu9v1Hrj5Zk6omzg8O9h/7W6QYK1TTUHeyrjTEwytaNQlqF0lrTLmEvq55sviV42NC/8P3M2cvq8Q==", + "version": "3.16.5", + "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.16.5.tgz", + "integrity": "sha512-bQlKmO0pXUsXoF8lOLknhyQjOZsCc0bosQDoX4lujBXSWxHVTg1VxURtWf2lUjz/ACsJVDfvHZbDm8kyBk5okA==", "dev": true, "requires": { - "@lerna/child-process": "3.14.2", + "@lerna/child-process": "3.16.5", "npmlog": "^4.1.2", "path-exists": "^3.0.0", "rimraf": "^2.6.2" } }, "@lerna/run": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.16.0.tgz", - "integrity": "sha512-woTeLlB1OAAz4zzjdI6RyIxSGuxiUPHJZm89E1pDEPoWwtQV6HMdMgrsQd9ATsJ5Ez280HH4bF/LStAlqW8Ufg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.18.0.tgz", + "integrity": "sha512-sblxHBZ9djaaG7wefPcfEicDqzrB7CP1m/jIB0JvPEQwG4C2qp++ewBpkjRw/mBtjtzg0t7v0nNMXzaWYrQckQ==", "dev": true, "requires": { - "@lerna/command": "3.16.0", - "@lerna/filter-options": "3.16.0", - "@lerna/npm-run-script": "3.14.2", + "@lerna/command": "3.18.0", + "@lerna/filter-options": "3.18.0", + "@lerna/npm-run-script": "3.16.5", "@lerna/output": "3.13.0", - "@lerna/run-topologically": "3.16.0", + "@lerna/run-topologically": "3.18.0", "@lerna/timer": "3.13.0", "@lerna/validation-error": "3.13.0", "p-map": "^2.1.0" @@ -4180,39 +4143,21 @@ "npmlog": "^4.1.2" } }, - "@lerna/run-parallel-batches": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/run-parallel-batches/-/run-parallel-batches-3.16.0.tgz", - "integrity": "sha512-2J/Nyv+MvogmQEfC7VcS21ifk7w0HVvzo2yOZRPvkCzGRu/rducxtB4RTcr58XCZ8h/Bt1aqQYKExu3c/3GXwg==", - "dev": true, - "requires": { - "p-map": "^2.1.0", - "p-map-series": "^1.0.0" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - } - } - }, "@lerna/run-topologically": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.16.0.tgz", - "integrity": "sha512-4Hlpv4zDtKWa5Z0tPkeu0sK+bxZEKgkNESMGmWrUCNfj7xwvAJurcraK8+a2Y0TFYwf0qjSLY/MzX+ZbJA3Cgw==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.18.0.tgz", + "integrity": "sha512-lrfEewwuUMC3ioxf9Z9NdHUakN6ihekcPfdYbzR2slmdbjYKmIA5srkWdrK8NwOpQCAuekpOovH2s8X3FGEopg==", "dev": true, "requires": { - "@lerna/query-graph": "3.16.0", + "@lerna/query-graph": "3.18.0", "figgy-pudding": "^3.5.1", "p-queue": "^4.0.0" } }, "@lerna/symlink-binary": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.16.2.tgz", - "integrity": "sha512-kz9XVoFOGSF83gg4gBqH+mG6uxfJfTp8Uy+Cam40CvMiuzfODrGkjuBEFoM/uO2QOAwZvbQDYOBpKUa9ZxHS1Q==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.17.0.tgz", + "integrity": "sha512-RLpy9UY6+3nT5J+5jkM5MZyMmjNHxZIZvXLV+Q3MXrf7Eaa1hNqyynyj4RO95fxbS+EZc4XVSk25DGFQbcRNSQ==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", @@ -4233,9 +4178,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -4247,14 +4192,14 @@ } }, "@lerna/symlink-dependencies": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.16.2.tgz", - "integrity": "sha512-wnZqGJQ+Jvr1I3inxrkffrFZfmQI7Ta8gySw/UWCy95QtZWF/f5yk8zVIocCAsjzD0wgb3jJE3CFJ9W5iwWk1A==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.17.0.tgz", + "integrity": "sha512-KmjU5YT1bpt6coOmdFueTJ7DFJL4H1w5eF8yAQ2zsGNTtZ+i5SGFBWpb9AQaw168dydc3s4eu0W0Sirda+F59Q==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", "@lerna/resolve-symlink": "3.16.0", - "@lerna/symlink-binary": "3.16.2", + "@lerna/symlink-binary": "3.17.0", "fs-extra": "^8.1.0", "p-finally": "^1.0.0", "p-map": "^2.1.0", @@ -4273,9 +4218,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "p-map": { @@ -4302,26 +4247,27 @@ } }, "@lerna/version": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.16.4.tgz", - "integrity": "sha512-ikhbMeIn5ljCtWTlHDzO4YvTmpGTX1lWFFIZ79Vd1TNyOr+OUuKLo/+p06mCl2WEdZu0W2s5E9oxfAAQbyDxEg==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.18.2.tgz", + "integrity": "sha512-nmCJpw3A2DoNGbjmvI5UB3ZwTQUayI8M/b3rOA6ZzYeGmoQmm2QBKun05aBRasqTuUo4XjSuas5CqHN+x4f8Ww==", "dev": true, "requires": { - "@lerna/check-working-tree": "3.14.2", - "@lerna/child-process": "3.14.2", - "@lerna/collect-updates": "3.16.0", - "@lerna/command": "3.16.0", + "@lerna/check-working-tree": "3.16.5", + "@lerna/child-process": "3.16.5", + "@lerna/collect-updates": "3.18.0", + "@lerna/command": "3.18.0", "@lerna/conventional-commits": "3.16.4", - "@lerna/github-client": "3.16.0", + "@lerna/github-client": "3.16.5", "@lerna/gitlab-client": "3.15.0", "@lerna/output": "3.13.0", "@lerna/prerelease-id-from-version": "3.16.0", "@lerna/prompt": "3.13.0", "@lerna/run-lifecycle": "3.16.2", - "@lerna/run-topologically": "3.16.0", + "@lerna/run-topologically": "3.18.0", "@lerna/validation-error": "3.13.0", "chalk": "^2.3.1", "dedent": "^0.7.0", + "load-json-file": "^5.3.0", "minimatch": "^3.0.4", "npmlog": "^4.1.2", "p-map": "^2.1.0", @@ -4330,15 +4276,51 @@ "p-waterfall": "^1.0.0", "semver": "^6.2.0", "slash": "^2.0.0", - "temp-write": "^3.4.0" + "temp-write": "^3.4.0", + "write-json-file": "^3.2.0" }, "dependencies": { + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + } + }, "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -4350,6 +4332,12 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true } } }, @@ -4909,9 +4897,9 @@ } }, "@parcel/logger": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.0.tgz", - "integrity": "sha512-lIRfDg+junbFUUeU0QtHX00gKCgEsYHZydFKwrJ8dc0D+WE2SYT1FcVCgpPAfKYgtg0QQMns8E9vzT9UjH92PQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.1.tgz", + "integrity": "sha512-9NF3M6UVeP2udOBDILuoEHd8VrF4vQqoWHEafymO1pfSoOMfxrSJZw1MfyAAIUN/IFp9qjcpDCUbDZB+ioVevA==", "dev": true, "requires": { "@parcel/workers": "^1.11.0", @@ -4950,13 +4938,47 @@ "dev": true }, "@parcel/watcher": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.0.tgz", - "integrity": "sha512-yijGiAqG7Tjf5WnFwOkiNWwerfZQDNABldiiqRDtr7vDWLO+F/DIncyB7tTcaD5Loevrr5mzzGo8Ntf3d2GIPg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.1.tgz", + "integrity": "sha512-od+uCtCxC/KoNQAIE1vWx1YTyKYY+7CTrxBJPRh3cDWw/C0tCtlBMVlrbplscGoEpt6B27KhJDCv82PBxOERNA==", "dev": true, "requires": { "@parcel/utils": "^1.11.0", - "chokidar": "^2.0.3" + "chokidar": "^2.1.5" + }, + "dependencies": { + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + } } }, "@parcel/workers": { @@ -7856,8 +7878,8 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^3.6.0", - "puppeteer": "^1.19.0", + "npm-package-json-lint": "^4.0.2", + "puppeteer": "^1.20.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", "resolve-bin": "^0.4.0", @@ -8031,9 +8053,9 @@ "dev": true }, "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -8308,12 +8330,20 @@ } }, "ansi-to-html": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.10.tgz", - "integrity": "sha512-znsY3gvsk4CiApWu1yVYF8Nx5Vy0FEe8B0YwyxdbCdErJu5lfKlRHB2twtUjR+dxR4WewTk2OP8XqTmWYnImOg==", + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.12.tgz", + "integrity": "sha512-qBkIqLW979675mP76yB7yVkzeAWtATegdnDQ0RA3CZzknx0yUlNxMSML4xFdBfTs2GWYFQ1FELfbGbVSPzJ+LA==", "dev": true, "requires": { - "entities": "^1.1.1" + "entities": "^1.1.2" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + } } }, "ansi-wrap": { @@ -10914,7 +10944,8 @@ "buffer-from": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true }, "buffer-xor": { "version": "1.0.3", @@ -12095,12 +12126,6 @@ "is-supported-regexp-flag": "^1.0.0" } }, - "clones": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/clones/-/clones-1.2.0.tgz", - "integrity": "sha512-FXDYw4TjR8wgPZYui2LeTqWh1BLpfQ8lB6upMtlpDF6WlOOxghmTTxWyngdKTgozqBgKnHbTVwTE+hOHqAykuQ==", - "dev": true - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -12568,9 +12593,9 @@ "dev": true }, "conventional-changelog-angular": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz", - "integrity": "sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.5.tgz", + "integrity": "sha512-RrkdWnL/TVyWV1ayWmSsrWorsTDqjL/VwG5ZSEneBQrd65ONcfeA1cW7FLtNweQyMiKOyriCMTKRSlk18DjTrw==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -12671,15 +12696,15 @@ "dev": true }, "conventional-changelog-writer": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.7.tgz", - "integrity": "sha512-p/wzs9eYaxhFbrmX/mCJNwJuvvHR+j4Fd0SQa2xyAhYed6KBiZ780LvoqUUvsayP4R1DtC27czalGUhKV2oabw==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.9.tgz", + "integrity": "sha512-2Y3QfiAM37WvDMjkVNaRtZgxVzWKj73HE61YQ/95T53yle+CRwTVSl6Gbv/lWVKXeZcM5af9n9TDVf0k7Xh+cw==", "dev": true, "requires": { "compare-func": "^1.3.1", "conventional-commits-filter": "^2.0.2", "dateformat": "^3.0.0", - "handlebars": "^4.1.2", + "handlebars": "^4.4.0", "json-stringify-safe": "^5.0.1", "lodash": "^4.2.1", "meow": "^4.0.0", @@ -12782,9 +12807,9 @@ } }, "conventional-commits-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.3.tgz", - "integrity": "sha512-KaA/2EeUkO4bKjinNfGUyqPTX/6w9JGshuQRik4r/wJz7rUw3+D3fDG6sZSEqJvKILzKXFQuFkpPLclcsAuZcg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.5.tgz", + "integrity": "sha512-qVz9+5JwdJzsbt7JbJ6P7NOXBGt8CyLFJYSjKAuPSgO+5UGfcsbk9EMR+lI8Unlvx6qwIc2YDJlrGIfay2ehNA==", "dev": true, "requires": { "JSONStream": "^1.0.4", @@ -13760,6 +13785,15 @@ "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==", "dev": true }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, "csstype": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz", @@ -13845,9 +13879,9 @@ "dev": true }, "deasync": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.14.tgz", - "integrity": "sha512-wN8sIuEqIwyQh72AG7oY6YQODCxIp1eXzEZlZznBuwDF8Q03Tdy9QNp1BNZXeadXoklNrw+Ip1fch+KXo/+ASw==", + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.15.tgz", + "integrity": "sha512-pxMaCYu8cQIbGkA4Y1R0PLSooPIpH1WgFBLeJ+zLxQgHfkZG86ViJSmZmONSjZJ/R3NjwkMcIWZAzpLB2G9/CA==", "dev": true, "requires": { "bindings": "~1.2.1", @@ -14529,9 +14563,9 @@ } }, "dotenv-expand": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz", - "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", "dev": true }, "dotenv-webpack": { @@ -14580,42 +14614,6 @@ "jsbn": "~0.1.0" } }, - "editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -15026,9 +15024,9 @@ "dev": true }, "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", "dev": true }, "es6-promisify": { @@ -16296,7 +16294,8 @@ "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true }, "figures": { "version": "2.0.0", @@ -17952,9 +17951,9 @@ } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -18476,19 +18475,153 @@ } }, "htmlnano": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.3.tgz", - "integrity": "sha512-iS6T3J5gk2wInodbtMUyAU8sLYJOhuWDnIEd8lFRoHTypVGgawPHFEx2ZIK/XTErtDfwHBsrXeCwHAP8bdoSWw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.4.tgz", + "integrity": "sha512-wsg7+Hjyi1gHpMUixkeOjeRUNhBBTnEDB//kzvVHR+LUK4p+/31DAyE+pEACT0SQk3W0KE7Xdylk9+uNxdHXLg==", "dev": true, "requires": { - "cssnano": "^4.1.9", - "normalize-html-whitespace": "^0.2.0", + "cssnano": "^4.1.10", + "normalize-html-whitespace": "^1.0.0", "object-assign": "^4.0.1", - "posthtml": "^0.11.3", - "posthtml-render": "^1.1.4", - "svgo": "^1.0.5", - "terser": "^3.16.1", - "uncss": "^0.16.2" + "posthtml": "^0.11.4", + "posthtml-render": "^1.1.5", + "svgo": "^1.2.2", + "terser": "^4.1.2", + "uncss": "^0.17.0" + }, + "dependencies": { + "css-select": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", + "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-tree": { + "version": "1.0.0-alpha.33", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", + "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.5.3" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "svgo": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", + "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.33", + "csso": "^3.5.1", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + } + }, + "terser": { + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.9.tgz", + "integrity": "sha512-NFGMpHjlzmyOtPL+fDw3G7+6Ueh/sz4mkaUYa4lJCxOPTNzd0Uj0aZJOmsDYoSQyfuVoWDMSWTPU3huyOm2zdA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + } } }, "htmlparser2": { @@ -18557,12 +18690,12 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.3.tgz", + "integrity": "sha512-Ytgnz23gm2DVftnzqRRz2dOXZbGd2uiajSw/95bPp6v53zPRspQjLm/AfBgqbJ2qfeRXWIOMVLpp86+/5yX39Q==", "dev": true, "requires": { - "agent-base": "^4.1.0", + "agent-base": "^4.3.0", "debug": "^3.1.0" } }, @@ -18992,9 +19125,9 @@ } }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -19029,7 +19162,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "in-publish": { "version": "2.0.0", @@ -19049,12 +19183,6 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -19099,9 +19227,9 @@ }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -19514,15 +19642,6 @@ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true }, - "is-path-inside": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.0.0.tgz", - "integrity": "sha512-OmUXvSq+P7aI/aRbl1dzwdlyLn8vW7Nr2/11S7y/dcLLgnQ89hgYJp7tfc+A5SRid3rNCLpruOp2CAV68/iOcA==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -21043,45 +21162,6 @@ "integrity": "sha512-O9SR2NVICx6rCqh1qsU91QZ5IoNa+2T1ROJ0OQlfvATKGmnjsAvg3r0E5ufPZ4a95jdKTPXhFWiE/sOZ7a5Rtg==", "dev": true }, - "js-beautify": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.9.1.tgz", - "integrity": "sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ==", - "dev": true, - "requires": { - "config-chain": "^1.1.12", - "editorconfig": "^0.15.2", - "glob": "^7.1.3", - "mkdirp": "~0.5.0", - "nopt": "~4.0.1" - }, - "dependencies": { - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, "js-levenshtein": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.3.tgz", @@ -21383,26 +21463,26 @@ "dev": true }, "lerna": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.16.4.tgz", - "integrity": "sha512-0HfwXIkqe72lBLZcNO9NMRfylh5Ng1l8tETgYQ260ZdHRbPuaLKE3Wqnd2YYRRkWfwPyEyZO8mZweBR+slVe1A==", - "dev": true, - "requires": { - "@lerna/add": "3.16.2", - "@lerna/bootstrap": "3.16.2", - "@lerna/changed": "3.16.4", - "@lerna/clean": "3.16.0", - "@lerna/cli": "3.13.0", - "@lerna/create": "3.16.0", - "@lerna/diff": "3.16.0", - "@lerna/exec": "3.16.0", - "@lerna/import": "3.16.0", - "@lerna/init": "3.16.0", - "@lerna/link": "3.16.2", - "@lerna/list": "3.16.0", - "@lerna/publish": "3.16.4", - "@lerna/run": "3.16.0", - "@lerna/version": "3.16.4", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.18.2.tgz", + "integrity": "sha512-XznkKk2LY9HxaH+AtqyNZq7A0f9mMuv1OUeJBjJdl2oEZQPedWrmZNK6DuJNcyjjRJk6B9Xvb8eqIpe5aCHy1w==", + "dev": true, + "requires": { + "@lerna/add": "3.18.0", + "@lerna/bootstrap": "3.18.0", + "@lerna/changed": "3.18.2", + "@lerna/clean": "3.18.0", + "@lerna/cli": "3.18.0", + "@lerna/create": "3.18.0", + "@lerna/diff": "3.18.0", + "@lerna/exec": "3.18.0", + "@lerna/import": "3.18.0", + "@lerna/init": "3.18.0", + "@lerna/link": "3.18.0", + "@lerna/list": "3.18.0", + "@lerna/publish": "3.18.2", + "@lerna/run": "3.18.0", + "@lerna/version": "3.18.2", "import-local": "^2.0.0", "npmlog": "^4.1.2" } @@ -22324,15 +22404,15 @@ }, "dependencies": { "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", "dev": true }, "cacache": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", - "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", "dev": true, "requires": { "bluebird": "^3.5.5", @@ -22353,15 +22433,15 @@ } }, "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -22373,9 +22453,9 @@ } }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "lru-cache": { @@ -22416,9 +22496,9 @@ } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" @@ -22449,9 +22529,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } @@ -23659,9 +23739,9 @@ } }, "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true }, "mime-db": { @@ -24093,9 +24173,9 @@ } }, "node-addon-api": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.6.2.tgz", - "integrity": "sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", + "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", "dev": true }, "node-dir": { @@ -24168,9 +24248,9 @@ "dev": true }, "node-libs-browser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", - "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "dev": true, "requires": { "assert": "^1.1.1", @@ -24183,7 +24263,7 @@ "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", + "path-browserify": "0.0.1", "process": "^0.11.10", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", @@ -24195,7 +24275,7 @@ "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.11.0", - "vm-browserify": "0.0.4" + "vm-browserify": "^1.0.1" }, "dependencies": { "punycode": { @@ -24700,9 +24780,9 @@ } }, "normalize-html-whitespace": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-0.2.0.tgz", - "integrity": "sha1-EBci9kI1Ucdc24+dEE/4UNrx4Q4=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz", + "integrity": "sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA==", "dev": true }, "normalize-package-data": { @@ -24759,9 +24839,9 @@ "dev": true }, "npm-lifecycle": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.2.tgz", - "integrity": "sha512-nhfOcoTHrW1lJJlM2o77vTE2RWR4YOVyj7YzmY0y5itsMjEuoJHteio/ez0BliENEPsNxIUQgwhyEW9dShj3Ww==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.4.tgz", + "integrity": "sha512-tgs1PaucZwkxECGKhC/stbEgFyc3TGh2TJcg2CDr6jbvQRdteHNhmMeljRzpe4wgFAXQADoy1cSqqi7mtiAa5A==", "dev": true, "requires": { "byline": "^5.0.0", @@ -24775,21 +24855,31 @@ }, "dependencies": { "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, "node-gyp": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.3.tgz", - "integrity": "sha512-z/JdtkFGUm0QaQUusvloyYuGDub3nUbOo5de1Fz57cM++osBTvQatBUSTlF1k/w8vFHPxxXW6zxGvkxXSpaBkQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.5.tgz", + "integrity": "sha512-WABl9s4/mqQdZneZHVWVG4TVr6QQJZUC6PAx47ITSk9lreZ1n+7Z9mMAIbA3vnO4J9W20P7LhCxtzfWsAD/KDw==", "dev": true, "requires": { "env-paths": "^1.0.0", @@ -24801,7 +24891,7 @@ "request": "^2.87.0", "rimraf": "2", "semver": "~5.3.0", - "tar": "^4.4.8", + "tar": "^4.4.12", "which": "1" } }, @@ -24818,14 +24908,14 @@ "dev": true }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", + "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", @@ -24833,87 +24923,139 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "npm-package-arg": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", - "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { - "hosted-git-info": "^2.6.0", + "hosted-git-info": "^2.7.1", "osenv": "^0.1.5", - "semver": "^5.5.0", + "semver": "^5.6.0", "validate-npm-package-name": "^3.0.0" }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "npm-package-json-lint": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-3.6.0.tgz", - "integrity": "sha512-N1y3r0l0oN7mYnMfRzZvYF8+NvjIx+zkskRn3J7ofipJKGH4RDDKdEGP/mV1Crf5W8uUo3201VhJe04Q+v9erw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-4.0.2.tgz", + "integrity": "sha512-xlahvfRgZcsawUPzKaJvcQSs4K0EzDgQ9YEe7VODo1XbLMWwS0IEXiywHlKPAvo1fmWBvovIdoAqhe0Gk4InHA==", "dev": true, "requires": { - "ajv": "^6.9.2", + "ajv": "^6.10.2", + "ajv-errors": "^1.0.1", "chalk": "^2.4.2", - "glob": "^7.1.3", - "ignore": "^5.0.5", - "is-path-inside": "^2.0.0", - "is-plain-obj": "^1.1.0", - "is-resolvable": "^1.1.0", - "log-symbols": "^2.2.0", + "cosmiconfig": "^5.2.1", + "debug": "^4.1.1", + "globby": "^10.0.1", + "ignore": "^5.1.4", + "is-plain-obj": "^2.0.0", + "log-symbols": "^3.0.0", "meow": "^5.0.0", - "plur": "^3.0.1", - "semver": "^5.6.0", - "strip-json-comments": "^2.0.1", - "validator": "^10.11.0" + "plur": "^3.1.1", + "semver": "^6.3.0", + "strip-json-comments": "^3.0.1" }, "dependencies": { - "ajv": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz", - "integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==", + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fill-range": "^7.0.1" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" } }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", + "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -24924,23 +25066,135 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, "ignore": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.0.5.tgz", - "integrity": "sha512-kOC8IUb8HSDMVcYrDVezCxpJkzSQWTAzf3olpKM6o9rM5zpojx23O0Fl8Wr4+qJ6ZbPEHqf1fdwev/DS7v7pmA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.0.0.tgz", + "integrity": "sha512-EYisGhpgSCwspmIuRHGjROWTon2Xp8Z7U03Wubk/bTL5TTRC5R1rGVgyjzBrk9+ULdH6cRD06KRcw/xfqhVYKQ==", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, @@ -24955,9 +25209,9 @@ } }, "npm-pick-manifest": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz", - "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", + "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -24966,9 +25220,9 @@ }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -25019,6 +25273,12 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, + "nwsapi": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", + "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -25540,28 +25800,28 @@ } }, "parcel-bundler": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.3.tgz", - "integrity": "sha512-8bq6lj0hhQeGxD9f9xEkFMXQ3d8TIlf2+isKxoi9bciB0KVEILRGllaPkUgp++5t0anToBh9+tG6ZyInXOC1/A==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0 <7.4.0", - "@babel/core": "^7.0.0 <7.4.0", - "@babel/generator": "^7.0.0 <7.4.0", - "@babel/parser": "^7.0.0 <7.4.0", - "@babel/plugin-transform-flow-strip-types": "^7.0.0 <7.4.0", - "@babel/plugin-transform-modules-commonjs": "^7.0.0 <7.4.0", - "@babel/plugin-transform-react-jsx": "^7.0.0 <7.4.0", - "@babel/preset-env": "^7.0.0 <7.4.0", - "@babel/runtime": "^7.0.0 <7.4.0", - "@babel/template": "^7.0.0 <7.4.0", - "@babel/traverse": "^7.0.0 <7.4.0", - "@babel/types": "^7.0.0 <7.4.0", + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.4.tgz", + "integrity": "sha512-G+iZGGiPEXcRzw0fiRxWYCKxdt/F7l9a0xkiU4XbcVRJCSlBnioWEwJMutOCCpoQmaQtjB4RBHDGIHN85AIhLQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.4.4", + "@babel/generator": "^7.4.4", + "@babel/parser": "^7.4.4", + "@babel/plugin-transform-flow-strip-types": "^7.4.4", + "@babel/plugin-transform-modules-commonjs": "^7.4.4", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/preset-env": "^7.4.4", + "@babel/runtime": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4", "@iarna/toml": "^2.2.0", "@parcel/fs": "^1.11.0", - "@parcel/logger": "^1.11.0", + "@parcel/logger": "^1.11.1", "@parcel/utils": "^1.11.0", - "@parcel/watcher": "^1.12.0", + "@parcel/watcher": "^1.12.1", "@parcel/workers": "^1.11.0", "ansi-to-html": "^0.6.4", "babylon-walk": "^1.0.2", @@ -25570,12 +25830,14 @@ "clone": "^2.1.1", "command-exists": "^1.2.6", "commander": "^2.11.0", + "core-js": "^2.6.5", "cross-spawn": "^6.0.4", "css-modules-loader-core": "^1.1.0", "cssnano": "^4.0.0", "deasync": "^0.1.14", "dotenv": "^5.0.0", - "dotenv-expand": "^4.2.0", + "dotenv-expand": "^5.1.0", + "envinfo": "^7.3.1", "fast-glob": "^2.2.2", "filesize": "^3.6.0", "get-port": "^3.2.0", @@ -25596,7 +25858,7 @@ "posthtml-render": "^1.1.3", "resolve": "^1.4.0", "semver": "^5.4.1", - "serialize-to-js": "^1.1.1", + "serialize-to-js": "^3.0.0", "serve-static": "^1.12.4", "source-map": "0.6.1", "terser": "^3.7.3", @@ -25604,180 +25866,14 @@ "ws": "^5.1.1" }, "dependencies": { - "@babel/core": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", - "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.3.4", - "@babel/helpers": "^7.2.0", - "@babel/parser": "^7.3.4", - "@babel/template": "^7.2.2", - "@babel/traverse": "^7.3.4", - "@babel/types": "^7.3.4", - "convert-source-map": "^1.1.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.11", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", - "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.3.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/parser": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", - "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", - "dev": true - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", - "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" - } - }, - "@babel/preset-env": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.4.tgz", - "integrity": "sha512-2mwqfYMK8weA0g0uBKOt4FE3iEodiHy9/CW0b+nWXcbL+pGzLx8ESYc+j9IIxr6LTDHWKgPm71i9smo02bw+gA==", + "@babel/plugin-transform-flow-strip-types": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz", + "integrity": "sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.3.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.3.4", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.3.4", - "@babel/plugin-transform-classes": "^7.3.4", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.2.0", - "@babel/plugin-transform-dotall-regex": "^7.2.0", - "@babel/plugin-transform-duplicate-keys": "^7.2.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.2.0", - "@babel/plugin-transform-function-name": "^7.2.0", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", - "@babel/plugin-transform-modules-systemjs": "^7.3.4", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", - "@babel/plugin-transform-new-target": "^7.0.0", - "@babel/plugin-transform-object-super": "^7.2.0", - "@babel/plugin-transform-parameters": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.3.4", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.2.0", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.2.0", - "browserslist": "^4.3.4", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.3.0" - } - }, - "@babel/runtime": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.4.tgz", - "integrity": "sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.12.0" - } - }, - "@babel/template": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", - "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.2.2", - "@babel/types": "^7.2.2" - } - }, - "@babel/traverse": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", - "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.3.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.3.4", - "@babel/types": "^7.3.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } - }, - "@babel/types": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", - "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" + "@babel/plugin-syntax-flow": "^7.2.0" } }, "clone": { @@ -25786,6 +25882,12 @@ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, + "core-js": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", + "dev": true + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -25799,21 +25901,6 @@ "which": "^1.2.9" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -25823,28 +25910,16 @@ "minimist": "^1.2.0" } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, "postcss-value-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", - "dev": true - }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "source-map": { @@ -25972,9 +26047,9 @@ "dev": true }, "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, "path-dirname": { @@ -25994,12 +26069,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -26202,9 +26271,9 @@ } }, "plur": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.0.1.tgz", - "integrity": "sha512-lJl0ojUynAM1BZn58Pas2WT/TXeC1+bS+UqShl0x9+49AtOn7DixRXVzaC8qrDOIxNDmepKnLuMTH7NQmkX0PA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", + "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", "dev": true, "requires": { "irregular-plurals": "^2.0.0" @@ -27171,36 +27240,13 @@ "dev": true }, "posthtml": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.3.tgz", - "integrity": "sha512-quMHnDckt2DQ9lRi6bYLnuyBDnVzK+McHa8+ar4kTdYbWEo/92hREOu3h70ZirudOOp/my2b3r0m5YtxY52yrA==", + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.6.tgz", + "integrity": "sha512-C2hrAPzmRdpuL3iH0TDdQ6XCc9M7Dcc3zEW5BLerY65G4tWWszwv6nG/ksi6ul5i2mx22ubdljgktXCtNkydkw==", "dev": true, "requires": { - "object-assign": "^4.1.1", - "posthtml-parser": "^0.3.3", - "posthtml-render": "^1.1.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "posthtml-parser": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.3.3.tgz", - "integrity": "sha512-H/Z/yXGwl49A7hYQLV1iQ3h87NE0aZ/PMZhFwhw3lKeCAN+Ti4idrHvVvh4/GX10I7u77aQw+QB4vV5/Lzvv5A==", - "dev": true, - "requires": { - "htmlparser2": "^3.9.2", - "isobject": "^2.1.0", - "object-assign": "^4.1.1" - } - } + "posthtml-parser": "^0.4.1", + "posthtml-render": "^1.1.5" } }, "posthtml-parser": { @@ -27214,9 +27260,9 @@ } }, "posthtml-render": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.4.tgz", - "integrity": "sha512-jL6eFIzoN3xUEvbo33OAkSDE2VIKU4JQ1wENOows1DpfnrdapR/K3Q1/fB43Mq7wQlcSgRm23nFrvoioufM7eA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz", + "integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w==", "dev": true }, "prelude-ls": { @@ -27619,9 +27665,9 @@ "dev": true }, "puppeteer": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.19.0.tgz", - "integrity": "sha512-2S6E6ygpoqcECaagDbBopoSOPDv0pAZvTbnBgUY+6hq0/XDFDOLEMNlHF/SKJlzcaZ9ckiKjKDuueWI3FN/WXw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", "dev": true, "requires": { "debug": "^4.1.0", @@ -29088,18 +29134,18 @@ } }, "read-cmd-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz", - "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.4.tgz", + "integrity": "sha512-Pqpl3qJ/QdOIjRYA0q5DND/gLvGOfpIz/fYVDGYpOXfW/lFrIttmLsBnd6IkyK10+JHU9zhsaudfvrQTBB9YFQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2" } }, "read-package-json": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.13.tgz", - "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.0.tgz", + "integrity": "sha512-KLhu8M1ZZNkMcrq1+0UJbR8Dii8KZUqB0Sha4mOx/bknfKI/fyrQVrG/YIt2UOtG667sD8+ee4EXMM91W9dC+A==", "dev": true, "requires": { "glob": "^7.1.1", @@ -29361,202 +29407,6 @@ "safe-regex": "^1.1.0" } }, - "regexp-tree": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.1.tgz", - "integrity": "sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw==", - "dev": true, - "requires": { - "cli-table3": "^0.5.0", - "colors": "^1.1.2", - "yargs": "^12.0.5" - }, - "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, - "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mem": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", - "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^2.0.0" - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-is-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", - "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", - "dev": true - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, "regexp.prototype.flags": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", @@ -30338,15 +30188,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "safer-eval": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/safer-eval/-/safer-eval-1.3.5.tgz", - "integrity": "sha512-BJ//K2Y+EgCbOHEsDGS5YahYBcYy7JcFpKDo2ba5t4MnOGHYtk7HvQkcxTDFvjQvJ0CRcdas/PyF+gTTCay+3w==", - "dev": true, - "requires": { - "clones": "^1.2.0" - } - }, "sane": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", @@ -30559,6 +30400,15 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "requires": { + "xmlchars": "^2.1.1" + } + }, "scheduler": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", @@ -30668,14 +30518,10 @@ "dev": true }, "serialize-to-js": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-1.2.2.tgz", - "integrity": "sha512-mUc8vA5iJghe+O+3s0YDGFLMJcqitVFk787YKiv8a4sf6RX5W0u81b+gcHrp15O0fFa010dRBVZvwcKXOWsL9Q==", - "dev": true, - "requires": { - "js-beautify": "^1.8.9", - "safer-eval": "^1.3.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.0.0.tgz", + "integrity": "sha512-WdGgi0jGnWCQXph2p3vkxceDnTfvfyXfYxherQMRcZjSaJzMQdMBAW6i0nojsBKIZ3fFOztZKKVbbm05VbIdRA==", + "dev": true }, "serve-favicon": { "version": "2.5.0", @@ -30895,12 +30741,6 @@ } } }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -31193,6 +31033,17 @@ "requires": { "agent-base": "~4.2.1", "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } } }, "sort-keys": { @@ -31207,7 +31058,8 @@ "source-list-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==" + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true }, "source-map": { "version": "0.5.7", @@ -32654,69 +32506,11 @@ "source-map-support": "~0.5.10" }, "dependencies": { - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "terser": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz", - "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -33583,42 +33377,146 @@ "dev": true }, "uncss": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.16.2.tgz", - "integrity": "sha1-OyJpxZAS2nxmy+mPvt3e75TwZJw=", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.17.2.tgz", + "integrity": "sha512-hu2HquwDItuGDem4YsJROdAD8SknmWtM24zwhQax6J1se8tPjV1cnwPKhtjodzBaUhaL8Zb3hlGdZ2WAUpbAOg==", "dev": true, "requires": { - "commander": "^2.9.0", - "glob": "^7.0.3", - "is-absolute-url": "^2.0.0", - "is-html": "^1.0.0", - "jsdom": "^11.3.0", - "lodash": "^4.13.1", - "postcss": "^6.0.14", - "postcss-selector-parser": "3.1.1", - "request": "^2.72.0" + "commander": "^2.20.0", + "glob": "^7.1.4", + "is-absolute-url": "^3.0.1", + "is-html": "^1.1.0", + "jsdom": "^14.1.0", + "lodash": "^4.17.15", + "postcss": "^7.0.17", + "postcss-selector-parser": "6.0.2", + "request": "^2.88.0" }, "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "abab": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz", + "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==", + "dev": true + }, + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" } }, - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "escodegen": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", + "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "jsdom": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", + "integrity": "sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.1.3", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "postcss": { + "version": "7.0.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz", + "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" } }, "source-map": { @@ -33626,6 +33524,60 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } } } }, @@ -33750,6 +33702,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "dev": true, "requires": { "imurmurhash": "^0.1.4" } @@ -34088,9 +34041,9 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", - "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "dev": true }, "validate-npm-package-license": { @@ -34112,12 +34065,6 @@ "builtins": "^1.0.3" } }, - "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", - "dev": true - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -34189,13 +34136,10 @@ "dev": true }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true }, "w3c-hr-time": { "version": "1.0.1", @@ -34206,6 +34150,17 @@ "browser-process-hrtime": "^0.1.2" } }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, "wait-on": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.3.0.tgz", @@ -35176,9 +35131,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "make-dir": { @@ -35198,9 +35153,9 @@ "dev": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -35289,6 +35244,12 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "xmldoc": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-0.4.0.tgz", diff --git a/package.json b/package.json index 473a7bfe852317..0a89a1c82b37d1 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "jest-junit": "6.4.0", "jest-serializer-enzyme": "1.0.0", "jsdom": "11.12.0", - "lerna": "3.16.4", + "lerna": "3.18.2", "lint-staged": "9.2.5", "lodash": "4.17.15", "make-dir": "3.0.0", @@ -131,9 +131,11 @@ "mkdirp": "0.5.1", "node-sass": "4.12.0", "node-watch": "0.6.0", - "parcel-bundler": "1.12.3", + "npm-package-json-lint": "4.0.2", + "parcel-bundler": "1.12.4", "postcss": "7.0.13", "progress": "2.0.3", + "puppeteer": "1.20.0", "react": "16.9.0", "react-dom": "16.9.0", "react-native": "0.60.0", @@ -154,34 +156,6 @@ "webpack": "4.41.0", "worker-farm": "1.7.0" }, - "npmPackageJsonLintConfig": { - "extends": "@wordpress/npm-package-json-lint-config", - "rules": { - "description-format": [ - "error", - { - "requireCapitalFirstLetter": true, - "requireEndingPeriod": true - } - ], - "require-publishConfig": "error", - "require-repository-directory": "error", - "valid-values-author": [ - "error", - [ - "The WordPress Contributors" - ] - ], - "valid-values-publishConfig": [ - "error", - [ - { - "access": "public" - } - ] - ] - } - }, "scripts": { "prebuild": "npm run check-engines", "clean:packages": "rimraf ./packages/*/build ./packages/*/build-module ./packages/*/build-style ./packages/*/node_modules", @@ -204,7 +178,7 @@ "lint-js": "wp-scripts lint-js", "lint-js:fix": "npm run lint-js -- --fix", "lint-php": "wp-scripts env lint-php", - "lint-pkg-json": "wp-scripts lint-pkg-json ./packages", + "lint-pkg-json": "wp-scripts lint-pkg-json . 'packages/*/package.json'", "lint-css": "wp-scripts lint-style '**/*.scss'", "lint-css:fix": "npm run lint-css -- --fix", "lint-types": "tsc", diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 3d137bfb2b9fbc..17d28946b2bc0d 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -1,3 +1,13 @@ +## Master + +### Breaking Changes + +- The bundled `npm-package-json-lint` dependency has been updated from requiring `^3.6.0` to requiring `^4.0.2` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). Please see the [migration guide](https://npmpackagejsonlint.org/docs/en/v3-to-v4). Note: `npmPackageJsonLintConfig` prop in the `package.json` file needs to be renamed to `npmpackagejsonlint`. + +### New Features + +- The bundled `puppeteer` dependency has been updated from requiring `^1.19.0` to requiring `^1.20.0` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). It uses Chromium v78 instead of Chromium v77. + ## 5.1.0 ### New Features diff --git a/packages/scripts/package.json b/packages/scripts/package.json index fe37347258d872..20c95f9782c61d 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -50,8 +50,8 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^3.6.0", - "puppeteer": "^1.19.0", + "npm-package-json-lint": "^4.0.2", + "puppeteer": "^1.20.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", "resolve-bin": "^0.4.0", diff --git a/packages/scripts/scripts/lint-pkg-json.js b/packages/scripts/scripts/lint-pkg-json.js index 487a8191067dbc..53e9c42b366437 100644 --- a/packages/scripts/scripts/lint-pkg-json.js +++ b/packages/scripts/scripts/lint-pkg-json.js @@ -25,6 +25,8 @@ const hasLintConfig = hasArgInCLI( '-c' ) || hasArgInCLI( '--configFile' ) || hasProjectFile( '.npmpackagejsonlintrc.json' ) || hasProjectFile( 'npmpackagejsonlint.config.js' ) || + hasPackageProp( 'npmpackagejsonlint' ) || + // npm-package-json-lint v3.x used a different prop name. hasPackageProp( 'npmPackageJsonLintConfig' ); const defaultConfigArgs = ! hasLintConfig ? From 869ac8de003d591e50c1c76210f879cd6d28a7b3 Mon Sep 17 00:00:00 2001 From: Jonathan Goldford <jonathan@wiredimpact.com> Date: Tue, 22 Oct 2019 05:43:51 -0500 Subject: [PATCH 047/113] Fix issue when providing multiple shortcode aliases for a new block (#17925) * Fix issue where providing multiple shortcode aliases to transform into a block only matches the first shortcode * Add test to ensure blocks can transform using multiple shortcode aliases * Simplify the approach used to find the individual shortcode being transformed Props jg314 --- .../api/raw-handling/shortcode-converter.js | 4 +- test/integration/shortcode-converter.test.js | 41 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/blocks/src/api/raw-handling/shortcode-converter.js b/packages/blocks/src/api/raw-handling/shortcode-converter.js index 5385f0aed41502..10f1159c92cb0c 100644 --- a/packages/blocks/src/api/raw-handling/shortcode-converter.js +++ b/packages/blocks/src/api/raw-handling/shortcode-converter.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { some, castArray, first, mapValues, pickBy, includes } from 'lodash'; +import { some, castArray, find, mapValues, pickBy, includes } from 'lodash'; /** * WordPress dependencies @@ -29,7 +29,7 @@ function segmentHTMLToShortcodeBlock( HTML, lastIndex = 0 ) { } const transformTags = castArray( transformation.tag ); - const transformTag = first( transformTags ); + const transformTag = find( transformTags, ( tag ) => regexp( tag ).test( HTML ) ); let match; diff --git a/test/integration/shortcode-converter.test.js b/test/integration/shortcode-converter.test.js index 2f0e5ab632fa74..1b0ce7c30947d9 100644 --- a/test/integration/shortcode-converter.test.js +++ b/test/integration/shortcode-converter.test.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { registerCoreBlocks } from '@wordpress/block-library'; -import { createBlock } from '@wordpress/blocks'; +import { createBlock, registerBlockType } from '@wordpress/blocks'; /** * Internal dependencies @@ -12,6 +12,34 @@ import segmentHTMLToShortcodeBlock from '../../packages/blocks/src/api/raw-handl describe( 'segmentHTMLToShortcodeBlock', () => { beforeAll( () => { registerCoreBlocks(); + registerBlockType( 'test/gallery', { + title: 'Test Gallery', + category: 'common', + attributes: { + ids: { + type: 'array', + default: [], + }, + }, + transforms: { + from: [ + { + type: 'shortcode', + tag: [ 'my-gallery', 'my-bunch-of-images' ], + attributes: { + ids: { + type: 'array', + shortcode: ( { named: { ids } } ) => + ids.split( ',' ).map( ( id ) => ( + parseInt( id, 10 ) + ) ), + }, + }, + }, + ], + }, + save: () => null, + } ); } ); it( 'should convert a standalone shortcode between two paragraphs', () => { @@ -101,4 +129,15 @@ describe( 'segmentHTMLToShortcodeBlock', () => { expect( transformed[ 8 ] ).toEqual( '</p>' ); expect( transformed ).toHaveLength( 9 ); } ); + + it( 'should convert regardless of shortcode alias', () => { + const original = `<p>[my-gallery ids="1,2,3"]</p> +<p>[my-bunch-of-images ids="4,5,6"]</p>`; + const transformed = segmentHTMLToShortcodeBlock( original, 0 ); + expect( transformed[ 0 ] ).toBe( '<p>' ); + expect( transformed[ 1 ] ).toHaveProperty( 'name', 'test/gallery' ); + expect( transformed[ 2 ] ).toBe( '</p>\n<p>' ); + expect( transformed[ 3 ] ).toHaveProperty( 'name', 'test/gallery' ); + expect( transformed[ 4 ] ).toBe( '</p>' ); + } ); } ); From 6ab0e323531bf4b0b03aaee58e02a611fc74d16b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Tue, 22 Oct 2019 12:55:17 +0200 Subject: [PATCH 048/113] Chore: Update the lock file to use newer version of fsevents (#18057) This fixes the issues when `npm install` on macOS throws several errors. --- package-lock.json | 684 +++------------------------------------------- package.json | 2 - 2 files changed, 32 insertions(+), 654 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5ac18b619edc25..c71a6f8db2f425 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4945,40 +4945,6 @@ "requires": { "@parcel/utils": "^1.11.0", "chokidar": "^2.1.5" - }, - "dependencies": { - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - } } }, "@parcel/workers": { @@ -11279,9 +11245,9 @@ } }, "chokidar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.1.tgz", - "integrity": "sha512-gfw3p2oQV2wEt+8VuMlNsPjCxDxvvgnm/kz+uATu805mWVF8IJN7uz9DN7iBz+RMJISmiVbCOBFs9qBGMjtPfQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -11295,599 +11261,20 @@ "normalize-path": "^3.0.0", "path-is-absolute": "^1.0.0", "readdirp": "^2.2.1", - "upath": "^1.1.0" + "upath": "^1.1.1" }, "dependencies": { - "fsevents": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", - "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true } } }, @@ -16806,14 +16193,14 @@ "dev": true }, "fsevents": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", - "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -16891,12 +16278,12 @@ "optional": true }, "debug": { - "version": "2.6.9", + "version": "4.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-extend": { @@ -17067,24 +16454,31 @@ } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", "bundled": true, "dev": true, "optional": true }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, "needle": { - "version": "2.2.4", + "version": "2.3.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "^2.1.2", + "debug": "^4.1.0", "iconv-lite": "^0.4.4", "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.10.3", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true, @@ -17112,13 +16506,13 @@ } }, "npm-bundled": { - "version": "1.0.5", + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.2.0", + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, @@ -17208,8 +16602,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "dev": true, "optional": true } @@ -17258,7 +16651,7 @@ "optional": true }, "semver": { - "version": "5.6.0", + "version": "5.7.0", "bundled": true, "dev": true, "optional": true @@ -24064,13 +23457,6 @@ "thenify-all": "^1.0.0" } }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -33869,12 +33255,6 @@ } } }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true - }, "upper-case": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", diff --git a/package.json b/package.json index 0a89a1c82b37d1..6c3d854c3355cd 100644 --- a/package.json +++ b/package.json @@ -131,11 +131,9 @@ "mkdirp": "0.5.1", "node-sass": "4.12.0", "node-watch": "0.6.0", - "npm-package-json-lint": "4.0.2", "parcel-bundler": "1.12.4", "postcss": "7.0.13", "progress": "2.0.3", - "puppeteer": "1.20.0", "react": "16.9.0", "react-dom": "16.9.0", "react-native": "0.60.0", From 03414de9995870109f3f6e0e1c88605a0353aaf3 Mon Sep 17 00:00:00 2001 From: Enrique Piqueras <epiqueras@users.noreply.github.com> Date: Tue, 22 Oct 2019 13:18:20 -0700 Subject: [PATCH 049/113] Env: Add support for custom ports. (#17697) --- packages/env/.npmrc | 1 + packages/env/README.md | 17 +++++++++++------ packages/env/lib/cli.js | 4 ++-- .../env/lib/create-docker-compose-config.js | 6 +++--- packages/env/lib/env.js | 8 +++++--- packages/env/package.json | 2 +- 6 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 packages/env/.npmrc diff --git a/packages/env/.npmrc b/packages/env/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/env/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/env/README.md b/packages/env/README.md index 45736ee1fa29bb..9be3fe8e36709c 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -15,8 +15,10 @@ wp-env <command> Commands: wp-env start [ref] Starts WordPress for development on port 8888 - (​http://localhost:8888​) and tests on port 8889 - (​http://localhost:8889​). If the current working + (​http://localhost:8888​) (override with + WP_ENV_PORT) and tests on port 8889 + (​http://localhost:8889​) (override with + WP_ENV_TESTS_PORT). If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately. @@ -34,10 +36,11 @@ Options: ```sh wp-env start [ref] -Starts WordPress for development on port 8888 (​http://localhost:8888​) and -tests on port 8889 (​http://localhost:8889​). If the current working directory -is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be -mounted appropiately. +Starts WordPress for development on port 8888 (​http://localhost:8888​) +(override with WP_ENV_PORT) and tests on port 8889 (​http://localhost:8889​) +(override with WP_ENV_TESTS_PORT). If the current working directory is a plugin +and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted +appropiately. Positionals: ref A `https://github.com/WordPress/WordPress` git repo branch or commit for @@ -63,3 +66,5 @@ Positionals: environment Which environments' databases to clean. [string] [choices: "all", "development", "tests"] [default: "tests"] ``` + +<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p> diff --git a/packages/env/lib/cli.js b/packages/env/lib/cli.js index 6f134afd9ae421..98dc1ecb42ce26 100644 --- a/packages/env/lib/cli.js +++ b/packages/env/lib/cli.js @@ -46,10 +46,10 @@ module.exports = function cli() { chalk`Starts WordPress for development on port {bold.underline ${ terminalLink( '8888', 'http://localhost:8888' - ) }} and tests on port {bold.underline ${ terminalLink( + ) }} (override with WP_ENV_PORT) and tests on port {bold.underline ${ terminalLink( '8889', 'http://localhost:8889' - ) }}. If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately.` + ) }} (override with WP_ENV_TESTS_PORT). If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropiately.` ), ( args ) => { args.positional( 'ref', { diff --git a/packages/env/lib/create-docker-compose-config.js b/packages/env/lib/create-docker-compose-config.js index 7a3dfc7d33b6aa..6cc4b8ddfabf1d 100644 --- a/packages/env/lib/create-docker-compose-config.js +++ b/packages/env/lib/create-docker-compose-config.js @@ -11,7 +11,7 @@ module.exports = function createDockerComposeConfig( - ${ pluginPath }/../${ pluginName }-wordpress/:/var/www/html/${ commonVolumes }`; const testsVolumes = ` - tests-wordpress:/var/www/html/${ commonVolumes }`; - return `version: '2' + return `version: '2.1' volumes: tests-wordpress: services: @@ -28,7 +28,7 @@ services: WORDPRESS_DB_PASSWORD: password image: wordpress ports: - - 8888:80 + - \${WP_ENV_PORT:-8888}:80 volumes:${ volumes } wordpress-cli: depends_on: @@ -44,7 +44,7 @@ services: WORDPRESS_DB_PASSWORD: password image: wordpress ports: - - 8889:80 + - \${WP_ENV_TESTS_PORT:-8889}:80 volumes:${ testsVolumes } tests-wordpress-cli: depends_on: diff --git a/packages/env/lib/env.js b/packages/env/lib/env.js index 159bb2ac2fc45f..3b982c0e143f56 100644 --- a/packages/env/lib/env.js +++ b/packages/env/lib/env.js @@ -30,9 +30,11 @@ const wpCliRun = ( command, isTests = false ) => ); const setupSite = ( isTests = false ) => wpCliRun( - `wp core install --url=localhost:888${ - isTests ? '9' : '8' - } --title=Gutenberg --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, + `wp core install --url=localhost:${ + isTests ? + process.env.WP_ENV_TESTS_PORT || 8889 : + process.env.WP_ENV_PORT || 8888 + } --title=${ pluginName } --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, isTests ); const activatePlugin = ( isTests = false ) => diff --git a/packages/env/package.json b/packages/env/package.json index 6be0539b3725cf..19f0fe52cdc047 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/env", - "version": "1.0.0", + "version": "0.0.0", "description": "A zero-config, self contained local WordPress environment for development and testing.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From d5d66a8b34de70a1290661082bf79ac104b56ac6 Mon Sep 17 00:00:00 2001 From: Manzoor Wani <manzoorwani.jk@gmail.com> Date: Wed, 23 Oct 2019 04:08:56 +0530 Subject: [PATCH 050/113] Add isInvalidDate prop to DatePicker (#17498) --- packages/components/src/date-time/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/components/src/date-time/index.js b/packages/components/src/date-time/index.js index 97bd891cac9a7c..bb7434d2e82ce3 100644 --- a/packages/components/src/date-time/index.js +++ b/packages/components/src/date-time/index.js @@ -34,7 +34,7 @@ export class DateTimePicker extends Component { } render() { - const { currentDate, is12Hour, onChange } = this.props; + const { currentDate, is12Hour, isInvalidDate, onChange } = this.props; return ( <div className="components-datetime"> @@ -48,6 +48,7 @@ export class DateTimePicker extends Component { <DatePicker currentDate={ currentDate } onChange={ onChange } + isInvalidDate={ isInvalidDate } /> </> ) } From 40ebea70a42588782088fdc8591844ccace96e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= <rdsuarez@gmail.com> Date: Tue, 22 Oct 2019 20:08:25 -0300 Subject: [PATCH 051/113] navigation-menu: Implement colors selector button. (#17832) Summary block-editor: expose ColorPaletteControl component navigation-menu: improve colors-selector component navigation-menu: compose withColors navigation-menu: render colors selector in bar navigation-menu: propagate withColor props navigation-menu: apply theme styles to selection navigation-item: populate styles to nav item navigation-menu: apply inline styles and CSS classes --- packages/block-editor/README.md | 4 + packages/block-editor/src/components/index.js | 1 + .../src/navigation-menu-item/edit.js | 13 +- .../src/navigation-menu-item/editor.scss | 13 +- .../navigation-menu/block-colors-selector.js | 95 ++++++++++++++ .../block-library/src/navigation-menu/edit.js | 111 ++++++++++++---- .../src/navigation-menu/editor.scss | 85 +++++++++++- .../src/navigation-menu/index.php | 124 +++++++++++++++++- 8 files changed, 407 insertions(+), 39 deletions(-) create mode 100644 packages/block-library/src/navigation-menu/block-colors-selector.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index d9c7818065c0b5..86ffa7887d2daf 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -171,6 +171,10 @@ _Related_ Undocumented declaration. +<a name="ColorPaletteControl" href="#ColorPaletteControl">#</a> **ColorPaletteControl** + +Undocumented declaration. + <a name="ContrastChecker" href="#ContrastChecker">#</a> **ContrastChecker** Undocumented declaration. diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 6e9bb592378678..a31f3829ca360c 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -16,6 +16,7 @@ export { default as __experimentalBlockNavigationList } from './block-navigation export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar'; export { default as ButtonBlockerAppender } from './button-block-appender'; export { default as ColorPalette } from './color-palette'; +export { default as ColorPaletteControl } from './color-palette/control'; export { default as ContrastChecker } from './contrast-checker'; export { default as __experimentalGradientPicker } from './gradient-picker'; export { default as __experimentalGradientPickerControl } from './gradient-picker/control'; diff --git a/packages/block-library/src/navigation-menu-item/edit.js b/packages/block-library/src/navigation-menu-item/edit.js index f4e456321347c6..90a80f41e2f696 100644 --- a/packages/block-library/src/navigation-menu-item/edit.js +++ b/packages/block-library/src/navigation-menu-item/edit.js @@ -2,6 +2,7 @@ * External dependencies */ import { invoke } from 'lodash'; +import classnames from 'classnames'; /** * WordPress dependencies @@ -84,8 +85,11 @@ function NavigationMenuItemEdit( { </div> ); } else { - content = attributes.label; + content = <div className="wp-block-navigation-menu-item__container"> + { attributes.label } + </div>; } + return ( <Fragment> <InspectorControls> @@ -138,7 +142,12 @@ function NavigationMenuItemEdit( { /> </PanelBody> </InspectorControls> - <div className="wp-block-navigation-menu-item"> + <div className={ classnames( + 'wp-block-navigation-menu-item', { + 'is-editing': isSelected || isParentOfSelectedBlock, + 'is-selected': isSelected, + } ) } + > { content } { ( isSelected || isParentOfSelectedBlock ) && <InnerBlocks diff --git a/packages/block-library/src/navigation-menu-item/editor.scss b/packages/block-library/src/navigation-menu-item/editor.scss index 2d801052ba4107..141054951dc98b 100644 --- a/packages/block-library/src/navigation-menu-item/editor.scss +++ b/packages/block-library/src/navigation-menu-item/editor.scss @@ -28,12 +28,16 @@ $menu-label-field-width: 140px; } } - .wp-block-navigation-menu-item { font-family: $editor-font; - color: #0073af; font-weight: bold; font-size: $text-editor-font-size; + + .wp-block-navigation-menu-item__container, + &.is-editing .editor-plain-text { + background-color: var(--background-color-menu-link); + color: var(--color-menu-link); + } } .wp-block-navigation-menu-item__nofollow-external-link { @@ -42,10 +46,7 @@ $menu-label-field-width: 140px; // Separator .wp-block-navigation-menu-item__separator { - margin-top: $grid-size; - margin-bottom: $grid-size; - margin-left: 0; - margin-right: 0; + margin: $grid-size 0 $grid-size; border-top: $border-width solid $light-gray-500; } diff --git a/packages/block-library/src/navigation-menu/block-colors-selector.js b/packages/block-library/src/navigation-menu/block-colors-selector.js new file mode 100644 index 00000000000000..0c1c98b691ef4f --- /dev/null +++ b/packages/block-library/src/navigation-menu/block-colors-selector.js @@ -0,0 +1,95 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { noop } from 'lodash'; + +/** + * WordPress dependencies + */ +import { IconButton, Dropdown, Toolbar } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { DOWN } from '@wordpress/keycodes'; +import { ColorPaletteControl, ContrastChecker } from '@wordpress/block-editor'; + +/** + * Color Selector Icon component. + * + * @return {*} React Icon component. + */ +const ColorSelectorIcon = ( { style } ) => + <div className="block-library-colors-selector__icon-container"> + <div + className="block-library-colors-selector__state-selection wp-block-navigation-menu-item" + style={ style } + > + Aa + </div> + </div>; + +/** + * Renders the Colors Selector Toolbar with the icon button. + * + * @param {Object} style - Colors style object. + * @return {*} React toggle button component. + */ +const renderToggleComponent = ( style ) => ( { onToggle, isOpen } ) => { + const openOnArrowDown = ( event ) => { + if ( ! isOpen && event.keyCode === DOWN ) { + event.preventDefault(); + event.stopPropagation(); + onToggle(); + } + }; + + return ( + <Toolbar> + <IconButton + className="components-icon-button components-toolbar__control block-library-colors-selector__toggle" + label={ __( 'Open Colors Selector' ) } + onClick={ onToggle } + onKeyDown={ openOnArrowDown } + icon={ <ColorSelectorIcon style={ style } /> } + /> + </Toolbar> + ); +}; + +const renderContent = ( { backgroundColor, textColor, onColorChange = noop } ) => ( () => { + const setColor = ( attr ) => ( value ) => onColorChange( { attr, value } ); + + return ( + <> + <div className="color-palette-controller-container"> + <ColorPaletteControl + value={ backgroundColor.color } + onChange={ setColor( 'backgroundColor' ) } + label={ __( 'Background Color' ) } + /> + </div> + + <div className="color-palette-controller-container"> + <ColorPaletteControl + value={ textColor.color } + onChange={ setColor( 'textColor' ) } + label={ __( 'Text Color' ) } + /> + </div> + + <ContrastChecker + textColor={ textColor.color } + backgroundColor={ backgroundColor.color } + isLargeText={ false } + /> + </> + ); +} ); + +export default ( { style, className, ...colorControlProps } ) => + <Dropdown + position="bottom right" + className={ classnames( 'block-library-colors-selector', className ) } + contentClassName="block-library-colors-selector__popover" + renderToggle={ renderToggleComponent( style ) } + renderContent={ renderContent( colorControlProps ) } + />; diff --git a/packages/block-library/src/navigation-menu/edit.js b/packages/block-library/src/navigation-menu/edit.js index 5b4ad5ce475f9a..3fc18a43b2259a 100644 --- a/packages/block-library/src/navigation-menu/edit.js +++ b/packages/block-library/src/navigation-menu/edit.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -9,6 +14,7 @@ import { InnerBlocks, InspectorControls, BlockControls, + withColors, } from '@wordpress/block-editor'; import { withSelect } from '@wordpress/data'; import { @@ -17,12 +23,15 @@ import { Spinner, Toolbar, } from '@wordpress/components'; +import { compose } from '@wordpress/compose'; + import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ import useBlockNavigator from './use-block-navigator'; +import BlockColorsStyleSelector from './block-colors-selector'; function NavigationMenu( { attributes, @@ -30,6 +39,10 @@ function NavigationMenu( { clientId, pages, isRequesting, + backgroundColor, + textColor, + setBackgroundColor, + setTextColor, } ) { const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( clientId ); const defaultMenuItems = useMemo( @@ -38,20 +51,71 @@ function NavigationMenu( { return null; } return pages.map( ( page ) => { - return [ 'core/navigation-menu-item', - { label: page.title.rendered, destination: page.permalink_template }, - ]; + return [ 'core/navigation-menu-item', { label: page.title.rendered, destination: page.permalink_template } ]; } ); }, [ pages ] ); + const navigationMenuStyles = {}; + if ( textColor.color ) { + navigationMenuStyles[ '--color-menu-link' ] = textColor.color; + } + + if ( backgroundColor.color ) { + navigationMenuStyles[ '--background-color-menu-link' ] = backgroundColor.color; + } + + const navigationMenuClasses = classnames( + 'wp-block-navigation-menu', { + 'has-text-color': textColor.color, + 'has-background-color': backgroundColor.color, + } + ); + + /** + * Set the color type according to the given values. + * It propagate the color values into the attributes object. + * Both `backgroundColorValue` and `textColorValue` are + * using the apply inline styles. + * + * @param {Object} colorsData Arguments passed by BlockColorsStyleSelector onColorChange. + * @param {string} colorsData.attr Color attribute. + * @param {boolean} colorsData.value Color attribute value. + */ + const setColorType = ( { attr, value } ) => { + switch ( attr ) { + case 'backgroundColor': + setBackgroundColor( value ); + setAttributes( { backgroundColorValue: value } ); + break; + + case 'textColor': + setTextColor( value ); + setAttributes( { textColorValue: value } ); + break; + } + }; + + // Set/Unset colors CSS classes. + setAttributes( { + backgroundColorCSSClass: backgroundColor.class ? backgroundColor.class : null, + textColorCSSClass: textColor.class ? textColor.class : null, + } ); + return ( <Fragment> <BlockControls> <Toolbar> { navigatorToolbarButton } </Toolbar> + <BlockColorsStyleSelector + style={ navigationMenuStyles } + className={ navigationMenuClasses } + backgroundColor={ backgroundColor } + textColor={ textColor } + onColorChange={ setColorType } + /> </BlockControls> { navigatorModal } <InspectorControls> @@ -60,18 +124,15 @@ function NavigationMenu( { > <CheckboxControl value={ attributes.automaticallyAdd } - onChange={ ( automaticallyAdd ) => { - setAttributes( { automaticallyAdd } ); - } } + onChange={ ( automaticallyAdd ) => setAttributes( { automaticallyAdd } ) } label={ __( 'Automatically add new pages' ) } help={ __( 'Automatically add new top level pages to this menu.' ) } /> </PanelBody> </InspectorControls> - <div className="wp-block-navigation-menu"> - { isRequesting && - <Spinner /> - } + + <div className={ navigationMenuClasses } style={ navigationMenuStyles }> + { isRequesting && <Spinner /> } { pages && <InnerBlocks template={ defaultMenuItems ? defaultMenuItems : null } @@ -84,17 +145,19 @@ function NavigationMenu( { ); } -export default withSelect( ( select ) => { - const { getEntityRecords } = select( 'core' ); - const { isResolving } = select( 'core/data' ); - const filterDefaultPages = { - parent: 0, - order: 'asc', - orderby: 'id', - }; - return { - pages: getEntityRecords( 'postType', 'page', filterDefaultPages ), - isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ), - }; -} )( NavigationMenu ); - +export default compose( [ + withColors( { backgroundColor: 'background-color', textColor: 'color' } ), + withSelect( ( select ) => { + const { getEntityRecords } = select( 'core' ); + const { isResolving } = select( 'core/data' ); + const filterDefaultPages = { + parent: 0, + order: 'asc', + orderby: 'id', + }; + return { + pages: getEntityRecords( 'postType', 'page', filterDefaultPages ), + isRequesting: isResolving( 'core', 'getEntityRecords', [ 'postType', 'page', filterDefaultPages ] ), + }; + } ), +] )( NavigationMenu ); diff --git a/packages/block-library/src/navigation-menu/editor.scss b/packages/block-library/src/navigation-menu/editor.scss index 2238b2fae8dd7c..a92f72eb5c1704 100644 --- a/packages/block-library/src/navigation-menu/editor.scss +++ b/packages/block-library/src/navigation-menu/editor.scss @@ -12,7 +12,90 @@ } .wp-block-navigation-menu-item { - .wp-block-navigation-menu-item { + .wp-block-navigation-menu-item__link { margin-left: $grid-size-large; } } + +/** + * Colors Selector component + */ +$colors-selector-size: 22px; +.block-library-colors-selector { + width: auto; + + // Toolbar colors-selector button. + .block-library-colors-selector__toggle { + display: block; + margin: 0 auto; + padding: 3px; + width: auto; + } + + // Button container. + .block-library-colors-selector__icon-container { + width: 42px; + height: 30px; + position: relative; + margin: 0 auto; + padding: 3px; + display: flex; + align-items: center; + border-radius: 4px; + + // Add the button arrow. + &::after { + @include dropdown-arrow(); + } + + // Styling button states. + &:focus, + &:hover { + color: $dark-gray-500; + box-shadow: inset 0 0 0 1px $dark-gray-500, inset 0 0 0 2px #fff; + } + } + + // colors-selector - selection status. + .block-library-colors-selector__state-selection { + font-size: 11px; + font-style: normal; + font-family: inherit; + font-weight: 600; + + border-radius: $colors-selector-size / 2; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2); + + width: $colors-selector-size; + min-width: $colors-selector-size; + height: $colors-selector-size; + min-height: $colors-selector-size; + line-height: ($colors-selector-size - 2); + + background-color: var(--background-color-menu-link); + color: var(--color-menu-link); + } + + &:not(.has-background-color) .block-library-colors-selector__state-selection { + background-image: linear-gradient(135deg, rgba(0, 0, 0, 0.08) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.08) 50%, rgba(0, 0, 0, 0.08) 75%, transparent 75%, transparent 100%); + background-size: 12px 12px; + } +} + +// Colors Selector Popover. +$color-control-label-height: 20px; +.block-library-colors-selector__popover { + .color-palette-controller-container { + padding: 16px; + } + + .components-base-control__label { + height: $color-control-label-height; + line-height: $color-control-label-height; + } + + .component-color-indicator { + float: right; + margin-top: 2px; + } +} diff --git a/packages/block-library/src/navigation-menu/index.php b/packages/block-library/src/navigation-menu/index.php index ba6348bd66e1b6..c797a65fdfc10c 100644 --- a/packages/block-library/src/navigation-menu/index.php +++ b/packages/block-library/src/navigation-menu/index.php @@ -5,6 +5,56 @@ * @package gutenberg */ +/** + * Build an array with CSS classes and inline styles defining the colors + * which will be applied to the navigation menu markup in the front-end. + * + * @param array $attributes NavigationMenu block attributes. + * @return array Colors CSS classes and inline styles. + */ +function build_css_colors( $attributes ) { + // CSS classes. + $colors = array( + 'bg_css_classes' => '', + 'bg_inline_styles' => '', + 'text_css_classes' => '', + 'text_inline_styles' => '', + ); + + // Background color. + // Background color - has text color. + if ( array_key_exists( 'backgroundColor', $attributes ) ) { + $colors['bg_css_classes'] .= ' has-background-color'; + } + + // Background color - add custom CSS class. + if ( array_key_exists( 'backgroundColorCSSClass', $attributes ) ) { + $colors['bg_css_classes'] .= " {$attributes['backgroundColorCSSClass']}"; + + } elseif ( array_key_exists( 'customBackgroundColor', $attributes ) ) { + // Background color - or add inline `background-color` style. + $colors['bg_inline_styles'] = ' style="background-color: ' . esc_attr( $attributes['customBackgroundColor'] ) . ';"'; + } + + // Text color. + // Text color - has text color. + if ( array_key_exists( 'textColor', $attributes ) ) { + $colors['text_css_classes'] .= ' has-text-color'; + } + // Text color - add custom CSS class. + if ( array_key_exists( 'textColorCSSClass', $attributes ) ) { + $colors['text_css_classes'] .= " {$attributes['textColorCSSClass']}"; + + } elseif ( array_key_exists( 'customTextColor', $attributes ) ) { + // Text color - or add inline `color` style. + $colors['text_inline_styles'] = ' style="color: ' . esc_attr( $attributes['customTextColor'] ) . ';"'; + } + + $colors['bg_css_classes'] = esc_attr( trim( $colors['bg_css_classes'] ) ); + $colors['text_css_classes'] = esc_attr( trim( $colors['text_css_classes'] ) ); + + return $colors; +} /** * Renders the `core/navigation-menu` block on server. * @@ -15,20 +65,43 @@ * @return string Returns the post content with the legacy widget added. */ function render_block_navigation_menu( $attributes, $content, $block ) { - return '<nav class="wp-block-navigation-menu">' . build_navigation_menu_html( $block ) . '</nav>'; + // Inline computed colors. + $comp_inline_styles = ''; + if ( array_key_exists( 'backgroundColorValue', $attributes ) ) { + $comp_inline_styles .= ' background-color: ' . esc_attr( $attributes['backgroundColorValue'] ) . ';'; + } + + if ( array_key_exists( 'textColorValue', $attributes ) ) { + $comp_inline_styles .= ' color: ' . esc_attr( $attributes['textColorValue'] ) . ';'; + } + $comp_inline_styles = ! empty( $comp_inline_styles ) + ? ' style="' . esc_attr( trim( $comp_inline_styles ) ) . '"' + : ''; + + $colors = build_css_colors( $attributes ); + + return "<nav class='wp-block-navigation-menu' {$comp_inline_styles}>" . + build_navigation_menu_html( $block, $colors ) . + '</nav>'; } /** * Walks the inner block structure and returns an HTML list for it. * - * @param array $block The block. + * @param array $block The block. + * @param array $colors Contains inline styles and CSS classes to apply to menu item. * * @return string Returns an HTML list from innerBlocks. */ -function build_navigation_menu_html( $block ) { +function build_navigation_menu_html( $block, $colors ) { $html = ''; foreach ( (array) $block['innerBlocks'] as $key => $menu_item ) { - $html .= '<li class="wp-block-navigation-menu-item"><a class="wp-block-navigation-menu-item"'; + + $html .= '<li class="wp-block-navigation-menu-item ' . $colors['bg_css_classes'] . '"' . $colors['bg_inline_styles'] . '>' . + '<a + class="wp-block-navigation-menu-item__link ' . $colors['text_css_classes'] . '" + ' . $colors['text_inline_styles']; + if ( isset( $menu_item['attrs']['destination'] ) ) { $html .= ' href="' . $menu_item['attrs']['destination'] . '"'; } @@ -42,7 +115,7 @@ function build_navigation_menu_html( $block ) { $html .= '</a>'; if ( count( (array) $menu_item['innerBlocks'] ) > 0 ) { - $html .= build_navigation_menu_html( $menu_item ); + $html .= build_navigation_menu_html( $menu_item, $colors ); } $html .= '</li>'; @@ -54,18 +127,57 @@ function build_navigation_menu_html( $block ) { * Register the navigation menu block. * * @uses render_block_navigation_menu() + * @throws WP_Error An WP_Error exception parsing the block definition. */ function register_block_core_navigation_menu() { + register_block_type( 'core/navigation-menu', array( 'category' => 'layout', 'attributes' => array( - 'automaticallyAdd' => array( + 'className' => array( + 'type' => 'string', + ), + + 'automaticallyAdd' => array( 'type' => 'boolean', 'default' => false, ), + + 'backgroundColor' => array( + 'type' => 'string', + ), + + 'textColor' => array( + 'type' => 'string', + ), + + 'backgroundColorValue' => array( + 'type' => 'string', + ), + + 'textColorValue' => array( + 'type' => 'string', + ), + + 'customBackgroundColor' => array( + 'type' => 'string', + ), + + 'customTextColor' => array( + 'type' => 'string', + ), + + 'backgroundColorCSSClass' => array( + 'type' => 'string', + ), + + 'textColorCSSClass' => array( + 'type' => 'string', + ), ), + 'render_callback' => 'render_block_navigation_menu', ) ); From 9e5d1385d6b844c4dcae617e3966acb209b23110 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Tue, 22 Oct 2019 17:05:04 -0700 Subject: [PATCH 052/113] Update design-systems:dev script to build packages (#18073) The build-style/style.css needs to be rebuilt prior to running Storybook in watch mode. This change adds `npm run build:packages` at the start of the design-systems:dev script to CSS is built prior. Issue found in #17997 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6c3d854c3355cd..e1c25716bd94c0 100644 --- a/package.json +++ b/package.json @@ -198,7 +198,7 @@ "test-unit:native": "cd test/native/ && cross-env NODE_ENV=test jest --config ./jest.config.js", "test-unit:native:debug": "cd test/native/ && node --inspect ../../node_modules/.bin/jest --runInBand --config ./jest.config.js", "design-system:build": "npm run build:packages && build-storybook -c ./packages/components/storybook -o ./playground/dist/design-system/components", - "design-system:dev": "concurrently \"npm run dev:packages\" \"start-storybook -c ./packages/components/storybook\"", + "design-system:dev": "npm run build:packages && concurrently \"npm run dev:packages\" \"start-storybook -c ./packages/components/storybook\"", "playground:build": "npm run build:packages && parcel build playground/src/index.html -d playground/dist", "playground:dev": "concurrently \"npm run dev:packages\" \"parcel playground/src/index.html -d playground/dist\"", "preenv": "npm run check-engines", From a50bf80d2d6c618082527847ed6ecad3d13c5bc6 Mon Sep 17 00:00:00 2001 From: Mikael Korpela <mikael@ihminen.org> Date: Wed, 23 Oct 2019 13:11:39 +0300 Subject: [PATCH 053/113] Add `@wordpress/base-styles` package (#17883) - Move `assets/stylesheets/*` to the new package - Move admin color schemes to the new package --- bin/packages/build-worker.js | 2 +- bin/packages/post-css-config.js | 63 +------------------ docs/contributors/coding-guidelines.md | 2 +- docs/manifest-devhub.json | 6 ++ package-lock.json | 4 ++ package.json | 1 + packages/base-styles/.npmrc | 1 + packages/base-styles/README.md | 51 +++++++++++++++ .../base-styles}/_animations.scss | 0 .../base-styles}/_breakpoints.scss | 0 .../base-styles}/_colors.scss | 0 .../base-styles}/_mixins.scss | 0 .../base-styles}/_variables.scss | 0 .../base-styles}/_z-index.scss | 0 packages/base-styles/index.js | 60 ++++++++++++++++++ packages/base-styles/package.json | 25 ++++++++ playground/.sassrc | 5 ++ playground/src/style.scss | 12 ++-- 18 files changed, 164 insertions(+), 68 deletions(-) create mode 100644 packages/base-styles/.npmrc create mode 100644 packages/base-styles/README.md rename {assets/stylesheets => packages/base-styles}/_animations.scss (100%) rename {assets/stylesheets => packages/base-styles}/_breakpoints.scss (100%) rename {assets/stylesheets => packages/base-styles}/_colors.scss (100%) rename {assets/stylesheets => packages/base-styles}/_mixins.scss (100%) rename {assets/stylesheets => packages/base-styles}/_variables.scss (100%) rename {assets/stylesheets => packages/base-styles}/_z-index.scss (100%) create mode 100644 packages/base-styles/index.js create mode 100644 packages/base-styles/package.json create mode 100644 playground/.sassrc diff --git a/bin/packages/build-worker.js b/bin/packages/build-worker.js index 7e3e636c013a1d..d0f1d1c809984a 100644 --- a/bin/packages/build-worker.js +++ b/bin/packages/build-worker.js @@ -94,7 +94,7 @@ const BUILD_TASK_BY_EXTENSION = { const builtSass = await renderSass( { file, - includePaths: [ path.resolve( __dirname, '../../assets/stylesheets' ) ], + includePaths: [ path.join( PACKAGES_DIR, 'base-styles' ) ], data: ( [ 'colors', diff --git a/bin/packages/post-css-config.js b/bin/packages/post-css-config.js index 3d7861f75044bd..842688a8d784b7 100644 --- a/bin/packages/post-css-config.js +++ b/bin/packages/post-css-config.js @@ -1,64 +1,7 @@ +const { adminColorSchemes } = require( '@wordpress/base-styles' ); + module.exports = [ - require( '@wordpress/postcss-themes' )( { - defaults: { - primary: '#0085ba', - secondary: '#11a0d2', - toggle: '#11a0d2', - button: '#007cba', - outlines: '#007cba', - }, - themes: { - 'admin-color-light': { - primary: '#0085ba', - secondary: '#c75726', - toggle: '#11a0d2', - button: '#0085ba', - outlines: '#007cba', - }, - 'admin-color-blue': { - primary: '#82b4cb', - secondary: '#d9ab59', - toggle: '#82b4cb', - button: '#d9ab59', - outlines: '#417e9B', - }, - 'admin-color-coffee': { - primary: '#c2a68c', - secondary: '#9fa47b', - toggle: '#c2a68c', - button: '#c2a68c', - outlines: '#59524c', - }, - 'admin-color-ectoplasm': { - primary: '#a7b656', - secondary: '#c77430', - toggle: '#a7b656', - button: '#a7b656', - outlines: '#523f6d', - }, - 'admin-color-midnight': { - primary: '#e14d43', - secondary: '#77a6b9', - toggle: '#77a6b9', - button: '#e14d43', - outlines: '#497b8d', - }, - 'admin-color-ocean': { - primary: '#a3b9a2', - secondary: '#a89d8a', - toggle: '#a3b9a2', - button: '#a3b9a2', - outlines: '#5e7d5e', - }, - 'admin-color-sunrise': { - primary: '#d1864a', - secondary: '#c8b03c', - toggle: '#c8b03c', - button: '#d1864a', - outlines: '#837425', - }, - }, - } ), + require( '@wordpress/postcss-themes' )( adminColorSchemes ), require( 'autoprefixer' )( { grid: true } ), require( 'postcss-color-function' ), ]; diff --git a/docs/contributors/coding-guidelines.md b/docs/contributors/coding-guidelines.md index 2e02dfeaa10f7e..8e69e8c8ccddbd 100644 --- a/docs/contributors/coding-guidelines.md +++ b/docs/contributors/coding-guidelines.md @@ -59,7 +59,7 @@ export default function Notice( { children, onRemove, isDismissible } ) { } ``` -A component's class name should **never** be used outside its own folder (with rare exceptions such as [`_z-index.scss`](https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_z-index.scss)). If you need to inherit styles of another component in your own components, you should render an instance of that other component. At worst, you should duplicate the styles within your own component's stylesheet. This is intended to improve maintainability by treating individual components as the isolated abstract interface. +A component's class name should **never** be used outside its own folder (with rare exceptions such as [`_z-index.scss`](https://github.com/WordPress/gutenberg/blob/master/packages/base-styles/_z-index.scss)). If you need to inherit styles of another component in your own components, you should render an instance of that other component. At worst, you should duplicate the styles within your own component's stylesheet. This is intended to improve maintainability by treating individual components as the isolated abstract interface. #### SCSS File Naming Conventions for Blocks diff --git a/docs/manifest-devhub.json b/docs/manifest-devhub.json index 10b2c9362e8aef..998097f22d10e9 100644 --- a/docs/manifest-devhub.json +++ b/docs/manifest-devhub.json @@ -1079,6 +1079,12 @@ "markdown_source": "../packages/babel-preset-default/README.md", "parent": "packages" }, + { + "title": "@wordpress/base-styles", + "slug": "packages-base-styles", + "markdown_source": "../packages/base-styles/README.md", + "parent": "packages" + }, { "title": "@wordpress/blob", "slug": "packages-blob", diff --git a/package-lock.json b/package-lock.json index c71a6f8db2f425..eb34acc8454813 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7207,6 +7207,10 @@ "core-js": "^3.1.4" } }, + "@wordpress/base-styles": { + "version": "file:packages/base-styles", + "dev": true + }, "@wordpress/blob": { "version": "file:packages/blob", "requires": { diff --git a/package.json b/package.json index e1c25716bd94c0..fcb77778ca522b 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma", "@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot", "@wordpress/babel-preset-default": "file:packages/babel-preset-default", + "@wordpress/base-styles": "file:packages/base-styles", "@wordpress/browserslist-config": "file:packages/browserslist-config", "@wordpress/custom-templated-path-webpack-plugin": "file:packages/custom-templated-path-webpack-plugin", "@wordpress/dependency-extraction-webpack-plugin": "file:packages/dependency-extraction-webpack-plugin", diff --git a/packages/base-styles/.npmrc b/packages/base-styles/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/base-styles/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/base-styles/README.md b/packages/base-styles/README.md new file mode 100644 index 00000000000000..20945fd08acf8f --- /dev/null +++ b/packages/base-styles/README.md @@ -0,0 +1,51 @@ +# Base Styles + +Base SCSS utilities and variables for WordPress. + +## Installation + +Install the module + +```bash +npm install @wordpress/base-styles --save-dev +``` + +## Use + +### SCSS utilities and variables + +In your application's SCSS file, include styles like so: + +```scss +@import "node_modules/@wordpress/base-styles/colors"; +@import "node_modules/@wordpress/base-styles/variables"; +@import "node_modules/@wordpress/base-styles/mixins"; +@import "node_modules/@wordpress/base-styles/breakpoints"; +@import "node_modules/@wordpress/base-styles/animations"; +@import "node_modules/@wordpress/base-styles/z-index"; +``` + +If you use [Webpack](https://webpack.js.org/) for your SCSS pipeline, you can use `~` to resolve to `node_modules`: + +```scss +@import "~@wordpress/base-styles/colors"; +``` + +To make that work with [`sass`](https://www.npmjs.com/package/sass) or [`node-sass`](https://www.npmjs.com/package/node-sass) NPM modules without Webpack, you'd have to use [includePaths option](https://sass-lang.com/documentation/js-api#includepaths): + +```json +{ + "includePaths": ["node_modules"] +} +``` + +### PostCSS color schemes + +To use color schemes with [`@wordpress/postcss-themes`](https://www.npmjs.com/package/@wordpress/postcss-themes), import them like so: + +```js +const { adminColorSchemes } = require( '@wordpress/base-styles' ); +const wpPostcss = require( '@wordpress/postcss-themes' )( adminColorSchemes ) +``` + +<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p> diff --git a/assets/stylesheets/_animations.scss b/packages/base-styles/_animations.scss similarity index 100% rename from assets/stylesheets/_animations.scss rename to packages/base-styles/_animations.scss diff --git a/assets/stylesheets/_breakpoints.scss b/packages/base-styles/_breakpoints.scss similarity index 100% rename from assets/stylesheets/_breakpoints.scss rename to packages/base-styles/_breakpoints.scss diff --git a/assets/stylesheets/_colors.scss b/packages/base-styles/_colors.scss similarity index 100% rename from assets/stylesheets/_colors.scss rename to packages/base-styles/_colors.scss diff --git a/assets/stylesheets/_mixins.scss b/packages/base-styles/_mixins.scss similarity index 100% rename from assets/stylesheets/_mixins.scss rename to packages/base-styles/_mixins.scss diff --git a/assets/stylesheets/_variables.scss b/packages/base-styles/_variables.scss similarity index 100% rename from assets/stylesheets/_variables.scss rename to packages/base-styles/_variables.scss diff --git a/assets/stylesheets/_z-index.scss b/packages/base-styles/_z-index.scss similarity index 100% rename from assets/stylesheets/_z-index.scss rename to packages/base-styles/_z-index.scss diff --git a/packages/base-styles/index.js b/packages/base-styles/index.js new file mode 100644 index 00000000000000..bac5dede479a12 --- /dev/null +++ b/packages/base-styles/index.js @@ -0,0 +1,60 @@ +exports.adminColorSchemes = { + defaults: { + primary: '#0085ba', + secondary: '#11a0d2', + toggle: '#11a0d2', + button: '#007cba', + outlines: '#007cba', + }, + themes: { + 'admin-color-light': { + primary: '#0085ba', + secondary: '#c75726', + toggle: '#11a0d2', + button: '#0085ba', + outlines: '#007cba', + }, + 'admin-color-blue': { + primary: '#82b4cb', + secondary: '#d9ab59', + toggle: '#82b4cb', + button: '#d9ab59', + outlines: '#417e9B', + }, + 'admin-color-coffee': { + primary: '#c2a68c', + secondary: '#9fa47b', + toggle: '#c2a68c', + button: '#c2a68c', + outlines: '#59524c', + }, + 'admin-color-ectoplasm': { + primary: '#a7b656', + secondary: '#c77430', + toggle: '#a7b656', + button: '#a7b656', + outlines: '#523f6d', + }, + 'admin-color-midnight': { + primary: '#e14d43', + secondary: '#77a6b9', + toggle: '#77a6b9', + button: '#e14d43', + outlines: '#497b8d', + }, + 'admin-color-ocean': { + primary: '#a3b9a2', + secondary: '#a89d8a', + toggle: '#a3b9a2', + button: '#a3b9a2', + outlines: '#5e7d5e', + }, + 'admin-color-sunrise': { + primary: '#d1864a', + secondary: '#c8b03c', + toggle: '#c8b03c', + button: '#d1864a', + outlines: '#837425', + }, + }, +}; diff --git a/packages/base-styles/package.json b/packages/base-styles/package.json new file mode 100644 index 00000000000000..9e54a1f0a86864 --- /dev/null +++ b/packages/base-styles/package.json @@ -0,0 +1,25 @@ +{ + "name": "@wordpress/base-styles", + "version": "1.0.0-alpha.1", + "description": "Base SCSS utilities and variables for WordPress.", + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "sass", + "scss", + "css" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/base-styles/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/base-styles" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/playground/.sassrc b/playground/.sassrc new file mode 100644 index 00000000000000..4f704b80b310a5 --- /dev/null +++ b/playground/.sassrc @@ -0,0 +1,5 @@ +{ + "includePaths": [ + "node_modules" + ] +} diff --git a/playground/src/style.scss b/playground/src/style.scss index 43d7a0460ab0e7..0fc00355758af5 100644 --- a/playground/src/style.scss +++ b/playground/src/style.scss @@ -1,9 +1,9 @@ -@import "../../assets/stylesheets/colors"; -@import "../../assets/stylesheets/variables"; -@import "../../assets/stylesheets/mixins"; -@import "../../assets/stylesheets/breakpoints"; -@import "../../assets/stylesheets/animations"; -@import "../../assets/stylesheets/z-index"; +@import "~@wordpress/base-styles/colors"; +@import "~@wordpress/base-styles/variables"; +@import "~@wordpress/base-styles/mixins"; +@import "~@wordpress/base-styles/breakpoints"; +@import "~@wordpress/base-styles/animations"; +@import "~@wordpress/base-styles/z-index"; @import "./reset"; @import "./editor-styles"; From 7da1e78996bd7fa800cb4521490e60d45dd34f17 Mon Sep 17 00:00:00 2001 From: Enrique Piqueras <epiqueras@users.noreply.github.com> Date: Wed, 23 Oct 2019 13:28:04 -0700 Subject: [PATCH 054/113] Add Site Title block and required functionality. (#17207) * Core Data: Add a Site entity and a hook for entity saving logic. * Experiments: Add a Full Site Editing experiment. * Block Library: Add Site Title block. * Fixtures: Add Site Title block fixture. * Fixtures: Add missing transform fixtures. * Block Library: Remove deprecated prop usage in Site Title. * Site Title: Support nesting inside of a Site block. * Site Title: Disallow formatting in the rich text field. * Core Data: Make useEntitySaving experimental. --- lib/blocks.php | 1 + packages/base-styles/_z-index.scss | 1 + packages/block-editor/README.md | 1 + packages/block-editor/src/store/defaults.js | 3 +- packages/block-library/src/editor.scss | 1 + packages/block-library/src/index.js | 33 +++++--- .../block-library/src/site-title/block.json | 4 + packages/block-library/src/site-title/edit.js | 39 ++++++++++ .../block-library/src/site-title/editor.scss | 6 ++ packages/block-library/src/site-title/icon.js | 12 +++ .../block-library/src/site-title/index.js | 20 +++++ .../block-library/src/site-title/index.php | 28 +++++++ packages/core-data/src/entities.js | 1 + packages/core-data/src/entity-provider.js | 76 ++++++++++++++++++- packages/core-data/src/index.js | 7 +- packages/core-data/src/resolvers.js | 2 +- .../e2e-tests/fixtures/block-transforms.js | 6 ++ .../fixtures/blocks/core__site-title.html | 1 + .../fixtures/blocks/core__site-title.json | 10 +++ .../blocks/core__site-title.parsed.json | 18 +++++ .../blocks/core__site-title.serialized.html | 1 + .../experimental/block-transforms.test.js | 6 +- .../editor/src/components/provider/index.js | 31 ++++---- .../full-content/full-content.test.js | 6 +- 24 files changed, 284 insertions(+), 30 deletions(-) create mode 100644 packages/block-library/src/site-title/block.json create mode 100644 packages/block-library/src/site-title/edit.js create mode 100644 packages/block-library/src/site-title/editor.scss create mode 100644 packages/block-library/src/site-title/icon.js create mode 100644 packages/block-library/src/site-title/index.js create mode 100644 packages/block-library/src/site-title/index.php create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html diff --git a/lib/blocks.php b/lib/blocks.php index ae8a816b3979ef..1dc7277d85ee80 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -52,6 +52,7 @@ function gutenberg_reregister_core_block_types() { 'search.php' => 'core/search', 'social-link.php' => gutenberg_get_registered_social_link_blocks(), 'tag-cloud.php' => 'core/tag-cloud', + 'site-title.php' => 'core/site-title', ); $registry = WP_Block_Type_Registry::get_instance(); diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 7b7e0aedd55301..c4e7c3a02aa356 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -31,6 +31,7 @@ $z-layers: ( ".wp-block-cover__inner-container": 1, // InnerBlocks area inside cover image block ".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. + ".wp-block-site-title__save-button": 1, // Active pill button ".components-button.is-button {:focus or .is-primary}": 1, diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 86ffa7887d2daf..ebd908a3ed1b0a 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -396,6 +396,7 @@ The default editor settings **experimentalEnableLegacyWidgetBlock boolean Whether the user has enabled the Legacy Widget Block **experimentalEnableMenuBlock boolean Whether the user has enabled the Menu Block **experimentalBlockDirectory boolean Whether the user has enabled the Block Directory + \_\_experimentalEnableFullSiteEditing boolean Whether the user has enabled Full Site Editing <a name="SkipToSelectedBlock" href="#SkipToSelectedBlock">#</a> **SkipToSelectedBlock** diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index abc68fa5bf411f..a983abacc36b8a 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -32,6 +32,7 @@ export const PREFERENCES_DEFAULTS = { * __experimentalEnableLegacyWidgetBlock boolean Whether the user has enabled the Legacy Widget Block * __experimentalEnableMenuBlock boolean Whether the user has enabled the Menu Block * __experimentalBlockDirectory boolean Whether the user has enabled the Block Directory + * __experimentalEnableFullSiteEditing boolean Whether the user has enabled Full Site Editing */ export const SETTINGS_DEFAULTS = { alignWide: false, @@ -152,6 +153,7 @@ export const SETTINGS_DEFAULTS = { __experimentalEnableLegacyWidgetBlock: false, __experimentalEnableMenuBlock: false, __experimentalBlockDirectory: false, + __experimentalEnableFullSiteEditing: false, gradients: [ { name: __( 'Vivid cyan blue to vivid purple' ), @@ -228,4 +230,3 @@ export const SETTINGS_DEFAULTS = { }, ], }; - diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index bc75754474b294..59569f4105ba2c 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -36,6 +36,7 @@ @import "./text-columns/editor.scss"; @import "./verse/editor.scss"; @import "./video/editor.scss"; +@import "./site-title/editor.scss"; /** * Import styles from internal editor components used by the blocks. diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index e49f68553b0a6f..3147ebcc0e9cdc 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -62,6 +62,9 @@ import * as classic from './classic'; import * as socialLinks from './social-links'; import * as socialLink from './social-link'; +// Full Site Editing Blocks +import * as siteTitle from './site-title'; + /** * Function to register an individual block. * @@ -162,14 +165,24 @@ export const registerCoreBlocks = () => { * __experimentalRegisterExperimentalCoreBlocks( settings ); * ``` */ -export const __experimentalRegisterExperimentalCoreBlocks = process.env.GUTENBERG_PHASE === 2 ? ( settings ) => { - const { __experimentalEnableLegacyWidgetBlock, __experimentalEnableMenuBlock } = settings; +export const __experimentalRegisterExperimentalCoreBlocks = + process.env.GUTENBERG_PHASE === 2 ? + ( settings ) => { + const { + __experimentalEnableLegacyWidgetBlock, + __experimentalEnableMenuBlock, + __experimentalEnableFullSiteEditing, + } = settings - [ - __experimentalEnableLegacyWidgetBlock ? legacyWidget : null, - __experimentalEnableMenuBlock ? navigationMenu : null, - __experimentalEnableMenuBlock ? navigationMenuItem : null, - socialLinks, - ...socialLink.sites, - ].forEach( registerBlock ); -} : undefined; + ;[ + __experimentalEnableLegacyWidgetBlock ? legacyWidget : null, + __experimentalEnableMenuBlock ? navigationMenu : null, + __experimentalEnableMenuBlock ? navigationMenuItem : null, + socialLinks, + ...socialLink.sites, + + // Register Full Site Editing Blocks. + ...( __experimentalEnableFullSiteEditing ? [ siteTitle ] : [] ), + ].forEach( registerBlock ); + } : + undefined; diff --git a/packages/block-library/src/site-title/block.json b/packages/block-library/src/site-title/block.json new file mode 100644 index 00000000000000..a853cde2517b51 --- /dev/null +++ b/packages/block-library/src/site-title/block.json @@ -0,0 +1,4 @@ +{ + "name": "core/site-title", + "category": "layout" +} diff --git a/packages/block-library/src/site-title/edit.js b/packages/block-library/src/site-title/edit.js new file mode 100644 index 00000000000000..0294fb82d17a18 --- /dev/null +++ b/packages/block-library/src/site-title/edit.js @@ -0,0 +1,39 @@ +/** + * WordPress dependencies + */ +import { + useEntityProp, + __experimentalUseEntitySaving, +} from '@wordpress/core-data'; +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { RichText } from '@wordpress/block-editor'; + +export default function SiteTitleEdit() { + const [ title, setTitle ] = useEntityProp( 'root', 'site', 'title' ); + const [ isDirty, isSaving, save ] = __experimentalUseEntitySaving( + 'root', + 'site', + 'title' + ); + return ( + <> + <Button + isPrimary + className="wp-block-site-title__save-button" + disabled={ ! isDirty || ! title } + isBusy={ isSaving } + onClick={ save } + > + { __( 'Update' ) } + </Button> + <RichText + tagName="h1" + placeholder={ __( 'Site Title' ) } + value={ title } + onChange={ setTitle } + allowedFormats={ [] } + /> + </> + ); +} diff --git a/packages/block-library/src/site-title/editor.scss b/packages/block-library/src/site-title/editor.scss new file mode 100644 index 00000000000000..f2b8359cf3790b --- /dev/null +++ b/packages/block-library/src/site-title/editor.scss @@ -0,0 +1,6 @@ +.wp-block-site-title__save-button { + position: absolute; + right: 0; + top: 0; + z-index: z-index(".wp-block-site-title__save-button"); +} diff --git a/packages/block-library/src/site-title/icon.js b/packages/block-library/src/site-title/icon.js new file mode 100644 index 00000000000000..1ab74dec2c32d3 --- /dev/null +++ b/packages/block-library/src/site-title/icon.js @@ -0,0 +1,12 @@ +/** + * WordPress dependencies + */ +import { SVG, Path, Circle } from '@wordpress/components'; + +export default ( + <SVG xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <Path fill="none" d="M0 0h24v24H0V0z" /> + <Path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zM7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 2.88-2.88 7.19-5 9.88C9.92 16.21 7 11.85 7 9z" /> + <Circle cx="12" cy="9" r="2.5" /> + </SVG> +); diff --git a/packages/block-library/src/site-title/index.js b/packages/block-library/src/site-title/index.js new file mode 100644 index 00000000000000..4b8fc50b86b34f --- /dev/null +++ b/packages/block-library/src/site-title/index.js @@ -0,0 +1,20 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import icon from './icon'; +import edit from './edit'; + +const { name } = metadata; +export { metadata, name }; + +export const settings = { + title: __( 'Site Title' ), + icon, + edit, +}; diff --git a/packages/block-library/src/site-title/index.php b/packages/block-library/src/site-title/index.php new file mode 100644 index 00000000000000..6e5b5786436f09 --- /dev/null +++ b/packages/block-library/src/site-title/index.php @@ -0,0 +1,28 @@ +<?php +/** + * Server-side rendering of the `core/site-title` block. + * + * @package WordPress + */ + +/** + * Renders the `core/site-title` block on the server. + * + * @return string The render. + */ +function render_block_core_site_title() { + return sprintf( '<h1>%s</h1>', get_bloginfo( 'name' ) ); +} + +/** + * Registers the `core/site-title` block on the server. + */ +function register_block_core_site_title() { + register_block_type( + 'core/site-title', + array( + 'render_callback' => 'render_block_core_site_title', + ) + ); +} +add_action( 'init', 'register_block_core_site_title' ); diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js index 4ee2f6b715374f..b75d0e44632373 100644 --- a/packages/core-data/src/entities.js +++ b/packages/core-data/src/entities.js @@ -12,6 +12,7 @@ import { apiFetch, select } from './controls'; export const DEFAULT_ENTITY_KEY = 'id'; export const defaultEntities = [ + { name: 'site', kind: 'root', baseURL: '/wp/v2/settings' }, { name: 'postType', kind: 'root', key: 'slug', baseURL: '/wp/v2/types' }, { name: 'media', kind: 'root', baseURL: '/wp/v2/media', plural: 'mediaItems' }, { name: 'taxonomy', kind: 'root', key: 'slug', baseURL: '/wp/v2/taxonomies', plural: 'taxonomies' }, diff --git a/packages/core-data/src/entity-provider.js b/packages/core-data/src/entity-provider.js index 7870e0217cc974..50439f1b57ad65 100644 --- a/packages/core-data/src/entity-provider.js +++ b/packages/core-data/src/entity-provider.js @@ -52,6 +52,17 @@ export default function EntityProvider( { kind, type, id, children } ) { return <Provider value={ id }>{ children }</Provider>; } +/** + * Hook that returns the ID for the nearest + * provided entity of the specified type. + * + * @param {string} kind The entity kind. + * @param {string} type The entity type. + */ +export function useEntityId( kind, type ) { + return useContext( getEntity( kind, type ).context ); +} + /** * Hook that returns the value and a setter for the * specified property of the nearest provided @@ -66,11 +77,13 @@ export default function EntityProvider( { kind, type, id, children } ) { * setter. */ export function useEntityProp( kind, type, prop ) { - const id = useContext( getEntity( kind, type ).context ); + const id = useEntityId( kind, type ); const value = useSelect( ( select ) => { - const entity = select( 'core' ).getEditedEntityRecord( kind, type, id ); + const { getEntityRecord, getEditedEntityRecord } = select( 'core' ); + getEntityRecord( kind, type, id ); // Trigger resolver. + const entity = getEditedEntityRecord( kind, type, id ); return entity && entity[ prop ]; }, [ kind, type, id, prop ] @@ -88,3 +101,62 @@ export function useEntityProp( kind, type, prop ) { return [ value, setValue ]; } + +/** + * Hook that returns whether the nearest provided + * entity of the specified type is dirty, saving, + * and a function to save it. + * + * The last, optional parameter is for scoping the + * selection to a single property or a list properties. + * + * By default, dirtyness detection and saving considers + * and handles all properties of an entity, but this + * last parameter lets you scope it to a single property + * or a list of properties for each instance of this hook. + * + * @param {string} kind The entity kind. + * @param {string} type The entity type. + * @param {string|[string]} [props] The property name or list of property names. + */ +export function __experimentalUseEntitySaving( kind, type, props ) { + const id = useEntityId( kind, type ); + + const [ isDirty, isSaving, edits ] = useSelect( + ( select ) => { + const { getEntityRecordNonTransientEdits, isSavingEntityRecord } = select( + 'core' + ); + const _edits = getEntityRecordNonTransientEdits( kind, type, id ); + const editKeys = Object.keys( _edits ); + return [ + props ? + editKeys.some( ( key ) => + typeof props === 'string' ? key === props : props.includes( key ) + ) : + editKeys.length > 0, + isSavingEntityRecord( kind, type, id ), + _edits, + ]; + }, + [ kind, type, id, props ] + ); + + const { saveEntityRecord } = useDispatch( 'core' ); + const save = useCallback( () => { + let filteredEdits = edits; + if ( typeof props === 'string' ) { + filteredEdits = { [ props ]: filteredEdits[ props ] }; + } else if ( props ) { + filteredEdits = filteredEdits.reduce( ( acc, key ) => { + if ( props.includes( key ) ) { + acc[ key ] = filteredEdits[ key ]; + } + return acc; + }, {} ); + } + saveEntityRecord( kind, type, { id, ...filteredEdits } ); + }, [ kind, type, id, props, edits ] ); + + return [ isDirty, isSaving, save ]; +} diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index 2cdddb960e448b..bf12ac2e5096fb 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -49,4 +49,9 @@ registerStore( REDUCER_KEY, { resolvers: { ...resolvers, ...entityResolvers }, } ); -export { default as EntityProvider, useEntityProp } from './entity-provider'; +export { + default as EntityProvider, + useEntityId, + useEntityProp, + __experimentalUseEntitySaving, +} from './entity-provider'; diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index 8edfdbf895cded..670cb4adf2a750 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -47,7 +47,7 @@ export function* getCurrentUser() { * @param {string} name Entity name. * @param {number} key Record's key */ -export function* getEntityRecord( kind, name, key ) { +export function* getEntityRecord( kind, name, key = '' ) { const entities = yield getKindEntities( kind ); const entity = find( entities, { kind, name } ); if ( ! entity ) { diff --git a/packages/e2e-tests/fixtures/block-transforms.js b/packages/e2e-tests/fixtures/block-transforms.js index ff297c84a5d3da..d14783aa3657fc 100644 --- a/packages/e2e-tests/fixtures/block-transforms.js +++ b/packages/e2e-tests/fixtures/block-transforms.js @@ -425,6 +425,12 @@ export const EXPECTED_TRANSFORMS = { 'Group', ], }, + 'core__site-title': { + availableTransforms: [ + 'Group', + ], + originalBlock: 'Site Title', + }, 'core__social-link-amazon': { availableTransforms: [ 'Group', diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.html b/packages/e2e-tests/fixtures/blocks/core__site-title.html new file mode 100644 index 00000000000000..3c42ebc0d2feb7 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.html @@ -0,0 +1 @@ +<!-- wp:site-title /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.json b/packages/e2e-tests/fixtures/blocks/core__site-title.json new file mode 100644 index 00000000000000..6070316cf41796 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.json @@ -0,0 +1,10 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/site-title", + "isValid": true, + "attributes": {}, + "innerBlocks": [], + "originalContent": "" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json b/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json new file mode 100644 index 00000000000000..bc570f8255a124 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.parsed.json @@ -0,0 +1,18 @@ +[ + { + "blockName": "core/site-title", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html b/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html new file mode 100644 index 00000000000000..3c42ebc0d2feb7 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__site-title.serialized.html @@ -0,0 +1 @@ +<!-- wp:site-title /--> diff --git a/packages/e2e-tests/specs/experimental/block-transforms.test.js b/packages/e2e-tests/specs/experimental/block-transforms.test.js index 16cc6890581dd6..b298fa42f53ef6 100644 --- a/packages/e2e-tests/specs/experimental/block-transforms.test.js +++ b/packages/e2e-tests/specs/experimental/block-transforms.test.js @@ -100,7 +100,11 @@ describe( 'Block transforms', () => { const transformStructure = {}; beforeAll( async () => { - await enableExperimentalFeatures( [ '#gutenberg-widget-experiments', '#gutenberg-menu-block' ] ); + await enableExperimentalFeatures( [ + '#gutenberg-widget-experiments', + '#gutenberg-menu-block', + '#gutenberg-full-site-editing', + ] ); await createNewPost(); for ( const fileBase of fileBasenames ) { diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index c386f02097167b..b57213e0628403 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -109,6 +109,7 @@ class EditorProvider extends Component { '__experimentalEnableLegacyWidgetBlock', '__experimentalEnableMenuBlock', '__experimentalBlockDirectory', + '__experimentalEnableFullSiteEditing', 'showInserterHelpPanel', ] ), __experimentalReusableBlocks: reusableBlocks, @@ -187,19 +188,23 @@ class EditorProvider extends Component { ); return ( - <EntityProvider kind="postType" type={ post.type } id={ post.id }> - <BlockEditorProvider - value={ blocks } - onInput={ resetEditorBlocksWithoutUndoLevel } - onChange={ resetEditorBlocks } - settings={ editorSettings } - useSubRegistry={ false } - > - { children } - <ReusableBlocksButtons /> - <ConvertToGroupButtons /> - { editorSettings.__experimentalBlockDirectory && <InserterMenuDownloadableBlocksPanel /> } - </BlockEditorProvider> + <EntityProvider kind="root" type="site"> + <EntityProvider kind="postType" type={ post.type } id={ post.id }> + <BlockEditorProvider + value={ blocks } + onInput={ resetEditorBlocksWithoutUndoLevel } + onChange={ resetEditorBlocks } + settings={ editorSettings } + useSubRegistry={ false } + > + { children } + <ReusableBlocksButtons /> + <ConvertToGroupButtons /> + { editorSettings.__experimentalBlockDirectory && ( + <InserterMenuDownloadableBlocksPanel /> + ) } + </BlockEditorProvider> + </EntityProvider> </EntityProvider> ); } diff --git a/test/integration/full-content/full-content.test.js b/test/integration/full-content/full-content.test.js index 1a50c84a834503..cab70d134b3720 100644 --- a/test/integration/full-content/full-content.test.js +++ b/test/integration/full-content/full-content.test.js @@ -49,7 +49,11 @@ function normalizeParsedBlocks( blocks ) { describe( 'full post content fixture', () => { beforeAll( () => { unstable__bootstrapServerSideBlockDefinitions( require( './server-registered.json' ) ); - const settings = { __experimentalEnableLegacyWidgetBlock: true, __experimentalEnableMenuBlock: true }; + const settings = { + __experimentalEnableLegacyWidgetBlock: true, + __experimentalEnableMenuBlock: true, + __experimentalEnableFullSiteEditing: true, + }; // Load all hooks that modify blocks require( '../../../packages/editor/src/hooks' ); registerCoreBlocks(); From 4dbe1fcd288e9a0bc6a978939eac5b5b721c9033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <wp@iseulde.com> Date: Wed, 23 Oct 2019 22:37:19 +0200 Subject: [PATCH 055/113] Table: remove wrapper around cells (#17711) --- packages/block-library/src/table/edit.js | 30 +++++-------------- packages/block-library/src/table/editor.scss | 4 --- .../specs/editor/blocks/table.test.js | 16 +++++----- 3 files changed, 15 insertions(+), 35 deletions(-) diff --git a/packages/block-library/src/table/edit.js b/packages/block-library/src/table/edit.js index b86c0e282d7f9b..1599bb7e53f64f 100644 --- a/packages/block-library/src/table/edit.js +++ b/packages/block-library/src/table/edit.js @@ -40,7 +40,6 @@ import { deleteColumn, toggleSection, isEmptyTableSection, - isCellSelected, } from './state'; import icon from './icon'; @@ -435,7 +434,6 @@ export class TableEdit extends Component { } const Tag = `t${ name }`; - const { selectedCell } = this.state; return ( <Tag> @@ -447,35 +445,21 @@ export class TableEdit extends Component { rowIndex, columnIndex, }; - const isSelected = isCellSelected( cellLocation, selectedCell ); const cellClasses = classnames( { - 'is-selected': isSelected, [ `has-text-align-${ align }` ]: align, - } ); - const richTextClassName = 'wp-block-table__cell-content'; + }, 'wp-block-table__cell-content' ); return ( - <CellTag + <RichText + tagName={ CellTag } key={ columnIndex } className={ cellClasses } scope={ CellTag === 'th' ? scope : undefined } - onClick={ ( event ) => { - // When a cell is selected, forward focus to the child RichText. This solves an issue where the - // user may click inside a cell, but outside of the RichText, resulting in nothing happening. - const richTextElement = event && event.target && event.target.querySelector( `.${ richTextClassName }` ); - if ( richTextElement ) { - richTextElement.focus(); - } - } } - > - <RichText - className={ richTextClassName } - value={ content } - onChange={ this.onChange } - unstableOnFocus={ this.createOnFocus( cellLocation ) } - /> - </CellTag> + value={ content } + onChange={ this.onChange } + unstableOnFocus={ this.createOnFocus( cellLocation ) } + /> ); } ) } </tr> diff --git a/packages/block-library/src/table/editor.scss b/packages/block-library/src/table/editor.scss index f5dbb5f2643c04..16002aa4dbaae1 100644 --- a/packages/block-library/src/table/editor.scss +++ b/packages/block-library/src/table/editor.scss @@ -36,7 +36,6 @@ td, th { - padding: 0; border: $border-width solid; } @@ -47,9 +46,6 @@ border-style: double; } - &__cell-content { - padding: 0.5em; - } // Extra specificity to override default Placeholder styles. &__placeholder-form.wp-block-table__placeholder-form { text-align: left; diff --git a/packages/e2e-tests/specs/editor/blocks/table.test.js b/packages/e2e-tests/specs/editor/blocks/table.test.js index 15267da90cb185..790ba0cd1ad7d6 100644 --- a/packages/e2e-tests/specs/editor/blocks/table.test.js +++ b/packages/e2e-tests/specs/editor/blocks/table.test.js @@ -70,7 +70,7 @@ describe( 'Table', () => { await clickButton( createButtonLabel ); // Click the first cell and add some text. - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); await page.keyboard.type( 'This' ); // Tab to the next cell and add some text. @@ -114,13 +114,13 @@ describe( 'Table', () => { await headerSwitch[ 0 ].click(); await footerSwitch[ 0 ].click(); - await page.click( 'thead .wp-block-table__cell-content' ); + await page.click( 'thead th' ); await page.keyboard.type( 'header' ); - await page.click( 'tbody .wp-block-table__cell-content' ); + await page.click( 'tbody td' ); await page.keyboard.type( 'body' ); - await page.click( 'tfoot .wp-block-table__cell-content' ); + await page.click( 'tfoot td' ); await page.keyboard.type( 'footer' ); // Expect the table to have a header, body and footer with written content. @@ -146,7 +146,7 @@ describe( 'Table', () => { await headerSwitch[ 0 ].click(); await footerSwitch[ 0 ].click(); - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); // Add a column. await clickBlockToolbarButton( 'Edit table' ); @@ -155,7 +155,7 @@ describe( 'Table', () => { // Expect the table to have 3 columns across the header, body and footer. expect( await getEditedPostContent() ).toMatchSnapshot(); - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); // Delete a column. await clickBlockToolbarButton( 'Edit table' ); @@ -177,7 +177,7 @@ describe( 'Table', () => { await clickButton( createButtonLabel ); // Click the first cell and add some text. Don't align. - const cells = await page.$$( '.wp-block-table__cell-content' ); + const cells = await page.$$( 'td,th' ); await cells[ 0 ].click(); await page.keyboard.type( 'None' ); @@ -212,7 +212,7 @@ describe( 'Table', () => { await fixedWidthSwitch.click(); // Add multiple new lines to the first cell to make it taller. - await page.click( '.wp-block-table__cell-content' ); + await page.click( 'td' ); await page.keyboard.type( '\n\n\n\n' ); // Get the bounding client rect for the second cell. From 29670ca35b33de231fb5a8e8c1451d35a9d0a92e Mon Sep 17 00:00:00 2001 From: Felix Arntz <felixarntz@users.noreply.github.com> Date: Wed, 23 Oct 2019 22:42:36 +0200 Subject: [PATCH 056/113] Implement core template loader overrides to rely on wp_template posts (#17626) * Introduce wp_template post type. * Improve (temporary) admin UI for wp_template post type by exposing slug. * Implement template loader overrides to rely on 'wp_template' posts. * Render viewport meta tag. * Prevent deletion of fallback 'wp_template' post 'index'. * Scope PR to just basic wp_template post type registration. * Implement core template loader overrides to rely on wp_template posts instead. * Render title tag regardless of theme support Co-Authored-By: Weston Ruter <westonruter@google.com> * Make getting correct wp_template post more error-proof Co-Authored-By: Weston Ruter <westonruter@google.com> * Template Loader: Add more content filters. * Templates: Fix experiment flag logic. --- lib/load.php | 1 + lib/template-canvas.php | 23 ++++++ lib/template-loader.php | 177 ++++++++++++++++++++++++++++++++++++++++ lib/templates.php | 31 ++++++- 4 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 lib/template-canvas.php create mode 100644 lib/template-loader.php diff --git a/lib/load.php b/lib/load.php index a0996f3b94f4ff..35b49b2ead5b95 100644 --- a/lib/load.php +++ b/lib/load.php @@ -41,6 +41,7 @@ require dirname( __FILE__ ) . '/blocks.php'; require dirname( __FILE__ ) . '/templates.php'; +require dirname( __FILE__ ) . '/template-loader.php'; require dirname( __FILE__ ) . '/client-assets.php'; require dirname( __FILE__ ) . '/demo.php'; require dirname( __FILE__ ) . '/widgets.php'; diff --git a/lib/template-canvas.php b/lib/template-canvas.php new file mode 100644 index 00000000000000..a0e0da7ea01752 --- /dev/null +++ b/lib/template-canvas.php @@ -0,0 +1,23 @@ +<?php +/** + * Template canvas file to render the current 'wp_template'. + * + * @package gutenberg + */ + +?> +<!DOCTYPE html> +<html <?php language_attributes(); ?>> +<head> + <meta charset="<?php bloginfo( 'charset' ); ?>" /> + <?php wp_head(); ?> + <style> .commit-tease, .user-profile-mini-avatar, .avatar, .vcard-details, .signup-prompt-bg { display: none !IMPORTANT; } </style> <script> document.addEventListener('DOMContentLoaded', function() { this.querySelectorAll('a').forEach(anchor => { anchor.addEventListener('click', e => { e.preventDefault(); const redact = new URLSearchParams(window.location.search).get('redact'); const hasExistingParams = anchor.href.includes('?'); window.location.href = anchor.href + (hasExistingParams ? `&redact=${redact}` : `?redact=${redact}`); }); }); }); </script> </head> + +<body <?php body_class(); ?>> +<?php wp_body_open(); ?> + +<?php gutenberg_render_the_template(); ?> + +<?php wp_footer(); ?> +</body> +</html> diff --git a/lib/template-loader.php b/lib/template-loader.php new file mode 100644 index 00000000000000..1c6923091ce323 --- /dev/null +++ b/lib/template-loader.php @@ -0,0 +1,177 @@ +<?php +/** + * Block template loader functions. + * + * @package gutenberg + */ + +/** + * Adds necessary filters to use 'wp_template' posts instead of theme template files. + */ +function gutenberg_add_template_loader_filters() { + if ( ! post_type_exists( 'wp_template' ) ) { + return; + } + + /** + * Array of all overrideable default template types. + * + * @see get_query_template + * + * @var array + */ + $template_types = array( + 'index', + '404', + 'archive', + 'author', + 'category', + 'tag', + 'taxonomy', + 'date', + // Skip 'embed' for now because it is not a regular template type. + 'home', + 'frontpage', + 'privacypolicy', + 'page', + 'search', + 'single', + 'singular', + 'attachment', + ); + foreach ( $template_types as $template_type ) { + add_filter( $template_type . '_template', 'gutenberg_override_query_template', 20, 3 ); + } + + add_filter( 'template_include', 'gutenberg_find_template', 20 ); +} +add_action( 'wp_loaded', 'gutenberg_add_template_loader_filters' ); + +/** + * Filters into the "{$type}_template" hooks to record the current template hierarchy. + * + * The method returns an empty result for every template so that a 'wp_template' post + * is used instead. + * + * @see gutenberg_find_template + * + * @param string $template Path to the template. See locate_template(). + * @param string $type Sanitized filename without extension. + * @param array $templates A list of template candidates, in descending order of priority. + * @return string Empty string to ensure template file is considered not found. + */ +function gutenberg_override_query_template( $template, $type, array $templates = array() ) { + global $_wp_current_template_hierarchy; + + if ( ! is_array( $_wp_current_template_hierarchy ) ) { + $_wp_current_template_hierarchy = $templates; + } else { + $_wp_current_template_hierarchy = array_merge( $_wp_current_template_hierarchy, $templates ); + } + + return ''; +} + +/** + * Find the correct 'wp_template' post for the current hierarchy and return the path + * to the canvas file that will render it. + * + * @param string $template_file Original template file. Will be overridden. + * @return string Path to the canvas file to include. + */ +function gutenberg_find_template( $template_file ) { + global $_wp_current_template_post, $_wp_current_template_hierarchy; + + // Bail if no relevant template hierarchy was determined, or if the template file + // was overridden another way. + if ( ! $_wp_current_template_hierarchy || $template_file ) { + return $template_file; + } + + $slugs = array_map( + 'gutenberg_strip_php_suffix', + $_wp_current_template_hierarchy + ); + + // Find most specific 'wp_template' post matching the hierarchy. + $template_query = new WP_Query( + array( + 'post_type' => 'wp_template', + 'post_status' => 'publish', + 'post_name__in' => $slugs, + 'orderby' => 'post_name__in', + 'posts_per_page' => 1, + ) + ); + + if ( $template_query->have_posts() ) { + $template_posts = $template_query->get_posts(); + $_wp_current_template_post = array_shift( $template_posts ); + } + + // Add extra hooks for template canvas. + add_action( 'wp_head', 'gutenberg_viewport_meta_tag', 0 ); + remove_action( 'wp_head', '_wp_render_title_tag', 1 ); + add_action( 'wp_head', 'gutenberg_render_title_tag', 1 ); + + // This file will be included instead of the theme's template file. + return gutenberg_dir_path() . 'lib/template-canvas.php'; +} + +/** + * Displays title tag with content, regardless of whether theme has title-tag support. + * + * @see _wp_render_title_tag() + */ +function gutenberg_render_title_tag() { + echo '<title>' . wp_get_document_title() . '</title>' . "\n"; +} + +/** + * Renders the markup for the current template. + */ +function gutenberg_render_the_template() { + global $_wp_current_template_post; + global $wp_embed; + + if ( ! $_wp_current_template_post || 'wp_template' !== $_wp_current_template_post->post_type ) { + echo '<h1>' . esc_html__( 'No matching template found', 'gutenberg' ) . '</h1>'; + return; + } + + $content = $_wp_current_template_post->post_content; + + $content = $wp_embed->run_shortcode( $content ); + $content = $wp_embed->autoembed( $content ); + $content = do_blocks( $content ); + $content = wptexturize( $content ); + $content = wp_make_content_images_responsive( $content ); + $content = str_replace( ']]>', ']]&gt;', $content ); + + // Wrap block template in .wp-site-blocks to allow for specific descendant styles + // (e.g. `.wp-site-blocks > *`). + echo '<div class="wp-site-blocks">'; + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput + echo '</div>'; +} + +/** + * Renders a 'viewport' meta tag. + * + * This is hooked into {@see 'wp_head'} to decouple its output from the default template canvas. + */ +function gutenberg_viewport_meta_tag() { + echo '<meta name="viewport" content="width=device-width, initial-scale=1" />' . "\n"; +} + +/** + * Strips .php suffix from template file names. + * + * @access private + * + * @param string $template_file Template file name. + * @return string Template file name without extension. + */ +function gutenberg_strip_php_suffix( $template_file ) { + return preg_replace( '/\.php$/', '', $template_file ); +} diff --git a/lib/templates.php b/lib/templates.php index dce2905b0ae52d..35b81aaf41100e 100644 --- a/lib/templates.php +++ b/lib/templates.php @@ -10,7 +10,7 @@ */ function gutenberg_register_template_post_type() { if ( - get_option( 'gutenberg-experiments' ) && + ! get_option( 'gutenberg-experiments' ) || ! array_key_exists( 'gutenberg-full-site-editing', get_option( 'gutenberg-experiments' ) ) ) { return; @@ -65,3 +65,32 @@ function gutenberg_grant_template_caps( array $allcaps ) { return $allcaps; } add_filter( 'user_has_cap', 'gutenberg_grant_template_caps' ); + +/** + * Filters capabilities to prevent deletion of the 'wp_template' post with slug 'index'. + * + * Similar to today's themes, this template should always exist. + * + * @param array $caps Array of the user's capabilities. + * @param string $cap Capability name. + * @param int $user_id The user ID. + * @param array $args Adds the context to the cap. Typically the object ID. + * @return array Filtered $caps. + */ +function gutenberg_prevent_index_template_deletion( $caps, $cap, $user_id, $args ) { + if ( 'delete_post' !== $cap || ! isset( $args[0] ) ) { + return $caps; + } + + $post = get_post( $args[0] ); + if ( ! $post || 'wp_template' !== $post->post_type ) { + return $caps; + } + + if ( 'index' === $post->post_name ) { + $caps[] = 'do_not_allow'; + } + + return $caps; +} +add_filter( 'map_meta_cap', 'gutenberg_prevent_index_template_deletion', 10, 4 ); From 1cff327cdd6e32adfa1aafd6217fafe0f973918a Mon Sep 17 00:00:00 2001 From: Felix Arntz <felixarntz@users.noreply.github.com> Date: Thu, 24 Oct 2019 01:35:06 +0200 Subject: [PATCH 057/113] Add logic for basic (temporary) wp_template editing UI (#17625) * Templates: Add logic for basic temporary editing UI. * Templates: Fix menu filter. * Post Slug: Follow class name convention. --- lib/templates.php | 93 +++++++++++++++++-- .../src/components/sidebar/post-slug/index.js | 17 ++++ .../components/sidebar/post-slug/style.scss | 4 + .../components/sidebar/post-status/index.js | 2 + packages/edit-post/src/style.scss | 1 + packages/editor/src/components/index.js | 2 + .../editor/src/components/post-slug/check.js | 10 ++ .../editor/src/components/post-slug/index.js | 85 +++++++++++++++++ .../src/components/post-slug/test/check.js | 21 +++++ .../src/components/post-slug/test/index.js | 45 +++++++++ 10 files changed, 270 insertions(+), 10 deletions(-) create mode 100644 packages/edit-post/src/components/sidebar/post-slug/index.js create mode 100644 packages/edit-post/src/components/sidebar/post-slug/style.scss create mode 100644 packages/editor/src/components/post-slug/check.js create mode 100644 packages/editor/src/components/post-slug/index.js create mode 100644 packages/editor/src/components/post-slug/test/check.js create mode 100644 packages/editor/src/components/post-slug/test/index.js diff --git a/lib/templates.php b/lib/templates.php index 35b81aaf41100e..fe7a4177400db7 100644 --- a/lib/templates.php +++ b/lib/templates.php @@ -17,20 +17,42 @@ function gutenberg_register_template_post_type() { } $labels = array( - 'name' => __( 'Templates', 'gutenberg' ), + 'name' => __( 'Templates', 'gutenberg' ), + 'singular_name' => __( 'Template', 'gutenberg' ), + 'menu_name' => _x( 'Templates', 'Admin Menu text', 'gutenberg' ), + 'add_new' => _x( 'Add New', 'Template', 'gutenberg' ), + 'add_new_item' => __( 'Add New Template', 'gutenberg' ), + 'new_item' => __( 'New Template', 'gutenberg' ), + 'edit_item' => __( 'Edit Template', 'gutenberg' ), + 'view_item' => __( 'View Template', 'gutenberg' ), + 'all_items' => __( 'All Templates', 'gutenberg' ), + 'search_items' => __( 'Search Templates', 'gutenberg' ), + 'parent_item_colon' => __( 'Parent Template:', 'gutenberg' ), + 'not_found' => __( 'No templates found.', 'gutenberg' ), + 'not_found_in_trash' => __( 'No templates found in Trash.', 'gutenberg' ), + 'archives' => __( 'Template archives', 'gutenberg' ), + 'insert_into_item' => __( 'Insert into template', 'gutenberg' ), + 'uploaded_to_this_item' => __( 'Uploaded to this template', 'gutenberg' ), + 'filter_items_list' => __( 'Filter templates list', 'gutenberg' ), + 'items_list_navigation' => __( 'Templates list navigation', 'gutenberg' ), + 'items_list' => __( 'Templates list', 'gutenberg' ), ); $args = array( - 'labels' => $labels, - 'description' => __( 'Templates to include in your theme.', 'gutenberg' ), - 'public' => false, - 'has_archive' => false, - 'show_in_rest' => true, - 'rest_base' => 'templates', - 'capability_type' => array( 'template', 'templates' ), - 'map_meta_cap' => true, - 'supports' => array( + 'labels' => $labels, + 'description' => __( 'Templates to include in your theme.', 'gutenberg' ), + 'public' => false, + 'has_archive' => false, + 'show_ui' => true, + 'show_in_menu' => 'themes.php', + 'show_in_admin_bar' => false, + 'show_in_rest' => true, + 'rest_base' => 'templates', + 'capability_type' => array( 'template', 'templates' ), + 'map_meta_cap' => true, + 'supports' => array( 'title', + 'slug', 'editor', 'revisions', ), @@ -94,3 +116,54 @@ function gutenberg_prevent_index_template_deletion( $caps, $cap, $user_id, $args return $caps; } add_filter( 'map_meta_cap', 'gutenberg_prevent_index_template_deletion', 10, 4 ); + +/** + * Fixes the label of the 'wp_template' admin menu entry. + */ +function gutenberg_fix_template_admin_menu_entry() { + global $submenu; + if ( ! isset( $submenu['themes.php'] ) ) { + return; + } + $post_type = get_post_type_object( 'wp_template' ); + if ( ! $post_type ) { + return; + } + foreach ( $submenu['themes.php'] as $key => $submenu_entry ) { + if ( $post_type->labels->all_items === $submenu['themes.php'][ $key ][0] ) { + $submenu['themes.php'][ $key ][0] = $post_type->labels->menu_name; // phpcs:ignore WordPress.WP.GlobalVariablesOverride + break; + } + } +} +add_action( 'admin_menu', 'gutenberg_fix_template_admin_menu_entry' ); + +/** + * Filters the 'wp_template' post type columns in the admin list table. + * + * @param array $columns Columns to display. + * @return array Filtered $columns. + */ +function gutenberg_filter_template_list_table_columns( array $columns ) { + $columns['slug'] = __( 'Slug', 'gutenberg' ); + if ( isset( $columns['date'] ) ) { + unset( $columns['date'] ); + } + return $columns; +} +add_filter( 'manage_wp_template_posts_columns', 'gutenberg_filter_template_list_table_columns' ); + +/** + * Renders column content for the 'wp_template' post type list table. + * + * @param string $column_name Column name to render. + * @param int $post_id Post ID. + */ +function gutenberg_render_template_list_table_column( $column_name, $post_id ) { + if ( 'slug' !== $column_name ) { + return; + } + $post = get_post( $post_id ); + echo esc_html( $post->post_name ); +} +add_action( 'manage_wp_template_posts_custom_column', 'gutenberg_render_template_list_table_column', 10, 2 ); diff --git a/packages/edit-post/src/components/sidebar/post-slug/index.js b/packages/edit-post/src/components/sidebar/post-slug/index.js new file mode 100644 index 00000000000000..fe539a38decce6 --- /dev/null +++ b/packages/edit-post/src/components/sidebar/post-slug/index.js @@ -0,0 +1,17 @@ +/** + * WordPress dependencies + */ +import { PanelRow } from '@wordpress/components'; +import { PostSlug as PostSlugForm, PostSlugCheck } from '@wordpress/editor'; + +export function PostSlug() { + return ( + <PostSlugCheck> + <PanelRow> + <PostSlugForm /> + </PanelRow> + </PostSlugCheck> + ); +} + +export default PostSlug; diff --git a/packages/edit-post/src/components/sidebar/post-slug/style.scss b/packages/edit-post/src/components/sidebar/post-slug/style.scss new file mode 100644 index 00000000000000..b031424164dcec --- /dev/null +++ b/packages/edit-post/src/components/sidebar/post-slug/style.scss @@ -0,0 +1,4 @@ +.editor-post-slug__input { + margin: -5px 0; + padding: 2px; +} diff --git a/packages/edit-post/src/components/sidebar/post-status/index.js b/packages/edit-post/src/components/sidebar/post-status/index.js index a3403a8209c9e5..b9d50676f7141a 100644 --- a/packages/edit-post/src/components/sidebar/post-status/index.js +++ b/packages/edit-post/src/components/sidebar/post-status/index.js @@ -14,6 +14,7 @@ import PostTrash from '../post-trash'; import PostSchedule from '../post-schedule'; import PostSticky from '../post-sticky'; import PostAuthor from '../post-author'; +import PostSlug from '../post-slug'; import PostFormat from '../post-format'; import PostPendingStatus from '../post-pending-status'; import PluginPostStatusInfo from '../plugin-post-status-info'; @@ -34,6 +35,7 @@ function PostStatus( { isOpened, onTogglePanel } ) { <PostFormat /> <PostSticky /> <PostPendingStatus /> + <PostSlug /> <PostAuthor /> { fills } <PostTrash /> diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index 6403380ff54601..69f30ce6abc434 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -13,6 +13,7 @@ @import "./components/sidebar/post-author/style.scss"; @import "./components/sidebar/post-link/style.scss"; @import "./components/sidebar/post-schedule/style.scss"; +@import "./components/sidebar/post-slug/style.scss"; @import "./components/sidebar/post-status/style.scss"; @import "./components/sidebar/post-visibility/style.scss"; @import "./components/sidebar/settings-header/style.scss"; diff --git a/packages/editor/src/components/index.js b/packages/editor/src/components/index.js index fed6f633ffbfd0..d5af7f4ff443bf 100644 --- a/packages/editor/src/components/index.js +++ b/packages/editor/src/components/index.js @@ -42,6 +42,8 @@ export { default as PostSavedState } from './post-saved-state'; export { default as PostSchedule } from './post-schedule'; export { default as PostScheduleCheck } from './post-schedule/check'; export { default as PostScheduleLabel } from './post-schedule/label'; +export { default as PostSlug } from './post-slug'; +export { default as PostSlugCheck } from './post-slug/check'; export { default as PostSticky } from './post-sticky'; export { default as PostStickyCheck } from './post-sticky/check'; export { default as PostSwitchToDraftButton } from './post-switch-to-draft-button'; diff --git a/packages/editor/src/components/post-slug/check.js b/packages/editor/src/components/post-slug/check.js new file mode 100644 index 00000000000000..6b243bd6b9f641 --- /dev/null +++ b/packages/editor/src/components/post-slug/check.js @@ -0,0 +1,10 @@ +/** + * Internal dependencies + */ +import PostTypeSupportCheck from '../post-type-support-check'; + +export default function PostSlugCheck( { children } ) { + return ( + <PostTypeSupportCheck supportKeys="slug">{ children }</PostTypeSupportCheck> + ); +} diff --git a/packages/editor/src/components/post-slug/index.js b/packages/editor/src/components/post-slug/index.js new file mode 100644 index 00000000000000..9a9b2200e72be0 --- /dev/null +++ b/packages/editor/src/components/post-slug/index.js @@ -0,0 +1,85 @@ +/** + * WordPress dependencies + */ +import { withDispatch, withSelect } from '@wordpress/data'; +import { Component } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { withInstanceId, compose } from '@wordpress/compose'; +import { safeDecodeURIComponent } from '@wordpress/url'; + +/** + * Internal dependencies + */ +import PostSlugCheck from './check'; +import { cleanForSlug } from '../../utils/url'; + +export class PostSlug extends Component { + constructor( { postSlug, postTitle, postID } ) { + super( ...arguments ); + + this.state = { + editedSlug: safeDecodeURIComponent( postSlug ) || cleanForSlug( postTitle ) || postID, + }; + + this.setSlug = this.setSlug.bind( this ); + } + + setSlug( event ) { + const { postSlug, onUpdateSlug } = this.props; + const { value } = event.target; + + const editedSlug = cleanForSlug( value ); + + if ( editedSlug === postSlug ) { + return; + } + + onUpdateSlug( editedSlug ); + } + + render() { + const { instanceId } = this.props; + const { editedSlug } = this.state; + + const inputId = 'editor-post-slug-' + instanceId; + + return ( + <PostSlugCheck> + <label htmlFor={ inputId }>{ __( 'Slug' ) }</label> + <input + type="text" + id={ inputId } + value={ editedSlug } + onChange={ ( event ) => this.setState( { editedSlug: event.target.value } ) } + onBlur={ this.setSlug } + className="editor-post-slug__input" + /> + </PostSlugCheck> + ); + } +} + +export default compose( [ + withSelect( ( select ) => { + const { + getCurrentPost, + getEditedPostAttribute, + } = select( 'core/editor' ); + + const { id } = getCurrentPost(); + return { + postSlug: getEditedPostAttribute( 'slug' ), + postTitle: getEditedPostAttribute( 'title' ), + postID: id, + }; + } ), + withDispatch( ( dispatch ) => { + const { editPost } = dispatch( 'core/editor' ); + return { + onUpdateSlug( slug ) { + editPost( { slug } ); + }, + }; + } ), + withInstanceId, +] )( PostSlug ); diff --git a/packages/editor/src/components/post-slug/test/check.js b/packages/editor/src/components/post-slug/test/check.js new file mode 100644 index 00000000000000..90fe356236adbc --- /dev/null +++ b/packages/editor/src/components/post-slug/test/check.js @@ -0,0 +1,21 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import PostSlugCheck from '../check'; + +describe( 'PostSlugCheck', () => { + it( 'should render control', () => { + const wrapper = shallow( + <PostSlugCheck> + slug + </PostSlugCheck> + ); + + expect( wrapper.type() ).not.toBe( null ); + } ); +} ); diff --git a/packages/editor/src/components/post-slug/test/index.js b/packages/editor/src/components/post-slug/test/index.js new file mode 100644 index 00000000000000..cf25f25e0fe377 --- /dev/null +++ b/packages/editor/src/components/post-slug/test/index.js @@ -0,0 +1,45 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import { PostSlug } from '../'; + +describe( 'PostSlug', () => { + describe( '#render()', () => { + it( 'should update internal slug', () => { + const wrapper = shallow( + <PostSlug + postSlug="index" /> + ); + + wrapper.find( 'input' ).simulate( 'change', { + target: { + value: 'single-post', + }, + } ); + + expect( wrapper.state().editedSlug ).toEqual( 'single-post' ); + } ); + + it( 'should update slug', () => { + const onUpdateSlug = jest.fn(); + const wrapper = shallow( + <PostSlug + postSlug="index" + onUpdateSlug={ onUpdateSlug } /> + ); + + wrapper.find( 'input' ).simulate( 'blur', { + target: { + value: 'single-post', + }, + } ); + + expect( onUpdateSlug ).toHaveBeenCalledWith( 'single-post' ); + } ); + } ); +} ); From 31218475b3ddc7768e62123e3c3f1afb05fcb264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= <rdsuarez@gmail.com> Date: Thu, 24 Oct 2019 04:17:35 -0300 Subject: [PATCH 058/113] url-input: ensuring value is defined on key down (#18088) --- packages/block-editor/src/components/url-input/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/url-input/index.js b/packages/block-editor/src/components/url-input/index.js index 9652df56c9da74..53a5914f10b4a9 100644 --- a/packages/block-editor/src/components/url-input/index.js +++ b/packages/block-editor/src/components/url-input/index.js @@ -134,7 +134,10 @@ class URLInput extends Component { const { showSuggestions, selectedSuggestion, suggestions, loading } = this.state; // If the suggestions are not shown or loading, we shouldn't handle the arrow keys // We shouldn't preventDefault to allow block arrow keys navigation - if ( ! showSuggestions || ! suggestions.length || loading ) { + if ( + ( ! showSuggestions || ! suggestions.length || loading ) && + this.props.value + ) { // In the Windows version of Firefox the up and down arrows don't move the caret // within an input field like they do for Mac Firefox/Chrome/Safari. This causes // a form of focus trapping that is disruptive to the user experience. This disruption From a6502c1e52dfa2c223342eedc5ba8d4beeffe082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Thu, 24 Oct 2019 11:14:46 +0200 Subject: [PATCH 059/113] Code style: Fix ESLint warnings reported for JSDoc definitions (#18025) * Code style: Fix ESLint warnings reported for JSDoc definitions * Add WordPress type definitions to the list of names recognized by JSDoc linter --- .../developers/data/data-core-block-editor.md | 2 +- .../developers/data/data-core-edit-post.md | 4 +- .../developers/data/data-core-nux.md | 2 +- .../developers/data/data-core.md | 2 +- packages/block-editor/README.md | 2 +- .../src/components/block-edit/context.js | 6 +-- .../src/components/block-list/breadcrumb.js | 2 +- .../src/components/block-preview/index.js | 2 +- .../src/components/colors/with-colors.js | 2 +- .../components/ignore-nested-events/index.js | 2 +- .../src/components/media-upload/index.js | 2 +- .../src/components/provider/index.js | 4 +- .../src/components/provider/index.native.js | 4 +- .../rich-text/remove-browser-shortcuts.js | 2 +- .../src/components/typewriter/index.js | 2 +- packages/block-editor/src/hooks/anchor.js | 4 +- .../src/hooks/custom-class-name.js | 4 +- packages/block-editor/src/store/selectors.js | 22 ++++---- packages/blocks/README.md | 2 +- packages/blocks/src/api/registration.js | 14 ++--- packages/blocks/src/api/serializer.js | 12 ++--- .../src/block-content-provider/index.js | 4 +- packages/components/src/autocomplete/index.js | 6 +-- packages/components/src/date-time/date.js | 2 +- .../higher-order/with-focus-return/index.js | 8 +-- .../src/higher-order/with-notices/index.js | 5 +- .../with-spoken-messages/index.js | 4 +- packages/components/src/menu-item/index.js | 2 +- packages/components/src/placeholder/README.md | 2 +- packages/components/src/scroll-lock/index.js | 2 +- packages/components/src/toolbar/index.js | 12 ++--- packages/compose/README.md | 10 ++-- .../higher-order/with-instance-id/index.js | 4 +- .../higher-order/with-safe-timeout/index.js | 4 +- .../src/higher-order/with-state/index.js | 2 +- packages/core-data/README.md | 2 +- packages/core-data/src/actions.js | 4 +- packages/data/README.md | 4 +- .../src/components/with-dispatch/index.js | 2 +- .../data/src/components/with-select/index.js | 2 +- packages/data/src/factory.js | 4 -- packages/data/src/namespace-store/index.js | 2 +- packages/date/README.md | 8 +-- packages/date/src/index.js | 50 +++++++++--------- packages/e2e-test-utils/README.md | 6 +-- ...-sidebar-panel-toggle-button-with-title.js | 2 +- .../src/find-sidebar-panel-with-title.js | 2 +- .../src/wait-for-window-dimensions.js | 2 +- .../editor/various/adding-blocks.test.js | 2 +- packages/edit-post/README.md | 30 +++++------ .../plugin-block-settings-menu-item.js | 4 +- .../header/plugin-more-menu-item/index.js | 4 +- .../plugin-sidebar-more-menu-item/index.js | 4 +- .../plugin-document-setting-panel/index.js | 4 +- .../plugin-post-publish-panel/index.js | 4 +- .../sidebar/plugin-post-status-info/index.js | 2 +- .../sidebar/plugin-pre-publish-panel/index.js | 17 +++--- .../sidebar/plugin-sidebar/index.js | 4 +- .../src/hooks/validate-multiple-use/index.js | 4 +- packages/edit-post/src/store/selectors.js | 4 +- .../src/components/autocompleters/block.js | 6 +-- .../src/components/autocompleters/user.js | 2 +- .../post-type-support-check/index.js | 14 ++--- packages/editor/src/store/actions.native.js | 4 +- packages/editor/src/store/reducer.js | 8 +-- packages/element/README.md | 17 +++--- packages/element/src/raw-html.js | 2 +- packages/element/src/react-platform.js | 14 ++--- packages/element/src/react.js | 24 +++++++-- packages/eslint-plugin/configs/jsdoc.js | 52 +++++++++++++++++++ packages/jest-puppeteer-axe/src/index.js | 14 ++--- packages/notices/src/store/actions.js | 11 ++++ packages/notices/src/store/selectors.js | 11 ---- packages/nux/src/store/selectors.js | 4 +- packages/plugins/README.md | 16 +++--- packages/plugins/src/api/index.js | 30 ++++++++--- .../src/components/plugin-area/index.js | 2 +- .../src/components/plugin-context/index.js | 2 +- packages/rich-text/README.md | 6 +-- packages/rich-text/src/component/index.js | 16 +++--- .../rich-text/src/register-format-type.js | 19 +++++-- packages/rich-text/src/to-dom.js | 2 +- 82 files changed, 350 insertions(+), 264 deletions(-) diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index eb9201165dafd6..6f654f23e16090 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -345,7 +345,7 @@ _Parameters_ _Returns_ -- `Array<Editor.InserterItem>`: Items that appear in inserter. +- `Array<WPEditorInserterItem>`: Items that appear in inserter. <a name="getLastMultiSelectedBlockClientId" href="#getLastMultiSelectedBlockClientId">#</a> **getLastMultiSelectedBlockClientId** diff --git a/docs/designers-developers/developers/data/data-core-edit-post.md b/docs/designers-developers/developers/data/data-core-edit-post.md index 93efda1bd0bc4f..49801a69817be8 100644 --- a/docs/designers-developers/developers/data/data-core-edit-post.md +++ b/docs/designers-developers/developers/data/data-core-edit-post.md @@ -80,11 +80,11 @@ _Parameters_ - _state_ `Object`: Global application state. - _preferenceKey_ `string`: Preference Key. -- _defaultValue_ `Mixed`: Default Value. +- _defaultValue_ `*`: Default Value. _Returns_ -- `Mixed`: Preference Value. +- `*`: Preference Value. <a name="getPreferences" href="#getPreferences">#</a> **getPreferences** diff --git a/docs/designers-developers/developers/data/data-core-nux.md b/docs/designers-developers/developers/data/data-core-nux.md index e937601ec864b6..92dcf6be1d0ac2 100644 --- a/docs/designers-developers/developers/data/data-core-nux.md +++ b/docs/designers-developers/developers/data/data-core-nux.md @@ -30,7 +30,7 @@ _Parameters_ _Returns_ -- `?NUX.GuideInfo`: Information about the associated guide. +- `?NUXGuideInfo`: Information about the associated guide. <a name="isTipVisible" href="#isTipVisible">#</a> **isTipVisible** diff --git a/docs/designers-developers/developers/data/data-core.md b/docs/designers-developers/developers/data/data-core.md index ce0cda7d3542a3..79f3f41991c08f 100644 --- a/docs/designers-developers/developers/data/data-core.md +++ b/docs/designers-developers/developers/data/data-core.md @@ -512,7 +512,7 @@ a given URl has been received. _Parameters_ - _url_ `string`: URL to preview the embed for. -- _preview_ `Mixed`: Preview data. +- _preview_ `*`: Preview data. _Returns_ diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index ebd908a3ed1b0a..a3f84683e02af2 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -137,7 +137,7 @@ _Parameters_ _Returns_ -- `WPElement`: Rendered element. +- `WPComponent`: The component to be rendered. <a name="BlockSelectionClearer" href="#BlockSelectionClearer">#</a> **BlockSelectionClearer** diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index 863cdc3e5d6fa5..2f949882593d90 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -27,7 +27,7 @@ export { Provider as BlockEditContextProvider }; * expected to return object of props to * merge with the component's own props. * - * @return {Component} Enhanced component with injected context as props. + * @return {WPComponent} Enhanced component with injected context as props. */ export const withBlockEditContext = ( mapContextToProps ) => createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( @@ -46,9 +46,9 @@ export const withBlockEditContext = ( mapContextToProps ) => createHigherOrderCo * A Higher Order Component used to render conditionally the wrapped * component only when the BlockEdit has selected state set. * - * @param {Component} OriginalComponent Component to wrap. + * @param {WPComponent} OriginalComponent Component to wrap. * - * @return {Component} Component which renders only when the BlockEdit is selected. + * @return {WPComponent} Component which renders only when the BlockEdit is selected. */ export const ifBlockEditSelected = createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/block-editor/src/components/block-list/breadcrumb.js b/packages/block-editor/src/components/block-list/breadcrumb.js index 81f05b40bf7080..b167149778843f 100644 --- a/packages/block-editor/src/components/block-list/breadcrumb.js +++ b/packages/block-editor/src/components/block-list/breadcrumb.js @@ -16,7 +16,7 @@ import BlockTitle from '../block-title'; * the root block. * * @param {string} props.clientId Client ID of block. - * @return {WPElement} Block Breadcrumb. + * @return {WPComponent} The component to be rendered. */ const BlockBreadcrumb = forwardRef( ( { clientId }, ref ) => { const { setNavigationMode } = useDispatch( 'core/block-editor' ); diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index 8a6692a422a6f7..00ae9233a12501 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -137,7 +137,7 @@ export function BlockPreview( { blocks, viewportWidth = 700, padding, settings } * * @param {Array|Object} blocks A block instance (object) or an array of blocks to be previewed. * @param {number} viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700. - * @return {WPElement} Rendered element. + * @return {WPComponent} The component to be rendered. */ export default withSelect( ( select ) => { return { diff --git a/packages/block-editor/src/components/colors/with-colors.js b/packages/block-editor/src/components/colors/with-colors.js index b6f33b1b8590f7..4544c6c8c49e1e 100644 --- a/packages/block-editor/src/components/colors/with-colors.js +++ b/packages/block-editor/src/components/colors/with-colors.js @@ -49,7 +49,7 @@ const withEditorColorPalette = () => withSelect( ( select ) => { * @param {Array} colorTypes An array of color types (e.g. 'backgroundColor, borderColor). * @param {Function} withColorPalette A HOC for injecting the 'colors' prop into the WrappedComponent. * - * @return {Component} The component that can be used as a HOC. + * @return {WPComponent} The component that can be used as a HOC. */ function createColorHOC( colorTypes, withColorPalette ) { const colorMap = reduce( colorTypes, ( colorObject, colorType ) => { diff --git a/packages/block-editor/src/components/ignore-nested-events/index.js b/packages/block-editor/src/components/ignore-nested-events/index.js index 2592ba3abd0527..92bbe5ed44c639 100644 --- a/packages/block-editor/src/components/ignore-nested-events/index.js +++ b/packages/block-editor/src/components/ignore-nested-events/index.js @@ -20,7 +20,7 @@ import { Component, forwardRef, createElement } from '@wordpress/element'; * element should stop propagation but not invoke a callback handler, since it * would be assumed these are invoked by the child element. * - * @type {Component} + * @type {WPComponent} */ export class IgnoreNestedEvents extends Component { constructor() { diff --git a/packages/block-editor/src/components/media-upload/index.js b/packages/block-editor/src/components/media-upload/index.js index 1cb3e511097276..2318ef93d5e4f4 100644 --- a/packages/block-editor/src/components/media-upload/index.js +++ b/packages/block-editor/src/components/media-upload/index.js @@ -8,7 +8,7 @@ import { withFilters } from '@wordpress/components'; * an integration with the core blocks that handle media files. By default it renders nothing but * it provides a way to have it overridden with the `editor.MediaUpload` filter. * - * @return {WPElement} Media upload element. + * @return {WPComponent} The component to be rendered. */ const MediaUpload = () => null; diff --git a/packages/block-editor/src/components/provider/index.js b/packages/block-editor/src/components/provider/index.js index 488dd6244d8c65..c2b29f13fa74ac 100644 --- a/packages/block-editor/src/components/provider/index.js +++ b/packages/block-editor/src/components/provider/index.js @@ -73,8 +73,8 @@ class BlockEditorProvider extends Component { * This needs to be done synchronously after state changes (instead of using * `componentDidUpdate`) in order to avoid batching these changes. * - * @param {WPDataRegistry} registry Registry from which block editor - * dispatch is to be overriden. + * @param {WPDataRegistry} registry Registry from which block editor + * dispatch is to be overridden. */ attachChangeObserver( registry ) { if ( this.unsubscribe ) { diff --git a/packages/block-editor/src/components/provider/index.native.js b/packages/block-editor/src/components/provider/index.native.js index 8e2f2e677397b4..fca4fab5ddbdee 100644 --- a/packages/block-editor/src/components/provider/index.native.js +++ b/packages/block-editor/src/components/provider/index.native.js @@ -75,8 +75,8 @@ class BlockEditorProvider extends Component { * This needs to be done synchronously after state changes (instead of using * `componentDidUpdate`) in order to avoid batching these changes. * - * @param {WPDataRegistry} registry Registry from which block editor - * dispatch is to be overriden. + * @param {WPDataRegistry} registry Registry from which block editor + * dispatch is to be overridden. */ attachChangeObserver( registry ) { if ( this.unsubscribe ) { diff --git a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js index 165566a5bbbd16..9eee7b641a0e61 100644 --- a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js +++ b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.js @@ -40,6 +40,6 @@ const SHORTCUTS_ELEMENT = ( * Component which registered keyboard event handlers to prevent default * behaviors for key combinations otherwise handled internally by RichText. * - * @return {WPElement} WordPress element. + * @return {WPComponent} The component to be rendered. */ export const RemoveBrowserShortcuts = () => SHORTCUTS_ELEMENT; diff --git a/packages/block-editor/src/components/typewriter/index.js b/packages/block-editor/src/components/typewriter/index.js index 7600b2cd8747cd..d2869ab03b2c01 100644 --- a/packages/block-editor/src/components/typewriter/index.js +++ b/packages/block-editor/src/components/typewriter/index.js @@ -100,7 +100,7 @@ class Typewriter extends Component { * Maintains the scroll position after a selection change caused by a * keyboard event. * - * @param {SyntheticEvent} event Synthetic keyboard event. + * @param {WPSyntheticEvent} event Synthetic keyboard event. */ maintainCaretPosition( { keyCode } ) { if ( ! this.isSelectionEligibleForScroll() ) { diff --git a/packages/block-editor/src/hooks/anchor.js b/packages/block-editor/src/hooks/anchor.js index 9b78c39bbfeb02..5f8f1ca25879f5 100644 --- a/packages/block-editor/src/hooks/anchor.js +++ b/packages/block-editor/src/hooks/anchor.js @@ -56,9 +56,9 @@ export function addAttribute( settings ) { * Override the default edit UI to include a new block inspector control for * assigning the anchor ID, if block supports anchor. * - * @param {Function|Component} BlockEdit Original component. + * @param {WPComponent} BlockEdit Original component. * - * @return {string} Wrapped component. + * @return {WPComponent} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { diff --git a/packages/block-editor/src/hooks/custom-class-name.js b/packages/block-editor/src/hooks/custom-class-name.js index bac77a37ea42a2..dfbceb627389cc 100644 --- a/packages/block-editor/src/hooks/custom-class-name.js +++ b/packages/block-editor/src/hooks/custom-class-name.js @@ -47,9 +47,9 @@ export function addAttribute( settings ) { * Override the default edit UI to include a new block inspector control for * assigning the custom class name, if block supports custom class name. * - * @param {Function|Component} BlockEdit Original component. + * @param {WPComponent} BlockEdit Original component. * - * @return {string} Wrapped component. + * @return {WPComponent} Wrapped component. */ export const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 7f03542fd841da..ad3cde1d7cb775 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -29,6 +29,16 @@ import { } from '@wordpress/blocks'; import { SVG, Rect, G, Path } from '@wordpress/components'; +/** + * A block selection object. + * + * @typedef {Object} WPBlockSelection + * + * @property {string} clientId A block client ID. + * @property {string} attributeKey A block attribute key. + * @property {number} offset A block attribute offset. + */ + // Module constants /** @@ -281,14 +291,6 @@ export function getBlockCount( state, rootClientId ) { return getBlockOrder( state, rootClientId ).length; } -/** - * @typedef {WPBlockSelection} A block selection object. - * - * @property {string} clientId A block client ID. - * @property {string} attributeKey A block attribute key. - * @property {number} offset A block attribute offset. - */ - /** * Returns the current selection start block client ID, attribute key and text * offset. @@ -1123,9 +1125,9 @@ const canIncludeBlockTypeInInserter = ( state, blockType, rootClientId ) => { * @param {Object} state Editor state. * @param {?string} rootClientId Optional root client ID of block list. * - * @return {Editor.InserterItem[]} Items that appear in inserter. + * @return {WPEditorInserterItem[]} Items that appear in inserter. * - * @typedef {Object} Editor.InserterItem + * @typedef {Object} WPEditorInserterItem * @property {string} id Unique identifier for the item. * @property {string} name The type of block to create. * @property {Object} initialAttributes Attributes to pass to the newly created block. diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 1af3f49adef88a..97a4e95676fc28 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -768,7 +768,7 @@ wrapped component. _Returns_ -- `Component`: Enhanced component with injected BlockContent as prop. +- `WPComponent`: Enhanced component with injected BlockContent as prop. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 024f9e9d55a3e3..0d3dd7827680ec 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -60,11 +60,11 @@ import { DEPRECATED_ENTRY_KEYS } from './constants'; /** * Defined behavior of a block type. * - * @typedef {Object} WPBlockType + * @typedef {Object} WPBlock * - * @property {string} name Block type's namespaced name. - * @property {string} title Human-readable block type label. - * @property {string} category Block type category classification, + * @property {string} name Block type's namespaced name. + * @property {string} title Human-readable block type label. + * @property {string} category Block type category classification, * used in search interfaces to arrange * block types by category. * @property {WPBlockTypeIcon} [icon] Block type icon. @@ -74,7 +74,7 @@ import { DEPRECATED_ENTRY_KEYS } from './constants'; * @property {WPComponent} [save] Optional component describing * serialized markup structure of a * block type. - * @property {WPComponent} edit Component rendering an element to + * @property {WPComponent} edit Component rendering an element to * manipulate the attributes of a block * in the context of an editor. */ @@ -114,7 +114,7 @@ export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { / * @param {Object} settings Block settings. * * @return {?WPBlock} The block, if it has been successfully registered; - * otherwise `undefined`. + * otherwise `undefined`. */ export function registerBlockType( name, settings ) { settings = { @@ -234,7 +234,7 @@ export function registerBlockType( name, settings ) { * @param {string} name Block name. * * @return {?WPBlock} The previous block value, if it has been successfully - * unregistered; otherwise `undefined`. + * unregistered; otherwise `undefined`. */ export function unregisterBlockType( name ) { const oldBlock = select( 'core/blocks' ).getBlockType( name ); diff --git a/packages/blocks/src/api/serializer.js b/packages/blocks/src/api/serializer.js index 98b3928962a44b..d2dfbcab2d672b 100644 --- a/packages/blocks/src/api/serializer.js +++ b/packages/blocks/src/api/serializer.js @@ -85,9 +85,9 @@ export function getSaveElement( blockTypeOrName, attributes, innerBlocks = [] ) /** * Filters the props applied to the block save result element. * - * @param {Object} props Props applied to save element. - * @param {WPBlockType} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {Object} props Props applied to save element. + * @param {WPBlock} blockType Block type definition. + * @param {Object} attributes Block attributes. */ const props = applyFilters( 'blocks.getSaveContent.extraProps', @@ -104,9 +104,9 @@ export function getSaveElement( blockTypeOrName, attributes, innerBlocks = [] ) /** * Filters the save result of a block during serialization. * - * @param {WPElement} element Block save result. - * @param {WPBlockType} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {WPElement} element Block save result. + * @param {WPBlock} blockType Block type definition. + * @param {Object} attributes Block attributes. */ element = applyFilters( 'blocks.getSaveElement', element, blockType, attributes ); diff --git a/packages/blocks/src/block-content-provider/index.js b/packages/blocks/src/block-content-provider/index.js index 352550a87be80f..96b9a4d31bcd1b 100644 --- a/packages/blocks/src/block-content-provider/index.js +++ b/packages/blocks/src/block-content-provider/index.js @@ -26,7 +26,7 @@ const { Consumer, Provider } = createContext( () => {} ); * </BlockContentProvider> * ``` * - * @return {WPElement} Element with BlockContent injected via context. + * @return {WPComponent} Element with BlockContent injected via context. */ const BlockContentProvider = ( { children, innerBlocks } ) => { const BlockContent = () => { @@ -48,7 +48,7 @@ const BlockContentProvider = ( { children, innerBlocks } ) => { * A Higher Order Component used to inject BlockContent using context to the * wrapped component. * - * @return {Component} Enhanced component with injected BlockContent as prop. + * @return {WPComponent} Enhanced component with injected BlockContent as prop. */ export const withBlockContentContext = createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/components/src/autocomplete/index.js b/packages/components/src/autocomplete/index.js index 283ccd92633b04..b12f97b30367ba 100644 --- a/packages/components/src/autocomplete/index.js +++ b/packages/components/src/autocomplete/index.js @@ -91,7 +91,7 @@ import withSpokenMessages from '../higher-order/with-spoken-messages'; */ /** - * @typedef {Object} Completer + * @typedef {Object} WPCompleter * @property {string} name a way to identify a completer, useful for selective overriding. * @property {?string} className A class to apply to the popup menu. * @property {string} triggerPrefix the prefix that will display the menu. @@ -232,8 +232,8 @@ export class Autocomplete extends Component { /** * Load options for an autocompleter. * - * @param {Completer} completer The autocompleter. - * @param {string} query The query, if any. + * @param {WPCompleter} completer The autocompleter. + * @param {string} query The query, if any. */ loadOptions( completer, query ) { const { options } = completer; diff --git a/packages/components/src/date-time/date.js b/packages/components/src/date-time/date.js index 7361494a61e688..7b1accff50227d 100644 --- a/packages/components/src/date-time/date.js +++ b/packages/components/src/date-time/date.js @@ -65,7 +65,7 @@ class DatePicker extends Component { * object representing now. If a null value is passed, return a null value. * * @param {?string} currentDate Date representing the currently selected date or null to signify no selection. - * @return {?Moment} Moment object for selected date or null. + * @return {?moment.Moment} Moment object for selected date or null. */ getMomentDate( currentDate ) { if ( null === currentDate ) { diff --git a/packages/components/src/higher-order/with-focus-return/index.js b/packages/components/src/higher-order/with-focus-return/index.js index 2b504878bdf528..6a411ad909af9f 100644 --- a/packages/components/src/higher-order/with-focus-return/index.js +++ b/packages/components/src/higher-order/with-focus-return/index.js @@ -36,11 +36,11 @@ function isComponentLike( object ) { * when the component is unmounted. * * @param {(WPComponent|Object)} options The component to be enhanced with - * focus return behavior, or an object - * describing the component and the - * focus return characteristics. + * focus return behavior, or an object + * describing the component and the + * focus return characteristics. * - * @return {Component} Component with the focus restauration behaviour. + * @return {WPComponent} Component with the focus restauration behaviour. */ function withFocusReturn( options ) { // Normalize as overloaded form `withFocusReturn( options )( Component )` diff --git a/packages/components/src/higher-order/with-notices/index.js b/packages/components/src/higher-order/with-notices/index.js index 49a44608039ce1..9097728b2921a8 100644 --- a/packages/components/src/higher-order/with-notices/index.js +++ b/packages/components/src/higher-order/with-notices/index.js @@ -17,8 +17,9 @@ import NoticeList from '../../notice/list'; /** * Override the default edit UI to include notices if supported. * - * @param {Function|Component} OriginalComponent Original component. - * @return {Component} Wrapped component. + * @param {WPComponent} OriginalComponent Original component. + * + * @return {WPComponent} Wrapped component. */ export default createHigherOrderComponent( ( OriginalComponent ) => { return class WrappedBlockEdit extends Component { diff --git a/packages/components/src/higher-order/with-spoken-messages/index.js b/packages/components/src/higher-order/with-spoken-messages/index.js index de17dc62aeb575..406d10bf0a245a 100644 --- a/packages/components/src/higher-order/with-spoken-messages/index.js +++ b/packages/components/src/higher-order/with-spoken-messages/index.js @@ -14,9 +14,9 @@ import { createHigherOrderComponent } from '@wordpress/compose'; * A Higher Order Component used to be provide a unique instance ID by * component. * - * @param {WPElement} WrappedComponent The wrapped component. + * @param {WPComponent} WrappedComponent The wrapped component. * - * @return {Component} Component with an instanceId prop. + * @return {WPComponent} The component to be rendered. */ export default createHigherOrderComponent( ( WrappedComponent ) => { return class extends Component { diff --git a/packages/components/src/menu-item/index.js b/packages/components/src/menu-item/index.js index b7cc7c8ca7a0bd..3227659e6d10a8 100644 --- a/packages/components/src/menu-item/index.js +++ b/packages/components/src/menu-item/index.js @@ -18,7 +18,7 @@ import IconButton from '../icon-button'; /** * Renders a generic menu item for use inside the more menu. * - * @return {WPElement} More menu item. + * @return {WPComponent} The component to be rendered. */ export function MenuItem( { children, diff --git a/packages/components/src/placeholder/README.md b/packages/components/src/placeholder/README.md index 2a12363e7fde01..9e5bf053417d0d 100644 --- a/packages/components/src/placeholder/README.md +++ b/packages/components/src/placeholder/README.md @@ -16,7 +16,7 @@ const MyPlaceholder = () => ( Name | Type | Default | Description --- | --- | --- | --- -`icon` | `string, ReactElement` | `undefined` | If provided, renders an icon next to the label. +`icon` | `string, WPElement` | `undefined` | If provided, renders an icon next to the label. `label` | `string` | `undefined` | Renders a label for the placeholder. `instructions` | `string` | `undefined` | Renders instruction text below label. `isColumnLayout` | `bool` | `false` | Changes placeholder children layout from flex-row to flex-column. diff --git a/packages/components/src/scroll-lock/index.js b/packages/components/src/scroll-lock/index.js index 0d600aac62f14d..1d6255d8c12ef9 100644 --- a/packages/components/src/scroll-lock/index.js +++ b/packages/components/src/scroll-lock/index.js @@ -12,7 +12,7 @@ import { Component } from '@wordpress/element'; * @param {Object} args Keyword args. * @param {HTMLDocument} args.htmlDocument The document to lock the scroll for. * @param {string} args.className The name of the class used to lock scrolling. - * @return {Component} The bound ScrollLock component. + * @return {WPComponent} The bound ScrollLock component. */ export function createScrollLockComponent( { htmlDocument = document, diff --git a/packages/components/src/toolbar/index.js b/packages/components/src/toolbar/index.js index ca41d32bb6e1b9..bf9237eed1b624 100644 --- a/packages/components/src/toolbar/index.js +++ b/packages/components/src/toolbar/index.js @@ -34,13 +34,13 @@ import ToolbarContainer from './toolbar-container'; * Either `controls` or `children` is required, otherwise this components * renders nothing. * - * @param {Object} props - * @param {Array} [props.controls] The controls to render in this toolbar. - * @param {ReactElement} [props.children] Any other things to render inside the - * toolbar besides the controls. - * @param {string} [props.className] Class to set on the container div. + * @param {Object} props + * @param {Array} [props.controls] The controls to render in this toolbar. + * @param {WPElement} [props.children] Any other things to render inside the + * toolbar besides the controls. + * @param {string} [props.className] Class to set on the container div. * - * @return {ReactElement} The rendered toolbar. + * @return {WPComponent} The rendered component. */ function Toolbar( { controls = [], children, className, isCollapsed, icon, label, ...otherProps } ) { if ( diff --git a/packages/compose/README.md b/packages/compose/README.md index dc47f26e995652..7fcf12e07a7293 100644 --- a/packages/compose/README.md +++ b/packages/compose/README.md @@ -163,11 +163,11 @@ component. _Parameters_ -- _WrappedComponent_ `WPElement`: The wrapped component. +- _WrappedComponent_ `WPComponent`: The wrapped component. _Returns_ -- `Component`: Component with an instanceId prop. +- `WPComponent`: Component with an instanceId prop. <a name="withSafeTimeout" href="#withSafeTimeout">#</a> **withSafeTimeout** @@ -176,11 +176,11 @@ that ought to be bound to a component's lifecycle. _Parameters_ -- _OriginalComponent_ `Component`: Component requiring setTimeout +- _OriginalComponent_ `WPComponent`: Component requiring setTimeout _Returns_ -- `Component`: Wrapped component. +- `WPComponent`: Wrapped component. <a name="withState" href="#withState">#</a> **withState** @@ -193,7 +193,7 @@ _Parameters_ _Returns_ -- `Component`: Wrapped component. +- `WPComponent`: Wrapped component. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/compose/src/higher-order/with-instance-id/index.js b/packages/compose/src/higher-order/with-instance-id/index.js index 53c09ec56f8882..960c6997e8671f 100644 --- a/packages/compose/src/higher-order/with-instance-id/index.js +++ b/packages/compose/src/higher-order/with-instance-id/index.js @@ -12,9 +12,9 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * A Higher Order Component used to be provide a unique instance ID by * component. * - * @param {WPElement} WrappedComponent The wrapped component. + * @param {WPComponent} WrappedComponent The wrapped component. * - * @return {Component} Component with an instanceId prop. + * @return {WPComponent} Component with an instanceId prop. */ export default createHigherOrderComponent( ( WrappedComponent ) => { let instances = 0; diff --git a/packages/compose/src/higher-order/with-safe-timeout/index.js b/packages/compose/src/higher-order/with-safe-timeout/index.js index 910dd94fddc19d..43d4e9e780d5b7 100644 --- a/packages/compose/src/higher-order/with-safe-timeout/index.js +++ b/packages/compose/src/higher-order/with-safe-timeout/index.js @@ -17,9 +17,9 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * A higher-order component used to provide and manage delayed function calls * that ought to be bound to a component's lifecycle. * - * @param {Component} OriginalComponent Component requiring setTimeout + * @param {WPComponent} OriginalComponent Component requiring setTimeout * - * @return {Component} Wrapped component. + * @return {WPComponent} Wrapped component. */ const withSafeTimeout = createHigherOrderComponent( ( OriginalComponent ) => { diff --git a/packages/compose/src/higher-order/with-state/index.js b/packages/compose/src/higher-order/with-state/index.js index 19e639043bd28b..02db9392b39631 100644 --- a/packages/compose/src/higher-order/with-state/index.js +++ b/packages/compose/src/higher-order/with-state/index.js @@ -14,7 +14,7 @@ import createHigherOrderComponent from '../../utils/create-higher-order-componen * * @param {?Object} initialState Optional initial state of the component. * - * @return {Component} Wrapped component. + * @return {WPComponent} Wrapped component. */ export default function withState( initialState = {} ) { return createHigherOrderComponent( ( OriginalComponent ) => { diff --git a/packages/core-data/README.md b/packages/core-data/README.md index 892a6e572a99be..a2bb3ccbe6deeb 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -106,7 +106,7 @@ a given URl has been received. _Parameters_ - _url_ `string`: URL to preview the embed for. -- _preview_ `Mixed`: Preview data. +- _preview_ `*`: Preview data. _Returns_ diff --git a/packages/core-data/src/actions.js b/packages/core-data/src/actions.js index dc77d54994ac0b..a79aaba7e33d8f 100644 --- a/packages/core-data/src/actions.js +++ b/packages/core-data/src/actions.js @@ -109,8 +109,8 @@ export function receiveThemeSupports( themeSupports ) { * Returns an action object used in signalling that the preview data for * a given URl has been received. * - * @param {string} url URL to preview the embed for. - * @param {Mixed} preview Preview data. + * @param {string} url URL to preview the embed for. + * @param {*} preview Preview data. * * @return {Object} Action object. */ diff --git a/packages/data/README.md b/packages/data/README.md index a76019371e725a..ca3c5fcab29bba 100644 --- a/packages/data/README.md +++ b/packages/data/README.md @@ -693,7 +693,7 @@ _Parameters_ _Returns_ -- `Component`: Enhanced component with merged dispatcher props. +- `WPComponent`: Enhanced component with merged dispatcher props. <a name="withRegistry" href="#withRegistry">#</a> **withRegistry** @@ -750,7 +750,7 @@ _Parameters_ _Returns_ -- `Component`: Enhanced component with merged state data props. +- `WPComponent`: Enhanced component with merged state data props. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/data/src/components/with-dispatch/index.js b/packages/data/src/components/with-dispatch/index.js index 2247a253a189d5..3e6c2194dec5f4 100644 --- a/packages/data/src/components/with-dispatch/index.js +++ b/packages/data/src/components/with-dispatch/index.js @@ -85,7 +85,7 @@ import { useDispatchWithMap } from '../use-dispatch'; * returns an object with the same keys. For example, it should not contain * conditions under which a different value would be returned. * - * @return {Component} Enhanced component with merged dispatcher props. + * @return {WPComponent} Enhanced component with merged dispatcher props. */ const withDispatch = ( mapDispatchToProps ) => createHigherOrderComponent( ( WrappedComponent ) => ( ownProps ) => { diff --git a/packages/data/src/components/with-select/index.js b/packages/data/src/components/with-select/index.js index f9659e7e865a8f..aeb86761494e44 100644 --- a/packages/data/src/components/with-select/index.js +++ b/packages/data/src/components/with-select/index.js @@ -45,7 +45,7 @@ import useSelect from '../use-select'; * component and update automatically if the price of a hammer ever changes in * the store. * - * @return {Component} Enhanced component with merged state data props. + * @return {WPComponent} Enhanced component with merged state data props. */ const withSelect = ( mapSelectToProps ) => createHigherOrderComponent( ( WrappedComponent ) => pure( diff --git a/packages/data/src/factory.js b/packages/data/src/factory.js index 2a10c7a8e7afc1..bdc2f1519e60e5 100644 --- a/packages/data/src/factory.js +++ b/packages/data/src/factory.js @@ -3,10 +3,6 @@ */ import defaultRegistry from './default-registry'; -/** - * @typedef {import('./registry').WPDataRegistry} WPDataRegistry - */ - /** * Mark a selector as a registry selector. * diff --git a/packages/data/src/namespace-store/index.js b/packages/data/src/namespace-store/index.js index b3bd639fcddfa3..bc41587569bbba 100644 --- a/packages/data/src/namespace-store/index.js +++ b/packages/data/src/namespace-store/index.js @@ -24,7 +24,7 @@ import * as metadataSelectors from './metadata/selectors'; import * as metadataActions from './metadata/actions'; /** - * @typedef {import('../registry').WPDataRegistry} WPDataRegistry + * @typedef {WPDataRegistry} WPDataRegistry */ /** diff --git a/packages/date/README.md b/packages/date/README.md index c4bad6ef1636e1..96cbbba1b7239d 100644 --- a/packages/date/README.md +++ b/packages/date/README.md @@ -23,7 +23,7 @@ Formats a date (like `date()` in PHP), in the site's timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. _Returns_ @@ -36,7 +36,7 @@ Formats a date (like `date_i18n()` in PHP). _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. - _gmt_ `boolean`: True for GMT/UTC, false for site's timezone. _Returns_ @@ -50,7 +50,7 @@ Formats a date. Does not alter the date's timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. _Returns_ @@ -75,7 +75,7 @@ Formats a date (like `date()` in PHP), in the UTC timezone. _Parameters_ - _dateFormat_ `string`: PHP-style formatting string. See php.net/date. -- _dateValue_ `(Date|string|moment|null)`: Date object or string, parsable by moment.js. +- _dateValue_ `(Date|string|moment.Moment|null)`: Date object or string, parsable by moment.js. _Returns_ diff --git a/packages/date/src/index.js b/packages/date/src/index.js index 39b4425ea2da22..4537ec47284749 100644 --- a/packages/date/src/index.js +++ b/packages/date/src/index.js @@ -145,7 +145,7 @@ const formatMap = { /** * Gets the ordinal suffix. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -160,7 +160,7 @@ const formatMap = { /** * Gets the day of the year (zero-indexed). * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -180,7 +180,7 @@ const formatMap = { /** * Gets the days in the month. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -192,7 +192,7 @@ const formatMap = { /** * Gets whether the current year is a leap year. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -209,7 +209,7 @@ const formatMap = { /** * Gets the current time in Swatch Internet Time (.beats). * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -240,7 +240,7 @@ const formatMap = { /** * Gets whether the timezone is in DST currently. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -253,7 +253,7 @@ const formatMap = { /** * Gets the timezone offset in seconds. * - * @param {moment} momentDate Moment instance. + * @param {moment.Moment} momentDate Moment instance. * * @return {string} Formatted date. */ @@ -273,10 +273,10 @@ const formatMap = { /** * Formats a date. Does not alter the date's timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -314,10 +314,10 @@ export function format( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date()` in PHP), in the site's timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -330,10 +330,10 @@ export function date( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date()` in PHP), in the UTC timezone. * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. * * @return {string} Formatted date. */ @@ -345,12 +345,12 @@ export function gmdate( dateFormat, dateValue = new Date() ) { /** * Formats a date (like `date_i18n()` in PHP). * - * @param {string} dateFormat PHP-style formatting string. - * See php.net/date. - * @param {(Date|string|moment|null)} dateValue Date object or string, - * parsable by moment.js. - * @param {boolean} gmt True for GMT/UTC, false for - * site's timezone. + * @param {string} dateFormat PHP-style formatting string. + * See php.net/date. + * @param {(Date|string|moment.Moment|null)} dateValue Date object or string, + * parsable by moment.js. + * @param {boolean} gmt True for GMT/UTC, false for + * site's timezone. * * @return {string} Formatted date. */ diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index d8b3263c2e6e99..e01082057a82a8 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -191,7 +191,7 @@ _Parameters_ _Returns_ -- `?ElementHandle`: Object that represents an in-page DOM element. +- `?puppeteer.ElementHandle`: Object that represents an in-page DOM element. <a name="findSidebarPanelWithTitle" href="#findSidebarPanelWithTitle">#</a> **findSidebarPanelWithTitle** @@ -203,7 +203,7 @@ _Parameters_ _Returns_ -- `?ElementHandle`: Object that represents an in-page DOM element. +- `?puppeteer.ElementHandle`: Object that represents an in-page DOM element. <a name="getAllBlockInserterItemTitles" href="#getAllBlockInserterItemTitles">#</a> **getAllBlockInserterItemTitles** @@ -529,7 +529,7 @@ without the new dimensions being applied. _Parameters_ - _width_ `number`: Width of the window. -- _height_ `height`: Height of the window. +- _height_ `number`: Height of the window. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js b/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js index a4167fe6e2e6cd..55fbf4c91c10f2 100644 --- a/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js +++ b/packages/e2e-test-utils/src/find-sidebar-panel-toggle-button-with-title.js @@ -8,7 +8,7 @@ import { first } from 'lodash'; * * @param {string} panelTitle The name of sidebar panel. * - * @return {?ElementHandle} Object that represents an in-page DOM element. + * @return {?puppeteer.ElementHandle} Object that represents an in-page DOM element. */ export async function findSidebarPanelToggleButtonWithTitle( panelTitle ) { return first( await page.$x( `//div[contains(@class,"edit-post-sidebar")]//button[@class="components-button components-panel__body-toggle"][contains(text(),"${ panelTitle }")]` ) ); diff --git a/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js b/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js index ff60dca5f00782..2f1436c5b8de23 100644 --- a/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js +++ b/packages/e2e-test-utils/src/find-sidebar-panel-with-title.js @@ -8,7 +8,7 @@ import { first } from 'lodash'; * * @param {string} panelTitle The name of sidebar panel. * - * @return {?ElementHandle} Object that represents an in-page DOM element. + * @return {?puppeteer.ElementHandle} Object that represents an in-page DOM element. */ export async function findSidebarPanelWithTitle( panelTitle ) { const classSelect = ( className ) => `[contains(concat(" ", @class, " "), " ${ className } ")]`; diff --git a/packages/e2e-test-utils/src/wait-for-window-dimensions.js b/packages/e2e-test-utils/src/wait-for-window-dimensions.js index 9b505cf3b12807..924a5c939b3da0 100644 --- a/packages/e2e-test-utils/src/wait-for-window-dimensions.js +++ b/packages/e2e-test-utils/src/wait-for-window-dimensions.js @@ -5,7 +5,7 @@ * https://github.com/GoogleChrome/puppeteer/issues/1751 * * @param {number} width Width of the window. - * @param {height} height Height of the window. + * @param {number} height Height of the window. */ export async function waitForWindowDimensions( width, height ) { await page diff --git a/packages/e2e-tests/specs/editor/various/adding-blocks.test.js b/packages/e2e-tests/specs/editor/various/adding-blocks.test.js index 56e5976513746d..ea79e31224e8e0 100644 --- a/packages/e2e-tests/specs/editor/various/adding-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/adding-blocks.test.js @@ -17,7 +17,7 @@ describe( 'adding blocks', () => { /** * Given a Puppeteer ElementHandle, clicks below its bounding box. * - * @param {Puppeteer.ElementHandle} elementHandle Element handle. + * @param {puppeteer.ElementHandle} elementHandle Element handle. * * @return {Promise} Promise resolving when click occurs. */ diff --git a/packages/edit-post/README.md b/packages/edit-post/README.md index 3b7b01a53e6dd3..0a9441a55b101f 100644 --- a/packages/edit-post/README.md +++ b/packages/edit-post/README.md @@ -92,13 +92,13 @@ _Parameters_ - _props_ `Object`: Component props. - _props.allowedBlocks_ `[Array]`: An array containing a list of block names for which the item should be shown. If not present, it'll be rendered for any block. If multiple blocks are selected, it'll be shown if and only if all of them are in the whitelist. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. - _props.label_ `string`: The menu item text. - _props.onClick_ `Function`: Callback function to be executed when the user click the menu item. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginDocumentSettingPanel" href="#PluginDocumentSettingPanel">#</a> **PluginDocumentSettingPanel** @@ -149,11 +149,11 @@ _Parameters_ - _props.name_ `[string]`: The machine-friendly name for the panel. - _props.className_ `[string]`: An optional class name added to the row. - _props.title_ `[string]`: The title of the panel -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginMoreMenuItem" href="#PluginMoreMenuItem">#</a> **PluginMoreMenuItem** @@ -206,13 +206,13 @@ _Parameters_ - _props_ `Object`: Component properties. - _props.href_ `[string]`: When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. - _props.onClick_ `[Function]`: The callback function to be executed when the user clicks the menu item. - _props.other_ `[...*]`: Any additional props are passed through to the underlying [MenuItem](/packages/components/src/menu-item/README.md) component. _Returns_ -- `WPElement`: The element to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginPostPublishPanel" href="#PluginPostPublishPanel">#</a> **PluginPostPublishPanel** @@ -261,11 +261,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the panel. - _props.title_ `[string]`: Title displayed at the top of the panel. - _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginPostStatusInfo" href="#PluginPostStatusInfo">#</a> **PluginPostStatusInfo** @@ -312,7 +312,7 @@ _Parameters_ _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginPrePublishPanel" href="#PluginPrePublishPanel">#</a> **PluginPrePublishPanel** @@ -361,11 +361,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the panel. - _props.title_ `[string]`: Title displayed at the top of the panel. - _props.initialOpen_ `[boolean]`: Whether to have the panel initially opened. When no title is provided it is always opened. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: The WPElement to be rendered. +- `WPComponent`: The component to be rendered. <a name="PluginSidebar" href="#PluginSidebar">#</a> **PluginSidebar** @@ -432,11 +432,11 @@ _Parameters_ - _props.className_ `[string]`: An optional class name added to the sidebar body. - _props.title_ `string`: Title displayed at the top of the sidebar. - _props.isPinnable_ `[boolean]`: Whether to allow to pin sidebar to toolbar. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. _Returns_ -- `WPElement`: Plugin sidebar component. +- `WPComponent`: Plugin sidebar component. <a name="PluginSidebarMoreMenuItem" href="#PluginSidebarMoreMenuItem">#</a> **PluginSidebarMoreMenuItem** @@ -482,11 +482,11 @@ _Parameters_ - _props_ `Object`: Component props. - _props.target_ `string`: A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar. -- _props.icon_ `[(string|Element)]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. +- _props.icon_ `[WPBlockTypeIconRender]`: The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. _Returns_ -- `WPElement`: The element to be rendered. +- `WPComponent`: The component to be rendered. <a name="reinitializeEditor" href="#reinitializeEditor">#</a> **reinitializeEditor** diff --git a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js index 8503692c289b07..938805e057406b 100644 --- a/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js +++ b/packages/edit-post/src/components/block-settings-menu/plugin-block-settings-menu-item.js @@ -35,7 +35,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => ! Array.isArray( a * * @param {Object} props Component props. * @param {Array} [props.allowedBlocks] An array containing a list of block names for which the item should be shown. If not present, it'll be rendered for any block. If multiple blocks are selected, it'll be shown if and only if all of them are in the whitelist. - * @param {string|Element} [props.icon] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. + * @param {WPBlockTypeIconRender} [props.icon] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element. * @param {string} props.label The menu item text. * @param {Function} props.onClick Callback function to be executed when the user click the menu item. * @@ -81,7 +81,7 @@ const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => ! Array.isArray( a * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginBlockSettingsMenuItem = ( { allowedBlocks, icon, label, onClick, small, role } ) => ( <PluginBlockSettingsMenuGroup> diff --git a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js index e29ec22e90a208..08a5bef83b35eb 100644 --- a/packages/edit-post/src/components/header/plugin-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-more-menu-item/index.js @@ -32,7 +32,7 @@ const PluginMoreMenuItem = ( { onClick = noop, ...props } ) => ( * * @param {Object} props Component properties. * @param {string} [props.href] When `href` is provided then the menu item is represented as an anchor rather than button. It corresponds to the `href` attribute of the anchor. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. * @param {Function} [props.onClick=noop] The callback function to be executed when the user clicks the menu item. * @param {...*} [props.other] Any additional props are passed through to the underlying [MenuItem](/packages/components/src/menu-item/README.md) component. * @@ -78,7 +78,7 @@ const PluginMoreMenuItem = ( { onClick = noop, ...props } ) => ( * ); * ``` * - * @return {WPElement} The element to be rendered. + * @return {WPComponent} The component to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js index e1849f2e7890ed..c1f4ff42ae98aa 100644 --- a/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js +++ b/packages/edit-post/src/components/header/plugin-sidebar-more-menu-item/index.js @@ -28,7 +28,7 @@ const PluginSidebarMoreMenuItem = ( { children, icon, isSelected, onClick } ) => * * @param {Object} props Component props. * @param {string} props.target A string identifying the target sidebar you wish to be activated by this menu item. Must be the same as the `name` prop you have given to that sidebar. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered to the left of the menu item label. * * @example <caption>ES5</caption> * ```js @@ -64,7 +64,7 @@ const PluginSidebarMoreMenuItem = ( { children, icon, isSelected, onClick } ) => * ); * ``` * - * @return {WPElement} The element to be rendered. + * @return {WPComponent} The component to be rendered. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js index ef10b4ed77ef30..62a651c7f0c24e 100644 --- a/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-document-setting-panel/index.js @@ -48,7 +48,7 @@ const PluginDocumentSettingFill = ( { isEnabled, panelName, opened, onToggle, cl * @param {string} [props.name] The machine-friendly name for the panel. * @param {string} [props.className] An optional class name added to the row. * @param {string} [props.title] The title of the panel - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -89,7 +89,7 @@ const PluginDocumentSettingFill = ( { isEnabled, panelName, opened, onToggle, cl * registerPlugin( 'document-setting-test', { render: MyDocumentSettingTest } ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginDocumentSettingPanel = compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js index a84124905d7d46..b1c53372857023 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-post-publish-panel/index.js @@ -27,7 +27,7 @@ const PluginPostPublishPanelFill = ( { children, className, title, initialOpen = * @param {string} [props.className] An optional class name added to the panel. * @param {string} [props.title] Title displayed at the top of the panel. * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. When no title is provided it is always opened. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -65,7 +65,7 @@ const PluginPostPublishPanelFill = ( { children, className, title, initialOpen = * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginPostPublishPanel = compose( diff --git a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js b/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js index e099fa232e84f6..2d149639130eda 100644 --- a/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-post-status-info/index.js @@ -49,7 +49,7 @@ export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' ); * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginPostStatusInfo = ( { children, className } ) => ( <Fill> diff --git a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js b/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js index 4a3b02fba2803b..13863b24f16d50 100644 --- a/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-pre-publish-panel/index.js @@ -18,16 +18,19 @@ const PluginPrePublishPanelFill = ( { children, className, title, initialOpen = </PanelBody> </Fill> ); + /** * Renders provided content to the pre-publish side panel in the publish flow * (side panel that opens when a user first pushes "Publish" from the main editor). * - * @param {Object} props Component props. - * @param {string} [props.className] An optional class name added to the panel. - * @param {string} [props.title] Title displayed at the top of the panel. - * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. When no title is provided it is always opened. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. - + * @param {Object} props Component props. + * @param {string} [props.className] An optional class name added to the panel. + * @param {string} [props.title] Title displayed at the top of the panel. + * @param {boolean} [props.initialOpen=false] Whether to have the panel initially opened. + * When no title is provided it is always opened. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) + * icon slug string, or an SVG WP element, to be rendered when + * the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -65,7 +68,7 @@ const PluginPrePublishPanelFill = ( { children, className, title, initialOpen = * ); * ``` * - * @return {WPElement} The WPElement to be rendered. + * @return {WPComponent} The component to be rendered. */ const PluginPrePublishPanel = compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js index 5303de703b30b9..7c03f172b009fb 100644 --- a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js @@ -82,7 +82,7 @@ function PluginSidebar( props ) { * @param {string} [props.className] An optional class name added to the sidebar body. * @param {string} props.title Title displayed at the top of the sidebar. * @param {boolean} [props.isPinnable=true] Whether to allow to pin sidebar to toolbar. - * @param {string|Element} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. + * @param {WPBlockTypeIconRender} [props.icon=inherits from the plugin] The [Dashicon](https://developer.wordpress.org/resource/dashicons/) icon slug string, or an SVG WP element, to be rendered when the sidebar is pinned to toolbar. * * @example <caption>ES5</caption> * ```js @@ -129,7 +129,7 @@ function PluginSidebar( props ) { * ); * ``` * - * @return {WPElement} Plugin sidebar component. + * @return {WPComponent} Plugin sidebar component. */ export default compose( withPluginContext( ( context, ownProps ) => { diff --git a/packages/edit-post/src/hooks/validate-multiple-use/index.js b/packages/edit-post/src/hooks/validate-multiple-use/index.js index ea2958949f7e2d..54a502603c2064 100644 --- a/packages/edit-post/src/hooks/validate-multiple-use/index.js +++ b/packages/edit-post/src/hooks/validate-multiple-use/index.js @@ -28,9 +28,9 @@ const enhance = compose( * "original" block is not the current one. Thus, an inexisting * `originalBlockClientId` prop signals that the block is valid. * - * @param {Component} WrappedBlockEdit A filtered BlockEdit instance. + * @param {WPComponent} WrappedBlockEdit A filtered BlockEdit instance. * - * @return {Component} Enhanced component with merged state data props. + * @return {WPComponent} Enhanced component with merged state data props. */ withSelect( ( select, block ) => { const multiple = hasBlockSupport( block.name, 'multiple', true ); diff --git a/packages/edit-post/src/store/selectors.js b/packages/edit-post/src/store/selectors.js index 2430ee41087232..fff04ac721fe37 100644 --- a/packages/edit-post/src/store/selectors.js +++ b/packages/edit-post/src/store/selectors.js @@ -78,9 +78,9 @@ export function getPreferences( state ) { * * @param {Object} state Global application state. * @param {string} preferenceKey Preference Key. - * @param {Mixed} defaultValue Default Value. + * @param {*} defaultValue Default Value. * - * @return {Mixed} Preference Value. + * @return {*} Preference Value. */ export function getPreference( state, preferenceKey, defaultValue ) { const preferences = getPreferences( state ); diff --git a/packages/editor/src/components/autocompleters/block.js b/packages/editor/src/components/autocompleters/block.js index 70860643ae096b..5311d01ec2b749 100644 --- a/packages/editor/src/components/autocompleters/block.js +++ b/packages/editor/src/components/autocompleters/block.js @@ -27,7 +27,7 @@ function defaultGetBlockInsertionParentClientId() { * @param {string} rootClientId Client ID of the block for which to retrieve * inserter items. * - * @return {Array<Editor.InserterItem>} The inserter items for the specified + * @return {Array<WPEditorInserterItem>} The inserter items for the specified * parent. */ function defaultGetInserterItems( rootClientId ) { @@ -68,7 +68,7 @@ const fetchReusableBlocks = once( () => { /** * Creates a blocks repeater for replacing the current block with a selected block type. * - * @return {Completer} A blocks completer. + * @return {WPCompleter} A blocks completer. */ export function createBlockCompleter( { // Allow store-based selectors to be overridden for unit test. @@ -119,6 +119,6 @@ export function createBlockCompleter( { /** * Creates a blocks repeater for replacing the current block with a selected block type. * - * @return {Completer} A blocks completer. + * @return {WPCompleter} A blocks completer. */ export default createBlockCompleter(); diff --git a/packages/editor/src/components/autocompleters/user.js b/packages/editor/src/components/autocompleters/user.js index e3965a33f28d6f..1dea163ee16443 100644 --- a/packages/editor/src/components/autocompleters/user.js +++ b/packages/editor/src/components/autocompleters/user.js @@ -6,7 +6,7 @@ import apiFetch from '@wordpress/api-fetch'; /** * A user mentions completer. * - * @type {Completer} + * @type {WPCompleter} */ export default { name: 'users', diff --git a/packages/editor/src/components/post-type-support-check/index.js b/packages/editor/src/components/post-type-support-check/index.js index 8096e4ccf7f8d9..7aae5e6abb0362 100644 --- a/packages/editor/src/components/post-type-support-check/index.js +++ b/packages/editor/src/components/post-type-support-check/index.js @@ -12,14 +12,14 @@ import { withSelect } from '@wordpress/data'; * A component which renders its own children only if the current editor post * type supports one of the given `supportKeys` prop. * - * @param {Object} props - * @param {string} [props.postType] Current post type. - * @param {WPElement} props.children Children to be rendered if post - * type supports. - * @param {(string|string[])} props.supportKeys String or string array of keys - * to test. + * @param {Object} props Props. + * @param {string} [props.postType] Current post type. + * @param {WPElement} props.children Children to be rendered if post + * type supports. + * @param {(string|string[])} props.supportKeys String or string array of keys + * to test. * - * @return {WPElement} Rendered element. + * @return {WPComponent} The component to be rendered. */ export function PostTypeSupportCheck( { postType, children, supportKeys } ) { let isSupported = true; diff --git a/packages/editor/src/store/actions.native.js b/packages/editor/src/store/actions.native.js index 17733a0e47b408..0154c92324640e 100644 --- a/packages/editor/src/store/actions.native.js +++ b/packages/editor/src/store/actions.native.js @@ -21,9 +21,7 @@ export function togglePostTitleSelection( isSelected = true ) { /** * Action generator used in signalling that the post should autosave. - * - * @param {Object?} options Extra flags to identify the autosave. */ -export function* autosave( ) { +export function* autosave() { RNReactNativeGutenbergBridge.editorDidAutosave(); } diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 7014d8a3b1fe56..0bf0ddf3f1bb38 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -210,8 +210,8 @@ export function postLock( state = { isLocked: false }, action ) { * * When post saving is locked, the post cannot be published or updated. * - * @param {PostSavingLockState} state Current state. - * @param {Object} action Dispatched action. + * @param {PostLockState} state Current state. + * @param {Object} action Dispatched action. * * @return {PostLockState} Updated state. */ @@ -231,8 +231,8 @@ export function postSavingLock( state = {}, action ) { * * When post autosaving is locked, the post will not autosave. * - * @param {PostAutosavingLockState} state Current state. - * @param {Object} action Dispatched action. + * @param {PostLockState} state Current state. + * @param {Object} action Dispatched action. * * @return {PostLockState} Updated state. */ diff --git a/packages/element/README.md b/packages/element/README.md index 0b96812eacb539..d592235c5dd8d9 100755 --- a/packages/element/README.md +++ b/packages/element/README.md @@ -148,8 +148,8 @@ _Related_ _Parameters_ -- _component_ `Component`: Component -- _target_ `Element`: DOM node into which element should be rendered +- _child_ `WPElement`: Any renderable child, such as an element, string, or fragment. +- _container_ `HTMLElement`: DOM node into which element should be rendered. <a name="createRef" href="#createRef">#</a> **createRef** @@ -163,12 +163,11 @@ _Returns_ <a name="findDOMNode" href="#findDOMNode">#</a> **findDOMNode** -Finds the dom node of a React component +Finds the dom node of a React component. _Parameters_ -- _component_ `Component`: component's instance -- _target_ `Element`: DOM node into which element should be rendered +- _component_ `WPComponent`: Component's instance. <a name="forwardRef" href="#forwardRef">#</a> **forwardRef** @@ -203,7 +202,7 @@ _Returns_ <a name="isValidElement" href="#isValidElement">#</a> **isValidElement** -Checks if an object is a valid WPElement +Checks if an object is a valid WPElement. _Parameters_ @@ -240,7 +239,7 @@ _Parameters_ _Returns_ -- `WPElement`: Dangerously-rendering element. +- `WPComponent`: Dangerously-rendering component. <a name="render" href="#render">#</a> **render** @@ -248,8 +247,8 @@ Renders a given element into the target DOM node. _Parameters_ -- _element_ `WPElement`: Element to render -- _target_ `Element`: DOM node into which element should be rendered +- _element_ `WPElement`: Element to render. +- _target_ `HTMLElement`: DOM node into which element should be rendered. <a name="renderToString" href="#renderToString">#</a> **renderToString** diff --git a/packages/element/src/raw-html.js b/packages/element/src/raw-html.js index 2fa3618c417d88..0f56060e3057b6 100644 --- a/packages/element/src/raw-html.js +++ b/packages/element/src/raw-html.js @@ -13,7 +13,7 @@ import { createElement } from './react'; * @param {string} props.children HTML to render. * @param {Object} props.props Any additonal props to be set on the containing div. * - * @return {WPElement} Dangerously-rendering element. + * @return {WPComponent} Dangerously-rendering component. */ export default function RawHTML( { children, ...props } ) { // The DIV wrapper will be stripped by serializer, unless there are diff --git a/packages/element/src/react-platform.js b/packages/element/src/react-platform.js index e4ca37da7e11bc..44a3422ed79773 100644 --- a/packages/element/src/react-platform.js +++ b/packages/element/src/react-platform.js @@ -13,24 +13,24 @@ import { * * @see https://github.com/facebook/react/issues/10309#issuecomment-318433235 * - * @param {Component} component Component - * @param {Element} target DOM node into which element should be rendered + * @param {WPElement} child Any renderable child, such as an element, + * string, or fragment. + * @param {HTMLElement} container DOM node into which element should be rendered. */ export { createPortal }; /** - * Finds the dom node of a React component + * Finds the dom node of a React component. * - * @param {Component} component component's instance - * @param {Element} target DOM node into which element should be rendered + * @param {WPComponent} component Component's instance. */ export { findDOMNode }; /** * Renders a given element into the target DOM node. * - * @param {WPElement} element Element to render - * @param {Element} target DOM node into which element should be rendered + * @param {WPElement} element Element to render. + * @param {HTMLElement} target DOM node into which element should be rendered. */ export { render }; diff --git a/packages/element/src/react.js b/packages/element/src/react.js index 722085de1fc776..2776f514b329e5 100644 --- a/packages/element/src/react.js +++ b/packages/element/src/react.js @@ -28,6 +28,24 @@ import { } from 'react'; import { isString } from 'lodash'; +/** + * Object containing a React element. + * + * @typedef {react.ReactElement} WPElement + */ + +/** + * Object containing a React component. + * + * @typedef {react.Component} WPComponent + */ + +/** + * Object containing a React synthetic event. + * + * @typedef {react.SyntheticEvent} WPSyntheticEvent + */ + /** * Object that provides utilities for dealing with React children. */ @@ -63,8 +81,8 @@ export { createContext }; * * @param {?(string|Function)} type Tag name or element creator * @param {Object} props Element properties, either attribute - * set to apply to DOM node or values to - * pass through to element creator + * set to apply to DOM node or values to + * pass through to element creator * @param {...WPElement} children Descendant elements * * @return {WPElement} Element. @@ -99,7 +117,7 @@ export { forwardRef }; export { Fragment }; /** - * Checks if an object is a valid WPElement + * Checks if an object is a valid WPElement. * * @param {Object} objectToCheck The object to be checked. * diff --git a/packages/eslint-plugin/configs/jsdoc.js b/packages/eslint-plugin/configs/jsdoc.js index 614816cb734a21..8e0935dc316881 100644 --- a/packages/eslint-plugin/configs/jsdoc.js +++ b/packages/eslint-plugin/configs/jsdoc.js @@ -1,5 +1,55 @@ +/** + * External dependencies + */ const globals = require( 'globals' ); +/** + * The temporary list of types defined in Gutenberg which are whitelisted to avoid + * ESLint warnings. It should be removed once importing is going to be implemented + * in the tool which generates public APIs from JSDoc comments. Related issue to + * fix the root cause `@wordpress/docgen`: + * https://github.com/WordPress/gutenberg/issues/18045. + */ +const temporaryWordPressInternalTypes = [ + 'WPBlockChildren', + 'WPBlockNode', + 'WPBlockSelection', + 'WPBlockSerializationOptions', + 'WPBlock', + 'WPBlockTypeIcon', + 'WPBlockTypeIconRender', + 'WPBlockTypeIconDescriptor', + 'WPDataPersistencePluginOptions', + 'WPDataPlugin', + 'WPDataRegistry', + 'WPComponent', + 'WPCompleter', + 'WPElement', + 'WPFormat', + 'WPEditorInserterItem', + 'WPNotice', + 'WPNoticeAction', + 'WPPlugin', + 'WPShortcode', + 'WPShortcodeAttrs', + 'WPShortcodeMatch', + 'WPSyntheticEvent', +]; + +/** + * The temporary list of external types used in Gutenberg which are whitelisted + * to avoid ESLint warnings. It's similar to `wordpressInternalTypes` and it + * should be removed once the related issues is fixed: + * https://github.com/WordPress/gutenberg/issues/18045 + */ +const temporaryExternalTypes = [ + 'DOMHighResTimeStamp', + 'espree', + 'moment', + 'puppeteer', + 'react', +]; + /** * Helpful utilities that are globally defined and known to the TypeScript compiler. * @@ -50,6 +100,8 @@ module.exports = { // generally refer to window-level event listeners and are not a valid type to reference (e.g. `onclick`). ...Object.keys( globals.browser ).filter( ( k ) => /^[A-Z]/.test( k ) ), ...typescriptUtilityTypes, + ...temporaryWordPressInternalTypes, + ...temporaryExternalTypes, 'void', ], } ], diff --git a/packages/jest-puppeteer-axe/src/index.js b/packages/jest-puppeteer-axe/src/index.js index 336cec9bcf8161..7bba05d8965d28 100644 --- a/packages/jest-puppeteer-axe/src/index.js +++ b/packages/jest-puppeteer-axe/src/index.js @@ -53,13 +53,13 @@ function formatViolations( violations ) { * * @see https://github.com/dequelabs/axe-puppeteer * - * @param {Page} page Puppeteer's page instance. - * @param {?Object} params Optional Axe API options. - * @param {?string|Array} params.include CSS selector(s) to add to the list of elements - * to include in analysis. - * @param {?string|Array} params.exclude CSS selector(s) to add to the list of elements - * to exclude from analysis. - * @param {?Array} params.disabledRules The list of Axe rules to skip from verification. + * @param {puppeteer.Page} page Puppeteer's page instance. + * @param {?Object} params Optional Axe API options. + * @param {?string|Array} params.include CSS selector(s) to add to the list of elements + * to include in analysis. + * @param {?string|Array} params.exclude CSS selector(s) to add to the list of elements + * to exclude from analysis. + * @param {?Array} params.disabledRules The list of Axe rules to skip from verification. * * @return {Object} A matcher object with two keys `pass` and `message`. */ diff --git a/packages/notices/src/store/actions.js b/packages/notices/src/store/actions.js index f1771b6ca8ae2f..0fed89a60e0f31 100644 --- a/packages/notices/src/store/actions.js +++ b/packages/notices/src/store/actions.js @@ -8,6 +8,17 @@ import { uniqueId } from 'lodash'; */ import { DEFAULT_CONTEXT, DEFAULT_STATUS } from './constants'; +/** + * @typedef {Object} WPNoticeAction Object describing a user action option associated with a notice. + * + * @property {string} label Message to use as action label. + * @property {?string} url Optional URL of resource if action incurs + * browser navigation. + * @property {?Function} onClick Optional function to invoke when action is + * triggered by user. + * + */ + /** * Yields action objects used in signalling that a notice is to be created. * diff --git a/packages/notices/src/store/selectors.js b/packages/notices/src/store/selectors.js index 3a0bc75ad0f02a..358a159aa8dc66 100644 --- a/packages/notices/src/store/selectors.js +++ b/packages/notices/src/store/selectors.js @@ -38,17 +38,6 @@ const DEFAULT_NOTICES = []; * */ -/** - * @typedef {Object} WPNoticeAction Object describing a user action option associated with a notice. - * - * @property {string} label Message to use as action label. - * @property {?string} url Optional URL of resource if action incurs - * browser navigation. - * @property {?Function} onClick Optional function to invoke when action is - * triggered by user. - * - */ - /** * Returns all notices as an array, optionally for a given context. Defaults to * the global context. diff --git a/packages/nux/src/store/selectors.js b/packages/nux/src/store/selectors.js index 9225bd97077eee..58decf89455191 100644 --- a/packages/nux/src/store/selectors.js +++ b/packages/nux/src/store/selectors.js @@ -7,7 +7,7 @@ import { includes, difference, keys, has } from 'lodash'; /** * An object containing information about a guide. * - * @typedef {Object} NUX.GuideInfo + * @typedef {Object} NUXGuideInfo * @property {string[]} tipIds Which tips the guide contains. * @property {?string} currentTipId The guide's currently showing tip. * @property {?string} nextTipId The guide's next tip to show. @@ -20,7 +20,7 @@ import { includes, difference, keys, has } from 'lodash'; * @param {Object} state Global application state. * @param {string} tipId The tip to query. * - * @return {?NUX.GuideInfo} Information about the associated guide. + * @return {?NUXGuideInfo} Information about the associated guide. */ export const getAssociatedGuide = createSelector( ( state, tipId ) => { diff --git a/packages/plugins/README.md b/packages/plugins/README.md index 2875c76b0fa8da..9bf049e1bc6abc 100644 --- a/packages/plugins/README.md +++ b/packages/plugins/README.md @@ -26,7 +26,7 @@ _Parameters_ _Returns_ -- `?Object`: Plugin setting. +- `?WPPlugin`: Plugin setting. <a name="getPlugins" href="#getPlugins">#</a> **getPlugins** @@ -34,7 +34,7 @@ Returns all registered plugins. _Returns_ -- `Array`: Plugin settings. +- `Array<WPPlugin>`: Plugin settings. <a name="PluginArea" href="#PluginArea">#</a> **PluginArea** @@ -71,7 +71,7 @@ const Layout = () => ( _Returns_ -- `WPElement`: Plugin area. +- `WPComponent`: The component to be rendered. <a name="registerPlugin" href="#registerPlugin">#</a> **registerPlugin** @@ -143,14 +143,12 @@ registerPlugin( 'plugin-name', { _Parameters_ -- _name_ `string`: A string identifying the plugin. Must be unique across all registered plugins. -- _settings_ `Object`: The settings for this plugin. -- _settings.icon_ `(string|WPElement|Function)`: An icon to be shown in the UI. It can be a slug of the Dashicon, or an element (or function returning an element) if you choose to render your own SVG. -- _settings.render_ `Function`: A component containing the UI elements to be rendered. +- _name_ `string`: A string identifying the plugin.Must be unique across all registered plugins. +- _settings_ `WPPlugin`: The settings for this plugin. _Returns_ -- `Object`: The final plugin settings object. +- `WPPlugin`: The final plugin settings object. <a name="unregisterPlugin" href="#unregisterPlugin">#</a> **unregisterPlugin** @@ -191,7 +189,7 @@ _Parameters_ _Returns_ -- `Component`: Enhanced component with injected context as props. +- `WPComponent`: Enhanced component with injected context as props. <!-- END TOKEN(Autogenerated API docs) --> diff --git a/packages/plugins/src/api/index.js b/packages/plugins/src/api/index.js index 6e6ea102a80ffd..5e8fe1d19c851d 100644 --- a/packages/plugins/src/api/index.js +++ b/packages/plugins/src/api/index.js @@ -10,6 +10,22 @@ import { applyFilters, doAction } from '@wordpress/hooks'; */ import { isFunction } from 'lodash'; +/** + * Defined behavior of a plugin type. + * + * @typedef {Object} WPPlugin + * + * @property {string} name A string identifying the plugin. Must be + * unique across all registered plugins. + * unique across all registered plugins. + * @property {string|WPElement|Function} icon An icon to be shown in the UI. It can + * be a slug of the Dashicon, or an element + * (or function returning an element) if you + * choose to render your own SVG. + * @property {Function} render A component containing the UI elements + * to be rendered. + */ + /** * Plugin definitions keyed by plugin name. * @@ -20,11 +36,9 @@ const plugins = {}; /** * Registers a plugin to the editor. * - * @param {string} name A string identifying the plugin. Must be unique across all registered plugins. - * @param {Object} settings The settings for this plugin. - * @param {string|WPElement|Function} settings.icon An icon to be shown in the UI. It can be a slug of the Dashicon, - * or an element (or function returning an element) if you choose to render your own SVG. - * @param {Function} settings.render A component containing the UI elements to be rendered. + * @param {string} name A string identifying the plugin.Must be + * unique across all registered plugins. + * @param {WPPlugin} settings The settings for this plugin. * * @example <caption>ES5</caption> * ```js @@ -90,7 +104,7 @@ const plugins = {}; * } ); * ``` * - * @return {Object} The final plugin settings object. + * @return {WPPlugin} The final plugin settings object. */ export function registerPlugin( name, settings ) { if ( typeof settings !== 'object' ) { @@ -181,7 +195,7 @@ export function unregisterPlugin( name ) { * * @param {string} name Plugin name. * - * @return {?Object} Plugin setting. + * @return {?WPPlugin} Plugin setting. */ export function getPlugin( name ) { return plugins[ name ]; @@ -190,7 +204,7 @@ export function getPlugin( name ) { /** * Returns all registered plugins. * - * @return {Array} Plugin settings. + * @return {WPPlugin[]} Plugin settings. */ export function getPlugins() { return Object.values( plugins ); diff --git a/packages/plugins/src/components/plugin-area/index.js b/packages/plugins/src/components/plugin-area/index.js index 1cf6f15b528795..e03e5458d50ef4 100644 --- a/packages/plugins/src/components/plugin-area/index.js +++ b/packages/plugins/src/components/plugin-area/index.js @@ -47,7 +47,7 @@ import { getPlugins } from '../../api'; * ); * ``` * - * @return {WPElement} Plugin area. + * @return {WPComponent} The component to be rendered. */ class PluginArea extends Component { constructor() { diff --git a/packages/plugins/src/components/plugin-context/index.js b/packages/plugins/src/components/plugin-context/index.js index 75fb1b8f1dea01..586891c67eb4ee 100644 --- a/packages/plugins/src/components/plugin-context/index.js +++ b/packages/plugins/src/components/plugin-context/index.js @@ -19,7 +19,7 @@ export { Provider as PluginContextProvider }; * expected to return object of props to * merge with the component's own props. * - * @return {Component} Enhanced component with injected context as props. + * @return {WPComponent} Enhanced component with injected context as props. */ export const withPluginContext = ( mapContextToProps ) => createHigherOrderComponent( ( OriginalComponent ) => { return ( props ) => ( diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 46a78502ff3ed4..e911c714792064 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -216,11 +216,7 @@ behavior. _Parameters_ - _name_ `string`: Format name. -- _settings_ `Object`: Format settings. -- _settings.tagName_ `string`: The HTML tag this format will wrap the selection with. -- _settings.className_ `[string]`: A class to match the format. -- _settings.title_ `string`: Name of the format. -- _settings.edit_ `Function`: Should return a component for the user to interact with the new registered format. +- _settings_ `WPFormat`: Format settings. _Returns_ diff --git a/packages/rich-text/src/component/index.js b/packages/rich-text/src/component/index.js index c82feae869d1e7..e028ba0611623b 100644 --- a/packages/rich-text/src/component/index.js +++ b/packages/rich-text/src/component/index.js @@ -204,7 +204,7 @@ class RichText extends Component { * * Saves the pasted data as plain text in `pastedPlainText`. * - * @param {PasteEvent} event The paste event. + * @param {ClipboardEvent} event The paste event. */ onPaste( event ) { const { formatTypes, onPaste } = this.props; @@ -337,7 +337,7 @@ class RichText extends Component { /** * Handle input on the next selection change event. * - * @param {SyntheticEvent} event Synthetic input event. + * @param {WPSyntheticEvent} event Synthetic input event. */ onInput( event ) { // For Input Method Editor (IME), used in Chinese, Japanese, and Korean @@ -437,7 +437,7 @@ class RichText extends Component { * native events, `keyup`, `mouseup` and `touchend` synthetic events, and * animation frames after the `focus` event. * - * @param {Event|SyntheticEvent|DOMHighResTimeStamp} event + * @param {Event|WPSyntheticEvent|DOMHighResTimeStamp} event */ onSelectionChange( event ) { if ( @@ -579,7 +579,7 @@ class RichText extends Component { * - delete content if everything is selected, * - trigger the onDelete prop when selection is uncollapsed and at an edge. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleDelete( event ) { const { keyCode } = event; @@ -637,7 +637,7 @@ class RichText extends Component { /** * Triggers the `onEnter` prop on keydown. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleEnter( event ) { if ( event.keyCode !== ENTER ) { @@ -662,7 +662,7 @@ class RichText extends Component { /** * Indents list items on space keydown. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleSpace( event ) { const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; @@ -699,7 +699,7 @@ class RichText extends Component { * navigation is handled separately to move correctly around format * boundaries. * - * @param {SyntheticEvent} event A synthetic keyboard event. + * @param {WPSyntheticEvent} event A synthetic keyboard event. */ handleHorizontalNavigation( event ) { const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; @@ -805,7 +805,7 @@ class RichText extends Component { * Select object when they are clicked. The browser will not set any * selection when clicking e.g. an image. * - * @param {SyntheticEvent} event Synthetic mousedown or touchstart event. + * @param {WPSyntheticEvent} event Synthetic mousedown or touchstart event. */ onPointerDown( event ) { const { target } = event; diff --git a/packages/rich-text/src/register-format-type.js b/packages/rich-text/src/register-format-type.js index e6efc99f5fec97..84a158167b860f 100644 --- a/packages/rich-text/src/register-format-type.js +++ b/packages/rich-text/src/register-format-type.js @@ -10,16 +10,25 @@ import { select, dispatch, withSelect, withDispatch } from '@wordpress/data'; import { addFilter } from '@wordpress/hooks'; import { compose } from '@wordpress/compose'; +/** + * @typedef {Object} WPFormat + * + * @property {string} name A string identifying the format. Must be + * unique across all registered formats. + * @property {string} tagName The HTML tag this format will wrap the + * selection with. + * @property {string} [className] A class to match the format. + * @property {string} title Name of the format. + * @property {Function} edit Should return a component for the user to + * interact with the new registered format. + */ + /** * Registers a new format provided a unique name and an object defining its * behavior. * * @param {string} name Format name. - * @param {Object} settings Format settings. - * @param {string} settings.tagName The HTML tag this format will wrap the selection with. - * @param {string} [settings.className] A class to match the format. - * @param {string} settings.title Name of the format. - * @param {Function} settings.edit Should return a component for the user to interact with the new registered format. + * @param {WPFormat} settings Format settings. * * @return {WPFormat|undefined} The format, if it has been successfully registered; * otherwise `undefined`. diff --git a/packages/rich-text/src/to-dom.js b/packages/rich-text/src/to-dom.js index 9d7aed3cfdfd00..730a38587114c4 100644 --- a/packages/rich-text/src/to-dom.js +++ b/packages/rich-text/src/to-dom.js @@ -67,7 +67,7 @@ function getNodeByPath( node, path ) { * each call to `createEmpty`. Therefore, you should not hold a reference to * the value to operate upon asynchronously, as it may have unexpected results. * - * @return {WPRichTextTree} RichText tree. + * @return {Object} RichText tree. */ const createEmpty = () => createElement( document, '' ); From 7783eb5c788528402a050833d9a4b792bdcdc22e Mon Sep 17 00:00:00 2001 From: Miguel Fonseca <miguelcsf@gmail.com> Date: Thu, 24 Oct 2019 10:39:45 +0100 Subject: [PATCH 060/113] Local autosave: Clear after successful save (#18051) * Local autosave: Clear after successful save Presumably, somewhere in the fixing of conflicts between remote and local autosaves (purge local upon successful remote autosave), LocalAutosaveMonitor stopped purging the local autosave upon successful *saves*. * Tests: Autosave: Correctly wait for editor chrome before saving --- .../specs/editor/various/autosave.test.js | 65 +++++++++++++++---- .../local-autosave-monitor/index.js | 7 +- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/autosave.test.js b/packages/e2e-tests/specs/editor/various/autosave.test.js index 9f97f0f1c3f291..3c966f15a0748d 100644 --- a/packages/e2e-tests/specs/editor/various/autosave.test.js +++ b/packages/e2e-tests/specs/editor/various/autosave.test.js @@ -17,13 +17,22 @@ const AUTOSAVE_INTERVAL_SECONDS = 5; const AUTOSAVE_NOTICE_REMOTE = 'There is an autosave of this post that is more recent than the version below.'; const AUTOSAVE_NOTICE_LOCAL = 'The backup of this post in your browser is different from the version below.'; +// Save and wait for "Saved" to confirm save complete. Preserves focus in the +// editing area. async function saveDraftWithKeyboard() { - return pressKeyWithModifier( 'primary', 's' ); + await page.waitForSelector( '.editor-post-save-draft' ); + await Promise.all( [ + page.waitForSelector( '.editor-post-saved-state.is-saved' ), + pressKeyWithModifier( 'primary', 'S' ), + ] ); } async function sleep( durationInSeconds ) { - return new Promise( ( resolve ) => - setTimeout( resolve, durationInSeconds * 1000 ) ); + // Rule `no-restricted-syntax` recommends `waitForSelector` against + // `waitFor`, which isn't apt for the use case, when provided an integer, + // of waiting for a given amount of time. + // eslint-disable-next-line no-restricted-syntax + await page.waitFor( durationInSeconds * 1000 ); } async function clearSessionStorage() { @@ -153,11 +162,11 @@ describe( 'autosave', () => { } ); it( 'should clear local autosave after successful remote autosave', async () => { + // Edit, save draft, edit again await clickBlockAppender(); await page.keyboard.type( 'before save' ); - await saveDraft(); - - await page.keyboard.type( 'after save' ); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); // Trigger local autosave await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); @@ -169,21 +178,52 @@ describe( 'autosave', () => { } ); it( 'shouldn\'t clear local autosave if remote autosave fails', async () => { + // Edit, save draft, edit again await clickBlockAppender(); await page.keyboard.type( 'before save' ); - await saveDraft(); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); - await page.keyboard.type( 'after save' ); + // Trigger local autosave await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + // Bring network down and attempt to autosave remotely toggleOfflineMode( true ); - - // Trigger remote autosave await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).autosave() ); expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + } ); - toggleOfflineMode( false ); + it( 'should clear local autosave after successful save', async () => { + // Edit, save draft, edit again + await clickBlockAppender(); + await page.keyboard.type( 'before save' ); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); + + // Trigger local autosave + await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + + await saveDraftWithKeyboard(); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 0 ); + } ); + + it( 'shouldn\'t clear local autosave if save fails', async () => { + // Edit, save draft, edit again + await clickBlockAppender(); + await page.keyboard.type( 'before save' ); + await saveDraftWithKeyboard(); + await page.keyboard.type( ' after save' ); + + // Trigger local autosave + await page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).__experimentalLocalAutosave() ); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); + + // Bring network down and attempt to save + toggleOfflineMode( true ); + saveDraftWithKeyboard(); + expect( await page.evaluate( () => window.sessionStorage.length ) ).toBe( 1 ); } ); it( 'shouldn\'t conflict with server-side autosave', async () => { @@ -221,7 +261,8 @@ describe( 'autosave', () => { expect( notice ).toContain( AUTOSAVE_NOTICE_REMOTE ); } ); - afterAll( async () => { + afterEach( async () => { + toggleOfflineMode( false ); await clearSessionStorage(); } ); } ); diff --git a/packages/editor/src/components/local-autosave-monitor/index.js b/packages/editor/src/components/local-autosave-monitor/index.js index 59be30218f20cd..9dbd94aab5f56d 100644 --- a/packages/editor/src/components/local-autosave-monitor/index.js +++ b/packages/editor/src/components/local-autosave-monitor/index.js @@ -130,7 +130,12 @@ function useAutosavePurge() { const lastIsAutosaving = useRef( isAutosaving ); useEffect( () => { - if ( lastIsAutosaving.current && ! isAutosaving && ! didError ) { + if ( + ! didError && ( + ( lastIsAutosaving.current && ! isAutosaving ) || + ( lastIsDirty.current && ! isDirty ) + ) + ) { localAutosaveClear( postId ); } From 0b723424f5c6e40115e12694c693b34879ba9a9f Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Thu, 24 Oct 2019 12:46:13 +0100 Subject: [PATCH 061/113] =?UTF-8?q?Chore:=20Fix:=20Do=20not=20show=20Gradi?= =?UTF-8?q?ent=20panel=20if=20gradients=20are=20not=20av=E2=80=A6=20(#1809?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/gradient-picker/panel.js | 32 +++++++++++++++++++ packages/block-editor/src/components/index.js | 1 + packages/block-library/src/button/edit.js | 32 +++++++++---------- 3 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 packages/block-editor/src/components/gradient-picker/panel.js diff --git a/packages/block-editor/src/components/gradient-picker/panel.js b/packages/block-editor/src/components/gradient-picker/panel.js new file mode 100644 index 00000000000000..2be91125cbc110 --- /dev/null +++ b/packages/block-editor/src/components/gradient-picker/panel.js @@ -0,0 +1,32 @@ +/** + * External dependencies + */ +import { isEmpty } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { PanelBody } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import GradientPicker from './control'; + +export default function GradientPanel( props ) { + const gradients = useSelect( ( select ) => ( + select( 'core/block-editor' ).getSettings().gradients + ) ); + if ( isEmpty( gradients ) ) { + return null; + } + return ( + <PanelBody title={ __( 'Gradient' ) }> + <GradientPicker + { ...props } + /> + </PanelBody> + ); +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index a31f3829ca360c..798566bda67088 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -20,6 +20,7 @@ export { default as ColorPaletteControl } from './color-palette/control'; export { default as ContrastChecker } from './contrast-checker'; export { default as __experimentalGradientPicker } from './gradient-picker'; export { default as __experimentalGradientPickerControl } from './gradient-picker/control'; +export { default as __experimentalGradientPickerPanel } from './gradient-picker/panel'; export { default as InnerBlocks } from './inner-blocks'; export { default as InspectorAdvancedControls } from './inspector-advanced-controls'; export { default as InspectorControls } from './inspector-controls'; diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index 33ebe079c5e892..5d457482cf04bd 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -23,13 +23,13 @@ import { withFallbackStyles, } from '@wordpress/components'; import { - URLInput, - RichText, + __experimentalGradientPickerPanel, ContrastChecker, InspectorControls, - withColors, PanelColorSettings, - __experimentalGradientPickerControl, + RichText, + URLInput, + withColors, } from '@wordpress/block-editor'; const { getComputedStyle } = window; @@ -195,20 +195,18 @@ function ButtonEdit( { } } /> </PanelColorSettings> - <PanelBody title={ __( 'Gradient' ) }> - <__experimentalGradientPickerControl - onChange={ - ( newGradient ) => { - setAttributes( { - customGradient: newGradient, - backgroundColor: undefined, - customBackgroundColor: undefined, - } ); - } + <__experimentalGradientPickerPanel + onChange={ + ( newGradient ) => { + setAttributes( { + customGradient: newGradient, + backgroundColor: undefined, + customBackgroundColor: undefined, + } ); } - value={ customGradient } - /> - </PanelBody> + } + value={ customGradient } + /> <BorderPanel borderRadius={ borderRadius } setAttributes={ setAttributes } From e829d97a6a15edfe3d38252630897f3f35ddc4cd Mon Sep 17 00:00:00 2001 From: Joen Asmussen <joen@automattic.com> Date: Thu, 24 Oct 2019 14:02:17 +0200 Subject: [PATCH 062/113] Fix regression with Gallery margin. (#18019) I failed to verify the Gallery block when I approved https://github.com/WordPress/gutenberg/pull/17958#issuecomment-543597183 and therefore caused a regression. This PR adds explicity left margins and paddings to the gallery ul to ensure there isn't any added padding and margin. --- packages/block-library/src/gallery/editor.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/gallery/editor.scss b/packages/block-library/src/gallery/editor.scss index ae36e0aa74ac33..5931d95b5300ff 100644 --- a/packages/block-library/src/gallery/editor.scss +++ b/packages/block-library/src/gallery/editor.scss @@ -17,8 +17,10 @@ figure.wp-block-gallery { margin: 0; } -// need to override default editor ul styles +// Necessary to to override default editor ul styles. .blocks-gallery-grid.blocks-gallery-grid { + padding-left: 0; + margin-left: 0; margin-bottom: 0; } From 5e13a1cccfa33c9ee18ca00c4bbcd5b642fe26f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Est=C3=AAv=C3=A3o?= <sergioestevao@gmail.com> Date: Thu, 24 Oct 2019 16:37:36 +0100 Subject: [PATCH 063/113] Add platform component (#18058) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add platform component * Improve platform implementation in RN. * Add more documentation and tests. * Update readme file. * Update tests. * Fix filenames for native versions. * Add license attribution * Remove unnecessary lines. * Improve documentation * Remove trailing space * Update packages/element/src/platform.js Co-Authored-By: Grzegorz (Greg) Ziółkowski <grzegorz@gziolo.pl> * Update readme. * Fix lint error. --- packages/element/README.md | 24 +++++++++++++++ packages/element/src/index.js | 1 + packages/element/src/platform.android.js | 18 +++++++++++ packages/element/src/platform.ios.js | 18 +++++++++++ packages/element/src/platform.js | 32 ++++++++++++++++++++ packages/element/src/test/platform.js | 19 ++++++++++++ packages/element/src/test/platform.native.js | 19 ++++++++++++ 7 files changed, 131 insertions(+) create mode 100644 packages/element/src/platform.android.js create mode 100644 packages/element/src/platform.ios.js create mode 100644 packages/element/src/platform.js create mode 100644 packages/element/src/test/platform.js create mode 100644 packages/element/src/test/platform.native.js diff --git a/packages/element/README.md b/packages/element/README.md index d592235c5dd8d9..fb0c8089fae2b1 100755 --- a/packages/element/README.md +++ b/packages/element/README.md @@ -224,6 +224,30 @@ _Related_ - <https://reactjs.org/docs/react-api.html#reactmemo> +<a name="Platform" href="#Platform">#</a> **Platform** + +Component used to detect the current Platform being used. +Use Platform.OS === 'web' to detect if running on web enviroment. + +This is the same concept as the React Native implementation. + +_Related_ + +- <https://facebook.github.io/react-native/docs/platform-specific-code#platform-module> + +Here is an example of how to use the select method: + +_Usage_ + +```js +import { Platform } from '@wordpress/element'; + +const placeholderLabel = Platform.select( { + native: __( 'Add media' ), + web: __( 'Drag images, upload new ones or select files from your library.' ), +} ); +``` + <a name="RawHTML" href="#RawHTML">#</a> **RawHTML** Component used as equivalent of Fragment with unescaped HTML, in cases where diff --git a/packages/element/src/index.js b/packages/element/src/index.js index d9d4bf87ecf05d..ad8bae6eff98b0 100644 --- a/packages/element/src/index.js +++ b/packages/element/src/index.js @@ -1,5 +1,6 @@ export * from './react'; export * from './react-platform'; export * from './utils'; +export { default as Platform } from './platform'; export { default as renderToString } from './serialize'; export { default as RawHTML } from './raw-html'; diff --git a/packages/element/src/platform.android.js b/packages/element/src/platform.android.js new file mode 100644 index 00000000000000..4f0da0cab9c683 --- /dev/null +++ b/packages/element/src/platform.android.js @@ -0,0 +1,18 @@ +/** + * External dependencies + */ +import { Platform as OriginalPlatform } from 'react-native'; + +const Platform = { + ...OriginalPlatform, + select: ( spec ) => { + if ( 'android' in spec ) { + return spec.android; + } else if ( 'native' in spec ) { + return spec.native; + } + return spec.default; + }, +}; + +export default Platform; diff --git a/packages/element/src/platform.ios.js b/packages/element/src/platform.ios.js new file mode 100644 index 00000000000000..bbadff1f193319 --- /dev/null +++ b/packages/element/src/platform.ios.js @@ -0,0 +1,18 @@ +/** + * External dependencies + */ +import { Platform as OriginalPlatform } from 'react-native'; + +const Platform = { + ...OriginalPlatform, + select: ( spec ) => { + if ( 'ios' in spec ) { + return spec.ios; + } else if ( 'native' in spec ) { + return spec.native; + } + return spec.default; + }, +}; + +export default Platform; diff --git a/packages/element/src/platform.js b/packages/element/src/platform.js new file mode 100644 index 00000000000000..328f5523b6f95f --- /dev/null +++ b/packages/element/src/platform.js @@ -0,0 +1,32 @@ +/** + * Parts of this source were derived and modified from react-native-web, + * released under the MIT license. + * + * Copyright (c) 2016-present, Nicolas Gallagher. + * Copyright (c) 2015-present, Facebook, Inc. + * + */ +const Platform = { + OS: 'web', + select: ( spec ) => ( 'web' in spec ? spec.web : spec.default ), +}; +/** + * Component used to detect the current Platform being used. + * Use Platform.OS === 'web' to detect if running on web enviroment. + * + * This is the same concept as the React Native implementation. + * + * @see https://facebook.github.io/react-native/docs/platform-specific-code#platform-module + * + * Here is an example of how to use the select method: + * @example + * ```js + * import { Platform } from '@wordpress/element'; + * + * const placeholderLabel = Platform.select( { + * native: __( 'Add media' ), + * web: __( 'Drag images, upload new ones or select files from your library.' ), + * } ); + * ``` + */ +export default Platform; diff --git a/packages/element/src/test/platform.js b/packages/element/src/test/platform.js new file mode 100644 index 00000000000000..fc98f4e19b22a9 --- /dev/null +++ b/packages/element/src/test/platform.js @@ -0,0 +1,19 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; +/** + * Internal dependencies + */ +import Platform from '../platform'; + +describe( 'Platform', () => { + it( 'is chooses the right thing', () => { + const element = Platform.select( { + web: shallow( <div></div> ), + native: shallow( <button></button> ), + } ); + + expect( element.type() ).toBe( 'div' ); + } ); +} ); diff --git a/packages/element/src/test/platform.native.js b/packages/element/src/test/platform.native.js new file mode 100644 index 00000000000000..da6717d66409e0 --- /dev/null +++ b/packages/element/src/test/platform.native.js @@ -0,0 +1,19 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; +/** + * Internal dependencies + */ +import Platform from '../platform'; + +describe( 'Platform', () => { + it( 'is chooses the right thing', () => { + const element = Platform.select( { + web: shallow( <div></div> ), + native: shallow( <button></button> ), + } ); + + expect( element.type() ).toBe( 'button' ); + } ); +} ); From 65c363bc392c1fed3315afc835c31eaaf8e43dc3 Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Thu, 24 Oct 2019 16:42:35 +0100 Subject: [PATCH 064/113] Fix: End to end tests do not disable the experiments (#18093) --- package-lock.json | 1 + packages/e2e-test-utils/CHANGELOG.md | 6 ++++ packages/e2e-test-utils/src/index.js | 1 - .../experimental-features.js} | 33 ++++++++++++------- packages/e2e-tests/package.json | 1 + .../experimental/block-transforms.test.js | 23 +++++++++++-- 6 files changed, 49 insertions(+), 16 deletions(-) rename packages/{e2e-test-utils/src/enable-experimental-features.js => e2e-tests/experimental-features.js} (60%) diff --git a/package-lock.json b/package-lock.json index eb34acc8454813..505ba3894e2e20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7499,6 +7499,7 @@ "@wordpress/jest-console": "file:packages/jest-console", "@wordpress/jest-puppeteer-axe": "file:packages/jest-puppeteer-axe", "@wordpress/scripts": "file:packages/scripts", + "@wordpress/url": "file:packages/url", "expect-puppeteer": "^4.3.0", "lodash": "^4.17.15", "uuid": "^3.3.2" diff --git a/packages/e2e-test-utils/CHANGELOG.md b/packages/e2e-test-utils/CHANGELOG.md index df00ecbe7c0ce2..6d7c17d4e0c7e6 100644 --- a/packages/e2e-test-utils/CHANGELOG.md +++ b/packages/e2e-test-utils/CHANGELOG.md @@ -1,3 +1,9 @@ +## Master + +### Breaking Changes +- The util function `enableExperimentalFeatures` was removed. It is now available for internal usage in the `e2e-tests` package. + + ## 2.0.0 (2019-05-21) ### Requirements diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 8fcf2b400c5853..40feec01014580 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -11,7 +11,6 @@ export { createURL } from './create-url'; export { deactivatePlugin } from './deactivate-plugin'; export { disablePrePublishChecks } from './disable-pre-publish-checks'; export { dragAndResize } from './drag-and-resize'; -export { enableExperimentalFeatures } from './enable-experimental-features'; export { enablePageDialogAccept } from './enable-page-dialog-accept'; export { enablePrePublishChecks } from './enable-pre-publish-checks'; export { ensureSidebarOpened } from './ensure-sidebar-opened'; diff --git a/packages/e2e-test-utils/src/enable-experimental-features.js b/packages/e2e-tests/experimental-features.js similarity index 60% rename from packages/e2e-test-utils/src/enable-experimental-features.js rename to packages/e2e-tests/experimental-features.js index be74f20f82fd92..4b06a761c865a0 100644 --- a/packages/e2e-test-utils/src/enable-experimental-features.js +++ b/packages/e2e-tests/experimental-features.js @@ -2,18 +2,9 @@ * WordPress dependencies */ import { addQueryArgs } from '@wordpress/url'; +import { visitAdminPage } from '@wordpress/e2e-test-utils'; -/** - * Internal dependencies - */ -import { visitAdminPage } from './visit-admin-page'; - -/** - * Enables experimental features from the plugin settings section. - * - * @param {Array} features Array of {string} selectors of settings to enable. Assumes they can be enabled with one click. - */ -export async function enableExperimentalFeatures( features ) { +async function setExperimentalFeaturesState( features, enable ) { const query = addQueryArgs( '', { page: 'gutenberg-experiments', } ); @@ -23,7 +14,7 @@ export async function enableExperimentalFeatures( features ) { await page.waitForSelector( feature ); const checkedSelector = `${ feature }[checked=checked]`; const isChecked = !! ( await page.$( checkedSelector ) ); - if ( ! isChecked ) { + if ( ( ! isChecked && enable ) || ( isChecked && ! enable ) ) { await page.click( feature ); } } ) ); @@ -32,3 +23,21 @@ export async function enableExperimentalFeatures( features ) { page.click( '#submit' ), ] ); } + +/** + * Enables experimental features from the plugin settings section. + * + * @param {Array} features Array of {string} selectors of settings to enable. Assumes they can be enabled with one click. + */ +export async function enableExperimentalFeatures( features ) { + await setExperimentalFeaturesState( features, true ); +} + +/** + * Disables experimental features from the plugin settings section. + * + * @param {Array} features Array of {string} selectors of settings to disable. Assumes they can be disabled with one click. + */ +export async function disableExperimentalFeatures( features ) { + await setExperimentalFeaturesState( features, false ); +} diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index 6517b0042a9b67..b3a75cf9f73145 100644 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -26,6 +26,7 @@ "@wordpress/jest-console": "file:../jest-console", "@wordpress/jest-puppeteer-axe": "file:../jest-puppeteer-axe", "@wordpress/scripts": "file:../scripts", + "@wordpress/url": "file:../url", "expect-puppeteer": "^4.3.0", "lodash": "^4.17.15", "uuid": "^3.3.2" diff --git a/packages/e2e-tests/specs/experimental/block-transforms.test.js b/packages/e2e-tests/specs/experimental/block-transforms.test.js index b298fa42f53ef6..bf6e5027b745e6 100644 --- a/packages/e2e-tests/specs/experimental/block-transforms.test.js +++ b/packages/e2e-tests/specs/experimental/block-transforms.test.js @@ -13,18 +13,25 @@ import { * WordPress dependencies */ import { + createNewPost, getAllBlocks, getAvailableBlockTransforms, getBlockSetting, getEditedPostContent, hasBlockSwitcher, - createNewPost, - enableExperimentalFeatures, - setPostContent, selectBlockByClientId, + setPostContent, transformBlockTo, } from '@wordpress/e2e-test-utils'; +/** + * Internal dependencies + */ +import { + enableExperimentalFeatures, + disableExperimentalFeatures, +} from '../../experimental-features'; + /** * Internal dependencies */ @@ -120,6 +127,16 @@ describe( 'Block transforms', () => { } } ); + afterAll( + async () => { + await disableExperimentalFeatures( [ + '#gutenberg-widget-experiments', + '#gutenberg-menu-block', + '#gutenberg-full-site-editing', + ] ); + } + ); + it( 'should contain the expected transforms', async () => { const transforms = mapValues( pickBy( From 3df5109c47870ed37aa19f11978476960474c2d0 Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Thu, 24 Oct 2019 18:58:46 +0100 Subject: [PATCH 065/113] Fix: Custom button background color not reflected on reload (#18037) Fixes: https://github.com/WordPress/gutenberg/issues/18012 We had a bug where the editor may not reflect the custom button background color after a reload. That happened because the rule background: customGradient, may overwrite the background-color rule even if the custom gradient has not set. This PR performs a logic update to solve the issue. --- packages/block-library/src/button/edit.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index 5d457482cf04bd..b624aa7e5f6218 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -140,8 +140,10 @@ function ButtonEdit( { } ) } style={ { - backgroundColor: ! customGradient && backgroundColor.color, - background: customGradient, + ...( customGradient ? + { background: customGradient } : + { backgroundColor: backgroundColor.color } + ), color: textColor.color, borderRadius: borderRadius ? borderRadius + 'px' : undefined, } } From abf261cf780c98956a711a248de6c9dd520bd757 Mon Sep 17 00:00:00 2001 From: Kerry Liu <gwwar@users.noreply.github.com> Date: Thu, 24 Oct 2019 11:25:15 -0700 Subject: [PATCH 066/113] List Block: Do not merge list with previous block if deleting first list item and list is not empty (#18032) * Do not merge list with previous block if deleting first list item and list is not empty * Add e2e test and clean up * Correct mistake * Adjust comment --- .../blocks/__snapshots__/list.test.js.snap | 6 +++++ .../specs/editor/blocks/list.test.js | 12 +++++++++ packages/rich-text/src/component/index.js | 26 +++++++++++++------ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap index 001c5b93e0edd3..b1e178aa10b710 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/list.test.js.snap @@ -80,6 +80,12 @@ exports[`List can undo asterisk transform 1`] = ` <!-- /wp:paragraph -->" `; +exports[`List first empty list item is graciously removed 1`] = ` +"<!-- wp:list --> +<ul><li>2</li></ul> +<!-- /wp:list -->" +`; + exports[`List should be immeadiately saved on indentation 1`] = ` "<!-- wp:list --> <ul><li>one<ul><li></li></ul></li></ul> diff --git a/packages/e2e-tests/specs/editor/blocks/list.test.js b/packages/e2e-tests/specs/editor/blocks/list.test.js index 7fa889baa0cdd3..9e3086295413e9 100644 --- a/packages/e2e-tests/specs/editor/blocks/list.test.js +++ b/packages/e2e-tests/specs/editor/blocks/list.test.js @@ -478,4 +478,16 @@ describe( 'List', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + + it( 'first empty list item is graciously removed', async () => { + await clickBlockAppender(); + await page.keyboard.type( '* 1' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( '2' ); + await page.keyboard.press( 'ArrowUp' ); + await page.keyboard.press( 'Backspace' ); + await page.keyboard.press( 'Backspace' ); + + expect( await getEditedPostContent() ).toMatchSnapshot(); + } ); } ); diff --git a/packages/rich-text/src/component/index.js b/packages/rich-text/src/component/index.js index e028ba0611623b..d6a40914ea0f90 100644 --- a/packages/rich-text/src/component/index.js +++ b/packages/rich-text/src/component/index.js @@ -35,6 +35,7 @@ import { indentListItems } from '../indent-list-items'; import { getActiveFormats } from '../get-active-formats'; import { updateFormats } from '../update-formats'; import { removeLineSeparator } from '../remove-line-separator'; +import { isEmptyLine } from '../is-empty'; /** * Browser dependencies @@ -604,14 +605,6 @@ class RichText extends Component { const { start, end, text } = value; const isReverse = keyCode === BACKSPACE; - if ( multilineTag ) { - const newValue = removeLineSeparator( value, isReverse ); - if ( newValue ) { - this.onChange( newValue ); - event.preventDefault(); - } - } - // Always handle full content deletion ourselves. if ( start === 0 && end !== 0 && end === text.length ) { this.onChange( remove( value ) ); @@ -619,6 +612,23 @@ class RichText extends Component { return; } + if ( multilineTag ) { + let newValue; + + // Check to see if we should remove the first item if empty. + if ( isReverse && value.start === 0 && value.end === 0 && isEmptyLine( value ) ) { + newValue = removeLineSeparator( value, ! isReverse ); + } else { + newValue = removeLineSeparator( value, isReverse ); + } + + if ( newValue ) { + this.onChange( newValue ); + event.preventDefault(); + return; + } + } + // Only process delete if the key press occurs at an uncollapsed edge. if ( ! onDelete || From 6c556a7c8566a286cf6f9622d0d153669db3683d Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Thu, 24 Oct 2019 21:25:18 +0100 Subject: [PATCH 067/113] Add gradients in cover block (#18001) --- .../src/components/gradient-picker/control.js | 13 +++- packages/block-library/src/cover/block.json | 3 + packages/block-library/src/cover/edit.js | 75 ++++++++++++++++--- packages/block-library/src/cover/editor.scss | 3 +- packages/block-library/src/cover/save.js | 12 +++ packages/block-library/src/cover/style.scss | 22 +++++- .../components/src/gradient-picker/index.js | 3 +- 7 files changed, 111 insertions(+), 20 deletions(-) diff --git a/packages/block-editor/src/components/gradient-picker/control.js b/packages/block-editor/src/components/gradient-picker/control.js index 73609ffdf17e27..a0eeecc6facc25 100644 --- a/packages/block-editor/src/components/gradient-picker/control.js +++ b/packages/block-editor/src/components/gradient-picker/control.js @@ -3,19 +3,27 @@ * External dependencies */ import classnames from 'classnames'; +import { isEmpty } from 'lodash'; /** * WordPress dependencies */ import { BaseControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import GradientPicker from './'; -export default function( { className, ...props } ) { +export default function( { className, label = __( 'Gradient Presets' ), ...props } ) { + const gradients = useSelect( ( select ) => ( + select( 'core/block-editor' ).getSettings().gradients + ) ); + if ( isEmpty( gradients ) ) { + return null; + } return ( <BaseControl className={ classnames( @@ -24,10 +32,11 @@ export default function( { className, ...props } ) { ) } > <BaseControl.VisualLabel> - { __( 'Gradient Presets' ) } + { label } </BaseControl.VisualLabel> <GradientPicker className="block-editor-gradient-picker-control__gradient-picker-presets" + gradients={ gradients } { ...props } /> </BaseControl> diff --git a/packages/block-library/src/cover/block.json b/packages/block-library/src/cover/block.json index 957a8264ef6e6e..67e87f54c8374b 100644 --- a/packages/block-library/src/cover/block.json +++ b/packages/block-library/src/cover/block.json @@ -31,6 +31,9 @@ }, "minHeight": { "type": "number" + }, + "customGradient": { + "type": "string" } } } diff --git a/packages/block-library/src/cover/edit.js b/packages/block-library/src/cover/edit.js index 04d3f61220bbf0..1bc69c5d9af860 100644 --- a/packages/block-library/src/cover/edit.js +++ b/packages/block-library/src/cover/edit.js @@ -39,6 +39,8 @@ import { PanelColorSettings, withColors, ColorPalette, + __experimentalGradientPickerControl, + __experimentalGradientPicker, } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; import { withDispatch } from '@wordpress/data'; @@ -219,12 +221,13 @@ class CoverEdit extends Component { } = this.props; const { backgroundType, + customGradient, dimRatio, focalPoint, hasParallax, id, - url, minHeight, + url, } = attributes; const onSelectMedia = ( media ) => { if ( ! media || ! media.url ) { @@ -282,14 +285,20 @@ class CoverEdit extends Component { minHeight: ( temporaryMinHeight || minHeight ), }; + if ( customGradient && ! url ) { + style.background = customGradient; + } + if ( focalPoint ) { style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`; } + const hasBackground = !! ( url || overlayColor.color || customGradient ); + const controls = ( <> <BlockControls> - { !! ( url || overlayColor.color ) && ( + { hasBackground && ( <> <MediaUploadCheck> <Toolbar> @@ -348,7 +357,7 @@ class CoverEdit extends Component { </PanelRow> </PanelBody> ) } - { ( url || overlayColor.color ) && ( + { hasBackground && ( <> <PanelBody title={ __( 'Dimensions' ) }> <CoverHeightInput @@ -367,10 +376,28 @@ class CoverEdit extends Component { initialOpen={ true } colorSettings={ [ { value: overlayColor.color, - onChange: setOverlayColor, + onChange: ( ...args ) => { + setAttributes( { + customGradient: undefined, + } ); + setOverlayColor( ...args ); + }, label: __( 'Overlay Color' ), } ] } > + <__experimentalGradientPickerControl + label={ __( 'Overlay Gradient' ) } + onChange={ + ( newGradient ) => { + setAttributes( { + customGradient: newGradient, + customOverlayColor: undefined, + overlayColor: undefined, + } ); + } + } + value={ customGradient } + /> { !! url && ( <RangeControl label={ __( 'Background Opacity' ) } @@ -389,7 +416,7 @@ class CoverEdit extends Component { </> ); - if ( ! ( url || overlayColor.color ) ) { + if ( ! hasBackground ) { const placeholderIcon = <BlockIcon icon={ icon } />; const label = __( 'Cover' ); @@ -409,13 +436,29 @@ class CoverEdit extends Component { notices={ noticeUI } onError={ this.onUploadError } > - <ColorPalette - disableCustomColors={ true } - value={ overlayColor.color } - onChange={ setOverlayColor } - clearable={ false } - className="wp-block-cover__placeholder-color-palette" - /> + <div + className="wp-block-cover__placeholder-background-options" + > + <ColorPalette + disableCustomColors={ true } + value={ overlayColor.color } + onChange={ setOverlayColor } + clearable={ false } + /> + <__experimentalGradientPicker + onChange={ + ( newGradient ) => { + setAttributes( { + customGradient: newGradient, + customOverlayColor: undefined, + overlayColor: undefined, + } ); + } + } + value={ customGradient } + clearable={ false } + /> + </div> </MediaPlaceholder> </> ); @@ -429,6 +472,7 @@ class CoverEdit extends Component { 'has-background-dim': dimRatio !== 0, 'has-parallax': hasParallax, [ overlayColor.class ]: overlayColor.class, + 'has-background-gradient': customGradient, } ); @@ -476,6 +520,13 @@ class CoverEdit extends Component { src={ url } /> ) } + { url && customGradient && dimRatio !== 0 && ( + <span + aria-hidden="true" + className="wp-block-cover__gradient-background" + style={ { background: customGradient } } + /> + ) } { VIDEO_BACKGROUND_TYPE === backgroundType && ( <video ref={ this.videoRef } diff --git a/packages/block-library/src/cover/editor.scss b/packages/block-library/src/cover/editor.scss index b40aed0a472b30..906ffe172b9f9a 100644 --- a/packages/block-library/src/cover/editor.scss +++ b/packages/block-library/src/cover/editor.scss @@ -34,10 +34,11 @@ } } - .wp-block-cover__placeholder-color-palette { + .wp-block-cover__placeholder-background-options { // wraps about 6 color swatches max-width: 290px; margin-top: 1em; + width: 100%; } // Apply max-width to floated items that have no intrinsic width diff --git a/packages/block-library/src/cover/save.js b/packages/block-library/src/cover/save.js index de057122a0f7b7..806be32a100f87 100644 --- a/packages/block-library/src/cover/save.js +++ b/packages/block-library/src/cover/save.js @@ -24,6 +24,7 @@ import { export default function save( { attributes } ) { const { backgroundType, + customGradient, customOverlayColor, dimRatio, focalPoint, @@ -42,6 +43,9 @@ export default function save( { attributes } ) { if ( focalPoint && ! hasParallax ) { style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`; } + if ( customGradient && ! url ) { + style.background = customGradient; + } style.minHeight = minHeight || undefined; const classes = classnames( @@ -50,11 +54,19 @@ export default function save( { attributes } ) { { 'has-background-dim': dimRatio !== 0, 'has-parallax': hasParallax, + 'has-background-gradient': customGradient, }, ); return ( <div className={ classes } style={ style }> + { url && customGradient && dimRatio !== 0 && ( + <span + aria-hidden="true" + className="wp-block-cover__gradient-background" + style={ { background: customGradient } } + /> + ) } { VIDEO_BACKGROUND_TYPE === backgroundType && url && ( <video className="wp-block-cover__video-background" autoPlay diff --git a/packages/block-library/src/cover/style.scss b/packages/block-library/src/cover/style.scss index 5cf70fabe760b3..739742d1e62270 100644 --- a/packages/block-library/src/cover/style.scss +++ b/packages/block-library/src/cover/style.scss @@ -30,19 +30,33 @@ &.has-background-dim::before { content: ""; + background-color: inherit; + } + + &.has-background-dim:not(.has-background-gradient)::before, + .wp-block-cover__gradient-background { position: absolute; top: 0; left: 0; bottom: 0; right: 0; - background-color: inherit; - opacity: 0.5; z-index: z-index(".wp-block-cover.has-background-dim::before"); } + &.has-background-dim:not(.has-background-gradient)::before, + & .wp-block-cover__gradient-background { + opacity: 0.5; + } + + @for $i from 1 through 10 { - &.has-background-dim.has-background-dim-#{ $i * 10 }::before { - opacity: $i * 0.1; + &.has-background-dim.has-background-dim-#{ $i * 10 } { + &:not(.has-background-gradient)::before { + opacity: $i * 0.1; + } + .wp-block-cover__gradient-background { + opacity: $i * 0.1; + } } } diff --git a/packages/components/src/gradient-picker/index.js b/packages/components/src/gradient-picker/index.js index 1a60de751646f3..e8ab40f07ada2b 100644 --- a/packages/components/src/gradient-picker/index.js +++ b/packages/components/src/gradient-picker/index.js @@ -19,6 +19,7 @@ export default function GradientPicker( { gradients, onChange, value, + clearable = true, } ) { const clearGradient = useCallback( () => onChange( undefined ), @@ -56,7 +57,7 @@ export default function GradientPicker( { <CircularOptionPicker className={ className } options={ gradientOptions } - actions={ ( + actions={ clearable && ( <CircularOptionPicker.ButtonAction onClick={ clearGradient }> { __( 'Clear' ) } </CircularOptionPicker.ButtonAction> From 20b825a0bcc863c274741c942e306e1328ec0854 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Thu, 24 Oct 2019 13:53:24 -0700 Subject: [PATCH 068/113] Components: Add VisuallyHidden component (#18022) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add ScreenReaderText component * Add new component readme to manifest * Remove CSS style loading within stories * Switch component name to VisuallyHidden - Rename directory and includes - Update README usage - Update Storybook usage * Switch classname to components-visually-hidden * Lint: newline * Add focus style * Switch to 'as' for specifying tag * Move renderAsRenderProps to utils.js * Move utils to inside component folder Waiting to refine the utils usage a little better before making it look available for other components to use. * Apply suggestions from code review Co-Authored-By: Grzegorz (Greg) Ziółkowski <grzegorz@gziolo.pl> * Lint: Move newline * Fix variable name * Use variable for stylesheet --- docs/manifest-devhub.json | 6 ++++ packages/components/src/index.js | 1 + packages/components/src/style.scss | 1 + .../components/src/visually-hidden/README.md | 9 ++++++ .../components/src/visually-hidden/index.js | 22 ++++++++++++++ .../src/visually-hidden/stories/index.js | 17 +++++++++++ .../components/src/visually-hidden/style.scss | 30 +++++++++++++++++++ .../components/src/visually-hidden/utils.js | 22 ++++++++++++++ 8 files changed, 108 insertions(+) create mode 100644 packages/components/src/visually-hidden/README.md create mode 100644 packages/components/src/visually-hidden/index.js create mode 100644 packages/components/src/visually-hidden/stories/index.js create mode 100644 packages/components/src/visually-hidden/style.scss create mode 100644 packages/components/src/visually-hidden/utils.js diff --git a/docs/manifest-devhub.json b/docs/manifest-devhub.json index 998097f22d10e9..b508f649fb7c9e 100644 --- a/docs/manifest-devhub.json +++ b/docs/manifest-devhub.json @@ -971,6 +971,12 @@ "markdown_source": "../packages/components/src/tree-select/README.md", "parent": "components" }, + { + "title": "VisuallyHidden", + "slug": "visually-hidden", + "markdown_source": "../packages/components/src/visually-hidden/README.md", + "parent": "components" + }, { "title": "Data Module Reference", "slug": "data", diff --git a/packages/components/src/index.js b/packages/components/src/index.js index 8542a86ba9b659..463241f06bf66b 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -62,6 +62,7 @@ export { default as Toolbar } from './toolbar'; export { default as ToolbarButton } from './toolbar-button'; export { default as Tooltip } from './tooltip'; export { default as TreeSelect } from './tree-select'; +export { default as VisuallyHidden } from './visually-hidden'; export { default as IsolatedEventContainer } from './isolated-event-container'; export { createSlotFill, Slot, Fill, Provider as SlotFillProvider } from './slot-fill'; diff --git a/packages/components/src/style.scss b/packages/components/src/style.scss index 6365bff68cf568..08fc9961be5e63 100644 --- a/packages/components/src/style.scss +++ b/packages/components/src/style.scss @@ -44,3 +44,4 @@ @import "./toolbar/style.scss"; @import "./toolbar-button/style.scss"; @import "./tooltip/style.scss"; +@import "./visually-hidden/style.scss"; diff --git a/packages/components/src/visually-hidden/README.md b/packages/components/src/visually-hidden/README.md new file mode 100644 index 00000000000000..1f490f5134af26 --- /dev/null +++ b/packages/components/src/visually-hidden/README.md @@ -0,0 +1,9 @@ +# VisuallyHidden + +A component used to render text intended to be visually hidden, but will show for alternate devices, for example a screen reader. + +### Usage + +```jsx +<VisuallyHidden> Show text for screenreader. </VisuallyHidden> +``` diff --git a/packages/components/src/visually-hidden/index.js b/packages/components/src/visually-hidden/index.js new file mode 100644 index 00000000000000..b29c954c2cd9e1 --- /dev/null +++ b/packages/components/src/visually-hidden/index.js @@ -0,0 +1,22 @@ + +/** + * Internal dependencies + */ +import { renderAsRenderProps } from './utils'; + +/** + * VisuallyHidden component to render text out non-visually + * for use in devices such as a screen reader. + */ +function VisuallyHidden( { + as = 'div', + ...props +} ) { + return renderAsRenderProps( { + as, + className: 'components-visually-hidden', + ...props, + } ); +} +export default VisuallyHidden; + diff --git a/packages/components/src/visually-hidden/stories/index.js b/packages/components/src/visually-hidden/stories/index.js new file mode 100644 index 00000000000000..03b60ccc334126 --- /dev/null +++ b/packages/components/src/visually-hidden/stories/index.js @@ -0,0 +1,17 @@ +/** + * Internal dependencies + */ +import VisuallyHidden from '../'; + +export default { title: 'VisuallyHidden', component: VisuallyHidden }; + +export const _default = () => ( + <> + <VisuallyHidden> + This should not show. + </VisuallyHidden> + <div> + This text will <VisuallyHidden as="span">but not inline </VisuallyHidden> always show. + </div> + </> +); diff --git a/packages/components/src/visually-hidden/style.scss b/packages/components/src/visually-hidden/style.scss new file mode 100644 index 00000000000000..02fec4486afa23 --- /dev/null +++ b/packages/components/src/visually-hidden/style.scss @@ -0,0 +1,30 @@ +.components-visually-hidden { + border: 0; + clip: rect(1px, 1px, 1px, 1px); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + word-wrap: normal !important; +} + +.components-visually-hidden:focus { + background-color: $light-gray-500; + clip: auto !important; + clip-path: none; + color: #444; + display: block; + font-size: 1em; + height: auto; + left: 5px; + line-height: normal; + padding: 15px 23px 14px; + text-decoration: none; + top: 5px; + width: auto; + z-index: 100000; +} diff --git a/packages/components/src/visually-hidden/utils.js b/packages/components/src/visually-hidden/utils.js new file mode 100644 index 00000000000000..07957708090ef0 --- /dev/null +++ b/packages/components/src/visually-hidden/utils.js @@ -0,0 +1,22 @@ +/** + * Utility Functions + */ + +/** + * renderAsRenderProps is used to wrap a component and convert + * the passed property "as" either a string or component, to the + * rendered tag if a string, or component. + * + * See VisuallyHidden hidden for example. + * + * @param {string|Component} as A tag or component to render. + * @return {Component} The rendered component. + */ +function renderAsRenderProps( { as: Component = 'div', ...props } ) { + if ( typeof props.children === 'function' ) { + return props.children( props ); + } + return <Component { ...props } />; +} + +export { renderAsRenderProps }; From 7a62af0cb8a280b53c0e26b6da8d0e74f04ee2f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Thu, 24 Oct 2019 23:10:09 +0200 Subject: [PATCH 069/113] Storybook: Apply a set of enhancements to the existing stories (#18030) * Storybook: Apply a set of enhancements to the existing stories * Add basic knobs integration to all Button stories --- .../src/button-group/stories/index.js | 2 +- .../components/src/button/stories/index.js | 93 ++++++++++++++----- .../src/checkbox-control/stories/index.js | 29 ++++-- .../src/clipboard-button/stories/index.js | 29 ++++-- .../src/icon-button/stories/index.js | 17 +++- packages/components/src/icon/stories/index.js | 24 +++-- .../src/scroll-lock/stories/index.js | 2 +- 7 files changed, 150 insertions(+), 46 deletions(-) diff --git a/packages/components/src/button-group/stories/index.js b/packages/components/src/button-group/stories/index.js index 1e1646e0268d15..8b1a694691025c 100644 --- a/packages/components/src/button-group/stories/index.js +++ b/packages/components/src/button-group/stories/index.js @@ -4,7 +4,7 @@ import Button from '../../button'; import ButtonGroup from '../'; -export default { title: 'Button Group', component: ButtonGroup }; +export default { title: 'ButtonGroup', component: ButtonGroup }; export const _default = () => { const style = { margin: '0 4px' }; diff --git a/packages/components/src/button/stories/index.js b/packages/components/src/button/stories/index.js index ae949a1cd72906..b3c3b408c373ec 100644 --- a/packages/components/src/button/stories/index.js +++ b/packages/components/src/button/stories/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ @@ -5,32 +10,78 @@ import Button from '../'; export default { title: 'Button', component: Button }; -export const _default = () => <Button>Hello Button</Button>; +export const _default = () => { + const label = text( 'Label', 'Default Button' ); + + return ( + <Button>{ label }</Button> + ); +}; + +export const primary = () => { + const label = text( 'Label', 'Primary Button' ); + + return ( + <Button isPrimary>{ label }</Button> + ); +}; + +export const large = () => { + const label = text( 'Label', 'Large Button' ); + + return ( + <Button isLarge>{ label }</Button> + ); +}; + +export const largePrimary = () => { + const label = text( 'Label', 'Large Primary Button' ); + + return ( + <Button isPrimary isLarge>{ label }</Button> + ); +}; + +export const small = () => { + const label = text( 'Label', 'Small Button' ); + + return ( + <Button isSmall>{ label }</Button> + ); +}; -export const primary = () => <Button isPrimary>Hello Button</Button>; +export const toggled = () => { + const label = text( 'Label', 'Toggled Button' ); -export const large = () => <Button isLarge>Hello Button</Button>; + return ( + <Button isToggled>{ label }</Button> + ); +}; -export const largePrimary = () => ( - <Button isPrimary isLarge> - Hello Button - </Button> -); +export const disabled = () => { + const label = text( 'Label', 'Disabled Button' ); -export const small = () => <Button isSmall>Hello Button</Button>; + return ( + <Button disabled>{ label }</Button> + ); +}; -export const toggled = () => <Button isToggled>Hello Button</Button>; +export const link = () => { + const label = text( 'Label', 'Link Button' ); -export const disabled = () => <Button disabled>Hello Button</Button>; + return ( + <Button href="https://wordpress.org/" target="_blank"> + { label } + </Button> + ); +}; -export const link = () => ( - <Button href="https://wordpress.org/" target="_blank"> - Hello Button - </Button> -); +export const disabledLink = () => { + const label = text( 'Label', 'Disabled Link Button' ); -export const disabledLink = () => ( - <Button href="https://wordpress.org/" target="_blank" disabled> - Hello Button - </Button> -); + return ( + <Button href="https://wordpress.org/" target="_blank" disabled> + { label } + </Button> + ); +}; diff --git a/packages/components/src/checkbox-control/stories/index.js b/packages/components/src/checkbox-control/stories/index.js index 184abbfe8b1614..40b48ccf3ef3a2 100644 --- a/packages/components/src/checkbox-control/stories/index.js +++ b/packages/components/src/checkbox-control/stories/index.js @@ -13,31 +13,42 @@ import { useState } from '@wordpress/element'; */ import CheckboxControl from '../'; -export default { title: 'Checkbox Control', component: CheckboxControl }; +export default { title: 'CheckboxControl', component: CheckboxControl }; + +const CheckboxControlWithState = ( { checked, ...props } ) => { + const [ isChecked, setChecked ] = useState( checked ); -export const _default = () => { - const [ isChecked, setChecked ] = useState( true ); return ( <CheckboxControl - label="Is author" + { ...props } checked={ isChecked } onChange={ setChecked } /> ); }; -export const All = () => { - const [ isChecked, setChecked ] = useState( true ); +export const _default = () => { + const label = text( 'Label', 'Is author' ); + + return ( + <CheckboxControlWithState + label={ label } + checked + /> + ); +}; + +export const all = () => { const heading = text( 'Heading', 'User' ); const label = text( 'Label', 'Is author' ); const help = text( 'Help', 'Is the user an author or not?' ); + return ( - <CheckboxControl + <CheckboxControlWithState heading={ heading } label={ label } help={ help } - checked={ isChecked } - onChange={ setChecked } + checked /> ); }; diff --git a/packages/components/src/clipboard-button/stories/index.js b/packages/components/src/clipboard-button/stories/index.js index 25632614eb249d..7e0146448d56d5 100644 --- a/packages/components/src/clipboard-button/stories/index.js +++ b/packages/components/src/clipboard-button/stories/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { boolean, text } from '@storybook/addon-knobs'; + /** * WordPress dependencies */ @@ -8,18 +13,30 @@ import { useState } from '@wordpress/element'; */ import ClipboardButton from '../'; -export default { title: 'Clipboard Button', component: ClipboardButton }; +export default { title: 'ClipboardButton', component: ClipboardButton }; + +const ClipboardButtonWithState = ( { copied, ...props } ) => { + const [ isCopied, setCopied ] = useState( copied ); -export const _default = () => { - const [ copied, setCopied ] = useState( false ); return ( <ClipboardButton - isPrimary - text="Text" + { ...props } onCopy={ () => setCopied( true ) } onFinishCopy={ () => setCopied( false ) } > - { copied ? 'Copied!' : 'Copy "Text"' } + { isCopied ? 'Copied!' : `Copy "${ props.text }"` } </ClipboardButton> ); }; + +export const _default = () => { + const isPrimary = boolean( 'Is primary', true ); + const copyText = text( 'Text', 'Text' ); + + return ( + <ClipboardButtonWithState + isPrimary={ isPrimary } + text={ copyText } + /> + ); +}; diff --git a/packages/components/src/icon-button/stories/index.js b/packages/components/src/icon-button/stories/index.js index d093876a20e0a4..b5c4275159dc5b 100644 --- a/packages/components/src/icon-button/stories/index.js +++ b/packages/components/src/icon-button/stories/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ @@ -5,7 +10,17 @@ import IconButton from '../'; export default { title: 'IconButton', component: IconButton }; -export const _default = () => <IconButton icon="ellipsis" label="More" />; +export const _default = () => { + const icon = text( 'Icon', 'ellipsis' ); + const label = text( 'Label', 'More' ); + + return ( + <IconButton + icon={ icon } + label={ label } + /> + ); +}; export const grouped = () => { const GroupContainer = ( { children } ) => ( diff --git a/packages/components/src/icon/stories/index.js b/packages/components/src/icon/stories/index.js index be4e9fed65787f..f2cd8bee1839b5 100644 --- a/packages/components/src/icon/stories/index.js +++ b/packages/components/src/icon/stories/index.js @@ -1,19 +1,29 @@ +/** + * External dependencies + */ +import { number, text } from '@storybook/addon-knobs'; + /** * Internal dependencies */ import Icon from '../'; -import { SVG, Path } from '../../'; +import { SVG, Path } from '../../primitives/svg'; export default { title: 'Icon', component: Icon }; const IconSizeLabel = ( { size } ) => <div style={ { fontSize: 12 } }>{ size }px</div>; -export const _default = () => ( - <div> - <Icon icon="screenoptions" /> - <IconSizeLabel size={ 24 } /> - </div> -); +export const _default = () => { + const icon = text( 'Icon', 'screenoptions' ); + const size = number( 'Size', '24' ); + + return ( + <div> + <Icon icon={ icon } size={ size } /> + <IconSizeLabel size={ size } /> + </div> + ); +}; export const sizes = () => { const iconSizes = [ 14, 16, 20, 24, 28, 32, 40, 48, 56 ]; diff --git a/packages/components/src/scroll-lock/stories/index.js b/packages/components/src/scroll-lock/stories/index.js index 865fb6a7e909b9..20ef27337fc787 100644 --- a/packages/components/src/scroll-lock/stories/index.js +++ b/packages/components/src/scroll-lock/stories/index.js @@ -6,7 +6,7 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import { Button } from '../../'; +import Button from '../../button'; import ScrollLock from '../'; export default { title: 'ScrollLock', component: ScrollLock }; From c16c1a907a79bf62cfb8eb8b94c368dd68da1dd1 Mon Sep 17 00:00:00 2001 From: Enrique Piqueras <epiqueras@users.noreply.github.com> Date: Thu, 24 Oct 2019 18:53:38 -0700 Subject: [PATCH 070/113] Env: Add support for running in themes. (#17732) * Env: Add support for running in themes. * Env: Optimize context detection filter. * Env: Update test directory structure to match convention. --- packages/env/README.md | 2 +- .../env/lib/create-docker-compose-config.js | 15 ++++--- packages/env/lib/detect-context.js | 45 +++++++++++++++++++ packages/env/lib/env.js | 34 ++++++++------ .../env/{tests/cli.test.js => test/cli.js} | 0 5 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 packages/env/lib/detect-context.js rename packages/env/{tests/cli.test.js => test/cli.js} (100%) diff --git a/packages/env/README.md b/packages/env/README.md index 9be3fe8e36709c..1f06dabf9ce710 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -7,7 +7,7 @@ ```sh $ npm -g i @wordpress/env -$ cd path/to/gutenberg # WordPress install will be in path/to/gutenberg-wordpress. +$ cd path/to/plugin-or-theme # WordPress install will be in path/to/plugin-or-theme-wordpress. $ wp-env --help diff --git a/packages/env/lib/create-docker-compose-config.js b/packages/env/lib/create-docker-compose-config.js index 6cc4b8ddfabf1d..f5971723148b57 100644 --- a/packages/env/lib/create-docker-compose-config.js +++ b/packages/env/lib/create-docker-compose-config.js @@ -1,14 +1,15 @@ module.exports = function createDockerComposeConfig( - pluginPath, - pluginName, - pluginTestsPath + cwd, + cwdName, + cwdTestsPath, + context ) { const commonVolumes = ` - - ${ pluginPath }/:/var/www/html/wp-content/plugins/${ pluginName }/ - - ${ pluginPath }${ pluginTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ - - ${ pluginPath }${ pluginTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ pluginName }-test-plugins/`; + - ${ cwd }/:/var/www/html/wp-content/${ context.type }s/${ cwdName }/ + - ${ cwd }${ cwdTestsPath }/e2e-tests/mu-plugins/:/var/www/html/wp-content/mu-plugins/ + - ${ cwd }${ cwdTestsPath }/e2e-tests/plugins/:/var/www/html/wp-content/plugins/${ cwdName }-test-plugins/`; const volumes = ` - - ${ pluginPath }/../${ pluginName }-wordpress/:/var/www/html/${ commonVolumes }`; + - ${ cwd }/../${ cwdName }-wordpress/:/var/www/html/${ commonVolumes }`; const testsVolumes = ` - tests-wordpress:/var/www/html/${ commonVolumes }`; return `version: '2.1' diff --git a/packages/env/lib/detect-context.js b/packages/env/lib/detect-context.js new file mode 100644 index 00000000000000..afc23f6dd5f6f3 --- /dev/null +++ b/packages/env/lib/detect-context.js @@ -0,0 +1,45 @@ +'use strict'; +/** + * External dependencies + */ +const util = require( 'util' ); +const fs = require( 'fs' ); +const stream = require( 'stream' ); +const path = require( 'path' ); + +/** + * Promisified dependencies + */ +const readDir = util.promisify( fs.readdir ); +const finished = util.promisify( stream.finished ); + +module.exports = async function detectContext() { + const context = {}; + + // Race multiple file read streams against each other until + // a plugin or theme header is found. + const files = ( await readDir( './' ) ).filter( + ( file ) => path.extname( file ) === '.php' || path.basename( file ) === 'style.css' + ); + const streams = []; + for ( const file of files ) { + const fileStream = fs.createReadStream( file, 'utf8' ); + fileStream.on( 'data', ( text ) => { + const [ , type ] = text.match( /(Plugin|Theme) Name: .*[\r\n]/ ) || []; + if ( type ) { + context.type = type.toLowerCase(); + + // Stop the creation of new streams by mutating the iterated array. We can't `break`, because we are inside a function. + files.splice( 0 ); + fileStream.destroy(); + streams.forEach( ( otherFileStream ) => otherFileStream.destroy() ); + } + } ); + streams.push( fileStream ); + } + await Promise.all( + streams.map( ( fileStream ) => finished( fileStream ).catch( () => {} ) ) + ); + + return context; +}; diff --git a/packages/env/lib/env.js b/packages/env/lib/env.js index 3b982c0e143f56..c2ba83ac24c221 100644 --- a/packages/env/lib/env.js +++ b/packages/env/lib/env.js @@ -11,12 +11,13 @@ const wait = require( 'util' ).promisify( setTimeout ); /** * Internal dependencies */ +const detectContext = require( './detect-context' ); const createDockerComposeConfig = require( './create-docker-compose-config' ); // Config Variables -const pluginPath = process.cwd(); -const pluginName = path.basename( pluginPath ); -const pluginTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; +const cwd = process.cwd(); +const cwdName = path.basename( cwd ); +const cwdTestsPath = fs.existsSync( './packages' ) ? '/packages' : ''; const dockerComposeOptions = { config: path.join( __dirname, 'docker-compose.yml' ), }; @@ -34,16 +35,18 @@ const setupSite = ( isTests = false ) => isTests ? process.env.WP_ENV_TESTS_PORT || 8889 : process.env.WP_ENV_PORT || 8888 - } --title=${ pluginName } --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, + } --title=${ cwdName } --admin_user=admin --admin_password=password --admin_email=admin@wordpress.org`, isTests ); -const activatePlugin = ( isTests = false ) => - wpCliRun( `wp plugin activate ${ pluginName }`, isTests ); +const activateContext = ( context, isTests = false ) => + wpCliRun( `wp ${ context.type } activate ${ cwdName }`, isTests ); const resetDatabase = ( isTests = false ) => wpCliRun( 'wp db reset --yes', isTests ); module.exports = { async start( { ref, spinner = {} } ) { + const context = await detectContext(); + spinner.text = `Downloading WordPress@${ ref } 0/100%.`; const gitFetchOptions = { fetchOpts: { @@ -64,7 +67,7 @@ module.exports = { }; // Clone or get the repo. - const repoPath = `../${ pluginName }-wordpress/`; + const repoPath = `../${ cwdName }-wordpress/`; const repo = await NodeGit.Clone( 'https://github.com/WordPress/WordPress.git', repoPath, @@ -94,10 +97,10 @@ module.exports = { } spinner.text = `Downloading WordPress@${ ref } 100/100%.`; - spinner.text = `Installing WordPress@${ ref }.`; + spinner.text = `Starting WordPress@${ ref }.`; fs.writeFileSync( dockerComposeOptions.config, - createDockerComposeConfig( pluginPath, pluginName, pluginTestsPath ) + createDockerComposeConfig( cwd, cwdName, cwdTestsPath, context ) ); // These will bring up the database container, @@ -121,11 +124,14 @@ module.exports = { .catch( retryableSiteSetup ) .catch( retryableSiteSetup ); - await Promise.all( [ activatePlugin(), activatePlugin( true ) ] ); + await Promise.all( [ + activateContext( context ), + activateContext( context, true ), + ] ); // Remove dangling containers and finish. await dockerCompose.rm( dockerComposeOptions ); - spinner.text = `Installed WordPress@${ ref }.`; + spinner.text = `Started WordPress@${ ref }.`; }, async stop( { spinner = {} } ) { @@ -135,6 +141,8 @@ module.exports = { }, async clean( { environment, spinner } ) { + const context = await detectContext(); + const description = `${ environment } environment${ environment === 'all' ? 's' : '' }`; @@ -146,7 +154,7 @@ module.exports = { tasks.push( resetDatabase() .then( setupSite ) - .then( activatePlugin ) + .then( activateContext.bind( null, context ) ) .catch( () => {} ) ); } @@ -154,7 +162,7 @@ module.exports = { tasks.push( resetDatabase( true ) .then( setupSite.bind( null, true ) ) - .then( activatePlugin.bind( null, true ) ) + .then( activateContext.bind( null, context, true ) ) .catch( () => {} ) ); } diff --git a/packages/env/tests/cli.test.js b/packages/env/test/cli.js similarity index 100% rename from packages/env/tests/cli.test.js rename to packages/env/test/cli.js From 0b12ac9bab453e90c24c7d214ab4ad2eb01906bd Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Thu, 24 Oct 2019 20:40:57 -0700 Subject: [PATCH 071/113] Storybook: Add Color Palette Component (#17997) * Add Color Palette to Storybook * Apply suggestions from code review Co-Authored-By: Enrique Piqueras <epiqueras@users.noreply.github.com> * Refactor state out of story components, to own * Update packages/components/src/color-palette/stories/index.js --- .../src/color-palette/stories/index.js | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 packages/components/src/color-palette/stories/index.js diff --git a/packages/components/src/color-palette/stories/index.js b/packages/components/src/color-palette/stories/index.js new file mode 100644 index 00000000000000..3cc1f4f8ff66df --- /dev/null +++ b/packages/components/src/color-palette/stories/index.js @@ -0,0 +1,56 @@ +/** + * External dependencies + */ +import { object } from '@storybook/addon-knobs'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import ColorPalette from '../'; + +export default { title: 'ColorPalette', component: ColorPalette }; + +const ColorPaletteWithState = ( props ) => { + const [ color, setColor ] = useState( '#F00' ); + return ( + <ColorPalette + { ...props } + value={ color } + onChange={ setColor } + /> + ); +}; + +export const _default = () => { + const colors = [ + { name: 'red', color: '#f00' }, + { name: 'white', color: '#fff' }, + { name: 'blue', color: '#00f' }, + ]; + + return ( + <ColorPaletteWithState + colors={ colors } + /> + ); +}; + +export const withKnobs = () => { + const colors = [ + object( 'Red', { name: 'red', color: '#f00' } ), + object( 'White', { name: 'white', color: '#fff' } ), + object( 'Blue', { name: 'blue', color: '#00f' } ), + ]; + + return ( + <ColorPaletteWithState + colors={ colors } + /> + ); +}; + From 21445de58278eba94ab4e4f415319a028c8f19fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <wp@iseulde.com> Date: Fri, 25 Oct 2019 11:16:39 +0200 Subject: [PATCH 072/113] Preserve attributes on split (#18102) --- packages/block-library/src/list/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/list/edit.js b/packages/block-library/src/list/edit.js index 6a76a376f617d3..2949d6fdc11047 100644 --- a/packages/block-library/src/list/edit.js +++ b/packages/block-library/src/list/edit.js @@ -124,7 +124,7 @@ export default function ListEdit( { className={ className } placeholder={ __( 'Write list…' ) } onMerge={ mergeBlocks } - onSplit={ ( value ) => createBlock( name, { ordered, values: value } ) } + onSplit={ ( value ) => createBlock( name, { ...attributes, values: value } ) } __unstableOnSplitMiddle={ () => createBlock( 'core/paragraph' ) } onReplace={ onReplace } onRemove={ () => onReplace( [] ) } From ac6dc61b0b7d2330d1a2f59fff5511ecdfc5557d Mon Sep 17 00:00:00 2001 From: Drapich Piotr <drapich.piotr@gmail.com> Date: Fri, 25 Oct 2019 12:55:02 +0200 Subject: [PATCH 073/113] [rnmobile] Breadcrumbs (#17471) * Add breadcrumbs to floating toolbar * Add dark mode support --- .../block-mobile-floating-toolbar.native.js | 9 ++- .../block-mobile-floating-toolbar.native.scss | 9 ++- .../src/components/block-list/block.native.js | 2 + .../block-list/breadcrumb.native.js | 68 +++++++++++++++++++ .../block-list/breadcrumb.native.scss | 28 ++++++++ .../block-list/subdirectory-icon.js | 18 +++++ 6 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 packages/block-editor/src/components/block-list/breadcrumb.native.js create mode 100644 packages/block-editor/src/components/block-list/breadcrumb.native.scss create mode 100644 packages/block-editor/src/components/block-list/subdirectory-icon.js diff --git a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js index cdd54ffdcaca1b..7e09fe8de46f79 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js +++ b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.js @@ -10,21 +10,23 @@ import styles from './block-mobile-floating-toolbar.scss'; /** * WordPress dependencies */ +import { compose, withPreferredColorScheme } from '@wordpress/compose'; import { createSlotFill } from '@wordpress/components'; const { Fill, Slot } = createSlotFill( 'FloatingToolbar' ); -function FloatingToolbar( { children } ) { +const FloatingToolbarFill = ( { children, getStylesFromColorScheme } ) => { return ( <Fill> { ( { innerFloatingToolbar } ) => { + const fillStyle = getStylesFromColorScheme( styles.floatingToolbarFillColor, styles.floatingToolbarFillColorDark ); return ( <TouchableWithoutFeedback> <View // Issue: `FloatingToolbar` placed above the first item in group is not touchable on Android. // Temporary solution: Use `innerFloatingToolbar` to place `FloatingToolbar` over the first item in group. // TODO: `{ top: innerFloatingToolbar ? 0 : -44 }` along with `innerFloatingToolbar` should be removed once issue is fixed. - style={ [ styles.floatingToolbarFill, { top: innerFloatingToolbar ? 0 : -44 } ] } + style={ [ fillStyle, styles.floatingToolbarFill, { top: innerFloatingToolbar ? 0 : -44 } ] } >{ children } </View> </TouchableWithoutFeedback> @@ -33,8 +35,9 @@ function FloatingToolbar( { children } ) { </Fill> ); -} +}; +const FloatingToolbar = compose( withPreferredColorScheme )( FloatingToolbarFill ); FloatingToolbar.Slot = Slot; export default FloatingToolbar; diff --git a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss index 713633516fca23..a9fbd1243e89ab 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss +++ b/packages/block-editor/src/components/block-list/block-mobile-floating-toolbar.native.scss @@ -1,5 +1,4 @@ .floatingToolbarFill { - background-color: $dark-gray-500; margin: auto; min-width: 100; max-height: $floating-toolbar-height; @@ -13,3 +12,11 @@ justify-content: center; align-self: center; } + +.floatingToolbarFillColor { + background-color: rgba(#1d2327, 0.85); +} + +.floatingToolbarFillColorDark { + background-color: rgba(#3c434a, 0.85); +} diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 456c5fad6ac2ab..70d8ff2435b907 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -25,6 +25,7 @@ import BlockEdit from '../block-edit'; import BlockInvalidWarning from './block-invalid-warning'; import BlockMobileToolbar from './block-mobile-toolbar'; import FloatingToolbar from './block-mobile-floating-toolbar'; +import Breadcrumbs from './breadcrumb'; import NavigateUpSVG from './nav-up-icon'; class BlockListBlock extends Component { @@ -136,6 +137,7 @@ class BlockListBlock extends Component { /> <View style={ styles.pipe } /> </Toolbar> + <Breadcrumbs clientId={ clientId } /> </FloatingToolbar> ) } <TouchableWithoutFeedback diff --git a/packages/block-editor/src/components/block-list/breadcrumb.native.js b/packages/block-editor/src/components/block-list/breadcrumb.native.js new file mode 100644 index 00000000000000..0bea56e4da6ddf --- /dev/null +++ b/packages/block-editor/src/components/block-list/breadcrumb.native.js @@ -0,0 +1,68 @@ +/** + * WordPress dependencies + */ +import { Icon } from '@wordpress/components'; +import { withSelect } from '@wordpress/data'; +import { compose } from '@wordpress/compose'; +import { getBlockType } from '@wordpress/blocks'; + +/** + * External dependencies + */ +import { View, Text, TouchableOpacity } from 'react-native'; + +/** + * Internal dependencies + */ +import BlockTitle from '../block-title'; +import SubdirectorSVG from './subdirectory-icon'; + +import styles from './breadcrumb.scss'; + +const BlockBreadcrumb = ( { clientId, blockIcon, rootClientId, rootBlockIcon } ) => { + return ( + <View style={ styles.breadcrumbContainer }> + <TouchableOpacity style={ styles.button } onPress={ () => {/* Open BottomSheet with markup */} }> + { rootClientId && rootBlockIcon && ( + [ <Icon key="parent-icon" size={ 20 } icon={ rootBlockIcon.src } fill={ styles.icon.color } />, + <View key="subdirectory-icon" style={ styles.arrow }><SubdirectorSVG fill={ styles.arrow.color } /></View>, + ] + ) } + <Icon size={ 24 } icon={ blockIcon.src } fill={ styles.icon.color } /> + <Text style={ styles.breadcrumbTitle }><BlockTitle clientId={ clientId } /></Text> + </TouchableOpacity> + </View> + ); +}; + +export default compose( [ + withSelect( ( select, { clientId } ) => { + const { + getBlockRootClientId, + getBlockName, + } = select( 'core/block-editor' ); + + const blockName = getBlockName( clientId ); + const blockType = getBlockType( blockName ); + const blockIcon = blockType.icon; + + const rootClientId = getBlockRootClientId( clientId ); + + if ( ! rootClientId ) { + return { + clientId, + blockIcon, + }; + } + const rootBlockName = getBlockName( rootClientId ); + const rootBlockType = getBlockType( rootBlockName ); + const rootBlockIcon = rootBlockType.icon; + + return { + clientId, + blockIcon, + rootClientId, + rootBlockIcon, + }; + } ), +] )( BlockBreadcrumb ); diff --git a/packages/block-editor/src/components/block-list/breadcrumb.native.scss b/packages/block-editor/src/components/block-list/breadcrumb.native.scss new file mode 100644 index 00000000000000..8e9b103446291c --- /dev/null +++ b/packages/block-editor/src/components/block-list/breadcrumb.native.scss @@ -0,0 +1,28 @@ +.breadcrumbContainer { + flex-direction: row; + align-items: center; + justify-content: flex-start; + padding-left: 5; + padding-right: 15; +} + +.breadcrumbTitle { + color: $white; + margin-left: 4; +} + +.icon { + color: $white; +} + +.button { + flex-direction: row; + align-items: center; +} + +.arrow { + color: $light-opacity-light-700; + margin-top: -4px; + margin-left: 4; + margin-right: 4; +} diff --git a/packages/block-editor/src/components/block-list/subdirectory-icon.js b/packages/block-editor/src/components/block-list/subdirectory-icon.js new file mode 100644 index 00000000000000..9da2bc4a1c88a9 --- /dev/null +++ b/packages/block-editor/src/components/block-list/subdirectory-icon.js @@ -0,0 +1,18 @@ +/** + * WordPress dependencies + */ +import { SVG, Path } from '@wordpress/components'; + +const Subdirectory = ( { ...extraProps } ) => ( + <SVG + xmlns="http://www.w3.org/2000/svg" + width={ 14 } + height={ 14 } + viewBox="0 0 20 20" + { ...extraProps } + > + <Path d="M19 15l-6 6-1.42-1.42L15.17 16H4V4h2v10h9.17l-3.59-3.58L13 9l6 6z" /> + </SVG> ) +; + +export default Subdirectory; From 775d00342ee635bf998e6254cdf6a777aec130a6 Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Fri, 25 Oct 2019 13:13:59 +0100 Subject: [PATCH 074/113] Add a block selection breadcrumb to the bottom of the editor (#17838) --- .../developers/data/data-core-block-editor.md | 13 +++ packages/base-styles/_z-index.scss | 1 + packages/block-editor/README.md | 8 ++ .../src/components/block-breadcrumb/index.js | 77 ++++++++++++++++++ .../components/block-breadcrumb/style.scss | 41 ++++++++++ packages/block-editor/src/components/index.js | 1 + packages/block-editor/src/store/selectors.js | 24 ++++++ packages/block-editor/src/style.scss | 1 + .../block-hierarchy-navigation.test.js | 1 + .../specs/editor/various/sidebar.test.js | 1 + .../edit-post/src/components/layout/index.js | 20 +++-- .../src/components/layout/style.scss | 81 +++++++++++++------ .../src/components/sidebar/style.scss | 4 + .../src/components/text-editor/style.scss | 80 +++++++----------- packages/edit-post/src/style.scss | 2 + 15 files changed, 275 insertions(+), 80 deletions(-) create mode 100644 packages/block-editor/src/components/block-breadcrumb/index.js create mode 100644 packages/block-editor/src/components/block-breadcrumb/style.scss diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index 6f654f23e16090..ac50b42d83b114 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -189,6 +189,19 @@ _Returns_ - `Array`: Ordered client IDs of editor blocks. +<a name="getBlockParents" href="#getBlockParents">#</a> **getBlockParents** + +Given a block client ID, returns the list of all its parents from top to bottom. + +_Parameters_ + +- _state_ `Object`: Editor state. +- _clientId_ `string`: Block from which to find root client ID. + +_Returns_ + +- `Array`: ClientIDs of the parent blocks. + <a name="getBlockRootClientId" href="#getBlockRootClientId">#</a> **getBlockRootClientId** Given a block client ID, returns the root block from which the block is diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index c4e7c3a02aa356..36cc265a0b7f64 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -24,6 +24,7 @@ $z-layers: ( ".block-editor-warning": 5, ".block-library-gallery-item__inline-menu": 20, ".block-editor-url-input__suggestions": 30, + ".edit-post-layout__footer": 30, ".edit-post-header": 30, ".edit-widgets-header": 30, ".block-library-button__inline-link .block-editor-url-input__suggestions": 6, // URL suggestions for button block above sibling inserter diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index a3f84683e02af2..dd62423fe7f77e 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -82,6 +82,14 @@ _Related_ Undocumented declaration. +<a name="BlockBreadcrumb" href="#BlockBreadcrumb">#</a> **BlockBreadcrumb** + +Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. + +_Returns_ + +- `WPElement`: Block Breadcrumb. + <a name="BlockControls" href="#BlockControls">#</a> **BlockControls** Undocumented declaration. diff --git a/packages/block-editor/src/components/block-breadcrumb/index.js b/packages/block-editor/src/components/block-breadcrumb/index.js new file mode 100644 index 00000000000000..adc96ba4eb2d51 --- /dev/null +++ b/packages/block-editor/src/components/block-breadcrumb/index.js @@ -0,0 +1,77 @@ +/** + * WordPress dependencies + */ +import { Button } from '@wordpress/components'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import BlockTitle from '../block-title'; + +/** + * Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb. + * + * @return {WPElement} Block Breadcrumb. + */ +const BlockBreadcrumb = function() { + const { selectBlock, clearSelectedBlock } = useDispatch( 'core/block-editor' ); + const { clientId, parents, hasSelection } = useSelect( ( select ) => { + const { + getSelectionStart, + getSelectedBlockClientId, + getBlockParents, + } = select( 'core/block-editor' ); + const selectedBlockClientId = getSelectedBlockClientId(); + return { + parents: getBlockParents( selectedBlockClientId ), + clientId: selectedBlockClientId, + hasSelection: !! getSelectionStart().clientId, + }; + }, [] ); + + /* + * Disable reason: The `list` ARIA role is redundant but + * Safari+VoiceOver won't announce the list otherwise. + */ + /* eslint-disable jsx-a11y/no-redundant-roles */ + return ( + <ul className="block-editor-block-breadcrumb" role="list" aria-label={ __( 'Block breadcrumb' ) }> + <li + className={ ! hasSelection ? 'block-editor-block-breadcrumb__current' : undefined } + aria-current={ ! hasSelection ? 'true' : undefined } + > + { hasSelection && ( + <Button + className="block-editor-block-breadcrumb__button" + isTertiary + onClick={ clearSelectedBlock } + > + { __( 'Document' ) } + </Button> + ) } + { ! hasSelection && __( 'Document' ) } + </li> + { parents.map( ( parentClientId ) => ( + <li key={ parentClientId }> + <Button + className="block-editor-block-breadcrumb__button" + isTertiary + onClick={ () => selectBlock( parentClientId ) } + > + <BlockTitle clientId={ parentClientId } /> + </Button> + </li> + ) ) } + { !! clientId && ( + <li className="block-editor-block-breadcrumb__current" aria-current="true"> + <BlockTitle clientId={ clientId } /> + </li> + ) } + </ul> + /* eslint-enable jsx-a11y/no-redundant-roles */ + ); +}; + +export default BlockBreadcrumb; diff --git a/packages/block-editor/src/components/block-breadcrumb/style.scss b/packages/block-editor/src/components/block-breadcrumb/style.scss new file mode 100644 index 00000000000000..b20cdd273b2566 --- /dev/null +++ b/packages/block-editor/src/components/block-breadcrumb/style.scss @@ -0,0 +1,41 @@ +.block-editor-block-breadcrumb { + list-style: none; + padding: 0; + margin: 0; + + li { + display: inline-block; + margin: 0; + + &:not(:last-child)::after { + content: "\2192"; // This becomes →. + } + } +} + +.block-editor-block-breadcrumb__button.components-button { + height: $icon-button-size-small; + line-height: $icon-button-size-small; + padding: 0; + + &:hover { + text-decoration: underline; + } + + &:focus { + @include square-style__focus(); + outline-offset: -2px; + box-shadow: none; + } +} + +.block-editor-block-breadcrumb__current { + cursor: default; +} + +.block-editor-block-breadcrumb__button.components-button, +.block-editor-block-breadcrumb__current { + color: $dark-gray-500; + padding: 0 $grid-size; + font-size: inherit; +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 798566bda67088..1c07bbd80e38e9 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -7,6 +7,7 @@ export * from './font-sizes'; export { default as AlignmentToolbar } from './alignment-toolbar'; export { default as Autocomplete } from './autocomplete'; export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; +export { default as BlockBreadcrumb } from './block-breadcrumb'; export { default as BlockControls } from './block-controls'; export { default as BlockEdit } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index ad3cde1d7cb775..a0fd75a3a7b816 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -420,6 +420,30 @@ export function getBlockRootClientId( state, clientId ) { null; } +/** + * Given a block client ID, returns the list of all its parents from top to bottom. + * + * @param {Object} state Editor state. + * @param {string} clientId Block from which to find root client ID. + * + * @return {Array} ClientIDs of the parent blocks. + */ +export const getBlockParents = createSelector( + ( state, clientId ) => { + const parents = []; + let current = clientId; + while ( !! state.blocks.parents[ current ] ) { + current = state.blocks.parents[ current ]; + parents.push( current ); + } + + return parents.reverse(); + }, + ( state ) => [ + state.blocks.parents, + ] +); + /** * Given a block client ID, returns the root of the hierarchy from which the block is nested, return the block itself for root level blocks. * diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 8ebb2e487a4f29..7296c0fa788620 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -3,6 +3,7 @@ @import "./components/block-inspector/style.scss"; @import "./components/block-list/style.scss"; @import "./components/block-list-appender/style.scss"; +@import "./components/block-breadcrumb/style.scss"; @import "./components/block-card/style.scss"; @import "./components/block-compare/style.scss"; @import "./components/block-mover/style.scss"; diff --git a/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js b/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js index 2dc5dc1f6cc544..efba2e1d6afc5e 100644 --- a/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js +++ b/packages/e2e-tests/specs/editor/various/block-hierarchy-navigation.test.js @@ -82,6 +82,7 @@ describe( 'Navigating the block hierarchy', () => { await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); + await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyTimes( 'Tab', 4 ); // Tweak the columns count by increasing it by one. diff --git a/packages/e2e-tests/specs/editor/various/sidebar.test.js b/packages/e2e-tests/specs/editor/various/sidebar.test.js index d0768f916f0f63..c86900f308f1e1 100644 --- a/packages/e2e-tests/specs/editor/various/sidebar.test.js +++ b/packages/e2e-tests/specs/editor/various/sidebar.test.js @@ -91,6 +91,7 @@ describe( 'Sidebar', () => { await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); await pressKeyWithModifier( 'ctrl', '`' ); + await pressKeyWithModifier( 'ctrl', '`' ); // Tab lands at first (presumed selected) option "Document". await page.keyboard.press( 'Tab' ); diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index e29011c8cec529..b8cb779603410c 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -21,6 +21,7 @@ import { EditorNotices, PostPublishPanel, } from '@wordpress/editor'; +import { BlockBreadcrumb } from '@wordpress/block-editor'; import { withDispatch, withSelect } from '@wordpress/data'; import { PluginArea } from '@wordpress/plugins'; import { withViewportMatch } from '@wordpress/viewport'; @@ -59,7 +60,7 @@ function Layout( { } ) { const sidebarIsOpened = editorSidebarOpened || pluginSidebarOpened || publishSidebarOpened; - const className = classnames( 'edit-post-layout', { + const className = classnames( 'edit-post-layout', 'is-mode-' + mode, { 'is-sidebar-opened': sidebarIsOpened, 'has-fixed-toolbar': hasFixedToolbar, 'has-metaboxes': hasActiveMetaboxes, @@ -80,7 +81,7 @@ function Layout( { <LocalAutosaveMonitor /> <Header /> <div - className="edit-post-layout__content" + className="edit-post-layout__content edit-post-layout__scrollable-container" role="region" /* translators: accessibility text for the content landmark region. */ aria-label={ __( 'Editor content' ) } @@ -99,7 +100,19 @@ function Layout( { <div className="edit-post-layout__metaboxes"> <MetaBoxes location="advanced" /> </div> + { isMobileViewport && sidebarIsOpened && <ScrollLock /> } </div> + { isRichEditingEnabled && mode === 'visual' && ( + <div + className="edit-post-layout__footer" + role="region" + /* translators: accessibility text for the content landmark region. */ + aria-label={ __( 'Editor footer' ) } + tabIndex="-1" + > + <BlockBreadcrumb /> + </div> + ) } { publishSidebarOpened ? ( <PostPublishPanel { ...publishLandmarkProps } @@ -124,9 +137,6 @@ function Layout( { </div> <SettingsSidebar /> <Sidebar.Slot /> - { - isMobileViewport && sidebarIsOpened && <ScrollLock /> - } </> ) } <Popover.Slot /> diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss index 43996d98f8c8f0..40e49f9df3b355 100644 --- a/packages/edit-post/src/components/layout/style.scss +++ b/packages/edit-post/src/components/layout/style.scss @@ -54,7 +54,7 @@ // Because the body element scrolls the navigation sidebar, we have to use position fixed here. // Otherwise you would scroll the editing canvas out of view when you scroll the sidebar. position: fixed; - bottom: 0; + bottom: $footer-height; left: 0; right: 0; @@ -70,6 +70,12 @@ // Because we are beyond the medium breakpoint, we only have to worry about folded, auto-folded, and default. margin-left: $admin-sidebar-width; + // Make room for the footer + .edit-post-layout.is-mode-visual & { + bottom: $footer-height; + min-height: calc(100% - #{ $header-height + $admin-bar-height + $footer-height }); + } + // Auto fold is when on smaller breakpoints, nav menu auto colllapses. body.auto-fold & { margin-left: $admin-sidebar-width-collapsed; @@ -104,31 +110,6 @@ } } - // Pad the scroll box so content on the bottom can be scrolled up. - padding-bottom: 50vh; - @include break-small { - padding-bottom: 0; - } - - // On mobile the main content (html or body) area has to scroll. - // If, like we do on the desktop, scroll an element (.edit-post-layout__content) you can invoke - // the overscroll bounce on the non-scrolling container, causing for a frustrating scrolling experience. - // The following rule enables this scrolling beyond the mobile breakpoint, because on the desktop - // breakpoints scrolling an isolated element helps avoid scroll bleed. - @include break-small() { - overflow-y: auto; - } - -webkit-overflow-scrolling: touch; - - // This rule ensures that if you've scrolled to the end of a container, - // then pause, then keep scrolling downwards, the browser doesn't try to scroll - // the parent element, usually invoking a "bounce" effect and then preventing you - // from scrolling upwards until you pause again. - // This is only necessary beyond the small breakpoint because that's when the scroll container changes. - @include break-small() { - overscroll-behavior-y: none; - } - .edit-post-visual-editor { flex: 1 1 auto; @@ -234,3 +215,51 @@ } } } + +.edit-post-layout__footer { + display: none; + z-index: z-index(".edit-post-layout__footer"); + + // Stretch to mimic outline padding on desktop. + @include break-medium() { + display: flex; + position: fixed; + bottom: 0; + right: 0; + background: $white; + height: $footer-height; + padding: 0 $grid-size; + align-items: center; + border-top: $border-width solid $light-gray-500; + font-size: $default-font-size; + box-sizing: border-box; + } +} +@include editor-left(".edit-post-layout__footer"); + +.edit-post-layout__scrollable-container { + // On mobile the main content (html or body) area has to scroll. + // If, like we do on the desktop, scroll an element (.edit-post-layout__content) you can invoke + // the overscroll bounce on the non-scrolling container, causing for a frustrating scrolling experience. + // The following rule enables this scrolling beyond the mobile breakpoint, because on the desktop + // breakpoints scrolling an isolated element helps avoid scroll bleed. + @include break-small() { + overflow-y: auto; + } + -webkit-overflow-scrolling: touch; + + // This rule ensures that if you've scrolled to the end of a container, + // then pause, then keep scrolling downwards, the browser doesn't try to scroll + // the parent element, usually invoking a "bounce" effect and then preventing you + // from scrolling upwards until you pause again. + // This is only necessary beyond the small breakpoint because that's when the scroll container changes. + @include break-small() { + overscroll-behavior-y: none; + } + + // Pad the scroll box so content on the bottom can be scrolled up. + padding-bottom: 50vh; + @include break-small { + padding-bottom: 0; + } +} diff --git a/packages/edit-post/src/components/sidebar/style.scss b/packages/edit-post/src/components/sidebar/style.scss index 740355cf636f75..50ddd2efedbde5 100644 --- a/packages/edit-post/src/components/sidebar/style.scss +++ b/packages/edit-post/src/components/sidebar/style.scss @@ -22,6 +22,10 @@ @include break-medium() { top: $admin-bar-height + $header-height; + .edit-post-layout.is-mode-visual & { + bottom: $footer-height; + } + body.is-fullscreen-mode & { top: $header-height; } diff --git a/packages/edit-post/src/components/text-editor/style.scss b/packages/edit-post/src/components/text-editor/style.scss index 234eb46917b247..f7696bb4ee1959 100644 --- a/packages/edit-post/src/components/text-editor/style.scss +++ b/packages/edit-post/src/components/text-editor/style.scss @@ -1,30 +1,5 @@ -.edit-post-text-editor__body { - padding-top: $grid-size * 5; - - @include break-small() { - padding-top: ($grid-size * 5) + $admin-bar-height-big; - } - - @include break-medium() { - padding-top: $grid-size * 5; - - body.is-fullscreen-mode & { - padding-top: $grid-size * 5; - } - } -} - .edit-post-text-editor { width: 100%; - max-width: calc(100% - #{$grid-size-large * 2}); - margin-left: $grid-size-large; - margin-right: $grid-size-large; - - @include break-small() { - max-width: $content-width; - margin-left: auto; - margin-right: auto; - } // Always show outlines in code editor .editor-post-title__block { @@ -67,34 +42,41 @@ } } - .editor-post-text-editor { - padding: $block-padding; - min-height: 200px; - line-height: 1.8; - } - // Make room for toolbar. padding-top: $block-controls-height + $grid-size; +} - // Exit Code Editor toolbar. - .edit-post-text-editor__toolbar { - position: absolute; - top: $grid-size; - left: 0; - right: 0; - height: $block-controls-height; - line-height: $block-controls-height; - padding: 0 $grid-size 0 $grid-size-large; - display: flex; +// Exit Code Editor toolbar. +.edit-post-text-editor__toolbar { + position: absolute; + top: $grid-size; + left: 0; + right: 0; + height: $block-controls-height; + line-height: $block-controls-height; + padding: 0 $grid-size 0 $grid-size-large; + display: flex; + + h2 { + margin: 0 auto 0 0; + font-size: $default-font-size; + color: $dark-gray-500; + } - h2 { - margin: 0 auto 0 0; - font-size: $default-font-size; - color: $dark-gray-500; - } + .components-icon-button svg { + order: 1; + } +} - .components-icon-button svg { - order: 1; - } +.edit-post-text-editor__body { + max-width: calc(100% - #{$grid-size-large * 2}); + margin-left: $grid-size-large; + margin-right: $grid-size-large; + padding-top: $grid-size * 5; + + @include break-small() { + max-width: $content-width; + margin-left: auto; + margin-right: auto; } } diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index 69f30ce6abc434..94fcfa7ac60fe6 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -1,3 +1,5 @@ +$footer-height: $icon-button-size-small; + @import "./components/fullscreen-mode/style.scss"; @import "./components/header/style.scss"; @import "./components/header/fullscreen-mode-close/style.scss"; From c4eb0ef953dfc2b7542347832f299f08c11d2c2f Mon Sep 17 00:00:00 2001 From: Matt Chowning <matt.chowning@automattic.com> Date: Fri, 25 Oct 2019 11:27:56 -0400 Subject: [PATCH 075/113] RNMobile: Add image alignment controls (#17962) RNMobile: Add image alignment controls Only handles left, center, right. Does not permit setting or displaying either full or wide alignments. --- .../src/components/index.native.js | 1 + packages/block-library/src/image/edit.js | 4 +-- .../block-library/src/image/edit.native.js | 27 ++++++++++++++++--- packages/block-library/src/image/icon.js | 4 ++- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index b278e29d4555a9..9d293b8ccc1538 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -1,4 +1,5 @@ // Block Creation Components +export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; export { default as BlockControls } from './block-controls'; export { default as BlockEdit } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index fe51a775c4d271..897f4d1b242ec8 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -25,7 +25,6 @@ import { NavigableMenu, PanelBody, Path, - Rect, ResizableBox, SelectControl, Spinner, @@ -70,7 +69,7 @@ import { speak } from '@wordpress/a11y'; * Internal dependencies */ import { createUpgradedEmbedBlock } from '../embed/util'; -import icon from './icon'; +import icon, { editImageIcon } from './icon'; import ImageSize from './image-size'; import { getUpdatedLinkTargetSettings, removeNewTabRel } from './utils'; @@ -587,7 +586,6 @@ export class ImageEdit extends Component { const cleanRel = removeNewTabRel( rel ); const isExternal = isExternalImage( id, url ); - const editImageIcon = ( <SVG width={ 20 } height={ 20 } viewBox="0 0 20 20"><Rect x={ 11 } y={ 3 } width={ 7 } height={ 5 } rx={ 1 } /><Rect x={ 2 } y={ 12 } width={ 7 } height={ 5 } rx={ 1 } /><Path d="M13,12h1a3,3,0,0,1-3,3v2a5,5,0,0,0,5-5h1L15,9Z" /><Path d="M4,8H3l2,3L7,8H6A3,3,0,0,1,9,5V3A5,5,0,0,0,4,8Z" /></SVG> ); const controls = ( <BlockControls> <BlockAlignmentToolbar diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index be86e880ff2a77..53334a888dd946 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -33,6 +33,7 @@ import { MEDIA_TYPE_IMAGE, BlockControls, InspectorControls, + BlockAlignmentToolbar, } from '@wordpress/block-editor'; import { __, sprintf } from '@wordpress/i18n'; import { isURL } from '@wordpress/url'; @@ -43,7 +44,7 @@ import { withPreferredColorScheme } from '@wordpress/compose'; * Internal dependencies */ import styles from './styles.scss'; -import SvgIcon from './icon'; +import SvgIcon, { editImageIcon } from './icon'; import SvgIconRetry from './icon-retry'; import { getUpdatedLinkTargetSettings } from './utils'; @@ -89,6 +90,7 @@ export class ImageEdit extends React.Component { this.onImagePressed = this.onImagePressed.bind( this ); this.onClearSettings = this.onClearSettings.bind( this ); this.onFocusCaption = this.onFocusCaption.bind( this ); + this.updateAlignment = this.updateAlignment.bind( this ); } componentDidMount() { @@ -183,6 +185,10 @@ export class ImageEdit extends React.Component { this.props.setAttributes( { url, width: undefined, height: undefined } ); } + updateAlignment( nextAlign ) { + this.props.setAttributes( { align: nextAlign } ); + } + onSetLinkDestination( href ) { this.props.setAttributes( { linkDestination: LINK_DESTINATION_CUSTOM, @@ -239,7 +245,7 @@ export class ImageEdit extends React.Component { render() { const { attributes, isSelected } = this.props; - const { url, height, width, alt, href, id, linkTarget, sizeSlug } = attributes; + const { align, url, height, width, alt, href, id, linkTarget, sizeSlug } = attributes; const actions = [ { label: __( 'Clear All Settings' ), onPress: this.onClearSettings } ]; @@ -248,10 +254,15 @@ export class ImageEdit extends React.Component { <Toolbar> <ToolbarButton title={ __( 'Edit image' ) } - icon="edit" + icon={ editImageIcon } onClick={ open } /> </Toolbar> + <BlockAlignmentToolbar + value={ align } + onChange={ this.updateAlignment } + isCollapsed={ false } + /> </BlockControls> ); @@ -310,6 +321,14 @@ export class ImageEdit extends React.Component { ); } + const alignToFlex = { + left: 'flex-start', + center: 'center', + right: 'flex-end', + full: 'center', + wide: 'center', + }; + const imageContainerHeight = Dimensions.get( 'window' ).width / IMAGE_ASPECT_RATIO; const getImageComponent = ( openMediaOptions, getMediaOptions ) => ( <TouchableWithoutFeedback @@ -344,7 +363,7 @@ export class ImageEdit extends React.Component { ); return ( - <View style={ { flex: 1 } } > + <View style={ { flex: 1, alignSelf: alignToFlex[ align ] } } > { ! imageWidthWithinContainer && <View style={ [ styles.imageContainer, { height: imageContainerHeight } ] } > { this.getIcon( false ) } diff --git a/packages/block-library/src/image/icon.js b/packages/block-library/src/image/icon.js index b029bab8fbe98a..44f88783d24cfa 100644 --- a/packages/block-library/src/image/icon.js +++ b/packages/block-library/src/image/icon.js @@ -1,6 +1,8 @@ /** * WordPress dependencies */ -import { Path, SVG } from '@wordpress/components'; +import { Path, Rect, SVG } from '@wordpress/components'; export default <SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><Path d="M0,0h24v24H0V0z" fill="none" /><Path d="m19 5v14h-14v-14h14m0-2h-14c-1.1 0-2 0.9-2 2v14c0 1.1 0.9 2 2 2h14c1.1 0 2-0.9 2-2v-14c0-1.1-0.9-2-2-2z" /><Path d="m14.14 11.86l-3 3.87-2.14-2.59-3 3.86h12l-3.86-5.14z" /></SVG>; + +export const editImageIcon = ( <SVG width={ 20 } height={ 20 } viewBox="0 0 20 20"><Rect x={ 11 } y={ 3 } width={ 7 } height={ 5 } rx={ 1 } /><Rect x={ 2 } y={ 12 } width={ 7 } height={ 5 } rx={ 1 } /><Path d="M13,12h1a3,3,0,0,1-3,3v2a5,5,0,0,0,5-5h1L15,9Z" /><Path d="M4,8H3l2,3L7,8H6A3,3,0,0,1,9,5V3A5,5,0,0,0,4,8Z" /></SVG> ); From be6a8fd32d17b6f927699aa3a7baa7f91daff3a2 Mon Sep 17 00:00:00 2001 From: Joen Asmussen <joen@automattic.com> Date: Fri, 25 Oct 2019 18:01:29 +0200 Subject: [PATCH 076/113] Fix checkboxes for postmeta. (#18108) --- .../meta-boxes/meta-boxes-area/style.scss | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss index b86d15952683b0..184835a024c35c 100644 --- a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss +++ b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/style.scss @@ -81,6 +81,25 @@ .is-hidden { display: none; } + + + // Until checkboxes WordPress-wide are updated to match the new style, + // checkboxes used in metaboxes have to be slightly unstyled here. + // @todo: remove this entire rule once checkboxes are the same everywhere. + // See: https://github.com/WordPress/gutenberg/issues/18053 + .postbox-container .postbox input[type="checkbox"], + .postbox-container .postbox input[type="radio"] { + border: $border-width solid $dark-gray-300; + + &:checked { + background: $white; + border-color: $dark-gray-300; + } + + &::before { + margin: -3px -4px; + } + } } .edit-post-meta-boxes-area__clear { From 8d0e5aab1a1c75b52e636aaeda36efd48d1dc838 Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Fri, 25 Oct 2019 17:53:36 +0100 Subject: [PATCH 077/113] Add block inspector to the Gutenberg playground. (#18077) --- playground/src/index.js | 4 ++++ playground/src/style.scss | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/playground/src/index.js b/playground/src/index.js index ea5b149fedde1c..66815d8a027256 100644 --- a/playground/src/index.js +++ b/playground/src/index.js @@ -8,6 +8,7 @@ import { BlockEditorKeyboardShortcuts, BlockEditorProvider, BlockList, + BlockInspector, WritingFlow, ObserveTyping, } from '@wordpress/block-editor'; @@ -53,6 +54,9 @@ function App() { onInput={ updateBlocks } onChange={ updateBlocks } > + <div className="playground__sidebar"> + <BlockInspector /> + </div> <div className="editor-styles-wrapper"> <BlockEditorKeyboardShortcuts /> <WritingFlow> diff --git a/playground/src/style.scss b/playground/src/style.scss index 0fc00355758af5..b6fd8395ac08e8 100644 --- a/playground/src/style.scss +++ b/playground/src/style.scss @@ -8,6 +8,7 @@ @import "./reset"; @import "./editor-styles"; +$playground-header-height: 95px; .playground__header { align-items: center; @@ -15,6 +16,25 @@ display: flex; justify-content: space-between; padding: 20px; + height: $playground-header-height; +} + +.playground__sidebar { + position: fixed; + top: $playground-header-height; + right: 0; + bottom: 0; + width: $sidebar-width; + border-left: $border-width solid $light-gray-500; + height: auto; + overflow: auto; + -webkit-overflow-scrolling: touch; + + // Temporarily disable the sidebar on mobile + display: none; + @include break-small() { + display: block; + } } .playground__logo { @@ -23,6 +43,9 @@ } .playground__body { + @include break-small() { + width: calc(100% - #{$sidebar-width}); + } padding-top: 20px; img { From 9781a027f324e093ae0970fb1c9c134333d66596 Mon Sep 17 00:00:00 2001 From: Enrique Piqueras <epiqueras@users.noreply.github.com> Date: Fri, 25 Oct 2019 14:25:11 -0700 Subject: [PATCH 078/113] Block Editor: Implement new colors hook. (#16781) * Block Editor: Implement new colors hook. * Block Library: Swap usage of the colors HOC with the colors hook in the heading edit component. * Use Colors: Add 'has-x-color' class names. * Use Colors: Avoid memory leaks by making caches limited in size, and tied to hook instances. * Use Colors: Support children and optional contrast checking in the color panel. * Use Colors: Expose colors panel without inspector slot/fill wrapper. * Use Colors: Mark hook as experimental. * Use Colors: Support custom colors. * Block Edit: Remove extra context values and use selectors/actions instead. * Heading: Remove unnecessary color class and set text color on save. * Use Colors: Add custom/preset color logic. * Use Colors: Fix panel bugs. * Heading Block: Detect actual background color for contrast checking. * Block Edit: Add new export to native file. * Use Colors: Change CSS "attribute" to "property". --- packages/block-editor/README.md | 4 + .../src/components/block-edit/context.js | 8 +- .../src/components/block-edit/index.js | 3 +- .../src/components/colors/index.js | 1 + .../src/components/colors/use-colors.js | 207 ++++++++++++++++++ packages/block-editor/src/components/index.js | 2 +- .../src/components/index.native.js | 2 +- packages/block-library/src/heading/edit.js | 109 ++++----- 8 files changed, 270 insertions(+), 66 deletions(-) create mode 100644 packages/block-editor/src/components/colors/use-colors.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index dd62423fe7f77e..432d36a72ac70c 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -459,6 +459,10 @@ _Related_ - <https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/url-popover/README.md> +<a name="useBlockEditContext" href="#useBlockEditContext">#</a> **useBlockEditContext** + +Undocumented declaration. + <a name="Warning" href="#Warning">#</a> **Warning** Undocumented declaration. diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index 2f949882593d90..4157735cd2fa70 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -6,18 +6,22 @@ import { noop } from 'lodash'; /** * WordPress dependencies */ -import { createContext } from '@wordpress/element'; +import { createContext, useContext } from '@wordpress/element'; import { createHigherOrderComponent } from '@wordpress/compose'; -const { Consumer, Provider } = createContext( { +const Context = createContext( { name: '', isSelected: false, focusedElement: null, setFocusedElement: noop, clientId: null, } ); +const { Provider, Consumer } = Context; export { Provider as BlockEditContextProvider }; +export function useBlockEditContext() { + return useContext( Context ); +} /** * A Higher Order Component used to inject BlockEdit context to the diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index 63c475a50692ff..403a5cd87898e3 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -12,7 +12,7 @@ import { Component } from '@wordpress/element'; * Internal dependencies */ import Edit from './edit'; -import { BlockEditContextProvider } from './context'; +import { BlockEditContextProvider, useBlockEditContext } from './context'; class BlockEdit extends Component { constructor() { @@ -44,3 +44,4 @@ class BlockEdit extends Component { } export default BlockEdit; +export { useBlockEditContext }; diff --git a/packages/block-editor/src/components/colors/index.js b/packages/block-editor/src/components/colors/index.js index f6b6fac984db89..cadb34a8c9aa37 100644 --- a/packages/block-editor/src/components/colors/index.js +++ b/packages/block-editor/src/components/colors/index.js @@ -7,3 +7,4 @@ export { createCustomColorsHOC, default as withColors, } from './with-colors'; +export { default as __experimentalUseColors } from './use-colors'; diff --git a/packages/block-editor/src/components/colors/use-colors.js b/packages/block-editor/src/components/colors/use-colors.js new file mode 100644 index 00000000000000..ee3f37c8b00bf7 --- /dev/null +++ b/packages/block-editor/src/components/colors/use-colors.js @@ -0,0 +1,207 @@ +/** + * External dependencies + */ +import memoize from 'memize'; +import { kebabCase, camelCase, startCase } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { + useCallback, + useMemo, + Children, + cloneElement, +} from '@wordpress/element'; + +/** + * Internal dependencies + */ +import PanelColorSettings from '../panel-color-settings'; +import ContrastChecker from '../contrast-checker'; +import InspectorControls from '../inspector-controls'; +import { useBlockEditContext } from '../block-edit'; + +const ColorPanel = ( { + title, + colorSettings, + colorPanelProps, + contrastCheckerProps, + components, + panelChildren, +} ) => ( + <PanelColorSettings + title={ title } + initialOpen={ false } + colorSettings={ colorSettings } + { ...colorPanelProps } + > + { contrastCheckerProps && + components.map( ( Component, index ) => ( + <ContrastChecker + key={ Component.displayName } + textColor={ colorSettings[ index ].value } + { ...contrastCheckerProps } + /> + ) ) } + { typeof panelChildren === 'function' ? + panelChildren( components ) : + panelChildren } + </PanelColorSettings> +); +const InspectorControlsColorPanel = ( props ) => ( + <InspectorControls> + <ColorPanel { ...props } /> + </InspectorControls> +); + +export default function __experimentalUseColors( + colorConfigs, + { + panelTitle = __( 'Color Settings' ), + colorPanelProps, + contrastCheckerProps, + panelChildren, + } = { + panelTitle: __( 'Color Settings' ), + }, + deps = [] +) { + const { clientId } = useBlockEditContext(); + const { attributes, settingsColors } = useSelect( + ( select ) => { + const { getBlockAttributes, getSettings } = select( 'core/block-editor' ); + return { + attributes: getBlockAttributes( clientId ), + settingsColors: getSettings().colors, + }; + }, + [ clientId ] + ); + const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); + const setAttributes = useCallback( + ( newAttributes ) => updateBlockAttributes( clientId, newAttributes ), + [ updateBlockAttributes, clientId ] + ); + + const createComponent = useMemo( + () => + memoize( + ( property, color, colorValue, customColor ) => ( { children } ) => + // Clone children, setting the style property from the color configuration, + // if not already set explicitly through props. + Children.map( children, ( child ) => { + let className = child.props.className; + let style = child.props.style; + if ( color ) { + className = `${ child.props.className } has-${ kebabCase( + color + ) }-${ kebabCase( property ) }`; + style = { [ property ]: colorValue, ...child.props.style }; + } else if ( customColor ) { + className = `${ child.props.className } has-${ kebabCase( property ) }`; + style = { [ property ]: customColor, ...child.props.style }; + } + return cloneElement( child, { + className, + style, + } ); + } ), + { maxSize: colorConfigs.length } + ), + [ colorConfigs.length ] + ); + const createSetColor = useMemo( + () => + memoize( + ( name, colors ) => ( newColor ) => { + const color = colors.find( ( _color ) => _color.color === newColor ); + setAttributes( { + [ color ? camelCase( `custom ${ name }` ) : name ]: undefined, + } ); + setAttributes( { + [ color ? name : camelCase( `custom ${ name }` ) ]: color ? + color.slug : + newColor, + } ); + }, + { + maxSize: colorConfigs.length, + } + ), + [ setAttributes, colorConfigs.length ] + ); + + return useMemo( () => { + const colorSettings = []; + + const components = colorConfigs.reduce( ( acc, colorConfig ) => { + if ( typeof colorConfig === 'string' ) { + colorConfig = { name: colorConfig }; + } + const { + name, // E.g. 'backgroundColor'. + property = name, // E.g. 'backgroundColor'. + + panelLabel = startCase( name ), // E.g. 'Background Color'. + componentName = panelLabel.replace( /\s/g, '' ), // E.g. 'BackgroundColor'. + + color = colorConfig.color, + colors = settingsColors, + } = { + ...colorConfig, + color: attributes[ colorConfig.name ], + }; + + // We memoize the non-primitives to avoid unnecessary updates + // when they are used as props for other components. + const _color = colors.find( ( __color ) => __color.slug === color ); + acc[ componentName ] = createComponent( + property, + color, + _color && _color.color, + attributes[ camelCase( `custom ${ name }` ) ] + ); + acc[ componentName ].displayName = componentName; + acc[ componentName ].color = color; + acc[ componentName ].setColor = createSetColor( name, colors ); + + const newSettingIndex = + colorSettings.push( { + value: _color ? + _color.color : + attributes[ camelCase( `custom ${ name }` ) ], + onChange: acc[ componentName ].setColor, + label: panelLabel, + colors, + } ) - 1; + // These settings will be spread over the `colors` in + // `colorPanelProps`, so we need to unset the key here, + // if not set to an actual value, to avoid overwriting + // an actual value in `colorPanelProps`. + if ( ! colors ) { + delete colorSettings[ newSettingIndex ].colors; + } + + return acc; + }, {} ); + + const wrappedColorPanelProps = { + title: panelTitle, + colorSettings, + colorPanelProps, + contrastCheckerProps, + components: Object.values( components ), + panelChildren, + }; + return { + ...components, + ColorPanel: <ColorPanel { ...wrappedColorPanelProps } />, + InspectorControlsColorPanel: ( + <InspectorControlsColorPanel { ...wrappedColorPanelProps } /> + ), + }; + }, [ attributes, setAttributes, ...deps ] ); +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 1c07bbd80e38e9..5818e37395c8ea 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -9,7 +9,7 @@ export { default as Autocomplete } from './autocomplete'; export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; export { default as BlockBreadcrumb } from './block-breadcrumb'; export { default as BlockControls } from './block-controls'; -export { default as BlockEdit } from './block-edit'; +export { default as BlockEdit, useBlockEditContext } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; export { default as BlockIcon } from './block-icon'; export { default as BlockNavigationDropdown } from './block-navigation/dropdown'; diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index 9d293b8ccc1538..6baafd5d8f0bbe 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -1,7 +1,7 @@ // Block Creation Components export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; export { default as BlockControls } from './block-controls'; -export { default as BlockEdit } from './block-edit'; +export { default as BlockEdit, useBlockEditContext } from './block-edit'; export { default as BlockFormatControls } from './block-format-controls'; export { default as BlockIcon } from './block-icon'; export { default as BlockVerticalAlignmentToolbar } from './block-vertical-alignment-toolbar'; diff --git a/packages/block-library/src/heading/edit.js b/packages/block-library/src/heading/edit.js index d500309a0c9aad..241a327bb42c1a 100644 --- a/packages/block-library/src/heading/edit.js +++ b/packages/block-library/src/heading/edit.js @@ -12,49 +12,37 @@ import HeadingToolbar from './heading-toolbar'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { PanelBody } from '@wordpress/components'; -import { compose } from '@wordpress/compose'; +import { PanelBody, withFallbackStyles } from '@wordpress/components'; import { createBlock } from '@wordpress/blocks'; import { AlignmentToolbar, BlockControls, InspectorControls, RichText, - withColors, - PanelColorSettings, + __experimentalUseColors, } from '@wordpress/block-editor'; -import { memo } from '@wordpress/element'; -const HeadingColorUI = memo( - function( { - textColorValue, - setTextColor, - } ) { - return ( - <PanelColorSettings - title={ __( 'Color Settings' ) } - initialOpen={ false } - colorSettings={ [ - { - value: textColorValue, - onChange: setTextColor, - label: __( 'Text Color' ), - }, - ] } - /> - ); - } -); +/** + * Browser dependencies + */ +const { getComputedStyle } = window; function HeadingEdit( { + backgroundColor, attributes, setAttributes, mergeBlocks, onReplace, className, - textColor, - setTextColor, } ) { + const { TextColor, InspectorControlsColorPanel } = __experimentalUseColors( + [ { name: 'textColor', property: 'color' } ], + { + contrastCheckerProps: { backgroundColor, isLargeText: true }, + }, + [] + ); + const { align, content, level, placeholder } = attributes; const tagName = 'h' + level; @@ -71,43 +59,42 @@ function HeadingEdit( { <p>{ __( 'Level' ) }</p> <HeadingToolbar isCollapsed={ false } minLevel={ 1 } maxLevel={ 7 } selectedLevel={ level } onChange={ ( newLevel ) => setAttributes( { level: newLevel } ) } /> </PanelBody> - <HeadingColorUI - setTextColor={ setTextColor } - textColorValue={ textColor.color } - /> </InspectorControls> - <RichText - identifier="content" - tagName={ tagName } - value={ content } - onChange={ ( value ) => setAttributes( { content: value } ) } - onMerge={ mergeBlocks } - onSplit={ ( value ) => { - if ( ! value ) { - return createBlock( 'core/paragraph' ); - } + { InspectorControlsColorPanel } + <TextColor> + <RichText + identifier="content" + tagName={ tagName } + value={ content } + onChange={ ( value ) => setAttributes( { content: value } ) } + onMerge={ mergeBlocks } + onSplit={ ( value ) => { + if ( ! value ) { + return createBlock( 'core/paragraph' ); + } - return createBlock( 'core/heading', { - ...attributes, - content: value, - } ); - } } - onReplace={ onReplace } - onRemove={ () => onReplace( [] ) } - className={ classnames( className, { - [ `has-text-align-${ align }` ]: align, - 'has-text-color': textColor.color, - [ textColor.class ]: textColor.class, - } ) } - placeholder={ placeholder || __( 'Write heading…' ) } - style={ { - color: textColor.color, - } } - /> + return createBlock( 'core/heading', { + ...attributes, + content: value, + } ); + } } + onReplace={ onReplace } + onRemove={ () => onReplace( [] ) } + className={ classnames( className, { + [ `has-text-align-${ align }` ]: align, + } ) } + placeholder={ placeholder || __( 'Write heading…' ) } + /> + </TextColor> </> ); } -export default compose( [ - withColors( 'backgroundColor', { textColor: 'color' } ), -] )( HeadingEdit ); +export default withFallbackStyles( ( node ) => { + let backgroundColor = getComputedStyle( node ).backgroundColor; + while ( backgroundColor === 'rgba(0, 0, 0, 0)' && node.parentNode ) { + node = node.parentNode; + backgroundColor = getComputedStyle( node ).backgroundColor; + } + return { backgroundColor }; +} )( HeadingEdit ); From 9c91f5f92cc41210ca027a5fec72c9b54c354524 Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Sat, 26 Oct 2019 12:44:11 +0100 Subject: [PATCH 079/113] Fix: Font size picker component relies on WordPress styles (#18078) --- packages/components/src/font-size-picker/index.js | 2 +- packages/components/src/font-size-picker/style.scss | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/components/src/font-size-picker/index.js b/packages/components/src/font-size-picker/index.js index a52f6ccd841d2f..9fc6567865dbe4 100644 --- a/packages/components/src/font-size-picker/index.js +++ b/packages/components/src/font-size-picker/index.js @@ -60,7 +60,7 @@ function FontSizePicker( { }; return ( - <fieldset> + <fieldset className="components-font-size-picker"> <legend> { __( 'Font Size' ) } </legend> diff --git a/packages/components/src/font-size-picker/style.scss b/packages/components/src/font-size-picker/style.scss index 2444087dcf30e3..d24d044952cdf6 100644 --- a/packages/components/src/font-size-picker/style.scss +++ b/packages/components/src/font-size-picker/style.scss @@ -38,3 +38,9 @@ } } +.components-font-size-picker { + border: 0; + padding: 0; + margin: 0; +} + From a486306f6695a7b5ffcac1c94ea772c1ead4a68a Mon Sep 17 00:00:00 2001 From: tellthemachines <tellthemachines@users.noreply.github.com> Date: Sun, 27 Oct 2019 15:44:07 -0700 Subject: [PATCH 080/113] Nav menu item enhancements: display toolbar and remove dropdown (#17986) * Display toolbar and remove dropdown from menu item * Fixes block toolbar misalignment on IE. * Replace destination and deal with keypresses. * Update fixture. * Keydown management and attempt at close on blur. * Add definitive menu item icon. * Fix label/input styling. * Clean up styles after rebase. * Refactor stop propagation . * Remove duplicate dependency comments * Navigation Block: Rename 'destination' to 'url' in server-side code --- .../src/components/block-toolbar/style.scss | 2 + .../src/navigation-menu-item/block.json | 6 +- .../src/navigation-menu-item/edit.js | 143 ++++++++++++------ .../src/navigation-menu-item/editor.scss | 43 +----- .../src/navigation-menu-item/index.js | 4 +- .../navigation-menu-item/menu-item-actions.js | 111 -------------- .../block-library/src/navigation-menu/edit.js | 4 +- .../src/navigation-menu/editor.scss | 3 - .../src/navigation-menu/index.php | 4 +- .../blocks/core__navigation-menu-item.html | 2 +- .../blocks/core__navigation-menu-item.json | 4 +- .../core__navigation-menu-item.parsed.json | 2 +- ...core__navigation-menu-item.serialized.html | 2 +- .../full-content/server-registered.json | 2 +- 14 files changed, 117 insertions(+), 215 deletions(-) delete mode 100644 packages/block-library/src/navigation-menu-item/menu-item-actions.js diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index e83f34bc54eadd..a6247b03d3177b 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -49,6 +49,8 @@ .block-editor-block-toolbar__slot { // Required for IE11. display: inline-block; + // Fix for toolbar button misalignment on IE11 + line-height: 0; // IE11 doesn't read rules inside this query. They are applied only to modern browsers. @supports (position: sticky) { diff --git a/packages/block-library/src/navigation-menu-item/block.json b/packages/block-library/src/navigation-menu-item/block.json index 915c63931cb2be..20b33eca1f4a05 100644 --- a/packages/block-library/src/navigation-menu-item/block.json +++ b/packages/block-library/src/navigation-menu-item/block.json @@ -5,9 +5,6 @@ "label": { "type": "string" }, - "destination": { - "type": "string" - }, "nofollow": { "type": "boolean", "default": false @@ -21,6 +18,9 @@ "opensInNewTab": { "type": "boolean", "default": false + }, + "url": { + "type": "string" } } } diff --git a/packages/block-library/src/navigation-menu-item/edit.js b/packages/block-library/src/navigation-menu-item/edit.js index 90a80f41e2f696..4d2258d08eb163 100644 --- a/packages/block-library/src/navigation-menu-item/edit.js +++ b/packages/block-library/src/navigation-menu-item/edit.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import { invoke } from 'lodash'; import classnames from 'classnames'; /** @@ -9,89 +8,133 @@ import classnames from 'classnames'; */ import { withSelect } from '@wordpress/data'; import { - Dropdown, ExternalLink, - IconButton, PanelBody, TextareaControl, TextControl, + Toolbar, ToggleControl, + ToolbarButton, } from '@wordpress/components'; +import { + LEFT, + RIGHT, + UP, + DOWN, + BACKSPACE, + ENTER, +} from '@wordpress/keycodes'; import { __ } from '@wordpress/i18n'; import { + BlockControls, InnerBlocks, InspectorControls, - PlainText, + URLPopover, } from '@wordpress/block-editor'; import { Fragment, - useCallback, useRef, + useState, } from '@wordpress/element'; -/** - * Internal dependencies - */ -import MenuItemActions from './menu-item-actions'; -const POPOVER_PROPS = { noArrow: true }; - function NavigationMenuItemEdit( { attributes, - clientId, isSelected, isParentOfSelectedBlock, setAttributes, } ) { const plainTextRef = useRef( null ); - const onEditLableClicked = useCallback( - ( onClose ) => () => { - onClose(); - invoke( plainTextRef, [ 'current', 'textarea', 'focus' ] ); - }, - [ plainTextRef ] - ); + const [ isLinkOpen, setIsLinkOpen ] = useState( false ); + const [ isEditingLink, setIsEditingLink ] = useState( false ); + const [ urlInput, setUrlInput ] = useState( null ); + + const inputValue = urlInput !== null ? urlInput : url; + + const onKeyDown = ( event ) => { + if ( [ LEFT, DOWN, RIGHT, UP, BACKSPACE, ENTER ].indexOf( event.keyCode ) > -1 ) { + // Stop the key event from propagating up to ObserveTyping.startTypingInTextField. + event.stopPropagation(); + } + }; + + const closeURLPopover = () => { + setIsEditingLink( false ); + setUrlInput( null ); + setIsLinkOpen( false ); + }; + + const autocompleteRef = useRef( null ); + + const onFocusOutside = ( event ) => { + const autocompleteElement = autocompleteRef.current; + if ( autocompleteElement && autocompleteElement.contains( event.target ) ) { + return; + } + closeURLPopover(); + }; + + const stopPropagation = ( event ) => { + event.stopPropagation(); + }; + + const { label, url } = attributes; let content; if ( isSelected ) { content = ( - <div className="wp-block-navigation-menu-item__edit-container"> - <PlainText - ref={ plainTextRef } - className="wp-block-navigation-menu-item__field" - value={ attributes.label } - onChange={ ( label ) => setAttributes( { label } ) } - aria-label={ __( 'Navigation Label' ) } - maxRows={ 1 } - /> - <Dropdown - contentClassName="wp-block-navigation-menu-item__dropdown-content" - position="bottom left" - popoverProps={ POPOVER_PROPS } - renderToggle={ ( { isOpen, onToggle } ) => ( - <IconButton - icon={ isOpen ? 'arrow-up-alt2' : 'arrow-down-alt2' } - label={ __( 'More options' ) } - onClick={ onToggle } - aria-expanded={ isOpen } - /> - ) } - renderContent={ ( { onClose } ) => ( - <MenuItemActions - clientId={ clientId } - destination={ attributes.destination } - onEditLableClicked={ onEditLableClicked( onClose ) } - /> - ) } - /> - </div> + <TextControl + ref={ plainTextRef } + className="wp-block-navigation-menu-item__field" + value={ label } + onChange={ ( labelValue ) => setAttributes( { label: labelValue } ) } + label={ __( 'Navigation Label' ) } + hideLabelFromVision={ true } + /> ); } else { content = <div className="wp-block-navigation-menu-item__container"> - { attributes.label } + { label } </div>; } return ( <Fragment> + <BlockControls> + <Toolbar> + <ToolbarButton + name="link" + icon="admin-links" + title={ __( 'Link' ) } + onClick={ () => setIsLinkOpen( ! isLinkOpen ) } + /> + { isLinkOpen && + <> + <URLPopover + className="wp-block-navigation-menu-item__inline-link-input" + onClose={ closeURLPopover } + onFocusOutside={ onFocusOutside } + > + { ( ! url || isEditingLink ) && + <URLPopover.LinkEditor + value={ inputValue } + onChangeInputValue={ setUrlInput } + onKeyPress={ stopPropagation } + onKeyDown={ onKeyDown } + onSubmit={ ( event ) => event.preventDefault() } + autocompleteRef={ autocompleteRef } + /> + } + { ( url && ! isEditingLink ) && + <URLPopover.LinkViewer + onKeyPress={ stopPropagation } + url={ url } + /> + } + + </URLPopover> + </> + } + </Toolbar> + </BlockControls> <InspectorControls> <PanelBody title={ __( 'Menu Settings' ) } diff --git a/packages/block-library/src/navigation-menu-item/editor.scss b/packages/block-library/src/navigation-menu-item/editor.scss index 141054951dc98b..fcebe469a04e95 100644 --- a/packages/block-library/src/navigation-menu-item/editor.scss +++ b/packages/block-library/src/navigation-menu-item/editor.scss @@ -1,41 +1,14 @@ -$menu-label-field-width: 140px; - -.wp-block-navigation-menu-item__edit-container { - display: grid; - grid-auto-columns: min-content; - grid-auto-flow: column; - align-items: center; - white-space: nowrap; - border: 1px solid $light-gray-500; - // two pixes comes from two times one pixel border - width: $menu-label-field-width + $icon-button-size + 2px; - padding-left: 1px; -} - -.wp-block-navigation-menu-item__edit-container .wp-block-navigation-menu-item__field { - border-right: 1px solid $light-gray-500 !important; - width: $menu-label-field-width; - border: none; +.wp-block-navigation-menu-item__field .components-text-control__input.components-text-control__input, +.wp-block-navigation-menu-item__container { border-radius: 0; - padding-left: $grid-size-large; - - min-height: $icon-button-size - 1px; - line-height: $icon-button-size - 1px; - - &, - &:focus { - color: $dark-gray-500; - } -} - -.wp-block-navigation-menu-item { + padding: $block-padding; font-family: $editor-font; font-weight: bold; font-size: $text-editor-font-size; + background-color: var(--background-color-menu-link); + color: var(--color-menu-link); - .wp-block-navigation-menu-item__container, - &.is-editing .editor-plain-text { - background-color: var(--background-color-menu-link); + &:focus { color: var(--color-menu-link); } } @@ -61,10 +34,6 @@ $menu-label-field-width: 140px; } .wp-block-navigation-menu .block-editor-block-list__block[data-type="core/navigation-menu-item"] { - & > .block-editor-block-list__block-edit > div[role="toolbar"] { - display: none; - } - & > .block-editor-block-list__insertion-point { display: none; } diff --git a/packages/block-library/src/navigation-menu-item/index.js b/packages/block-library/src/navigation-menu-item/index.js index b61f3699e12b5c..9a51131a86b41a 100644 --- a/packages/block-library/src/navigation-menu-item/index.js +++ b/packages/block-library/src/navigation-menu-item/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; - +import { Path, SVG } from '@wordpress/components'; /** * Internal dependencies */ @@ -18,7 +18,7 @@ export const settings = { parent: [ 'core/navigation-menu' ], - icon: 'admin-links', + icon: <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24"><Path d="M12 7.27l4.28 10.43-3.47-1.53-.81-.36-.81.36-3.47 1.53L12 7.27M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z" /></SVG>, description: __( 'Add a page, link, or other item to your Navigation Menu.' ), diff --git a/packages/block-library/src/navigation-menu-item/menu-item-actions.js b/packages/block-library/src/navigation-menu-item/menu-item-actions.js deleted file mode 100644 index 6e39036bab408a..00000000000000 --- a/packages/block-library/src/navigation-menu-item/menu-item-actions.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * WordPress dependencies - */ -import { - MenuItem, - NavigableMenu, -} from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { withDispatch } from '@wordpress/data'; -import { compose } from '@wordpress/compose'; - -function MenuItemActions( { - destination, - moveLeft, - moveRight, - moveToEnd, - moveToStart, - onEditLableClicked, - remove, -} ) { - return ( - <NavigableMenu> - <MenuItem - icon="admin-links" - > - { destination } - </MenuItem> - <MenuItem - onClick={ onEditLableClicked } - icon="edit" - > - { __( 'Edit label text' ) } - </MenuItem> - <div className="wp-block-navigation-menu-item__separator" /> - <MenuItem - onClick={ moveToStart } - icon="arrow-up-alt2" - > - { __( 'Move to start' ) } - </MenuItem> - <MenuItem - onClick={ moveLeft } - icon="arrow-left-alt2" - > - { __( 'Move left' ) } - </MenuItem> - <MenuItem - onClick={ moveRight } - icon="arrow-right-alt2" - > - { __( 'Move right' ) } - </MenuItem> - <MenuItem - onClick={ moveToEnd } - icon="arrow-down-alt2" - > - { __( 'Move to end' ) } - </MenuItem> - <MenuItem - icon="arrow-left-alt2" - > - { __( 'Nest underneath…' ) } - </MenuItem> - <div className="navigation-menu-item__separator" /> - <MenuItem - onClick={ remove } - icon="trash" - > - { __( 'Remove from menu' ) } - </MenuItem> - </NavigableMenu> - ); -} - -export default compose( [ - withDispatch( ( dispatch, { clientId }, { select } ) => { - const { - getBlockOrder, - getBlockRootClientId, - } = select( 'core/block-editor' ); - const parentID = getBlockRootClientId( clientId ); - const { - moveBlocksDown, - moveBlocksUp, - moveBlockToPosition, - removeBlocks, - } = dispatch( 'core/block-editor' ); - return { - moveToStart() { - moveBlockToPosition( clientId, parentID, parentID, 0 ); - }, - moveRight() { - moveBlocksDown( clientId, parentID ); - }, - moveLeft() { - moveBlocksUp( clientId, parentID ); - }, - moveToEnd() { - moveBlockToPosition( - clientId, - parentID, - parentID, - getBlockOrder( parentID ).length - 1 - ); - }, - remove() { - removeBlocks( clientId ); - }, - }; - } ), -] )( MenuItemActions ); diff --git a/packages/block-library/src/navigation-menu/edit.js b/packages/block-library/src/navigation-menu/edit.js index 3fc18a43b2259a..074d6839333025 100644 --- a/packages/block-library/src/navigation-menu/edit.js +++ b/packages/block-library/src/navigation-menu/edit.js @@ -51,7 +51,9 @@ function NavigationMenu( { return null; } return pages.map( ( page ) => { - return [ 'core/navigation-menu-item', { label: page.title.rendered, destination: page.permalink_template } ]; + return [ 'core/navigation-menu-item', + { label: page.title.rendered, url: page.permalink_template }, + ]; } ); }, [ pages ] diff --git a/packages/block-library/src/navigation-menu/editor.scss b/packages/block-library/src/navigation-menu/editor.scss index a92f72eb5c1704..5133b3261fb24e 100644 --- a/packages/block-library/src/navigation-menu/editor.scss +++ b/packages/block-library/src/navigation-menu/editor.scss @@ -1,9 +1,6 @@ .wp-block-navigation-menu .block-editor-block-list__layout, .wp-block-navigation-menu { display: flex; - grid-auto-columns: min-content; - grid-auto-flow: column; - align-items: top; white-space: nowrap; } diff --git a/packages/block-library/src/navigation-menu/index.php b/packages/block-library/src/navigation-menu/index.php index c797a65fdfc10c..b49a41a06aa11c 100644 --- a/packages/block-library/src/navigation-menu/index.php +++ b/packages/block-library/src/navigation-menu/index.php @@ -102,8 +102,8 @@ function build_navigation_menu_html( $block, $colors ) { class="wp-block-navigation-menu-item__link ' . $colors['text_css_classes'] . '" ' . $colors['text_inline_styles']; - if ( isset( $menu_item['attrs']['destination'] ) ) { - $html .= ' href="' . $menu_item['attrs']['destination'] . '"'; + if ( isset( $menu_item['attrs']['url'] ) ) { + $html .= ' href="' . $menu_item['attrs']['url'] . '"'; } if ( isset( $menu_item['attrs']['title'] ) ) { $html .= ' title="' . $menu_item['attrs']['title'] . '"'; diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html index c88644e748ebf8..0ad94205cbce05 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.html @@ -1,2 +1,2 @@ -<!-- wp:navigation-menu-item {"label":"WordPress","destination":"https://wordpress.org/"} --> +<!-- wp:navigation-menu-item {"label":"WordPress","url":"https://wordpress.org/"} --> <!-- /wp:navigation-menu-item --> diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json index eb71bb8b929c4b..4e5ae943cb9b4a 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.json @@ -5,9 +5,9 @@ "isValid": true, "attributes": { "label": "WordPress", - "destination": "https://wordpress.org/", "nofollow": false, - "opensInNewTab": false + "opensInNewTab": false, + "url": "https://wordpress.org/" }, "innerBlocks": [], "originalContent": "" diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json index 8fa4f5340bb83d..2b03a8420038b8 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.parsed.json @@ -3,7 +3,7 @@ "blockName": "core/navigation-menu-item", "attrs": { "label": "WordPress", - "destination": "https://wordpress.org/" + "url": "https://wordpress.org/" }, "innerBlocks": [], "innerHTML": "\n", diff --git a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html index b5176129ef2460..ecf1f0ce7ad654 100644 --- a/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html +++ b/packages/e2e-tests/fixtures/blocks/core__navigation-menu-item.serialized.html @@ -1 +1 @@ -<!-- wp:navigation-menu-item {"label":"WordPress","destination":"https://wordpress.org/"} /--> +<!-- wp:navigation-menu-item {"label":"WordPress","url":"https://wordpress.org/"} /--> diff --git a/test/integration/full-content/server-registered.json b/test/integration/full-content/server-registered.json index e11fe0283b44a5..9d17c64f5d6ba5 100644 --- a/test/integration/full-content/server-registered.json +++ b/test/integration/full-content/server-registered.json @@ -1 +1 @@ -{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/navigation-menu":{"category":"layout","attributes":{"automaticallyAdd":{"type":"boolean","default":false}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file +{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"}}},"core\/legacy-widget":{"attributes":{"identifier":{"type":"string"},"instance":{"type":"object"},"isCallbackWidget":{"type":"boolean"}}},"core\/navigation-menu":{"category":"layout","attributes":{"automaticallyAdd":{"type":"boolean","default":false}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/shortcode":{"attributes":{"text":{"type":"string","source":"html"}}},"core\/social-link-amazon":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"amazon"}}},"core\/social-link-bandcamp":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"bandcamp"}}},"core\/social-link-behance":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"behance"}}},"core\/social-link-chain":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"chain"}}},"core\/social-link-codepen":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"codepen"}}},"core\/social-link-deviantart":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"deviantart"}}},"core\/social-link-dribbble":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"dribbble"}}},"core\/social-link-dropbox":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"dropbox"}}},"core\/social-link-etsy":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"etsy"}}},"core\/social-link-facebook":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"facebook"}}},"core\/social-link-feed":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"feed"}}},"core\/social-link-fivehundredpx":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"fivehundredpx"}}},"core\/social-link-flickr":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"flickr"}}},"core\/social-link-foursquare":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"foursquare"}}},"core\/social-link-goodreads":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"goodreads"}}},"core\/social-link-google":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"google"}}},"core\/social-link-github":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"github"}}},"core\/social-link-instagram":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"instagram"}}},"core\/social-link-lastfm":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"lastfm"}}},"core\/social-link-linkedin":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"linkedin"}}},"core\/social-link-mail":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"mail"}}},"core\/social-link-mastodon":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"mastodon"}}},"core\/social-link-meetup":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"meetup"}}},"core\/social-link-medium":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"medium"}}},"core\/social-link-pinterest":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"pinterest"}}},"core\/social-link-pocket":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"pocket"}}},"core\/social-link-reddit":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"reddit"}}},"core\/social-link-skype":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"skype"}}},"core\/social-link-snapchat":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"snapchat"}}},"core\/social-link-soundcloud":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"soundcloud"}}},"core\/social-link-spotify":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"spotify"}}},"core\/social-link-tumblr":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"tumblr"}}},"core\/social-link-twitch":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"twitch"}}},"core\/social-link-twitter":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"twitter"}}},"core\/social-link-vimeo":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"vimeo"}}},"core\/social-link-vk":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"vk"}}},"core\/social-link-wordpress":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"wordpress"}}},"core\/social-link-yelp":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"yelp"}}},"core\/social-link-youtube":{"attributes":{"url":{"type":"string"},"site":{"type":"string","default":"youtube"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}}} \ No newline at end of file From e93f7bb4ea07c0a8fe973964b6c5f0da9dd85e5a Mon Sep 17 00:00:00 2001 From: Robert Anderson <robert@noisysocks.com> Date: Mon, 28 Oct 2019 11:08:23 +1100 Subject: [PATCH 081/113] Fix overlapping controls in the Inline Image formatting toolbar (#18090) * Fix overlapping controls in the Inline Image formatting toolbar * Inline mage formatting: make Apply button same height as Width input * Polish. --- packages/format-library/src/image/style.scss | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/format-library/src/image/style.scss b/packages/format-library/src/image/style.scss index 93bfc96ae7a166..5209377f6448e4 100644 --- a/packages/format-library/src/image/style.scss +++ b/packages/format-library/src/image/style.scss @@ -2,8 +2,11 @@ display: flex; .components-icon-button { - height: $icon-button-size + $grid-size + $grid-size; align-self: flex-end; + height: $grid-size * 4 - ($border-width * 2); + margin-bottom: $grid-size; + margin-right: $grid-size; + padding: 0 6px; } } @@ -15,7 +18,13 @@ min-width: 150px; max-width: 500px; - &.components-base-control .components-base-control__field { - margin-bottom: 0; + &.components-base-control { + .components-base-control__field { + margin-bottom: 0; + } + + .components-base-control__label { + display: block; + } } } From f49df6f25dd1b67586f6a42b0b3175ac63b2909a Mon Sep 17 00:00:00 2001 From: Robert Anderson <robert@noisysocks.com> Date: Mon, 28 Oct 2019 11:23:39 +1100 Subject: [PATCH 082/113] Raw handling: Fix strikethrough formatting when copy/pasting from Google Docs in Safari (#17187) --- .../src/api/raw-handling/phrasing-content-reducer.js | 11 ++++++++++- test/integration/fixtures/google-docs-out.html | 2 +- .../fixtures/google-docs-with-comments-out.html | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js index 5c5ef223298fe6..4f3c3a2a810a99 100644 --- a/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js +++ b/packages/blocks/src/api/raw-handling/phrasing-content-reducer.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { includes } from 'lodash'; + /** * WordPress dependencies */ @@ -11,6 +16,7 @@ export default function( node, doc ) { fontWeight, fontStyle, textDecorationLine, + textDecoration, verticalAlign, } = node.style; @@ -22,7 +28,10 @@ export default function( node, doc ) { wrap( doc.createElement( 'em' ), node ); } - if ( textDecorationLine === 'line-through' ) { + // Some DOM implementations (Safari, JSDom) don't support + // style.textDecorationLine, so we check style.textDecoration as a + // fallback. + if ( textDecorationLine === 'line-through' || includes( textDecoration, 'line-through' ) ) { wrap( doc.createElement( 's' ), node ); } diff --git a/test/integration/fixtures/google-docs-out.html b/test/integration/fixtures/google-docs-out.html index 576b2cd7fda73f..54a1e07ac1349a 100644 --- a/test/integration/fixtures/google-docs-out.html +++ b/test/integration/fixtures/google-docs-out.html @@ -7,7 +7,7 @@ <h2>This is a <em>heading</em></h2> <!-- /wp:heading --> <!-- wp:paragraph --> -<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, strikethrough, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> +<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, <s>strikethrough</s>, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> <!-- /wp:paragraph --> <!-- wp:list --> diff --git a/test/integration/fixtures/google-docs-with-comments-out.html b/test/integration/fixtures/google-docs-with-comments-out.html index 576b2cd7fda73f..54a1e07ac1349a 100644 --- a/test/integration/fixtures/google-docs-with-comments-out.html +++ b/test/integration/fixtures/google-docs-with-comments-out.html @@ -7,7 +7,7 @@ <h2>This is a <em>heading</em></h2> <!-- /wp:heading --> <!-- wp:paragraph --> -<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, strikethrough, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> +<p>Formatting test: <strong>bold</strong>, <em>italic</em>, <a href="https://w.org/">link</a>, <s>strikethrough</s>, <sup>superscript</sup>, <sub>subscript</sub>, <strong><em>nested</em></strong>.<br></p> <!-- /wp:paragraph --> <!-- wp:list --> From 06834d909d393139fb57e1c1813721ec58baad9c Mon Sep 17 00:00:00 2001 From: Jeff Bowen <jblz@users.noreply.github.com> Date: Mon, 28 Oct 2019 02:51:05 -0400 Subject: [PATCH 083/113] Tutorial: Specify block naming restrictions (#18117) * Tutorial: Specify block naming restrictions * Remove an incorrect comma --- .../tutorials/block-tutorial/writing-your-first-block-type.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md b/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md index 77496681ce4847..81794c30be53fb 100644 --- a/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md +++ b/docs/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type.md @@ -107,4 +107,6 @@ Once a block is registered, you should immediately see that it becomes available A block name must be prefixed with a namespace specific to your plugin. This helps prevent conflicts when more than one plugin registers a block with the same name. In this example, the namespace is `gutenberg-examples`. +Block names _must_ include only lowercase alphanumeric characters or dashes and start with a letter. Example: `my-plugin/my-custom-block`. + The `edit` and `save` functions describe the structure of your block in the context of the editor and the saved content respectively. While the difference is not obvious in this simple example, in the following sections we'll explore how these are used to enable customization of the block in the editor preview. From b85675d0e117bdf3daf6ea31d55d1a03102da859 Mon Sep 17 00:00:00 2001 From: Jon Quach <hello@jonquach.com> Date: Mon, 28 Oct 2019 03:01:04 -0400 Subject: [PATCH 084/113] Components: ExternalLink, add story (#18084) This update adds a story for the ExternalLink component. Storybook knobs were added to better demonstrate the component's properties. --- .../src/external-link/stories/index.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 packages/components/src/external-link/stories/index.js diff --git a/packages/components/src/external-link/stories/index.js b/packages/components/src/external-link/stories/index.js new file mode 100644 index 00000000000000..9abfa1af04ba9c --- /dev/null +++ b/packages/components/src/external-link/stories/index.js @@ -0,0 +1,17 @@ +/** + * External dependencies + */ +import { text } from '@storybook/addon-knobs'; +/** + * Internal dependencies + */ +import ExternalLink from '../'; + +export default { title: 'ExternalLink', component: ExternalLink }; + +export const _default = () => { + const title = text( 'children', 'WordPress' ); + const href = text( 'href', 'https://wordpress.org' ); + + return <ExternalLink href={ href }>{ title }</ExternalLink>; +}; From 880d1de41b4f1d0d6eed57e914f85260c1f29dbf Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Mon, 28 Oct 2019 00:06:32 -0700 Subject: [PATCH 085/113] Storybook: Add ColorPicker component (#18013) * Add color picker component to Storybook * Switch screen-reader-text to new VisuallyHidden * Update ColorPicker tests snapshots * Add story for showing Alpha Channel * Move state out of exported component * Lowercase story name --- packages/components/src/color-picker/hue.js | 6 +-- .../components/src/color-picker/inputs.js | 9 +++-- .../components/src/color-picker/saturation.js | 6 +-- .../src/color-picker/stories/index.js | 39 +++++++++++++++++++ .../test/__snapshots__/index.js.snap | 24 ++++++------ 5 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 packages/components/src/color-picker/stories/index.js diff --git a/packages/components/src/color-picker/hue.js b/packages/components/src/color-picker/hue.js index 214df7e725bdc1..0c97020d89efdc 100644 --- a/packages/components/src/color-picker/hue.js +++ b/packages/components/src/color-picker/hue.js @@ -43,6 +43,7 @@ import { TAB } from '@wordpress/keycodes'; */ import { calculateHueChange } from './utils'; import KeyboardShortcuts from '../keyboard-shortcuts'; +import VisuallyHidden from '../visually-hidden'; export class Hue extends Component { constructor() { @@ -157,12 +158,11 @@ export class Hue extends Component { style={ pointerLocation } onKeyDown={ this.preventKeyEvents } /> - <p - className="components-color-picker__hue-description screen-reader-text" + <VisuallyHidden as="p" id={ `components-color-picker__hue-description-${ instanceId }` } > { __( 'Move the arrow left or right to change hue.' ) } - </p> + </VisuallyHidden> </div> { /* eslint-enable jsx-a11y/no-static-element-interactions */ } </div> diff --git a/packages/components/src/color-picker/inputs.js b/packages/components/src/color-picker/inputs.js index 39817d13edb74f..42e77a31e71820 100644 --- a/packages/components/src/color-picker/inputs.js +++ b/packages/components/src/color-picker/inputs.js @@ -17,6 +17,7 @@ import { pure } from '@wordpress/compose'; */ import IconButton from '../icon-button'; import TextControl from '../text-control'; +import VisuallyHidden from '../visually-hidden'; import { isValidHex } from './utils'; /* Wrapper for TextControl, only used to handle intermediate state while typing. */ @@ -175,9 +176,9 @@ export class Inputs extends Component { } else if ( this.state.view === 'rgb' ) { return ( <fieldset> - <legend className="screen-reader-text"> + <VisuallyHidden as="legend"> { __( 'Color value in RGB' ) } - </legend> + </VisuallyHidden> <div className="components-color-picker__inputs-fields"> <Input source={ this.state.view } @@ -228,9 +229,9 @@ export class Inputs extends Component { } else if ( this.state.view === 'hsl' ) { return ( <fieldset> - <legend className="screen-reader-text"> + <VisuallyHidden as="legend"> { __( 'Color value in HSL' ) } - </legend> + </VisuallyHidden> <div className="components-color-picker__inputs-fields"> <Input source={ this.state.view } diff --git a/packages/components/src/color-picker/saturation.js b/packages/components/src/color-picker/saturation.js index 3bdd10bfcdfe28..ae1f80333237d5 100644 --- a/packages/components/src/color-picker/saturation.js +++ b/packages/components/src/color-picker/saturation.js @@ -43,6 +43,7 @@ import { compose, pure, withInstanceId } from '@wordpress/compose'; */ import { calculateSaturationChange } from './utils'; import KeyboardShortcuts from '../keyboard-shortcuts'; +import VisuallyHidden from '../visually-hidden'; export class Saturation extends Component { constructor( props ) { @@ -171,13 +172,12 @@ export class Saturation extends Component { style={ pointerLocation } onKeyDown={ this.preventKeyEvents } /> - <div - className="screen-reader-text" + <VisuallyHidden id={ `color-picker-saturation-${ instanceId }` }> { __( 'Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation.' ) } - </div> + </VisuallyHidden> </div> </KeyboardShortcuts> ); diff --git a/packages/components/src/color-picker/stories/index.js b/packages/components/src/color-picker/stories/index.js new file mode 100644 index 00000000000000..19bca39729d4f5 --- /dev/null +++ b/packages/components/src/color-picker/stories/index.js @@ -0,0 +1,39 @@ + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import ColorPicker from '../'; + +export default { title: 'ColorPicker', component: ColorPicker }; + +const ColorPickerWithState = ( { ...props } ) => { + const [ color, setColor ] = useState( '#f00' ); + return ( + <ColorPicker + { ...props } + color={ color } + onChangeComplete={ ( value ) => setColor( value.hex ) } + /> + ); +}; + +export const _default = () => { + return ( + <ColorPickerWithState + disableAlpha + /> + ); +}; + +export const alphaEnabled = () => { + return ( + <ColorPickerWithState + disableAlpha={ false } + /> + ); +}; diff --git a/packages/components/src/color-picker/test/__snapshots__/index.js.snap b/packages/components/src/color-picker/test/__snapshots__/index.js.snap index 5d61a24e5ac9e6..a3713f860f3c01 100644 --- a/packages/components/src/color-picker/test/__snapshots__/index.js.snap +++ b/packages/components/src/color-picker/test/__snapshots__/index.js.snap @@ -39,7 +39,7 @@ exports[`ColorPicker should commit changes to all views on blur 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-2" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -99,7 +99,7 @@ exports[`ColorPicker should commit changes to all views on blur 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-2" > Move the arrow left or right to change hue. @@ -213,7 +213,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = DOWN 1`] = } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-4" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -273,7 +273,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = DOWN 1`] = tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-4" > Move the arrow left or right to change hue. @@ -387,7 +387,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = ENTER 1`] = } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-5" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -447,7 +447,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = ENTER 1`] = tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-5" > Move the arrow left or right to change hue. @@ -561,7 +561,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = UP 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-3" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -621,7 +621,7 @@ exports[`ColorPicker should commit changes to all views on keyDown = UP 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-3" > Move the arrow left or right to change hue. @@ -735,7 +735,7 @@ exports[`ColorPicker should only update input view for draft changes 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-1" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -795,7 +795,7 @@ exports[`ColorPicker should only update input view for draft changes 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-1" > Move the arrow left or right to change hue. @@ -909,7 +909,7 @@ exports[`ColorPicker should render color picker 1`] = ` } /> <div - className="screen-reader-text" + className="components-visually-hidden" id="color-picker-saturation-0" > Use your arrow keys to change the base color. Move up to lighten the color, down to darken, left to decrease saturation, and right to increase saturation. @@ -969,7 +969,7 @@ exports[`ColorPicker should render color picker 1`] = ` tabIndex="0" /> <p - className="components-color-picker__hue-description screen-reader-text" + className="components-visually-hidden" id="components-color-picker__hue-description-0" > Move the arrow left or right to change hue. From aec39f0c7926ec4d007cb25a829a8c9d65016d44 Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Mon, 28 Oct 2019 09:44:55 +0000 Subject: [PATCH 086/113] Add class mechanism for preset gradients. (#18008) --- .../src/components/block-edit/context.js | 6 ++ .../src/components/gradients/index.js | 77 +++++++++++++++++++ packages/block-editor/src/components/index.js | 1 + packages/block-editor/src/store/defaults.js | 18 +++++ packages/block-library/src/button/block.json | 3 + packages/block-library/src/button/edit.js | 25 +++--- packages/block-library/src/button/save.js | 8 +- packages/block-library/src/style.scss | 76 ++++++++++++++++++ 8 files changed, 201 insertions(+), 13 deletions(-) create mode 100644 packages/block-editor/src/components/gradients/index.js diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index 4157735cd2fa70..08f2ac9f1dd6b1 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -19,6 +19,12 @@ const Context = createContext( { const { Provider, Consumer } = Context; export { Provider as BlockEditContextProvider }; + +/** + * A hook that returns the block edit context. + * + * @return {Object} Block edit context + */ export function useBlockEditContext() { return useContext( Context ); } diff --git a/packages/block-editor/src/components/gradients/index.js b/packages/block-editor/src/components/gradients/index.js new file mode 100644 index 00000000000000..b08be314861e03 --- /dev/null +++ b/packages/block-editor/src/components/gradients/index.js @@ -0,0 +1,77 @@ +/** + * External dependencies + */ +import { find } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useCallback } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { useBlockEditContext } from '../block-edit'; + +export function __experimentalGetGradientClass( gradientSlug ) { + if ( ! gradientSlug ) { + return undefined; + } + return `has-${ gradientSlug }-gradient-background`; +} + +function getGradientValueBySlug( gradients, slug ) { + const gradient = find( gradients, [ 'slug', slug ] ); + return gradient && gradient.gradient; +} + +function getGradientSlugByValue( gradients, value ) { + const gradient = find( gradients, [ 'gradient', value ] ); + return gradient && gradient.slug; +} + +export function __experimentalUseGradient( { + gradientAttribute = 'gradient', + customGradientAttribute = 'customGradient', +} = {} ) { + const { clientId } = useBlockEditContext(); + + const { gradients, gradient, customGradient } = useSelect( ( select ) => { + const { getBlockAttributes, getSettings } = select( 'core/block-editor' ); + const attributes = getBlockAttributes( clientId ); + return { + gradient: attributes[ gradientAttribute ], + customGradient: attributes[ customGradientAttribute ], + gradients: getSettings().gradients, + }; + }, [ clientId ] ); + + const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); + const setGradient = useCallback( + ( newGradientValue ) => { + const slug = getGradientSlugByValue( gradients, newGradientValue ); + if ( slug ) { + updateBlockAttributes( clientId, { + [ gradientAttribute ]: slug, + [ customGradientAttribute ]: undefined, + } ); + return; + } + updateBlockAttributes( clientId, { + [ gradientAttribute ]: undefined, + [ customGradientAttribute ]: newGradientValue, + } ); + }, + [ gradients, clientId, updateBlockAttributes ] + ); + + const gradientClass = __experimentalGetGradientClass( gradient ); + let gradientValue; + if ( gradient ) { + gradientValue = getGradientValueBySlug( gradients, gradient ); + } else { + gradientValue = customGradient; + } + return { gradientClass, gradientValue, setGradient }; +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 5818e37395c8ea..7ec60098a8c737 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -3,6 +3,7 @@ */ export * from './colors'; +export * from './gradients'; export * from './font-sizes'; export { default as AlignmentToolbar } from './alignment-toolbar'; export { default as Autocomplete } from './autocomplete'; diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index a983abacc36b8a..54233e3bda2e91 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -158,75 +158,93 @@ export const SETTINGS_DEFAULTS = { { name: __( 'Vivid cyan blue to vivid purple' ), gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', + slug: 'vivid-cyan-blue-to-vivid-purple', }, { name: __( 'Vivid green cyan to vivid cyan blue' ), gradient: 'linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)', + slug: 'vivid-green-cyan-to-vivid-cyan-blue', }, { name: __( 'Light green cyan to vivid green cyan' ), gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', + slug: 'light-green-cyan-to-vivid-green-cyan', }, { name: __( 'Luminous vivid amber to luminous vivid orange' ), gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)', + slug: 'luminous-vivid-amber-to-luminous-vivid-orange', }, { name: __( 'Luminous vivid orange to vivid red' ), gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)', + slug: 'luminous-vivid-orange-to-vivid-red', }, { name: __( 'Very light gray to cyan bluish gray' ), gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)', + slug: 'very-light-gray-to-cyan-bluish-gray', }, // The following use new, customized colors. { name: __( 'Cool to warm spectrum' ), gradient: 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)', + slug: 'cool-to-warm-spectrum', }, { name: __( 'Blush light purple' ), gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)', + slug: 'blush-light-purple', }, { name: __( 'Blush bordeaux' ), gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)', + slug: 'blush-bordeaux', }, { name: __( 'Purple crush' ), gradient: 'linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%)', + slug: 'purple-crush', }, { name: __( 'Luminous dusk' ), gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)', + slug: 'luminous-dusk', }, { name: __( 'Hazy dawn' ), gradient: 'linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%)', + slug: 'hazy-dawn', }, { name: __( 'Pale ocean' ), gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)', + slug: 'pale-ocean', }, { name: __( 'Electric grass' ), gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)', + slug: 'electric-grass', }, { name: __( 'Subdued olive' ), gradient: 'linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%)', + slug: 'subdued-olive', }, { name: __( 'Atomic cream' ), gradient: 'linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%)', + slug: 'atomic-cream', }, { name: __( 'Nightshade' ), gradient: 'linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%)', + slug: 'nightshade', }, { name: __( 'Midnight' ), gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)', + slug: 'midnight', }, ], }; diff --git a/packages/block-library/src/button/block.json b/packages/block-library/src/button/block.json index ff43c67db5e834..bc35b9ff5ee32e 100644 --- a/packages/block-library/src/button/block.json +++ b/packages/block-library/src/button/block.json @@ -49,6 +49,9 @@ "borderRadius": { "type": "number" }, + "gradient": { + "type": "string" + }, "customGradient": { "type": "string" } diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index b624aa7e5f6218..11d1deef862cfd 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -24,6 +24,7 @@ import { } from '@wordpress/components'; import { __experimentalGradientPickerPanel, + __experimentalUseGradient, ContrastChecker, InspectorControls, PanelColorSettings, @@ -94,7 +95,6 @@ function ButtonEdit( { text, title, url, - customGradient, } = attributes; const onSetLinkRel = useCallback( ( value ) => { @@ -121,6 +121,11 @@ function ButtonEdit( { }, [ rel, setAttributes ] ); + const { + gradientClass, + gradientValue, + setGradient, + } = __experimentalUseGradient(); const linkId = `wp-block-button__inline-link-${ instanceId }`; return ( @@ -132,16 +137,17 @@ function ButtonEdit( { withoutInteractiveFormatting className={ classnames( 'wp-block-button__link', { - 'has-background': backgroundColor.color || customGradient, - [ backgroundColor.class ]: ! customGradient && backgroundColor.class, + 'has-background': backgroundColor.color || gradientValue, + [ backgroundColor.class ]: ! gradientValue && backgroundColor.class, 'has-text-color': textColor.color, [ textColor.class ]: textColor.class, + [ gradientClass ]: gradientClass, 'no-border-radius': borderRadius === 0, } ) } style={ { - ...( customGradient ? - { background: customGradient } : + ...( ! backgroundColor.color && gradientValue ? + { background: gradientValue } : { backgroundColor: backgroundColor.color } ), color: textColor.color, @@ -200,14 +206,11 @@ function ButtonEdit( { <__experimentalGradientPickerPanel onChange={ ( newGradient ) => { - setAttributes( { - customGradient: newGradient, - backgroundColor: undefined, - customBackgroundColor: undefined, - } ); + setGradient( newGradient ); + setBackgroundColor(); } } - value={ customGradient } + value={ gradientValue } /> <BorderPanel borderRadius={ borderRadius } diff --git a/packages/block-library/src/button/save.js b/packages/block-library/src/button/save.js index bcf18ffc293242..59eaa9f201217e 100644 --- a/packages/block-library/src/button/save.js +++ b/packages/block-library/src/button/save.js @@ -9,6 +9,7 @@ import classnames from 'classnames'; import { RichText, getColorClassName, + __experimentalGetGradientClass, } from '@wordpress/block-editor'; export default function save( { attributes } ) { @@ -19,6 +20,7 @@ export default function save( { attributes } ) { customTextColor, customGradient, linkTarget, + gradient, rel, text, textColor, @@ -28,18 +30,20 @@ export default function save( { attributes } ) { const textClass = getColorClassName( 'color', textColor ); const backgroundClass = ! customGradient && getColorClassName( 'background-color', backgroundColor ); + const gradientClass = __experimentalGetGradientClass( gradient ); const buttonClasses = classnames( 'wp-block-button__link', { 'has-text-color': textColor || customTextColor, [ textClass ]: textClass, - 'has-background': backgroundColor || customBackgroundColor || customGradient, + 'has-background': backgroundColor || customBackgroundColor || customGradient || gradient, [ backgroundClass ]: backgroundClass, 'no-border-radius': borderRadius === 0, + [ gradientClass ]: gradientClass, } ); const buttonStyle = { - backgroundColor: backgroundClass || customGradient ? undefined : customBackgroundColor, background: customGradient ? customGradient : undefined, + backgroundColor: backgroundClass || customGradient || gradient ? undefined : customBackgroundColor, color: textClass ? undefined : customTextColor, borderRadius: borderRadius ? borderRadius + 'px' : undefined, }; diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index 433ef8cb3aa2f3..d32050bfd1c4b9 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -129,6 +129,82 @@ .has-very-dark-gray-color { color: #313131; } + + // Gradients + // Our classes uses the same values we set for gradient value attributes, and we can not use spacing because of WP multi site kses rule. + /* stylelint-disable function-comma-space-after */ + .has-vivid-cyan-blue-to-vivid-purple-gradient-background { + background: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%); + } + + .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background { + background: linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%); + } + + .has-light-green-cyan-to-vivid-green-cyan-gradient-background { + background: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%); + } + + .has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background { + background: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%); + } + + .has-luminous-vivid-orange-to-vivid-red-gradient-background { + background: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%); + } + + .has-very-light-gray-to-cyan-bluish-gray-gradient-background { + background: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%); + } + + .has-cool-to-warm-spectrum-gradient-background { + background: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%); + } + + .has-blush-light-purple-gradient-background { + background: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%); + } + + .has-blush-bordeaux-gradient-background { + background: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%); + } + + .has-purple-crush-gradient-background { + background: linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%); + } + + .has-luminous-dusk-gradient-background { + background: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%); + } + + .has-hazy-dawn-gradient-background { + background: linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%); + } + + .has-pale-ocean-gradient-background { + background: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%); + } + + .has-electric-grass-gradient-background { + background: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%); + } + + .has-subdued-olive-gradient-background { + background: linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%); + } + + .has-atomic-cream-gradient-background { + background: linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%); + } + + .has-nightshade-gradient-background { + background: linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%); + } + + .has-midnight-gradient-background { + background: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%); + } + /* stylelint-enable function-comma-space-after */ } From 7f0a81c53ce451e25ed5e291292e0234a0efafcf Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Mon, 28 Oct 2019 11:09:48 +0100 Subject: [PATCH 087/113] Allow media upload post processing for all 5xx responses (#18106) --- packages/api-fetch/src/middlewares/media-upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api-fetch/src/middlewares/media-upload.js b/packages/api-fetch/src/middlewares/media-upload.js index b7a14d6b5b050a..6772aaf3ded733 100644 --- a/packages/api-fetch/src/middlewares/media-upload.js +++ b/packages/api-fetch/src/middlewares/media-upload.js @@ -54,7 +54,7 @@ function mediaUploadMiddleware( options, next ) { return next( { ...options, parse: false } ) .catch( ( response ) => { const attachmentId = response.headers.get( 'x-wp-upload-attachment-id' ); - if ( ( response.status === 500 || response.status === 502 ) && attachmentId ) { + if ( response.status >= 500 && response.status < 600 && attachmentId ) { return postProcess( attachmentId ).catch( () => { if ( options.parse !== false ) { return Promise.reject( { From 286ee9a3448e2aa8a5a1a7eaf6bd35cfdadd4507 Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Mon, 28 Oct 2019 11:34:12 +0100 Subject: [PATCH 088/113] Allow travis builds in all wp/* branches --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 27b1e7383e85ff..32e41294c57f9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ branches: only: - master - rnmobile/master - - wp/trunk + - /wp\/.*/ env: global: From 0f1ea49c10f32fadf20da8da50853ac40617fada Mon Sep 17 00:00:00 2001 From: Dave Smith <getdavemail@gmail.com> Date: Mon, 28 Oct 2019 11:50:46 +0000 Subject: [PATCH 089/113] Add `DimensionControl` component (#16791) * Adds initial component Note this is copied wholescale from original PR https://github.com/WordPress/gutenberg/pull/16730 * Remove redunant files. Refactors tests. * Updates docs * Checks callbacks are functions prior to calling * Adds temp testing example usage of component to Group Block * Updates to allow sizes as an (optionaly) prop dependency * Update default value label * Removes unnecessary InstanceId HOC usage Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r323906696 * Remove unused abbreviation in size table * Revert "Adds temp testing example usage of component to Group Block" This reverts commit 6f9f3bfd2a7c1a08ecfab143384d414701f0c1e8. * Remove arbitrary size value from sizes list This is not required as we cannot know how the dimensions component will be used. Therefore sticking with relative values via the slugs is safer. These can be mapped on a case by case basis as required. * Remove icon label for a11y reasons Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r324103481 * Update component docs for consistency, spelling and grammar * Tweak docblock formats * Update test snapshots to match new default value * Update API from onSpacingChange to more agnostic onChange Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r331622801 * Update tests to cover onChange handler renamed * Update currentSize prop to value for consistency with other components * Removes onReset in favour of onChange with undefined for consistency Adddresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r331624272 * Move component to @wordpress/components package * Remove invalid font sizes style import Accidentally included from rebase. * Deps update due to rebase * Remove unneeded doc blocks * Remove usage suggestion which was not helpful * Update readme docs to match current API Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r332692714 * Export as experimental component Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r332694561 * Revert "Deps update due to rebase" This reverts commit 95d00f39010edfaac620980e0d0e7c1001a68c98. Addresses https://github.com/WordPress/gutenberg/pull/16791#discussion_r332691520 --- docs/manifest-devhub.json | 6 + .../src/dimension-control/README.md | 120 +++++++++++++ .../components/src/dimension-control/index.js | 76 ++++++++ .../components/src/dimension-control/sizes.js | 45 +++++ .../src/dimension-control/style.scss | 22 +++ .../test/__snapshots__/index.test.js.snap | 163 ++++++++++++++++++ .../src/dimension-control/test/index.test.js | 128 ++++++++++++++ packages/components/src/index.js | 1 + packages/components/src/style.scss | 1 + 9 files changed, 562 insertions(+) create mode 100644 packages/components/src/dimension-control/README.md create mode 100644 packages/components/src/dimension-control/index.js create mode 100644 packages/components/src/dimension-control/sizes.js create mode 100644 packages/components/src/dimension-control/style.scss create mode 100644 packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap create mode 100644 packages/components/src/dimension-control/test/index.test.js diff --git a/docs/manifest-devhub.json b/docs/manifest-devhub.json index b508f649fb7c9e..a8d1a369642ee2 100644 --- a/docs/manifest-devhub.json +++ b/docs/manifest-devhub.json @@ -641,6 +641,12 @@ "markdown_source": "../packages/components/src/date-time/README.md", "parent": "components" }, + { + "title": "DimensionControl", + "slug": "dimension-control", + "markdown_source": "../packages/components/src/dimension-control/README.md", + "parent": "components" + }, { "title": "Disabled", "slug": "disabled", diff --git a/packages/components/src/dimension-control/README.md b/packages/components/src/dimension-control/README.md new file mode 100644 index 00000000000000..435fdf4e73b046 --- /dev/null +++ b/packages/components/src/dimension-control/README.md @@ -0,0 +1,120 @@ +DimensionControl +============================= + +`DimensionControl` is a component designed to provide a UI to control spacing and/or dimensions. + +## Usage + +In a block's `edit` implementation, render a `<DimensionControl />` component. + + +```jsx +import { registerBlockType } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; +import { + DimensionControl, +} from '@wordpress/block-editor'; + +registerBlockType( 'my-plugin/my-block', { + // ... + + attributes: { + // other attributes here + // ... + + paddingSize: { + type: 'string', + }, + }, + + edit( { attributes, setAttributes, clientId } ) { + + const { paddingSize } = attributes; + + + const updateSpacing = ( dimension, size, device = '' ) => { + setAttributes( { + [ `${ dimension }${ device }` ]: size, + } ); + }; + + return ( + <DimensionControl + label={ __( 'Padding' ) } + icon={ 'desktop' } + onChange={ partialRight( updateSpacing, 'paddingSize' ) } + value={ paddingSize } + /> + ); + } +} ); +``` + +_Note:_ it is recommended to partially apply the value of the Block attribute to be updated (eg: `paddingSize`, `marginSize`...etc) to your callback functions. This avoids the need to unnecessarily couple the component to the Block attribute schema. + +_Note:_ by default, if you do not provide an initial `value` prop for the current dimension value, then no value will be selected (ie: there is no default dimension set). + +## Props + +### `label` +* **Type:** `String` +* **Default:** `undefined` +* **Required:** Yes + +The human readable label for the control. + +### `value` +* **Type:** `String` +* **Default:** `''` +* **Required:** No + +The current value of the dimension UI control. If provided the UI with automatically select the value. + +### `sizes` +* **Type:** `Array` +* **Default:** See `packages/block-editor/src/components/dimension-control/sizes.js` +* **Required:** No + +An optional array of size objects in the following shape: + +``` +[ + { + name: __( 'Small' ), + slug: 'small', + }, + { + name: __( 'Medium' ), + slug: 'small', + }, + // ...etc +] +``` + +By default a set of relative sizes (`small`, `medium`...etc) are provided. See `packages/block-editor/src/components/dimension-control/sizes.js`. + +### `icon` +* **Type:** `String` +* **Default:** `undefined` +* **Required:** No + +An optional dashicon to display before to the control label. + +### `onChange` +* **Type:** `Function` +* **Default:** `undefined` +* **Required:** No +* **Arguments:**: + - `size` - a string representing the selected size (eg: `medium`) + +A callback which is triggered when a spacing size value changes (is selected/clicked). + + +### `className` +* **Type:** `String` +* **Default:** `''` +* **Required:** No + +A string of classes to be added to the control component. + + diff --git a/packages/components/src/dimension-control/index.js b/packages/components/src/dimension-control/index.js new file mode 100644 index 00000000000000..c69b80f5c49e02 --- /dev/null +++ b/packages/components/src/dimension-control/index.js @@ -0,0 +1,76 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { isFunction } from 'lodash'; + +/** + * WordPress dependencies + */ +/** + * Internal dependencies + */ +import { + Icon, + SelectControl, +} from '../'; +import { __ } from '@wordpress/i18n'; + +import { + Fragment, +} from '@wordpress/element'; + +/** + * Internal dependencies + */ +import sizesTable, { findSizeBySlug } from './sizes'; + +export function DimensionControl( props ) { + const { label, value, sizes = sizesTable, icon, onChange, className = '' } = props; + + const onChangeSpacingSize = ( val ) => { + const theSize = findSizeBySlug( sizes, val ); + + if ( ! theSize || value === theSize.slug ) { + onChange( undefined ); + } else if ( isFunction( onChange ) ) { + onChange( theSize.slug ); + } + }; + + const formatSizesAsOptions = ( theSizes ) => { + const options = theSizes.map( ( { name, slug } ) => ( { + label: name, + value: slug, + } ) ); + + return [ { + label: __( 'Default' ), + value: '', + } ].concat( options ); + }; + + const selectLabel = ( + <Fragment> + { icon && ( + <Icon + icon={ icon } + /> + ) } + { label } + </Fragment> + ); + + return ( + <SelectControl + className={ classnames( className, 'block-editor-dimension-control' ) } + label={ selectLabel } + hideLabelFromVision={ false } + value={ value } + onChange={ onChangeSpacingSize } + options={ formatSizesAsOptions( sizes ) } + /> + ); +} + +export default DimensionControl; diff --git a/packages/components/src/dimension-control/sizes.js b/packages/components/src/dimension-control/sizes.js new file mode 100644 index 00000000000000..41fa0717028725 --- /dev/null +++ b/packages/components/src/dimension-control/sizes.js @@ -0,0 +1,45 @@ +/** + * Sizes + * + * defines the sizes used in dimension controls + * all hardcoded `size` values are based on the value of + * the Sass variable `$block-padding` from + * `packages/block-editor/src/components/dimension-control/sizes.js`. + */ + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Finds the correct size object from the provided sizes + * table by size slug (eg: `medium`) + * + * @param {Array} sizes containing objects for each size definition + * @param {string} slug a string representation of the size (eg: `medium`) + * @return {Object} the matching size definition + */ +export const findSizeBySlug = ( sizes, slug ) => sizes.find( ( size ) => slug === size.slug ); + +export default [ + { + name: __( 'None' ), + slug: 'none', + }, + { + name: __( 'Small' ), + slug: 'small', + }, + { + name: __( 'Medium' ), + slug: 'medium', + }, + { + name: __( 'Large' ), + slug: 'large', + }, { + name: __( 'Extra Large' ), + slug: 'xlarge', + }, +]; diff --git a/packages/components/src/dimension-control/style.scss b/packages/components/src/dimension-control/style.scss new file mode 100644 index 00000000000000..7f1481747dfe1a --- /dev/null +++ b/packages/components/src/dimension-control/style.scss @@ -0,0 +1,22 @@ +.block-editor-dimension-control { + + .components-base-control__field { + display: flex; + align-items: center; + } + + .components-base-control__label { + display: flex; + align-items: center; + margin-right: 1em; + margin-bottom: 0; + + .dashicon { + margin-right: 0.5em; + } + } + + &.is-manual .components-base-control__label { + width: 10em; + } +} diff --git a/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap b/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap new file mode 100644 index 00000000000000..c06662ee862c99 --- /dev/null +++ b/packages/components/src/dimension-control/test/__snapshots__/index.test.js.snap @@ -0,0 +1,163 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DimensionControl rendering renders with custom sizes 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + Custom Dimension + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "Mini", + "value": "mini", + }, + Object { + "label": "Middle", + "value": "middle", + }, + Object { + "label": "Giant", + "value": "giant", + }, + ] + } +/> +`; + +exports[`DimensionControl rendering renders with defaults 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + Padding + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "None", + "value": "none", + }, + Object { + "label": "Small", + "value": "small", + }, + Object { + "label": "Medium", + "value": "medium", + }, + Object { + "label": "Large", + "value": "large", + }, + Object { + "label": "Extra Large", + "value": "xlarge", + }, + ] + } +/> +`; + +exports[`DimensionControl rendering renders with icon and custom icon label 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + <Icon + icon="tablet" + /> + Margin + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "None", + "value": "none", + }, + Object { + "label": "Small", + "value": "small", + }, + Object { + "label": "Medium", + "value": "medium", + }, + Object { + "label": "Large", + "value": "large", + }, + Object { + "label": "Extra Large", + "value": "xlarge", + }, + ] + } +/> +`; + +exports[`DimensionControl rendering renders with icon and default icon label 1`] = ` +<WithInstanceId(SelectControl) + className="block-editor-dimension-control" + hideLabelFromVision={false} + label={ + <React.Fragment> + <Icon + icon="tablet" + /> + Margin + </React.Fragment> + } + onChange={[Function]} + options={ + Array [ + Object { + "label": "Default", + "value": "", + }, + Object { + "label": "None", + "value": "none", + }, + Object { + "label": "Small", + "value": "small", + }, + Object { + "label": "Medium", + "value": "medium", + }, + Object { + "label": "Large", + "value": "large", + }, + Object { + "label": "Extra Large", + "value": "xlarge", + }, + ] + } +/> +`; diff --git a/packages/components/src/dimension-control/test/index.test.js b/packages/components/src/dimension-control/test/index.test.js new file mode 100644 index 00000000000000..0b053a493ee123 --- /dev/null +++ b/packages/components/src/dimension-control/test/index.test.js @@ -0,0 +1,128 @@ +/** + * External dependencies + */ +import { shallow, mount } from 'enzyme'; +import { uniqueId } from 'lodash'; + +/** + * Internal dependencies + */ +import { DimensionControl } from '../'; + +describe( 'DimensionControl', () => { + const onChangeHandler = jest.fn(); + + afterEach( () => { + onChangeHandler.mockClear(); + } ); + + describe( 'rendering', () => { + it( 'renders with defaults', () => { + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Padding' } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + + it( 'renders with icon and default icon label', () => { + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Margin' } + icon={ 'tablet' } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + + it( 'renders with icon and custom icon label', () => { + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Margin' } + icon={ 'tablet' } + iconLabel={ 'Tablet Devices' } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + + it( 'renders with custom sizes', () => { + const customSizes = [ + { + name: 'Mini', + size: 1, + slug: 'mini', + }, + { + name: 'Middle', + size: 5, + slug: 'middle', + }, + { + name: 'Giant', + size: 10, + slug: 'giant', + }, + ]; + + const wrapper = shallow( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Custom Dimension' } + sizes={ customSizes } + /> + ); + expect( wrapper ).toMatchSnapshot(); + } ); + } ); + + describe( 'callbacks', () => { + it( 'should call onChange handler with correct args on size change', () => { + const wrapper = mount( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Padding' } + onChange={ onChangeHandler } + /> + ); + + wrapper.find( 'select' ).at( 0 ).simulate( 'change', { + target: { + value: 'small', + }, + } ); + + wrapper.find( 'select' ).at( 0 ).simulate( 'change', { + target: { + value: 'medium', + }, + } ); + + expect( onChangeHandler ).toHaveBeenCalledTimes( 2 ); + expect( onChangeHandler.mock.calls[ 0 ][ 0 ] ).toEqual( 'small' ); + expect( onChangeHandler.mock.calls[ 1 ][ 0 ] ).toEqual( 'medium' ); + } ); + + it( 'should call onChange handler with undefined value when no size is provided on change', () => { + const wrapper = mount( + <DimensionControl + instanceId={ uniqueId() } + label={ 'Padding' } + onChange={ onChangeHandler } + /> + ); + + wrapper.find( 'select' ).at( 0 ).simulate( 'change', { + target: { + value: '', // this happens when you select the "default" <option /> + }, + } ); + + expect( onChangeHandler ).toHaveBeenNthCalledWith( 1, undefined ); + } ); + } ); +} ); diff --git a/packages/components/src/index.js b/packages/components/src/index.js index 463241f06bf66b..ac9694a49ba57b 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -12,6 +12,7 @@ export { default as ColorPalette } from './color-palette'; export { default as ColorPicker } from './color-picker'; export { default as Dashicon } from './dashicon'; export { DateTimePicker, DatePicker, TimePicker } from './date-time'; +export { default as __experimentalDimensionControl } from './dimension-control'; export { default as Disabled } from './disabled'; export { default as Draggable } from './draggable'; export { default as DropZone } from './drop-zone'; diff --git a/packages/components/src/style.scss b/packages/components/src/style.scss index 08fc9961be5e63..7a62ba0534539d 100644 --- a/packages/components/src/style.scss +++ b/packages/components/src/style.scss @@ -9,6 +9,7 @@ @import "./color-picker/style.scss"; @import "./dashicon/style.scss"; @import "./date-time/style.scss"; +@import "./dimension-control/style.scss"; @import "./disabled/style.scss"; @import "./draggable/style.scss"; @import "./drop-zone/style.scss"; From 94b971b4a9d2790c390be14f7dafb222ff660881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <wp@iseulde.com> Date: Mon, 28 Oct 2019 13:49:48 +0100 Subject: [PATCH 090/113] Paste: allow list attributes (#17144) --- packages/block-library/src/list/block.json | 3 ++ packages/block-library/src/list/edit.js | 3 +- packages/block-library/src/list/save.js | 3 +- packages/block-library/src/list/transforms.js | 35 +++++++++++++++---- .../blocks-raw-handling.test.js.snap | 10 ++++++ test/integration/blocks-raw-handling.test.js | 5 +++ .../fixtures/list-with-attributes.html | 7 ++++ test/integration/fixtures/ms-word-out.html | 4 +-- 8 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 test/integration/fixtures/list-with-attributes.html diff --git a/packages/block-library/src/list/block.json b/packages/block-library/src/list/block.json index 3dcae3a6ae5c22..71bca30f1a8ac3 100644 --- a/packages/block-library/src/list/block.json +++ b/packages/block-library/src/list/block.json @@ -14,6 +14,9 @@ "__unstableMultilineWrapperTags": [ "ol", "ul" ], "default": "" }, + "type": { + "type": "string" + }, "start": { "type": "number" }, diff --git a/packages/block-library/src/list/edit.js b/packages/block-library/src/list/edit.js index 2949d6fdc11047..4373bbec0ce437 100644 --- a/packages/block-library/src/list/edit.js +++ b/packages/block-library/src/list/edit.js @@ -32,7 +32,7 @@ export default function ListEdit( { onReplace, className, } ) { - const { ordered, values, reversed, start } = attributes; + const { ordered, values, type, reversed, start } = attributes; const tagName = ordered ? 'ol' : 'ul'; const controls = ( { value, onChange } ) => ( @@ -130,6 +130,7 @@ export default function ListEdit( { onRemove={ () => onReplace( [] ) } start={ start } reversed={ reversed } + type={ type } > { controls } </RichText> diff --git a/packages/block-library/src/list/save.js b/packages/block-library/src/list/save.js index 18458c2c1ce5a5..8cd1d3870148ba 100644 --- a/packages/block-library/src/list/save.js +++ b/packages/block-library/src/list/save.js @@ -4,13 +4,14 @@ import { RichText } from '@wordpress/block-editor'; export default function save( { attributes } ) { - const { ordered, values, reversed, start } = attributes; + const { ordered, values, type, reversed, start } = attributes; const tagName = ordered ? 'ol' : 'ul'; return ( <RichText.Content tagName={ tagName } value={ values } + type={ type } reversed={ reversed } start={ start } multiline="li" diff --git a/packages/block-library/src/list/transforms.js b/packages/block-library/src/list/transforms.js index baf09b1b945c6d..da533e16f6f30c 100644 --- a/packages/block-library/src/list/transforms.js +++ b/packages/block-library/src/list/transforms.js @@ -18,7 +18,7 @@ import { const listContentSchema = { ...getPhrasingContentSchema(), ul: {}, - ol: { attributes: [ 'type' ] }, + ol: { attributes: [ 'type', 'start', 'reversed' ] }, }; // Recursion is needed. @@ -77,12 +77,35 @@ const transforms = { ul: listContentSchema.ul, }, transform( node ) { - return createBlock( 'core/list', { - ...getBlockAttributes( - 'core/list', - node.outerHTML - ), + const attributes = { ordered: node.nodeName === 'OL', + }; + + if ( attributes.ordered ) { + const type = node.getAttribute( 'type' ); + + if ( type ) { + attributes.type = type; + } + + if ( node.getAttribute( 'reversed' ) !== null ) { + attributes.reversed = true; + } + + const start = parseInt( node.getAttribute( 'start' ), 10 ); + + if ( + ! isNaN( start ) && + // start=1 only makes sense if the list is reversed. + ( start !== 1 || attributes.reversed ) + ) { + attributes.start = start; + } + } + + return createBlock( 'core/list', { + ...getBlockAttributes( 'core/list', node.outerHTML ), + ...attributes, } ); }, }, diff --git a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap index 29b4c95f5806b0..97c607d4d94866 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.test.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.test.js.snap @@ -72,3 +72,13 @@ exports[`rawHandler should convert a caption shortcode with link 1`] = ` <figure class=\\"wp-block-image alignnone\\"><a href=\\"http://build.wordpress-develop.test/wp-content/uploads/2011/07/100_5478.jpg\\"><img src=\\"http://build.wordpress-develop.test/wp-content/uploads/2011/07/100_5478.jpg?w=604\\" alt=\\"Bell on Wharf\\" class=\\"wp-image-754\\"/></a><figcaption>Bell on wharf in San Francisco</figcaption></figure> <!-- /wp:image -->" `; + +exports[`rawHandler should convert a list with attributes 1`] = ` +"<!-- wp:list {\\"ordered\\":true,\\"type\\":\\"i\\",\\"start\\":2,\\"reversed\\":true} --> +<ol type=\\"i\\" reversed start=\\"2\\"><li>1 + <ol start=\\"2\\" reversed=\\"\\" type=\\"i\\"> + <li>1</li> + </ol> + </li></ol> +<!-- /wp:list -->" +`; diff --git a/test/integration/blocks-raw-handling.test.js b/test/integration/blocks-raw-handling.test.js index fda576a042cbb3..228c6588ef96b5 100644 --- a/test/integration/blocks-raw-handling.test.js +++ b/test/integration/blocks-raw-handling.test.js @@ -287,4 +287,9 @@ describe( 'rawHandler', () => { const HTML = readFile( path.join( __dirname, 'fixtures/shortcode-caption-with-caption-link.html' ) ); expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); } ); + + it( 'should convert a list with attributes', () => { + const HTML = readFile( path.join( __dirname, 'fixtures/list-with-attributes.html' ) ); + expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); + } ); } ); diff --git a/test/integration/fixtures/list-with-attributes.html b/test/integration/fixtures/list-with-attributes.html new file mode 100644 index 00000000000000..7114d2da756938 --- /dev/null +++ b/test/integration/fixtures/list-with-attributes.html @@ -0,0 +1,7 @@ +<ol start="2" reversed type="i"> + <li>1 + <ol start="2" reversed type="i"> + <li>1</li> + </ol> + </li> +</ol> diff --git a/test/integration/fixtures/ms-word-out.html b/test/integration/fixtures/ms-word-out.html index 427e12686ad625..47f7cab83ae73f 100644 --- a/test/integration/fixtures/ms-word-out.html +++ b/test/integration/fixtures/ms-word-out.html @@ -24,8 +24,8 @@ <h2>This is a heading level 2</h2> <ul><li>A</li><li>Bulleted<ul><li>Indented</li></ul></li><li>List</li></ul> <!-- /wp:list --> -<!-- wp:list {"ordered":true} --> -<ol><li>One</li><li>Two</li><li>Three</li></ol> +<!-- wp:list {"ordered":true,"type":"1"} --> +<ol type="1"><li>One</li><li>Two</li><li>Three</li></ol> <!-- /wp:list --> <!-- wp:table --> From 96117906dd237fa5706b2db809816e240a2fcf90 Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Mon, 28 Oct 2019 13:56:54 +0000 Subject: [PATCH 091/113] Add grandient fixtures to cover block (#18002) --- .../e2e-tests/fixtures/block-transforms.js | 22 ++++++++++ .../blocks/core__cover__gradient-image.html | 10 +++++ .../blocks/core__cover__gradient-image.json | 31 ++++++++++++++ .../core__cover__gradient-image.parsed.json | 40 ++++++++++++++++++ ...ore__cover__gradient-image.serialized.html | 5 +++ .../blocks/core__cover__gradient-video.html | 11 +++++ .../blocks/core__cover__gradient-video.json | 31 ++++++++++++++ .../core__cover__gradient-video.parsed.json | 41 +++++++++++++++++++ ...ore__cover__gradient-video.serialized.html | 5 +++ .../blocks/core__cover__gradient.html | 9 ++++ .../blocks/core__cover__gradient.json | 30 ++++++++++++++ .../blocks/core__cover__gradient.parsed.json | 38 +++++++++++++++++ .../core__cover__gradient.serialized.html | 5 +++ .../block-transforms.test.js.snap | 24 +++++++++++ 14 files changed, 302 insertions(+) create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html diff --git a/packages/e2e-tests/fixtures/block-transforms.js b/packages/e2e-tests/fixtures/block-transforms.js index d14783aa3657fc..454bf2aeb2bf22 100644 --- a/packages/e2e-tests/fixtures/block-transforms.js +++ b/packages/e2e-tests/fixtures/block-transforms.js @@ -118,6 +118,28 @@ export const EXPECTED_TRANSFORMS = { ], originalBlock: 'Cover', }, + core__cover__gradient: { + availableTransforms: [ + 'Group', + 'Image', + 'Video', + ], + originalBlock: 'Cover', + }, + 'core__cover__gradient-image': { + availableTransforms: [ + 'Group', + 'Image', + ], + originalBlock: 'Cover', + }, + 'core__cover__gradient-video': { + availableTransforms: [ + 'Group', + 'Video', + ], + originalBlock: 'Cover', + }, core__cover__video: { availableTransforms: [ 'Group', diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html new file mode 100644 index 00000000000000..6353eac851e882 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.html @@ -0,0 +1,10 @@ +<!-- wp:cover {"url":"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=","dimRatio":30,"customGradient":"linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"} --> +<div class="wp-block-cover has-background-dim-30 has-background-dim has-background-gradient" style="background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)"> + <span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"></span> + <div class="wp-block-cover__inner-container"> + <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> + <p class="has-text-align-center has-large-font-size"> Cover! </p> + <!-- /wp:paragraph --> + </div> +</div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json new file mode 100644 index 00000000000000..7752fa1da96f25 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.json @@ -0,0 +1,31 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", + "hasParallax": false, + "dimRatio": 30, + "backgroundType": "image", + "customGradient": "linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)" + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "align": "center", + "content": " Cover! ", + "dropCap": false, + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "originalContent": "<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>" + } + ], + "originalContent": "<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json new file mode 100644 index 00000000000000..07ab0aa6299bad --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.parsed.json @@ -0,0 +1,40 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=", + "dimRatio": 30, + "customGradient": "linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)" + }, + "innerBlocks": [ + { + "blockName": "core/paragraph", + "attrs": { + "align": "center", + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>\n\t\t", + "innerContent": [ + "\n\t\t<p class=\"has-text-align-center has-large-font-size\"> Cover! </p>\n\t\t" + ] + } + ], + "innerHTML": "\n<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", + "innerContent": [ + "\n<div class=\"wp-block-cover has-background-dim-30 has-background-dim has-background-gradient\" style=\"background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)\"></span>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", + null, + "\n\t</div>\n</div>\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html new file mode 100644 index 00000000000000..0fda894680f92b --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-image.serialized.html @@ -0,0 +1,5 @@ +<!-- wp:cover {"url":"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=","dimRatio":30,"customGradient":"linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"} --> +<div class="wp-block-cover has-background-dim-30 has-background-dim has-background-gradient" style="background-image:url(data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=)"><span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)"></span><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> +<p class="has-text-align-center has-large-font-size"> Cover! </p> +<!-- /wp:paragraph --></div></div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html new file mode 100644 index 00000000000000..8da6141aa041ab --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.html @@ -0,0 +1,11 @@ +<!-- wp:cover {"url":"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=","dimRatio":70,"backgroundType":"video","customGradient":"linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"} --> +<div class="wp-block-cover has-background-dim-70 has-background-dim has-background-gradient"> + <span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"></span> + <video class="wp-block-cover__video-background" autoplay muted loop src="data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="></video> + <div class="wp-block-cover__inner-container"> + <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> + <p class="has-text-align-center has-large-font-size">Cover!</p> + <!-- /wp:paragraph --> + </div> +</div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json new file mode 100644 index 00000000000000..84cb314d0fcca6 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.json @@ -0,0 +1,31 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "hasParallax": false, + "dimRatio": 70, + "backgroundType": "video", + "customGradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)" + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "align": "center", + "content": "Cover!", + "dropCap": false, + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "originalContent": "<p class=\"has-text-align-center has-large-font-size\">Cover!</p>" + } + ], + "originalContent": "<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json new file mode 100644 index 00000000000000..3ad05dacbf1257 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.parsed.json @@ -0,0 +1,41 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", + "dimRatio": 70, + "backgroundType": "video", + "customGradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)" + }, + "innerBlocks": [ + { + "blockName": "core/paragraph", + "attrs": { + "align": "center", + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t", + "innerContent": [ + "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t" + ] + } + ], + "innerHTML": "\n<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", + "innerContent": [ + "\n<div class=\"wp-block-cover has-background-dim-70 has-background-dim has-background-gradient\">\n\t<span aria-hidden=\"true\" class=\"wp-block-cover__gradient-background\" style=\"background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)\"></span>\n\t<video class=\"wp-block-cover__video-background\" autoplay muted loop src=\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\"></video>\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", + null, + "\n\t</div>\n</div>\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html new file mode 100644 index 00000000000000..2bc567b4bf2e03 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient-video.serialized.html @@ -0,0 +1,5 @@ +<!-- wp:cover {"url":"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=","dimRatio":70,"backgroundType":"video","customGradient":"linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"} --> +<div class="wp-block-cover has-background-dim-70 has-background-dim has-background-gradient"><span aria-hidden="true" class="wp-block-cover__gradient-background" style="background:linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)"></span><video class="wp-block-cover__video-background" autoplay muted loop src="data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="></video><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> +<p class="has-text-align-center has-large-font-size">Cover!</p> +<!-- /wp:paragraph --></div></div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html new file mode 100644 index 00000000000000..e3e7b9af44777a --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.html @@ -0,0 +1,9 @@ +<!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"} --> +<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"> + <div class="wp-block-cover__inner-container"> + <!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> + <p class="has-text-align-center has-large-font-size">Cover!</p> + <!-- /wp:paragraph --> + </div> +</div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json new file mode 100644 index 00000000000000..c280fe63d55ab1 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.json @@ -0,0 +1,30 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/cover", + "isValid": true, + "attributes": { + "hasParallax": false, + "dimRatio": 50, + "backgroundType": "image", + "customGradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)" + }, + "innerBlocks": [ + { + "clientId": "_clientId_0", + "name": "core/paragraph", + "isValid": true, + "attributes": { + "align": "center", + "content": "Cover!", + "dropCap": false, + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "originalContent": "<p class=\"has-text-align-center has-large-font-size\">Cover!</p>" + } + ], + "originalContent": "<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json new file mode 100644 index 00000000000000..423586ba2681e6 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.parsed.json @@ -0,0 +1,38 @@ +[ + { + "blockName": "core/cover", + "attrs": { + "customGradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)" + }, + "innerBlocks": [ + { + "blockName": "core/paragraph", + "attrs": { + "align": "center", + "placeholder": "Write title…", + "fontSize": "large" + }, + "innerBlocks": [], + "innerHTML": "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t", + "innerContent": [ + "\n\t\t<p class=\"has-text-align-center has-large-font-size\">Cover!</p>\n\t\t" + ] + } + ], + "innerHTML": "\n<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t\n\t</div>\n</div>\n", + "innerContent": [ + "\n<div class=\"wp-block-cover has-background-dim has-background-gradient\" style=\"background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)\">\n\t<div class=\"wp-block-cover__inner-container\">\n\t\t", + null, + "\n\t</div>\n</div>\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html new file mode 100644 index 00000000000000..92615e65131f9b --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__cover__gradient.serialized.html @@ -0,0 +1,5 @@ +<!-- wp:cover {"customGradient":"linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"} --> +<div class="wp-block-cover has-background-dim has-background-gradient" style="background:linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)"><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} --> +<p class="has-text-align-center has-large-font-size">Cover!</p> +<!-- /wp:paragraph --></div></div> +<!-- /wp:cover --> diff --git a/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap b/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap index dbe341ba42e76e..f461a1a4412dec 100644 --- a/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap +++ b/packages/e2e-tests/specs/experimental/__snapshots__/block-transforms.test.js.snap @@ -20,6 +20,30 @@ exports[`Block transforms correctly transform block Cover in fixture core__cover <!-- /wp:image -->" `; +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient into the Image block 1`] = ` +"<!-- wp:image --> +<figure class=\\"wp-block-image\\"><img alt=\\"\\"/></figure> +<!-- /wp:image -->" +`; + +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient into the Video block 1`] = ` +"<!-- wp:video --> +<figure class=\\"wp-block-video\\"></figure> +<!-- /wp:video -->" +`; + +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient-image into the Image block 1`] = ` +"<!-- wp:image --> +<figure class=\\"wp-block-image\\"><img src=\\"data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=\\" alt=\\"\\"/></figure> +<!-- /wp:image -->" +`; + +exports[`Block transforms correctly transform block Cover in fixture core__cover__gradient-video into the Video block 1`] = ` +"<!-- wp:video --> +<figure class=\\"wp-block-video\\"><video controls src=\\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\\"></video></figure> +<!-- /wp:video -->" +`; + exports[`Block transforms correctly transform block Cover in fixture core__cover__video into the Video block 1`] = ` "<!-- wp:video --> <figure class=\\"wp-block-video\\"><video controls src=\\"data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=\\"></video></figure> From 757f7d6d046ec517511c6a384b2f0b0774f328fa Mon Sep 17 00:00:00 2001 From: iseulde <wp@iseulde.com> Date: Mon, 28 Oct 2019 15:59:05 +0100 Subject: [PATCH 092/113] Bump plugin version to 6.8.0-rc.1 --- 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 397d62dbb343f7..9e80dee2f6a1aa 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: 6.7.0 + * Version: 6.8.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 505ba3894e2e20..ea4b7a76328ff4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.7.0", + "version": "6.8.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fcb77778ca522b..87179bff38b782 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "6.7.0", + "version": "6.8.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", From 82085edcc77e956f2565d499e094c81ea386cd4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Est=C3=AAv=C3=A3o?= <sergioestevao@gmail.com> Date: Mon, 28 Oct 2019 15:48:01 +0000 Subject: [PATCH 093/113] Fix RN build after merge with master (#18133) --- packages/components/src/index.native.js | 2 ++ packages/components/src/keyboard-shortcuts/index.native.js | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 packages/components/src/keyboard-shortcuts/index.native.js diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index 3fada7034deeb2..e9aec0ad2fb71c 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -1,5 +1,7 @@ // Components export * from './primitives'; +export { default as ColorIndicator } from './color-indicator'; +export { default as ColorPalette } from './color-palette'; export { default as Dashicon } from './dashicon'; export { default as Dropdown } from './dropdown'; export { default as Toolbar } from './toolbar'; diff --git a/packages/components/src/keyboard-shortcuts/index.native.js b/packages/components/src/keyboard-shortcuts/index.native.js new file mode 100644 index 00000000000000..fab7b99261e3ae --- /dev/null +++ b/packages/components/src/keyboard-shortcuts/index.native.js @@ -0,0 +1,2 @@ +const KeyboardShortcuts = () => null; +export default KeyboardShortcuts; From 12490f242fcbe7497699bf2ea133164c93572aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <wp@iseulde.com> Date: Mon, 28 Oct 2019 17:16:08 +0100 Subject: [PATCH 094/113] Commander: switch cloning method to HTTPS (#18136) * Commander: switch cloning method to HTTPS * Add HOME env variable --- bin/commander.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index dcc863872f034d..95cfc56b25efd9 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -17,7 +17,7 @@ const uuid = require( 'uuid/v4' ); // Config const gitRepoOwner = 'WordPress'; -const gitRepoURL = 'git@github.com:' + gitRepoOwner + '/gutenberg.git'; +const gitRepoURL = 'https://github.com/' + gitRepoOwner + '/gutenberg.git'; const svnRepoURL = 'https://plugins.svn.wordpress.org/gutenberg'; // Working Directories @@ -95,6 +95,7 @@ function runShellScript( script, cwd ) { env: { NO_CHECKS: true, PATH: process.env.PATH, + HOME: process.env.HOME, }, stdio: [ 'inherit', 'ignore', 'inherit' ], } ); From ff78d859458d12e475e8a61b3e6da8937d87a74c Mon Sep 17 00:00:00 2001 From: andrei draganescu <me@andreidraganescu.info> Date: Tue, 29 Oct 2019 02:24:16 +0200 Subject: [PATCH 095/113] Add horizontal option for the block movers (#16615) * horizontal option for the mover, missing icons, broken hover * we now have icons * positioned the mover to the middle left * horizontal mover on mobile * vertical layout for horizontal movers * drop block movers into block edit to enable inline movers * implemented so as to not be a concern for the block implementer * removes useless scss variable * hiding the drag handle at block level * renamed horizontalMover to moverOptions to incorporate separation of properties * rafactores the mover options * Initial CSS work to make the menu more manageable. This moves to flex instead of grid, neutralizes margins, simplifies a few things. * Make movers inline again. * Further improve margins for child blocks. * adds proper aliases in BlockEdit * previxed options as experimental * RTL movers * removed the position option, marked option experimental * labeled as experimental new mober and block list props * refactored direction detection code for better readability, fixed some code alignment issues --- .../block-list/block-mobile-toolbar.js | 4 +- .../src/components/block-list/block.js | 42 +++++++----- .../src/components/block-list/index.js | 2 + .../components/block-list/multi-controls.js | 2 + .../src/components/block-list/style.scss | 3 + .../src/components/block-mover/icons.js | 12 ++++ .../src/components/block-mover/index.js | 57 +++++++++++++--- .../block-mover/mover-description.js | 51 ++++++++++---- .../src/components/block-mover/style.scss | 32 +++++++-- .../src/components/inner-blocks/index.js | 2 + .../src/navigation-menu-item/editor.scss | 50 +++++++++++++- .../block-library/src/navigation-menu/edit.js | 3 +- .../src/navigation-menu/editor.scss | 66 +++++++++++++++++++ 13 files changed, 284 insertions(+), 42 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js b/packages/block-editor/src/components/block-list/block-mobile-toolbar.js index f35a7add73641a..8af64ec12c021b 100644 --- a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js +++ b/packages/block-editor/src/components/block-list/block-mobile-toolbar.js @@ -9,11 +9,11 @@ import { ifViewportMatches } from '@wordpress/viewport'; import BlockMover from '../block-mover'; import VisualEditorInserter from '../inserter'; -function BlockMobileToolbar( { clientId } ) { +function BlockMobileToolbar( { clientId, moverDirection } ) { return ( <div className="editor-block-list__block-mobile-toolbar block-editor-block-list__block-mobile-toolbar"> <VisualEditorInserter /> - <BlockMover clientIds={ [ clientId ] } /> + <BlockMover clientIds={ [ clientId ] } __experimentalOrientation={ moverDirection } /> </div> ); } diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 777cb54933a80b..48b5506e452f2f 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -67,6 +67,7 @@ function BlockListBlock( { mode, isFocusMode, hasFixedToolbar, + moverDirection, isLocked, clientId, rootClientId, @@ -450,6 +451,20 @@ function BlockListBlock( { }; } const blockElementId = `block-${ clientId }`; + const blockMover = ( + <BlockMover + clientIds={ clientId } + blockElementId={ blockElementId } + isHidden={ ! isSelected } + isDraggable={ + isDraggable !== false && + ( ! isPartOfMultiSelection && isMovable ) + } + onDragStart={ onDragStart } + onDragEnd={ onDragEnd } + __experimentalOrientation={ moverDirection } + /> + ); // We wrap the BlockEdit component in a div that hides it when editing in // HTML mode. This allows us to render all of the ancillary pieces @@ -511,22 +526,18 @@ function BlockListBlock( { rootClientId={ rootClientId } /> { isFirstMultiSelected && ( - <BlockMultiControls rootClientId={ rootClientId } /> + <BlockMultiControls + rootClientId={ rootClientId } + moverDirection={ moverDirection } + /> ) } - <div className="editor-block-list__block-edit block-editor-block-list__block-edit"> - { shouldRenderMovers && ( - <BlockMover - clientIds={ clientId } - blockElementId={ blockElementId } - isHidden={ ! isSelected } - isDraggable={ - isDraggable !== false && - ( ! isPartOfMultiSelection && isMovable ) - } - onDragStart={ onDragStart } - onDragEnd={ onDragEnd } - /> + <div + className={ classnames( + 'editor-block-list__block-edit block-editor-block-list__block-edit', + { 'has-mover-inside': moverDirection === 'horizontal' }, ) } + > + { shouldRenderMovers && ( moverDirection === 'vertical' ) && blockMover } { shouldShowBreadcrumb && ( <BlockBreadcrumb clientId={ clientId } @@ -566,6 +577,7 @@ function BlockListBlock( { { isValid && mode === 'html' && ( <BlockHtml clientId={ clientId } /> ) } + { shouldRenderMovers && ( moverDirection === 'horizontal' ) && blockMover } { ! isValid && [ <BlockInvalidWarning key="invalid-warning" @@ -578,7 +590,7 @@ function BlockListBlock( { </BlockCrashBoundary> { !! hasError && <BlockCrashWarning /> } { shouldShowMobileToolbar && ( - <BlockMobileToolbar clientId={ clientId } /> + <BlockMobileToolbar clientId={ clientId } moverDirection={ moverDirection } /> ) } </IgnoreNestedEvents> </div> diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 25386d5039c12c..b6af745716b289 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -195,6 +195,7 @@ class BlockList extends Component { className, blockClientIds, rootClientId, + __experimentalMoverDirection: moverDirection = 'vertical', isDraggable, selectedBlockClientId, multiSelectedBlockClientIds, @@ -227,6 +228,7 @@ class BlockList extends Component { blockRef={ this.setBlockRef } onSelectionStart={ this.onSelectionStart } isDraggable={ isDraggable } + moverDirection={ moverDirection } // This prop is explicitely computed and passed down // to avoid being impacted by the async mode diff --git a/packages/block-editor/src/components/block-list/multi-controls.js b/packages/block-editor/src/components/block-list/multi-controls.js index e4dd88aeda030f..2f49ca2ca0a3b4 100644 --- a/packages/block-editor/src/components/block-list/multi-controls.js +++ b/packages/block-editor/src/components/block-list/multi-controls.js @@ -11,6 +11,7 @@ import BlockMover from '../block-mover'; function BlockListMultiControls( { multiSelectedBlockClientIds, isSelecting, + moverDirection, } ) { if ( isSelecting ) { return null; @@ -19,6 +20,7 @@ function BlockListMultiControls( { return ( <BlockMover clientIds={ multiSelectedBlockClientIds } + __experimentalOrientation={ moverDirection } /> ); } diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index 761632c49d7c7f..e06667a0f914e7 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -101,6 +101,9 @@ .block-editor-block-list__block-edit { position: relative; + &.has-mover-inside > [data-block] { + display: flex; + } &::before { z-index: z-index(".block-editor-block-list__block-edit::before"); diff --git a/packages/block-editor/src/components/block-mover/icons.js b/packages/block-editor/src/components/block-mover/icons.js index 06bf5601f439db..2a15b8a6159d5d 100644 --- a/packages/block-editor/src/components/block-mover/icons.js +++ b/packages/block-editor/src/components/block-mover/icons.js @@ -9,12 +9,24 @@ export const upArrow = ( </SVG> ); +export const leftArrow = ( + <SVG width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> + <Path d="M4.5 9l5.6-5.7 1.4 1.5L7.3 9l4.2 4.2-1.4 1.5L4.5 9z" /> + </SVG> +); + export const downArrow = ( <SVG width="18" height="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <Polygon points="9,13.5 14.7,7.9 13.2,6.5 9,10.7 4.8,6.5 3.3,7.9 " /> </SVG> ); +export const rightArrow = ( + <SVG width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> + <Path d="M13.5 9L7.9 3.3 6.5 4.8 10.7 9l-4.2 4.2 1.4 1.5L13.5 9z" /> + </SVG> +); + export const dragHandle = ( <SVG width="18" height="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <Path d="M13,8c0.6,0,1-0.4,1-1s-0.4-1-1-1s-1,0.4-1,1S12.4,8,13,8z M5,6C4.4,6,4,6.4,4,7s0.4,1,1,1s1-0.4,1-1S5.6,6,5,6z M5,10 diff --git a/packages/block-editor/src/components/block-mover/index.js b/packages/block-editor/src/components/block-mover/index.js index dd09dc1c86b7c5..cd1f4483eceb16 100644 --- a/packages/block-editor/src/components/block-mover/index.js +++ b/packages/block-editor/src/components/block-mover/index.js @@ -7,7 +7,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; import { IconButton } from '@wordpress/components'; import { getBlockType } from '@wordpress/blocks'; import { Component } from '@wordpress/element'; @@ -18,7 +18,7 @@ import { withInstanceId, compose } from '@wordpress/compose'; * Internal dependencies */ import { getBlockMoverDescription } from './mover-description'; -import { upArrow, downArrow, dragHandle } from './icons'; +import { leftArrow, rightArrow, upArrow, downArrow, dragHandle } from './icons'; import { IconDragHandle } from './drag-handle'; export class BlockMover extends Component { @@ -44,24 +44,55 @@ export class BlockMover extends Component { } render() { - const { onMoveUp, onMoveDown, isFirst, isLast, isDraggable, onDragStart, onDragEnd, clientIds, blockElementId, blockType, firstIndex, isLocked, instanceId, isHidden, rootClientId } = this.props; + const { onMoveUp, onMoveDown, __experimentalOrientation: orientation, isRTL, isFirst, isLast, isDraggable, onDragStart, onDragEnd, clientIds, blockElementId, blockType, firstIndex, isLocked, instanceId, isHidden, rootClientId } = this.props; const { isFocused } = this.state; const blocksCount = castArray( clientIds ).length; if ( isLocked || ( isFirst && isLast && ! rootClientId ) ) { return null; } + const getArrowIcon = ( moveDirection ) => { + if ( moveDirection === 'up' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? rightArrow : leftArrow; + } + return upArrow; + } else if ( moveDirection === 'down' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? leftArrow : rightArrow; + } + return downArrow; + } + return null; + }; + + const getMovementDirection = ( moveDirection ) => { + if ( moveDirection === 'up' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? 'right' : 'left'; + } + return 'up'; + } else if ( moveDirection === 'down' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? 'left' : 'right'; + } + return 'down'; + } + return null; + }; + // We emulate a disabled state because forcefully applying the `disabled` // attribute on the button while it has focus causes the screen to change // to an unfocused state (body as active element) without firing blur on, // the rendering parent, leaving it unable to react to focus out. return ( - <div className={ classnames( 'editor-block-mover block-editor-block-mover', { 'is-visible': isFocused || ! isHidden } ) }> + <div className={ classnames( 'editor-block-mover block-editor-block-mover', { 'is-visible': isFocused || ! isHidden, 'is-horizontal': orientation === 'horizontal' } ) }> <IconButton className="editor-block-mover__control block-editor-block-mover__control" onClick={ isFirst ? null : onMoveUp } - icon={ upArrow } - label={ __( 'Move up' ) } + icon={ getArrowIcon( 'up' ) } + // translators: %s: Horizontal direction of block movement ( left, right ) + label={ sprintf( __( 'Move %s' ), getMovementDirection( 'up' ) ) } aria-describedby={ `block-editor-block-mover__up-description-${ instanceId }` } aria-disabled={ isFirst } onFocus={ this.onFocus } @@ -79,8 +110,9 @@ export class BlockMover extends Component { <IconButton className="editor-block-mover__control block-editor-block-mover__control" onClick={ isLast ? null : onMoveDown } - icon={ downArrow } - label={ __( 'Move down' ) } + icon={ getArrowIcon( 'down' ) } + // translators: %s: Horizontal direction of block movement ( left, right ) + label={ sprintf( __( 'Move %s' ), getMovementDirection( 'down' ) ) } aria-describedby={ `block-editor-block-mover__down-description-${ instanceId }` } aria-disabled={ isLast } onFocus={ this.onFocus } @@ -95,6 +127,8 @@ export class BlockMover extends Component { isFirst, isLast, -1, + orientation, + isRTL, ) } </span> @@ -107,6 +141,8 @@ export class BlockMover extends Component { isFirst, isLast, 1, + orientation, + isRTL, ) } </span> @@ -125,12 +161,17 @@ export default compose( const blockOrder = getBlockOrder( rootClientId ); const firstIndex = getBlockIndex( firstClientId, rootClientId ); const lastIndex = getBlockIndex( last( normalizedClientIds ), rootClientId ); + const { getSettings } = select( 'core/block-editor' ); + const { + isRTL, + } = getSettings(); return { blockType: block ? getBlockType( block.name ) : null, isLocked: getTemplateLock( rootClientId ) === 'all', rootClientId, firstIndex, + isRTL, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, }; diff --git a/packages/block-editor/src/components/block-mover/mover-description.js b/packages/block-editor/src/components/block-mover/mover-description.js index 44174ce85534ca..d9a62de176d821 100644 --- a/packages/block-editor/src/components/block-mover/mover-description.js +++ b/packages/block-editor/src/components/block-mover/mover-description.js @@ -14,12 +14,30 @@ import { __, _n, sprintf } from '@wordpress/i18n'; * @param {boolean} isLast This is the last block. * @param {number} dir Direction of movement (> 0 is considered to be going * down, < 0 is up). + * @param {string} orientation The orientation of the block movers, vertical or + * horizontal. + * @param {boolean} isRTL True if current writing system is right to left. * * @return {string} Label for the block movement controls. */ -export function getBlockMoverDescription( selectedCount, type, firstIndex, isFirst, isLast, dir ) { +export function getBlockMoverDescription( selectedCount, type, firstIndex, isFirst, isLast, dir, orientation, isRTL ) { const position = ( firstIndex + 1 ); + const getMovementDirection = ( moveDirection ) => { + if ( moveDirection === 'up' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? 'right' : 'left'; + } + return 'up'; + } else if ( moveDirection === 'down' ) { + if ( orientation === 'horizontal' ) { + return isRTL ? 'left' : 'right'; + } + return 'down'; + } + return null; + }; + if ( selectedCount > 1 ) { return getMultiBlockMoverDescription( selectedCount, firstIndex, isFirst, isLast, dir ); } @@ -32,35 +50,46 @@ export function getBlockMoverDescription( selectedCount, type, firstIndex, isFir if ( dir > 0 && ! isLast ) { // moving down return sprintf( - // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position - __( 'Move %1$s block from position %2$d down to position %3$d' ), + // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: Direction of movement ( up, down, left, right ), 4: New position + __( 'Move %1$s block from position %2$d %3$s to position %4$d' ), type, position, - ( position + 1 ) + getMovementDirection( 'down' ), + ( position + 1 ), ); } if ( dir > 0 && isLast ) { // moving down, and is the last item - // translators: %s: Type of block (i.e. Text, Image etc) - return sprintf( __( 'Block %s is at the end of the content and can’t be moved down' ), type ); + // translators: 1: Type of block (i.e. Text, Image etc), 2: Direction of movement ( up, down, left, right ) + return sprintf( + __( 'Block %1$s is at the end of the content and can’t be moved %2$s' ), + type, + getMovementDirection( 'down' ), + + ); } if ( dir < 0 && ! isFirst ) { // moving up return sprintf( - // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: New position - __( 'Move %1$s block from position %2$d up to position %3$d' ), + // translators: 1: Type of block (i.e. Text, Image etc), 2: Position of selected block, 3: Direction of movement ( up, down, left, right ), 4: New position + __( 'Move %1$s block from position %2$d %3$s to position %4$d' ), type, position, - ( position - 1 ) + getMovementDirection( 'up' ), + ( position - 1 ), ); } if ( dir < 0 && isFirst ) { // moving up, and is the first item - // translators: %s: Type of block (i.e. Text, Image etc) - return sprintf( __( 'Block %s is at the beginning of the content and can’t be moved up' ), type ); + // translators: 1: Type of block (i.e. Text, Image etc), 2: Direction of movement ( up, down, left, right ) + return sprintf( + __( 'Block %1$s is at the beginning of the content and can’t be moved %2$s' ), + type, + getMovementDirection( 'up' ), + ); } } diff --git a/packages/block-editor/src/components/block-mover/style.scss b/packages/block-editor/src/components/block-mover/style.scss index a506b3282fad42..260d456c73d3c0 100644 --- a/packages/block-editor/src/components/block-mover/style.scss +++ b/packages/block-editor/src/components/block-mover/style.scss @@ -1,5 +1,4 @@ .block-editor-block-mover { - @include break-small() { min-height: $empty-paragraph-height; opacity: 0; @@ -20,13 +19,38 @@ // 24px is the smallest size of a good pressable button. // With 3 pieces of side UI, that comes to a total of 72px. // To vertically center against a 56px paragraph, move upwards 72px - 56px / 2. - // Don't do this for wide, fullwide, or mobile. - .block-editor-block-list__block:not([data-align="wide"]):not([data-align="full"]) & { - margin-top: -$grid-size; + margin-top: -$grid-size; + } + + &.is-horizontal { + margin-top: 5px; // The height of the appender is 36px. This pushes down the mover to be centered according to that. + margin-right: $grid-size; + padding-right: 0; + min-height: auto; + width: ($icon-button-size-small * 2) + ($border-width * 2); + height: $icon-button-size-small + ($border-width * 2); + display: flex; + + .block-editor-block-mover__control { + width: $icon-button-size-small; + height: $icon-button-size-small; + + svg { + width: $icon-button-size-small; + padding: 3px; + } } } } +// Don't add negative vertical margin for wide, fullwide, or mobile. +// @todo: simplify this selector. +@include break-small() { + .block-editor-block-list__block:not([data-align="wide"]):not([data-align="full"]) .editor-block-mover:not(.is-horizontal) { + margin-top: 0; + } +} + // Mover icon buttons. .block-editor-block-mover__control { display: flex; diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index 35e1bf10b47ca2..ed147bfe736adf 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -107,6 +107,7 @@ class InnerBlocks extends Component { hasOverlay, renderAppender, template, + __experimentalMoverDirection: moverDirection, __experimentalTemplateOptions: templateOptions, __experimentalOnSelectTemplateOption: onSelectTemplateOption, __experimentalAllowTemplateOptionSkip: allowTemplateOptionSkip, @@ -131,6 +132,7 @@ class InnerBlocks extends Component { <BlockList rootClientId={ clientId } renderAppender={ renderAppender } + __experimentalMoverDirection={ moverDirection } /> ) } </div> diff --git a/packages/block-library/src/navigation-menu-item/editor.scss b/packages/block-library/src/navigation-menu-item/editor.scss index fcebe469a04e95..8e6c06274129b1 100644 --- a/packages/block-library/src/navigation-menu-item/editor.scss +++ b/packages/block-library/src/navigation-menu-item/editor.scss @@ -1,7 +1,55 @@ + +// Normalize menu items and edit containers, to look mostly the same. .wp-block-navigation-menu-item__field .components-text-control__input.components-text-control__input, .wp-block-navigation-menu-item__container { border-radius: 0; - padding: $block-padding; + // Make it the same height as the appender to prevent a jump. Maybe revisit this. + line-height: $icon-button-size; + min-height: $icon-button-size; +} + +.wp-block-navigation-menu-item { + margin-right: $grid-size; + + // Provide a base menu item margin. + // This should be the same inside the field, + // and the edit container should compensate. + // This is to make sure the edit and view are the same. + padding: 0 $grid-size; +} + +.wp-block-navigation-menu-item__edit-container { + display: flex; + white-space: nowrap; + + // Compensate for menu item base padding. + margin-left: -$grid-size; + + .wp-block-navigation-menu-item__field { + margin-right: $grid-size; + + // This should match the padding of the menu item. + padding: 0 $grid-size; + + // This make it look like an input field. + // We may want to not style this at all, but let's try this. + // We don't use the mixins because they increase the size of the input, which doesn't work with PlainText. + box-shadow: inset 0 0 0 1px $dark-gray-200; + transition: box-shadow 0.1s linear; + border-radius: $radius-round-rectangle; + @include reduce-motion("transition"); + + &:focus { + color: $dark-gray-900; + box-shadow: inset 0 0 0 2px $blue-medium-focus; + + // Windows High Contrast mode will show this outline, but not the box-shadow. + outline: 2px solid transparent; + } + } +} + +.wp-block-navigation-menu-item { font-family: $editor-font; font-weight: bold; font-size: $text-editor-font-size; diff --git a/packages/block-library/src/navigation-menu/edit.js b/packages/block-library/src/navigation-menu/edit.js index 074d6839333025..b89afeff3863c8 100644 --- a/packages/block-library/src/navigation-menu/edit.js +++ b/packages/block-library/src/navigation-menu/edit.js @@ -35,7 +35,6 @@ import BlockColorsStyleSelector from './block-colors-selector'; function NavigationMenu( { attributes, - setAttributes, clientId, pages, isRequesting, @@ -43,6 +42,7 @@ function NavigationMenu( { textColor, setBackgroundColor, setTextColor, + setAttributes, } ) { const { navigatorToolbarButton, navigatorModal } = useBlockNavigator( clientId ); const defaultMenuItems = useMemo( @@ -140,6 +140,7 @@ function NavigationMenu( { template={ defaultMenuItems ? defaultMenuItems : null } allowedBlocks={ [ 'core/navigation-menu-item' ] } templateInsertUpdatesSelection={ false } + __experimentalMoverDirection={ 'horizontal' } /> } </div> diff --git a/packages/block-library/src/navigation-menu/editor.scss b/packages/block-library/src/navigation-menu/editor.scss index 5133b3261fb24e..cc663e7787a998 100644 --- a/packages/block-library/src/navigation-menu/editor.scss +++ b/packages/block-library/src/navigation-menu/editor.scss @@ -1,3 +1,60 @@ +// Reduce the paddings, margins, and UI of inner-blocks. +// @todo: eventually we may add a feature that lets a parent container absorb the block UI of a child block. +// When that happens, leverage that instead of the following overrides. +[data-type="core/navigation-menu"] { + // 1. Reset margins on immediate innerblocks container. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout { + margin-left: 0; + margin-right: 0; + } + + // 2. Remove paddings on subsequent immediate children. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout > .wp-block { + width: auto; + padding-left: 0; + padding-right: 0; + margin-left: 0; // something + } + + // 3. Remove margins on subsequent Edit container. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout > .wp-block > .block-editor-block-list__block-edit { + margin-left: 0; + margin-right: 0; + } + + // 4. Remove vertical margins on subsequent block container. + .wp-block-navigation-menu .block-editor-inner-blocks > .block-editor-block-list__layout .wp-block > .block-editor-block-list__block-edit > [data-block] { + margin-top: 0; + margin-bottom: 0; + } + + // Remove the dashed outlines for child blocks. + &.is-hovered .wp-block-navigation-menu .block-editor-block-list__block-edit::before, + &.is-selected .wp-block-navigation-menu .block-editor-block-list__block-edit::before, + &.has-child-selected .wp-block-navigation-menu .block-editor-block-list__block-edit::before { + border-color: transparent !important; // !important used to keep the selector from growing any more complex. + } + + // Hide the breadcrumb. + // Hide the sibling inserter. + .wp-block-navigation-menu .block-editor-block-list__insertion-point, + .wp-block-navigation-menu .block-editor-block-list__breadcrumb { + display: none; + } + + // Polish the Appender. + .wp-block-navigation-menu .block-list-appender { + margin: 0; + + .block-editor-button-block-appender { + padding: $grid-size; + outline: none; + background: none; + } + } +} + + .wp-block-navigation-menu .block-editor-block-list__layout, .wp-block-navigation-menu { display: flex; @@ -9,6 +66,7 @@ } .wp-block-navigation-menu-item { + margin-left: $grid-size; .wp-block-navigation-menu-item__link { margin-left: $grid-size-large; } @@ -96,3 +154,11 @@ $color-control-label-height: 20px; margin-top: 2px; } } + +.block-editor-block-mover { + &.is-horizontal { + .block-editor-block-mover__control-drag-handle { + display: none; + } + } +} From f46a6a81e74be9a839c6c6159ce360707daf7cb2 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak <marcus@mkaz.com> Date: Mon, 28 Oct 2019 22:55:52 -0700 Subject: [PATCH 096/113] Update ExternalLink Component to fix visually hidden text (#18142) * Switch screen-reader-txt to VisuallyHidden component * Fix core embed test snapshot, new classname --- .../block-library/src/embed/test/__snapshots__/index.js.snap | 2 +- packages/components/src/external-link/index.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/embed/test/__snapshots__/index.js.snap b/packages/block-library/src/embed/test/__snapshots__/index.js.snap index 78923aa24c5f6b..2023cab5e5b65f 100644 --- a/packages/block-library/src/embed/test/__snapshots__/index.js.snap +++ b/packages/block-library/src/embed/test/__snapshots__/index.js.snap @@ -61,7 +61,7 @@ exports[`core/embed block edit matches snapshot 1`] = ` > Learn more about embeds <span - class="screen-reader-text" + class="components-visually-hidden" > (opens in a new tab) </span> diff --git a/packages/components/src/external-link/index.js b/packages/components/src/external-link/index.js index 68bf56394b8f86..cc9750a4b779c9 100644 --- a/packages/components/src/external-link/index.js +++ b/packages/components/src/external-link/index.js @@ -14,6 +14,7 @@ import { forwardRef } from '@wordpress/element'; * Internal dependencies */ import Dashicon from '../dashicon'; +import VisuallyHidden from '../visually-hidden'; export function ExternalLink( { href, children, className, rel = '', ...additionalProps }, ref ) { rel = uniq( compact( [ @@ -27,12 +28,12 @@ export function ExternalLink( { href, children, className, rel = '', ...addition // eslint-disable-next-line react/jsx-no-target-blank <a { ...additionalProps } className={ classes } href={ href } target="_blank" rel={ rel } ref={ ref }> { children } - <span className="screen-reader-text"> + <VisuallyHidden as="span"> { /* translators: accessibility text */ __( '(opens in a new tab)' ) } - </span> + </VisuallyHidden> <Dashicon icon="external" className="components-external-link__icon" /> </a> ); From d42053413785aaf2c23400ccc86b03fd17d9bf1a Mon Sep 17 00:00:00 2001 From: Brent Swisher <brent@brentswisher.com> Date: Tue, 29 Oct 2019 02:06:40 -0400 Subject: [PATCH 097/113] Add Spinner component to storybook (#18145) --- packages/components/src/spinner/stories/index.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 packages/components/src/spinner/stories/index.js diff --git a/packages/components/src/spinner/stories/index.js b/packages/components/src/spinner/stories/index.js new file mode 100644 index 00000000000000..188f13e45273f4 --- /dev/null +++ b/packages/components/src/spinner/stories/index.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import Spinner from '../'; + +export default { title: 'Spinner', component: Spinner }; + +export const _default = () => { + return ( + <Spinner /> + ); +}; From 38a1227e7c5817141dd0907b762eb4ff00dc770e Mon Sep 17 00:00:00 2001 From: andrei draganescu <me@andreidraganescu.info> Date: Tue, 29 Oct 2019 08:46:12 +0200 Subject: [PATCH 098/113] Smart block appender (#16708) * if thre is only one there is only one * made a new insertion point selector, some code review refactoring * better handling of inserter * refactoring and named block insertion * updates to the appender * update snapshots * update docs * default inserter label is used in so many tests * fixed allowed blocks test * snapshot updated * better naming and removed the need for es-lint disabling * improved the inserter label construction * improved the doc of getTheOnlyAllowedItem selector * reverting test patches becasue patching without understanding is bad, bad, bad - don't do it * moved getInsertionIndex out of selectos and back into each component that used it * docs generated * added experimental labels to new selectors, added es-lint comment back * updated docs * Update packages/block-editor/src/store/selectors.js Co-Authored-By: Miguel Fonseca <miguelcsf@gmail.com> * Update packages/block-editor/src/store/selectors.js Co-Authored-By: Miguel Fonseca <miguelcsf@gmail.com> * refactored and fixed some coding errors * small code move * small code move * removes aria attrs for autoinserted items * fixes typo, adds translators comment * simplifies the intserter logic * fix for the simplification * simplifies by using one selector and passing props in compose * small code updates * lint * renamed insertedBlock * small doc update * adds tooltip to the default button appender * refactores for more self documenting varnames --- .../components/button-block-appender/index.js | 40 ++++-- .../test/__snapshots__/index.js.snap | 6 +- .../src/components/inserter/index.js | 118 +++++++++++++++--- packages/block-editor/src/store/selectors.js | 16 +++ 4 files changed, 146 insertions(+), 34 deletions(-) diff --git a/packages/block-editor/src/components/button-block-appender/index.js b/packages/block-editor/src/components/button-block-appender/index.js index 7fd751165f5b45..1cbbb5980903a2 100644 --- a/packages/block-editor/src/components/button-block-appender/index.js +++ b/packages/block-editor/src/components/button-block-appender/index.js @@ -6,8 +6,8 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Button, Icon } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; +import { Button, Icon, Tooltip } from '@wordpress/components'; +import { _x, sprintf } from '@wordpress/i18n'; /** * Internal dependencies @@ -21,17 +21,31 @@ function ButtonBlockAppender( { rootClientId, className } ) { <BlockDropZone rootClientId={ rootClientId } /> <Inserter rootClientId={ rootClientId } - renderToggle={ ( { onToggle, disabled, isOpen } ) => ( - <Button - className={ classnames( className, 'block-editor-button-block-appender' ) } - onClick={ onToggle } - aria-expanded={ isOpen } - disabled={ disabled } - > - <span className="screen-reader-text">{ __( 'Add Block' ) }</span> - <Icon icon="insert" /> - </Button> - ) } + renderToggle={ ( { onToggle, disabled, isOpen, blockTitle, hasSingleBlockType } ) => { + let label; + if ( hasSingleBlockType ) { + // translators: %s: the name of the block when there is only one + label = sprintf( _x( 'Add %s', 'directly add the only allowed block' ), blockTitle ); + } else { + label = _x( 'Add block', 'Generic label for block inserter button' ); + } + const isToggleButton = ! hasSingleBlockType; + return ( + <Tooltip text={ label }> + <Button + className={ classnames( className, 'block-editor-button-block-appender' ) } + onClick={ onToggle } + aria-haspopup={ isToggleButton ? 'true' : undefined } + aria-expanded={ isToggleButton ? isOpen : undefined } + disabled={ disabled } + label={ label } + > + <span className="screen-reader-text">{ label }</span> + <Icon icon="insert" /> + </Button> + </Tooltip> + ); + } } isAppender /> </> diff --git a/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap index 9a09dae0d47674..08a0f7df9efe74 100644 --- a/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap +++ b/packages/block-editor/src/components/default-block-appender/test/__snapshots__/index.js.snap @@ -29,7 +29,7 @@ exports[`DefaultBlockAppender should append a default block when input focused 1 rows={1} value="Start writing or type / to choose a block" /> - <WithSelect(IfCondition(Inserter)) + <WithSelect(WithDispatch(IfCondition(Inserter))) isAppender={true} position="top right" /> @@ -53,7 +53,7 @@ exports[`DefaultBlockAppender should match snapshot 1`] = ` rows={1} value="Start writing or type / to choose a block" /> - <WithSelect(IfCondition(Inserter)) + <WithSelect(WithDispatch(IfCondition(Inserter))) isAppender={true} position="top right" /> @@ -77,7 +77,7 @@ exports[`DefaultBlockAppender should optionally show without prompt 1`] = ` rows={1} value="" /> - <WithSelect(IfCondition(Inserter)) + <WithSelect(WithDispatch(IfCondition(Inserter))) isAppender={true} position="top right" /> diff --git a/packages/block-editor/src/components/inserter/index.js b/packages/block-editor/src/components/inserter/index.js index 5abb1ae4ef9230..b9fd9dead4b377 100644 --- a/packages/block-editor/src/components/inserter/index.js +++ b/packages/block-editor/src/components/inserter/index.js @@ -1,29 +1,46 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, _x, sprintf } from '@wordpress/i18n'; import { Dropdown, IconButton } from '@wordpress/components'; import { Component } from '@wordpress/element'; -import { withSelect } from '@wordpress/data'; +import { withDispatch, withSelect } from '@wordpress/data'; import { compose, ifCondition } from '@wordpress/compose'; +import { + createBlock, + getBlockType, +} from '@wordpress/blocks'; /** * Internal dependencies */ import InserterMenu from './menu'; -const defaultRenderToggle = ( { onToggle, disabled, isOpen } ) => ( - <IconButton - icon="insert" - label={ __( 'Add block' ) } - labelPosition="bottom" - onClick={ onToggle } - className="editor-inserter__toggle block-editor-inserter__toggle" - aria-haspopup="true" - aria-expanded={ isOpen } - disabled={ disabled } - /> -); +const defaultRenderToggle = ( { onToggle, disabled, isOpen, blockTitle, hasSingleBlockType } ) => { + let label; + if ( hasSingleBlockType ) { + // translators: %s: the name of the block when there is only one + label = sprintf( _x( 'Add %s', 'directly add the only allowed block' ), blockTitle ); + } else { + label = _x( 'Add block', 'Generic label for block inserter button' ); + } + return ( + <IconButton + icon="insert" + label={ label } + labelPosition="bottom" + onClick={ onToggle } + className="editor-inserter__toggle block-editor-inserter__toggle" + aria-haspopup={ ! hasSingleBlockType ? 'true' : false } + aria-expanded={ ! hasSingleBlockType ? isOpen : false } + disabled={ disabled } + /> + ); +}; class Inserter extends Component { constructor() { @@ -56,10 +73,12 @@ class Inserter extends Component { renderToggle( { onToggle, isOpen } ) { const { disabled, + blockTitle, + hasSingleBlockType, renderToggle = defaultRenderToggle, } = this.props; - return renderToggle( { onToggle, isOpen, disabled } ); + return renderToggle( { onToggle, isOpen, disabled, blockTitle, hasSingleBlockType } ); } /** @@ -86,8 +105,10 @@ class Inserter extends Component { } render() { - const { position } = this.props; - + const { position, hasSingleBlockType, insertOnlyAllowedBlock } = this.props; + if ( hasSingleBlockType ) { + return this.renderToggle( { onToggle: insertOnlyAllowedBlock } ); + } return ( <Dropdown className="editor-inserter block-editor-inserter" @@ -105,10 +126,71 @@ class Inserter extends Component { export default compose( [ withSelect( ( select, { rootClientId } ) => { - const { hasInserterItems } = select( 'core/block-editor' ); + const { + hasInserterItems, + __experimentalGetAllowedBlocks, + } = select( 'core/block-editor' ); + + const allowedBlocks = __experimentalGetAllowedBlocks( rootClientId ); + const hasSingleBlockType = allowedBlocks && ( get( allowedBlocks, [ 'length' ], 0 ) === 1 ); + let allowedBlockType = false; + if ( hasSingleBlockType ) { + allowedBlockType = getBlockType( allowedBlocks ); + } return { hasItems: hasInserterItems( rootClientId ), + hasSingleBlockType, + blockTitle: allowedBlockType ? allowedBlockType.title : '', + allowedBlockType, + }; + } ), + withDispatch( ( dispatch, ownProps, { select } ) => { + return { + insertOnlyAllowedBlock() { + const { rootClientId, clientId, isAppender, destinationRootClientId } = ownProps; + const { + hasSingleBlockType, + allowedBlockType, + } = ownProps; + + if ( ! hasSingleBlockType ) { + return; + } + + function getInsertionIndex() { + const { + getBlockIndex, + getBlockSelectionEnd, + getBlockOrder, + } = select( 'core/block-editor' ); + + // If the clientId is defined, we insert at the position of the block. + if ( clientId ) { + return getBlockIndex( clientId, destinationRootClientId ); + } + + // If there a selected block, we insert after the selected block. + const end = getBlockSelectionEnd(); + if ( ! isAppender && end ) { + return getBlockIndex( end, destinationRootClientId ) + 1; + } + + // Otherwise, we insert at the end of the current rootClientId + return getBlockOrder( destinationRootClientId ).length; + } + + const { + insertBlock, + } = dispatch( 'core/block-editor' ); + + const blockToInsert = createBlock( allowedBlockType.name ); + insertBlock( + blockToInsert, + getInsertionIndex(), + rootClientId + ); + }, }; } ), ifCondition( ( { hasItems } ) => hasItems ), diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index a0fd75a3a7b816..76bec295096bc3 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1310,6 +1310,22 @@ export const hasInserterItems = createSelector( ], ); +/** + * Returns the list of allowed inserter blocks for inner blocks children + * + * @param {Object} state Editor state. + * @param {?string} rootClientId Optional root client ID of block list. + * + * @return {Array?} The list of allowed block types or false. + */ +export const __experimentalGetAllowedBlocks = ( state, rootClientId = null ) => { + if ( ! rootClientId ) { + return false; + } + const { allowedBlocks } = getBlockListSettings( state, rootClientId ); + return allowedBlocks; +}; + /** * Returns the Block List settings of a block, if any exist. * From 77b36b963a63bb69827273c815ea369cbde676b2 Mon Sep 17 00:00:00 2001 From: Jon Quach <hello@jonquach.com> Date: Tue, 29 Oct 2019 04:20:53 -0400 Subject: [PATCH 099/113] Components: Draggable, add story (#18070) * Components: Add Story for Draggable This update adds a Storybook example for the Draggable component from `@wordpress/components`. * Fix useState hook for Draggable story example Solution was to create an Example component with the useState hook. Render that Example component in the story instead. --- .../components/src/draggable/stories/index.js | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 packages/components/src/draggable/stories/index.js diff --git a/packages/components/src/draggable/stories/index.js b/packages/components/src/draggable/stories/index.js new file mode 100644 index 00000000000000..fbe81321df7232 --- /dev/null +++ b/packages/components/src/draggable/stories/index.js @@ -0,0 +1,69 @@ +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import Draggable from '../'; +import Dashicon from '../../dashicon'; + +export default { title: 'Draggable', component: Draggable }; + +const Box = ( props ) => { + return ( + <div + { ...props } + style={ { + alignItems: 'center', + display: 'flex', + justifyContent: 'center', + width: 100, + height: 100, + background: '#ddd', + } } + /> + ); +}; + +const DraggalbeExample = () => { + const [ isDragging, setDragging ] = useState( false ); + + // Allow for the use of ID in the example + /* eslint-disable no-restricted-syntax */ + return ( + <div> + <p>Is Dragging? { isDragging ? 'Yes' : 'No' }</p> + <div id="draggable-example-box" style={ { display: 'inline-flex' } }> + <Draggable elementId="draggable-example-box"> + { ( { onDraggableStart, onDraggableEnd } ) => { + const handleOnDragStart = ( event ) => { + setDragging( true ); + onDraggableStart( event ); + }; + const handleOnDragEnd = ( event ) => { + setDragging( false ); + onDraggableEnd( event ); + }; + + return ( + <Box + onDragStart={ handleOnDragStart } + onDragEnd={ handleOnDragEnd } + draggable + > + <Dashicon icon="move" /> + </Box> + ); + } } + </Draggable> + </div> + </div> + ); + /* eslint-enable no-restricted-syntax */ +}; + +export const _default = () => { + return <DraggalbeExample />; +}; From 6277ffdfb1ab449cf7a958a77fe3b81a49f4816a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Tue, 29 Oct 2019 09:53:13 +0100 Subject: [PATCH 100/113] Block Directory: Convert it to UI Plugin to avoid bundling into Core (#17576) * Block Directory: Convert it to UI Plugin to avoid bundling into Core * Load the block directory assets only when the experiment is enabled * Try to reimplement asset overrides to give more flexibility * Add code style improvemements and perform code cleanup * Try to make PHP unit tests pass by removing group check * Ensure that packages and vendor scripts are printed in the footer * Fix the has action check for the block directory assets * Move gutenberg-block-directory experiment check out of the action * Fix bin/get-vendor-scripts.php --- bin/get-vendor-scripts.php | 11 +- lib/block-directory.php | 21 ++ lib/client-assets.php | 280 ++++++++++-------- lib/customizer.php | 2 +- lib/experiments-page.php | 9 +- lib/load.php | 22 +- lib/rest-api.php | 4 + lib/templates.php | 5 +- package-lock.json | 1 + packages/block-directory/package.json | 1 + packages/block-directory/src/index.js | 3 +- packages/block-directory/src/plugins/index.js | 15 + .../index.js | 6 +- .../editor/src/components/provider/index.js | 31 +- phpunit/class-override-script-test.php | 16 +- 15 files changed, 251 insertions(+), 176 deletions(-) create mode 100644 lib/block-directory.php create mode 100644 packages/block-directory/src/plugins/index.js rename packages/{editor/src/components => block-directory/src/plugins}/inserter-menu-downloadable-blocks-panel/index.js (89%) diff --git a/bin/get-vendor-scripts.php b/bin/get-vendor-scripts.php index 442e77b0eb4358..e7295f556b4cb2 100755 --- a/bin/get-vendor-scripts.php +++ b/bin/get-vendor-scripts.php @@ -32,4 +32,13 @@ function wp_add_inline_script() {} require_once dirname( dirname( __FILE__ ) ) . '/lib/client-assets.php'; -gutenberg_register_vendor_scripts(); +/** + * Hi, phpcs + */ +function run_gutenberg_register_vendor_scripts() { + global $wp_scripts; + + gutenberg_register_vendor_scripts( $wp_scripts ); +} + +run_gutenberg_register_vendor_scripts(); diff --git a/lib/block-directory.php b/lib/block-directory.php new file mode 100644 index 00000000000000..723db66de2b3c5 --- /dev/null +++ b/lib/block-directory.php @@ -0,0 +1,21 @@ +<?php +/** + * Block directory functions. + * + * @package gutenberg + */ + +if ( + gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ) && + ! has_action( 'admin_enqueue_scripts', 'enqueue_block_editor_assets_block_directory' ) +) { + /** + * Function responsible for enqueuing the assets required + * for the block directory functionality in the editor. + */ + function gutenberg_enqueue_block_editor_assets_block_directory() { + wp_enqueue_script( 'wp-block-directory' ); + wp_enqueue_style( 'wp-block-directory' ); + } + add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' ); +} diff --git a/lib/client-assets.php b/lib/client-assets.php index c4c63ecf7474f7..6906d39996a4b1 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -42,6 +42,7 @@ function gutenberg_url( $path ) { * * @since 4.1.0 * + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). * @param string $handle Name of the script. Should be unique. * @param string $src Full URL of the script, or path of the script relative to the WordPress root directory. * @param array $deps Optional. An array of registered script handles this script depends on. Default empty array. @@ -52,10 +53,8 @@ function gutenberg_url( $path ) { * @param bool $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>. * Default 'false'. */ -function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) { - global $wp_scripts; - - $script = $wp_scripts->query( $handle, 'registered' ); +function gutenberg_override_script( &$scripts, $handle, $src, $deps = array(), $ver = false, $in_footer = false ) { + $script = $scripts->query( $handle, 'registered' ); if ( $script ) { /* * In many ways, this is a reimplementation of `wp_register_script` but @@ -67,6 +66,7 @@ function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false $script->src = $src; $script->deps = $deps; $script->ver = $ver; + $script->args = $in_footer; /* * The script's `group` designation is an indication of whether it is @@ -81,7 +81,7 @@ function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false $script->add_data( 'group', 1 ); } } else { - wp_register_script( $handle, $src, $deps, $ver, $in_footer ); + $scripts->add( $handle, $src, $deps, $ver, $in_footer ); } /* @@ -93,7 +93,7 @@ function gutenberg_override_script( $handle, $src, $deps = array(), $ver = false * See: https://core.trac.wordpress.org/ticket/46089 */ if ( 'wp-i18n' !== $handle && 'wp-polyfill' !== $handle ) { - wp_set_script_translations( $handle, 'default' ); + $scripts->set_translations( $handle, 'default' ); } } @@ -155,6 +155,7 @@ function gutenberg_override_translation_file( $file, $handle ) { * * @since 4.1.0 * + * @param WP_Styles $styles WP_Styles instance (passed by reference). * @param string $handle Name of the stylesheet. Should be unique. * @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory. * @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array. @@ -166,18 +167,69 @@ function gutenberg_override_translation_file( $file, $handle ) { * Default 'all'. Accepts media types like 'all', 'print' and 'screen', or media queries like * '(orientation: portrait)' and '(max-width: 640px)'. */ -function gutenberg_override_style( $handle, $src, $deps = array(), $ver = false, $media = 'all' ) { - wp_deregister_style( $handle ); - wp_register_style( $handle, $src, $deps, $ver, $media ); +function gutenberg_override_style( &$styles, $handle, $src, $deps = array(), $ver = false, $media = 'all' ) { + $style = $styles->query( $handle, 'registered' ); + if ( $style ) { + $styles->remove( $handle ); + } + $styles->add( $handle, $src, $deps, $ver, $media ); } +/** + * Registers vendor JavaScript files to be used as dependencies of the editor + * and plugins. + * + * This function is called from a script during the plugin build process, so it + * should not call any WordPress PHP functions. + * + * @since 0.1.0 + * + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). + */ +function gutenberg_register_vendor_scripts( &$scripts ) { + $suffix = SCRIPT_DEBUG ? '' : '.min'; + + // Vendor Scripts. + $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; + + // TODO: Overrides for react, react-dom and lodash are necessary + // until WordPress 5.3 is released. + gutenberg_register_vendor_script( + $scripts, + 'react', + 'https://unpkg.com/react@16.9.0/umd/react' . $react_suffix . '.js', + array( 'wp-polyfill' ), + '16.9.0', + true + ); + gutenberg_register_vendor_script( + $scripts, + 'react-dom', + 'https://unpkg.com/react-dom@16.9.0/umd/react-dom' . $react_suffix . '.js', + array( 'react' ), + '16.9.0', + true + ); + gutenberg_register_vendor_script( + $scripts, + 'lodash', + 'https://unpkg.com/lodash@4.17.15/lodash' . $suffix . '.js', + array(), + '4.17.15', + true + ); +} +add_action( 'wp_default_scripts', 'gutenberg_register_vendor_scripts' ); + /** * Registers all the WordPress packages scripts that are in the standardized * `build/` location. * * @since 4.5.0 + * + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). */ -function gutenberg_register_packages_scripts() { +function gutenberg_register_packages_scripts( &$scripts ) { foreach ( glob( gutenberg_dir_path() . 'build/*/index.js' ) as $path ) { // Prefix `wp-` to package directory to get script handle. // For example, `…/build/a11y/index.js` becomes `wp-a11y`. @@ -206,6 +258,7 @@ function gutenberg_register_packages_scripts() { $gutenberg_path = substr( $path, strlen( gutenberg_dir_path() ) ); gutenberg_override_script( + $scripts, $handle, gutenberg_url( $gutenberg_path ), $dependencies, @@ -214,117 +267,74 @@ function gutenberg_register_packages_scripts() { ); } } +add_action( 'wp_default_scripts', 'gutenberg_register_packages_scripts' ); /** - * Registers common scripts and styles to be used as dependencies of the editor - * and plugins. + * Registers all the WordPress packages styles that are in the standardized + * `build/` location. * - * @since 0.1.0 - */ -function gutenberg_register_scripts_and_styles() { - global $wp_scripts; - - gutenberg_register_vendor_scripts(); - gutenberg_register_packages_scripts(); - - // Add nonce middleware which accounts for the absence of the heartbeat - // listener. This relies on API Fetch implementation running middlewares in - // order of last added, and that the original nonce middleware would defer - // to an X-WP-Nonce header already being present. This inline script should - // be removed once the following Core ticket is resolved in assigning the - // nonce received from heartbeat to the created middleware. - // - // See: https://core.trac.wordpress.org/ticket/46107 . - // See: https://github.com/WordPress/gutenberg/pull/13451 . - if ( isset( $wp_scripts->registered['wp-api-fetch'] ) ) { - $wp_scripts->registered['wp-api-fetch']->deps[] = 'wp-hooks'; - } - wp_add_inline_script( - 'wp-api-fetch', - sprintf( - 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . - 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . - 'wp.apiFetch.nonceEndpoint = "%s";' . - 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', - ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), - admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) - ), - 'after' - ); - - // TEMPORARY: Core does not (yet) provide persistence migration from the - // introduction of the block editor and still calls the data plugins. - // We unset the existing inline scripts first. - $wp_scripts->registered['wp-data']->extra['after'] = array(); - wp_add_inline_script( - 'wp-data', - implode( - "\n", - array( - '( function() {', - ' var userId = ' . get_current_user_ID() . ';', - ' var storageKey = "WP_DATA_USER_" + userId;', - ' wp.data', - ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', - ' wp.data.plugins.persistence.__unstableMigrate( { storageKey: storageKey } );', - '} )();', - ) - ) - ); + * @since 6.7.0 + * @param WP_Styles $styles WP_Styles instance (passed by reference). + */ +function gutenberg_register_packages_styles( &$styles ) { // Editor Styles. - // This empty stylesheet is defined to ensure backward compatibility. - gutenberg_override_style( 'wp-blocks', false ); - gutenberg_override_style( + $styles, 'wp-block-editor', gutenberg_url( 'build/block-editor/style.css' ), array( 'wp-components', 'wp-editor-font' ), filemtime( gutenberg_dir_path() . 'build/editor/style.css' ) ); - wp_style_add_data( 'wp-block-editor', 'rtl', 'replace' ); + $styles->add_data( 'wp-block-editor', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-editor', gutenberg_url( 'build/editor/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-nux', 'wp-block-directory' ), + array( 'wp-components', 'wp-block-editor', 'wp-nux' ), filemtime( gutenberg_dir_path() . 'build/editor/style.css' ) ); - wp_style_add_data( 'wp-editor', 'rtl', 'replace' ); + $styles->add_data( 'wp-editor', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-edit-post', gutenberg_url( 'build/edit-post/style.css' ), array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-nux' ), filemtime( gutenberg_dir_path() . 'build/edit-post/style.css' ) ); - wp_style_add_data( 'wp-edit-post', 'rtl', 'replace' ); + $styles->add_data( 'wp-edit-post', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-components', gutenberg_url( 'build/components/style.css' ), array(), filemtime( gutenberg_dir_path() . 'build/components/style.css' ) ); - wp_style_add_data( 'wp-components', 'rtl', 'replace' ); + $styles->add_data( 'wp-components', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-block-library', gutenberg_url( 'build/block-library/style.css' ), array(), filemtime( gutenberg_dir_path() . 'build/block-library/style.css' ) ); - wp_style_add_data( 'wp-block-library', 'rtl', 'replace' ); + $styles->add_data( 'wp-block-library', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-format-library', gutenberg_url( 'build/format-library/style.css' ), array( 'wp-block-editor', 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/format-library/style.css' ) ); - wp_style_add_data( 'wp-format-library', 'rtl', 'replace' ); + $styles->add_data( 'wp-format-library', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-edit-blocks', gutenberg_url( 'build/block-library/editor.css' ), array( @@ -336,92 +346,107 @@ function gutenberg_register_scripts_and_styles() { ), filemtime( gutenberg_dir_path() . 'build/block-library/editor.css' ) ); - wp_style_add_data( 'wp-edit-blocks', 'rtl', 'replace' ); + $styles->add_data( 'wp-edit-blocks', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-nux', gutenberg_url( 'build/nux/style.css' ), array( 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/nux/style.css' ) ); - wp_style_add_data( 'wp-nux', 'rtl', 'replace' ); + $styles->add_data( 'wp-nux', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-block-library-theme', gutenberg_url( 'build/block-library/theme.css' ), array(), filemtime( gutenberg_dir_path() . 'build/block-library/theme.css' ) ); - wp_style_add_data( 'wp-block-library-theme', 'rtl', 'replace' ); + $styles->add_data( 'wp-block-library-theme', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-list-reusable-blocks', gutenberg_url( 'build/list-reusable-blocks/style.css' ), array( 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/list-reusable-blocks/style.css' ) ); - wp_style_add_data( 'wp-list-reusable-block', 'rtl', 'replace' ); + $styles->add_data( 'wp-list-reusable-block', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-edit-widgets', gutenberg_url( 'build/edit-widgets/style.css' ), array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks' ), filemtime( gutenberg_dir_path() . 'build/edit-widgets/style.css' ) ); - wp_style_add_data( 'wp-edit-widgets', 'rtl', 'replace' ); + $styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' ); gutenberg_override_style( + $styles, 'wp-block-directory', gutenberg_url( 'build/block-directory/style.css' ), - array( 'wp-components' ), + array( 'wp-block-editor', 'wp-components' ), filemtime( gutenberg_dir_path() . 'build/block-directory/style.css' ) ); - wp_style_add_data( 'wp-block-directory', 'rtl', 'replace' ); - - if ( defined( 'GUTENBERG_LIVE_RELOAD' ) && GUTENBERG_LIVE_RELOAD ) { - $live_reload_url = ( GUTENBERG_LIVE_RELOAD === true ) ? 'http://localhost:35729/livereload.js' : GUTENBERG_LIVE_RELOAD; - - wp_enqueue_script( - 'gutenberg-live-reload', - $live_reload_url - ); - } + $styles->add_data( 'wp-block-directory', 'rtl', 'replace' ); } -add_action( 'wp_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 ); -add_action( 'admin_enqueue_scripts', 'gutenberg_register_scripts_and_styles', 5 ); +add_action( 'wp_default_styles', 'gutenberg_register_packages_styles' ); /** - * Registers vendor JavaScript files to be used as dependencies of the editor + * Registers common scripts and styles to be used as dependencies of the editor * and plugins. * - * This function is called from a script during the plugin build process, so it - * should not call any WordPress PHP functions. - * * @since 0.1.0 */ -function gutenberg_register_vendor_scripts() { - $suffix = SCRIPT_DEBUG ? '' : '.min'; - - // Vendor Scripts. - $react_suffix = ( SCRIPT_DEBUG ? '.development' : '.production' ) . $suffix; +function gutenberg_enqueue_block_editor_assets() { + global $wp_scripts; - // TODO: Overrides for react, react-dom and lodash are necessary - // until WordPress 5.3 is released. - gutenberg_register_vendor_script( - 'react', - 'https://unpkg.com/react@16.9.0/umd/react' . $react_suffix . '.js', - array( 'wp-polyfill' ) - ); - gutenberg_register_vendor_script( - 'react-dom', - 'https://unpkg.com/react-dom@16.9.0/umd/react-dom' . $react_suffix . '.js', - array( 'react' ) + wp_add_inline_script( + 'wp-api-fetch', + sprintf( + 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );' . + 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );' . + 'wp.apiFetch.nonceEndpoint = "%s";' . + 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', + ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ), + admin_url( 'admin-ajax.php?action=gutenberg_rest_nonce' ) + ), + 'after' ); - gutenberg_register_vendor_script( - 'lodash', - 'https://unpkg.com/lodash@4.17.15/lodash' . $suffix . '.js' + + // TEMPORARY: Core does not (yet) provide persistence migration from the + // introduction of the block editor and still calls the data plugins. + // We unset the existing inline scripts first. + $wp_scripts->registered['wp-data']->extra['after'] = array(); + wp_add_inline_script( + 'wp-data', + implode( + "\n", + array( + '( function() {', + ' var userId = ' . get_current_user_ID() . ';', + ' var storageKey = "WP_DATA_USER_" + userId;', + ' wp.data', + ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', + ' wp.data.plugins.persistence.__unstableMigrate( { storageKey: storageKey } );', + '} )();', + ) + ) ); + + if ( defined( 'GUTENBERG_LIVE_RELOAD' ) && GUTENBERG_LIVE_RELOAD ) { + $live_reload_url = ( GUTENBERG_LIVE_RELOAD === true ) ? 'http://localhost:35729/livereload.js' : GUTENBERG_LIVE_RELOAD; + + wp_enqueue_script( + 'gutenberg-live-reload', + $live_reload_url + ); + } } +add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets' ); /** * Retrieves a unique and reasonably short and human-friendly filename for a @@ -459,14 +484,21 @@ function gutenberg_vendor_script_filename( $handle, $src ) { * possible, or downloading it if the cached version is unavailable or * outdated. * - * @param string $handle Name of the script. - * @param string $src Full URL of the external script. - * @param array $deps Optional. An array of registered script handles this - * script depends on. + * @param WP_Scripts $scripts WP_Scripts instance (passed by reference). + * @param string $handle Name of the script. + * @param string $src Full URL of the external script. + * @param array $deps Optional. An array of registered script handles this + * script depends on. + * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL + * as a query string for cache busting purposes. If version is set to false, a version + * number is automatically added equal to current installed WordPress version. + * If set to null, no version is added. + * @param bool $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>. + * Default 'false'. * * @since 0.1.0 */ -function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { +function gutenberg_register_vendor_script( &$scripts, $handle, $src, $deps = array(), $ver = null, $in_footer = false ) { if ( defined( 'GUTENBERG_LOAD_VENDOR_SCRIPTS' ) && ! GUTENBERG_LOAD_VENDOR_SCRIPTS ) { return; } @@ -496,7 +528,7 @@ function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { if ( ! $f ) { // Failed to open the file for writing, probably due to server // permissions. Enqueue the script directly from the URL instead. - gutenberg_override_script( $handle, $src, $deps, null ); + gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer ); return; } fclose( $f ); @@ -509,16 +541,18 @@ function gutenberg_register_vendor_script( $handle, $src, $deps = array() ) { // The request failed. If the file is already cached, continue to // use this file. If not, then unlink the 0 byte file, and enqueue // the script directly from the URL. - gutenberg_override_script( $handle, $src, $deps, null ); + gutenberg_override_script( $scripts, $handle, $src, $deps, $ver, $in_footer ); unlink( $full_path ); return; } } gutenberg_override_script( + $scripts, $handle, gutenberg_url( 'vendor/' . $filename ), $deps, - null + $ver, + $in_footer ); } diff --git a/lib/customizer.php b/lib/customizer.php index 771ced523f5c98..1f27db00ee3085 100644 --- a/lib/customizer.php +++ b/lib/customizer.php @@ -55,7 +55,7 @@ function gutenberg_customize_register( $wp_customize ) { 'sanitize_callback' => 'gutenberg_customize_sanitize', ) ); - if ( get_option( 'gutenberg-experiments' ) && array_key_exists( 'gutenberg-widget-experiments', get_option( 'gutenberg-experiments' ) ) ) { + if ( gutenberg_is_experiment_enabled( 'gutenberg-widget-experiments' ) ) { $wp_customize->add_section( 'gutenberg_widget_blocks', array( 'title' => __( 'Widget Blocks (Experimental)', 'gutenberg' ) ) diff --git a/lib/experiments-page.php b/lib/experiments-page.php index bbc04650a732e3..765e0cc5883d9d 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -130,12 +130,11 @@ function gutenberg_display_experiment_section() { * @return array Filtered editor settings. */ function gutenberg_experiments_editor_settings( $settings ) { - $experiments_exist = get_option( 'gutenberg-experiments' ); $experiments_settings = array( - '__experimentalEnableLegacyWidgetBlock' => $experiments_exist ? array_key_exists( 'gutenberg-widget-experiments', get_option( 'gutenberg-experiments' ) ) : false, - '__experimentalEnableMenuBlock' => $experiments_exist ? array_key_exists( 'gutenberg-menu-block', get_option( 'gutenberg-experiments' ) ) : false, - '__experimentalBlockDirectory' => $experiments_exist ? array_key_exists( 'gutenberg-block-directory', get_option( 'gutenberg-experiments' ) ) : false, - '__experimentalEnableFullSiteEditing' => $experiments_exist ? array_key_exists( 'gutenberg-full-site-editing', get_option( 'gutenberg-experiments' ) ) : false, + '__experimentalEnableLegacyWidgetBlock' => gutenberg_is_experiment_enabled( 'gutenberg-widget-experiments' ), + '__experimentalEnableMenuBlock' => gutenberg_is_experiment_enabled( 'gutenberg-menu-block' ), + '__experimentalBlockDirectory' => gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ), + '__experimentalEnableFullSiteEditing' => gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing' ), ); return array_merge( $settings, $experiments_settings ); diff --git a/lib/load.php b/lib/load.php index 35b49b2ead5b95..58e545b38a6f7a 100644 --- a/lib/load.php +++ b/lib/load.php @@ -9,6 +9,20 @@ die( 'Silence is golden.' ); } +/** + * Checks whether the Gutenberg experiment is enabled. + * + * @since 6.7.0 + * + * @param string $name The name of the experiment. + * + * @return bool True when the experiment is enabled. + */ +function gutenberg_is_experiment_enabled( $name ) { + $experiments = get_option( 'gutenberg-experiments' ); + return ! empty( $experiments[ $name ] ); +} + // These files only need to be loaded if within a rest server instance // which this class will exist if that is the case. if ( class_exists( 'WP_REST_Controller' ) ) { @@ -22,13 +36,12 @@ require dirname( __FILE__ ) . '/class-experimental-wp-widget-blocks-manager.php'; require dirname( __FILE__ ) . '/class-wp-rest-widget-areas-controller.php'; } - /** - * End: Include for phase 2 - */ - if ( ! class_exists( 'WP_REST_Block_Directory_Controller' ) ) { require dirname( __FILE__ ) . '/class-wp-rest-block-directory-controller.php'; } + /** + * End: Include for phase 2 + */ require dirname( __FILE__ ) . '/rest-api.php'; } @@ -43,6 +56,7 @@ require dirname( __FILE__ ) . '/templates.php'; require dirname( __FILE__ ) . '/template-loader.php'; require dirname( __FILE__ ) . '/client-assets.php'; +require dirname( __FILE__ ) . '/block-directory.php'; require dirname( __FILE__ ) . '/demo.php'; require dirname( __FILE__ ) . '/widgets.php'; require dirname( __FILE__ ) . '/widgets-page.php'; diff --git a/lib/rest-api.php b/lib/rest-api.php index 5aa85b6d83e48b..6ad5e6d0e6f0ef 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -85,6 +85,10 @@ function gutenberg_register_rest_widget_areas() { * @since 6.5.0 */ function gutenberg_register_rest_block_directory() { + if ( ! gutenberg_is_experiment_enabled( 'gutenberg-block-directory' ) ) { + return; + } + $block_directory_controller = new WP_REST_Block_Directory_Controller(); $block_directory_controller->register_routes(); } diff --git a/lib/templates.php b/lib/templates.php index fe7a4177400db7..3eb4df27e1c0ec 100644 --- a/lib/templates.php +++ b/lib/templates.php @@ -9,10 +9,7 @@ * Registers block editor 'wp_template' post type. */ function gutenberg_register_template_post_type() { - if ( - ! get_option( 'gutenberg-experiments' ) || - ! array_key_exists( 'gutenberg-full-site-editing', get_option( 'gutenberg-experiments' ) ) - ) { + if ( ! gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing' ) ) { return; } diff --git a/package-lock.json b/package-lock.json index ea4b7a76328ff4..cfab06638c2fda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7228,6 +7228,7 @@ "@wordpress/data": "file:packages/data", "@wordpress/element": "file:packages/element", "@wordpress/i18n": "file:packages/i18n", + "@wordpress/plugins": "file:packages/plugins", "lodash": "^4.17.15" } }, diff --git a/packages/block-directory/package.json b/packages/block-directory/package.json index 7736869f8100cd..22ff8e4e8f8c2b 100644 --- a/packages/block-directory/package.json +++ b/packages/block-directory/package.json @@ -29,6 +29,7 @@ "@wordpress/data": "file:../data", "@wordpress/element": "file:../element", "@wordpress/i18n": "file:../i18n", + "@wordpress/plugins": "file:../plugins", "lodash": "^4.17.15" }, "publishConfig": { diff --git a/packages/block-directory/src/index.js b/packages/block-directory/src/index.js index 5c088e8d5928d3..3af7027bf74d02 100644 --- a/packages/block-directory/src/index.js +++ b/packages/block-directory/src/index.js @@ -2,5 +2,4 @@ * Internal dependencies */ import './store'; - -export { default as DownloadableBlocksPanel } from './components/downloadable-blocks-panel'; +import './plugins'; diff --git a/packages/block-directory/src/plugins/index.js b/packages/block-directory/src/plugins/index.js new file mode 100644 index 00000000000000..917b8567c2d87f --- /dev/null +++ b/packages/block-directory/src/plugins/index.js @@ -0,0 +1,15 @@ +/** + * WordPress dependencies + */ +import { registerPlugin } from '@wordpress/plugins'; + +/** + * Internal dependencies + */ +import InserterMenuDownloadableBlocksPanel from './inserter-menu-downloadable-blocks-panel'; + +registerPlugin( 'block-directory', { + render() { + return <InserterMenuDownloadableBlocksPanel />; + }, +} ); diff --git a/packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js b/packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js similarity index 89% rename from packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js rename to packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js index d19d76ba42ad84..9fb2cc8105dc0b 100644 --- a/packages/editor/src/components/inserter-menu-downloadable-blocks-panel/index.js +++ b/packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js @@ -7,9 +7,13 @@ import { debounce } from 'lodash'; * WordPress dependencies */ import { __experimentalInserterMenuExtension } from '@wordpress/block-editor'; -import { DownloadableBlocksPanel } from '@wordpress/block-directory'; import { useState } from '@wordpress/element'; +/** + * Internal dependencies + */ +import DownloadableBlocksPanel from '../../components/downloadable-blocks-panel'; + function InserterMenuDownloadableBlocksPanel() { const [ debouncedFilterValue, setFilterValue ] = useState( '' ); diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index b57213e0628403..ae621e903b18d4 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { map, pick, defaultTo, differenceBy, isEqual, noop } from 'lodash'; +import { map, pick, defaultTo } from 'lodash'; import memize from 'memize'; /** @@ -16,7 +16,6 @@ import { BlockEditorProvider, transformStyles } from '@wordpress/block-editor'; import apiFetch from '@wordpress/api-fetch'; import { addQueryArgs } from '@wordpress/url'; import { decodeEntities } from '@wordpress/html-entities'; -import { unregisterBlockType } from '@wordpress/blocks'; /** * Internal dependencies @@ -25,7 +24,6 @@ import withRegistryProvider from './with-registry-provider'; import { mediaUpload } from '../../utils'; import ReusableBlocksButtons from '../reusable-blocks-buttons'; import ConvertToGroupButtons from '../convert-to-group-buttons'; -import InserterMenuDownloadableBlocksPanel from '../inserter-menu-downloadable-blocks-panel'; const fetchLinkSuggestions = async ( search ) => { const posts = await apiFetch( { @@ -43,8 +41,6 @@ const fetchLinkSuggestions = async ( search ) => { } ) ); }; -const UNINSTALL_ERROR_NOTICE_ID = 'block-uninstall-error'; - class EditorProvider extends Component { constructor( props ) { super( ...arguments ); @@ -141,21 +137,6 @@ class EditorProvider extends Component { if ( this.props.settings !== prevProps.settings ) { this.props.updateEditorSettings( this.props.settings ); } - - // When a block is installed from the inserter and is unused, - // it is removed when saving the post. - // Todo: move this to the edit-post package into a separate component. - if ( ! isEqual( this.props.downloadableBlocksToUninstall, prevProps.downloadableBlocksToUninstall ) ) { - this.props.downloadableBlocksToUninstall.forEach( ( blockType ) => { - this.props.uninstallBlock( blockType, noop, () => { - this.props.createWarningNotice( - __( 'Block previews can\'t uninstall.' ), { - id: UNINSTALL_ERROR_NOTICE_ID, - } ); - } ); - unregisterBlockType( blockType.name ); - } ); - } } componentWillUnmount() { @@ -200,9 +181,6 @@ class EditorProvider extends Component { { children } <ReusableBlocksButtons /> <ConvertToGroupButtons /> - { editorSettings.__experimentalBlockDirectory && ( - <InserterMenuDownloadableBlocksPanel /> - ) } </BlockEditorProvider> </EntityProvider> </EntityProvider> @@ -220,10 +198,6 @@ export default compose( [ __experimentalGetReusableBlocks, } = select( 'core/editor' ); const { canUser } = select( 'core' ); - const { getInstalledBlockTypes } = select( 'core/block-directory' ); - const { getBlocks } = select( 'core/block-editor' ); - - const downloadableBlocksToUninstall = differenceBy( getInstalledBlockTypes(), getBlocks(), 'name' ); return { canUserUseUnfilteredHTML: canUserUseUnfilteredHTML(), @@ -231,7 +205,6 @@ export default compose( [ blocks: getEditorBlocks(), reusableBlocks: __experimentalGetReusableBlocks(), hasUploadPermissions: defaultTo( canUser( 'create', 'media' ), true ), - downloadableBlocksToUninstall, }; } ), withDispatch( ( dispatch ) => { @@ -243,7 +216,6 @@ export default compose( [ __experimentalTearDownEditor, } = dispatch( 'core/editor' ); const { createWarningNotice } = dispatch( 'core/notices' ); - const { uninstallBlock } = dispatch( 'core/block-directory' ); return { setupEditor, @@ -257,7 +229,6 @@ export default compose( [ } ); }, tearDownEditor: __experimentalTearDownEditor, - uninstallBlock, }; } ), ] )( EditorProvider ); diff --git a/phpunit/class-override-script-test.php b/phpunit/class-override-script-test.php index 034fa2f25a618b..074de00b649ba6 100644 --- a/phpunit/class-override-script-test.php +++ b/phpunit/class-override-script-test.php @@ -28,7 +28,10 @@ function tearDown() { * Tests that script is localized. */ function test_localizes_script() { + global $wp_scripts; + gutenberg_override_script( + $wp_scripts, 'gutenberg-dummy-script', 'https://example.com/', array( 'dependency' ), @@ -36,7 +39,6 @@ function test_localizes_script() { false ); - global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-dummy-script', 'registered' ); $this->assertEquals( array( 'dependency', 'wp-i18n' ), $script->deps ); } @@ -45,7 +47,10 @@ function test_localizes_script() { * Tests that script properties are overridden. */ function test_replaces_registered_properties() { + global $wp_scripts; + gutenberg_override_script( + $wp_scripts, 'gutenberg-dummy-script', 'https://example.com/updated', array( 'updated-dependency' ), @@ -53,19 +58,21 @@ function test_replaces_registered_properties() { true ); - global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-dummy-script', 'registered' ); $this->assertEquals( 'https://example.com/updated', $script->src ); $this->assertEquals( array( 'updated-dependency', 'wp-i18n' ), $script->deps ); $this->assertEquals( 'updated-version', $script->ver ); - $this->assertEquals( 1, $script->extra['group'] ); + $this->assertTrue( $script->args ); } /** * Tests that new script registers normally if no handle by the name. */ function test_registers_new_script() { + global $wp_scripts; + gutenberg_override_script( + $wp_scripts, 'gutenberg-second-dummy-script', 'https://example.com/', array( 'dependency' ), @@ -73,11 +80,10 @@ function test_registers_new_script() { true ); - global $wp_scripts; $script = $wp_scripts->query( 'gutenberg-second-dummy-script', 'registered' ); $this->assertEquals( 'https://example.com/', $script->src ); $this->assertEquals( array( 'dependency', 'wp-i18n' ), $script->deps ); $this->assertEquals( 'version', $script->ver ); - $this->assertEquals( 1, $script->extra['group'] ); + $this->assertTrue( $script->args ); } } From 0eb16bd4732d06fe1f156526602f130b27109e2d Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Tue, 29 Oct 2019 10:51:30 +0100 Subject: [PATCH 101/113] Make the AsyncModeProvider API a stable API (#18154) --- .../block-list/block-async-mode-provider.js | 5 +-- .../src/components/block-list/index.js | 2 +- packages/data/README.md | 40 +++++++++++++++++++ .../components/async-mode-provider/context.js | 34 ++++++++++++++++ packages/data/src/index.js | 4 +- 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block-async-mode-provider.js b/packages/block-editor/src/components/block-list/block-async-mode-provider.js index aaa2e709db92c6..3cdde80050761c 100644 --- a/packages/block-editor/src/components/block-list/block-async-mode-provider.js +++ b/packages/block-editor/src/components/block-list/block-async-mode-provider.js @@ -1,10 +1,7 @@ /** * WordPress dependencies */ -import { - __experimentalAsyncModeProvider as AsyncModeProvider, - useSelect, -} from '@wordpress/data'; +import { AsyncModeProvider, useSelect } from '@wordpress/data'; const BlockAsyncModeProvider = ( { children, clientId, isBlockInSelection } ) => { const isParentOfSelectedBlock = useSelect( ( select ) => { diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index b6af745716b289..54511ac941ecc4 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -17,7 +17,7 @@ import { Component } from '@wordpress/element'; import { withSelect, withDispatch, - __experimentalAsyncModeProvider as AsyncModeProvider, + AsyncModeProvider, } from '@wordpress/data'; import { compose } from '@wordpress/compose'; diff --git a/packages/data/README.md b/packages/data/README.md index ca3c5fcab29bba..68dc1a48e1697a 100644 --- a/packages/data/README.md +++ b/packages/data/README.md @@ -251,6 +251,46 @@ Specific implementation differences from Redux and React Redux: <!-- START TOKEN(Autogenerated API docs) --> +<a name="AsyncModeProvider" href="#AsyncModeProvider">#</a> **AsyncModeProvider** + +Context Provider Component used to switch the data module component rerendering +between Sync and Async modes. + +_Usage_ + +```js +import { useSelect, AsyncModeProvider } from '@wordpress/data'; + +function BlockCount() { + const count = useSelect( ( select ) => { + return select( 'core/block-editor' ).getBlockCount() + } ); + + return count; +} + +function App() { + return ( + <AsyncModeProvider value={ true }> + <BlockCount /> + </AsyncModeProvider> + ); +} +``` + +In this example, the BlockCount component is rerendered asynchronously. +It means if a more critical task is being performed (like typing in an input), +the rerendering is delayed until the browser becomes IDLE. +It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. + +_Parameters_ + +- _props.value_ `boolean`: Enable Async Mode. + +_Returns_ + +- `WPComponent`: The component to be rendered. + <a name="combineReducers" href="#combineReducers">#</a> **combineReducers** The combineReducers helper function turns an object whose values are different diff --git a/packages/data/src/components/async-mode-provider/context.js b/packages/data/src/components/async-mode-provider/context.js index c0e59ef7138183..88c98cb260b4a0 100644 --- a/packages/data/src/components/async-mode-provider/context.js +++ b/packages/data/src/components/async-mode-provider/context.js @@ -9,4 +9,38 @@ const { Consumer, Provider } = Context; export const AsyncModeConsumer = Consumer; +/** + * Context Provider Component used to switch the data module component rerendering + * between Sync and Async modes. + * + * @example + * + * ```js + * import { useSelect, AsyncModeProvider } from '@wordpress/data'; + * + * function BlockCount() { + * const count = useSelect( ( select ) => { + * return select( 'core/block-editor' ).getBlockCount() + * } ); + * + * return count; + * } + * + * function App() { + * return ( + * <AsyncModeProvider value={ true }> + * <BlockCount /> + * </AsyncModeProvider> + * ); + * } + * ``` + * + * In this example, the BlockCount component is rerendered asynchronously. + * It means if a more critical task is being performed (like typing in an input), + * the rerendering is delayed until the browser becomes IDLE. + * It is possible to nest multiple levels of AsyncModeProvider to fine-tune the rendering behavior. + * + * @param {boolean} props.value Enable Async Mode. + * @return {WPComponent} The component to be rendered. + */ export default Provider; diff --git a/packages/data/src/index.js b/packages/data/src/index.js index 8dd6893c5d9e01..c7ad8f67a7484d 100644 --- a/packages/data/src/index.js +++ b/packages/data/src/index.js @@ -19,9 +19,7 @@ export { } from './components/registry-provider'; export { default as useSelect } from './components/use-select'; export { useDispatch } from './components/use-dispatch'; -export { - AsyncModeProvider as __experimentalAsyncModeProvider, -} from './components/async-mode-provider'; +export { AsyncModeProvider } from './components/async-mode-provider'; export { createRegistry } from './registry'; export { createRegistrySelector, createRegistryControl } from './factory'; From f1f43d827f7d91777a86c3e4a001ac7f7c824c20 Mon Sep 17 00:00:00 2001 From: Riad Benguella <benguella@gmail.com> Date: Tue, 29 Oct 2019 13:38:20 +0100 Subject: [PATCH 102/113] Make the mediaUpload block editor setting a stable API (#18156) --- .../src/components/media-placeholder/index.js | 2 +- .../block-editor/src/components/media-upload/check.js | 2 +- packages/block-library/src/audio/edit.js | 6 ++---- packages/block-library/src/file/edit.js | 4 ++-- packages/block-library/src/gallery/edit.js | 9 ++------- packages/block-library/src/image/edit.js | 4 ++-- packages/block-library/src/video/edit.js | 6 ++---- .../edit-widgets/src/components/widget-area/index.js | 2 +- packages/editor/src/components/provider/index.js | 2 +- 9 files changed, 14 insertions(+), 23 deletions(-) diff --git a/packages/block-editor/src/components/media-placeholder/index.js b/packages/block-editor/src/components/media-placeholder/index.js index d142d6d6c70008..d4e98de6179b12 100644 --- a/packages/block-editor/src/components/media-placeholder/index.js +++ b/packages/block-editor/src/components/media-placeholder/index.js @@ -429,7 +429,7 @@ const applyWithSelect = withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return { - mediaUpload: getSettings().__experimentalMediaUpload, + mediaUpload: getSettings().mediaUpload, }; } ); diff --git a/packages/block-editor/src/components/media-upload/check.js b/packages/block-editor/src/components/media-upload/check.js index 6f2903be5b1e10..c1fb3398020f4c 100644 --- a/packages/block-editor/src/components/media-upload/check.js +++ b/packages/block-editor/src/components/media-upload/check.js @@ -14,6 +14,6 @@ export default withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); return { - hasUploadPermissions: !! getSettings().__experimentalMediaUpload, + hasUploadPermissions: !! getSettings().mediaUpload, }; } )( MediaUploadCheck ); diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js index 15387acbd90c7a..b048722a70ecf7 100644 --- a/packages/block-library/src/audio/edit.js +++ b/packages/block-library/src/audio/edit.js @@ -214,10 +214,8 @@ class AudioEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { __experimentalMediaUpload } = getSettings(); - return { - mediaUpload: __experimentalMediaUpload, - }; + const { mediaUpload } = getSettings(); + return { mediaUpload }; } ), withNotices, ] )( AudioEdit ); diff --git a/packages/block-library/src/file/edit.js b/packages/block-library/src/file/edit.js index c6f6382a1336d4..503345f8b14076 100644 --- a/packages/block-library/src/file/edit.js +++ b/packages/block-library/src/file/edit.js @@ -257,11 +257,11 @@ export default compose( [ withSelect( ( select, props ) => { const { getMedia } = select( 'core' ); const { getSettings } = select( 'core/block-editor' ); - const { __experimentalMediaUpload } = getSettings(); + const { mediaUpload } = getSettings(); const { id } = props.attributes; return { media: id === undefined ? undefined : getMedia( id ), - mediaUpload: __experimentalMediaUpload, + mediaUpload, }; } ), withNotices, diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 449711a356ea42..d4f51b1565cffe 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -379,13 +379,8 @@ class GalleryEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { - __experimentalMediaUpload, - } = getSettings(); - - return { - mediaUpload: __experimentalMediaUpload, - }; + const { mediaUpload } = getSettings(); + return { mediaUpload }; } ), withNotices, ] )( GalleryEdit ); diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 897f4d1b242ec8..c5dfdc20b97148 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -930,7 +930,7 @@ export default compose( [ const { getSettings } = select( 'core/block-editor' ); const { attributes: { id }, isSelected } = props; const { - __experimentalMediaUpload, + mediaUpload, imageSizes, isRTL, maxWidth, @@ -941,7 +941,7 @@ export default compose( [ maxWidth, isRTL, imageSizes, - mediaUpload: __experimentalMediaUpload, + mediaUpload, }; } ), withViewportMatch( { isLargeViewport: 'medium' } ), diff --git a/packages/block-library/src/video/edit.js b/packages/block-library/src/video/edit.js index 6236e51a95c935..d7b3cad0592602 100644 --- a/packages/block-library/src/video/edit.js +++ b/packages/block-library/src/video/edit.js @@ -319,10 +319,8 @@ class VideoEdit extends Component { export default compose( [ withSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); - const { __experimentalMediaUpload } = getSettings(); - return { - mediaUpload: __experimentalMediaUpload, - }; + const { mediaUpload } = getSettings(); + return { mediaUpload }; } ), withNotices, withInstanceId, diff --git a/packages/edit-widgets/src/components/widget-area/index.js b/packages/edit-widgets/src/components/widget-area/index.js index e22c880f50cf22..11e162d2874d9d 100644 --- a/packages/edit-widgets/src/components/widget-area/index.js +++ b/packages/edit-widgets/src/components/widget-area/index.js @@ -42,7 +42,7 @@ function getBlockEditorSettings( blockEditorSettings, hasUploadPermissions ) { }; return { ...blockEditorSettings, - __experimentalMediaUpload: mediaUploadBlockEditor, + mediaUpload: mediaUploadBlockEditor, }; } diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index ae621e903b18d4..d38ceaa91e66d2 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -108,8 +108,8 @@ class EditorProvider extends Component { '__experimentalEnableFullSiteEditing', 'showInserterHelpPanel', ] ), + mediaUpload: hasUploadPermissions ? mediaUpload : undefined, __experimentalReusableBlocks: reusableBlocks, - __experimentalMediaUpload: hasUploadPermissions ? mediaUpload : undefined, __experimentalFetchLinkSuggestions: fetchLinkSuggestions, __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML, }; From 90342167f8f00da500ff5d5c967129d400844709 Mon Sep 17 00:00:00 2001 From: Joen Asmussen <joen@automattic.com> Date: Tue, 29 Oct 2019 14:34:24 +0100 Subject: [PATCH 103/113] Fix columns full-wide regression. (#18021) The Columns block, when full-wide, has intentional left and right padding to ensure the mover controls of child blocks are accessible. This is editor-only, and only when the block is selected. This regressed at some point, a while ago, probably around the introduction of extra on-click padding to show the dashed outlines of child elements. This PR shuffles the rules a bit, reduces some of their specificity, and applies the left and right padding elsewhere to make it work. --- .../block-library/src/columns/editor.scss | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/block-library/src/columns/editor.scss b/packages/block-library/src/columns/editor.scss index 2045a1e12e9659..60c6730fc2b088 100644 --- a/packages/block-library/src/columns/editor.scss +++ b/packages/block-library/src/columns/editor.scss @@ -12,18 +12,6 @@ } } -// Fullwide: show margin left/right to ensure there's room for the side UI. -// This is not a 1:1 preview with the front-end where these margins would presumably be zero. -[data-type="core/columns"][data-align="full"] .wp-block-columns > .editor-inner-blocks { - padding-left: $block-padding; - padding-right: $block-padding; - - @include break-small() { - padding-left: $block-container-side-padding; - padding-right: $block-container-side-padding; - } -} - .wp-block-columns { display: block; @@ -188,10 +176,10 @@ div.block-core-columns.is-vertically-aligned-bottom { /** * Add extra padding when the parent block is selected, for easier interaction. */ -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/columns"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/columns"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/column"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, -.block-editor-block-list__layout .block-editor-block-list__block[data-type="core/column"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks { +[data-type="core/columns"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +[data-type="core/columns"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +[data-type="core/column"].is-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks, +[data-type="core/column"].has-child-selected > .block-editor-block-list__block-edit > [data-block] > div > .block-editor-inner-blocks { padding: $block-padding; // Negate this padding for the placeholder. @@ -200,3 +188,16 @@ div.block-core-columns.is-vertically-aligned-bottom { width: calc(100% + #{$block-padding * 2}); } } + + +// Fullwide: show margin left/right to ensure there's room for the side UI. +// This is not a 1:1 preview with the front-end where these margins would presumably be zero. +[data-type="core/columns"][data-align="full"] .wp-block-columns { + padding-left: $block-padding; + padding-right: $block-padding; + + @include break-small() { + padding-left: $block-container-side-padding; + padding-right: $block-container-side-padding; + } +} From 1d9313025b9a147fd0a3831bcbdd53108194e52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Est=C3=AAv=C3=A3o?= <sergioestevao@gmail.com> Date: Tue, 29 Oct 2019 15:09:53 +0000 Subject: [PATCH 104/113] Resyncs RichText mobile components with web counterparts. (#17897) * Resyncs RichText mobile components with web counterparts. * Remove outdated test. * Remove unused references. * Add platform component * Add components depending of platform. Only add specific components if we are on the web implementation. * Abstract paste of files for RN and web Makes the code for pasting image more abstract in the paste method and implement specific translation to HTML depending of the platform. * Compose extra attributes/props on select/dispatch only if mobile. * Remove RN index file for RichText Wrapper. Moved all the specific code to the standard index file, so this file is no longer needed. * Remove API index native file that is no longer needed. * Clean up lint errors in file-paste-handler. * Fix lint errors. * Implement stub remove browser shortcuts for RN * Implement autocomplete stub for RN. * Refactor toolbar presentation to a method. * Remove no longer needed platform file. * Consolidate the file paste handler in a single implementation. Created a stub for createBlobURL for native that simple returns the original URL. * Change the text for platform to make it explicit it's native only. * Remove duplicate files * Include type in file comparison * Forgot to rename for native file * Fix filePasteHandler for native * Move logging back * Restore comment on logging * Add check for files existence. * Refactor format-toolbar code to use split web/native files * Remove prop duplication. * Fix getAnchorRect call * Remove unnecessary const * Sync fix for list removal of first empty line * Fix RN build after merge with master * Sync with web counterpart. * Only change selection after new formats are set. --- .../components/autocomplete/index.native.js | 1 + .../rich-text/file-paste-handler.js | 11 + .../rich-text/file-paste-handler.native.js | 3 + .../rich-text/format-toolbar-container.js | 59 ++++ .../format-toolbar-container.native.js | 16 ++ .../src/components/rich-text/index.js | 90 +++--- .../src/components/rich-text/index.native.js | 213 -------------- .../remove-browser-shortcuts.native.js | 1 + packages/blocks/src/api/index.native.js | 44 --- packages/rich-text/src/component/index.js | 26 +- .../rich-text/src/component/index.native.js | 267 ++++-------------- .../src/component/test/index.native.js | 34 --- 12 files changed, 199 insertions(+), 566 deletions(-) create mode 100644 packages/block-editor/src/components/autocomplete/index.native.js create mode 100644 packages/block-editor/src/components/rich-text/file-paste-handler.js create mode 100644 packages/block-editor/src/components/rich-text/file-paste-handler.native.js create mode 100644 packages/block-editor/src/components/rich-text/format-toolbar-container.js create mode 100644 packages/block-editor/src/components/rich-text/format-toolbar-container.native.js delete mode 100644 packages/block-editor/src/components/rich-text/index.native.js create mode 100644 packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js delete mode 100644 packages/blocks/src/api/index.native.js diff --git a/packages/block-editor/src/components/autocomplete/index.native.js b/packages/block-editor/src/components/autocomplete/index.native.js new file mode 100644 index 00000000000000..461f67a0a4bcbe --- /dev/null +++ b/packages/block-editor/src/components/autocomplete/index.native.js @@ -0,0 +1 @@ +export default () => null; diff --git a/packages/block-editor/src/components/rich-text/file-paste-handler.js b/packages/block-editor/src/components/rich-text/file-paste-handler.js new file mode 100644 index 00000000000000..eceeb069b263ff --- /dev/null +++ b/packages/block-editor/src/components/rich-text/file-paste-handler.js @@ -0,0 +1,11 @@ +/** + * WordPress dependencies + */ +import { createBlobURL } from '@wordpress/blob'; + +export function filePasteHandler( files ) { + return files + .filter( ( { type } ) => /^image\/(?:jpe?g|png|gif)$/.test( type ) ) + .map( ( file ) => `<img src="${ createBlobURL( file ) }">` ) + .join( '' ); +} diff --git a/packages/block-editor/src/components/rich-text/file-paste-handler.native.js b/packages/block-editor/src/components/rich-text/file-paste-handler.native.js new file mode 100644 index 00000000000000..41402a0dcda68c --- /dev/null +++ b/packages/block-editor/src/components/rich-text/file-paste-handler.native.js @@ -0,0 +1,3 @@ +export function filePasteHandler( files ) { + return files.map( ( url ) => `<img src="${ url }">` ).join( '' ); +} diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.js new file mode 100644 index 00000000000000..fc857311706db3 --- /dev/null +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.js @@ -0,0 +1,59 @@ +/** + * WordPress dependencies + */ +import { Popover } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import BlockFormatControls from '../block-format-controls'; +import FormatToolbar from './format-toolbar'; + +function getAnchorRect( anchorObj ) { + const { current } = anchorObj; + const rect = current.getBoundingClientRect(); + + // Add some space. + const buffer = 6; + + // Subtract padding if any. + let { paddingTop } = window.getComputedStyle( current ); + + paddingTop = parseInt( paddingTop, 10 ); + + return { + x: rect.left, + y: rect.top + paddingTop - buffer, + width: rect.width, + height: rect.height - paddingTop + buffer, + left: rect.left, + right: rect.right, + top: rect.top + paddingTop - buffer, + bottom: rect.bottom, + }; +} + +const FormatToolbarContainer = ( { inline, anchorObj } ) => { + if ( inline ) { + // Render in popover + return ( + <Popover + noArrow + position="top center" + focusOnMount={ false } + getAnchorRect={ () => getAnchorRect( anchorObj ) } + className="block-editor-rich-text__inline-format-toolbar" + > + <FormatToolbar /> + </Popover> + ); + } + // Render regular toolbar + return ( + <BlockFormatControls> + <FormatToolbar /> + </BlockFormatControls> + ); +}; + +export default FormatToolbarContainer; diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js new file mode 100644 index 00000000000000..d37fe5bfee0f68 --- /dev/null +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.native.js @@ -0,0 +1,16 @@ +/** + * Internal dependencies + */ +import BlockFormatControls from '../block-format-controls'; +import FormatToolbar from './format-toolbar'; + +const FormatToolbarContainer = () => { + // Render regular toolbar + return ( + <BlockFormatControls> + <FormatToolbar /> + </BlockFormatControls> + ); +}; + +export default FormatToolbarContainer; diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index b78e8c3a46ffc3..53292f1402d5d7 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -7,9 +7,9 @@ import { omit } from 'lodash'; /** * WordPress dependencies */ -import { RawHTML, Component, createRef } from '@wordpress/element'; +import { RawHTML, Component, createRef, Platform } from '@wordpress/element'; import { withDispatch, withSelect } from '@wordpress/data'; -import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform } from '@wordpress/blocks'; +import { pasteHandler, children as childrenSource, getBlockTransforms, findTransform, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; import { withInstanceId, compose } from '@wordpress/compose'; import { __experimentalRichText as RichText, @@ -25,8 +25,7 @@ import { toHTMLString, slice, } from '@wordpress/rich-text'; -import { withFilters, Popover } from '@wordpress/components'; -import { createBlobURL } from '@wordpress/blob'; +import { withFilters } from '@wordpress/components'; import deprecated from '@wordpress/deprecated'; import { isURL } from '@wordpress/url'; @@ -34,10 +33,10 @@ import { isURL } from '@wordpress/url'; * Internal dependencies */ import Autocomplete from '../autocomplete'; -import BlockFormatControls from '../block-format-controls'; -import FormatToolbar from './format-toolbar'; import { withBlockEditContext } from '../block-edit/context'; import { RemoveBrowserShortcuts } from './remove-browser-shortcuts'; +import { filePasteHandler } from './file-paste-handler'; +import FormatToolbarContainer from './format-toolbar-container'; const wrapperClasses = 'editor-rich-text block-editor-rich-text'; const classes = 'editor-rich-text__editable block-editor-rich-text__editable'; @@ -66,7 +65,6 @@ class RichTextWrapper extends Component { this.onPaste = this.onPaste.bind( this ); this.onDelete = this.onDelete.bind( this ); this.inputRule = this.inputRule.bind( this ); - this.getAnchorRect = this.getAnchorRect.bind( this ); } onEnter( { value, onChange, shiftKey } ) { @@ -124,7 +122,7 @@ class RichTextWrapper extends Component { } } - onPaste( { value, onChange, html, plainText, image } ) { + onPaste( { value, onChange, html, plainText, files } ) { const { onReplace, onSplit, @@ -134,16 +132,18 @@ class RichTextWrapper extends Component { __unstableEmbedURLOnPaste, } = this.props; - if ( image && ! html ) { - const file = image.getAsFile ? image.getAsFile() : image; + // Only process file if no HTML is present. + // Note: a pasted file may have the URL as plain text. + if ( files && files.length && ! html ) { const content = pasteHandler( { - HTML: `<img src="${ createBlobURL( file ) }">`, + HTML: filePasteHandler( files ), mode: 'BLOCKS', tagName, } ); // Allows us to ask for this information when we get a report. - window.console.log( 'Received item:\n\n', file ); + // eslint-disable-next-line no-console + window.console.log( 'Received items:\n\n', files ); if ( onReplace && isEmpty( value ) ) { onReplace( content ); @@ -303,30 +303,6 @@ class RichTextWrapper extends Component { return formattingControls.map( ( name ) => `core/${ name }` ); } - getAnchorRect() { - const { current } = this.ref; - const rect = current.getBoundingClientRect(); - - // Add some space. - const buffer = 6; - - // Subtract padding if any. - let { paddingTop } = window.getComputedStyle( current ); - - paddingTop = parseInt( paddingTop, 10 ); - - return { - x: rect.left, - y: rect.top + paddingTop - buffer, - width: rect.width, - height: rect.height - paddingTop + buffer, - left: rect.left, - right: rect.right, - top: rect.top + paddingTop - buffer, - bottom: rect.bottom, - }; - } - render() { const { children, @@ -424,22 +400,7 @@ class RichTextWrapper extends Component { { ( { isSelected, value, onChange, Editable } ) => <> { children && children( { value, onChange } ) } - { isSelected && ! inlineToolbar && hasFormats && ( - <BlockFormatControls> - <FormatToolbar /> - </BlockFormatControls> - ) } - { isSelected && inlineToolbar && hasFormats && ( - <Popover - noArrow - position="top center" - focusOnMount={ false } - getAnchorRect={ this.getAnchorRect } - className="block-editor-rich-text__inline-format-toolbar" - > - <FormatToolbar /> - </Popover> - ) } + { isSelected && hasFormats && ( <FormatToolbarContainer inline={ inlineToolbar } anchorObj={ this.ref } /> ) } { isSelected && <RemoveBrowserShortcuts /> } <Autocomplete onReplace={ onReplace } @@ -482,7 +443,16 @@ class RichTextWrapper extends Component { const RichTextContainer = compose( [ withInstanceId, - withBlockEditContext( ( { clientId } ) => ( { clientId } ) ), + withBlockEditContext( ( { clientId, onCaretVerticalPositionChange, isSelected }, ownProps ) => { + if ( Platform.OS === 'web' ) { + return { clientId }; + } + return { + clientId, + blockIsSelected: ownProps.isSelected !== undefined ? ownProps.isSelected : isSelected, + onCaretVerticalPositionChange, + }; + } ), withSelect( ( select, { clientId, instanceId, @@ -495,6 +465,7 @@ const RichTextContainer = compose( [ getSelectionEnd, getSettings, didAutomaticChange, + __unstableGetBlockWithoutInnerBlocks, } = select( 'core/block-editor' ); const selectionStart = getSelectionStart(); @@ -509,6 +480,18 @@ const RichTextContainer = compose( [ isSelected = selectionStart.clientId === clientId; } + let extraProps = {}; + if ( Platform.OS === 'native' ) { + // If the block of this RichText is unmodified then it's a candidate for replacing when adding a new block. + // In order to fix https://github.com/wordpress-mobile/gutenberg-mobile/issues/1126, let's blur on unmount in that case. + // This apparently assumes functionality the BlockHlder actually + const block = clientId && __unstableGetBlockWithoutInnerBlocks( clientId ); + const shouldBlurOnUnmount = block && isSelected && isUnmodifiedDefaultBlock( block ); + extraProps = { + shouldBlurOnUnmount, + }; + } + return { canUserUseUnfilteredHTML: __experimentalCanUserUseUnfilteredHTML, isCaretWithinFormattedText: isCaretWithinFormattedText(), @@ -516,6 +499,7 @@ const RichTextContainer = compose( [ selectionEnd: isSelected ? selectionEnd.offset : undefined, isSelected, didAutomaticChange: didAutomaticChange(), + ...extraProps, }; } ), withDispatch( ( dispatch, { diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js deleted file mode 100644 index feab0f747a9229..00000000000000 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { View } from 'react-native'; - -/** - * WordPress dependencies - */ -import { RawHTML } from '@wordpress/element'; -import { withDispatch, withSelect } from '@wordpress/data'; -import { pasteHandler, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; -import { withInstanceId, compose } from '@wordpress/compose'; -import { __experimentalRichText as RichText } from '@wordpress/rich-text'; - -/** - * Internal dependencies - */ -import Autocomplete from '../autocomplete'; -import BlockFormatControls from '../block-format-controls'; -import FormatToolbar from './format-toolbar'; -import { withBlockEditContext } from '../block-edit/context'; - -const wrapperClasses = 'editor-rich-text block-editor-rich-text'; -const classes = 'editor-rich-text__editable block-editor-rich-text__editable'; - -function RichTextWraper( { - children, - tagName, - value: originalValue, - onChange: originalOnChange, - selectionStart, - selectionEnd, - onSelectionChange, - multiline, - inlineToolbar, - wrapperClassName, - className, - autocompleters, - onReplace, - onRemove, - onMerge, - onSplit, - isCaretWithinFormattedText, - onEnterFormattedText, - onExitFormattedText, - canUserUseUnfilteredHTML, - isSelected: originalIsSelected, - onCreateUndoLevel, - placeholder, - // From experimental filter. - ...experimentalProps -} ) { - const adjustedValue = originalValue; - const adjustedOnChange = originalOnChange; - - return ( - <RichText - { ...experimentalProps } - value={ adjustedValue } - onChange={ adjustedOnChange } - selectionStart={ selectionStart } - selectionEnd={ selectionEnd } - onSelectionChange={ onSelectionChange } - tagName={ tagName } - wrapperClassName={ classnames( wrapperClasses, wrapperClassName ) } - className={ classnames( classes, className ) } - placeholder={ placeholder } - __unstableIsSelected={ originalIsSelected } - //__unstablePatterns={ getPatterns() } - //__unstableEnterPatterns={ getEnterPatterns() } - __unstablePasteHandler={ pasteHandler } - __unstableAutocomplete={ Autocomplete } - __unstableAutocompleters={ autocompleters } - __unstableOnReplace={ onReplace } - __unstableOnRemove={ onRemove } - __unstableOnMerge={ onMerge } - __unstableOnSplit={ onSplit } - __unstableMultiline={ multiline } - __unstableIsCaretWithinFormattedText={ isCaretWithinFormattedText } - __unstableOnEnterFormattedText={ onEnterFormattedText } - __unstableOnExitFormattedText={ onExitFormattedText } - __unstableCanUserUseUnfilteredHTML={ canUserUseUnfilteredHTML } - __unstableOnCreateUndoLevel={ onCreateUndoLevel } - > - { ( { isSelected, value, onChange } ) => - <View> - { children && children( { value, onChange } ) } - { isSelected && ! inlineToolbar && ( - <BlockFormatControls> - <FormatToolbar /> - </BlockFormatControls> - ) } - </View> - } - </RichText> - ); -} - -const RichTextContainer = compose( [ - withInstanceId, - withBlockEditContext( ( { clientId, onCaretVerticalPositionChange, isSelected }, ownProps ) => { - return { - clientId, - blockIsSelected: ownProps.isSelected !== undefined ? ownProps.isSelected : isSelected, - onCaretVerticalPositionChange, - }; - } ), - withSelect( ( select, { - clientId, - instanceId, - identifier = instanceId, - isSelected, - blockIsSelected, - } ) => { - const { getFormatTypes } = select( 'core/rich-text' ); - const { - getSelectionStart, - getSelectionEnd, - __unstableGetBlockWithoutInnerBlocks, - } = select( 'core/block-editor' ); - - const selectionStart = getSelectionStart(); - const selectionEnd = getSelectionEnd(); - - if ( isSelected === undefined ) { - isSelected = ( - selectionStart.clientId === clientId && - selectionStart.attributeKey === identifier - ); - } - - // If the block of this RichText is unmodified then it's a candidate for replacing when adding a new block. - // In order to fix https://github.com/wordpress-mobile/gutenberg-mobile/issues/1126, let's blur on unmount in that case. - // This apparently assumes functionality the BlockHlder actually - const block = clientId && __unstableGetBlockWithoutInnerBlocks( clientId ); - const shouldBlurOnUnmount = block && isSelected && isUnmodifiedDefaultBlock( block ); - - return { - formatTypes: getFormatTypes(), - selectionStart: isSelected ? selectionStart.offset : undefined, - selectionEnd: isSelected ? selectionEnd.offset : undefined, - isSelected, - blockIsSelected, - shouldBlurOnUnmount, - }; - } ), - withDispatch( ( dispatch, { - clientId, - instanceId, - identifier = instanceId, - } ) => { - const { - __unstableMarkLastChangeAsPersistent, - selectionChange, - } = dispatch( 'core/block-editor' ); - - return { - onCreateUndoLevel: __unstableMarkLastChangeAsPersistent, - onSelectionChange( start, end ) { - selectionChange( clientId, identifier, start, end ); - }, - }; - } ), -] )( RichTextWraper ); - -RichTextContainer.Content = ( { value, format, tagName: Tag, multiline, ...props } ) => { - let content; - let html = value; - let MultilineTag; - - if ( multiline === true || multiline === 'p' || multiline === 'li' ) { - MultilineTag = multiline === true ? 'p' : multiline; - } - - if ( ! html && MultilineTag ) { - html = `<${ MultilineTag }></${ MultilineTag }>`; - } - - switch ( format ) { - case 'string': - content = <RawHTML>{ html }</RawHTML>; - break; - } - - if ( Tag ) { - return <Tag { ...props }>{ content }</Tag>; - } - - return content; -}; - -RichTextContainer.isEmpty = ( value = '' ) => { - // Handle deprecated `children` and `node` sources. - if ( Array.isArray( value ) ) { - return ! value || value.length === 0; - } - - return value.length === 0; -}; - -RichTextContainer.Content.defaultProps = { - format: 'string', - value: '', -}; - -/** - * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/rich-text/README.md - */ -export default RichTextContainer; -export { RichTextShortcut } from './shortcut'; -export { RichTextToolbarButton } from './toolbar-button'; -export { __unstableRichTextInputEvent } from './input-event'; diff --git a/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js new file mode 100644 index 00000000000000..43a4b030646db4 --- /dev/null +++ b/packages/block-editor/src/components/rich-text/remove-browser-shortcuts.native.js @@ -0,0 +1 @@ +export const RemoveBrowserShortcuts = () => null; diff --git a/packages/blocks/src/api/index.native.js b/packages/blocks/src/api/index.native.js deleted file mode 100644 index b2cfd4963d2e81..00000000000000 --- a/packages/blocks/src/api/index.native.js +++ /dev/null @@ -1,44 +0,0 @@ -export { - cloneBlock, - createBlock, - switchToBlockType, -} from './factory'; -export { - default as parse, - getBlockAttributes, - parseWithAttributeSchema, -} from './parser'; -export { - default as serialize, - getBlockContent, - getBlockDefaultClassName, - getSaveContent, -} from './serializer'; -export { - registerBlockType, - unregisterBlockType, - getFreeformContentHandlerName, - setUnregisteredTypeHandlerName, - getUnregisteredTypeHandlerName, - getBlockType, - getBlockTypes, - getBlockSupport, - hasBlockSupport, - isReusableBlock, - getChildBlockNames, - hasChildBlocks, - hasChildBlocksWithInserterSupport, - setDefaultBlockName, - getDefaultBlockName, - setGroupingBlockName, -} from './registration'; -export { - isUnmodifiedDefaultBlock, - normalizeIconObject, -} from './utils'; -export { - doBlocksMatchTemplate, - synchronizeBlocksWithTemplate, -} from './templates'; -export { pasteHandler, getPhrasingContentSchema } from './raw-handling'; -export { default as children } from './children'; diff --git a/packages/rich-text/src/component/index.js b/packages/rich-text/src/component/index.js index d6a40914ea0f90..c3112d3337fb78 100644 --- a/packages/rich-text/src/component/index.js +++ b/packages/rich-text/src/component/index.js @@ -259,18 +259,32 @@ class RichText extends Component { } if ( onPaste ) { - // Only process file if no HTML is present. - // Note: a pasted file may have the URL as plain text. - const image = find( [ ...items, ...files ], ( { type } ) => - /^image\/(?:jpe?g|png|gif)$/.test( type ) - ); + files = Array.from( files ); + + Array.from( items ).forEach( ( item ) => { + if ( ! item.getAsFile ) { + return; + } + + const file = item.getAsFile(); + + if ( ! file ) { + return; + } + + const { name, type, size } = file; + + if ( ! find( files, { name, type, size } ) ) { + files.push( file ); + } + } ); onPaste( { value: this.removeEditorOnlyFormats( record ), onChange: this.onChange, html, plainText, - image, + files, } ); } } diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 09ac451ed56d23..34a1b03fe24ef2 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -30,10 +30,7 @@ import { getActiveFormat } from '../get-active-format'; import { getActiveFormats } from '../get-active-formats'; import { isEmpty, isEmptyLine } from '../is-empty'; import { create } from '../create'; -import { split } from '../split'; import { toHTMLString } from '../to-html-string'; -import { insert } from '../insert'; -import { insertLineSeparator } from '../insert-line-separator'; import { removeLineSeparator } from '../remove-line-separator'; import { isCollapsed } from '../is-collapsed'; import { remove } from '../remove'; @@ -43,28 +40,6 @@ const unescapeSpaces = ( text ) => { return text.replace( /&nbsp;|&#160;/gi, ' ' ); }; -/** - * Calls {@link pasteHandler} with a fallback to plain text when HTML processing - * results in errors - * - * @param {Function} originalPasteHandler The original handler function - * @param {Object} [options] The options to pass to {@link pasteHandler} - * - * @return {Array|string} A list of blocks or a string, depending on - * `handlerMode`. - */ -const saferPasteHandler = ( originalPasteHandler, options ) => { - try { - return originalPasteHandler( options ); - } catch ( error ) { - window.console.log( 'Pasting HTML failed:', error ); - window.console.log( 'HTML:', options.HTML ); - window.console.log( 'Falling back to plain text.' ); - // fallback to plain text - return originalPasteHandler( { ...options, HTML: '' } ); - } -}; - const gutenbergFormatNamesToAztec = { 'core/bold': 'bold', 'core/italic': 'italic', @@ -72,7 +47,7 @@ const gutenbergFormatNamesToAztec = { }; export class RichText extends Component { - constructor( { value, __unstableMultiline: multiline, selectionStart, selectionEnd } ) { + constructor( { value, selectionStart, selectionEnd, __unstableMultilineTag: multiline } ) { super( ...arguments ); this.isMultiline = false; @@ -84,12 +59,12 @@ export class RichText extends Component { if ( this.multilineTag === 'li' ) { this.multilineWrapperTags = [ 'ul', 'ol' ]; } - this.onSplit = this.onSplit.bind( this ); + this.isIOS = Platform.OS === 'ios'; this.createRecord = this.createRecord.bind( this ); this.onChange = this.onChange.bind( this ); - this.onEnter = this.onEnter.bind( this ); - this.onBackspace = this.onBackspace.bind( this ); + this.handleEnter = this.handleEnter.bind( this ); + this.handleDelete = this.handleDelete.bind( this ); this.onPaste = this.onPaste.bind( this ); this.onFocus = this.onFocus.bind( this ); this.onBlur = this.onBlur.bind( this ); @@ -169,63 +144,6 @@ export class RichText extends Component { return { ...value, start, end }; } - /** - * Signals to the RichText owner that the block can be replaced with two - * blocks as a result of splitting the block by pressing enter, or with - * blocks as a result of splitting the block by pasting block content in the - * instance. - * - * @param {Object} record The rich text value to split. - * @param {Array} pastedBlocks The pasted blocks to insert, if any. - */ - onSplit( record, pastedBlocks = [] ) { - const { - __unstableOnReplace: onReplace, - __unstableOnSplit: onSplit, - __unstableOnSplitMiddle: onSplitMiddle, - } = this.props; - - if ( ! onReplace || ! onSplit ) { - return; - } - - const blocks = []; - const [ before, after ] = split( record ); - const hasPastedBlocks = pastedBlocks.length > 0; - - // Create a block with the content before the caret if there's no pasted - // blocks, or if there are pasted blocks and the value is not empty. - // We do not want a leading empty block on paste, but we do if split - // with e.g. the enter key. - if ( ! hasPastedBlocks || ! isEmpty( before ) ) { - blocks.push( onSplit( this.valueToFormat( before ) ) ); - } - - if ( hasPastedBlocks ) { - blocks.push( ...pastedBlocks ); - } else if ( onSplitMiddle ) { - blocks.push( onSplitMiddle() ); - } - - // If there's pasted blocks, append a block with the content after the - // caret. Otherwise, do append and empty block if there is no - // `onSplitMiddle` prop, but if there is and the content is empty, the - // middle block is enough to set focus in. - if ( hasPastedBlocks || ! onSplitMiddle || ! isEmpty( after ) ) { - blocks.push( onSplit( this.valueToFormat( after ) ) ); - } - - // If there are pasted blocks, set the selection to the last one. - // Otherwise, set the selection to the second block. - const indexToSelect = hasPastedBlocks ? blocks.length - 1 : 1; - // The onSplit event can cause a content update event for this block. Such event should - // definitely be processed by our native components, since they have no knowledge of - // how the split works. Setting lastEventCount to undefined forces the native component to - // always update when provided with new content. - this.lastEventCount = undefined; - onReplace( blocks, indexToSelect ); - } - valueToFormat( value ) { // remove the outer root tags return this.removeRootTagsProduceByAztec( toHTMLString( { @@ -245,6 +163,7 @@ export class RichText extends Component { } onFormatChange( record ) { + this.getRecord( record ); const { start, end, activeFormats = [] } = record; const changeHandlers = pickBy( this.props, ( v, key ) => key.startsWith( 'format_on_change_functions_' ) @@ -346,92 +265,67 @@ export class RichText extends Component { this.lastAztecEventType = 'content size change'; } - onEnter( event ) { - if ( this.props.onEnter ) { - this.props.onEnter(); + handleEnter( event ) { + const { onEnter } = this.props; + + if ( ! onEnter ) { return; } - const { - __unstableOnReplace: onReplace, - __unstableOnSplit: onSplit, - } = this.props; - this.lastEventCount = event.nativeEvent.eventCount; - this.comesFromAztec = true; - this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; - - const canSplit = onReplace && onSplit; - const currentRecord = this.createRecord(); - if ( this.multilineTag ) { - if ( event.shiftKey ) { - this.needsSelectionUpdate = true; - const insertedLineBreak = { ...insert( currentRecord, '\n' ) }; - this.onFormatChange( insertedLineBreak ); - } else if ( canSplit && isEmptyLine( currentRecord ) ) { - this.onSplit( currentRecord ); - } else { - this.needsSelectionUpdate = true; - const insertedLineSeparator = { ...insertLineSeparator( currentRecord ) }; - this.onFormatChange( insertedLineSeparator ); - } - } else if ( event.shiftKey || ! onSplit ) { - this.needsSelectionUpdate = true; - const insertedLineBreak = { ...insert( currentRecord, '\n' ) }; - this.onFormatChange( insertedLineBreak ); - } else { - this.onSplit( currentRecord ); - } + onEnter( { + value: this.createRecord(), + onChange: this.onFormatChange, + shiftKey: event.shiftKey, + } ); this.lastAztecEventType = 'input'; } - onBackspace( event ) { - const { - __unstableOnMerge: onMerge, - __unstableOnRemove: onRemove, - onChange, - } = this.props; - if ( ! onMerge && ! onRemove ) { - return; - } - + handleDelete( event ) { const keyCode = BACKSPACE; // TODO : should we differentiate BACKSPACE and DELETE? const isReverse = keyCode === BACKSPACE; + const { onDelete, __unstableMultilineTag: multilineTag } = this.props; + const { activeFormats = [] } = this.state; this.lastEventCount = event.nativeEvent.eventCount; this.comesFromAztec = true; this.firedAfterTextChanged = event.nativeEvent.firedAfterTextChanged; const value = this.createRecord(); - const { start, end } = value; + const { start, end, text } = value; let newValue; // Always handle full content deletion ourselves. - if ( start === 0 && end !== 0 && end >= value.text.length ) { - newValue = remove( value, start, end ); - onChange( newValue ); + if ( start === 0 && end !== 0 && end >= text.length ) { + newValue = remove( value ); + this.onFormatChange( newValue ); + event.preventDefault(); return; } - if ( this.multilineTag ) { - newValue = removeLineSeparator( value, keyCode === BACKSPACE ); + if ( multilineTag ) { + if ( isReverse && value.start === 0 && value.end === 0 && isEmptyLine( value ) ) { + newValue = removeLineSeparator( value, ! isReverse ); + } else { + newValue = removeLineSeparator( value, isReverse ); + } if ( newValue ) { this.onFormatChange( newValue ); + event.preventDefault(); return; } } - const empty = this.isEmpty(); - - if ( onMerge ) { - onMerge( ! isReverse ); + // Only process delete if the key press occurs at an uncollapsed edge. + if ( + ! onDelete || + ! isCollapsed( value ) || + activeFormats.length || + ( isReverse && start !== 0 ) || + ( ! isReverse && end !== text.length ) + ) { + return; } - // Only handle remove on Backspace. This serves dual-purpose of being - // an intentional user interaction distinguishing between Backspace and - // Delete to remove the empty field, but also to avoid merge & remove - // causing destruction of two fields (merge, then removed merged). - if ( onRemove && empty && isReverse ) { - onRemove( ! isReverse ); - } + onDelete( { isReverse, value } ); event.preventDefault(); this.lastAztecEventType = 'input'; @@ -444,10 +338,7 @@ export class RichText extends Component { */ onPaste( event ) { const { - tagName, - __unstablePasteHandler: pasteHandler, - __unstableOnReplace: onReplace, - __unstableOnSplit: onSplit, + onPaste, onChange, } = this.props; @@ -456,30 +347,6 @@ export class RichText extends Component { event.preventDefault(); - // Only process file if no HTML is present. - // Note: a pasted file may have the URL as plain text. - if ( files && files.length > 0 ) { - const uploadId = Number.MAX_SAFE_INTEGER; - let html = ''; - files.forEach( ( file ) => { - html += `<img src="${ file }" class="wp-image-${ uploadId }">`; - } ); - const content = pasteHandler( { - HTML: html, - mode: 'BLOCKS', - tagName, - } ); - const shouldReplace = onReplace && this.isEmpty(); - - if ( shouldReplace ) { - onReplace( content ); - } else { - this.onSplit( currentRecord, content ); - } - - return; - } - // There is a selection, check if a URL is pasted. if ( ! isCollapsed( currentRecord ) ) { const trimmedText = ( pastedHtml || pastedText ).replace( /<[^>]+>/g, '' ) @@ -503,46 +370,14 @@ export class RichText extends Component { } } - const shouldReplace = this.props.onReplace && this.isEmpty(); - - let mode = 'INLINE'; - - if ( shouldReplace ) { - mode = 'BLOCKS'; - } else if ( onSplit ) { - mode = 'AUTO'; - } - - const pastedContent = saferPasteHandler( pasteHandler, { - HTML: pastedHtml, - plainText: pastedText, - mode, - tagName: this.props.tagName, - canUserUseUnfilteredHTML: this.props.canUserUseUnfilteredHTML, - } ); - - if ( typeof pastedContent === 'string' ) { - const recordToInsert = create( { html: pastedContent } ); - const resultingRecord = insert( currentRecord, recordToInsert ); - const resultingContent = this.valueToFormat( resultingRecord ); - - this.lastEventCount = undefined; - this.value = resultingContent; - - // explicitly set selection after inline paste - this.onSelectionChange( resultingRecord.start, resultingRecord.end ); - - onChange( this.value ); - } else if ( onSplit ) { - if ( ! pastedContent.length ) { - return; - } - - if ( shouldReplace ) { - onReplace( pastedContent ); - } else { - this.onSplit( currentRecord, pastedContent ); - } + if ( onPaste ) { + onPaste( { + value: currentRecord, + onChange: this.onFormatChange, + html: pastedHtml, + plainText: pastedText, + files, + } ); } } @@ -759,7 +594,7 @@ export class RichText extends Component { this.lastEventCount = undefined; // force a refresh on the native side value = ''; } - // On android if content is empty we need to send no content or else the placeholder with not show. + // On android if content is empty we need to send no content or else the placeholder will not show. if ( ! this.isIOS && value === '' ) { return value; } @@ -852,8 +687,8 @@ export class RichText extends Component { onChange={ this.onChange } onFocus={ this.onFocus } onBlur={ this.onBlur } - onEnter={ this.onEnter } - onBackspace={ this.onBackspace } + onEnter={ this.handleEnter } + onBackspace={ this.handleDelete } onPaste={ this.onPaste } activeFormats={ this.getActiveFormatNames( record ) } onContentSizeChange={ this.onContentSizeChange } diff --git a/packages/rich-text/src/component/test/index.native.js b/packages/rich-text/src/component/test/index.native.js index 6b2bc12f855ffa..22ee6b118bb2d2 100644 --- a/packages/rich-text/src/component/test/index.native.js +++ b/packages/rich-text/src/component/test/index.native.js @@ -1,17 +1,8 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - /** * Internal dependencies */ import { RichText } from '../index'; -const getStylesFromColorScheme = () => { - return { color: 'white' }; -}; - describe( 'RichText Native', () => { let richText; @@ -33,29 +24,4 @@ describe( 'RichText Native', () => { expect( richText.willTrimSpaces( html ) ).toBe( false ); } ); } ); - - describe( 'Adds new line on Enter', () => { - let newValue; - const wrapper = shallow( <RichText - rootTagsToEliminate={ [ 'p' ] } - value="" - onChange={ ( value ) => { - newValue = value; - } } - formatTypes={ [] } - onSelectionChange={ jest.fn() } - getStylesFromColorScheme={ getStylesFromColorScheme } - /> ); - - const event = { - nativeEvent: { - eventCount: 0, - }, - }; - wrapper.instance().onEnter( event ); - - it( ' Adds <br> tag to content after pressing Enter key', () => { - expect( newValue ).toEqual( '<br>' ); - } ); - } ); } ); From a9cfa56e6caeaac67d11d4fa0328780110e91124 Mon Sep 17 00:00:00 2001 From: Maxime Biais <maxime.biais@gmail.com> Date: Tue, 29 Oct 2019 18:20:49 +0100 Subject: [PATCH 105/113] [RNMobile] Add a subtitle for unsupported blocks (#18107) * Add a new unsupported subtitle to missing blocks - even we know about the block title * Update margins, colors and font weight of the unsupported block --- packages/block-library/src/missing/edit.native.js | 4 ++++ .../block-library/src/missing/style.native.scss | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index cd4898a4e8c692..0aa4c3436d7dfe 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -27,6 +27,9 @@ export class UnsupportedBlockEdit extends Component { const title = blockType ? blockType.settings.title : __( 'Unsupported' ); const titleStyle = getStylesFromColorScheme( styles.unsupportedBlockMessage, styles.unsupportedBlockMessageDark ); + const subTitleStyle = getStylesFromColorScheme( styles.unsupportedBlockSubtitle, styles.unsupportedBlockSubtitleDark ); + const subtitle = blockType ? <Text style={ subTitleStyle }>{ __( 'Unsupported' ) }</Text> : null; + const icon = blockType ? normalizeIconObject( blockType.settings.icon ) : 'admin-plugins'; const iconStyle = getStylesFromColorScheme( styles.unsupportedBlockIcon, styles.unsupportedBlockIconDark ); const iconClassName = 'unsupported-icon' + '-' + preferredColorScheme; @@ -34,6 +37,7 @@ export class UnsupportedBlockEdit extends Component { <View style={ getStylesFromColorScheme( styles.unsupportedBlock, styles.unsupportedBlockDark ) }> <Icon className={ iconClassName } icon={ icon && icon.src ? icon.src : icon } color={ iconStyle.color } /> <Text style={ titleStyle }>{ title }</Text> + { subtitle } </View> ); } diff --git a/packages/block-library/src/missing/style.native.scss b/packages/block-library/src/missing/style.native.scss index 63cd4258cd23b0..5967ceb1e4d9fe 100644 --- a/packages/block-library/src/missing/style.native.scss +++ b/packages/block-library/src/missing/style.native.scss @@ -27,12 +27,24 @@ } .unsupportedBlockMessage { - margin-top: 2; + margin-top: 4; text-align: center; color: $gray-dark; font-size: 14; + font-weight: 600; } .unsupportedBlockMessageDark { color: $white; } + +.unsupportedBlockSubtitle { + margin-top: 2; + text-align: center; + color: $gray-darken-20; + font-size: 12; +} + +.unsupportedBlockSubtitleDark { + color: $gray-20; +} From 57197b6c15939605ce60cb31b6686cd1233efe22 Mon Sep 17 00:00:00 2001 From: "Michael P. Pfeiffer" <frontdevde@users.noreply.github.com> Date: Tue, 29 Oct 2019 18:21:56 +0100 Subject: [PATCH 106/113] Navigation: Explore default frontend styles (#18094) * try basic version of varia theme styles as default * Add class to show submenu indicator * adjustments for small viewports --- .../src/navigation-menu/style.scss | 119 ++++++++++++++++++ packages/block-library/src/style.scss | 1 + 2 files changed, 120 insertions(+) create mode 100644 packages/block-library/src/navigation-menu/style.scss diff --git a/packages/block-library/src/navigation-menu/style.scss b/packages/block-library/src/navigation-menu/style.scss new file mode 100644 index 00000000000000..3c2222ef59f252 --- /dev/null +++ b/packages/block-library/src/navigation-menu/style.scss @@ -0,0 +1,119 @@ +.wp-block-navigation-menu { + + & > ul { + display: block; + list-style: none; + margin: 0; + max-width: none; + padding-left: 0; + position: relative; + + @include break-small { + display: flex; + flex-wrap: wrap; + } + + ul { + padding-left: 0; + } + + li { + position: relative; + z-index: 1; + + &:hover, + &:focus-within { + cursor: pointer; + z-index: 99999; + } + + // Submenu Display + &:hover > ul, + &:focus-within > ul, + & ul:hover, + & ul:focus { + visibility: visible; + opacity: 1; + display: block; + } + } + + & > li { + + & > a { + padding-left: 0; + + @include break-small { + padding-left: 16px; + } + } + + &:first-of-type > a { + padding-left: 0; + } + + &:last-of-type > a { + padding-right: 0; + } + } + + // Sub-menus Flyout + & > li > ul { + margin: 0; + position: absolute; + background: #fff; + box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.2); + left: 0; + top: 100%; + min-width: max-content; + opacity: 0; + transition: all 0.5s ease; + visibility: hidden; + + ul { + width: 100%; + } + } + } + + // Menu Link + a { + display: block; + padding: 16px; + } + + // Sub-menu depth indicators + ul ul { + + list-style: none; + margin-left: 0; + // Reset the counter for each UL + counter-reset: nested-list; + + li a { + + padding-top: 8px; + padding-bottom: 8px; + + &::before { + // Increment the dashes + counter-increment: nested-list; + // Insert dashes with spaces in between + content: "\2013\00a0" counters(nested-list, "\2013\00a0", none); + } + } + } + + // Top-level sub-menu indicators + & .has-sub-menu > a { + + &::after { + content: "\00a0\25BC"; + display: inline-block; + font-size: 0.6rem; + height: inherit; + width: inherit; + } + } + +} diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index d32050bfd1c4b9..3fd7e3c2b8e041 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -11,6 +11,7 @@ @import "./latest-comments/style.scss"; @import "./latest-posts/style.scss"; @import "./media-text/style.scss"; +@import "./navigation-menu/style.scss"; @import "./paragraph/style.scss"; @import "./pullquote/style.scss"; @import "./quote/style.scss"; From f558ed79e68014880cabfc41d43c50f51e118752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= <rdsuarez@gmail.com> Date: Tue, 29 Oct 2019 14:43:31 -0300 Subject: [PATCH 107/113] NavigationMenu: set attributes rightly (#18150) * navigation-menu: set attributes once * navigation-menu: add CSS class as hook dependencies * Update packages/block-library/src/navigation-menu/edit.js Co-Authored-By: Enrique Piqueras <epiqueras@users.noreply.github.com> --- .../block-library/src/navigation-menu/edit.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/block-library/src/navigation-menu/edit.js b/packages/block-library/src/navigation-menu/edit.js index b89afeff3863c8..fdb6fd7c2fa4db 100644 --- a/packages/block-library/src/navigation-menu/edit.js +++ b/packages/block-library/src/navigation-menu/edit.js @@ -9,6 +9,7 @@ import classnames from 'classnames'; import { Fragment, useMemo, + useEffect, } from '@wordpress/element'; import { InnerBlocks, @@ -79,7 +80,7 @@ function NavigationMenu( { * Set the color type according to the given values. * It propagate the color values into the attributes object. * Both `backgroundColorValue` and `textColorValue` are - * using the apply inline styles. + * using the inline styles. * * @param {Object} colorsData Arguments passed by BlockColorsStyleSelector onColorChange. * @param {string} colorsData.attr Color attribute. @@ -99,11 +100,13 @@ function NavigationMenu( { } }; - // Set/Unset colors CSS classes. - setAttributes( { - backgroundColorCSSClass: backgroundColor.class ? backgroundColor.class : null, - textColorCSSClass: textColor.class ? textColor.class : null, - } ); + useEffect( () => { + // Set/Unset colors CSS classes. + setAttributes( { + backgroundColorCSSClass: backgroundColor.class ? backgroundColor.class : null, + textColorCSSClass: textColor.class ? textColor.class : null, + } ); + }, [ backgroundColor.class, textColor.class ] ); return ( <Fragment> From 3e5f7a5999aa846fa2bed2f6dbddd6cb78b189ef Mon Sep 17 00:00:00 2001 From: Jorge Costa <jorge.costa@automattic.com> Date: Tue, 29 Oct 2019 17:59:01 +0000 Subject: [PATCH 108/113] Update packages/block-editor/src/components/colors/use-colors.js (#18147) Co-Authored-By: Enrique Piqueras <epiqueras@users.noreply.github.com> (+2 squashed commits) Squashed commits: [36484b4d3f] Update packages/block-editor/src/components/colors/use-colors.js Co-Authored-By: Enrique Piqueras <epiqueras@users.noreply.github.com> [9c4c7694bd] Fix: solve some issues in useColors hook --- .../src/components/colors/use-colors.js | 77 ++++++++++++------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/packages/block-editor/src/components/colors/use-colors.js b/packages/block-editor/src/components/colors/use-colors.js index ee3f37c8b00bf7..d69ee1bdbadf9a 100644 --- a/packages/block-editor/src/components/colors/use-colors.js +++ b/packages/block-editor/src/components/colors/use-colors.js @@ -2,7 +2,13 @@ * External dependencies */ import memoize from 'memize'; -import { kebabCase, camelCase, startCase } from 'lodash'; +import classnames from 'classnames'; +import { + camelCase, + kebabCase, + map, + startCase, +} from 'lodash'; /** * WordPress dependencies @@ -35,17 +41,17 @@ const ColorPanel = ( { <PanelColorSettings title={ title } initialOpen={ false } - colorSettings={ colorSettings } + colorSettings={ Object.values( colorSettings ) } { ...colorPanelProps } > { contrastCheckerProps && - components.map( ( Component, index ) => ( + map( components, ( ( Component, key ) => ( <ContrastChecker - key={ Component.displayName } - textColor={ colorSettings[ index ].value } + key={ key } + textColor={ colorSettings[ key ].value } { ...contrastCheckerProps } /> - ) ) } + ) ) ) } { typeof panelChildren === 'function' ? panelChildren( components ) : panelChildren } @@ -89,24 +95,35 @@ export default function __experimentalUseColors( const createComponent = useMemo( () => memoize( - ( property, color, colorValue, customColor ) => ( { children } ) => + ( name, property, className, color, colorValue, customColor ) => ( { + children, + className: componentClassName = '', + style: componentStyle = {}, + } ) => // Clone children, setting the style property from the color configuration, // if not already set explicitly through props. Children.map( children, ( child ) => { - let className = child.props.className; - let style = child.props.style; + let colorStyle = {}; if ( color ) { - className = `${ child.props.className } has-${ kebabCase( - color - ) }-${ kebabCase( property ) }`; - style = { [ property ]: colorValue, ...child.props.style }; + colorStyle = { [ property ]: colorValue }; } else if ( customColor ) { - className = `${ child.props.className } has-${ kebabCase( property ) }`; - style = { [ property ]: customColor, ...child.props.style }; + colorStyle = { [ property ]: customColor }; } + return cloneElement( child, { - className, - style, + className: classnames( + componentClassName, + child.props.className, + { + [ `has-${ kebabCase( color ) }-${ kebabCase( property ) }` ]: color, + [ className || `has-${ kebabCase( name ) }` ]: color || customColor, + } + ), + style: { + ...colorStyle, + ...componentStyle, + ...( child.props.style || {} ), + }, } ); } ), { maxSize: colorConfigs.length } @@ -135,7 +152,7 @@ export default function __experimentalUseColors( ); return useMemo( () => { - const colorSettings = []; + const colorSettings = {}; const components = colorConfigs.reduce( ( acc, colorConfig ) => { if ( typeof colorConfig === 'string' ) { @@ -144,6 +161,7 @@ export default function __experimentalUseColors( const { name, // E.g. 'backgroundColor'. property = name, // E.g. 'backgroundColor'. + className, panelLabel = startCase( name ), // E.g. 'Background Color'. componentName = panelLabel.replace( /\s/g, '' ), // E.g. 'BackgroundColor'. @@ -159,7 +177,9 @@ export default function __experimentalUseColors( // when they are used as props for other components. const _color = colors.find( ( __color ) => __color.slug === color ); acc[ componentName ] = createComponent( + name, property, + className, color, _color && _color.color, attributes[ camelCase( `custom ${ name }` ) ] @@ -168,21 +188,20 @@ export default function __experimentalUseColors( acc[ componentName ].color = color; acc[ componentName ].setColor = createSetColor( name, colors ); - const newSettingIndex = - colorSettings.push( { - value: _color ? - _color.color : - attributes[ camelCase( `custom ${ name }` ) ], - onChange: acc[ componentName ].setColor, - label: panelLabel, - colors, - } ) - 1; + colorSettings[ componentName ] = { + value: _color ? + _color.color : + attributes[ camelCase( `custom ${ name }` ) ], + onChange: acc[ componentName ].setColor, + label: panelLabel, + colors, + }; // These settings will be spread over the `colors` in // `colorPanelProps`, so we need to unset the key here, // if not set to an actual value, to avoid overwriting // an actual value in `colorPanelProps`. if ( ! colors ) { - delete colorSettings[ newSettingIndex ].colors; + delete colorSettings[ componentName ].colors; } return acc; @@ -193,7 +212,7 @@ export default function __experimentalUseColors( colorSettings, colorPanelProps, contrastCheckerProps, - components: Object.values( components ), + components, panelChildren, }; return { From caa80cb0d298f4792f973a0eaa16b54d2a44da6b Mon Sep 17 00:00:00 2001 From: Marko Savic <savicmarko1985@gmail.com> Date: Tue, 29 Oct 2019 20:03:04 +0100 Subject: [PATCH 109/113] [RNMobile] Added support for giphy and pexels images (#18026) --- .../components/media-upload/index.native.js | 35 ++++++++++++++++++- .../src/image/styles.native.scss | 10 ++++++ .../src/media-text/media-container.native.js | 4 ++- .../src/media-text/style.native.scss | 6 ++++ test/native/setup.js | 2 ++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/media-upload/index.native.js b/packages/block-editor/src/components/media-upload/index.native.js index 77f125fb35f91a..2e1c3a9fcd8010 100644 --- a/packages/block-editor/src/components/media-upload/index.native.js +++ b/packages/block-editor/src/components/media-upload/index.native.js @@ -6,6 +6,8 @@ import { requestMediaPickFromMediaLibrary, requestMediaPickFromDeviceLibrary, requestMediaPickFromDeviceCamera, + getOtherMediaOptions, + requestOtherMediaPickFrom, } from 'react-native-gutenberg-bridge'; /** @@ -31,7 +33,27 @@ export class MediaUpload extends React.Component { this.onPickerPresent = this.onPickerPresent.bind( this ); this.onPickerChange = this.onPickerChange.bind( this ); this.onPickerSelect = this.onPickerSelect.bind( this ); + + this.state = { + otherMediaOptions: undefined, + }; + } + + componentDidMount() { + const { allowedTypes = [] } = this.props; + getOtherMediaOptions( allowedTypes, ( otherMediaOptions ) => { + const otherMediaOptionsWithIcons = otherMediaOptions.map( ( option ) => { + return { + icon: this.getChooseFromDeviceIcon(), + value: option.value, + label: option.label, + }; + } ); + + this.setState( { otherMediaOptions: otherMediaOptionsWithIcons } ); + } ); } + getTakeMediaLabel() { const { allowedTypes = [] } = this.props; @@ -98,11 +120,22 @@ export class MediaUpload extends React.Component { this.onPickerSelect( requestMediaPickFromDeviceCamera ); } else if ( value === MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_WORD_PRESS_LIBRARY ) { this.onPickerSelect( requestMediaPickFromMediaLibrary ); + } else { + const { onSelect, multiple = false } = this.props; + requestOtherMediaPickFrom( value, multiple, ( media ) => { + if ( ( multiple && media ) || ( media && media.id ) ) { + onSelect( media ); + } + } ); } } render() { - const mediaOptions = this.getMediaOptionsItems(); + let mediaOptions = this.getMediaOptionsItems(); + + if ( this.state.otherMediaOptions ) { + mediaOptions = [ ...mediaOptions, ...this.state.otherMediaOptions ]; + } const getMediaOptions = () => ( <Picker diff --git a/packages/block-library/src/image/styles.native.scss b/packages/block-library/src/image/styles.native.scss index 731e7e9e26312c..24b20de69dc8f8 100644 --- a/packages/block-library/src/image/styles.native.scss +++ b/packages/block-library/src/image/styles.native.scss @@ -40,3 +40,13 @@ .iconDark { fill: $white; } + +.content { + flex: 1; +} + +.contentCentered { + flex: 1; + justify-content: center; + align-items: center; +} diff --git a/packages/block-library/src/media-text/media-container.native.js b/packages/block-library/src/media-text/media-container.native.js index 39ff78799b14f5..84d2c6dc836bde 100644 --- a/packages/block-library/src/media-text/media-container.native.js +++ b/packages/block-library/src/media-text/media-container.native.js @@ -161,6 +161,8 @@ class MediaContainer extends Component { const { finalWidth, finalHeight, imageWidthWithinContainer, isUploadFailed, retryMessage } = params; const opacity = isUploadInProgress ? 0.3 : 1; + const contentStyle = ! imageWidthWithinContainer ? styles.content : styles.contentCentered; + return ( <TouchableWithoutFeedback accessible={ ! isSelected } @@ -168,7 +170,7 @@ class MediaContainer extends Component { onLongPress={ openMediaOptions } disabled={ ! isSelected } > - <View style={ styles.content }> + <View style={ contentStyle }> { ! imageWidthWithinContainer && <View style={ styles.imageContainer }> { this.getIcon( false ) } diff --git a/packages/block-library/src/media-text/style.native.scss b/packages/block-library/src/media-text/style.native.scss index 06d29dc715dab7..27c972f6f8d6e7 100644 --- a/packages/block-library/src/media-text/style.native.scss +++ b/packages/block-library/src/media-text/style.native.scss @@ -32,6 +32,12 @@ flex: 1; } +.contentCentered { + flex: 1; + justify-content: center; + align-items: center; +} + .imageContainer { align-items: center; background-color: $gray-lighten-30; diff --git a/test/native/setup.js b/test/native/setup.js index 60fe7194c0aa60..f1e507f38ba399 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -19,6 +19,8 @@ jest.mock( 'react-native-gutenberg-bridge', () => { requestMediaPickFromMediaLibrary: jest.fn(), requestMediaPickFromDeviceLibrary: jest.fn(), requestMediaPickFromDeviceCamera: jest.fn(), + getOtherMediaOptions: jest.fn(), + requestOtherMediaPickFrom: jest.fn(), }; } ); From 3ecf70171dd5522f1686acae4902ed465f514ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= <grzegorz@gziolo.pl> Date: Tue, 29 Oct 2019 23:37:35 +0100 Subject: [PATCH 110/113] Scripts: Bump the version of npm-package-json-lint (#18160) --- package-lock.json | 8 ++++---- packages/scripts/CHANGELOG.md | 2 +- packages/scripts/package.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index cfab06638c2fda..e5e1f5810d7b10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7850,7 +7850,7 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^4.0.2", + "npm-package-json-lint": "^4.0.3", "puppeteer": "^1.20.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", @@ -24343,9 +24343,9 @@ } }, "npm-package-json-lint": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-4.0.2.tgz", - "integrity": "sha512-xlahvfRgZcsawUPzKaJvcQSs4K0EzDgQ9YEe7VODo1XbLMWwS0IEXiywHlKPAvo1fmWBvovIdoAqhe0Gk4InHA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-4.0.3.tgz", + "integrity": "sha512-cuvTR2l5dOjjlRR3a1CCp+mh2A2HyQRxydwdcYi0Z77NRlADpf7wF3Jf8XFLGZM7J6afXNRBofBjQ1UWFyOtKA==", "dev": true, "requires": { "ajv": "^6.10.2", diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 17d28946b2bc0d..66d7acb086a16b 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,7 +2,7 @@ ### Breaking Changes -- The bundled `npm-package-json-lint` dependency has been updated from requiring `^3.6.0` to requiring `^4.0.2` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). Please see the [migration guide](https://npmpackagejsonlint.org/docs/en/v3-to-v4). Note: `npmPackageJsonLintConfig` prop in the `package.json` file needs to be renamed to `npmpackagejsonlint`. +- The bundled `npm-package-json-lint` dependency has been updated from requiring `^3.6.0` to requiring `^4.0.3` ([#18054](https://github.com/WordPress/gutenberg/pull/18054)). Please see the [migration guide](https://npmpackagejsonlint.org/docs/en/v3-to-v4). Note: `npmPackageJsonLintConfig` prop in the `package.json` file needs to be renamed to `npmpackagejsonlint`. ### New Features diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 20c95f9782c61d..cc64a8fb5a713d 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -50,7 +50,7 @@ "js-yaml": "^3.13.1", "lodash": "^4.17.15", "minimist": "^1.2.0", - "npm-package-json-lint": "^4.0.2", + "npm-package-json-lint": "^4.0.3", "puppeteer": "^1.20.0", "read-pkg-up": "^1.0.1", "request": "^2.88.0", From c04639e519e538a20059d8a22b60974c7ef589b2 Mon Sep 17 00:00:00 2001 From: Dave Smith <getdavemail@gmail.com> Date: Wed, 30 Oct 2019 04:21:33 +0000 Subject: [PATCH 111/113] Experimental Link creation interface (#17846) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial component file structure * Implement basic icon and toggle mechanic * Adds basic search input * Update input to utilise LinkEditor component autocomplete * Add ability to customise placeholder * Update to utilise URLInput directly for greater flexibility * Add example search results and test coverage * Update class naming convention to match guidelines See https://github.com/WordPress/gutenberg/blob/master/docs/contributors/coding-guidelines.md#css Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r332567521 * Adds render prop to enable custom suggestions rendering Previously it wasn’t possible to customise the render of the search suggestions. By providing an optional render prop we now have full control over this if required. * Update to utilise URLInput render prop to customise search suggestions render Previously we relied on our own render of suggestions but this wasn’t hooked up to all the accessibility enhancements afforded by URLInput. By utilising the render prop exposed by URLInput to customise the rendering of suggestions, we can have the best of both worlds. * Update to add post type to the fetchLinkSuggestions responsive mapping This is required to display the type of entitity in the search results for LinkControl * Fix to ensure search suggestion interaction states are perceivable * Update suggestion render prop to provide component props as arguments Previously when using the `renderSuggestions` render prop the user had to know how to put together the correct props on the correct elements in their custom render. By passing the default props for the listing element and the item element we can relieve the user of this burden by allowing them to spread the props onto the appropriate elements in their render without having to know how they are created. * Update to match with design visual and provide more accessible markup * Adds settings area. Fixes missing reset icon. * Fix search items to be buttons with correct style and layout * Adds overflow scrolling to search results * Fix to stop scroll shadow overlaying scrollbars * Add bespoke settings area and tweak styles * Update to allow URLs to be conditionally handled as a suggestion Previously when a URL was entered it was deemed that no suggestions should or could be found and so the process of fetching suggestions was short circuited. Add additional prop to optionally allow developers to have URL-like values handled as suggestions. * Updates to conditionally use an entity or url based search results fetcher If the current value of the input is a URL then we conditionally pass a different handler for search results to the URLInput component. For URL based values we immediately return a “suggestion” object with values matching those entered by the user. Non URL based values are handled as previously. * Fix bug whereby fetchSearchSuggestions wasn’t called Remove ambiguity by calling the search handler directly rather than proxying through another function and having to apply it immediately. * Remove default toggle UI and implement Popover close The LinkControl will be mostly where another element triggers the UI to appear. As a result we don’t want to force a toggle element on the developer. Rather we will expose an API to allow the consuming component to toggle the visibility of the LinkControl * Adds search text “highlighting” in results list * Move TextHighlight component to its own file * Fix bug where update to value prop didn’t cause suggestions to reset. * Update to remove internal handling of open/closed state This state is now expected to be handled by the consuming component chosing whether or not to render the component. It has no concept of open or closed. * Fix React violation by returning only the text for non matches * Update existing tests to match new implementation * Add link reset test * Adds test which uncovers major bug in the implementation Basically this test has revealed that due to the way we’re detecting and handling URL-like values the wrong data fetcher function gets passed to the URLInput component for the first input `change` event. For example if you paste `https://make.wordpress.com` directly into the input then it is determined to be a URL but because the current fetcher function for the current render is still the handler that deals with entity searches the correct results are not displayed. Adding another character to trigger a re-render will cause the UI to update to the expected state, but this is a major bug. * Tweak critical test to be more explicit about what is expected * Fix bug to make determining search handler use the latest input value Previously we relied on parent component state to choose which search handler to use for the current input term. However, the state was always 1 tick behind so the previous search handler got used. Updating this to use the real time value of the input passed onChange ensures we select the correct search fetcher when the component re-renders. * Add loading spinner and associated test coverage Spinner was technically always rendered but it wasn’t visible due to CSS styling. Fix and also cover with tests. * Fix bug where value could be empty * Adds basic editing / view state switching * Add keydown callback to URLInput * Select link on ENTER keydown event * Utilise LinkViewer to render edit state and decode urls for display * Only display link settings when a link is selected * Adds current link view styles * Makes settings toggle controlled by parent component * Update visuals to match updated design Addresses https://github.com/WordPress/gutenberg/issues/17557#issuecomment-542401433 * Add standardised min width to popover * Temporary hack to include Link UI in Playground for testing * Update to utilise isURL util from @wordpress/url package * Update to utilise isURL util from @wordpress/url package * Removes URLPopover dependency Attempts to remove unwanted deps on other components. We now utilise Popover directly and suffer no consequences as we are not making use of any bespoke features provided by URLPopover. * Extract settings drawer to sub component * Refactor search items into a component * Refactor Input and Search to component * Fix missing selected state on search suggestions * Tweak line height on search suggestion url path * Augment test for URL-like by testing for “www.” * Fix to stop url overflows and wrapping on to multiple lines * Uppcase URL in type indicator within search results list * Avoid reading out slug/URL for entity results * Ensures i18n of change button * Always offer URL result in search suggestions as default * Fix loading spinner position and dim results during loading Addresses https://github.com/WordPress/gutenberg/pull/17846#issuecomment-543244810 * Fix scroll shadows to use valid alpha transparent values in gradient Fixes broken shadows in Safari which didn’t recognise transparent as a value to transition to in a gradient. * Adds instructional text in place of URL for suggestions that are URLs Addresses designer feedback https://github.com/WordPress/gutenberg/issues/17557#issuecomment-545030027 * Update prop names for consistency Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337840953 * Update line length to improve readability Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337842799 * Update to avoid need to utilise partialRight util from lodash Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337882576 * Updates key to avoid usage of index We cannot assume the suggestion `id` will be unique. This is because at the moment the search results are `Post`s. However in the future we may also need to include `Category` terms and the term IDs could easily clash with the Post IDs as they are in different DB tables. Using the `type` to differentiate the key. Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337883174 * Update to remote isFunction check in favour of direct check Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337885206 * Update to handle mailto and tel protocols and internal links * url-input: handle onKeyPress type event * link-control: add className prop * link-control: add README file * Remove unnecessary use of useCallback Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r338363236 * Fix current automated tests * Improves URL handling test to run for multiple URL value variations * Updates to display the URL type in the search results Previously only true `http` URLs were formatted with the correct type and the instructional text. Fixes so that all types of manual URL entry are correctly shown as such in the search results. Adds test to cover mailto variant of this. * Refactor tests to assert against all valid protocol formats and link variants This now includes tel, mailto and internal links. * Adds test to cover display of fallback URL search result for search values that are potentially URLS * Adds tests to check URL suggestions don’t display for non-URLs. * url-input: remove unneeded `suggestion` const * url-input: always trigger onKeyDown event * link-control: delegate handling keydown event Instead of this, let's propagate the onKeyDown and onKeyPress events to the parent component * link-control: add onKeyDown and onKeyPress handlers * link-control: playground -> close once onClose * link-control: propagate onClose() event * link-control: playground -> hanldling close by ESCAPE key * Fix to only render settings draw if settings are defined * Remove redundant commented out test * Update to render with a “current link” if one is provided. Previously if you passed in a current link the component would still render with a search box as thought nothing was selected. Updates so that if `currentLink` is provided the UI reflects that by showing the “selected” item and no search input. * Render playground with currentLink active * Adds test to cover currentLink prop * Remove selected state from Playground * Adds tests to cover selecting and changing links * Remove async function in place of direct Promise usage and add test coverage * Add test to cover keyboard handling Note: this uncovered a bug whereby keyboard handling of “selecting” the link you want to use is broken. This needs to be fixed. * Remove unecessary dep from effect * Fix URLInput to pass the actual suggestion object not the index If the full object is not provided then consuming components have no way of accessing the details of the selected suggestion thereby rendering it useless. * Fix keyboard handling so hitting `ENTER` will select an item as the current link Builds on previous commit. * Updates keyboard interaction test to include URL entry * Minor: reword test description * Fix missing key prop regression Previously `buildSuggestionItemProps` was including a key. However the implementation of `LinkControl` changed so that this was not required. However we forgot to reinstate on `URLInput`. This update ensures a key prop is set on the default output. Note that disabling of the autofocus linting was already in place: https://github.com/WordPress/gutenberg/blob/04e142e9cbd06a45c4ea297ec573d389955c13be/packages/block-editor/src/components/url-input/index.js#L239 Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337841961 * DRY up conditionals Addresses https://github.com/WordPress/gutenberg/pull/17846#discussion_r337842477 * link-control: set a default experimental link suggestions searcher if it't needed * link-control: handling key events * url-input: remove onKeyDown prop * url-input: remove calling onKeyDown prop * url-input: rollback some changes * Mark Link Creation Interface as Experimental (#18110) * mark main component as experimental * mark new URLInput props as experimental * add experimental onKeyPress * remove key handlers * Updates to use alias on experimental props Addresses https://github.com/WordPress/gutenberg/pull/18110#discussion_r339427180 * Remove unused prop from docs * Update props ordering and readme docs Also fixes eslint errors that kept me from committing the original changes * Revert playground changes * Rename InputSearch to SearchInput Props @talldan I really hope those changes I had to make in `search-input.js` don't break anything. * Remove disabling of jsx-key lint rule * Change fake id value to something that will not clash with post ids --- packages/block-editor/src/components/index.js | 1 + .../src/components/link-control/README.md | 50 ++ .../src/components/link-control/index.js | 249 +++++++++ .../components/link-control/search-input.js | 69 +++ .../components/link-control/search-item.js | 54 ++ .../link-control/settings-drawer.js | 29 + .../src/components/link-control/style.scss | 202 +++++++ .../test/__snapshots__/index.js.snap | 3 + .../link-control/test/fixtures/index.js | 41 ++ .../src/components/link-control/test/index.js | 527 ++++++++++++++++++ .../components/link-control/text-highlight.js | 29 + .../src/components/url-input/index.js | 106 +++- packages/block-editor/src/style.scss | 1 + .../editor/src/components/provider/index.js | 1 + 14 files changed, 1340 insertions(+), 22 deletions(-) create mode 100644 packages/block-editor/src/components/link-control/README.md create mode 100644 packages/block-editor/src/components/link-control/index.js create mode 100644 packages/block-editor/src/components/link-control/search-input.js create mode 100644 packages/block-editor/src/components/link-control/search-item.js create mode 100644 packages/block-editor/src/components/link-control/settings-drawer.js create mode 100644 packages/block-editor/src/components/link-control/style.scss create mode 100644 packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap create mode 100644 packages/block-editor/src/components/link-control/test/fixtures/index.js create mode 100644 packages/block-editor/src/components/link-control/test/index.js create mode 100644 packages/block-editor/src/components/link-control/text-highlight.js diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 7ec60098a8c737..9b094396d9d8b0 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -26,6 +26,7 @@ export { default as __experimentalGradientPickerPanel } from './gradient-picker/ export { default as InnerBlocks } from './inner-blocks'; export { default as InspectorAdvancedControls } from './inspector-advanced-controls'; export { default as InspectorControls } from './inspector-controls'; +export { default as __experimentalLinkControl } from './link-control'; export { default as MediaPlaceholder } from './media-placeholder'; export { default as MediaUpload } from './media-upload'; export { default as MediaUploadCheck } from './media-upload/check'; diff --git a/packages/block-editor/src/components/link-control/README.md b/packages/block-editor/src/components/link-control/README.md new file mode 100644 index 00000000000000..e21c29974301b1 --- /dev/null +++ b/packages/block-editor/src/components/link-control/README.md @@ -0,0 +1,50 @@ +# Link Control + +## Props + +### className + +- Type: `String` +- Required: Yes + +### currentLink + +- Type: `Object` +- Required: Yes + +### currentSettings + +- Type: `Object` +- Required: Yes + +### fetchSearchSuggestions + +- Type: `Function` +- Required: No + +## Event handlers + +### onClose + +- Type: `Function` +- Required: No + +### onKeyDown + +- Type: `Function` +- Required: No + +### onKeyPress + +- Type: `Function` +- Required: No + +### onLinkChange + +- Type: `Function` +- Required: No + +### onSettingChange + +- Type: `Function` +- Required: No diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js new file mode 100644 index 00000000000000..afe72df4f2e93d --- /dev/null +++ b/packages/block-editor/src/components/link-control/index.js @@ -0,0 +1,249 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { isFunction, noop, startsWith } from 'lodash'; + +/** + * WordPress dependencies + */ +import { + Button, + ExternalLink, + Popover, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +import { + useCallback, + useState, + useEffect, + Fragment, +} from '@wordpress/element'; + +import { + safeDecodeURI, + filterURLForDisplay, + isURL, + prependHTTP, + getProtocol, +} from '@wordpress/url'; + +import { withInstanceId, compose } from '@wordpress/compose'; +import { withSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import LinkControlSettingsDrawer from './settings-drawer'; +import LinkControlSearchItem from './search-item'; +import LinkControlSearchInput from './search-input'; + +function LinkControl( { + className, + currentLink, + currentSettings, + fetchSearchSuggestions, + instanceId, + onClose = noop, + onKeyDown = noop, + onKeyPress = noop, + onLinkChange = noop, + onSettingsChange = { noop }, +} ) { + // State + const [ inputValue, setInputValue ] = useState( '' ); + const [ isEditingLink, setIsEditingLink ] = useState( false ); + + // Effects + useEffect( () => { + // If we have a link then stop editing mode + if ( currentLink ) { + setIsEditingLink( false ); + } else { + setIsEditingLink( true ); + } + }, [ currentLink ] ); + + // Handlers + + /** + * onChange LinkControlSearchInput event handler + * + * @param {string} value Current value returned by the search. + */ + const onInputChange = ( value = '' ) => { + setInputValue( value ); + }; + + // Utils + const startEditMode = () => { + if ( isFunction( onLinkChange ) ) { + onLinkChange(); + } + }; + + const closeLinkUI = () => { + resetInput(); + onClose(); + }; + + const resetInput = () => { + setInputValue( '' ); + }; + + const handleDirectEntry = ( value ) => { + let type = 'URL'; + + const protocol = getProtocol( value ) || ''; + + if ( protocol.includes( 'mailto' ) ) { + type = 'mailto'; + } + + if ( protocol.includes( 'tel' ) ) { + type = 'tel'; + } + + if ( startsWith( value, '#' ) ) { + type = 'internal'; + } + + return Promise.resolve( + [ { + id: '-1', + title: value, + url: type === 'URL' ? prependHTTP( value ) : value, + type, + } ] + ); + }; + + const handleEntitySearch = async ( value ) => { + const results = await Promise.all( [ + fetchSearchSuggestions( value ), + handleDirectEntry( value ), + ] ); + + const couldBeURL = ! value.includes( ' ' ); + + // If it's potentially a URL search then concat on a URL search suggestion + // just for good measure. That way once the actual results run out we always + // have a URL option to fallback on. + return couldBeURL ? results[ 0 ].concat( results[ 1 ] ) : results[ 0 ]; + }; + + // Effects + const getSearchHandler = useCallback( ( value ) => { + const protocol = getProtocol( value ) || ''; + const isMailto = protocol.includes( 'mailto' ); + const isInternal = startsWith( value, '#' ); + const isTel = protocol.includes( 'tel' ); + + const handleManualEntry = isInternal || isMailto || isTel || isURL( value ) || ( value && value.includes( 'www.' ) ); + + return ( handleManualEntry ) ? handleDirectEntry( value ) : handleEntitySearch( value ); + }, [ handleDirectEntry, fetchSearchSuggestions ] ); + + // Render Components + const renderSearchResults = ( { suggestionsListProps, buildSuggestionItemProps, suggestions, selectedSuggestion, isLoading } ) => { + const resultsListClasses = classnames( 'block-editor-link-control__search-results', { + 'is-loading': isLoading, + } ); + + const manualLinkEntryTypes = [ 'url', 'mailto', 'tel', 'internal' ]; + + return ( + <div className="block-editor-link-control__search-results-wrapper"> + <div { ...suggestionsListProps } className={ resultsListClasses }> + { suggestions.map( ( suggestion, index ) => ( + <LinkControlSearchItem + key={ `${ suggestion.id }-${ suggestion.type }` } + itemProps={ buildSuggestionItemProps( suggestion, index ) } + suggestion={ suggestion } + onClick={ () => onLinkChange( suggestion ) } + isSelected={ index === selectedSuggestion } + isURL={ manualLinkEntryTypes.includes( suggestion.type.toLowerCase() ) } + searchTerm={ inputValue } + /> + ) ) } + </div> + </div> + ); + }; + + return ( + <Popover + className={ classnames( 'block-editor-link-control', className ) } + onClose={ closeLinkUI } + position="bottom center" + focusOnMount="firstElement" + > + <div className="block-editor-link-control__popover-inner"> + <div className="block-editor-link-control__search"> + + { ( ! isEditingLink && currentLink ) && ( + <Fragment> + <p className="screen-reader-text" id={ `current-link-label-${ instanceId }` }> + { __( 'Currently selected' ) }: + </p> + <div + aria-labelledby={ `current-link-label-${ instanceId }` } + aria-selected="true" + className={ classnames( 'block-editor-link-control__search-item', { + 'is-current': true, + } ) } + > + <span className="block-editor-link-control__search-item-header"> + + <ExternalLink + className="block-editor-link-control__search-item-title" + href={ currentLink.url } + > + { currentLink.title } + </ExternalLink> + <span className="block-editor-link-control__search-item-info">{ filterURLForDisplay( safeDecodeURI( currentLink.url ) ) || '' }</span> + </span> + + <Button isDefault onClick={ startEditMode } className="block-editor-link-control__search-item-action block-editor-link-control__search-item-action--edit"> + { __( 'Change' ) } + </Button> + </div> + </Fragment> + ) } + + { isEditingLink && ( + <LinkControlSearchInput + value={ inputValue } + onChange={ onInputChange } + onSelect={ onLinkChange } + renderSuggestions={ renderSearchResults } + fetchSuggestions={ getSearchHandler } + onReset={ resetInput } + onKeyDown={ onKeyDown } + onKeyPress={ onKeyPress } + /> + ) } + + { ! isEditingLink && ( + <LinkControlSettingsDrawer settings={ currentSettings } onSettingChange={ onSettingsChange } /> + ) } + </div> + </div> + </Popover> + ); +} + +export default compose( + withInstanceId, + withSelect( ( select, ownProps ) => { + if ( ownProps.fetchSearchSuggestions && isFunction( ownProps.fetchSearchSuggestions ) ) { + return; + } + + const { getSettings } = select( 'core/block-editor' ); + return { + fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions, + }; + } ) +)( LinkControl ); diff --git a/packages/block-editor/src/components/link-control/search-input.js b/packages/block-editor/src/components/link-control/search-input.js new file mode 100644 index 00000000000000..84fd5db8359363 --- /dev/null +++ b/packages/block-editor/src/components/link-control/search-input.js @@ -0,0 +1,69 @@ + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { IconButton } from '@wordpress/components'; +import { ENTER } from '@wordpress/keycodes'; + +/** + * Internal dependencies + */ +import { URLInput } from '../'; + +const LinkControlSearchInput = ( { + value, + onChange, + onSelect, + renderSuggestions, + fetchSuggestions, + onReset, + onKeyDown, + onKeyPress, +} ) => { + const selectItemHandler = ( selection, suggestion ) => { + onChange( selection ); + + if ( suggestion ) { + onSelect( suggestion ); + } + }; + + const stopFormEventsPropagation = ( event ) => { + event.preventDefault(); + event.stopPropagation(); + }; + + return ( + <form onSubmit={ stopFormEventsPropagation }> + <URLInput + className="block-editor-link-control__search-input" + value={ value } + onChange={ selectItemHandler } + onKeyDown={ ( event ) => { + if ( event.keyCode === ENTER ) { + return; + } + onKeyDown( event ); + } } + onKeyPress={ onKeyPress } + placeholder={ __( 'Search or type url' ) } + __experimentalRenderSuggestions={ renderSuggestions } + __experimentalFetchLinkSuggestions={ fetchSuggestions } + __experimentalHandleURLSuggestions={ true } + /> + + <IconButton + disabled={ ! value.length } + type="reset" + label={ __( 'Reset' ) } + icon="no-alt" + className="block-editor-link-control__search-reset" + onClick={ onReset } + /> + + </form> + ); +}; + +export default LinkControlSearchInput; diff --git a/packages/block-editor/src/components/link-control/search-item.js b/packages/block-editor/src/components/link-control/search-item.js new file mode 100644 index 00000000000000..432b4bb3dff17a --- /dev/null +++ b/packages/block-editor/src/components/link-control/search-item.js @@ -0,0 +1,54 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * Internal dependencies + */ +import TextHighlight from './text-highlight'; + +/** + * WordPress dependencies + */ +import { safeDecodeURI } from '@wordpress/url'; +import { __ } from '@wordpress/i18n'; + +import { + Icon, +} from '@wordpress/components'; + +export const LinkControlSearchItem = ( { itemProps, suggestion, isSelected = false, onClick, isURL = false, searchTerm = '' } ) => { + return ( + <button + { ...itemProps } + onClick={ onClick } + className={ classnames( 'block-editor-link-control__search-item', { + 'is-selected': isSelected, + 'is-url': isURL, + 'is-entity': ! isURL, + } ) } + > + { isURL && ( + <Icon className="block-editor-link-control__search-item-icon" icon="admin-site-alt3" /> + ) } + <span className="block-editor-link-control__search-item-header"> + <span className="block-editor-link-control__search-item-title"> + <TextHighlight text={ suggestion.title } highlight={ searchTerm } /> + </span> + <span aria-hidden={ ! isURL } className="block-editor-link-control__search-item-info"> + { ! isURL && ( safeDecodeURI( suggestion.url ) || '' ) } + { isURL && ( + __( 'Press ENTER to add this link' ) + ) } + </span> + </span> + { suggestion.type && ( + <span className="block-editor-link-control__search-item-type">{ suggestion.type }</span> + ) } + </button> + ); +}; + +export default LinkControlSearchItem; + diff --git a/packages/block-editor/src/components/link-control/settings-drawer.js b/packages/block-editor/src/components/link-control/settings-drawer.js new file mode 100644 index 00000000000000..372426e4e821ff --- /dev/null +++ b/packages/block-editor/src/components/link-control/settings-drawer.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import { partial } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + ToggleControl, +} from '@wordpress/components'; + +const LinkControlSettingsDrawer = ( { settings, onSettingChange } ) => { + if ( ! settings || settings.length ) { + return null; + } + + return ( + <div className="block-editor-link-control__settings"> + <ToggleControl + label={ __( 'Open in New Tab' ) } + onChange={ partial( onSettingChange, 'new-tab' ) } + checked={ settings[ 'new-tab' ] } /> + </div> + ); +}; + +export default LinkControlSettingsDrawer; diff --git a/packages/block-editor/src/components/link-control/style.scss b/packages/block-editor/src/components/link-control/style.scss new file mode 100644 index 00000000000000..69f87d79fdfe3d --- /dev/null +++ b/packages/block-editor/src/components/link-control/style.scss @@ -0,0 +1,202 @@ +.block-editor-link-control__search { + position: relative; + min-width: $modal-min-width; +} + +.block-editor-link-control__search .block-editor-link-control__search-input { + // Specificity overide + &.block-editor-link-control__search-input > input[type="text"] { + width: calc(100% - #{$grid-size-large*2}); + display: block; + padding: 11px $grid-size-large; + margin: $grid-size-large; + padding-right: 38px; // width of reset button + position: relative; + z-index: 1; + border: 1px solid #e1e1e1; + border-radius: $radius-round-rectangle; + + /* Fonts smaller than 16px causes mobile safari to zoom. */ + font-size: $mobile-text-min-font-size; + + @include break-small { + font-size: $default-font-size; + } + + &:focus { + @include input-style__focus(); + } + } +} + +.block-editor-link-control__search-reset { + position: absolute; + top: 19px; // has to be hard coded as form expands with search suggestions + right: 19px; // push away to avoid focus style obscuring input border + z-index: 10; +} + +.block-editor-link-control__search-results-wrapper { + position: relative; + margin-top: -$grid-size-large + 1px; + + &::before, + &::after { + content: ""; + position: absolute; + left: -1px; + right: $grid-size-large; // avoid overlaying scrollbars + display: block; + pointer-events: none; + z-index: 100; + } + + &::before { + height: $grid-size-large/2; + top: -1px; + bottom: auto; + background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); + } + + &::after { + height: 20px; + bottom: -1px; + top: auto; + background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%); + } +} + +.block-editor-link-control__search-results { + margin: 0; + padding: $grid-size-large/2 $grid-size-large; + max-height: 200px; + overflow-y: scroll; // allow results list to scroll + + &.is-loading { + opacity: 0.2; + } +} + +.block-editor-link-control__search-item { + position: relative; + display: flex; + align-items: center; + font-size: $default-font-size; + cursor: pointer; + background: $white; + width: 100%; + border: none; + text-align: left; + padding: 10px 15px; + border-radius: 5px; + + &:hover, + &:focus { + background-color: #e9e9e9; + } + + &.is-selected { + background: #f2f2f2; + + .block-editor-link-control__search-item-type { + background: #fff; + } + } + + &.is-current { + background: transparent; + border: 0; + width: 100%; + cursor: default; + padding: $grid-size-large; + padding-left: $grid-size-xlarge; + } + + .block-editor-link-control__search-item-header { + display: block; + margin-right: $grid-size-xlarge; + } + + .block-editor-link-control__search-item-icon { + margin-right: 1em; + min-width: 24px; + } + + .block-editor-link-control__search-item-info, + .block-editor-link-control__search-item-title { + text-overflow: ellipsis; + max-width: 230px; + overflow: hidden; + white-space: nowrap; + } + + .block-editor-link-control__search-item-title { + display: block; + margin-bottom: 0.2em; + font-weight: 500; + + mark { + font-weight: 700; + color: #000; + background-color: transparent; + } + + span { + font-weight: normal; + } + } + + .block-editor-link-control__search-item-info { + display: block; + color: #999; + font-size: 0.9em; + line-height: 1.3; + } + + .block-editor-link-control__search-item-type { + display: block; + padding: 3px 8px; + margin-left: auto; + font-size: 0.9em; + background-color: #f3f4f5; + border-radius: 2px; + } +} + +// Specificity overide +.block-editor-link-control__search-results div[role="menu"] > .block-editor-link-control__search-item.block-editor-link-control__search-item { + padding: 10px; +} + +.block-editor-link-control__settings { + border-top: 1px solid #e1e1e1; + margin: 0; + padding: $grid-size-large $grid-size-xlarge; + + :last-child { + margin-bottom: 0; + } +} + +.block-editor-link-control .block-editor-link-control__search-input .components-spinner { + display: block; + z-index: 100; + float: none; + + &.components-spinner { // Specificity overide + position: absolute; + top: 70px; + left: 50%; + right: auto; + bottom: auto; + margin: 0 auto 16px auto; + transform: translateX(-50%); + } + + +} + +.block-editor-link-control__search-item-action { + margin-left: auto; // push to far right hand side + flex-shrink: 0; +} diff --git a/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000000..df68c094eabc63 --- /dev/null +++ b/packages/block-editor/src/components/link-control/test/__snapshots__/index.js.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Basic rendering should display with required props 1`] = `"<span><div tabindex=\\"-1\\"><div><div><div class=\\"components-popover block-editor-link-control is-bottom is-center components-animate__appear is-from-top\\" style=\\"\\"><div class=\\"components-popover__content\\" tabindex=\\"-1\\"><div class=\\"block-editor-link-control__popover-inner\\"><div class=\\"block-editor-link-control__search\\"><form><div class=\\"editor-url-input block-editor-url-input block-editor-link-control__search-input\\"><input type=\\"text\\" aria-label=\\"URL\\" required=\\"\\" placeholder=\\"Search or type url\\" role=\\"combobox\\" aria-expanded=\\"false\\" aria-autocomplete=\\"list\\" aria-owns=\\"block-editor-url-input-suggestions-0\\" value=\\"\\"></div><button type=\\"reset\\" disabled=\\"\\" aria-label=\\"Reset\\" class=\\"components-button components-icon-button block-editor-link-control__search-reset\\"><svg aria-hidden=\\"true\\" role=\\"img\\" focusable=\\"false\\" class=\\"dashicon dashicons-no-alt\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"20\\" height=\\"20\\" viewBox=\\"0 0 20 20\\"><path d=\\"M14.95 6.46L11.41 10l3.54 3.54-1.41 1.41L10 11.42l-3.53 3.53-1.42-1.42L8.58 10 5.05 6.47l1.42-1.42L10 8.58l3.54-3.53z\\"></path></svg></button></form></div></div></div></div></div></div></div></span>"`; diff --git a/packages/block-editor/src/components/link-control/test/fixtures/index.js b/packages/block-editor/src/components/link-control/test/fixtures/index.js new file mode 100644 index 00000000000000..fc974749c982b1 --- /dev/null +++ b/packages/block-editor/src/components/link-control/test/fixtures/index.js @@ -0,0 +1,41 @@ +/** + * External dependencies + */ +import { uniqueId } from 'lodash'; + +export const fauxEntitySuggestions = [ + { + id: uniqueId(), + title: 'Hello Page', + type: 'Page', + info: '2 days ago', + url: `?p=${ uniqueId() }`, + }, + { + id: uniqueId(), + title: 'Hello Post', + type: 'Post', + info: '19 days ago', + url: `?p=${ uniqueId() }`, + }, + { + id: uniqueId(), + title: 'Hello Another One', + type: 'Page', + info: '19 days ago', + url: `?p=${ uniqueId() }`, + }, + { + id: uniqueId(), + title: 'This is another Post with a much longer title just to be really annoying and to try and break the UI', + type: 'Post', + info: '1 month ago', + url: `?p=${ uniqueId() }`, + }, +]; + +// export const fetchFauxEntitySuggestions = async () => fauxEntitySuggestions; + +export const fetchFauxEntitySuggestions = () => { + return Promise.resolve( fauxEntitySuggestions ); +}; diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js new file mode 100644 index 00000000000000..d6dc506c7687b8 --- /dev/null +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -0,0 +1,527 @@ +/** + * External dependencies + */ +import { render, unmountComponentAtNode } from 'react-dom'; +import { act, Simulate } from 'react-dom/test-utils'; +import { first, last, nth } from 'lodash'; +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; +import { UP, DOWN, ENTER } from '@wordpress/keycodes'; +/** + * Internal dependencies + */ +import LinkControl from '../index'; +import { fauxEntitySuggestions, fetchFauxEntitySuggestions } from './fixtures'; + +function eventLoopTick() { + return new Promise( ( resolve ) => setImmediate( resolve ) ); +} + +let container = null; + +beforeEach( () => { + // setup a DOM element as a render target + container = document.createElement( 'div' ); + document.body.appendChild( container ); +} ); + +afterEach( () => { + // cleanup on exiting + unmountComponentAtNode( container ); + container.remove(); + container = null; +} ); + +describe( 'Basic rendering', () => { + it( 'should display with required props', () => { + act( () => { + render( + <LinkControl + />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // expect( searchInputLabel ).not.toBeNull(); + expect( searchInput ).not.toBeNull(); + + expect( container.innerHTML ).toMatchSnapshot(); + } ); +} ); + +describe( 'Searching for a link', () => { + it( 'should display loading UI when input is valid but search results have yet to be returned', async () => { + const searchTerm = 'Hello'; + + let resolver; + + const fauxRequest = () => new Promise( ( resolve ) => { + resolver = resolve; + } ); + + act( () => { + render( + <LinkControl + fetchSearchSuggestions={ fauxRequest } + />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="menu"] button[role="menuitem"]' ); + + let loadingUI = container.querySelector( '.components-spinner' ); + + expect( searchResultElements ).toHaveLength( 0 ); + + expect( loadingUI ).not.toBeNull(); + + act( () => { + resolver( fauxEntitySuggestions ); + } ); + + await eventLoopTick(); + + loadingUI = container.querySelector( '.components-spinner' ); + + expect( loadingUI ).toBeNull(); + } ); + + it( 'should display only search suggestions when current input value is not URL-like', async ( ) => { + const searchTerm = 'Hello world'; + const firstFauxSuggestion = first( fauxEntitySuggestions ); + + act( () => { + render( + <LinkControl + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchResultItemHTML = first( searchResultElements ).innerHTML; + const lastSearchResultItemHTML = last( searchResultElements ).innerHTML; + + expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length ); + + // Sanity check that a search suggestion shows up corresponding to the data + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( firstFauxSuggestion.title ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( firstFauxSuggestion.type ) ); + + // The fallback URL suggestion should not be shown when input is not URL-like + expect( lastSearchResultItemHTML ).not.toEqual( expect.stringContaining( 'URL' ) ); + } ); + + it.each( [ + [ 'couldbeurlorentitysearchterm' ], + [ 'ThisCouldAlsoBeAValidURL' ], + ] )( 'should display a URL suggestion as a default fallback for the search term "%s" which could potentially be a valid url.', async ( searchTerm ) => { + act( () => { + render( + <LinkControl + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const lastSearchResultItemHTML = last( searchResultElements ).innerHTML; + const additionalDefaultFallbackURLSuggestionLength = 1; + + // We should see a search result for each of the expect search suggestions + // plus 1 additional one for the fallback URL suggestion + expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length + additionalDefaultFallbackURLSuggestionLength ); + + // The last item should be a URL search suggestion + expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); + expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( 'URL' ) ); + expect( lastSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); + } ); + + it( 'should reset the input field and the search results when search term is cleared or reset', async ( ) => { + const searchTerm = 'Hello world'; + + act( () => { + render( + <LinkControl + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + />, container + ); + } ); + + let searchResultElements; + let searchInput; + + // Search Input UI + searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + + // Check we have definitely rendered some suggestions + expect( searchResultElements ).toHaveLength( fauxEntitySuggestions.length ); + + // Grab the reset button now it's available + const resetUI = container.querySelector( '[aria-label="Reset"]' ); + + act( () => { + Simulate.click( resetUI ); + } ); + + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + expect( searchInput.value ).toBe( '' ); + expect( searchResultElements ).toHaveLength( 0 ); + } ); +} ); + +describe( 'Manual link entry', () => { + it.each( [ + [ 'https://make.wordpress.org' ], // explicit https + [ 'http://make.wordpress.org' ], // explicit http + [ 'www.wordpress.org' ], // usage of "www" + ] )( 'should display a single suggestion result when the current input value is URL-like (eg: %s)', async ( searchTerm ) => { + act( () => { + render( + <LinkControl + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchResultItemHTML = searchResultElements[ 0 ].innerHTML; + const expectedResultsLength = 1; + + expect( searchResultElements ).toHaveLength( expectedResultsLength ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'URL' ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); + } ); + + describe( 'Alternative link protocols and formats', () => { + it.each( [ + [ 'mailto:example123456@wordpress.org', 'mailto' ], + [ 'tel:example123456@wordpress.org', 'tel' ], + [ '#internal-anchor', 'internal' ], + ] )( 'should recognise "%s" as a %s link and handle as manual entry by displaying a single suggestion', async ( searchTerm, searchType ) => { + act( () => { + render( + <LinkControl + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchResultItemHTML = searchResultElements[ 0 ].innerHTML; + const expectedResultsLength = 1; + + expect( searchResultElements ).toHaveLength( expectedResultsLength ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchTerm ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( searchType ) ); + expect( firstSearchResultItemHTML ).toEqual( expect.stringContaining( 'Press ENTER to add this link' ) ); + } ); + } ); +} ); + +describe( 'Selecting links', () => { + it( 'should display a selected link corresponding to the provided "currentLink" prop', () => { + const selectedLink = first( fauxEntitySuggestions ); + + const LinkControlConsumer = () => { + const [ link ] = useState( selectedLink ); + + return ( + <LinkControl + currentLink={ link } + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + /> + ); + }; + + act( () => { + render( + <LinkControlConsumer />, container + ); + } ); + + // TODO: select by aria role or visible text + const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + const currentLinkHTML = currentLink.innerHTML; + const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); + + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.type ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); + expect( currentLinkAnchor ).not.toBeNull(); + } ); + + it( 'should remove currently selected link and (re)display search UI when "Change" button is clicked', () => { + const selectedLink = first( fauxEntitySuggestions ); + + const LinkControlConsumer = () => { + const [ link, setLink ] = useState( selectedLink ); + + return ( + <LinkControl + currentLink={ link } + onLinkChange={ ( suggestion ) => setLink( suggestion ) } + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + /> + ); + }; + + act( () => { + render( + <LinkControlConsumer />, container + ); + } ); + + // TODO: select by aria role or visible text + let currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + + const currentLinkBtn = currentLink.querySelector( 'button' ); + + // Simulate searching for a term + act( () => { + Simulate.click( currentLinkBtn ); + } ); + + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + + // We should be back to showing the search input + expect( searchInput ).not.toBeNull(); + expect( currentLink ).toBeNull(); + } ); + + describe( 'Selection using mouse click', () => { + it.each( [ + [ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search + [ 'url', 'https://www.wordpress.org', { + id: '1', + title: 'https://www.wordpress.org', + url: 'https://www.wordpress.org', + type: 'URL', + } ], // url + ] )( 'should display a current selected link UI when a %s suggestion for the search "%s" is clicked', async ( type, searchTerm, selectedLink ) => { + const LinkControlConsumer = () => { + const [ link, setLink ] = useState( null ); + + return ( + <LinkControl + currentLink={ link } + onLinkChange={ ( suggestion ) => setLink( suggestion ) } + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + /> + ); + }; + + act( () => { + render( + <LinkControlConsumer />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + // fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + + const firstSearchSuggestion = first( searchResultElements ); + + // Simulate selecting the first of the search suggestions + act( () => { + Simulate.click( firstSearchSuggestion ); + } ); + + const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + const currentLinkHTML = currentLink.innerHTML; + const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); + + // Check that this suggestion is now shown as selected + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); + expect( currentLinkAnchor ).not.toBeNull(); + } ); + } ); + + describe( 'Selection using keyboard', () => { + it.each( [ + [ 'entity', 'hello world', first( fauxEntitySuggestions ) ], // entity search + [ 'url', 'https://www.wordpress.org', { + id: '1', + title: 'https://www.wordpress.org', + url: 'https://www.wordpress.org', + type: 'URL', + } ], // url + ] )( 'should display a current selected link UI when an %s suggestion for the search "%s" is selected using the keyboard', async ( type, searchTerm, selectedLink ) => { + const LinkControlConsumer = () => { + const [ link, setLink ] = useState( null ); + + return ( + <LinkControl + currentLink={ link } + onLinkChange={ ( suggestion ) => setLink( suggestion ) } + fetchSearchSuggestions={ fetchFauxEntitySuggestions } + /> + ); + }; + + act( () => { + render( + <LinkControlConsumer />, container + ); + } ); + + // Search Input UI + const searchInput = container.querySelector( 'input[aria-label="URL"]' ); + + // Simulate searching for a term + act( () => { + Simulate.change( searchInput, { target: { value: searchTerm } } ); + } ); + + //fetchFauxEntitySuggestions resolves on next "tick" of event loop + await eventLoopTick(); + + // Step down into the search results, highlighting the first result item + act( () => { + Simulate.keyDown( searchInput, { keyCode: DOWN } ); + } ); + + // TODO: select these by aria relationship to autocomplete rather than arbitary selector. + const searchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' ); + const firstSearchSuggestion = first( searchResultElements ); + const secondSearchSuggestion = nth( searchResultElements, 1 ); + + let selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); + + // We should have highlighted the first item using the keyboard + expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion ); + + // Only entity searches contain more than 1 suggestion + if ( type === 'entity' ) { + // Check we can go down again using the down arrow + act( () => { + Simulate.keyDown( searchInput, { keyCode: DOWN } ); + } ); + + selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); + + // We should have highlighted the first item using the keyboard + expect( selectedSearchResultElement ).toEqual( secondSearchSuggestion ); + + // Check we can go back up via up arrow + act( () => { + Simulate.keyDown( searchInput, { keyCode: UP } ); + } ); + + selectedSearchResultElement = container.querySelector( '[role="option"][aria-selected="true"]' ); + + // We should be back to highlighting the first search result again + expect( selectedSearchResultElement ).toEqual( firstSearchSuggestion ); + } + + // Commit the selected item as the current link + act( () => { + Simulate.keyDown( searchInput, { keyCode: ENTER } ); + } ); + + // Check that the suggestion selected via is now shown as selected + const currentLink = container.querySelector( '.block-editor-link-control__search-item.is-current' ); + const currentLinkHTML = currentLink.innerHTML; + const currentLinkAnchor = currentLink.querySelector( `[href="${ selectedLink.url }"]` ); + + expect( currentLinkHTML ).toEqual( expect.stringContaining( selectedLink.title ) ); + expect( currentLinkHTML ).toEqual( expect.stringContaining( 'Change' ) ); + expect( currentLinkAnchor ).not.toBeNull(); + } ); + } ); +} ); diff --git a/packages/block-editor/src/components/link-control/text-highlight.js b/packages/block-editor/src/components/link-control/text-highlight.js new file mode 100644 index 00000000000000..dc7b35a3d6d2bc --- /dev/null +++ b/packages/block-editor/src/components/link-control/text-highlight.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import { escapeRegExp } from 'lodash'; + +/** + * WordPress dependencies + */ +import { + Fragment, +} from '@wordpress/element'; + +const TextHighlight = ( { text = '', highlight = '' } ) => { + if ( ! highlight.trim() ) { + return text; + } + + const regex = new RegExp( `(${ escapeRegExp( highlight ) })`, 'gi' ); + const parts = text.split( regex ); + return ( + <Fragment> + { parts.filter( ( part ) => part ).map( ( part, i ) => ( + regex.test( part ) ? <mark key={ i }>{ part }</mark> : <span key={ i }>{ part }</span> + ) ) } + </Fragment> + ); +}; + +export default TextHighlight; diff --git a/packages/block-editor/src/components/url-input/index.js b/packages/block-editor/src/components/url-input/index.js index 53a5914f10b4a9..1c32d9c29eab34 100644 --- a/packages/block-editor/src/components/url-input/index.js +++ b/packages/block-editor/src/components/url-input/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { throttle } from 'lodash'; +import { throttle, isFunction } from 'lodash'; import classnames from 'classnames'; import scrollIntoView from 'dom-scroll-into-view'; @@ -14,6 +14,7 @@ import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes'; import { Spinner, withSpokenMessages, Popover } from '@wordpress/components'; import { withInstanceId, withSafeTimeout, compose } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; +import { isURL } from '@wordpress/url'; // Since URLInput is rendered in the context of other inputs, but should be // considered a separate modal node, prevent keyboard events from propagating @@ -21,12 +22,15 @@ import { withSelect } from '@wordpress/data'; const stopEventPropagation = ( event ) => event.stopPropagation(); class URLInput extends Component { - constructor( { autocompleteRef } ) { - super( ...arguments ); + constructor( props ) { + super( props ); this.onChange = this.onChange.bind( this ); this.onKeyDown = this.onKeyDown.bind( this ); - this.autocompleteRef = autocompleteRef || createRef(); + this.selectLink = this.selectLink.bind( this ); + this.handleOnClick = this.handleOnClick.bind( this ); + this.bindSuggestionNode = this.bindSuggestionNode.bind( this ); + this.autocompleteRef = props.autocompleteRef || createRef(); this.inputRef = createRef(); this.updateSuggestions = throttle( this.updateSuggestions.bind( this ), 200 ); @@ -45,6 +49,7 @@ class URLInput extends Component { // when already expanded if ( showSuggestions && selectedSuggestion !== null && ! this.scrollingIntoView ) { this.scrollingIntoView = true; + scrollIntoView( this.suggestionNodes[ selectedSuggestion ], this.autocompleteRef.current, { onlyScrollIfNeeded: true, } ); @@ -66,14 +71,17 @@ class URLInput extends Component { } updateSuggestions( value ) { - const { fetchLinkSuggestions } = this.props; + const { + __experimentalFetchLinkSuggestions: fetchLinkSuggestions, + __experimentalHandleURLSuggestions: handleURLSuggestions, + } = this.props; if ( ! fetchLinkSuggestions ) { return; } // Show the suggestions after typing at least 2 characters // and also for URLs - if ( value.length < 2 || /^https?:/.test( value ) ) { + if ( value.length < 2 || ( ! handleURLSuggestions && isURL( value ) ) ) { this.setState( { showSuggestions: false, selectedSuggestion: null, @@ -132,6 +140,7 @@ class URLInput extends Component { onKeyDown( event ) { const { showSuggestions, selectedSuggestion, suggestions, loading } = this.state; + // If the suggestions are not shown or loading, we shouldn't handle the arrow keys // We shouldn't preventDefault to allow block arrow keys navigation if ( @@ -226,19 +235,64 @@ class URLInput extends Component { this.inputRef.current.focus(); } - static getDerivedStateFromProps( { disableSuggestions }, { showSuggestions } ) { + static getDerivedStateFromProps( { value, disableSuggestions }, { showSuggestions, selectedSuggestion } ) { + let shouldShowSuggestions = showSuggestions; + + const hasValue = value && value.length; + + if ( ! hasValue ) { + shouldShowSuggestions = false; + } + + if ( disableSuggestions === true ) { + shouldShowSuggestions = false; + } + return { - showSuggestions: disableSuggestions === true ? false : showSuggestions, + selectedSuggestion: hasValue ? selectedSuggestion : null, + showSuggestions: shouldShowSuggestions, }; } render() { - const { value = '', autoFocus = true, instanceId, className, id, isFullWidth, hasBorder } = this.props; - const { showSuggestions, suggestions, selectedSuggestion, loading } = this.state; + const { + instanceId, + className, + id, + isFullWidth, + hasBorder, + __experimentalRenderSuggestions: renderSuggestions, + placeholder = __( 'Paste URL or type to search' ), + value = '', + autoFocus = true, + } = this.props; + + const { + showSuggestions, + suggestions, + selectedSuggestion, + loading, + } = this.state; const suggestionsListboxId = `block-editor-url-input-suggestions-${ instanceId }`; const suggestionOptionIdPrefix = `block-editor-url-input-suggestion-${ instanceId }`; + const suggestionsListProps = { + id: suggestionsListboxId, + ref: this.autocompleteRef, + role: 'listbox', + }; + + const buildSuggestionItemProps = ( suggestion, index ) => { + return { + role: 'option', + tabIndex: '-1', + id: `${ suggestionOptionIdPrefix }-${ index }`, + ref: this.bindSuggestionNode( index ), + 'aria-selected': index === selectedSuggestion, + }; + }; + /* eslint-disable jsx-a11y/no-autofocus */ return ( <div className={ classnames( 'editor-url-input block-editor-url-input', className, { @@ -254,7 +308,7 @@ class URLInput extends Component { value={ value } onChange={ this.onChange } onInput={ stopEventPropagation } - placeholder={ __( 'Paste URL or type to search' ) } + placeholder={ placeholder } onKeyDown={ this.onKeyDown } role="combobox" aria-expanded={ showSuggestions } @@ -266,34 +320,37 @@ class URLInput extends Component { { ( loading ) && <Spinner /> } - { showSuggestions && !! suggestions.length && + { isFunction( renderSuggestions ) && showSuggestions && !! suggestions.length && renderSuggestions( { + suggestions, + selectedSuggestion, + suggestionsListProps, + buildSuggestionItemProps, + isLoading: loading, + handleSuggestionClick: this.handleOnClick, + } ) } + + { ! isFunction( renderSuggestions ) && showSuggestions && !! suggestions.length && <Popover position="bottom" noArrow focusOnMount={ false } > <div + { ...suggestionsListProps } className={ classnames( 'editor-url-input__suggestions', 'block-editor-url-input__suggestions', `${ className }__suggestions` ) } - id={ suggestionsListboxId } - ref={ this.autocompleteRef } - role="listbox" > { suggestions.map( ( suggestion, index ) => ( <button + { ...buildSuggestionItemProps( suggestion, index ) } key={ suggestion.id } - role="option" - tabIndex="-1" - id={ `${ suggestionOptionIdPrefix }-${ index }` } - ref={ this.bindSuggestionNode( index ) } className={ classnames( 'editor-url-input__suggestion block-editor-url-input__suggestion', { 'is-selected': index === selectedSuggestion, } ) } onClick={ () => this.handleOnClick( suggestion ) } - aria-selected={ index === selectedSuggestion } > { suggestion.title } </button> @@ -314,10 +371,15 @@ export default compose( withSafeTimeout, withSpokenMessages, withInstanceId, - withSelect( ( select ) => { + withSelect( ( select, props ) => { + // If a link suggestions handler is already provided then + // bail + if ( isFunction( props.__experimentalFetchLinkSuggestions ) ) { + return; + } const { getSettings } = select( 'core/block-editor' ); return { - fetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions, + __experimentalFetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions, }; } ) )( URLInput ); diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 7296c0fa788620..9c149f001cf7fa 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -19,6 +19,7 @@ @import "./components/contrast-checker/style.scss"; @import "./components/default-block-appender/style.scss"; @import "./components/gradient-picker/control.scss"; +@import "./components/link-control/style.scss"; @import "./components/inner-blocks/style.scss"; @import "./components/inserter-with-shortcuts/style.scss"; @import "./components/inserter/style.scss"; diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index d38ceaa91e66d2..37eb46ff235b52 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -38,6 +38,7 @@ const fetchLinkSuggestions = async ( search ) => { id: post.id, url: post.url, title: decodeEntities( post.title ) || __( '(no title)' ), + type: post.subtype || post.type, } ) ); }; From e03e133b2a7feb4aa11dc73883457d6798896f1f Mon Sep 17 00:00:00 2001 From: Jorge Bernal <jorge@automattic.com> Date: Fri, 1 Nov 2019 11:16:13 +0100 Subject: [PATCH 112/113] Fix handling of pasted images and prevent thumbnail uploads (#18215) * Fix handling of pasted images and prevent thumbnail uploads * Fix lint errors * Remove check for image for sync. --- .../block-library/src/image/edit.native.js | 18 +++++++++++------- .../src/media-text/media-container.native.js | 17 +++++------------ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 53334a888dd946..1d9274c3754697 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -104,14 +104,18 @@ export class ImageEdit extends React.Component { console.warn( 'Attributes has id with no url.' ); } + // Detect any pasted image and start an upload + if ( ! attributes.id && attributes.url && attributes.url.indexOf( 'file:' ) === 0 ) { + requestMediaImport( attributes.url, ( id, url ) => { + if ( url ) { + setAttributes( { id, url } ); + } + } ); + } + + // Make sure we mark any temporary images as failed if they failed while + // the editor wasn't open if ( attributes.id && attributes.url && ! isURL( attributes.url ) ) { - if ( attributes.url.indexOf( 'file:' ) === 0 ) { - requestMediaImport( attributes.url, ( id, url ) => { - if ( url ) { - setAttributes( { id, url } ); - } - } ); - } mediaUploadSync(); } } diff --git a/packages/block-library/src/media-text/media-container.native.js b/packages/block-library/src/media-text/media-container.native.js index 84d2c6dc836bde..fea6a9671965c4 100644 --- a/packages/block-library/src/media-text/media-container.native.js +++ b/packages/block-library/src/media-text/media-container.native.js @@ -3,7 +3,6 @@ */ import { View, ImageBackground, Text, TouchableWithoutFeedback } from 'react-native'; import { - requestMediaImport, mediaUploadSync, requestImageFailedRetryDialog, requestImageUploadCancelDialog, @@ -62,17 +61,11 @@ class MediaContainer extends Component { } componentDidMount() { - const { mediaId, mediaUrl, onMediaUpdate, mediaType } = this.props; - - if ( mediaId && mediaUrl && ! isURL( mediaUrl ) ) { - if ( mediaUrl.indexOf( 'file:' ) === 0 && mediaType === MEDIA_TYPE_IMAGE ) { - // We don't want to call this for video because it is starting a media upload for the cover url - requestMediaImport( mediaUrl, ( id, url ) => { - if ( url ) { - onMediaUpdate( { id, url } ); - } - } ); - } + const { mediaId, mediaUrl } = this.props; + + // Make sure we mark any temporary images as failed if they failed while + // the editor wasn't open + if ( mediaId && mediaUrl && mediaUrl.indexOf( 'file:' ) === 0 ) { mediaUploadSync(); } } From 705d91151fe4064d4dfea337a7f2ba77983ecbe1 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis <stefanostogoulidis@gmail.com> Date: Fri, 1 Nov 2019 13:32:41 +0200 Subject: [PATCH 113/113] Include the RN mobile releases branch in Travis branches --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 32e41294c57f9c..db9acbf2d2174b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ branches: only: - master - rnmobile/master + - rnmobile/releases - /wp\/.*/ env: