From 88f3b9a5a3b3927c21004d80ea9fa4d30cb0aca9 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 5 Jan 2021 12:39:09 +0100 Subject: [PATCH] Merge changes published in the Gutenberg plugin "release/9.7" branch --- .eslintignore | 1 - .eslintrc.js | 4 - .github/workflows/storybook-pages.yml | 2 +- .gitignore | 1 - .wp-env.json | 2 +- bin/build-plugin-zip.sh | 7 +- bin/plugin/commands/performance.js | 2 +- bin/plugin/commands/release.js | 19 +- changelog.txt | 285 +- docs/contributors/release.md | 4 +- docs/contributors/testing-overview.md | 3 +- .../block-api/block-registration.md | 35 +- .../developers/block-api/block-supports.md | 22 +- .../developers/block-api/block-templates.md | 4 +- .../developers/data/data-core-block-editor.md | 34 + .../developers/data/data-core-editor.md | 28 +- .../developers/data/data-core.md | 3 +- docs/manifest.json | 6 + gutenberg.php | 2 +- lib/block-directory.php | 54 - lib/block-patterns.php | 66 - lib/class-wp-block-list.php | 194 - ...s-wp-block-pattern-categories-registry.php | 144 - lib/class-wp-block-patterns-registry.php | 157 - lib/class-wp-block.php | 243 - ...ass-wp-rest-block-directory-controller.php | 343 - lib/class-wp-rest-block-types-controller.php | 528 -- lib/class-wp-rest-image-editor-controller.php | 362 - lib/class-wp-rest-plugins-controller.php | 950 --- lib/class-wp-theme-json-resolver.php | 7 +- lib/class-wp-theme-json.php | 111 +- lib/compat.php | 333 - lib/edit-site-page.php | 13 +- lib/full-site-editing/page-templates.php | 42 + lib/global-styles.php | 69 +- lib/load.php | 31 +- lib/patterns/heading-paragraph.php | 13 - lib/patterns/large-header-button.php | 13 - lib/patterns/large-header.php | 13 - lib/patterns/quote.php | 14 - lib/patterns/text-three-columns-buttons.php | 13 - lib/patterns/text-two-columns-with-images.php | 13 - lib/patterns/text-two-columns.php | 13 - lib/patterns/three-buttons.php | 14 - lib/patterns/two-buttons.php | 14 - lib/patterns/two-images.php | 13 - lib/rest-api.php | 164 - lib/template-loader.php | 3 +- package-lock.json | 7233 +++++++---------- package.json | 21 +- .../downloadable-blocks-list/index.js | 3 +- packages/block-editor/README.md | 25 +- .../block-editor/src/autocompleters/block.js | 7 - .../src/components/alignment-toolbar/index.js | 5 +- .../src/components/block-card/index.js | 13 +- .../src/components/block-inspector/index.js | 30 +- .../block-list/block-list-item.native.js | 85 +- .../src/components/block-list/block.native.js | 33 +- .../components/block-list/block.native.scss | 10 + .../src/components/block-list/index.js | 1 + .../src/components/block-list/index.native.js | 18 +- .../components/block-list/insertion-point.js | 4 +- .../components/block-list/style.native.scss | 9 +- .../src/components/block-list/style.scss | 4 + .../block-list/subdirectory-icon.js | 5 +- .../block-mobile-toolbar/index.native.js | 20 +- .../block-mobile-toolbar/style.native.scss | 8 +- .../src/components/block-mover/button.js | 25 +- .../components/block-mover/index.native.js | 78 +- .../block-mover/mover-description.js | 10 +- .../test/__snapshots__/index.native.js.snap | 51 + .../block-mover/test/index.native.js | 51 + .../block-navigation/block-select-button.js | 16 +- .../components/block-patterns-list/index.js | 70 +- .../components/block-patterns-list/style.scss | 4 + .../block-selection-clearer/index.js | 13 +- .../block-switcher/block-styles-menu.js | 56 + .../block-transformations-menu.js | 29 +- .../src/components/block-switcher/index.js | 354 +- .../block-switcher/preview-block-popover.js | 31 + .../components/block-switcher/test/index.js | 90 +- .../src/components/block-title/index.js | 27 +- .../src/components/block-title/test/index.js | 19 +- .../src/components/contrast-checker/README.md | 73 + .../floating-toolbar/nav-up-icon.js | 5 +- packages/block-editor/src/components/index.js | 1 + .../components/inner-blocks/index.native.js | 2 + .../index.js} | 4 +- .../components/inserter-list-item/index.js | 6 +- .../components/inserter/block-patterns-tab.js | 2 +- .../src/components/inserter/preview-panel.js | 21 +- .../src/components/inserter/search-results.js | 1 + .../components/link-control/link-preview.js | 3 +- .../src/components/link-control/style.scss | 2 +- .../provider/test/use-block-sync.js | 4 +- .../src/components/provider/use-block-sync.js | 79 +- .../src/components/url-popover/README.md | 2 +- .../use-block-display-information/README.md | 42 + .../use-block-display-information/index.js | 70 + packages/block-editor/src/hooks/style.js | 25 +- packages/block-editor/src/store/defaults.js | 1 - packages/block-editor/src/store/selectors.js | 208 +- .../block-editor/src/store/test/selectors.js | 217 + .../src/block/edit-panel/editor.scss | 60 - .../src/block/edit-panel/index.js | 129 - packages/block-library/src/block/edit.js | 145 +- packages/block-library/src/code/style.scss | 12 +- .../block-library/src/column/edit.native.js | 68 +- .../src/column/editor.native.scss | 12 +- .../src/columns/columnCalculations.native.js | 178 + .../block-library/src/columns/edit.native.js | 151 +- .../src/columns/editor.native.scss | 7 +- packages/block-library/src/columns/utils.js | 13 +- packages/block-library/src/editor.scss | 5 - .../block-library/src/embed/variations.js | 12 + packages/block-library/src/gallery/edit.js | 2 +- .../src/gallery/gallery.native.js | 8 +- .../block-library/src/group/edit.native.js | 46 +- .../src/group/editor.native.scss | 11 +- packages/block-library/src/html/edit.js | 2 +- packages/block-library/src/html/editor.scss | 2 +- .../block-library/src/image/edit.native.js | 77 +- packages/block-library/src/image/image.js | 31 +- packages/block-library/src/list/edit.js | 15 +- .../block-library/src/navigation/style.scss | 4 +- packages/block-library/src/paragraph/edit.js | 8 +- .../block-library/src/post-excerpt/index.php | 2 +- packages/block-library/src/query-loop/edit.js | 8 +- packages/block-library/src/rss/editor.scss | 6 - packages/block-library/src/rss/style.scss | 5 + packages/block-library/src/site-logo/edit.js | 8 +- .../block-library/src/site-logo/index.php | 2 +- .../src/social-link/variations.js | 11 + packages/block-library/src/tag-cloud/edit.js | 2 +- packages/blocks/src/api/constants.js | 17 +- .../api/raw-handling/get-raw-transforms.js | 24 + .../src/api/raw-handling/html-to-blocks.js | 47 + packages/blocks/src/api/raw-handling/index.js | 72 +- .../src/api/raw-handling/paste-handler.js | 72 +- .../blocks/src/api/raw-handling/test/utils.js | 18 +- packages/blocks/src/api/raw-handling/utils.js | 37 +- packages/blocks/src/api/registration.js | 8 + packages/components/CHANGELOG.md | 3 + .../src/alignment-matrix-control/index.js | 6 +- .../components/src/base-control/README.md | 2 +- .../components/src/combobox-control/index.js | 8 +- .../src/combobox-control/stories/index.js | 13 +- packages/components/src/date-time/date.js | 2 +- .../components/src/date-time/stories/index.js | 37 +- .../stories/with-days-highlighted.js | 52 - .../src/focal-point-picker/README.md | 2 +- .../src/higher-order/with-notices/README.md | 33 + packages/components/src/index.native.js | 2 + .../mobile/bottom-sheet/range-cell.native.js | 5 +- .../bottom-sheet/range-text-input.native.js | 16 +- .../src/mobile/link-settings/index.native.js | 44 +- .../src/mobile/utils/alignments.native.js | 23 +- .../use-unit-converter-to-mobile.native.js | 54 +- .../src/navigation/back-button/index.js | 7 +- .../components/src/navigation/group/index.js | 3 - packages/components/src/navigation/index.js | 4 +- .../src/navigation/item/base-content.js | 8 +- .../components/src/navigation/item/index.js | 5 +- .../src/navigation/menu/menu-title.js | 3 - .../navigation/styles/navigation-styles.js | 20 +- .../components/src/number-control/index.js | 7 +- packages/components/src/popover/README.md | 2 +- packages/components/src/popover/utils.js | 14 +- .../components/src/range-control/README.md | 2 +- .../components/src/range-control/index.js | 9 +- packages/components/src/range-control/rail.js | 9 +- .../src/range-control/stories/index.js | 23 +- .../src/resizable-box/resize-tooltip/label.js | 8 +- .../components/src/text-highlight/README.md | 10 +- .../components/src/toolbar-button/README.md | 2 +- .../components/src/toolbar-item/README.md | 2 +- .../src/toolbar/toolbar-container.js | 4 +- packages/components/src/utils/rtl.js | 29 +- packages/components/src/utils/style-mixins.js | 2 +- .../hooks/use-resize-observer/index.native.js | 5 +- packages/core-data/README.md | 3 +- packages/core-data/src/actions.js | 69 +- packages/core-data/src/entity-provider.js | 52 +- .../core-data/src/queried-data/actions.js | 11 +- packages/core-data/src/reducer.js | 9 +- packages/core-data/src/test/actions.js | 28 +- packages/create-block/CHANGELOG.md | 9 + packages/create-block/README.md | 1 + .../create-block/lib/init-package-json.js | 35 +- packages/create-block/lib/init-wp-scripts.js | 4 +- packages/create-block/lib/scaffold.js | 4 +- packages/create-block/lib/templates.js | 6 + .../lib/templates/es5/index.js.mustache | 2 +- .../lib/templates/esnext/src/save.js.mustache | 10 +- packages/create-block/package.json | 1 + packages/e2e-test-utils/src/inserter.js | 12 +- packages/e2e-test-utils/src/save-draft.js | 1 + .../e2e-tests/config/setup-test-framework.js | 49 - .../plugins/block-variations/index.js | 4 + .../specs/editor/plugins/block-variations.js | 73 + .../reusable-blocks.test.js.snap | 2 +- .../editor/various/change-detection.test.js | 28 +- .../specs/editor/various/editor-modes.test.js | 21 +- .../editor/various/font-size-picker.test.js | 82 +- .../various/keyboard-navigable-blocks.test.js | 16 +- .../editor/various/reusable-blocks.test.js | 346 +- .../specs/editor/various/rtl.test.js | 1 + .../experiments/blocks/post-title.test.js | 2 +- .../experiments/multi-entity-editing.test.js | 2 +- .../experiments/multi-entity-saving.test.js | 4 +- .../post-editor-template-mode.test.js | 2 +- .../specs/experiments/template-part.test.js | 2 +- .../specs/performance/site-editor.test.js | 2 +- packages/edit-post/README.md | 12 + .../src/components/device-preview/index.js | 13 +- .../components/header/feature-toggle/index.js | 9 +- .../header/fullscreen-mode-close/index.js | 7 +- .../components/header/header-toolbar/index.js | 17 +- .../header/header-toolbar/index.native.js | 6 +- .../edit-post/src/components/header/index.js | 13 +- .../components/header/mode-switcher/index.js | 9 +- .../header/post-publish-button-or-toggle.js | 9 +- .../header/preferences-menu-item/index.js | 7 +- .../keyboard-shortcut-help-modal/index.js | 5 +- .../components/keyboard-shortcuts/index.js | 11 +- .../src/components/layout/actions-panel.js | 9 +- .../edit-post/src/components/layout/index.js | 23 +- .../src/components/layout/index.native.js | 3 +- .../manage-blocks-modal/category.js | 5 +- .../components/manage-blocks-modal/index.js | 5 +- .../components/manage-blocks-modal/manager.js | 3 +- .../src/components/meta-boxes/index.js | 3 +- .../meta-boxes/meta-box-visibility.js | 7 +- .../meta-boxes/meta-boxes-area/index.js | 7 +- .../src/components/preferences-modal/index.js | 7 +- .../preferences-modal/meta-boxes-section.js | 3 +- .../options/enable-feature.js | 6 +- .../preferences-modal/options/enable-panel.js | 5 +- .../sidebar/discussion-panel/index.js | 13 +- .../sidebar/featured-image/index.js | 9 +- .../sidebar/page-attributes/index.js | 9 +- .../plugin-document-setting-panel/index.js | 7 +- .../sidebar/plugin-sidebar/index.js | 7 +- .../components/sidebar/post-excerpt/index.js | 13 +- .../src/components/sidebar/post-link/index.js | 9 +- .../components/sidebar/post-status/index.js | 5 +- .../sidebar/post-taxonomies/taxonomy-panel.js | 11 +- .../components/sidebar/post-template/index.js | 4 +- .../sidebar/settings-header/index.js | 7 +- .../sidebar/settings-sidebar/index.js | 3 +- .../src/components/text-editor/index.js | 7 +- .../visual-editor/block-inspector-button.js | 9 +- .../src/components/visual-editor/index.js | 6 +- .../src/components/welcome-guide/index.js | 6 +- packages/edit-post/src/editor.js | 11 +- packages/edit-post/src/editor.native.js | 5 +- packages/edit-post/src/index.js | 2 +- packages/edit-post/src/index.native.js | 2 +- .../index.js | 7 +- .../plugins/manage-blocks-menu-item/index.js | 7 +- .../plugins/welcome-guide-menu-item/index.js | 7 +- packages/edit-post/src/store/actions.js | 14 +- .../src/components/block-editor/index.js | 17 +- .../editor/global-styles-provider.js | 10 +- .../editor/global-styles-renderer.js | 48 +- .../edit-site/src/components/editor/index.js | 40 +- .../edit-site/src/components/header/index.js | 10 +- .../navigation-panel/templates-navigation.js | 35 +- .../src/components/sidebar/color-panel.js | 34 +- .../sidebar/global-styles-sidebar.js | 43 +- .../src/components/sidebar/spacing-panel.js | 63 + .../components/sidebar/typography-panel.js | 24 +- .../components/url-query-controller/index.js | 25 +- packages/edit-site/src/store/reducer.js | 80 +- packages/edit-site/src/store/selectors.js | 27 +- packages/edit-site/src/store/test/reducer.js | 118 +- .../edit-site/src/store/test/selectors.js | 29 +- packages/editor/package.json | 1 - .../components/post-publish-button/index.js | 8 +- packages/editor/src/store/actions.js | 34 +- packages/editor/src/store/constants.js | 1 - packages/editor/src/store/reducer.js | 29 +- packages/editor/src/store/reducer.native.js | 35 +- packages/editor/src/store/selectors.js | 107 +- packages/editor/src/store/test/actions.js | 29 +- packages/editor/src/store/test/selectors.js | 163 - .../link-settings-screen.native.js | 33 +- .../format-library/src/text-color/index.js | 5 +- packages/keycodes/CHANGELOG.md | 8 +- packages/keycodes/README.md | 77 +- packages/keycodes/package.json | 1 + packages/keycodes/src/index.js | 155 +- packages/keycodes/src/platform.js | 4 +- packages/keycodes/src/platform.native.js | 2 +- packages/keycodes/tsconfig.json | 9 + .../GutenbergBridgeJS2Parent.java | 4 +- .../RNReactNativeGutenbergBridgeModule.java | 9 +- .../mobile/WPAndroidGlue/AddMentionUtil.java | 7 - .../mobile/WPAndroidGlue/GutenbergProps.kt | 3 + .../WPAndroidGlue/ShowSuggestionsUtil.java | 8 + .../WPAndroidGlue/WPAndroidGlueCode.java | 14 +- packages/react-native-bridge/index.js | 8 +- .../ios/GutenbergBridgeDelegate.swift | 5 + .../ios/RNReactNativeGutenbergBridge.m | 3 +- .../ios/RNReactNativeGutenbergBridge.swift | 14 +- packages/react-native-editor/CHANGELOG.md | 11 +- .../__device-tests__/pages/editor-page.js | 4 +- .../main/java/com/gutenberg/MainActivity.java | 1 + .../java/com/gutenberg/MainApplication.java | 9 +- .../GutenbergViewController.swift | 5 + packages/react-native-editor/ios/Podfile.lock | 8 +- .../rich-text/src/component/index.native.js | 132 +- .../toolbar-button-with-options.native.js | 61 + .../src/component/use-format-types.js | 6 +- packages/rich-text/src/get-format-type.js | 6 +- packages/rich-text/src/get-format-types.js | 6 +- .../rich-text/src/register-format-type.js | 13 +- .../src/test/register-format-type.js | 3 +- .../rich-text/src/unregister-format-type.js | 9 +- packages/scripts/CHANGELOG.md | 4 + packages/scripts/config/webpack.config.js | 36 +- packages/scripts/utils/index.js | 9 +- packages/scripts/utils/package.js | 3 + packages/stylelint-config/.npmrc | 1 + packages/stylelint-config/CHANGELOG.md | 250 + packages/stylelint-config/LICENSE | 22 + packages/stylelint-config/README.md | 57 + packages/stylelint-config/index.js | 131 + packages/stylelint-config/package.json | 52 + packages/stylelint-config/scss.js | 36 + .../stylelint-config/test/.stylelintrc.json | 6 + .../test/__snapshots__/commenting.js.snap | 27 + .../test/__snapshots__/functions.js.snap | 13 + .../test/__snapshots__/index.js.snap | 13 + .../test/__snapshots__/media-queries.js.snap | 83 + .../test/__snapshots__/properties.js.snap | 55 + .../test/__snapshots__/selectors-scss.js.snap | 48 + .../test/__snapshots__/selectors.js.snap | 62 + .../test/__snapshots__/structure.js.snap | 62 + .../test/__snapshots__/values.js.snap | 69 + .../test/commenting-invalid.css | 24 + .../test/commenting-valid.css | 29 + packages/stylelint-config/test/commenting.js | 66 + .../stylelint-config/test/css-invalid.css | 3 + packages/stylelint-config/test/css-valid.css | 3 + .../test/functions-invalid.css | 5 + .../stylelint-config/test/functions-valid.css | 7 + packages/stylelint-config/test/functions.js | 66 + packages/stylelint-config/test/index.js | 66 + .../test/media-queries-invalid.css | 43 + .../test/media-queries-valid.css | 13 + .../stylelint-config/test/media-queries.js | 66 + .../test/properties-invalid.css | 7 + .../test/properties-valid.css | 6 + packages/stylelint-config/test/properties.js | 66 + .../stylelint-config/test/scss-invalid.scss | 32 + .../stylelint-config/test/scss-valid.scss | 32 + packages/stylelint-config/test/scss.js | 67 + .../test/selectors-invalid.css | 31 + .../test/selectors-invalid.scss | 34 + .../stylelint-config/test/selectors-scss.js | 66 + .../stylelint-config/test/selectors-valid.css | 19 + .../test/selectors-valid.scss | 37 + packages/stylelint-config/test/selectors.js | 66 + .../test/structure-invalid.css | 7 + .../stylelint-config/test/structure-valid.css | 29 + packages/stylelint-config/test/structure.js | 66 + .../stylelint-config/test/themes-valid.css | 16 + packages/stylelint-config/test/themes.js | 35 + .../stylelint-config/test/values-invalid.css | 17 + .../stylelint-config/test/values-valid.css | 15 + packages/stylelint-config/test/values.js | 66 + .../test/vendor-prefixes-valid.css | 5 + .../stylelint-config/test/vendor-prefixes.js | 35 + packages/url/CHANGELOG.md | 4 + packages/url/README.md | 2 + packages/url/src/filter-url-for-display.js | 39 +- packages/url/src/remove-query-args.js | 3 +- packages/url/src/test/index.test.js | 56 + ...register-block-type-from-metadata-test.php | 216 - phpunit/class-wp-block-list-test.php | 100 - phpunit/class-wp-block-test.php | 355 - phpunit/class-wp-theme-json-test.php | 65 +- readme.txt | 4 +- storybook/.babelrc | 7 +- test/unit/config/register-context.js | 6 - test/unit/jest.config.js | 1 - tsconfig.json | 1 + 388 files changed, 9471 insertions(+), 11956 deletions(-) delete mode 100644 lib/block-directory.php delete mode 100644 lib/block-patterns.php delete mode 100644 lib/class-wp-block-list.php delete mode 100644 lib/class-wp-block-pattern-categories-registry.php delete mode 100644 lib/class-wp-block-patterns-registry.php delete mode 100644 lib/class-wp-block.php delete mode 100644 lib/class-wp-rest-block-directory-controller.php delete mode 100644 lib/class-wp-rest-block-types-controller.php delete mode 100644 lib/class-wp-rest-image-editor-controller.php delete mode 100644 lib/class-wp-rest-plugins-controller.php create mode 100644 lib/full-site-editing/page-templates.php delete mode 100644 lib/patterns/heading-paragraph.php delete mode 100644 lib/patterns/large-header-button.php delete mode 100644 lib/patterns/large-header.php delete mode 100644 lib/patterns/quote.php delete mode 100644 lib/patterns/text-three-columns-buttons.php delete mode 100644 lib/patterns/text-two-columns-with-images.php delete mode 100644 lib/patterns/text-two-columns.php delete mode 100644 lib/patterns/three-buttons.php delete mode 100644 lib/patterns/two-buttons.php delete mode 100644 lib/patterns/two-images.php create mode 100644 packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap create mode 100644 packages/block-editor/src/components/block-mover/test/index.native.js create mode 100644 packages/block-editor/src/components/block-switcher/block-styles-menu.js create mode 100644 packages/block-editor/src/components/block-switcher/preview-block-popover.js create mode 100644 packages/block-editor/src/components/contrast-checker/README.md rename packages/block-editor/src/components/{inserter-list-item/draggable.js => inserter-draggable-blocks/index.js} (84%) create mode 100644 packages/block-editor/src/components/use-block-display-information/README.md create mode 100644 packages/block-editor/src/components/use-block-display-information/index.js delete mode 100644 packages/block-library/src/block/edit-panel/editor.scss delete mode 100644 packages/block-library/src/block/edit-panel/index.js create mode 100644 packages/block-library/src/columns/columnCalculations.native.js create mode 100644 packages/blocks/src/api/raw-handling/get-raw-transforms.js create mode 100644 packages/blocks/src/api/raw-handling/html-to-blocks.js delete mode 100644 packages/components/src/date-time/stories/with-days-highlighted.js create mode 100644 packages/edit-site/src/components/sidebar/spacing-panel.js create mode 100644 packages/keycodes/tsconfig.json delete mode 100644 packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/AddMentionUtil.java create mode 100644 packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/ShowSuggestionsUtil.java create mode 100644 packages/rich-text/src/component/toolbar-button-with-options.native.js create mode 100644 packages/stylelint-config/.npmrc create mode 100644 packages/stylelint-config/CHANGELOG.md create mode 100644 packages/stylelint-config/LICENSE create mode 100644 packages/stylelint-config/README.md create mode 100644 packages/stylelint-config/index.js create mode 100644 packages/stylelint-config/package.json create mode 100644 packages/stylelint-config/scss.js create mode 100644 packages/stylelint-config/test/.stylelintrc.json create mode 100644 packages/stylelint-config/test/__snapshots__/commenting.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/functions.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/index.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/media-queries.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/properties.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/selectors-scss.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/selectors.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/structure.js.snap create mode 100644 packages/stylelint-config/test/__snapshots__/values.js.snap create mode 100644 packages/stylelint-config/test/commenting-invalid.css create mode 100644 packages/stylelint-config/test/commenting-valid.css create mode 100644 packages/stylelint-config/test/commenting.js create mode 100644 packages/stylelint-config/test/css-invalid.css create mode 100644 packages/stylelint-config/test/css-valid.css create mode 100644 packages/stylelint-config/test/functions-invalid.css create mode 100644 packages/stylelint-config/test/functions-valid.css create mode 100644 packages/stylelint-config/test/functions.js create mode 100644 packages/stylelint-config/test/index.js create mode 100644 packages/stylelint-config/test/media-queries-invalid.css create mode 100644 packages/stylelint-config/test/media-queries-valid.css create mode 100644 packages/stylelint-config/test/media-queries.js create mode 100644 packages/stylelint-config/test/properties-invalid.css create mode 100644 packages/stylelint-config/test/properties-valid.css create mode 100644 packages/stylelint-config/test/properties.js create mode 100644 packages/stylelint-config/test/scss-invalid.scss create mode 100644 packages/stylelint-config/test/scss-valid.scss create mode 100644 packages/stylelint-config/test/scss.js create mode 100644 packages/stylelint-config/test/selectors-invalid.css create mode 100644 packages/stylelint-config/test/selectors-invalid.scss create mode 100644 packages/stylelint-config/test/selectors-scss.js create mode 100644 packages/stylelint-config/test/selectors-valid.css create mode 100644 packages/stylelint-config/test/selectors-valid.scss create mode 100644 packages/stylelint-config/test/selectors.js create mode 100644 packages/stylelint-config/test/structure-invalid.css create mode 100644 packages/stylelint-config/test/structure-valid.css create mode 100644 packages/stylelint-config/test/structure.js create mode 100644 packages/stylelint-config/test/themes-valid.css create mode 100644 packages/stylelint-config/test/themes.js create mode 100644 packages/stylelint-config/test/values-invalid.css create mode 100644 packages/stylelint-config/test/values-valid.css create mode 100644 packages/stylelint-config/test/values.js create mode 100644 packages/stylelint-config/test/vendor-prefixes-valid.css create mode 100644 packages/stylelint-config/test/vendor-prefixes.js delete mode 100644 phpunit/class-register-block-type-from-metadata-test.php delete mode 100644 phpunit/class-wp-block-list-test.php delete mode 100644 phpunit/class-wp-block-test.php delete mode 100644 test/unit/config/register-context.js diff --git a/.eslintignore b/.eslintignore index b6206ec553a90f..9a603c2bceb3d4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,7 +6,6 @@ node_modules packages/block-serialization-spec-parser/parser.js packages/e2e-tests/plugins packages/react-native-editor/bundle -playground/dist vendor wordpress !.*.js diff --git a/.eslintrc.js b/.eslintrc.js index 6d841c60444bed..4f848acaf2bdfb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -121,10 +121,6 @@ module.exports = { 'Avoid truthy checks on length property rendering, as zero length is rendered verbatim.', }, ], - // Temporarily converted to warning until all errors are resolved. - // See https://github.com/WordPress/gutenberg/pull/22771 for the eslint-plugin-jsdoc update. - 'jsdoc/check-param-names': 'warn', - 'jsdoc/require-param': 'warn', }, overrides: [ { diff --git a/.github/workflows/storybook-pages.yml b/.github/workflows/storybook-pages.yml index 0c66e9b9e92e55..f3a956c75841d6 100644 --- a/.github/workflows/storybook-pages.yml +++ b/.github/workflows/storybook-pages.yml @@ -42,4 +42,4 @@ jobs: uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./playground/dist + publish_dir: ./storybook/build diff --git a/.gitignore b/.gitignore index cf7a035b43b060..d79599e194f3cf 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,6 @@ yarn.lock /wordpress /artifacts -playground/dist .cache *.tsbuildinfo diff --git a/.wp-env.json b/.wp-env.json index 41ecee8042bb17..ccd1231aa28b25 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -3,7 +3,7 @@ "plugins": [ "." ], - "themes": [ "WordPress/theme-experiments/twentytwentyone-blocks" ], + "themes": [ "WordPress/theme-experiments/tt1-blocks" ], "env": { "tests": { "mappings": { diff --git a/bin/build-plugin-zip.sh b/bin/build-plugin-zip.sh index a8e91093205a2f..5d9de9b55b79ef 100755 --- a/bin/build-plugin-zip.sh +++ b/bin/build-plugin-zip.sh @@ -111,8 +111,11 @@ mv gutenberg.tmp.php gutenberg.php build_files=$( ls build/*/*.{js,css,asset.php} \ - build/block-library/blocks/*.php build/block-library/blocks/*/block.json \ - build/edit-widgets/blocks/*.php build/edit-widgets/blocks/*/block.json \ + build/block-library/blocks/*.php \ + build/block-library/blocks/*/block.json \ + build/block-library/blocks/*/*.css \ + build/edit-widgets/blocks/*.php \ + build/edit-widgets/blocks/*/block.json \ ) diff --git a/bin/plugin/commands/performance.js b/bin/plugin/commands/performance.js index 22f7f2e7eade47..4a2cfa2df29686 100644 --- a/bin/plugin/commands/performance.js +++ b/bin/plugin/commands/performance.js @@ -205,8 +205,8 @@ async function runTestSuite( testSuite, performanceTestDirectory ) { /** * Runs the performances tests on an array of branches and output the result. * - * @param {WPPerformanceCommandOptions} options Command options. * @param {string[]} branches Branches to compare + * @param {WPPerformanceCommandOptions} options Command options. */ async function runPerformanceTests( branches, options ) { // The default value doesn't work because commander provides an array. diff --git a/bin/plugin/commands/release.js b/bin/plugin/commands/release.js index 56a232d13882c4..16f8f8796e9033 100644 --- a/bin/plugin/commands/release.js +++ b/bin/plugin/commands/release.js @@ -6,6 +6,7 @@ const fs = require( 'fs' ); const semver = require( 'semver' ); const Octokit = require( '@octokit/rest' ); const { sprintf } = require( 'sprintf-js' ); +const os = require( 'os' ); /** * Internal dependencies @@ -518,13 +519,27 @@ async function runUpdateTrunkContentStep( newReadmeFileContent.replace( STABLE_TAG_PLACEHOLDER, stableTag ) ); + let xargsOpts = ''; + if ( os.platform === 'linux' ) { + // When xargs receives no arguments, it behaves differently in macOS and linux: + // - macOS: doesn't run + // - linux: run without arguments + // + // In linux, the -r option teaches xargs not to run if it receives no arguments. + xargsOpts = '-r'; + } + // Commit the content changes runShellScript( - "svn st | grep '^?' | awk '{print $2}' | xargs svn add", + "svn st | grep '^?' | awk '{print $2}' | xargs " + + xargsOpts + + ' svn add', svnWorkingDirectoryPath ); runShellScript( - "svn st | grep '^!' | awk '{print $2}' | xargs svn rm", + "svn st | grep '^!' | awk '{print $2}' | xargs " + + xargsOpts + + ' svn rm', svnWorkingDirectoryPath ); await askForConfirmation( diff --git a/changelog.txt b/changelog.txt index a3130d3329dfca..50b95587a200da 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,8 +1,289 @@ == Changelog == -= 9.6.0-rc.1 = += 9.7.0-rc.1 = + +### Features + +- Support drag and dropping block patterns from the inserter. ([27927](https://github.com/WordPress/gutenberg/pull/27927)) + +### Enhancements + +- Improve the Reusable Blocks UI by relying on multi entity save flow. ([27887](https://github.com/WordPress/gutenberg/pull/27887)) +- Show the insertion point indicator bellow the inbetween inserter. ([27842](https://github.com/WordPress/gutenberg/pull/27842)) +- URL: RemoveQueryArgs should remove the ? char after removing all args. ([27812](https://github.com/WordPress/gutenberg/pull/27812)) +- URL: Enhance the way long URLs are handled in filterURLForDisplay. ([27530](https://github.com/WordPress/gutenberg/pull/27530)) +- ComboboxControl: Updated component to deburr options labels before filter. ([26611](https://github.com/WordPress/gutenberg/pull/26611)) + +### New APIs + +- Create block: Allow to list npm packages to be installed in the template. ([27880](https://github.com/WordPress/gutenberg/pull/27880)) +- Display Block Information by matching block variations. ([27469](https://github.com/WordPress/gutenberg/pull/27469)) + +### Bug Fixes + +- Don't ignore extra edits made in the server when saving posts. ([27929](https://github.com/WordPress/gutenberg/pull/27929)) +- Allow using multiple controlled inner blocks refering to the same entity. ([27885](https://github.com/WordPress/gutenberg/pull/27885)) +- Remove the animation of post publish button during autosaving. ([27874](https://github.com/WordPress/gutenberg/pull/27874)) +- Remove default style information from the documentation. ([27811](https://github.com/WordPress/gutenberg/pull/27811)) +- Storybook: Fix broken import statements for DateTime component. ([27794](https://github.com/WordPress/gutenberg/pull/27794)) +- Pattern Inserter: Fix bug where the inserter cannot be closed if the user changes pattern category. ([27792](https://github.com/WordPress/gutenberg/pull/27792)) +- Create Block: Another try to fix support for external templates. ([27784](https://github.com/WordPress/gutenberg/pull/27784)) +- LinkControl: Fix horizontal scrollbar within block toolbar. ([27777](https://github.com/WordPress/gutenberg/pull/27777)) +- Create Block: Fix support for external templates hosted on npm. ([27776](https://github.com/WordPress/gutenberg/pull/27776)) +- Fix for bug #21989, #21650. ([27691](https://github.com/WordPress/gutenberg/pull/27691)) +- HTML Block: Fix editor styles. ([27627](https://github.com/WordPress/gutenberg/pull/27627)) +- Fix: Text color dropdown not showing up after clicking for the first time. ([27596](https://github.com/WordPress/gutenberg/pull/27596)) + +### Experiments + +- Site Logo: Remove duplicate link. ([27924](https://github.com/WordPress/gutenberg/pull/27924)) +- Post excerpt block: Fix incorrect quotes for the class attribute in the wrapper. ([27895](https://github.com/WordPress/gutenberg/pull/27895)) +- Refactor the edit-site store to clarify the purpose of templateId and templatePartId. ([27839](https://github.com/WordPress/gutenberg/pull/27839)) +- Add support for custom templates in FSE themes. ([27778](https://github.com/WordPress/gutenberg/pull/27778)) +- RSS Block: Add border-box CSS. ([27767](https://github.com/WordPress/gutenberg/pull/27767)) +- Add padding control to the Global Styles sidebar. ([27154](https://github.com/WordPress/gutenberg/pull/27154)) +- Navigation block: Fix the text color for links in the navigation block. ([26698](https://github.com/WordPress/gutenberg/pull/26698)) + +### Documentation + +- Fix: OpenURLPopover bind typo (DOCS). ([27909](https://github.com/WordPress/gutenberg/pull/27909)) +- Improve documentation for withNotices HOC in components package. ([27863](https://github.com/WordPress/gutenberg/pull/27863)) +- Docs: Fix typos in components package. ([27799](https://github.com/WordPress/gutenberg/pull/27799)) +- Add ContrastChecker component readme (block-editor). ([25570](https://github.com/WordPress/gutenberg/pull/25570)) + +### Code Quality + +- Use a consistent way to check isRTL. ([27838](https://github.com/WordPress/gutenberg/pull/27838)) +- Update the minimum required WordPress version to 5.5. ([27807](https://github.com/WordPress/gutenberg/pull/27807)) +- Remove unused redux-optimist dependency. ([27798](https://github.com/WordPress/gutenberg/pull/27798)) +- Storybook: Perform cleanup in the Storybook setup. ([27786](https://github.com/WordPress/gutenberg/pull/27786)) +- Raw handling: Remove duplicate code. ([27758](https://github.com/WordPress/gutenberg/pull/27758)) +- Refactor BlockSwitcher - make function component and new specific selector `getBlockTransformItems`. ([27674](https://github.com/WordPress/gutenberg/pull/27674)) + +### Tools + +- Code quality: Remove overrides for JSDoc rules downgraded to warnings (take 2). ([27912](https://github.com/WordPress/gutenberg/pull/27912)) +- Fix svn add/rm commands for release tool. ([27886](https://github.com/WordPress/gutenberg/pull/27886)) +- Include block CSS in the plugin ZIP. ([27884](https://github.com/WordPress/gutenberg/pull/27884)) +- Code quality: Remove overrides for JSDoc rules downgraded to warnings. ([27879](https://github.com/WordPress/gutenberg/pull/27879)) +- Make end to end tests do not rely on font size picker classes. ([27825](https://github.com/WordPress/gutenberg/pull/27825)) +- Remove expect.assertions count from multi-entity-saving tests. ([27818](https://github.com/WordPress/gutenberg/pull/27818)) +- [e2e tests]: Fix assertions number check. ([27802](https://github.com/WordPress/gutenberg/pull/27802)) +- Testing: Remove axe verification executed after every test case. ([26626](https://github.com/WordPress/gutenberg/pull/26626)) +- Add new package `@wordpress/stylelint config`. ([22777](https://github.com/WordPress/gutenberg/pull/22777)) +- Keycodes: Add, enhance types. ([19520](https://github.com/WordPress/gutenberg/pull/19520)) + +### Various + +- Show all taxonomies in Tag Cloud block. ([27930](https://github.com/WordPress/gutenberg/pull/27930)) +- Revert "Code quality: Remove overrides for JSDoc rules downgraded to warnings". ([27908](https://github.com/WordPress/gutenberg/pull/27908)) +- Update: Improve font size end to end tests to work with input changes on blur. ([27871](https://github.com/WordPress/gutenberg/pull/27871)) +- Add block transforms preview. ([27861](https://github.com/WordPress/gutenberg/pull/27861)) +- Add additional information about lock inheritance. ([27834](https://github.com/WordPress/gutenberg/pull/27834)) +- Rich Text: Replace store name string with exposed store definition. ([27820](https://github.com/WordPress/gutenberg/pull/27820)) +- Storybook: Updgrade to the latest version. ([27813](https://github.com/WordPress/gutenberg/pull/27813)) +- Update Twenty Twenty-One theme references. ([27770](https://github.com/WordPress/gutenberg/pull/27770)) + + + += 9.6.2 = + +### Bug Fixes + + - Fix toolbar controls in the widgets screen. + - Fix the slash inserter in the widgets screen. + + += 9.6.1 = + +### Bugfixes + +- Include block's CSS in the release for FSE themes ([27884](https://github.com/WordPress/gutenberg/pull/27884)) + + += 9.6.0 = + + +### Features + +- Allow dragging blocks from the inserter into the canvas. ([27669](https://github.com/WordPress/gutenberg/pull/27669)) +- Buttons: Add variations for vertical layout. ([27297](https://github.com/WordPress/gutenberg/pull/27297)) + +### Enhancements + +- Buttons block: Change position of the link popover. ([27408](https://github.com/WordPress/gutenberg/pull/27408)) + +### New APIs + +- Add a useFocusOnMount hook to the @wordpress/compose package. ([27574](https://github.com/WordPress/gutenberg/pull/27574)) +- Add a useFocusReturn hook. ([27572](https://github.com/WordPress/gutenberg/pull/27572)) +- Add a useConstrainedTabbing hook. ([27544](https://github.com/WordPress/gutenberg/pull/27544)) +- Components: Introduce a isDisabled prop to the Disabled component. ([26730](https://github.com/WordPress/gutenberg/pull/26730)) +- Create block: + - Use Block API version 2. ([26098](https://github.com/WordPress/gutenberg/pull/26098)) + - Fix for supporting external templates. ([27784](https://github.com/WordPress/gutenberg/pull/27784)) ([27776](https://github.com/WordPress/gutenberg/pull/27776)) + +### Bug Fixes + +- Widget screen: Fix block select on focus. ([27755](https://github.com/WordPress/gutenberg/pull/27755)) +- [Embed block]: Add html and reusable support back. ([27733](https://github.com/WordPress/gutenberg/pull/27733)) +- Add useCallbackRef to avoid calling the ref multiple times with the same node. ([27710](https://github.com/WordPress/gutenberg/pull/27710)) +- Correct getRedistributedColumnWidths and related tests. ([27681](https://github.com/WordPress/gutenberg/pull/27681)) +- Remove CSS Custom Property in code block. ([27672](https://github.com/WordPress/gutenberg/pull/27672)) +- Fix regression on code block for font-size property ([27862](https://github.com/WordPress/gutenberg/pull/27862)) +- Block crashes if font family is not found. ([27654](https://github.com/WordPress/gutenberg/pull/27654)) +- popover flickering on small screens. ([27648](https://github.com/WordPress/gutenberg/pull/27648)) +- Adding single use block from main inserter causes focus loss and menu to be stuck open. ([27641](https://github.com/WordPress/gutenberg/pull/27641)) +- Changelog for 9.5.2. ([27638](https://github.com/WordPress/gutenberg/pull/27638)) +- Uncaught error with a custom generic store without a unsubscribe function in useSelect. ([27634](https://github.com/WordPress/gutenberg/pull/27634)) +- Revert date changes from branch 'replace-moment'. ([27550](https://github.com/WordPress/gutenberg/pull/27550)) +- useMediaQuery: Make it safe for SSR environments without window. ([27542](https://github.com/WordPress/gutenberg/pull/27542)) +- Fixes the width on the circle color picker popover. ([27523](https://github.com/WordPress/gutenberg/pull/27523)) +- ComboboxControl/FormTokenField: Fix iOS zooming for input. ([27471](https://github.com/WordPress/gutenberg/pull/27471)) +- Fallback to regular subscribe if the store doesn't exist in useSelect. ([27466](https://github.com/WordPress/gutenberg/pull/27466)) +- Global Styles getPresetVariable uses a wrong variable; Remove GLOBAL_CONTEXT. ([27450](https://github.com/WordPress/gutenberg/pull/27450)) +- Popover: Fix issue with undefined getBoundingClientRect. ([27445](https://github.com/WordPress/gutenberg/pull/27445)) +- Try fixing combobox a11y issues. ([27431](https://github.com/WordPress/gutenberg/pull/27431)) +- Support gradients with omitted stop positions in CustomGradientPicker. ([27413](https://github.com/WordPress/gutenberg/pull/27413)) +- Fix combobox suggestion list closure when clicking scrollbar. ([27367](https://github.com/WordPress/gutenberg/pull/27367)) +- Video Block: Let the video fill the container. ([27328](https://github.com/WordPress/gutenberg/pull/27328)) +- Media & Text “crop image to fill” to work with linked media. ([27211](https://github.com/WordPress/gutenberg/pull/27211)) +- Give editable fields in blocks better aria-labels. ([26582](https://github.com/WordPress/gutenberg/pull/26582)) +- Replace function should handle empty string callback return in the shortcode parser. ([16358](https://github.com/WordPress/gutenberg/pull/16358)) + +### Performance + +- Split core blocks assets loading. ([25220](https://github.com/WordPress/gutenberg/pull/25220)) + +### Experiments + +- Add a useDialog hook and replace the duplicated PopoverWrapper. ([27643](https://github.com/WordPress/gutenberg/pull/27643)) +- Refactor withFocusOutside to hook. ([27369](https://github.com/WordPress/gutenberg/pull/27369)) +- FSE: Block Navigation: update Navigation block placeholder. ([27018](https://github.com/WordPress/gutenberg/pull/27018)) +- FSE: Block Query + - Add new post link to Query. ([27732](https://github.com/WordPress/gutenberg/pull/27732)) + - Allow Query Loop only inside Query block. ([27637](https://github.com/WordPress/gutenberg/pull/27637)) + - Adjust mobile margins for the Query block's grid view. ([27619](https://github.com/WordPress/gutenberg/pull/27619)) + - Query block: Allow inheriting the global query arguments. ([27128](https://github.com/WordPress/gutenberg/pull/27128)) +- FSE: Blocks + - Add comment-form block styles. ([27673](https://github.com/WordPress/gutenberg/pull/27673)) + - Tag Cloud block: Adjust styles for the different block alignments. ([27342](https://github.com/WordPress/gutenberg/pull/27342)) + - Site Logo: + - Remove line height. ([27623](https://github.com/WordPress/gutenberg/pull/27623)) + - Add a rounded block style. ([27621](https://github.com/WordPress/gutenberg/pull/27621)) +- FSE: Infrastructure + - Apply hover class in outline mode. ([27714](https://github.com/WordPress/gutenberg/pull/27714)) + - Update documentation to show how a theme can have FSE automatically enabled. ([27680](https://github.com/WordPress/gutenberg/pull/27680)) + - Make the inserter in the site editor behave as a popover. ([27502](https://github.com/WordPress/gutenberg/pull/27502)) + - Add an outline mode and use it both Site Editor and Template mode. ([27499](https://github.com/WordPress/gutenberg/pull/27499)) + - Load the block patterns in the site editor. ([27497](https://github.com/WordPress/gutenberg/pull/27497)) + - Move the templates prePersist logic to core-data. ([27464](https://github.com/WordPress/gutenberg/pull/27464)) + - Expand the multi-entity saving panel by default. ([27437](https://github.com/WordPress/gutenberg/pull/27437)) + - Reveal block boundaries on hover in the Site Editor. ([27271](https://github.com/WordPress/gutenberg/pull/27271)) + - Site Editor - add query args for current context. ([27124](https://github.com/WordPress/gutenberg/pull/27124)) + - Full Site Editing: Introduce a template editing mode inside the post editor. ([26355](https://github.com/WordPress/gutenberg/pull/26355)) + - Remove optimistic updates to solve the template revert issue ([27797](https://github.com/WordPress/gutenberg/pull/27797)) +- FSE: Style System + - Fix: Font Weight and Style don't work independently on global styles. ([27659](https://github.com/WordPress/gutenberg/pull/27659)) + - Add custom units in BoxControl. ([27626](https://github.com/WordPress/gutenberg/pull/27626)) + - Remove Font style, weight, decoration, and transform presets. ([27555](https://github.com/WordPress/gutenberg/pull/27555)) + - Make client preset metadata match server. ([27453](https://github.com/WordPress/gutenberg/pull/27453)) + - Do not pass selectors and supports information to the client. ([27449](https://github.com/WordPress/gutenberg/pull/27449)) + - Add border radius support. ([25791](https://github.com/WordPress/gutenberg/pull/25791)) + - Update font-weight names. ([27718](https://github.com/WordPress/gutenberg/pull/27718)) + - Update performance of global styles code ([27779](https://github.com/WordPress/gutenberg/pull/27779)) + +### Documentation + +- Add missing dependency to code example. ([27742](https://github.com/WordPress/gutenberg/pull/27742)) +- Precise that element ref returned by the hooks that return a ref can change between function or object. ([27610](https://github.com/WordPress/gutenberg/pull/27610)) +- Add escaping functions to code examples. ([27603](https://github.com/WordPress/gutenberg/pull/27603)) +- Add missing @wordpress/components/CHANGELOG.md entry. ([27576](https://github.com/WordPress/gutenberg/pull/27576)) +- Minor changes to release documentation for clarity. ([27571](https://github.com/WordPress/gutenberg/pull/27571)) +- Capitalize JavaScript in accordance with the word mark. ([27539](https://github.com/WordPress/gutenberg/pull/27539)) +- Fix typo in attributes.md. ([27440](https://github.com/WordPress/gutenberg/pull/27440)) +- Try: Update readme screenshot. ([27223](https://github.com/WordPress/gutenberg/pull/27223)) +- Document the useBlockWrapper hook in the block registration documentation. ([26592](https://github.com/WordPress/gutenberg/pull/26592)) +- Add a document explaining the different block API versions. ([26277](https://github.com/WordPress/gutenberg/pull/26277)) +- Update the registration examples to use apiVersion 2. ([26100](https://github.com/WordPress/gutenberg/pull/26100)) + +### Code Quality + +- Remove: Missed unused weights and style translation code. ([27739](https://github.com/WordPress/gutenberg/pull/27739)) +- useDialog: Remove mousedown propagation stopping. ([27725](https://github.com/WordPress/gutenberg/pull/27725)) +- Try: Simplify focus return. ([27705](https://github.com/WordPress/gutenberg/pull/27705)) +- Popover/Modal: Remove and deprecate IsolatedEventContainer. ([27703](https://github.com/WordPress/gutenberg/pull/27703)) +- Popover: Use focus outside hook. ([27700](https://github.com/WordPress/gutenberg/pull/27700)) +- refactor: Tooltip component from classical to functional with hooks. ([27682](https://github.com/WordPress/gutenberg/pull/27682)) +- Template-part padding: Use variables. ([27679](https://github.com/WordPress/gutenberg/pull/27679)) +- Scope image block style variations to only the image block. ([27649](https://github.com/WordPress/gutenberg/pull/27649)) +- Refactor the EditorProvider component and extract hooks. ([27605](https://github.com/WordPress/gutenberg/pull/27605)) +- Use store definition instead of string for notices packages. ([27548](https://github.com/WordPress/gutenberg/pull/27548)) +- Merge RootContainer with BlockList. ([27531](https://github.com/WordPress/gutenberg/pull/27531)) +- Block wrapper: Isolate functionality into smaller hooks. ([27503](https://github.com/WordPress/gutenberg/pull/27503)) +- Writing flow: Consider events only from DOM descendents. ([27489](https://github.com/WordPress/gutenberg/pull/27489)) +- Writing flow: Isolate multi select focus element. ([27482](https://github.com/WordPress/gutenberg/pull/27482)) +- Multi selection: Move hook to WritingFlow with other multi selection logic. ([27479](https://github.com/WordPress/gutenberg/pull/27479)) +- Insertion indicator: Render after last block if none is specified. ([27472](https://github.com/WordPress/gutenberg/pull/27472)) +- Rewrite selection clearer in Block editor. ([27468](https://github.com/WordPress/gutenberg/pull/27468)) +- Move block focus listener to block props hook. ([27463](https://github.com/WordPress/gutenberg/pull/27463)) +- Block editor: Refactor effect.js to controls. ([27298](https://github.com/WordPress/gutenberg/pull/27298)) +- Animate: Type getAnimateClassName. ([27123](https://github.com/WordPress/gutenberg/pull/27123)) +- Refactor image block's image editing tools into separate components. ([27089](https://github.com/WordPress/gutenberg/pull/27089)) +- Drop zone provider: Option to avoid wrapper element. ([27079](https://github.com/WordPress/gutenberg/pull/27079)) +- Audit variables stylesheet. ([26827](https://github.com/WordPress/gutenberg/pull/26827)) +- group block padding: Use variables. ([27676](https://github.com/WordPress/gutenberg/pull/27676)) + +### Tools + +- Release script: Set draft status, and only remove after uploading asset. ([27713](https://github.com/WordPress/gutenberg/pull/27713)) +- CI: Run date test timezone and locale variations using bash script. ([27600](https://github.com/WordPress/gutenberg/pull/27600)) +- Upgrade Babel packages to 7.12.x. ([27553](https://github.com/WordPress/gutenberg/pull/27553)) +- CI: Run package/date unit tests in different timezones. ([27552](https://github.com/WordPress/gutenberg/pull/27552)) +- Avoid cancelling other end-to-end test jobs when one fails. ([27541](https://github.com/WordPress/gutenberg/pull/27541)) +- Add webpack 5 support to dependency-extraction-webpack-plugin. ([27533](https://github.com/WordPress/gutenberg/pull/27533)) +- Add GitHub support document. ([27524](https://github.com/WordPress/gutenberg/pull/27524)) +- Stabilize adding blocks end to end test. ([27493](https://github.com/WordPress/gutenberg/pull/27493)) +- GitHub Actions: Use a build matrix for the end-to-end tests GH action. ([27487](https://github.com/WordPress/gutenberg/pull/27487)) +- Packages: Make it possible to select minimum version bump for publishing. ([27459](https://github.com/WordPress/gutenberg/pull/27459)) +- Upgrade wp-prettier to 2.2.1. ([27441](https://github.com/WordPress/gutenberg/pull/27441)) +- Testing: Make image size test more stable. ([27439](https://github.com/WordPress/gutenberg/pull/27439)) +- Packages: Improve the script that automates version bumps. ([27436](https://github.com/WordPress/gutenberg/pull/27436)) +- CI: Update bundle size workflow to use the latest version. ([27435](https://github.com/WordPress/gutenberg/pull/27435)) +- wp-env: Xdebug support. ([27346](https://github.com/WordPress/gutenberg/pull/27346)) +- Make zip-based URL parsing more general. ([27019](https://github.com/WordPress/gutenberg/pull/27019)) +- Add inserter performance measures. ([26634](https://github.com/WordPress/gutenberg/pull/26634)) + +### Various + +- Verse Block: + - Add support for custom padding. ([27341](https://github.com/WordPress/gutenberg/pull/27341)) + - Add support for font family. ([27332](https://github.com/WordPress/gutenberg/pull/27332)) + - Add support for font size. ([27735](https://github.com/WordPress/gutenberg/pull/27735)) + - Update CSS for frontend and editor. ([27734](https://github.com/WordPress/gutenberg/pull/27734)) +- Popover: Use a11y hooks instead of HoCs. ([27707](https://github.com/WordPress/gutenberg/pull/27707)) +- Refactor focus on mount. ([27699](https://github.com/WordPress/gutenberg/pull/27699)) +- Search block: Use em values for padding. ([27678](https://github.com/WordPress/gutenberg/pull/27678)) +- Button: Is-busy state candybar animation fixed. ([27592](https://github.com/WordPress/gutenberg/pull/27592)) +- Preformatted block: Add support for font sizes. ([27584](https://github.com/WordPress/gutenberg/pull/27584)) +- Remove autoFocus prop from URLInput and from the inserter search form. ([27578](https://github.com/WordPress/gutenberg/pull/27578)) +- Package lock: Update ws. ([27532](https://github.com/WordPress/gutenberg/pull/27532)) +- Update block-patterns.md. ([27520](https://github.com/WordPress/gutenberg/pull/27520)) +- Update wp-env codeowners. ([27491](https://github.com/WordPress/gutenberg/pull/27491)) +- Update the backup icon to better align with WordPress icon package dna. ([27465](https://github.com/WordPress/gutenberg/pull/27465)) +- Update the rich text control titles to sentence case structure. ([27447](https://github.com/WordPress/gutenberg/pull/27447)) +- Search Block: Remove the button only option from the UI. ([27379](https://github.com/WordPress/gutenberg/pull/27379)) +- Add icons for template parts. ([27378](https://github.com/WordPress/gutenberg/pull/27378)) +- Increase radio dimensions to match checkboxes. ([27377](https://github.com/WordPress/gutenberg/pull/27377)) +- Adjusts settings modal height to 90%. ([27362](https://github.com/WordPress/gutenberg/pull/27362)) +- Change the Labels of the Vertical Align options. ([27356](https://github.com/WordPress/gutenberg/pull/27356)) +- Add element selector to template-part block. ([27101](https://github.com/WordPress/gutenberg/pull/27101)) +- Add explicit dismiss button and on dismiss callback to snackbar. ([26952](https://github.com/WordPress/gutenberg/pull/26952)) +- Make social list block align right able on published page & preview. ([26861](https://github.com/WordPress/gutenberg/pull/26861)) +- Update media-text focalPoint conditional rendering. ([25968](https://github.com/WordPress/gutenberg/pull/25968)) +- Remove default icon from PluginBlockSettingsMenuItem. ([21392](https://github.com/WordPress/gutenberg/pull/21392)) +- Add example preview to video block. ([20703](https://github.com/WordPress/gutenberg/pull/20703)) -Changelog creation in progress. = 9.5.2 = diff --git a/docs/contributors/release.md b/docs/contributors/release.md index 97bf6d2acb23e3..a1bc58edce80a6 100644 --- a/docs/contributors/release.md +++ b/docs/contributors/release.md @@ -199,9 +199,9 @@ You'll need to use Subversion to publish the plugin to WordPress.org. 6. Add new files/remove deleted files from the repository: ```bash # Add new files: -svn st | grep '^\?' | awk '{print $2}' | xargs svn add +svn st | grep '^\?' | awk '{print $2}' | xargs svn add # add the -r option to xargs if you use a linux-based OS # Delete old files: -svn st | grep '^!' | awk '{print $2}' | xargs svn rm +svn st | grep '^!' | awk '{print $2}' | xargs svn rm # add the -r option to xargs if you use a linux-based OS ``` 7. Commit the new version: ```bash diff --git a/docs/contributors/testing-overview.md b/docs/contributors/testing-overview.md index c5d21a281e5df7..7616af58afacf0 100644 --- a/docs/contributors/testing-overview.md +++ b/docs/contributors/testing-overview.md @@ -355,9 +355,8 @@ It's tempting to snapshot deep renders, but that makes for huge snapshots. Addit Sometimes we need to mock refs for some stories which use them. Check the following documents to learn more: - Why we need to use [Mocking Refs for Snapshot Testing](https://reactjs.org/blog/2016/11/16/react-v15.4.0.html#mocking-refs-for-snapshot-testing) with React. -- [Using createNodeMock to mock refs](https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core#using-createnodemock-to-mock-refs) with StoryShots. -In that case, you might see test failures and `TypeError` reported by Jest in the lines which try to access a property from `ref.current`. If this happens, search for `initStoryshots` method call, which contains all necessary configurations to adjust. +In that case, you might see test failures and `TypeError` reported by Jest in the lines which try to access a property from `ref.current`. ### Debugging Jest unit tests diff --git a/docs/designers-developers/developers/block-api/block-registration.md b/docs/designers-developers/developers/block-api/block-registration.md index 46560971890650..ffe0981510eb16 100644 --- a/docs/designers-developers/developers/block-api/block-registration.md +++ b/docs/designers-developers/developers/block-api/block-registration.md @@ -222,7 +222,7 @@ example: { #### variations (optional) -- **Type:** `Object[]` +- **Type:** `Object[]` Similarly to how the block's style variations can be declared, a block type can define block variations that the user can pick from. The difference is that, rather than changing only the visual appearance, this field provides a way to apply initial custom attributes and inner blocks at the time when a block is inserted. @@ -256,19 +256,20 @@ variations: [ An object describing a variation defined for the block type can contain the following fields: -- `name` (type `string`) – The unique and machine-readable name. -- `title` (type `string`) – A human-readable variation title. -- `description` (optional, type `string`) – A detailed variation description. -- `icon` (optional, type `string` | `Object`) – An icon helping to visualize the variation. It can have the same shape as the block type. -- `isDefault` (optional, type `boolean`) – Indicates whether the current variation is the default one. Defaults to `false`. -- `attributes` (optional, type `Object`) – Values that override block attributes. -- `innerBlocks` (optional, type `Array[]`) – Initial configuration of nested blocks. -- `example` (optional, type `Object`) – Example provides structured data for the block preview. You can set to `undefined` to disable the preview shown for the block type. -- `scope` (optional, type `WPBlockVariationScope[]`) - the list of scopes where the variation is applicable. When not provided, it defaults to `block` and `inserter`. Available options: - - `inserter` - Block Variation is shown on the inserter. - - `block` - Used by blocks to filter specific block variations. Mostly used in Placeholder patterns like `Columns` block. - - `transform` - Block Variation will be shown in the component for Block Variations transformations. -- `keywords` (optional, type `string[]`) - An array of terms (which can be translated) that help users discover the variation while searching. +- `name` (type `string`) – The unique and machine-readable name. +- `title` (type `string`) – A human-readable variation title. +- `description` (optional, type `string`) – A detailed variation description. +- `icon` (optional, type `string` | `Object`) – An icon helping to visualize the variation. It can have the same shape as the block type. +- `isDefault` (optional, type `boolean`) – Indicates whether the current variation is the default one. Defaults to `false`. +- `attributes` (optional, type `Object`) – Values that override block attributes. +- `innerBlocks` (optional, type `Array[]`) – Initial configuration of nested blocks. +- `example` (optional, type `Object`) – Example provides structured data for the block preview. You can set to `undefined` to disable the preview shown for the block type. +- `scope` (optional, type `WPBlockVariationScope[]`) - the list of scopes where the variation is applicable. When not provided, it defaults to `block` and `inserter`. Available options: + - `inserter` - Block Variation is shown on the inserter. + - `block` - Used by blocks to filter specific block variations. Mostly used in Placeholder patterns like `Columns` block. + - `transform` - Block Variation will be shown in the component for Block Variations transformations. +- `keywords` (optional, type `string[]`) - An array of terms (which can be translated) that help users discover the variation while searching. +- `isActive` (optional, type `Function`) - A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. This function doesn't try to find a match dynamically based on all block's attributes, as in many cases some attributes are irrelevant. An example would be for `embed` block where we only care about `providerNameSlug` attribute's value. It's also possible to override the default block style variation using the `className` attribute when defining block variations. @@ -278,15 +279,17 @@ variations: [ name: 'blue', title: __( 'Blue Quote' ), isDefault: true, - attributes: { className: 'is-style-blue-quote' }, + attributes: { color: 'blue', className: 'is-style-blue-quote' }, icon: 'format-quote', + isActive: ( blockAttributes, variationAttributes ) => + blockAttributes.color === variationAttributes.color }, ], ``` #### supports (optional) -- ***Type:*** `Object` +- **_Type:_** `Object` Supports contains as set of options to control features used in the editor. See the [the supports documentation](/docs/designers-developers/developers/block-api/block-supports.md) for more details. diff --git a/docs/designers-developers/developers/block-api/block-supports.md b/docs/designers-developers/developers/block-api/block-supports.md index cd93af21096276..b4d8634ed33816 100644 --- a/docs/designers-developers/developers/block-api/block-supports.md +++ b/docs/designers-developers/developers/block-api/block-supports.md @@ -338,24 +338,6 @@ supports: { } ``` -When the block declares support for a specific spacing property, the attributes definition is extended to include some attributes. +When the block declares support for a specific spacing property, the attributes definition is extended to include the `style` attribute. -- `style`: attribute of `object` type with no default assigned. This is added when `padding` support is declared. It stores the custom values set by the user. The block can apply a default style by specifying its own `style` attribute with a default e.g.: - -```js -attributes: { - style: { - type: 'object', - default: { - spacing: { - padding: { - top: 'value', - right: 'value', - bottom: 'value', - left: 'value' - } - } - } - } -} -``` +- `style`: attribute of `object` type with no default assigned. This is added when `padding` support is declared. It stores the custom values set by the user. diff --git a/docs/designers-developers/developers/block-api/block-templates.md b/docs/designers-developers/developers/block-api/block-templates.md index ad961e8f8066d1..42e7a660545833 100644 --- a/docs/designers-developers/developers/block-api/block-templates.md +++ b/docs/designers-developers/developers/block-api/block-templates.md @@ -1,6 +1,6 @@ # Templates -A block template is defined as a list of block items. Such blocks can have predefined attributes, placeholder content, and be static or dynamic. Block templates allow to specify a default initial state for an editor session. +A block template is defined as a list of block items. Such blocks can have predefined attributes, placeholder content, and be static or dynamic. Block templates allow specifying a default initial state for an editor session. The scope of templates include: @@ -110,6 +110,8 @@ add_action( 'init', 'myplugin_register_template' ); - `all` — prevents all operations. It is not possible to insert new blocks, move existing blocks, or delete blocks. - `insert` — prevents inserting or removing blocks, but allows moving existing blocks. +Lock settings can be inherited by InnerBlocks. If `templateLock` is not set in an InnerBlocks area, the locking of the parent InnerBlocks area is used. If the block is a top level block, the locking configuration of the current post type is used. + ## Nested Templates Container blocks like the columns blocks also support templates. This is achieved by assigning a nested template to the block. 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 3ab9d0bd1cd3ec..ded41c1a63dfc6 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -344,6 +344,40 @@ _Returns_ - `?string`: Client ID of block selection start. +# **getBlockTransformItems** + +Determines the items that appear in the available block transforms list. + +Each item object contains what's necessary to display a menu item in the +transform list and handle its selection. + +The 'frecency' property is a heuristic () +that combines block usage frequenty and recency. + +Items are returned ordered descendingly by their 'frecency'. + +_Parameters_ + +- _state_ `Object`: Editor state. +- _rootClientId_ `?string`: Optional root client ID of block list. + +_Returns_ + +- `Array`: Items that appear in inserter. + +_Type Definition_ + +- _WPEditorTransformItem_ `Object` + +_Properties_ + +- _id_ `string`: Unique identifier for the item. +- _name_ `string`: The type of block to create. +- _title_ `string`: Title of the item, as it appears in the inserter. +- _icon_ `string`: Dashicon for the item, as it appears in the inserter. +- _isDisabled_ `boolean`: Whether or not the user should be prevented from inserting this item. +- _frecency_ `number`: Heuristic that combines frequency and recency. + # **getClientIdsOfDescendants** Returns an array containing the clientIds of all descendants diff --git a/docs/designers-developers/developers/data/data-core-editor.md b/docs/designers-developers/developers/data/data-core-editor.md index 1cf2a7cf6e297b..621461421e085c 100644 --- a/docs/designers-developers/developers/data/data-core-editor.md +++ b/docs/designers-developers/developers/data/data-core-editor.md @@ -568,18 +568,11 @@ _Related_ # **getStateBeforeOptimisticTransaction** +> **Deprecated** since Gutenberg 9.7.0. + Returns state object prior to a specified optimist transaction ID, or `null` if the transaction corresponding to the given ID cannot be found. -_Parameters_ - -- _state_ `Object`: Current global application state. -- _transactionId_ `Object`: Optimist transaction ID. - -_Returns_ - -- `Object`: Global application state prior to transaction. - # **getSuggestedPostFormat** Returns a suggested post format for the current post, inferred only if there @@ -696,18 +689,11 @@ _Related_ # **inSomeHistory** +> **Deprecated** since Gutenberg 9.7.0. + Returns true if an optimistic transaction is pending commit, for which the before state satisfies the given predicate function. -_Parameters_ - -- _state_ `Object`: Editor state. -- _predicate_ `Function`: Function given state, returning true if match. - -_Returns_ - -- `boolean`: Whether predicate matches for some history. - # **isAncestorMultiSelected** _Related_ @@ -1490,13 +1476,11 @@ Undocumented declaration. # **updatePost** +> **Deprecated** since Gutenberg 9.7.0. + Returns an action object used in signalling that a patch of updates for the latest version of the post have been received. -_Parameters_ - -- _edits_ `Object`: Updated post fields. - _Returns_ - `Object`: Action object. diff --git a/docs/designers-developers/developers/data/data-core.md b/docs/designers-developers/developers/data/data-core.md index 37c4ad7d5f8584..e079ad3b9ffc07 100644 --- a/docs/designers-developers/developers/data/data-core.md +++ b/docs/designers-developers/developers/data/data-core.md @@ -612,7 +612,8 @@ _Parameters_ - _name_ `string`: Name of the received entity. - _records_ `(Array|Object)`: Records received. - _query_ `?Object`: Query Object. -- _invalidateCache_ `?boolean`: Should invalidate query caches +- _invalidateCache_ `?boolean`: Should invalidate query caches. +- _edits_ `?Object`: Edits to reset. _Returns_ diff --git a/docs/manifest.json b/docs/manifest.json index b22e628e803e72..8c0881895f1428 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1805,6 +1805,12 @@ "markdown_source": "../packages/shortcode/README.md", "parent": "packages" }, + { + "title": "@wordpress/stylelint-config", + "slug": "packages-stylelint-config", + "markdown_source": "../packages/stylelint-config/README.md", + "parent": "packages" + }, { "title": "@wordpress/token-list", "slug": "packages-token-list", diff --git a/gutenberg.php b/gutenberg.php index 18ed34191750e7..2d81656f5b63fd 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the new block editor in core. * Requires at least: 5.3 * Requires PHP: 5.6 - * Version: 9.6.0-rc.1 + * Version: 9.7.0-rc.1 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/lib/block-directory.php b/lib/block-directory.php deleted file mode 100644 index cb1ec4bd9d1a2c..00000000000000 --- a/lib/block-directory.php +++ /dev/null @@ -1,54 +0,0 @@ -` tag for the enqueued script. - * @param string $handle The script's registered handle. - * @param string $esc_src The script's pre-escaped registered src. - * - * @return string Filtered script tag. - */ - function gutenberg_change_script_tag( $tag, $handle, $esc_src ) { - if ( ! is_admin() ) { - return $tag; - } - - $tag = str_replace( - sprintf( "", $esc_src ), - sprintf( "", esc_attr( $handle ), $esc_src ), - $tag - ); - - return $tag; - } - add_filter( 'script_loader_tag', 'gutenberg_change_script_tag', 1, 3 ); -} diff --git a/lib/block-patterns.php b/lib/block-patterns.php deleted file mode 100644 index e8c0d0811dae91..00000000000000 --- a/lib/block-patterns.php +++ /dev/null @@ -1,66 +0,0 @@ -get_all_registered(); - $settings['__experimentalBlockPatternCategories'] = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(); - - return $settings; -} -add_filter( 'block_editor_settings', 'gutenberg_extend_settings_block_patterns', 0 ); - - -/** - * Load a block pattern by name. - * - * @param string $name Block Pattern File name. - * - * @return array Block Pattern Array. - */ -function gutenberg_load_block_pattern( $name ) { - return require( __DIR__ . '/patterns/' . $name . '.php' ); -} - -/** - * Register default patterns and categories, potentially overriding ones that were already registered in Core. - * - * This can be removed when plugin support requires WordPress 5.5.0+, and patterns have been synced back to Core. - * - * @see https://core.trac.wordpress.org/ticket/50550 - */ -function gutenberg_register_block_patterns() { - $should_register_core_patterns = get_theme_support( 'core-block-patterns' ); - - if ( $should_register_core_patterns ) { - register_block_pattern( 'core/text-two-columns', gutenberg_load_block_pattern( 'text-two-columns' ) ); - register_block_pattern( 'core/two-buttons', gutenberg_load_block_pattern( 'two-buttons' ) ); - register_block_pattern( 'core/two-images', gutenberg_load_block_pattern( 'two-images' ) ); - register_block_pattern( 'core/text-two-columns-with-images', gutenberg_load_block_pattern( 'text-two-columns-with-images' ) ); - register_block_pattern( 'core/text-three-columns-buttons', gutenberg_load_block_pattern( 'text-three-columns-buttons' ) ); - register_block_pattern( 'core/large-header', gutenberg_load_block_pattern( 'large-header' ) ); - register_block_pattern( 'core/large-header-button', gutenberg_load_block_pattern( 'large-header-button' ) ); - register_block_pattern( 'core/three-buttons', gutenberg_load_block_pattern( 'three-buttons' ) ); - register_block_pattern( 'core/heading-paragraph', gutenberg_load_block_pattern( 'heading-paragraph' ) ); - register_block_pattern( 'core/quote', gutenberg_load_block_pattern( 'quote' ) ); - } - - register_block_pattern_category( 'buttons', array( 'label' => _x( 'Buttons', 'Block pattern category', 'gutenberg' ) ) ); - register_block_pattern_category( 'columns', array( 'label' => _x( 'Columns', 'Block pattern category', 'gutenberg' ) ) ); - register_block_pattern_category( 'gallery', array( 'label' => _x( 'Gallery', 'Block pattern category', 'gutenberg' ) ) ); - register_block_pattern_category( 'header', array( 'label' => _x( 'Headers', 'Block pattern category', 'gutenberg' ) ) ); - register_block_pattern_category( 'text', array( 'label' => _x( 'Text', 'Block pattern category', 'gutenberg' ) ) ); -} -add_action( 'init', 'gutenberg_register_block_patterns' ); diff --git a/lib/class-wp-block-list.php b/lib/class-wp-block-list.php deleted file mode 100644 index 3bf1f6252088b8..00000000000000 --- a/lib/class-wp-block-list.php +++ /dev/null @@ -1,194 +0,0 @@ -blocks = $blocks; - $this->available_context = $available_context; - $this->registry = $registry; - } - - /* - * ArrayAccess interface methods. - */ - - /** - * Returns true if a block exists by the specified block index, or false - * otherwise. - * - * @link https://www.php.net/manual/en/arrayaccess.offsetexists.php - * - * @param string $index Index of block to check. - * - * @return bool Whether block exists. - */ - public function offsetExists( $index ) { - return isset( $this->blocks[ $index ] ); - } - - /** - * Returns the value by the specified block index. - * - * @link https://www.php.net/manual/en/arrayaccess.offsetget.php - * - * @param string $index Index of block value to retrieve. - * - * @return mixed|null Block value if exists, or null. - */ - public function offsetGet( $index ) { - $block = $this->blocks[ $index ]; - - if ( isset( $block ) && is_array( $block ) ) { - $block = new WP_Block( $block, $this->available_context, $this->registry ); - $this->blocks[ $index ] = $block; - } - - return $block; - } - - /** - * Assign a block value by the specified block index. - * - * @link https://www.php.net/manual/en/arrayaccess.offsetset.php - * - * @param string $index Index of block value to set. - * @param mixed $value Block value. - */ - public function offsetSet( $index, $value ) { - if ( is_null( $index ) ) { - $this->blocks[] = $value; - } else { - $this->blocks[ $index ] = $value; - } - } - - /** - * Unset a block. - * - * @link https://www.php.net/manual/en/arrayaccess.offsetunset.php - * - * @param string $index Index of block value to unset. - */ - public function offsetUnset( $index ) { - unset( $this->blocks[ $index ] ); - } - - /* - * Iterator interface methods. - */ - - /** - * Rewinds back to the first element of the Iterator. - * - * @link https://www.php.net/manual/en/iterator.rewind.php - */ - public function rewind() { - reset( $this->blocks ); - } - - /** - * Returns the current element of the block list. - * - * @link https://www.php.net/manual/en/iterator.current.php - * - * @return mixed Current element. - */ - public function current() { - return $this->offsetGet( $this->key() ); - } - - /** - * Returns the key of the current element of the block list. - * - * @link https://www.php.net/manual/en/iterator.key.php - * - * @return mixed Key of the current element. - */ - public function key() { - return key( $this->blocks ); - } - - /** - * Moves the current position of the block list to the next element. - * - * @link https://www.php.net/manual/en/iterator.next.php - */ - public function next() { - next( $this->blocks ); - } - - /** - * Checks if current position is valid. - * - * @link https://www.php.net/manual/en/iterator.valid.php - */ - public function valid() { - return null !== key( $this->blocks ); - } - - /* - * Countable interface methods. - */ - - /** - * Returns the count of blocks in the list. - * - * @link https://www.php.net/manual/en/countable.count.php - * - * @return int Block count. - */ - public function count() { - return count( $this->blocks ); - } - -} diff --git a/lib/class-wp-block-pattern-categories-registry.php b/lib/class-wp-block-pattern-categories-registry.php deleted file mode 100644 index 2404f6a88dd92b..00000000000000 --- a/lib/class-wp-block-pattern-categories-registry.php +++ /dev/null @@ -1,144 +0,0 @@ -registered_categories[ $category_name ] = array_merge( - array( 'name' => $category_name ), - $category_properties - ); - - return true; - } - - /** - * Unregisters a pattern category. - * - * @param string $category_name Pattern name including namespace. - * @return boolean True if the pattern was unregistered with success and false otherwise. - */ - public function unregister( $category_name ) { - if ( ! $this->is_registered( $category_name ) ) { - /* translators: 1: Block pattern name. */ - $message = sprintf( __( 'Block pattern category "%1$s" not found.', 'gutenberg' ), $category_name ); - _doing_it_wrong( __METHOD__, $message, '8.1.0' ); - return false; - } - - unset( $this->registered_categories[ $category_name ] ); - - return true; - } - - /** - * Retrieves an array containing the properties of a registered pattern category. - * - * @param string $category_name Pattern category name. - * @return array Registered pattern properties. - */ - public function get_registered( $category_name ) { - if ( ! $this->is_registered( $category_name ) ) { - return null; - } - - return $this->registered_categories[ $category_name ]; - } - - /** - * Retrieves all registered pattern categories. - * - * @return array Array of arrays containing the registered pattern categories properties. - */ - public function get_all_registered() { - return array_values( $this->registered_categories ); - } - - /** - * Checks if a pattern category is registered. - * - * @param string $category_name Pattern category name. - * @return bool True if the pattern category is registered, false otherwise. - */ - public function is_registered( $category_name ) { - return isset( $this->registered_categories[ $category_name ] ); - } - - /** - * Utility method to retrieve the main instance of the class. - * - * The instance will be created if it does not exist yet. - * - * @since 5.3.0 - * - * @return WP_Block_Pattern_Categories_Registry The main instance. - */ - public static function get_instance() { - if ( null === self::$instance ) { - self::$instance = new self(); - } - - return self::$instance; - } -} - -/** - * Registers a new pattern category. - * - * @param string $category_name Pattern category name. - * @param array $category_properties Array containing the properties of the category. - * - * @return boolean True if the pattern category was registered with success and false otherwise. - */ -function register_block_pattern_category( $category_name, $category_properties ) { - return WP_Block_Pattern_Categories_Registry::get_instance()->register( $category_name, $category_properties ); -} - -/** - * Unregisters a pattern category. - * - * @param string $category_name Pattern category name including namespace. - * - * @return boolean True if the pattern category was unregistered with success and false otherwise. - */ -function unregister_block_pattern_category( $category_name ) { - return WP_Block_Pattern_Categories_Registry::get_instance()->unregister( $category_name ); -} diff --git a/lib/class-wp-block-patterns-registry.php b/lib/class-wp-block-patterns-registry.php deleted file mode 100644 index 56a36bce386f67..00000000000000 --- a/lib/class-wp-block-patterns-registry.php +++ /dev/null @@ -1,157 +0,0 @@ -registered_patterns[ $pattern_name ] = array_merge( - $pattern_properties, - array( 'name' => $pattern_name ) - ); - - return true; - } - - /** - * Unregisters a pattern. - * - * @param string $pattern_name Pattern name including namespace. - * @return boolean True if the pattern was unregistered with success and false otherwise. - */ - public function unregister( $pattern_name ) { - if ( ! $this->is_registered( $pattern_name ) ) { - /* translators: 1: Pattern name. */ - $message = sprintf( __( 'Block pattern "%1$s" not found.', 'gutenberg' ), $pattern_name ); - _doing_it_wrong( __METHOD__, $message, '7.8.0' ); - return false; - } - - unset( $this->registered_patterns[ $pattern_name ] ); - - return true; - } - - /** - * Retrieves an array containing the properties of a registered pattern. - * - * @param string $pattern_name Pattern name including namespace. - * @return array Registered pattern properties. - */ - public function get_registered( $pattern_name ) { - if ( ! $this->is_registered( $pattern_name ) ) { - return null; - } - - return $this->registered_patterns[ $pattern_name ]; - } - - /** - * Retrieves all registered patterns. - * - * @return array Array of arrays containing the registered patterns properties, - * and per style. - */ - public function get_all_registered() { - return array_values( $this->registered_patterns ); - } - - /** - * Checks if a pattern is registered. - * - * @param string $pattern_name Pattern name including namespace. - * @return bool True if the pattern is registered, false otherwise. - */ - public function is_registered( $pattern_name ) { - return isset( $this->registered_patterns[ $pattern_name ] ); - } - - /** - * Utility method to retrieve the main instance of the class. - * - * The instance will be created if it does not exist yet. - * - * @since 5.3.0 - * - * @return WP_Block_Patterns_Registry The main instance. - */ - public static function get_instance() { - if ( null === self::$instance ) { - self::$instance = new self(); - } - - return self::$instance; - } -} - -/** - * Registers a new pattern. - * - * @param string $pattern_name Pattern name including namespace. - * @param array $pattern_properties Array containing the properties of the pattern. - * - * @return boolean True if the pattern was registered with success and false otherwise. - */ -function register_block_pattern( $pattern_name, $pattern_properties ) { - return WP_Block_Patterns_Registry::get_instance()->register( $pattern_name, $pattern_properties ); -} - -/** - * Unregisters a pattern. - * - * @param string $pattern_name Pattern name including namespace. - * - * @return boolean True if the pattern was unregistered with success and false otherwise. - */ -function unregister_block_pattern( $pattern_name ) { - return WP_Block_Patterns_Registry::get_instance()->unregister( $pattern_name ); -} diff --git a/lib/class-wp-block.php b/lib/class-wp-block.php deleted file mode 100644 index cd029050745660..00000000000000 --- a/lib/class-wp-block.php +++ /dev/null @@ -1,243 +0,0 @@ - testing..." -> "Just testing..." - * - * @var string - */ - public $inner_html = ''; - - /** - * List of string fragments and null markers where inner blocks were found - * - * @example array( - * 'inner_html' => 'BeforeInnerAfter', - * 'inner_blocks' => array( block, block ), - * 'inner_content' => array( 'Before', null, 'Inner', null, 'After' ), - * ) - * - * @var array - */ - public $inner_content = array(); - - /** - * Constructor. - * - * Populates object properties from the provided block instance argument. - * - * The given array of context values will not necessarily be available on - * the instance itself, but is treated as the full set of values provided by - * the block's ancestry. This is assigned to the private `available_context` - * property. Only values which are configured to consumed by the block via - * its registered type will be assigned to the block's `context` property. - * - * @param array $block Array of parsed block properties. - * @param array $available_context Optional array of ancestry context values. - * @param WP_Block_Type_Registry $registry Optional block type registry. - */ - public function __construct( $block, $available_context = array(), $registry = null ) { - $this->parsed_block = $block; - $this->name = $block['blockName']; - - if ( is_null( $registry ) ) { - $registry = WP_Block_Type_Registry::get_instance(); - } - - $this->block_type = $registry->get_registered( $this->name ); - - if ( ! empty( $this->block_type->context ) ) { - $message = sprintf( - /* translators: 1: Block name. */ - __( 'The "context" parameter provided in block type "%s" is deprecated. Please use "uses_context" instead.', 'gutenberg' ), - $this->name - ); - _doing_it_wrong( __CLASS__, $message, '8.6.0' ); - $this->block_type->uses_context = $this->block_type->context; - } - if ( ! empty( $this->block_type->providesContext ) ) { - $message = sprintf( - /* translators: 1: Block name. */ - __( 'The "providesContext" parameter provided in block type "%s" is deprecated. Please use "provides_context".', 'gutenberg' ), - $this->name - ); - _doing_it_wrong( __CLASS__, $message, '8.6.0' ); - $this->block_type->provides_context = $this->block_type->providesContext; - } - - $this->available_context = $available_context; - - if ( ! empty( $this->block_type->uses_context ) ) { - foreach ( $this->block_type->uses_context as $context_name ) { - if ( array_key_exists( $context_name, $this->available_context ) ) { - $this->context[ $context_name ] = $this->available_context[ $context_name ]; - } - } - } - - if ( ! empty( $block['innerBlocks'] ) ) { - $child_context = $this->available_context; - - if ( ! empty( $this->block_type->provides_context ) ) { - foreach ( $this->block_type->provides_context as $context_name => $attribute_name ) { - if ( array_key_exists( $attribute_name, $this->attributes ) ) { - $child_context[ $context_name ] = $this->attributes[ $attribute_name ]; - } - } - } - - $this->inner_blocks = new WP_Block_List( $block['innerBlocks'], $child_context, $registry ); - } - - if ( ! empty( $block['innerHTML'] ) ) { - $this->inner_html = $block['innerHTML']; - } - - if ( ! empty( $block['innerContent'] ) ) { - $this->inner_content = $block['innerContent']; - } - } - - /** - * Returns a value from an inaccessible property. - * - * This is used to lazily initialize the `attributes` property of a block, - * such that it is only prepared with default attributes at the time that - * the property is accessed. For all other inaccessible properties, a `null` - * value is returned. - * - * @param string $name Property name. - * - * @return array|null Prepared attributes, or null. - */ - public function __get( $name ) { - if ( 'attributes' === $name ) { - $this->attributes = isset( $this->parsed_block['attrs'] ) ? - $this->parsed_block['attrs'] : - array(); - - if ( ! is_null( $this->block_type ) ) { - $this->attributes = $this->block_type->prepare_attributes_for_render( $this->attributes ); - } - - return $this->attributes; - } - - return null; - } - - /** - * Generates the render output for the block. - * - * @param array $options { - * Optional options object. - * - * @type bool $dynamic Defaults to 'true'. Optionally set to false to avoid using the block's render_callback. - * } - * - * @return string Rendered block output. - */ - public function render( $options = array() ) { - global $post; - $options = array_replace( - array( - 'dynamic' => true, - ), - $options - ); - - $is_dynamic = $options['dynamic'] && $this->name && null !== $this->block_type && $this->block_type->is_dynamic(); - $block_content = ''; - - if ( ! $options['dynamic'] || empty( $this->block_type->skip_inner_blocks ) ) { - $index = 0; - foreach ( $this->inner_content as $chunk ) { - $block_content .= is_string( $chunk ) ? - $chunk : - $this->inner_blocks[ $index++ ]->render(); - } - } - - if ( $is_dynamic ) { - $global_post = $post; - $block_content = (string) call_user_func( $this->block_type->render_callback, $this->attributes, $block_content, $this ); - $post = $global_post; - } - - if ( ! empty( $this->block_type->script ) ) { - wp_enqueue_script( $this->block_type->script ); - } - - if ( ! empty( $this->block_type->style ) ) { - wp_enqueue_style( $this->block_type->style ); - } - - /** This filter is documented in src/wp-includes/blocks.php */ - return apply_filters( 'render_block', $block_content, $this->parsed_block ); - } - -} diff --git a/lib/class-wp-rest-block-directory-controller.php b/lib/class-wp-rest-block-directory-controller.php deleted file mode 100644 index df1f2e408506e0..00000000000000 --- a/lib/class-wp-rest-block-directory-controller.php +++ /dev/null @@ -1,343 +0,0 @@ -namespace = 'wp/v2'; - $this->rest_base = 'block-directory'; - } - - /** - * Registers the necessary REST API routes. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/search', - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Checks whether a given request has permission to install and activate plugins. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_Error|bool True if the request has permission, WP_Error object otherwise. - */ - public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - if ( ! current_user_can( 'install_plugins' ) || ! current_user_can( 'activate_plugins' ) ) { - return new WP_Error( - 'rest_block_directory_cannot_view', - __( 'Sorry, you are not allowed to browse the block directory.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - return true; - } - - /** - * Search and retrieve blocks metadata - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. - */ - public function get_items( $request ) { - require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $response = plugins_api( - 'query_plugins', - array( - 'block' => $request['term'], - 'per_page' => $request['per_page'], - 'page' => $request['page'], - ) - ); - - if ( is_wp_error( $response ) ) { - $response->add_data( array( 'status' => 500 ) ); - - return $response; - } - - $result = array(); - - foreach ( $response->plugins as $plugin ) { - $data = $this->prepare_item_for_response( $plugin, $request ); - $result[] = $this->prepare_response_for_collection( $data ); - } - - return rest_ensure_response( $result ); - } - - /** - * Parse block metadata for a block, and prepare it for an API repsonse. - * - * @since 5.5.0 - * - * @param array $plugin The plugin metadata. - * @param WP_REST_Request $request Request object. - * - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. - */ - public function prepare_item_for_response( $plugin, $request ) { - // There might be multiple blocks in a plugin. Only the first block is mapped. - $block_data = reset( $plugin['blocks'] ); - - // A data array containing the properties we'll return. - $block = array( - 'name' => $block_data['name'], - 'title' => ( $block_data['title'] ? $block_data['title'] : $plugin['name'] ), - 'description' => wp_trim_words( $plugin['description'], 30, '...' ), - 'id' => $plugin['slug'], - 'rating' => $plugin['rating'] / 20, - 'rating_count' => intval( $plugin['num_ratings'] ), - 'active_installs' => intval( $plugin['active_installs'] ), - 'author_block_rating' => $plugin['author_block_rating'] / 20, - 'author_block_count' => intval( $plugin['author_block_count'] ), - 'author' => wp_strip_all_tags( $plugin['author'] ), - 'icon' => ( isset( $plugin['icons']['1x'] ) ? $plugin['icons']['1x'] : 'block-default' ), - 'assets' => array(), - 'last_updated' => $plugin['last_updated'], - 'humanized_updated' => sprintf( - /* translators: %s: Human-readable time difference. */ - __( '%s ago', 'gutenberg' ), - human_time_diff( strtotime( $plugin['last_updated'] ) ) - ), - ); - - foreach ( $plugin['block_assets'] as $asset ) { - // Allow for fully qualified URLs in future. - if ( 'https' === wp_parse_url( $asset, PHP_URL_SCHEME ) && ! empty( wp_parse_url( $asset, PHP_URL_HOST ) ) ) { - $block['assets'][] = esc_url_raw( - $asset, - array( 'https' ) - ); - } else { - $block['assets'][] = esc_url_raw( - add_query_arg( 'v', strtotime( $block['last_updated'] ), 'https://ps.w.org/' . $plugin['slug'] . $asset ), - array( 'https' ) - ); - } - } - - $this->add_additional_fields_to_object( $block, $request ); - - $response = new WP_REST_Response( $block ); - $response->add_links( $this->prepare_links( $plugin ) ); - - return $response; - } - - /** - * Generates a list of links to include in the response for the plugin. - * - * @since 5.5.0 - * - * @param array $plugin The plugin data from WordPress.org. - * - * @return array - */ - protected function prepare_links( $plugin ) { - $links = array( - 'https://api.w.org/install-plugin' => array( - 'href' => add_query_arg( 'slug', urlencode( $plugin['slug'] ), rest_url( 'wp/v2/plugins' ) ), - ), - ); - - $plugin_file = $this->find_plugin_for_slug( $plugin['slug'] ); - - if ( $plugin_file ) { - $links['https://api.w.org/plugin'] = array( - 'href' => rest_url( 'wp/v2/plugins/' . substr( $plugin_file, 0, - 4 ) ), - 'embeddable' => true, - ); - } - - return $links; - } - - /** - * Finds an installed plugin for the given slug. - * - * @since 5.5.0 - * - * @param string $slug The WordPress.org directory slug for a plugin. - * - * @return string The plugin file found matching it. - */ - protected function find_plugin_for_slug( $slug ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $plugin_files = get_plugins( '/' . $slug ); - - if ( ! $plugin_files ) { - return ''; - } - - $plugin_files = array_keys( $plugin_files ); - - return $slug . '/' . reset( $plugin_files ); - } - - /** - * Retrieves the theme's schema, conforming to JSON Schema. - * - * @since 5.5.0 - * - * @return array Item schema data. - */ - public function get_item_schema() { - if ( $this->schema ) { - return $this->add_additional_fields_schema( $this->schema ); - } - - $this->schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'block-directory-item', - 'type' => 'object', - 'properties' => array( - 'name' => array( - 'description' => __( 'The block name, in namespace/block-name format.', 'gutenberg' ), - 'type' => 'string', - 'context' => array( 'view' ), - ), - 'title' => array( - 'description' => __( 'The block title, in human readable format.', 'gutenberg' ), - 'type' => 'string', - 'context' => array( 'view' ), - ), - 'description' => array( - 'description' => __( 'A short description of the block, in human readable format.', 'gutenberg' ), - 'type' => 'string', - 'context' => array( 'view' ), - ), - 'id' => array( - 'description' => __( 'The block slug.', 'gutenberg' ), - 'type' => 'string', - 'context' => array( 'view' ), - ), - 'rating' => array( - 'description' => __( 'The star rating of the block.', 'gutenberg' ), - 'type' => 'integer', - 'context' => array( 'view' ), - ), - 'rating_count' => array( - 'description' => __( 'The number of ratings.', 'gutenberg' ), - 'type' => 'integer', - 'context' => array( 'view' ), - ), - 'active_installs' => array( - 'description' => __( 'The number sites that have activated this block.', 'gutenberg' ), - 'type' => 'string', - 'context' => array( 'view' ), - ), - 'author_block_rating' => array( - 'description' => __( 'The average rating of blocks published by the same author.', 'gutenberg' ), - 'type' => 'integer', - 'context' => array( 'view' ), - ), - 'author_block_count' => array( - 'description' => __( 'The number of blocks published by the same author.', 'gutenberg' ), - 'type' => 'integer', - 'context' => array( 'view' ), - ), - 'author' => array( - 'description' => __( 'The WordPress.org username of the block author.', 'gutenberg' ), - 'type' => 'string', - 'context' => array( 'view' ), - ), - 'icon' => array( - 'description' => __( 'The block icon.', 'gutenberg' ), - 'type' => 'string', - 'format' => 'uri', - 'context' => array( 'view' ), - ), - 'humanized_updated' => array( - 'description' => __( 'The date when the block was last updated, in fuzzy human readable format.', 'gutenberg' ), - 'type' => 'string', - 'context' => array( 'view' ), - ), - 'assets' => array( - 'description' => __( 'An object representing the block CSS and JavaScript assets.', 'gutenberg' ), - 'type' => 'array', - 'context' => array( 'view' ), - 'readonly' => true, - 'items' => array( - 'type' => 'string', - 'format' => 'uri', - ), - - ), - - ), - ); - - return $this->add_additional_fields_schema( $this->schema ); - } - - /** - * Retrieves the search params for the blocks collection. - * - * @since 5.5.0 - * - * @return array Collection parameters. - */ - public function get_collection_params() { - $query_params = parent::get_collection_params(); - - $query_params['context']['default'] = 'view'; - - $query_params['term'] = array( - 'description' => __( 'Limit result set to blocks matching the search term.', 'gutenberg' ), - 'type' => 'string', - 'required' => true, - 'minLength' => 1, - ); - - unset( $query_params['search'] ); - - /** - * Filter collection parameters for the block directory controller. - * - * @since 5.5.0 - * - * @param array $query_params JSON Schema-formatted collection parameters. - */ - return apply_filters( 'rest_block_directory_collection_params', $query_params ); - } -} diff --git a/lib/class-wp-rest-block-types-controller.php b/lib/class-wp-rest-block-types-controller.php deleted file mode 100644 index 9d7d819cf70b0a..00000000000000 --- a/lib/class-wp-rest-block-types-controller.php +++ /dev/null @@ -1,528 +0,0 @@ -namespace = '__experimental'; - $this->rest_base = 'block-types'; - $this->block_registry = WP_Block_Type_Registry::get_instance(); - $this->style_registry = WP_Block_Styles_Registry::get_instance(); - } - - /** - * Registers the routes for the objects of the controller. - * - * @see register_rest_route() - */ - public function register_routes() { - - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[a-zA-Z0-9_-]+)', - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[a-zA-Z0-9_-]+)/(?P[a-zA-Z0-9_-]+)', - array( - 'args' => array( - 'name' => array( - 'description' => __( 'Block name.', 'gutenberg' ), - 'type' => 'string', - ), - 'namespace' => array( - 'description' => __( 'Block namespace.', 'gutenberg' ), - 'type' => 'string', - ), - ), - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Checks whether a given request has permission to read post block types. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_Error|bool True if the request has read access, WP_Error object otherwise. - */ - public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - return $this->check_read_permission(); - } - - /** - * Retrieves all post block types, depending on user context. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. - */ - public function get_items( $request ) { - $data = array(); - $block_types = $this->block_registry->get_all_registered(); - - // Retrieve the list of registered collection query parameters. - $registered = $this->get_collection_params(); - $namespace = ''; - if ( isset( $registered['namespace'] ) && ! empty( $request['namespace'] ) ) { - $namespace = $request['namespace']; - } - - foreach ( $block_types as $obj ) { - if ( $namespace ) { - $pieces = explode( '/', $obj->name ); - $block_namespace = $pieces[0]; - if ( $namespace !== $block_namespace ) { - continue; - } - } - $block_type = $this->prepare_item_for_response( $obj, $request ); - $data[] = $this->prepare_response_for_collection( $block_type ); - } - - return rest_ensure_response( $data ); - } - - /** - * Checks if a given request has access to read a block type. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_Error|bool True if the request has read access for the item, WP_Error object otherwise. - */ - public function get_item_permissions_check( $request ) { - $check = $this->check_read_permission(); - if ( is_wp_error( $check ) ) { - return $check; - } - $block_name = sprintf( '%s/%s', $request['namespace'], $request['name'] ); - $block_type = $this->get_block( $block_name ); - if ( is_wp_error( $block_type ) ) { - return $block_type; - } - - return true; - } - - /** - * Checks whether a given block type should be visible. - * - * @return WP_Error|bool True if the block type is visible, otherwise false. - */ - protected function check_read_permission() { - if ( current_user_can( 'edit_posts' ) ) { - return true; - } - foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { - if ( current_user_can( $post_type->cap->edit_posts ) ) { - return true; - } - } - - return new WP_Error( 'rest_block_type_cannot_view', __( 'Sorry, you are not allowed to manage block types.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) ); - } - - /** - * Get the block, if the name is valid. - * - * @param string $name Block name. - * @return WP_Block_Type|WP_Error Block type object if name is valid, WP_Error otherwise. - */ - protected function get_block( $name ) { - $block_type = $this->block_registry->get_registered( $name ); - if ( empty( $block_type ) ) { - return new WP_Error( 'rest_block_type_invalid', __( 'Invalid block type.', 'gutenberg' ), array( 'status' => 404 ) ); - } - - return $block_type; - } - - /** - * Retrieves a specific block type. - * - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. - */ - public function get_item( $request ) { - $block_name = sprintf( '%s/%s', $request['namespace'], $request['name'] ); - $block_type = $this->get_block( $block_name ); - if ( is_wp_error( $block_type ) ) { - return $block_type; - } - $data = $this->prepare_item_for_response( $block_type, $request ); - - return rest_ensure_response( $data ); - } - - /** - * Prepares a block type object for serialization. - * - * @param WP_Block_Type $block_type block type data. - * @param WP_REST_Request $request Full details about the request. - * - * @return WP_REST_Response block type data. - */ - public function prepare_item_for_response( $block_type, $request ) { - - $fields = $this->get_fields_for_response( $request ); - $data = array(); - - if ( rest_is_field_included( 'attributes', $fields ) ) { - $data['attributes'] = $block_type->get_attributes(); - } - - if ( rest_is_field_included( 'is_dynamic', $fields ) ) { - $data['is_dynamic'] = $block_type->is_dynamic(); - } - - $schema = $this->get_item_schema(); - $extra_fields = array( - 'name' => 'name', - 'title' => 'title', - 'description' => 'description', - 'icon' => 'icon', - 'category' => 'category', - 'keywords' => 'keywords', - 'parent' => 'parent', - 'provides_context' => 'provides_context', - 'uses_context' => 'uses_context', - 'supports' => 'supports', - 'styles' => 'styles', - 'textdomain' => 'textdomain', - 'example' => 'example', - 'editor_script' => 'editor_script', - 'script' => 'script', - 'editor_style' => 'editor_style', - 'style' => 'style', - ); - foreach ( $extra_fields as $key => $extra_field ) { - if ( rest_is_field_included( $key, $fields ) ) { - if ( isset( $block_type->$extra_field ) ) { - $field = $block_type->$extra_field; - } elseif ( array_key_exists( 'default', $schema['properties'][ $key ] ) ) { - $field = $schema['properties'][ $key ]['default']; - } else { - $field = ''; - } - $data[ $key ] = rest_sanitize_value_from_schema( $field, $schema['properties'][ $key ] ); - } - } - - if ( rest_is_field_included( 'styles', $fields ) ) { - $styles = $this->style_registry->get_registered_styles_for_block( $block_type->name ); - $styles = array_values( $styles ); - $data['styles'] = wp_parse_args( $styles, $data['styles'] ); - } - - $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; - $data = $this->add_additional_fields_to_object( $data, $request ); - $data = $this->filter_response_by_context( $data, $context ); - - $response = rest_ensure_response( $data ); - - $response->add_links( $this->prepare_links( $block_type ) ); - - /** - * Filters a block type returned from the REST API. - * - * Allows modification of the block type data right before it is returned. - * - * @param WP_REST_Response $response The response object. - * @param object $block_type The original block type object. - * @param WP_REST_Request $request Request used to generate the response. - */ - return apply_filters( 'rest_prepare_block_type', $response, $block_type, $request ); - } - - /** - * Prepares links for the request. - * - * @param WP_Block_Type $block_type block type data. - * @return array Links for the given block type. - */ - protected function prepare_links( $block_type ) { - $pieces = explode( '/', $block_type->name ); - $namespace = $pieces[0]; - $links = array( - 'collection' => array( - 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), - ), - 'self' => array( - 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $block_type->name ) ), - ), - 'up' => array( - 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $namespace ) ), - ), - ); - - if ( $block_type->is_dynamic() ) { - $links['https://api.w.org/render-block']['href'] = add_query_arg( 'context', 'edit', rest_url( sprintf( '%s/%s/%s', 'wp/v2', 'block-renderer', $block_type->name ) ) ); - } - - return $links; - } - - /** - * Retrieves the block type' schema, conforming to JSON Schema. - * - * @return array Item schema data. - */ - public function get_item_schema() { - if ( $this->schema ) { - return $this->add_additional_fields_schema( $this->schema ); - } - - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'block-type', - 'type' => 'object', - 'properties' => array( - 'title' => array( - 'description' => __( 'Title of block type.', 'gutenberg' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'name' => array( - 'description' => __( 'Unique name identifying the block type.', 'gutenberg' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'description' => array( - 'description' => __( 'Description of block type.', 'gutenberg' ), - 'type' => 'string', - 'default' => '', - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'icon' => array( - 'description' => __( 'Icon of block type.', 'gutenberg' ), - 'type' => array( 'string', 'null' ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'attributes' => array( - 'description' => __( 'Block attributes.', 'gutenberg' ), - 'type' => array( 'object', 'null' ), - 'properties' => array(), - 'default' => null, - 'additionalProperties' => array( - 'type' => 'object', - ), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'provides_context' => array( - 'description' => __( 'Context provided by blocks of this type.', 'gutenberg' ), - 'type' => 'object', - 'properties' => array(), - 'additionalProperties' => array( - 'type' => 'string', - ), - 'default' => array(), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'uses_context' => array( - 'description' => __( 'Context values inherited by blocks of this type.', 'gutenberg' ), - 'type' => 'array', - 'default' => array(), - 'items' => array( - 'type' => 'string', - ), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'supports' => array( - 'description' => __( 'Block supports.', 'gutenberg' ), - 'type' => 'object', - 'default' => array(), - 'properties' => array(), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'category' => array( - 'description' => __( 'Block category.', 'gutenberg' ), - 'type' => array( 'string', null ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'is_dynamic' => array( - 'description' => __( 'Is the block dynamically rendered.', 'gutenberg' ), - 'type' => 'boolean', - 'default' => false, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'editor_script' => array( - 'description' => __( 'Editor script handle.', 'gutenberg' ), - 'type' => array( 'string', null ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'script' => array( - 'description' => __( 'Public facing script handle.', 'gutenberg' ), - 'type' => array( 'string', null ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'editor_style' => array( - 'description' => __( 'Editor style handle.', 'gutenberg' ), - 'type' => array( 'string', null ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'style' => array( - 'description' => __( 'Public facing style handle.', 'gutenberg' ), - 'type' => array( 'string', null ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'styles' => array( - 'description' => __( 'Block style variations.', 'gutenberg' ), - 'type' => 'array', - 'properties' => array(), - 'additionalProperties' => array( - 'type' => 'object', - ), - 'default' => array(), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'textdomain' => array( - 'description' => __( 'Public text domain.', 'gutenberg' ), - 'type' => array( 'string', 'null' ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'parent' => array( - 'description' => __( 'Parent blocks.', 'gutenberg' ), - 'type' => array( 'array', 'null' ), - 'items' => array( - 'type' => 'string', - ), - 'default' => null, - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'keywords' => array( - 'description' => __( 'Block keywords.', 'gutenberg' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - 'default' => array(), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - 'example' => array( - 'description' => __( 'Block example.', 'gutenberg' ), - 'type' => array( 'object', 'null' ), - 'default' => null, - 'properties' => array(), - 'additionalProperties' => array( - 'type' => 'object', - ), - 'context' => array( 'embed', 'view', 'edit' ), - 'readonly' => true, - ), - ), - ); - - $this->schema = $schema; - - return $this->add_additional_fields_schema( $this->schema ); - } - - /** - * Retrieves the query params for collections. - * - * @return array Collection parameters. - */ - public function get_collection_params() { - $new_params = array(); - $new_params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $new_params['namespace'] = array( - 'description' => __( 'Block namespace.', 'gutenberg' ), - 'type' => 'string', - ); - return $new_params; - } - -} diff --git a/lib/class-wp-rest-image-editor-controller.php b/lib/class-wp-rest-image-editor-controller.php deleted file mode 100644 index 66c8531e02d7ed..00000000000000 --- a/lib/class-wp-rest-image-editor-controller.php +++ /dev/null @@ -1,362 +0,0 @@ -namespace = 'wp/v2'; - $this->rest_base = 'media'; - } - - /** - * Registers the necessary REST API routes. - * - * @since 7.x ? - * @access public - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P[\d]+)/edit', - array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'apply_edits' ), - 'permission_callback' => array( $this, 'permission_callback' ), - 'args' => array( - 'rotation' => array( - 'type' => 'integer', - ), - - // Src is required to check for correct $image_meta. - 'src' => array( - 'type' => 'string', - 'required' => true, - ), - - // Crop values are in percents. - 'x' => array( - 'type' => 'number', - 'minimum' => 0, - 'maximum' => 100, - ), - 'y' => array( - 'type' => 'number', - 'minimum' => 0, - 'maximum' => 100, - ), - 'width' => array( - 'type' => 'number', - 'minimum' => 0, - 'maximum' => 100, - ), - 'height' => array( - 'type' => 'number', - 'minimum' => 0, - 'maximum' => 100, - ), - ), - ), - ) - ); - } - - /** - * Checks if the user has permissions to make the request. - * - * @since 7.x ? - * @access public - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function permission_callback( $request ) { - if ( ! current_user_can( 'edit_post', $request['id'] ) ) { - $error = __( 'Sorry, you are not allowed to edit images.', 'gutenberg' ); - return new WP_Error( 'rest_cannot_edit_image', $error, array( 'status' => rest_authorization_required_code() ) ); - } - - if ( ! current_user_can( 'upload_files' ) ) { - return new WP_Error( 'rest_cannot_edit_image', __( 'Sorry, you are not allowed to upload media on this site.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - - /** - * Applies all edits in one go. - * - * @since 7.x ? - * @access public - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error If successful image JSON for the modified image, otherwise a WP_Error. - */ - public function apply_edits( $request ) { - require_once ABSPATH . 'wp-admin/includes/image.php'; - - $attachment_id = $request['id']; - - // This also confirms the attachment is an image. - $image_file = wp_get_original_image_path( $attachment_id ); - $image_meta = wp_get_attachment_metadata( $attachment_id ); - - if ( function_exists( 'wp_image_file_matches_image_meta' ) ) { - if ( - ! $image_meta || - ! $image_file || - ! wp_image_file_matches_image_meta( $request['src'], $image_meta ) - ) { - return new WP_Error( - 'rest_unknown_attachment', - __( 'Unable to get meta information for file.', 'gutenberg' ), - array( 'status' => 404 ) - ); - } - } else { - // Back-compat for WP versions < 5.5. - if ( ! $image_meta || ! $image_file ) { - return new WP_Error( - 'rest_unknown_attachment', - __( 'Unable to get meta information for file.', 'gutenberg' ), - array( 'status' => 404 ) - ); - } else { - $match = false; - $image_src = $request['src']; - - if ( isset( $image_meta['file'] ) && strlen( $image_meta['file'] ) > 4 ) { - // Remove quiery args. - list( $image_src ) = explode( '?', $image_src ); - - // Check if the relative image path from the image meta is at the end of $image_src. - if ( strrpos( $image_src, $image_meta['file'] ) === strlen( $image_src ) - strlen( $image_meta['file'] ) ) { - $match = true; - } - - if ( ! empty( $image_meta['sizes'] ) ) { - // Retrieve the uploads sub-directory from the full size image. - $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); - - if ( $dirname ) { - $dirname = trailingslashit( $dirname ); - } - - foreach ( $image_meta['sizes'] as $image_size_data ) { - $relative_path = $dirname . $image_size_data['file']; - - if ( strrpos( $image_src, $relative_path ) === strlen( $image_src ) - strlen( $relative_path ) ) { - $match = true; - break; - } - } - } - } - - if ( ! $match ) { - return new WP_Error( - 'rest_unknown_attachment', - __( 'Unable to get meta information for file.', 'gutenberg' ), - array( 'status' => 404 ) - ); - } - } - } - - $supported_types = array( 'image/jpeg', 'image/png', 'image/gif' ); - $mime_type = get_post_mime_type( $attachment_id ); - if ( ! in_array( $mime_type, $supported_types, true ) ) { - return new WP_Error( - 'rest_cannot_edit_file_type', - __( 'This type of file cannot be edited.', 'gutenberg' ), - array( 'status' => 400 ) - ); - } - - // Check if we need to do anything. - $rotate = 0; - $crop = false; - - if ( ! empty( $request['rotation'] ) ) { - // Rotation direction: clockwise vs. counter clockwise. - $rotate = 0 - (int) $request['rotation']; - } - - if ( isset( $request['x'], $request['y'], $request['width'], $request['height'] ) ) { - $crop = true; - } - - if ( ! $rotate && ! $crop ) { - $error = __( 'The image was not edited. Edit the image before applying the changes.', 'gutenberg' ); - return new WP_Error( 'rest_image_not_edited', $error, array( 'status' => 400 ) ); - } - - // If the file doesn't exist, attempt a URL fopen on the src link. - // This can occur with certain file replication plugins. - // Keep the original file path to get a modified name later. - $image_file_to_edit = $image_file; - if ( ! file_exists( $image_file_to_edit ) ) { - $image_file_to_edit = _load_image_to_edit_path( $attachment_id ); - } - - $image_editor = wp_get_image_editor( $image_file_to_edit ); - - if ( is_wp_error( $image_editor ) ) { - // This image cannot be edited. - $error = __( 'Unable to edit this image.', 'gutenberg' ); - return new WP_Error( 'rest_unknown_image_file_type', $error, array( 'status' => 500 ) ); - } - - if ( 0 !== $rotate ) { - $result = $image_editor->rotate( $rotate ); - - if ( is_wp_error( $result ) ) { - $error = __( 'Unable to rotate this image.', 'gutenberg' ); - return new WP_Error( 'rest_image_rotation_failed', $error, array( 'status' => 500 ) ); - } - } - - if ( $crop ) { - $size = $image_editor->get_size(); - - $crop_x = round( ( $size['width'] * floatval( $request['x'] ) ) / 100.0 ); - $crop_y = round( ( $size['height'] * floatval( $request['y'] ) ) / 100.0 ); - $width = round( ( $size['width'] * floatval( $request['width'] ) ) / 100.0 ); - $height = round( ( $size['height'] * floatval( $request['height'] ) ) / 100.0 ); - - $result = $image_editor->crop( $crop_x, $crop_y, $width, $height ); - - if ( is_wp_error( $result ) ) { - $error = __( 'Unable to crop this image.', 'gutenberg' ); - return new WP_Error( 'rest_image_crop_failed', $error, array( 'status' => 500 ) ); - } - } - - // Calculate the file name. - $image_ext = pathinfo( $image_file, PATHINFO_EXTENSION ); - $image_name = wp_basename( $image_file, ".{$image_ext}" ); - - // Do not append multiple `-edited` to the file name. - // The user may be editing a previously edited image. - if ( preg_match( '/-edited(-\d+)?$/', $image_name ) ) { - // Remove any `-1`, `-2`, etc. `wp_unique_filename()` will add the proper number. - $image_name = preg_replace( '/-edited(-\d+)?$/', '-edited', $image_name ); - } else { - // Append `-edited` before the extension. - $image_name .= '-edited'; - } - - $filename = "{$image_name}.{$image_ext}"; - - // Create the uploads sub-directory if needed. - $uploads = wp_upload_dir(); - - // Make the file name unique in the (new) upload directory. - $filename = wp_unique_filename( $uploads['path'], $filename ); - - // Save to disk. - $saved = $image_editor->save( $uploads['path'] . "/$filename" ); - - if ( is_wp_error( $saved ) ) { - return $saved; - } - - // Create new attachment post. - $attachment_post = array( - 'post_mime_type' => $saved['mime-type'], - 'guid' => $uploads['url'] . "/$filename", - 'post_title' => $filename, - 'post_content' => '', - ); - - $new_attachment_id = wp_insert_attachment( wp_slash( $attachment_post ), $saved['path'], 0, true ); - - if ( is_wp_error( $new_attachment_id ) ) { - if ( 'db_update_error' === $new_attachment_id->get_error_code() ) { - $new_attachment_id->add_data( array( 'status' => 500 ) ); - } else { - $new_attachment_id->add_data( array( 'status' => 400 ) ); - } - - return $new_attachment_id; - } - - if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { - // Set a custom header with the attachment_id. - // Used by the browser/client to resume creating image sub-sizes after a PHP fatal error. - header( 'X-WP-Upload-Attachment-ID: ' . $new_attachment_id ); - } - - // Generate image sub-sizes and meta. - $new_image_meta = wp_generate_attachment_metadata( $new_attachment_id, $saved['path'] ); - - // Copy the EXIF metadata from the original attachment if not generated for the edited image. - if ( ! empty( $image_meta['image_meta'] ) ) { - $empty_image_meta = true; - - if ( isset( $new_image_meta['image_meta'] ) && is_array( $new_image_meta['image_meta'] ) ) { - $empty_image_meta = empty( array_filter( array_values( $new_image_meta['image_meta'] ) ) ); - } - - if ( $empty_image_meta ) { - $new_image_meta['image_meta'] = $image_meta['image_meta']; - } - } - - // Reset orientation. At this point the image is edited and orientation is correct. - if ( ! empty( $new_image_meta['image_meta']['orientation'] ) ) { - $new_image_meta['image_meta']['orientation'] = 1; - } - - // The attachment_id may change if the site is exported and imported. - $new_image_meta['parent_image'] = array( - 'attachment_id' => $attachment_id, - // Path to the originally uploaded image file relative to the uploads directory. - 'file' => _wp_relative_upload_path( $image_file ), - ); - - /** - * Filters the updated attachment meta data. - * - * @since 5.5.0 - * - * @param array $data Array of updated attachment meta data. - * @param int $new_attachment_id Attachment post ID. - * @param int $attachment_id Original Attachment post ID. - */ - $new_image_meta = apply_filters( 'wp_edited_attachment_metadata', $new_image_meta, $new_attachment_id, $attachment_id ); - - wp_update_attachment_metadata( $new_attachment_id, $new_image_meta ); - - $path = '/wp/v2/media/' . $new_attachment_id; - $new_request = new WP_REST_Request( 'GET', $path ); - $new_request->set_query_params( array( 'context' => 'edit' ) ); - $response = rest_do_request( $new_request ); - - if ( ! $response->is_error() ) { - $response->set_status( 201 ); - $response->header( 'Location', rest_url( $path ) ); - } - - return $response; - } -} diff --git a/lib/class-wp-rest-plugins-controller.php b/lib/class-wp-rest-plugins-controller.php deleted file mode 100644 index 49a55192dad204..00000000000000 --- a/lib/class-wp-rest-plugins-controller.php +++ /dev/null @@ -1,950 +0,0 @@ -namespace = 'wp/v2'; - $this->rest_base = 'plugins'; - } - - /** - * Registers the routes for the plugins controller. - * - * @since 5.5.0 - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), - array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => array( - 'slug' => array( - 'type' => 'string', - 'required' => true, - 'description' => __( 'WordPress.org plugin directory slug.', 'gutenberg' ), - 'pattern' => '[\w\-]+', - ), - 'status' => array( - 'description' => __( 'The plugin activation status.', 'gutenberg' ), - 'type' => 'string', - 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), - 'default' => 'inactive', - ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/(?P' . self::PATTERN . ')', - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - ), - 'args' => array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), - 'plugin' => array( - 'type' => 'string', - 'pattern' => self::PATTERN, - 'validate_callback' => array( $this, 'validate_plugin_param' ), - 'sanitize_callback' => array( $this, 'sanitize_plugin_param' ), - ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); - } - - /** - * Checks if a given request has access to get plugins. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access, WP_Error object otherwise. - */ - public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - if ( ! current_user_can( 'activate_plugins' ) ) { - return new WP_Error( - 'rest_cannot_view_plugins', - __( 'Sorry, you are not allowed to manage plugins for this site.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - return true; - } - - /** - * Retrieves a collection of plugins. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function get_items( $request ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $plugins = array(); - - foreach ( get_plugins() as $file => $data ) { - if ( is_wp_error( $this->check_read_permission( $file ) ) ) { - continue; - } - - $data['_file'] = $file; - - if ( ! $this->does_plugin_match_request( $request, $data ) ) { - continue; - } - - $plugins[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $data, $request ) ); - } - - return new WP_REST_Response( $plugins ); - } - - /** - * Checks if a given request has access to get a specific plugin. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. - */ - public function get_item_permissions_check( $request ) { - if ( ! current_user_can( 'activate_plugins' ) ) { - return new WP_Error( - 'rest_cannot_view_plugin', - __( 'Sorry, you are not allowed to manage plugins for this site.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - $can_read = $this->check_read_permission( $request['plugin'] ); - - if ( is_wp_error( $can_read ) ) { - return $can_read; - } - - return true; - } - - /** - * Retrieves one plugin from the site. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function get_item( $request ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $data = $this->get_plugin_data( $request['plugin'] ); - - if ( is_wp_error( $data ) ) { - return $data; - } - - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Checks if the given plugin can be viewed by the current user. - * - * On multisite, this hides non-active network only plugins if the user does not have permission - * to manage network plugins. - * - * @since 5.5.0 - * - * @param string $plugin The plugin file to check. - * @return true|WP_Error True if can read, a WP_Error instance otherwise. - */ - protected function check_read_permission( $plugin ) { - if ( ! $this->is_plugin_installed( $plugin ) ) { - return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.', 'gutenberg' ), array( 'status' => 404 ) ); - } - - if ( ! is_multisite() ) { - return true; - } - - if ( ! is_network_only_plugin( $plugin ) || is_plugin_active( $plugin ) || current_user_can( 'manage_network_plugins' ) ) { - return true; - } - - return new WP_Error( - 'rest_cannot_view_plugin', - __( 'Sorry, you are not allowed to manage this plugin.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - /** - * Checks if a given request has access to upload plugins. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. - */ - public function create_item_permissions_check( $request ) { - if ( ! current_user_can( 'install_plugins' ) ) { - return new WP_Error( - 'rest_cannot_install_plugin', - __( 'Sorry, you are not allowed to install plugins on this site.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - if ( 'inactive' !== $request['status'] && ! current_user_can( 'activate_plugins' ) ) { - return new WP_Error( - 'rest_cannot_activate_plugin', - __( 'Sorry, you are not allowed to activate plugins.', 'gutenberg' ), - array( - 'status' => rest_authorization_required_code(), - ) - ); - } - - return true; - } - - /** - * Uploads a plugin and optionally activates it. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function create_item( $request ) { - require_once ABSPATH . 'wp-admin/includes/file.php'; - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; - - $slug = $request['slug']; - - // Verify filesystem is accessible first. - $filesystem_available = $this->is_filesystem_available(); - if ( is_wp_error( $filesystem_available ) ) { - return $filesystem_available; - } - - $api = plugins_api( - 'plugin_information', - array( - 'slug' => $slug, - 'fields' => array( - 'sections' => false, - ), - ) - ); - - if ( is_wp_error( $api ) ) { - if ( false !== strpos( $api->get_error_message(), 'Plugin not found.' ) ) { - $api->add_data( array( 'status' => 404 ) ); - } else { - $api->add_data( array( 'status' => 500 ) ); - } - - return $api; - } - - $skin = new WP_Ajax_Upgrader_Skin(); - $upgrader = new Plugin_Upgrader( $skin ); - - $result = $upgrader->install( $api->download_link ); - - if ( is_wp_error( $result ) ) { - $result->add_data( array( 'status' => 500 ) ); - - return $result; - } - - // This should be the same as $result above. - if ( is_wp_error( $skin->result ) ) { - $skin->result->add_data( array( 'status' => 500 ) ); - - return $skin->result; - } - - if ( $skin->get_errors()->has_errors() ) { - $error = $skin->get_errors(); - $error->add_data( array( 'status' => 500 ) ); - - return $error; - } - - if ( is_null( $result ) ) { - global $wp_filesystem; - // Pass through the error from WP_Filesystem if one was raised. - if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) { - return new WP_Error( 'unable_to_connect_to_filesystem', $wp_filesystem->errors->get_error_message(), array( 'status' => 500 ) ); - } - - return new WP_Error( 'unable_to_connect_to_filesystem', __( 'Unable to connect to the filesystem. Please confirm your credentials.', 'gutenberg' ), array( 'status' => 500 ) ); - } - - $file = $upgrader->plugin_info(); - - if ( ! $file ) { - return new WP_Error( 'unable_to_determine_installed_plugin', __( 'Unable to determine what plugin was installed.', 'gutenberg' ), array( 'status' => 500 ) ); - } - - if ( 'inactive' !== $request['status'] ) { - $can_change_status = $this->plugin_status_permission_check( $file, $request['status'], 'inactive' ); - - if ( is_wp_error( $can_change_status ) ) { - return $can_change_status; - } - - $changed_status = $this->handle_plugin_status( $file, $request['status'], 'inactive' ); - - if ( is_wp_error( $changed_status ) ) { - return $changed_status; - } - } - - $path = WP_PLUGIN_DIR . '/' . $file; - $data = get_plugin_data( $path, false, false ); - $data['_file'] = $file; - - $response = $this->prepare_item_for_response( $data, $request ); - $response->set_status( 201 ); - $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $file, 0, - 4 ) ) ) ); - - return $response; - } - - /** - * Checks if a given request has access to update a specific plugin. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. - */ - public function update_item_permissions_check( $request ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - if ( ! current_user_can( 'activate_plugins' ) ) { - return new WP_Error( - 'rest_cannot_manage_plugins', - __( 'Sorry, you are not allowed to manage plugins for this site.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - $can_read = $this->check_read_permission( $request['plugin'] ); - - if ( is_wp_error( $can_read ) ) { - return $can_read; - } - - $status = $this->get_plugin_status( $request['plugin'] ); - - if ( $request['status'] && $status !== $request['status'] ) { - $can_change_status = $this->plugin_status_permission_check( $request['plugin'], $request['status'], $status ); - - if ( is_wp_error( $can_change_status ) ) { - return $can_change_status; - } - } - - return true; - } - - /** - * Updates one plugin. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function update_item( $request ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $data = $this->get_plugin_data( $request['plugin'] ); - - if ( is_wp_error( $data ) ) { - return $data; - } - - $status = $this->get_plugin_status( $request['plugin'] ); - - if ( $request['status'] && $status !== $request['status'] ) { - $handled = $this->handle_plugin_status( $request['plugin'], $request['status'], $status ); - - if ( is_wp_error( $handled ) ) { - return $handled; - } - } - - $this->update_additional_fields_for_object( $data, $request ); - - $request['context'] = 'edit'; - - return $this->prepare_item_for_response( $data, $request ); - } - - /** - * Checks if a given request has access to delete a specific plugin. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. - */ - public function delete_item_permissions_check( $request ) { - if ( ! current_user_can( 'activate_plugins' ) ) { - return new WP_Error( - 'rest_cannot_manage_plugins', - __( 'Sorry, you are not allowed to manage plugins for this site.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - if ( ! current_user_can( 'delete_plugins' ) ) { - return new WP_Error( - 'rest_cannot_manage_plugins', - __( 'Sorry, you are not allowed to delete plugins for this site.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - $can_read = $this->check_read_permission( $request['plugin'] ); - - if ( is_wp_error( $can_read ) ) { - return $can_read; - } - - return true; - } - - /** - * Deletes one plugin from the site. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function delete_item( $request ) { - require_once ABSPATH . 'wp-admin/includes/file.php'; - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - $data = $this->get_plugin_data( $request['plugin'] ); - - if ( is_wp_error( $data ) ) { - return $data; - } - - if ( is_plugin_active( $request['plugin'] ) ) { - return new WP_Error( - 'rest_cannot_delete_active_plugin', - __( 'Cannot delete an active plugin. Please deactivate it first.', 'gutenberg' ), - array( 'status' => 400 ) - ); - } - - $filesystem_available = $this->is_filesystem_available(); - if ( is_wp_error( $filesystem_available ) ) { - return $filesystem_available; - } - - $prepared = $this->prepare_item_for_response( $data, $request ); - $deleted = delete_plugins( array( $request['plugin'] ) ); - - if ( is_wp_error( $deleted ) ) { - $deleted->add_data( array( 'status' => 500 ) ); - - return $deleted; - } - - return new WP_REST_Response( - array( - 'deleted' => true, - 'previous' => $prepared->get_data(), - ) - ); - } - - /** - * Prepares the plugin for the REST response. - * - * @since 5.5.0 - * - * @param mixed $item Unmarked up and untranslated plugin data from {@see get_plugin_data()}. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. - */ - public function prepare_item_for_response( $item, $request ) { - $item = _get_plugin_data_markup_translate( $item['_file'], $item, false ); - $marked = _get_plugin_data_markup_translate( $item['_file'], $item, true ); - - $data = array( - 'plugin' => substr( $item['_file'], 0, - 4 ), - 'status' => $this->get_plugin_status( $item['_file'] ), - 'name' => $item['Name'], - 'plugin_uri' => $item['PluginURI'], - 'author' => $item['Author'], - 'author_uri' => $item['AuthorURI'], - 'description' => array( - 'raw' => $item['Description'], - 'rendered' => $marked['Description'], - ), - 'version' => $item['Version'], - 'network_only' => $item['Network'], - 'requires_wp' => $item['RequiresWP'], - 'requires_php' => $item['RequiresPHP'], - 'text_domain' => $item['TextDomain'], - ); - - $data = $this->add_additional_fields_to_object( $data, $request ); - - $response = new WP_REST_Response( $data ); - $response->add_links( $this->prepare_links( $item ) ); - - /** - * Filters the plugin data for a response. - * - * @since 5.5.0 - * - * @param WP_REST_Response $response The response object. - * @param array $item The plugin item from {@see get_plugin_data()}. - * @param WP_REST_Request $request The request object. - */ - return apply_filters( 'rest_prepare_plugin', $response, $item, $request ); - } - - /** - * Prepares links for the request. - * - * @since 5.5.0 - * - * @param array $item The plugin item. - * @return array[] - */ - protected function prepare_links( $item ) { - return array( - 'self' => array( - 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $item['_file'], 0, - 4 ) ) ), - ), - ); - } - - /** - * Gets the plugin header data for a plugin. - * - * @since 5.5.0 - * - * @param string $plugin The plugin file to get data for. - * @return array|WP_Error The plugin data, or a WP_Error if the plugin is not installed. - */ - protected function get_plugin_data( $plugin ) { - $plugins = get_plugins(); - - if ( ! isset( $plugins[ $plugin ] ) ) { - return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.', 'gutenberg' ), array( 'status' => 404 ) ); - } - - $data = $plugins[ $plugin ]; - $data['_file'] = $plugin; - - return $data; - } - - /** - * Get's the activation status for a plugin. - * - * @since 5.5.0 - * - * @param string $plugin The plugin file to check. - * @return string Either 'network-active', 'active' or 'inactive'. - */ - protected function get_plugin_status( $plugin ) { - if ( is_plugin_active_for_network( $plugin ) ) { - return 'network-active'; - } - - if ( is_plugin_active( $plugin ) ) { - return 'active'; - } - - return 'inactive'; - } - - /** - * Handle updating a plugin's status. - * - * @since 5.5.0 - * - * @param string $plugin The plugin file to update. - * @param string $new_status The plugin's new status. - * @param string $current_status The plugin's current status. - * - * @return true|WP_Error - */ - protected function plugin_status_permission_check( $plugin, $new_status, $current_status ) { - if ( is_multisite() && ( 'network-active' === $current_status || 'network-active' === $new_status ) && ! current_user_can( 'manage_network_plugins' ) ) { - return new WP_Error( - 'rest_cannot_manage_network_plugins', - __( 'Sorry, you do not have permission to manage network plugins.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - if ( ( 'active' === $new_status || 'network-active' === $new_status ) && ! current_user_can( 'activate_plugin', $plugin ) ) { - return new WP_Error( - 'rest_cannot_activate_plugin', - __( 'Sorry, you are not allowed to activate this plugin.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - if ( 'inactive' === $new_status && ! current_user_can( 'deactivate_plugin', $plugin ) ) { - return new WP_Error( - 'rest_cannot_deactivate_plugin', - __( 'Sorry, you are not allowed to deactivate this plugin.', 'gutenberg' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - - return true; - } - - /** - * Handle updating a plugin's status. - * - * @since 5.5.0 - * - * @param string $plugin The plugin file to update. - * @param string $new_status The plugin's new status. - * @param string $current_status The plugin's current status. - * @return true|WP_Error - */ - protected function handle_plugin_status( $plugin, $new_status, $current_status ) { - if ( 'inactive' === $new_status ) { - deactivate_plugins( $plugin, false, 'network-active' === $current_status ); - - return true; - } - - if ( 'active' === $new_status && 'network-active' === $current_status ) { - return true; - } - - $network_activate = 'network-active' === $new_status; - - if ( is_multisite() && ! $network_activate && is_network_only_plugin( $plugin ) ) { - return new WP_Error( - 'rest_network_only_plugin', - __( 'Network only plugin must be network activated.', 'gutenberg' ), - array( 'status' => 400 ) - ); - } - - $activated = activate_plugin( $plugin, '', $network_activate ); - - if ( is_wp_error( $activated ) ) { - $activated->add_data( array( 'status' => 500 ) ); - - return $activated; - } - - return true; - } - - /** - * Checks that the "plugin" parameter is a valid path. - * - * @since 5.5.0 - * - * @param string $file The plugin file parameter. - * @return bool - */ - public function validate_plugin_param( $file ) { - if ( ! is_string( $file ) || ! preg_match( '/' . self::PATTERN . '/u', $file ) ) { - return false; - } - - $validated = validate_file( plugin_basename( $file ) ); - - return 0 === $validated; - } - - /** - * Sanitizes the "plugin" parameter to be a proper plugin file with ".php" appended. - * - * @since 5.5.0 - * - * @param string $file The plugin file parameter. - * @return string - */ - public function sanitize_plugin_param( $file ) { - return plugin_basename( sanitize_text_field( $file . '.php' ) ); - } - - /** - * Checks if the plugin matches the requested parameters. - * - * @since 5.5.0 - * - * @param WP_REST_Request $request The request to require the plugin matches against. - * @param array $item The plugin item. - * - * @return bool - */ - protected function does_plugin_match_request( $request, $item ) { - $search = $request['search']; - - if ( $search ) { - $matched_search = false; - - foreach ( $item as $field ) { - if ( is_string( $field ) && false !== strpos( strip_tags( $field ), $search ) ) { - $matched_search = true; - break; - } - } - - if ( ! $matched_search ) { - return false; - } - } - - $status = $request['status']; - - if ( $status && ! in_array( $this->get_plugin_status( $item['_file'] ), $status, true ) ) { - return false; - } - - return true; - } - - /** - * Checks if the plugin is installed. - * - * @since 5.5.0 - * - * @param string $plugin The plugin file. - * @return bool - */ - protected function is_plugin_installed( $plugin ) { - return file_exists( WP_PLUGIN_DIR . '/' . $plugin ); - } - - /** - * Determine if the endpoints are available. - * - * Only the 'Direct' filesystem transport, and SSH/FTP when credentials are stored are supported at present. - * - * @since 5.5.0 - * - * @return true|WP_Error True if filesystem is available, WP_Error otherwise. - */ - protected function is_filesystem_available() { - $filesystem_method = get_filesystem_method(); - - if ( 'direct' === $filesystem_method ) { - return true; - } - - ob_start(); - $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() ); - ob_end_clean(); - - if ( $filesystem_credentials_are_stored ) { - return true; - } - - return new WP_Error( 'fs_unavailable', __( 'The filesystem is currently unavailable for managing plugins.', 'gutenberg' ), array( 'status' => 500 ) ); - } - - /** - * Retrieves the plugin's schema, conforming to JSON Schema. - * - * @since 4.7.0 - * - * @return array Item schema data. - */ - public function get_item_schema() { - if ( $this->schema ) { - return $this->add_additional_fields_schema( $this->schema ); - } - - $this->schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'plugin', - 'type' => 'object', - 'properties' => array( - 'plugin' => array( - 'description' => __( 'The plugin file.', 'gutenberg' ), - 'type' => 'string', - 'pattern' => self::PATTERN, - 'readonly' => true, - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'status' => array( - 'description' => __( 'The plugin activation status.', 'gutenberg' ), - 'type' => 'string', - 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'name' => array( - 'description' => __( 'The plugin name.', 'gutenberg' ), - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'plugin_uri' => array( - 'description' => __( 'The plugin\'s website address.', 'gutenberg' ), - 'type' => 'string', - 'format' => 'uri', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - ), - 'author' => array( - 'description' => __( 'The plugin author.', 'gutenberg' ), - 'type' => 'object', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - ), - 'author_uri' => array( - 'description' => __( 'Plugin author\'s website address.', 'gutenberg' ), - 'type' => 'string', - 'format' => 'uri', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - ), - 'description' => array( - 'description' => __( 'The plugin description.', 'gutenberg' ), - 'type' => 'object', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - 'properties' => array( - 'raw' => array( - 'description' => __( 'The raw plugin description.', 'gutenberg' ), - 'type' => 'string', - ), - 'rendered' => array( - 'description' => __( 'The plugin description formatted for display.', 'gutenberg' ), - 'type' => 'string', - ), - ), - ), - 'version' => array( - 'description' => __( 'The plugin version number.', 'gutenberg' ), - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - ), - 'network_only' => array( - 'description' => __( 'Whether the plugin can only be activated network-wide.', 'gutenberg' ), - 'type' => 'boolean', - 'readonly' => true, - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'requires_wp' => array( - 'description' => __( 'Minimum required version of WordPress.', 'gutenberg' ), - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'requires_php' => array( - 'description' => __( 'Minimum required version of PHP.', 'gutenberg' ), - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit', 'embed' ), - ), - 'text_domain' => array( - 'description' => __( 'The plugin\'s text domain.', 'gutenberg' ), - 'type' => 'string', - 'readonly' => true, - 'context' => array( 'view', 'edit' ), - ), - ), - ); - - return $this->add_additional_fields_schema( $this->schema ); - } - - /** - * Retrieves the query params for the collections. - * - * @since 5.5.0 - * - * @return array Query parameters for the collection. - */ - public function get_collection_params() { - $query_params = parent::get_collection_params(); - - $query_params['context']['default'] = 'view'; - - $query_params['status'] = array( - 'description' => __( 'Limits results to plugins with the given status.', 'gutenberg' ), - 'type' => 'array', - 'items' => array( - 'type' => 'string', - 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), - ), - ); - - unset( $query_params['page'], $query_params['per_page'] ); - - return $query_params; - } -} diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index 0fc357fb8a7d36..a94dbb1fde86d6 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -237,7 +237,7 @@ private static function get_user_origin() { $config = $decoded_data; } } - self::$user = new WP_Theme_JSON( $config ); + self::$user = new WP_Theme_JSON( $config, true ); return self::$user; } @@ -270,7 +270,6 @@ private static function get_user_origin() { * @return WP_Theme_JSON */ public function get_origin( $theme_support_data = array(), $origin = 'user', $merged = true ) { - if ( ( 'user' === $origin ) && $merged ) { $result = new WP_Theme_JSON(); $result->merge( self::get_core_origin() ); @@ -301,10 +300,6 @@ public function get_origin( $theme_support_data = array(), $origin = 'user', $me * Registers a Custom Post Type to store the user's origin config. */ public static function register_user_custom_post_type() { - if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) { - return; - } - $args = array( 'label' => __( 'Global Styles', 'gutenberg' ), 'description' => 'CPT to store user design tokens', diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index 8f0071f0478abe..c5a88421c7bbea 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -135,8 +135,8 @@ class WP_Theme_JSON { 'dropCap' => null, 'fontFamilies' => null, 'fontSizes' => null, - 'customFontStyle' => null, - 'customFontWeight' => null, + 'customFontStyle' => null, + 'customFontWeight' => null, 'customTextDecorations' => null, 'customTextTransforms' => null, ), @@ -272,21 +272,10 @@ class WP_Theme_JSON { 'value' => array( 'typography', 'lineHeight' ), 'support' => array( 'lineHeight' ), ), - 'paddingBottom' => array( - 'value' => array( 'spacing', 'padding', 'bottom' ), - 'support' => array( 'spacing', 'padding' ), - ), - 'paddingLeft' => array( - 'value' => array( 'spacing', 'padding', 'left' ), - 'support' => array( 'spacing', 'padding' ), - ), - 'paddingRight' => array( - 'value' => array( 'spacing', 'padding', 'right' ), - 'support' => array( 'spacing', 'padding' ), - ), - 'paddingTop' => array( - 'value' => array( 'spacing', 'padding', 'top' ), - 'support' => array( 'spacing', 'padding' ), + 'padding' => array( + 'value' => array( 'spacing', 'padding' ), + 'support' => array( 'spacing', 'padding' ), + 'properties' => array( 'top', 'right', 'bottom', 'left' ), ), 'textDecoration' => array( 'value' => array( 'typography', 'textDecoration' ), @@ -301,9 +290,10 @@ class WP_Theme_JSON { /** * Constructor. * - * @param array $contexts A structure that follows the theme.json schema. + * @param array $contexts A structure that follows the theme.json schema. + * @param boolean $should_escape_styles Whether the incoming styles should be escaped. */ - public function __construct( $contexts = array() ) { + public function __construct( $contexts = array(), $should_escape_styles = false ) { $this->contexts = array(); if ( ! is_array( $contexts ) ) { @@ -324,8 +314,9 @@ public function __construct( $contexts = array() ) { // Process styles subtree. $this->process_key( 'styles', $context, self::SCHEMA ); if ( isset( $context['styles'] ) ) { - $this->process_key( 'color', $context['styles'], self::SCHEMA['styles'] ); - $this->process_key( 'typography', $context['styles'], self::SCHEMA['styles'] ); + $this->process_key( 'color', $context['styles'], self::SCHEMA['styles'], $should_escape_styles ); + $this->process_key( 'spacing', $context['styles'], self::SCHEMA['styles'], $should_escape_styles ); + $this->process_key( 'typography', $context['styles'], self::SCHEMA['styles'], $should_escape_styles ); if ( empty( $context['styles'] ) ) { unset( $context['styles'] ); @@ -337,6 +328,7 @@ public function __construct( $contexts = array() ) { // Process settings subtree. $this->process_key( 'settings', $context, self::SCHEMA ); if ( isset( $context['settings'] ) ) { + $this->process_key( 'border', $context['settings'], self::SCHEMA['settings'] ); $this->process_key( 'color', $context['settings'], self::SCHEMA['settings'] ); $this->process_key( 'spacing', $context['settings'], self::SCHEMA['settings'] ); $this->process_key( 'typography', $context['settings'], self::SCHEMA['settings'] ); @@ -469,11 +461,12 @@ private static function get_blocks_metadata() { * This function modifies the given input by removing * the nodes that aren't valid per the schema. * - * @param string $key Key of the subtree to normalize. - * @param array $input Whole tree to normalize. - * @param array $schema Schema to use for normalization. + * @param string $key Key of the subtree to normalize. + * @param array $input Whole tree to normalize. + * @param array $schema Schema to use for normalization. + * @param boolean $should_escape Whether the subproperties should be escaped. */ - private static function process_key( $key, &$input, $schema ) { + private static function process_key( $key, &$input, $schema, $should_escape = false ) { if ( ! isset( $input[ $key ] ) ) { return; } @@ -493,6 +486,36 @@ private static function process_key( $key, &$input, $schema ) { $schema[ $key ] ); + if ( $should_escape ) { + $subtree = $input[ $key ]; + foreach ( $subtree as $property => $value ) { + $name = 'background-color'; + if ( 'gradient' === $property ) { + $name = 'background'; + } + + if ( is_array( $value ) ) { + $result = array(); + foreach ( $value as $subproperty => $subvalue ) { + $result_subproperty = safecss_filter_attr( "$name: $subvalue" ); + if ( '' !== $result_subproperty ) { + $result[ $subproperty ] = $result_subproperty; + } + } + + if ( empty( $result ) ) { + unset( $input[ $key ][ $property ] ); + } + } else { + $result = safecss_filter_attr( "$name: $value" ); + + if ( '' === $result ) { + unset( $input[ $key ][ $property ] ); + } + } + } + } + if ( 0 === count( $input[ $key ] ) ) { unset( $input[ $key ] ); } @@ -606,6 +629,21 @@ private static function get_property_value( $styles, $path ) { return $value; } + /** + * Whether the medatata contains a key named properties. + * + * @param array $metadata Description of the style property. + * + * @return boolean True if properties exists, false otherwise. + */ + private static function has_properties( $metadata ) { + if ( array_key_exists( 'properties', $metadata ) ) { + return true; + } + + return false; + } + /** * Given a context, it extracts the style properties * and adds them to the $declarations array following the format: @@ -628,14 +666,33 @@ private static function compute_style_properties( &$declarations, $context, $con return; } + $properties = array(); foreach ( self::PROPERTIES_METADATA as $name => $metadata ) { if ( ! in_array( $name, $context_supports, true ) ) { continue; } - $value = self::get_property_value( $context['styles'], $metadata['value'] ); + // Some properties can be shorthand properties, meaning that + // they contain multiple values instead of a single one. + if ( self::has_properties( $metadata ) ) { + foreach ( $metadata['properties'] as $property ) { + $properties[] = array( + 'name' => $name . ucfirst( $property ), + 'value' => array_merge( $metadata['value'], array( $property ) ), + ); + } + } else { + $properties[] = array( + 'name' => $name, + 'value' => $metadata['value'], + ); + } + } + + foreach ( $properties as $prop ) { + $value = self::get_property_value( $context['styles'], $prop['value'] ); if ( ! empty( $value ) ) { - $kebabcased_name = strtolower( preg_replace( '/(? $kebabcased_name, 'value' => $value, diff --git a/lib/compat.php b/lib/compat.php index d211a23dc4915c..008298df270967 100644 --- a/lib/compat.php +++ b/lib/compat.php @@ -8,231 +8,6 @@ * @package gutenberg */ -/** - * These functions can be removed when plugin support requires WordPress 5.5.0+. - * - * @see https://core.trac.wordpress.org/ticket/50263 - * @see https://core.trac.wordpress.org/changeset/48141 - */ -if ( ! function_exists( 'register_block_type_from_metadata' ) ) { - /** - * Removes the block asset's path prefix if provided. - * - * @since 5.5.0 - * - * @param string $asset_handle_or_path Asset handle or prefixed path. - * - * @return string Path without the prefix or the original value. - */ - function remove_block_asset_path_prefix( $asset_handle_or_path ) { - $path_prefix = 'file:'; - if ( strpos( $asset_handle_or_path, $path_prefix ) !== 0 ) { - return $asset_handle_or_path; - } - return substr( - $asset_handle_or_path, - strlen( $path_prefix ) - ); - } - - /** - * Generates the name for an asset based on the name of the block - * and the field name provided. - * - * @since 5.5.0 - * - * @param string $block_name Name of the block. - * @param string $field_name Name of the metadata field. - * - * @return string Generated asset name for the block's field. - */ - function generate_block_asset_handle( $block_name, $field_name ) { - $field_mappings = array( - 'editorScript' => 'editor-script', - 'script' => 'script', - 'editorStyle' => 'editor-style', - 'style' => 'style', - ); - return str_replace( '/', '-', $block_name ) . - '-' . $field_mappings[ $field_name ]; - } - - /** - * Finds a script handle for the selected block metadata field. It detects - * when a path to file was provided and finds a corresponding - * asset file with details necessary to register the script under - * automatically generated handle name. It returns unprocessed script handle - * otherwise. - * - * @since 5.5.0 - * - * @param array $metadata Block metadata. - * @param string $field_name Field name to pick from metadata. - * - * @return string|boolean Script handle provided directly or created through - * script's registration, or false on failure. - */ - function register_block_script_handle( $metadata, $field_name ) { - if ( empty( $metadata[ $field_name ] ) ) { - return false; - } - $script_handle = $metadata[ $field_name ]; - $script_path = remove_block_asset_path_prefix( $metadata[ $field_name ] ); - if ( $script_handle === $script_path ) { - return $script_handle; - } - - $script_handle = generate_block_asset_handle( $metadata['name'], $field_name ); - $script_asset_path = realpath( - dirname( $metadata['file'] ) . '/' . - substr_replace( $script_path, '.asset.php', - strlen( '.js' ) ) - ); - if ( ! file_exists( $script_asset_path ) ) { - $message = sprintf( - /* translators: %1: field name. %2: block name */ - __( 'The asset file for the "%1$s" defined in "%2$s" block definition is missing.', 'default' ), - $field_name, - $metadata['name'] - ); - _doing_it_wrong( __FUNCTION__, $message, '5.5.0' ); - return false; - } - $script_asset = require( $script_asset_path ); - $result = wp_register_script( - $script_handle, - plugins_url( $script_path, $metadata['file'] ), - $script_asset['dependencies'], - $script_asset['version'] - ); - return $result ? $script_handle : false; - } - - /** - * Finds a style handle for the block metadata field. It detects when a path - * to file was provided and registers the style under automatically - * generated handle name. It returns unprocessed style handle otherwise. - * - * @since 5.5.0 - * - * @param array $metadata Block metadata. - * @param string $field_name Field name to pick from metadata. - * - * @return string|boolean Style handle provided directly or created through - * style's registration, or false on failure. - */ - function register_block_style_handle( $metadata, $field_name ) { - if ( empty( $metadata[ $field_name ] ) ) { - return false; - } - $style_handle = $metadata[ $field_name ]; - $style_path = remove_block_asset_path_prefix( $metadata[ $field_name ] ); - if ( $style_handle === $style_path ) { - return $style_handle; - } - - $style_handle = generate_block_asset_handle( $metadata['name'], $field_name ); - $block_dir = dirname( $metadata['file'] ); - $result = wp_register_style( - $style_handle, - plugins_url( $style_path, $metadata['file'] ), - array(), - filemtime( realpath( "$block_dir/$style_path" ) ) - ); - return $result ? $style_handle : false; - } - - /** - * Registers a block type from metadata stored in the `block.json` file. - * - * @since 7.9.0 - * - * @param string $file_or_folder Path to the JSON file with metadata definition for - * the block or path to the folder where the `block.json` file is located. - * @param array $args { - * Optional. Array of block type arguments. Any arguments may be defined, however the - * ones described below are supported by default. Default empty array. - * - * @type callable $render_callback Callback used to render blocks of this block type. - * } - * @return WP_Block_Type|false The registered block type on success, or false on failure. - */ - function register_block_type_from_metadata( $file_or_folder, $args = array() ) { - $filename = 'block.json'; - $metadata_file = ( substr( $file_or_folder, -strlen( $filename ) ) !== $filename ) ? - trailingslashit( $file_or_folder ) . $filename : - $file_or_folder; - if ( ! file_exists( $metadata_file ) ) { - return false; - } - - $metadata = json_decode( file_get_contents( $metadata_file ), true ); - if ( ! is_array( $metadata ) || empty( $metadata['name'] ) ) { - return false; - } - $metadata['file'] = $metadata_file; - - $settings = array(); - $property_mappings = array( - 'title' => 'title', - 'category' => 'category', - 'parent' => 'parent', - 'icon' => 'icon', - 'description' => 'description', - 'keywords' => 'keywords', - 'attributes' => 'attributes', - 'providesContext' => 'provides_context', - 'usesContext' => 'uses_context', - // Deprecated: remove with Gutenberg 8.6 release. - 'context' => 'context', - 'supports' => 'supports', - 'styles' => 'styles', - 'example' => 'example', - ); - - foreach ( $property_mappings as $key => $mapped_key ) { - if ( isset( $metadata[ $key ] ) ) { - $settings[ $mapped_key ] = $metadata[ $key ]; - } - } - - if ( ! empty( $metadata['editorScript'] ) ) { - $settings['editor_script'] = register_block_script_handle( - $metadata, - 'editorScript' - ); - } - - if ( ! empty( $metadata['script'] ) ) { - $settings['script'] = register_block_script_handle( - $metadata, - 'script' - ); - } - - if ( ! empty( $metadata['editorStyle'] ) ) { - $settings['editor_style'] = register_block_style_handle( - $metadata, - 'editorStyle' - ); - } - - if ( ! empty( $metadata['style'] ) ) { - $settings['style'] = register_block_style_handle( - $metadata, - 'style' - ); - } - - return register_block_type( - $metadata['name'], - array_merge( - $settings, - $args - ) - ); - } -} - /** * Adds a wp.date.setSettings with timezone abbr parameter * @@ -304,114 +79,6 @@ function gutenberg_add_date_settings_timezone( $scripts ) { } add_action( 'wp_default_scripts', 'gutenberg_add_date_settings_timezone', 20 ); -/** - * Filters default block categories to substitute legacy category names with new - * block categories. - * - * This can be removed when plugin support requires WordPress 5.5.0+. - * - * @see https://core.trac.wordpress.org/ticket/50278 - * @see https://core.trac.wordpress.org/changeset/48177 - * - * @param array[] $default_categories Array of block categories. - * - * @return array[] Filtered block categories. - */ -function gutenberg_replace_default_block_categories( $default_categories ) { - $substitution = array( - 'common' => array( - 'slug' => 'text', - 'title' => __( 'Text', 'gutenberg' ), - 'icon' => null, - ), - 'formatting' => array( - 'slug' => 'media', - 'title' => __( 'Media', 'gutenberg' ), - 'icon' => null, - ), - 'layout' => array( - 'slug' => 'design', - 'title' => __( 'Design', 'gutenberg' ), - 'icon' => null, - ), - ); - - // Loop default categories to perform in-place substitution by legacy slug. - foreach ( $default_categories as $i => $default_category ) { - $slug = $default_category['slug']; - if ( isset( $substitution[ $slug ] ) ) { - $default_categories[ $i ] = $substitution[ $slug ]; - unset( $substitution[ $slug ] ); - } - } - - /* - * At this point, `$substitution` should contain only the categories which - * could not be in-place substituted with a default category, likely in the - * case that core has since been updated to use the default categories. - * Check to verify they exist. - */ - $default_category_slugs = wp_list_pluck( $default_categories, 'slug' ); - foreach ( $substitution as $i => $substitute_category ) { - if ( in_array( $substitute_category['slug'], $default_category_slugs, true ) ) { - unset( $substitution[ $i ] ); - } - } - - /* - * Any substitutes remaining should be appended, as they are not yet - * assigned in the default categories array. - */ - return array_merge( $default_categories, array_values( $substitution ) ); -} -add_filter( 'block_categories', 'gutenberg_replace_default_block_categories' ); - -/** - * Shim that hooks into `pre_render_block` so as to override `render_block` with - * a function that assigns block context. - * - * The context handling can be removed when plugin support requires WordPress 5.5.0+. - * - * @see https://core.trac.wordpress.org/ticket/49927 - * @see https://core.trac.wordpress.org/changeset/48243 - * - * @param string|null $pre_render The pre-rendered content. Defaults to null. - * @param array $parsed_block The parsed block being rendered. - * - * @return string String of rendered HTML. - */ -function gutenberg_render_block_with_assigned_block_context( $pre_render, $parsed_block ) { - $already_supports_context = version_compare( get_bloginfo( 'version' ), '5.5', '>=' ); - - /* - * If a non-null value is provided, a filter has run at an earlier priority - * and has already handled custom rendering and should take precedence. - */ - if ( null !== $pre_render || $already_supports_context ) { - return $pre_render; - } - - $source_block = $parsed_block; - - /** This filter is documented in src/wp-includes/blocks.php */ - $parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block ); - - $context = array(); - - /** - * Filters the default context provided to a rendered block. - * - * @param array $context Default context. - * @param array $parsed_block Block being rendered, filtered by `render_block_data`. - */ - $context = apply_filters( 'render_block_context', $context, $parsed_block ); - - $block = new WP_Block( $parsed_block, $context ); - - return $block->render(); -} -add_filter( 'pre_render_block', 'gutenberg_render_block_with_assigned_block_context', 9, 2 ); - /** * Determine if the current theme needs to load separate block styles or not. * diff --git a/lib/edit-site-page.php b/lib/edit-site-page.php index bc683ff0c02097..d73ad831a5233a 100644 --- a/lib/edit-site-page.php +++ b/lib/edit-site-page.php @@ -104,15 +104,16 @@ function gutenberg_edit_site_init( $hook ) { $settings = array_merge( gutenberg_get_common_block_editor_settings(), array( - 'alignWide' => get_theme_support( 'align-wide' ), - 'siteUrl' => site_url(), - 'postsPerPage' => get_option( 'posts_per_page' ), - 'styles' => gutenberg_get_editor_styles(), - 'defaultTemplateTypes' => gutenberg_get_indexed_default_template_types(), + 'alignWide' => get_theme_support( 'align-wide' ), + 'siteUrl' => site_url(), + 'postsPerPage' => get_option( 'posts_per_page' ), + 'styles' => gutenberg_get_editor_styles(), + 'defaultTemplateTypes' => gutenberg_get_indexed_default_template_types(), + '__experimentalBlockPatterns' => WP_Block_Patterns_Registry::get_instance()->get_all_registered(), + '__experimentalBlockPatternCategories' => WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(), ) ); $settings = gutenberg_experimental_global_styles_settings( $settings ); - $settings = gutenberg_extend_settings_block_patterns( $settings ); // Preload block editor paths. // most of these are copied from edit-forms-blocks.php. diff --git a/lib/full-site-editing/page-templates.php b/lib/full-site-editing/page-templates.php new file mode 100644 index 00000000000000..89ce31dba143f0 --- /dev/null +++ b/lib/full-site-editing/page-templates.php @@ -0,0 +1,42 @@ + $page_template ) { + if ( ( ! isset( $page_template['postTypes'] ) && 'page' === $post->post_type ) || + ( isset( $page_template['postTypes'] ) && in_array( $post->post_type, $page_template['postTypes'], true ) ) + ) { + $page_templates[ $key ] = $page_template['title']; + } + } + } + + return $page_templates; +} +add_filter( 'theme_post_templates', 'gutenberg_load_block_page_templates', 10, 3 ); +add_filter( 'theme_page_templates', 'gutenberg_load_block_page_templates', 10, 3 ); diff --git a/lib/global-styles.php b/lib/global-styles.php index 6c62d867fc967d..800048bdcb219f 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -162,6 +162,10 @@ function gutenberg_experimental_global_styles_get_stylesheet( $tree, $type = 'al * and enqueues the resulting stylesheet. */ function gutenberg_experimental_global_styles_enqueue_assets() { + if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) { + return; + } + $settings = gutenberg_get_common_block_editor_settings(); $theme_support_data = gutenberg_experimental_global_styles_get_theme_support_settings( $settings ); @@ -196,45 +200,74 @@ function gutenberg_experimental_global_styles_settings( $settings ) { unset( $settings['gradients'] ); $resolver = new WP_Theme_JSON_Resolver(); - $all = $resolver->get_origin( $theme_support_data ); - $base = $resolver->get_origin( $theme_support_data, 'theme' ); + $origin = 'theme'; + if ( + gutenberg_experimental_global_styles_has_theme_json_support() && + gutenberg_is_fse_theme() + ) { + // Only lookup for the user data if we need it. + $origin = 'user'; + } + $tree = $resolver->get_origin( $theme_support_data, $origin ); // STEP 1: ADD FEATURES - // These need to be added to settings always. - $settings['__experimentalFeatures'] = $all->get_settings(); + // + // These need to be always added to the editor settings, + // even for themes that don't support theme.json. + // An example of this is that the presets are configured + // from the theme support data. + $settings['__experimentalFeatures'] = $tree->get_settings(); // STEP 2 - IF EDIT-SITE, ADD DATA REQUIRED FOR GLOBAL STYLES SIDEBAR - // The client needs some information to be able to access/update the user styles. - // We only do this if the theme has support for theme.json, though, - // as an indicator that the theme will know how to combine this with its stylesheet. + // + // In the site editor, the user can change styles, so the client + // needs the ability to create them. Hence, we pass it some data + // for this: base styles (core+theme) and the ID of the user CPT. $screen = get_current_screen(); if ( ! empty( $screen ) && function_exists( 'gutenberg_is_edit_site_page' ) && gutenberg_is_edit_site_page( $screen->id ) && - gutenberg_experimental_global_styles_has_theme_json_support() + gutenberg_experimental_global_styles_has_theme_json_support() && + gutenberg_is_fse_theme() ) { - $settings['__experimentalGlobalStylesUserEntityId'] = WP_Theme_JSON_Resolver::get_user_custom_post_type_id(); - $settings['__experimentalGlobalStylesBaseStyles'] = $base->get_raw_data(); - } else { - // STEP 3 - OTHERWISE, ADD STYLES + $user_cpt_id = WP_Theme_JSON_Resolver::get_user_custom_post_type_id(); + $base_styles = $resolver->get_origin( $theme_support_data, 'theme' )->get_raw_data(); + + $settings['__experimentalGlobalStylesUserEntityId'] = $user_cpt_id; + $settings['__experimentalGlobalStylesBaseStyles'] = $base_styles; + } elseif ( gutenberg_experimental_global_styles_has_theme_json_support() ) { + // STEP 3 - ADD STYLES IF THEME HAS SUPPORT // // If we are in a block editor context, but not in edit-site, - // we need to add the styles via the settings. This is because - // we want them processed as if they were added via add_editor_styles, - // which adds the editor wrapper class. + // we add the styles via the settings, so the editor knows that + // some of these should be added the wrapper class, + // as if they were added via add_editor_styles. $settings['styles'][] = array( - 'css' => gutenberg_experimental_global_styles_get_stylesheet( $all, 'css_variables' ), + 'css' => gutenberg_experimental_global_styles_get_stylesheet( $tree, 'css_variables' ), '__experimentalNoWrapper' => true, ); $settings['styles'][] = array( - 'css' => gutenberg_experimental_global_styles_get_stylesheet( $all, 'block_styles' ), + 'css' => gutenberg_experimental_global_styles_get_stylesheet( $tree, 'block_styles' ), ); } return $settings; } -add_action( 'init', array( 'WP_Theme_JSON_Resolver', 'register_user_custom_post_type' ) ); +/** + * Register CPT to store/access user data. + * + * @return array|undefined + */ +function gutenberg_experimental_global_styles_register_user_cpt() { + if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) { + return; + } + + WP_Theme_JSON_Resolver::register_user_custom_post_type(); +} + +add_action( 'init', 'gutenberg_experimental_global_styles_register_user_cpt' ); add_filter( 'block_editor_settings', 'gutenberg_experimental_global_styles_settings', PHP_INT_MAX ); add_action( 'wp_enqueue_scripts', 'gutenberg_experimental_global_styles_enqueue_assets' ); diff --git a/lib/load.php b/lib/load.php index 82686d85ca45f8..02b54459609dd6 100644 --- a/lib/load.php +++ b/lib/load.php @@ -38,12 +38,6 @@ function gutenberg_is_experiment_enabled( $name ) { if ( ! class_exists( 'WP_REST_Widgets_Controller' ) ) { require_once __DIR__ . '/class-wp-rest-widgets-controller.php'; } - if ( ! class_exists( 'WP_REST_Block_Directory_Controller' ) ) { - require __DIR__ . '/class-wp-rest-block-directory-controller.php'; - } - if ( ! class_exists( 'WP_REST_Block_Types_Controller' ) ) { - require __DIR__ . '/class-wp-rest-block-types-controller.php'; - } if ( ! class_exists( 'WP_REST_Menus_Controller' ) ) { require_once __DIR__ . '/class-wp-rest-menus-controller.php'; } @@ -56,12 +50,6 @@ function gutenberg_is_experiment_enabled( $name ) { if ( ! class_exists( 'WP_Rest_Customizer_Nonces' ) ) { require_once __DIR__ . '/class-wp-rest-customizer-nonces.php'; } - if ( ! class_exists( 'WP_REST_Image_Editor_Controller' ) ) { - require __DIR__ . '/class-wp-rest-image-editor-controller.php'; - } - if ( ! class_exists( 'WP_REST_Plugins_Controller' ) ) { - require_once __DIR__ . '/class-wp-rest-plugins-controller.php'; - } if ( ! class_exists( 'WP_REST_Post_Format_Search_Handler' ) ) { require_once __DIR__ . '/class-wp-rest-post-format-search-handler.php'; } @@ -78,22 +66,6 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/rest-api.php'; } -if ( ! class_exists( 'WP_Block_Patterns_Registry' ) ) { - require __DIR__ . '/class-wp-block-patterns-registry.php'; -} - -if ( ! class_exists( 'WP_Block_Pattern_Categories_Registry' ) ) { - require __DIR__ . '/class-wp-block-pattern-categories-registry.php'; -} - -if ( ! class_exists( 'WP_Block' ) ) { - require __DIR__ . '/class-wp-block.php'; -} - -if ( ! class_exists( 'WP_Block_List' ) ) { - require __DIR__ . '/class-wp-block-list.php'; -} - if ( ! class_exists( 'WP_Widget_Block' ) ) { require_once __DIR__ . '/class-wp-widget-block.php'; } @@ -107,6 +79,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/full-site-editing.php'; require __DIR__ . '/full-site-editing/default-template-types.php'; require __DIR__ . '/full-site-editing/templates-utils.php'; +require __DIR__ . '/full-site-editing/page-templates.php'; require __DIR__ . '/templates-sync.php'; require __DIR__ . '/templates.php'; require __DIR__ . '/template-parts.php'; @@ -114,10 +87,8 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/edit-site-page.php'; require __DIR__ . '/edit-site-export.php'; -require __DIR__ . '/block-patterns.php'; require __DIR__ . '/blocks.php'; require __DIR__ . '/client-assets.php'; -require __DIR__ . '/block-directory.php'; require __DIR__ . '/demo.php'; require __DIR__ . '/widgets.php'; require __DIR__ . '/navigation.php'; diff --git a/lib/patterns/heading-paragraph.php b/lib/patterns/heading-paragraph.php deleted file mode 100644 index d06caa1d8cc2c8..00000000000000 --- a/lib/patterns/heading-paragraph.php +++ /dev/null @@ -1,13 +0,0 @@ - __( 'Heading and paragraph', 'gutenberg' ), - 'content' => "\n
\n

2.
" . __( 'Which treats of the first sally the ingenious Don Quixote made from home', 'gutenberg' ) . "

\n\n\n\n

" . __( 'These preliminaries settled, he did not care to put off any longer the execution of his design, urged on to it by the thought of all the world was losing by his delay, seeing what wrongs he intended to right, grievances to redress, injustices to repair, abuses to remove, and duties to discharge.', 'gutenberg' ) . "

\n
\n", - 'categories' => array( 'text' ), - 'description' => _x( 'A heading preceded by a chapter number, and followed by a paragraph.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/large-header-button.php b/lib/patterns/large-header-button.php deleted file mode 100644 index 75519963485e07..00000000000000 --- a/lib/patterns/large-header-button.php +++ /dev/null @@ -1,13 +0,0 @@ - __( 'Large header with a heading and a button ', 'gutenberg' ), - 'content' => "\n
\n
\n
\n
\n
\n\n\n\n
\n
\n\n\n\n

" . __( 'Thou hast seen
nothing yet', 'gutenberg' ) . "

\n\n\n\n\n\n\n\n
\n
\n\n\n\n
\n
\n
\n
\n
\n", - 'categories' => array( 'header' ), - 'description' => _x( 'A large hero section with a bright gradient background, a big heading and a filled button.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/large-header.php b/lib/patterns/large-header.php deleted file mode 100644 index 0583e1e6a03b2b..00000000000000 --- a/lib/patterns/large-header.php +++ /dev/null @@ -1,13 +0,0 @@ - __( 'Large header with a heading', 'gutenberg' ), - 'content' => "\n
\n

" . __( 'Don Quixote', 'gutenberg' ) . "

\n
\n", - 'categories' => array( 'header' ), - 'description' => _x( 'A large hero section with an example background image and a heading in the center.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/quote.php b/lib/patterns/quote.php deleted file mode 100644 index 0e1e0f3b248410..00000000000000 --- a/lib/patterns/quote.php +++ /dev/null @@ -1,14 +0,0 @@ - __( 'Quote', 'gutenberg' ), - 'content' => "\n
\n
\""
\n\n\n\n

" . __( '"Do you see over yonder, friend Sancho, thirty or forty hulking giants? I intend to do battle with them and slay them."', 'gutenberg' ) . '

' . __( '— Don Quixote', 'gutenberg' ) . "
\n\n\n\n
\n
\n", - 'viewportWidth' => 800, - 'categories' => array( 'text' ), - 'description' => _x( 'A quote and citation with an image above, and a separator at the bottom.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/text-three-columns-buttons.php b/lib/patterns/text-three-columns-buttons.php deleted file mode 100644 index 8386be74b9c5bb..00000000000000 --- a/lib/patterns/text-three-columns-buttons.php +++ /dev/null @@ -1,13 +0,0 @@ - __( 'Three columns of text with buttons', 'gutenberg' ), - 'categories' => array( 'columns' ), - 'content' => "\n
\n
\n
\n

" . __( 'Which treats of the character and pursuits of the famous Don Quixote of La Mancha.', 'gutenberg' ) . "

\n\n\n\n\n
\n\n\n\n
\n

" . __( 'Which treats of the first sally the ingenious Don Quixote made from home.', 'gutenberg' ) . "

\n\n\n\n\n
\n\n\n\n
\n

" . __( 'Wherein is related the droll way in which Don Quixote had himself dubbed a knight.', 'gutenberg' ) . "

\n\n\n\n\n
\n
\n
\n", - 'description' => _x( 'Three small columns of text, each with an outlined button with rounded corners at the bottom.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/text-two-columns-with-images.php b/lib/patterns/text-two-columns-with-images.php deleted file mode 100644 index c4978acbc371e7..00000000000000 --- a/lib/patterns/text-two-columns-with-images.php +++ /dev/null @@ -1,13 +0,0 @@ - __( 'Two columns of text with images', 'gutenberg' ), - 'categories' => array( 'columns' ), - 'content' => "\n
\n
\n
\n
\"\"/
\n\n\n\n

" . __( 'They must know, then, that the above-named gentleman whenever he was at leisure (which was mostly all the year round) gave himself up to reading books of chivalry with such ardour and avidity that he almost entirely neglected the pursuit of his field-sports, and even the management of his property; and to such a pitch did his eagerness and infatuation go that he sold many an acre of tillageland to buy books of chivalry to read, and brought home as many of them as he could get.', 'gutenberg' ) . "

\n
\n\n\n\n
\n
\"\"/
\n\n\n\n

" . __( 'But of all there were none he liked so well as those of the famous Feliciano de Silva\'s composition, for their lucidity of style and complicated conceits were as pearls in his sight, particularly when in his reading he came upon courtships and cartels, where he often found passages like "the reason of the unreason with which my reason is afflicted so weakens my reason that with reason I murmur at your beauty;" or again, "the high heavens render you deserving of the desert your greatness deserves."', 'gutenberg' ) . "

\n
\n
\n
\n", - 'description' => _x( 'Two columns of text, each with an image on top.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/text-two-columns.php b/lib/patterns/text-two-columns.php deleted file mode 100644 index ca40c74289a0a6..00000000000000 --- a/lib/patterns/text-two-columns.php +++ /dev/null @@ -1,13 +0,0 @@ - __( 'Two columns of text', 'gutenberg' ), - 'categories' => array( 'columns' ), - 'content' => "\n
\n

" . __( 'Which treats of the character and pursuits of the famous gentleman Don Quixote of La Mancha', 'gutenberg' ) . "

\n\n\n\n
\n
\n

" . __( 'In a village of La Mancha, the name of which I have no desire to call to mind, there lived not long since one of those gentlemen that keep a lance in the lance-rack, an old buckler, a lean hack, and a greyhound for coursing. An olla of rather more beef than mutton, a salad on most nights, scraps on Saturdays, lentils on Fridays, and a pigeon or so extra on Sundays, made away with three-quarters of his income.', 'gutenberg' ) . "

\n
\n\n\n\n
\n

" . __( 'The rest of it went in a doublet of fine cloth and velvet breeches and shoes to match for holidays, while on week-days he made a brave figure in his best homespun. He had in his house a housekeeper past forty, a niece under twenty, and a lad for the field and market-place, who used to saddle the hack as well as handle the bill-hook. The age of this gentleman of ours was bordering on fifty; he was of a hardy habit, spare, gaunt-featured, a very early riser and a great sportsman.', 'gutenberg' ) . "

\n
\n
\n
\n", - 'description' => _x( 'Two columns of text preceded by a long heading.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/three-buttons.php b/lib/patterns/three-buttons.php deleted file mode 100644 index 2f60d3cf009bfd..00000000000000 --- a/lib/patterns/three-buttons.php +++ /dev/null @@ -1,14 +0,0 @@ - __( 'Three buttons', 'gutenberg' ), - 'content' => "\n\n", - 'viewportWidth' => 600, - 'categories' => array( 'buttons' ), - 'description' => _x( 'Three filled buttons with rounded corners, side by side.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/two-buttons.php b/lib/patterns/two-buttons.php deleted file mode 100644 index 8cd24997ce20ed..00000000000000 --- a/lib/patterns/two-buttons.php +++ /dev/null @@ -1,14 +0,0 @@ - __( 'Two buttons', 'gutenberg' ), - 'content' => "\n\n", - 'viewportWidth' => 500, - 'categories' => array( 'buttons' ), - 'description' => _x( 'Two buttons, one filled and one outlined, side by side.', 'Block pattern description', 'gutenberg' ), -); diff --git a/lib/patterns/two-images.php b/lib/patterns/two-images.php deleted file mode 100644 index 6b71853f3f9707..00000000000000 --- a/lib/patterns/two-images.php +++ /dev/null @@ -1,13 +0,0 @@ - __( 'Two images side by side', 'gutenberg' ), - 'categories' => array( 'gallery' ), - 'description' => _x( 'An image gallery with two example images.', 'Block pattern description', 'gutenberg' ), - 'content' => "\n\n", -); diff --git a/lib/rest-api.php b/lib/rest-api.php index 30c44eb39d2452..add3d35f249d23 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -10,141 +10,6 @@ die( 'Silence is golden.' ); } -/** - * Handle a failing oEmbed proxy request to try embedding as a shortcode. - * - * @see https://core.trac.wordpress.org/ticket/45447 - * - * @since 2.3.0 - * - * @param WP_HTTP_Response|WP_Error $response The REST Request response. - * @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server). - * @param WP_REST_Request $request Request used to generate the response. - * @return WP_HTTP_Response|object|WP_Error The REST Request response. - */ -function gutenberg_filter_oembed_result( $response, $handler, $request ) { - if ( ! is_wp_error( $response ) || 'oembed_invalid_url' !== $response->get_error_code() || - '/oembed/1.0/proxy' !== $request->get_route() ) { - return $response; - } - - // Try using a classic embed instead. - global $wp_embed; - $html = $wp_embed->shortcode( array(), $_GET['url'] ); - if ( ! $html ) { - return $response; - } - - global $wp_scripts; - - // Check if any scripts were enqueued by the shortcode, and include them in - // the response. - $enqueued_scripts = array(); - foreach ( $wp_scripts->queue as $script ) { - $enqueued_scripts[] = $wp_scripts->registered[ $script ]->src; - } - - return array( - 'provider_name' => __( 'Embed Handler', 'gutenberg' ), - 'html' => $html, - 'scripts' => $enqueued_scripts, - ); -} -add_filter( 'rest_request_after_callbacks', 'gutenberg_filter_oembed_result', 10, 3 ); - -/** - * Add fields required for site editing to the /themes endpoint. - * - * @todo Remove once Gutenberg's minimum required WordPress version is v5.5. - * @see https://core.trac.wordpress.org/ticket/49906 - * @see https://core.trac.wordpress.org/changeset/47921 - * - * @param WP_REST_Response $response The response object. - * @param WP_Theme $theme Theme object used to create response. - */ -function gutenberg_filter_rest_prepare_theme( $response, $theme ) { - $data = $response->get_data(); - $fields = array_keys( $data ); - - /** - * The following is basically copied from Core's WP_REST_Themes_Controller::prepare_item_for_response() - * (as of WP v5.5), with `rest_is_field_included()` replaced by `! in_array()`. - * This makes sure that we add all the fields that are missing from Core. - * - * @see https://github.com/WordPress/WordPress/blob/019bc2d244c4d536338d2c634419583e928143df/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php#L118-L167 - */ - if ( ! in_array( 'stylesheet', $fields, true ) ) { - $data['stylesheet'] = $theme->get_stylesheet(); - } - - if ( ! in_array( 'template', $fields, true ) ) { - /** - * Use the get_template() method, not the 'Template' header, for finding the template. - * The 'Template' header is only good for what was written in the style.css, while - * get_template() takes into account where WordPress actually located the theme and - * whether it is actually valid. - */ - $data['template'] = $theme->get_template(); - } - - $plain_field_mappings = array( - 'requires_php' => 'RequiresPHP', - 'requires_wp' => 'RequiresWP', - 'textdomain' => 'TextDomain', - 'version' => 'Version', - ); - - foreach ( $plain_field_mappings as $field => $header ) { - if ( ! in_array( $field, $fields, true ) ) { - $data[ $field ] = $theme->get( $header ); - } - } - - if ( ! in_array( 'screenshot', $fields, true ) ) { - // Using $theme->get_screenshot() with no args to get absolute URL. - $data['screenshot'] = $theme->get_screenshot() ? $theme->get_screenshot() : ''; - } - - $rich_field_mappings = array( - 'author' => 'Author', - 'author_uri' => 'AuthorURI', - 'description' => 'Description', - 'name' => 'Name', - 'tags' => 'Tags', - 'theme_uri' => 'ThemeURI', - ); - - foreach ( $rich_field_mappings as $field => $header ) { - if ( ! in_array( $field, $fields, true ) ) { - $data[ $field ]['raw'] = $theme->display( $header, false, true ); - $data[ $field ]['rendered'] = $theme->display( $header ); - } - } - - $response->set_data( $data ); - return $response; -} -add_filter( 'rest_prepare_theme', 'gutenberg_filter_rest_prepare_theme', 10, 2 ); - -/** - * Registers the block directory. - * - * @since 6.5.0 - */ -function gutenberg_register_rest_block_directory() { - $block_directory_controller = new WP_REST_Block_Directory_Controller(); - $block_directory_controller->register_routes(); -} -add_filter( 'rest_api_init', 'gutenberg_register_rest_block_directory' ); - -/** - * Registers the Block types REST API routes. - */ -function gutenberg_register_block_type() { - $block_types = new WP_REST_Block_Types_Controller(); - $block_types->register_routes(); -} -add_action( 'rest_api_init', 'gutenberg_register_block_type' ); /** * Registers the menu locations area REST API routes. */ @@ -163,16 +28,6 @@ function gutenberg_register_rest_customizer_nonces() { } add_action( 'rest_api_init', 'gutenberg_register_rest_customizer_nonces' ); - -/** - * Registers the Plugins REST API routes. - */ -function gutenberg_register_plugins_endpoint() { - $plugins = new WP_REST_Plugins_Controller(); - $plugins->register_routes(); -} -add_action( 'rest_api_init', 'gutenberg_register_plugins_endpoint' ); - /** * Registers the Sidebars & Widgets REST API routes. */ @@ -307,25 +162,6 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na } add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 ); -/** - * Registers the image editor. - * - * @since 7.x.0 - */ -function gutenberg_register_image_editor() { - global $wp_version; - - // Strip '-src' from the version string. Messes up version_compare(). - $version = str_replace( '-src', '', $wp_version ); - - // Only register routes for versions older than WP 5.5. - if ( version_compare( $version, '5.5-beta', '<' ) ) { - $image_editor = new WP_REST_Image_Editor_Controller(); - $image_editor->register_routes(); - } -} -add_filter( 'rest_api_init', 'gutenberg_register_image_editor' ); - /** * Registers the post format search handler. * diff --git a/lib/template-loader.php b/lib/template-loader.php index b886a9f5ab58b6..5dc55ec88cb8f1 100644 --- a/lib/template-loader.php +++ b/lib/template-loader.php @@ -63,7 +63,6 @@ function get_template_hierarchy( $template_type ) { */ function gutenberg_override_query_template( $template, $type, array $templates = array() ) { global $_wp_current_template_content; - $current_template = gutenberg_resolve_template( $type, $templates ); if ( $current_template ) { @@ -215,7 +214,7 @@ function gutenberg_viewport_meta_tag() { * @return string Template file name without extension. */ function gutenberg_strip_php_suffix( $template_file ) { - return preg_replace( '/\.php$/', '', $template_file ); + return preg_replace( '/\.(php|html)$/', '', $template_file ); } /** diff --git a/package-lock.json b/package-lock.json index 7baee614bf0837..8c29e66a6aafe9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "9.6.0-rc.1", + "version": "9.7.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1511,22 +1511,24 @@ "@types/hammerjs": "^2.0.36" } }, - "@egoist/vue-to-react": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@egoist/vue-to-react/-/vue-to-react-1.1.0.tgz", - "integrity": "sha512-MwfwXHDh6ptZGLEtNLPXp2Wghteav7mzpT2Mcwl3NZWKF814i5hhHnNkVrcQQEuxUroSWQqzxLkMKSb+nhPang==", - "dev": true - }, "@emotion/cache": { - "version": "10.0.19", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.19.tgz", - "integrity": "sha512-BoiLlk4vEsGBg2dAqGSJu0vJl/PgVtCYLBFJaEO8RmQzPugXewQCXZJNXTDFaRlfCs0W+quesayav4fvaif5WQ==", + "version": "10.0.29", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", + "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==", "dev": true, "requires": { - "@emotion/sheet": "0.9.3", - "@emotion/stylis": "0.8.4", - "@emotion/utils": "0.11.2", - "@emotion/weak-memoize": "0.2.4" + "@emotion/sheet": "0.9.4", + "@emotion/stylis": "0.8.5", + "@emotion/utils": "0.11.3", + "@emotion/weak-memoize": "0.2.5" + }, + "dependencies": { + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==", + "dev": true + } } }, "@emotion/core": { @@ -1664,9 +1666,9 @@ } }, "@emotion/sheet": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.3.tgz", - "integrity": "sha512-c3Q6V7Df7jfwSq5AzQWbXHa5soeE4F5cbqi40xn0CzXxWW9/6Mxq48WJEtqfWzbZtW9odZdnRAkwCQwN12ob4A==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz", + "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==", "dev": true }, "@emotion/styled": { @@ -1690,9 +1692,9 @@ } }, "@emotion/stylis": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.4.tgz", - "integrity": "sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==", "dev": true }, "@emotion/utils": { @@ -1701,9 +1703,9 @@ "integrity": "sha512-UHX2XklLl3sIaP6oiMmlVzT0J+2ATTVpf0dHQVyPJHTkOITvXfaSqnRk6mdDhV9pR8T/tHc3cex78IKXssmzrA==" }, "@emotion/weak-memoize": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.4.tgz", - "integrity": "sha512-6PYY5DVdAY1ifaQW6XYTnOMihmBVT27elqSjEoodchsGjzYlEsTQMcEhSud99kVawatyTZRTiVkJ/c6lwbQ7nA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", "dev": true }, "@evocateur/libnpmaccess": { @@ -3958,70 +3960,186 @@ } }, "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", + "slash": "^3.0.0", "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" + "write-file-atomic": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@types/yargs-parser": "*" + "@types/istanbul-lib-report": "*" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, + "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" + } + }, + "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" + } + }, + "fsevents": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.1.tgz", + "integrity": "sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==", + "dev": true, + "optional": true + }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "slash": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "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 + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "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" + } + }, + "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 + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "source-map": { @@ -4030,15 +4148,34 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "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" + } + }, "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } } } @@ -6333,14 +6470,14 @@ } }, "@mdx-js/loader": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.5.5.tgz", - "integrity": "sha512-2/2WX73qj79Kv2cYk14kQsN/aypAH3RPzuNMx1gxwZjj77G0N6tzhM9WFkEDM/SXjasWep03ZmSRb9d//b2D8w==", + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.22.tgz", + "integrity": "sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==", "dev": true, "requires": { - "@mdx-js/mdx": "^1.5.5", - "@mdx-js/react": "^1.5.5", - "loader-utils": "1.2.3" + "@mdx-js/mdx": "1.6.22", + "@mdx-js/react": "1.6.22", + "loader-utils": "2.0.0" }, "dependencies": { "big.js": { @@ -6349,121 +6486,65 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" } }, "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "dev": true, "requires": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } } } }, "@mdx-js/mdx": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.5.5.tgz", - "integrity": "sha512-Xv1lJ+VWt8giWQrqf4GdIBxl08SfepfIWAnuuIzuR+wA59SaXDvkW6XFIvl8u495OQEB1eugMvq8l2XR8ZGr1A==", + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", + "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", "dev": true, "requires": { - "@babel/core": "7.8.0", - "@babel/plugin-syntax-jsx": "7.8.0", - "@babel/plugin-syntax-object-rest-spread": "7.8.0", - "@mdx-js/util": "^1.5.5", - "babel-plugin-apply-mdx-type-prop": "^1.5.5", - "babel-plugin-extract-import-names": "^1.5.5", + "@babel/core": "7.12.9", + "@babel/plugin-syntax-jsx": "7.12.1", + "@babel/plugin-syntax-object-rest-spread": "7.8.3", + "@mdx-js/util": "1.6.22", + "babel-plugin-apply-mdx-type-prop": "1.6.22", + "babel-plugin-extract-import-names": "1.6.22", "camelcase-css": "2.0.1", - "detab": "2.0.2", - "hast-util-raw": "5.0.1", + "detab": "2.0.4", + "hast-util-raw": "6.0.1", "lodash.uniq": "4.5.0", - "mdast-util-to-hast": "6.0.2", - "remark-mdx": "^1.5.5", - "remark-parse": "7.0.2", - "remark-squeeze-paragraphs": "3.0.4", + "mdast-util-to-hast": "10.0.1", + "remark-footnotes": "2.0.0", + "remark-mdx": "1.6.22", + "remark-parse": "8.0.3", + "remark-squeeze-paragraphs": "4.0.0", "style-to-object": "0.3.0", - "unified": "8.4.2", - "unist-builder": "1.0.4", - "unist-util-visit": "2.0.1" + "unified": "9.2.0", + "unist-builder": "2.0.3", + "unist-util-visit": "2.0.3" }, "dependencies": { - "@babel/core": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.0.tgz", - "integrity": "sha512-3rqPi/bv/Xfu2YzHvBz4XqMI1fKVwnhntPA1/fjoECrSjrhbOCxlTrbVu5gUtr8zkxW+RpkDOa/HCW93gzS2Dw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.0", - "@babel/generator": "^7.8.0", - "@babel/helpers": "^7.8.0", - "@babel/parser": "^7.8.0", - "@babel/template": "^7.8.0", - "@babel/traverse": "^7.8.0", - "@babel/types": "^7.8.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.0.tgz", - "integrity": "sha512-zLDUckAuKeOtxJhfNE0TlR7iEApb2u7EYRlh5cxKzq6A5VzUbYEdyJGJlug41jDbjRbHTtsLKZUnUcy/8V3xZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.0.tgz", - "integrity": "sha512-dt89fDlkfkTrQcy5KavMQPyF2A6tR0kYp8HAnIoQv5hO34iAUffHghP/hMGd7Gf/+uYTmLQO0ar7peX1SUWyIA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "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": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true }, "is-plain-obj": { @@ -6472,82 +6553,86 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, - "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dev": true, "requires": { - "minimist": "^1.2.0" + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" } }, - "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 - }, "remark-parse": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-7.0.2.tgz", - "integrity": "sha512-9+my0lQS80IQkYXsMA8Sg6m9QfXYJBnXjWYN5U+kFc5/n69t+XZVXU/ZBYr3cYH8FheEGf1v87rkFDhJ8bVgMA==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", + "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", "dev": true, "requires": { + "ccount": "^1.0.0", "collapse-white-space": "^1.0.2", "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0", "is-whitespace-character": "^1.0.0", "is-word-character": "^1.0.0", "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", + "parse-entities": "^2.0.0", "repeat-string": "^1.5.4", "state-toggle": "^1.0.0", "trim": "0.0.1", "trim-trailing-lines": "^1.0.0", "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", + "unist-util-remove-position": "^2.0.0", + "vfile-location": "^3.0.0", "xtend": "^4.0.1" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "unified": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz", - "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", "dev": true, "requires": { "bail": "^1.0.0", "extend": "^3.0.0", + "is-buffer": "^2.0.0", "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" } }, "unist-util-is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.1.tgz", - "integrity": "sha512-7NYjErP4LJtkEptPR22wO5RsCPnHZZrop7t2SoQzjvpFedCFer4WW8ujj9GI5DkUX7yVcffXLjoURf6h2QUv6Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", "dev": true }, + "unist-util-remove-position": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", + "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", + "dev": true, + "requires": { + "unist-util-visit": "^2.0.0" + } + }, "unist-util-stringify-position": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz", - "integrity": "sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dev": true, "requires": { "@types/unist": "^2.0.2" } }, "unist-util-visit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.1.tgz", - "integrity": "sha512-bEDa5S/O8WRDeI1mLaMoKuFFi89AjF+UAoMNxO+bbVdo06q+53Vhq4iiv1PenL6Rx1ZxIpXIzqZoc5HD2I1oMA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -6556,9 +6641,9 @@ } }, "unist-util-visit-parents": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.1.tgz", - "integrity": "sha512-umEOTkm6/y1gIqPrqet55mYqlvGXCia/v1FSc5AveLAI7jFmOAIbqiwcHcviLcusAkEQt1bq2hixCKO9ltMb2Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -6566,22 +6651,27 @@ } }, "vfile": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.0.2.tgz", - "integrity": "sha512-yhoTU5cDMSsaeaMfJ5g0bUKYkYmZhAh9fn9TZicxqn+Cw4Z439il2v3oT9S0yjlpqlI74aFOQCt3nOV+pxzlkw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "dev": true, "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" } }, + "vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "dev": true + }, "vfile-message": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.2.tgz", - "integrity": "sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -6591,15 +6681,15 @@ } }, "@mdx-js/react": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.5.5.tgz", - "integrity": "sha512-Qwvri4zyU9ZbhhXsH0wfSZ/J9b8mARRTB6GSCTnyKRffO2CaQXl9oLsvRAeQSLRei/onEARc+RexH+jMeNS1rw==", + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", + "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", "dev": true }, "@mdx-js/util": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.5.5.tgz", - "integrity": "sha512-IudQkyZuM8T1CrSX9r0ShPXCABjtEtyrV4lxQqhKAwFqw1aYpy/5LOZhitMLoJTybZPVdPotuh+zjqYy9ZOSbA==", + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", + "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", "dev": true }, "@mrmlnc/readdir-enhanced": { @@ -6876,22 +6966,84 @@ } } }, + "@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz", + "integrity": "sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ==", + "dev": true, + "requires": { + "ansi-html": "^0.0.7", + "error-stack-parser": "^2.0.6", + "html-entities": "^1.2.1", + "native-url": "^0.2.6", + "schema-utils": "^2.6.5", + "source-map": "^0.7.3" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "@popperjs/core": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.2.tgz", "integrity": "sha512-JlGTGRYHC2QK+DDbePyXdBdooxFq2+noLfWpRqJtkxcb/oYWzOF0kcbfvvbWrwevCC1l6hLUg1wHYT+ona5BWQ==" }, "@reach/router": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.2.1.tgz", - "integrity": "sha512-kTaX08X4g27tzIFQGRukaHmNbtMYDS3LEWIS8+l6OayGIw6Oyo1HIF/JzeuR2FoF9z6oV+x/wJSVSq4v8tcUGQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", + "integrity": "sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==", "dev": true, "requires": { - "create-react-context": "^0.2.1", + "create-react-context": "0.3.0", "invariant": "^2.2.3", "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4", - "warning": "^3.0.0" + "react-lifecycles-compat": "^3.0.4" } }, "@react-native-community/blur": { @@ -7144,93 +7296,89 @@ } }, "@storybook/addon-a11y": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-5.3.2.tgz", - "integrity": "sha512-JOx4GZl8ZDxPlYnMTiBNnzE6GQzojlJobcbJiXWXJP1P7YnOL7IwVS5zNxtGAtN0npL2I0ZhhSSsaG2Si5IoLQ==", - "dev": true, - "requires": { - "@storybook/addons": "5.3.2", - "@storybook/api": "5.3.2", - "@storybook/client-logger": "5.3.2", - "@storybook/components": "5.3.2", - "@storybook/core-events": "5.3.2", - "@storybook/theming": "5.3.2", - "axe-core": "^3.3.2", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.1.11.tgz", + "integrity": "sha512-DJJeBoYlO/WjSKgQEE44fwaKg9KZE6yifPAXT6oJlEPU9sRNnIIY5cAJNeaRbJ61SZ8rDr51iF/4yJb0uvyNxw==", + "dev": true, + "requires": { + "@storybook/addons": "6.1.11", + "@storybook/api": "6.1.11", + "@storybook/channels": "6.1.11", + "@storybook/client-api": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/components": "6.1.11", + "@storybook/core-events": "6.1.11", + "@storybook/theming": "6.1.11", + "axe-core": "^4.0.1", "core-js": "^3.0.1", "global": "^4.3.2", - "memoizerific": "^1.11.3", - "react": "^16.8.3", - "react-redux": "^7.0.2", + "lodash": "^4.17.15", "react-sizeme": "^2.5.2", - "redux": "^4.0.1", - "ts-dedent": "^1.1.0", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" }, "dependencies": { - "redux": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", - "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "symbol-observable": "^1.2.0" - } + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true } } }, "@storybook/addon-docs": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-5.3.2.tgz", - "integrity": "sha512-gGxDYP2VMl2Js3eSR0FM/QCf8PULLoZq57LIA8mxX38oxOydC3mIG1970sUM/g6MDtP4TV4F6rjd++eY4Gc07g==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.2", - "@babel/plugin-transform-react-jsx": "^7.3.0", - "@egoist/vue-to-react": "^1.1.0", - "@jest/transform": "^24.9.0", - "@mdx-js/loader": "^1.5.1", - "@mdx-js/mdx": "^1.5.1", - "@mdx-js/react": "^1.5.1", - "@storybook/addons": "5.3.2", - "@storybook/api": "5.3.2", - "@storybook/components": "5.3.2", - "@storybook/core-events": "5.3.2", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-6.1.11.tgz", + "integrity": "sha512-dC6RpNWFvbEs68WDk30jrzmPncR0u7nn0SQl0Ao1wdLqCU81ptti/t6Yc7zanlo9hokMzGiom87ZMef0ad9nTQ==", + "dev": true, + "requires": { + "@babel/core": "^7.12.1", + "@babel/generator": "^7.12.1", + "@babel/parser": "^7.12.3", + "@babel/plugin-transform-react-jsx": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@jest/transform": "^26.0.0", + "@mdx-js/loader": "^1.6.19", + "@mdx-js/mdx": "^1.6.19", + "@mdx-js/react": "^1.6.19", + "@storybook/addons": "6.1.11", + "@storybook/api": "6.1.11", + "@storybook/client-api": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/components": "6.1.11", + "@storybook/core": "6.1.11", + "@storybook/core-events": "6.1.11", "@storybook/csf": "0.0.1", - "@storybook/postinstall": "5.3.2", - "@storybook/source-loader": "5.3.2", - "@storybook/theming": "5.3.2", + "@storybook/node-logger": "6.1.11", + "@storybook/postinstall": "6.1.11", + "@storybook/source-loader": "6.1.11", + "@storybook/theming": "6.1.11", "acorn": "^7.1.0", "acorn-jsx": "^5.1.0", "acorn-walk": "^7.0.0", "core-js": "^3.0.1", "doctrine": "^3.0.0", "escodegen": "^1.12.0", + "fast-deep-equal": "^3.1.1", "global": "^4.3.2", "html-tags": "^3.1.0", "js-string-escape": "^1.0.1", "lodash": "^4.17.15", + "prettier": "~2.0.5", "prop-types": "^15.7.2", - "react-element-to-jsx-string": "^14.1.0", - "remark-external-links": "^5.0.0", - "remark-slug": "^5.1.2", - "ts-dedent": "^1.1.0", - "util-deprecate": "^1.0.2", - "vue-docgen-api": "^4.1.0", - "vue-docgen-loader": "^1.3.0-beta.0" + "react-element-to-jsx-string": "^14.3.1", + "regenerator-runtime": "^0.13.7", + "remark-external-links": "^6.0.0", + "remark-slug": "^6.0.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" }, "dependencies": { "acorn": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", - "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", - "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "doctrine": { @@ -7242,71 +7390,93 @@ "esutils": "^2.0.2" } }, - "html-tags": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", - "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "source-map": { - "version": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true } } }, "@storybook/addon-knobs": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-knobs/-/addon-knobs-5.3.2.tgz", - "integrity": "sha512-5enTXIoVzepQDDe55wTQOfqT1cOwngjlakKar7lYWqww2ixVJJ3xMZ9dLqnYZkROMsN67sDwmuawvze+W5lbEA==", - "dev": true, - "requires": { - "@storybook/addons": "5.3.2", - "@storybook/api": "5.3.2", - "@storybook/client-api": "5.3.2", - "@storybook/components": "5.3.2", - "@storybook/core-events": "5.3.2", - "@storybook/theming": "5.3.2", - "@types/react-color": "^3.0.1", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-knobs/-/addon-knobs-6.1.11.tgz", + "integrity": "sha512-5bVB7JbClyL/v8hJcifRL1Jetj1rDbVjmIOw2RputZHPbOJ2Dd18X3uOAfzNa7e2KJ0BmtA1ojZ3PuDfy9MAPw==", + "dev": true, + "requires": { + "@storybook/addons": "6.1.11", + "@storybook/api": "6.1.11", + "@storybook/channels": "6.1.11", + "@storybook/client-api": "6.1.11", + "@storybook/components": "6.1.11", + "@storybook/core-events": "6.1.11", + "@storybook/theming": "6.1.11", "copy-to-clipboard": "^3.0.8", "core-js": "^3.0.1", "escape-html": "^1.0.3", - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "global": "^4.3.2", "lodash": "^4.17.15", "prop-types": "^15.7.2", "qs": "^6.6.0", "react-color": "^2.17.0", "react-lifecycles-compat": "^3.0.4", - "react-select": "^3.0.8" + "react-select": "^3.0.8", + "regenerator-runtime": "^0.13.7" }, "dependencies": { + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "qs": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz", - "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==", + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "dev": true } } }, "@storybook/addon-storysource": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.3.2.tgz", - "integrity": "sha512-wLbYfwM/XX0HbXvJNWpTrA+Z61EIZQafEDClFeM0OUSoG7PkXzLEHQb5UC0me1an9veZfgejjEqn2NmMkAAV0Q==", - "dev": true, - "requires": { - "@storybook/addons": "5.3.2", - "@storybook/components": "5.3.2", - "@storybook/router": "5.3.2", - "@storybook/source-loader": "5.3.2", - "@storybook/theming": "5.3.2", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-6.1.11.tgz", + "integrity": "sha512-uscKgALJa/inMFPb/Fpe9LXB6c6WlrGOfaUiAdrahn9gZbDAG9qunaSkAZ9EPWckSosq3RuV59HMCQ2Bolh/lQ==", + "dev": true, + "requires": { + "@storybook/addons": "6.1.11", + "@storybook/api": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/components": "6.1.11", + "@storybook/router": "6.1.11", + "@storybook/source-loader": "6.1.11", + "@storybook/theming": "6.1.11", "core-js": "^3.0.1", "estraverse": "^4.2.0", - "loader-utils": "^1.2.3", - "prettier": "^1.16.4", + "loader-utils": "^2.0.0", + "prettier": "~2.0.5", "prop-types": "^15.7.2", - "react-syntax-highlighter": "^11.0.2", - "regenerator-runtime": "^0.13.3", - "util-deprecate": "^1.0.2" + "react-syntax-highlighter": "^13.5.0", + "regenerator-runtime": "^0.13.7" }, "dependencies": { "big.js": { @@ -7315,270 +7485,374 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" } }, "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "dev": true, "requires": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "dev": true }, "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "dev": true } } }, "@storybook/addon-viewport": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-5.3.2.tgz", - "integrity": "sha512-4W1pxVymFIcFO535Q2h7gXXdGeVluvVhHJGU58fFtrKVAN1UOgMprMe/6PnisvDtyWwqUbEHwxxghoaVF28xXA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-6.1.11.tgz", + "integrity": "sha512-VgCRLpTu56WzSJ0piBu4nL99GtXeMcDxaLvEZKyVCoYjyQZxRcg4N9OFwxpnu6bYYF7O4pMbs2wITc4mW6YSEg==", "dev": true, "requires": { - "@storybook/addons": "5.3.2", - "@storybook/api": "5.3.2", - "@storybook/client-logger": "5.3.2", - "@storybook/components": "5.3.2", - "@storybook/core-events": "5.3.2", - "@storybook/theming": "5.3.2", + "@storybook/addons": "6.1.11", + "@storybook/api": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/components": "6.1.11", + "@storybook/core-events": "6.1.11", + "@storybook/theming": "6.1.11", "core-js": "^3.0.1", "global": "^4.3.2", "memoizerific": "^1.11.3", "prop-types": "^15.7.2", - "util-deprecate": "^1.0.2" + "regenerator-runtime": "^0.13.7" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + } } }, "@storybook/addons": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-5.3.2.tgz", - "integrity": "sha512-vSByVK0yQJ8kjYmw8Ayj7cmCIOEdQKNjV7OLTXmLMpde+hUBqmDbCzwT0m5kZjzSFRTvB8bz0WBPavE02ZBN8A==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.1.11.tgz", + "integrity": "sha512-OZXsdmn60dVe482l9zWxzOqqJApD2jggk/8QJKn3/Ub9posmqdqg712bW6v71BBe0UXXG/QfkZA7gcyiyEENbw==", "dev": true, "requires": { - "@storybook/api": "5.3.2", - "@storybook/channels": "5.3.2", - "@storybook/client-logger": "5.3.2", - "@storybook/core-events": "5.3.2", + "@storybook/api": "6.1.11", + "@storybook/channels": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/core-events": "6.1.11", + "@storybook/router": "6.1.11", + "@storybook/theming": "6.1.11", "core-js": "^3.0.1", "global": "^4.3.2", - "util-deprecate": "^1.0.2" + "regenerator-runtime": "^0.13.7" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + } } }, "@storybook/api": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-5.3.2.tgz", - "integrity": "sha512-4XK1+RXCb0HnQsmDzQn6H9SljibV/Mi/vIixlcprcTZ5sBPhaMumt/T3d2rUEyP7Lpm4/7HMsuuhkkkXcjPJJw==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.1.11.tgz", + "integrity": "sha512-/p4QW/p3uWO0AKVveNezX3I/CotyBKaJ5ui8PuvSPsl7yvqcsK41qI4evKOw7GMQn6oP+2enRbzHpGuCUgQSjA==", "dev": true, "requires": { - "@reach/router": "^1.2.1", - "@storybook/channels": "5.3.2", - "@storybook/client-logger": "5.3.2", - "@storybook/core-events": "5.3.2", + "@reach/router": "^1.3.3", + "@storybook/channels": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/core-events": "6.1.11", "@storybook/csf": "0.0.1", - "@storybook/router": "5.3.2", - "@storybook/theming": "5.3.2", - "@types/reach__router": "^1.2.3", + "@storybook/router": "6.1.11", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.1.11", + "@types/reach__router": "^1.3.5", "core-js": "^3.0.1", - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "global": "^4.3.2", "lodash": "^4.17.15", "memoizerific": "^1.11.3", - "prop-types": "^15.6.2", - "react": "^16.8.3", - "semver": "^6.0.0", - "shallow-equal": "^1.1.0", + "regenerator-runtime": "^0.13.7", "store2": "^2.7.1", - "telejson": "^3.2.0", + "telejson": "^5.0.2", + "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@storybook/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", + "dev": true, + "requires": { + "core-js": "^3.6.5", + "find-up": "^4.1.0" + }, + "dependencies": { + "core-js": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.1.tgz", + "integrity": "sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg==", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "shallow-equal": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", - "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.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 + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "dev": true } } }, "@storybook/channel-postmessage": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.3.2.tgz", - "integrity": "sha512-2SnYDtzBhtBEu8tKn+2QzewdW1/R7xpBY3FmMqhY+vdBCtFFSqdiFuaKbGUQRKKLH+mQEKc7DBVf/U+HJlKPyg==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.1.11.tgz", + "integrity": "sha512-voW4Z2SUacDOxwN2q1NEBL//8OpgvL2C5CeoG1VQyEllKM8Vg9t1Nxo2FFTJBzv5LeEX7VIJKeBoB25DYvKyng==", "dev": true, "requires": { - "@storybook/channels": "5.3.2", - "@storybook/client-logger": "5.3.2", + "@storybook/channels": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/core-events": "6.1.11", "core-js": "^3.0.1", "global": "^4.3.2", - "telejson": "^3.2.0" + "qs": "^6.6.0", + "telejson": "^5.0.2" + }, + "dependencies": { + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "dev": true + } } }, "@storybook/channels": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-5.3.2.tgz", - "integrity": "sha512-eVHGrFCsQ6sO/H1cdEvPoBCsEndIbkbvOEMdI3Fah6jnWLb9fXJwM7f+UKkMPUOflMvzyO17dfXtigSU8uJMoA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.1.11.tgz", + "integrity": "sha512-NvjWzQ95TSV1e18jaQBCOGoe+vptKH2NOKZ7QRQ7I0O5OoHKr47IXoh+MQ5C8CRD9FTdLE/xWdn1sVVEPRyHEw==", "dev": true, "requires": { - "core-js": "^3.0.1" + "core-js": "^3.0.1", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" } }, "@storybook/client-api": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.3.2.tgz", - "integrity": "sha512-zfnfy46YUBukPpztAB9nZYJ3RazZx1a+0ZCCMEK6KuZkFSOVcYeqJe2PRAbiRVdCG+fG05OaSWw/AXraHZCE8Q==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.1.11.tgz", + "integrity": "sha512-DodJQzGCR+PYs26klvbquTjfBgkw5nvCZd3jpgWQtOrYaY/cMY1LLkVkKqrm2ENW8f7vf7tiw78RtxaXy7xeIQ==", "dev": true, "requires": { - "@storybook/addons": "5.3.2", - "@storybook/channel-postmessage": "5.3.2", - "@storybook/channels": "5.3.2", - "@storybook/client-logger": "5.3.2", - "@storybook/core-events": "5.3.2", + "@storybook/addons": "6.1.11", + "@storybook/channel-postmessage": "6.1.11", + "@storybook/channels": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/core-events": "6.1.11", "@storybook/csf": "0.0.1", + "@types/qs": "^6.9.0", + "@types/webpack-env": "^1.15.3", "core-js": "^3.0.1", - "eventemitter3": "^4.0.0", "global": "^4.3.2", - "is-plain-object": "^3.0.0", "lodash": "^4.17.15", "memoizerific": "^1.11.3", "qs": "^6.6.0", + "regenerator-runtime": "^0.13.7", "stable": "^0.1.8", - "ts-dedent": "^1.1.0", + "store2": "^2.7.1", + "ts-dedent": "^2.0.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==", + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", "dev": true }, - "qs": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz", - "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==", + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "dev": true } } }, "@storybook/client-logger": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.3.2.tgz", - "integrity": "sha512-sLP3MZ1LPQg/YR9yDoJq2S9/iM+yuD925RR0tD1ItQksKZA2gsI1CSf6zRPBluf7UwS7ACsotLlIPJg+czvr4A==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.1.11.tgz", + "integrity": "sha512-dSc+VKLW1UaiMPMhlZYRqhynrrHdHFiBEgU28+8LcmoZ1yhZBwLkcKdSD4YTT0CbMJAG1/+NUW5kRI8Geeg+rA==", "dev": true, "requires": { - "core-js": "^3.0.1" + "core-js": "^3.0.1", + "global": "^4.3.2" } }, "@storybook/components": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-5.3.2.tgz", - "integrity": "sha512-JtVPz03vVDI9/QqUbYitTQhLGxXHN0+49y97G527Xn3y6S71DkdQAVgYqUNnsUpPSyNLESgvAV39HRvzy/LSyw==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.1.11.tgz", + "integrity": "sha512-DGDl76uONTkg0rpsa36TpVuXv4K7rFYe8GnQ/Q8n4By5tvldC4s9YXwcDRYHVrfnYybKzuZ/+jv2ZAp4/8ZaeA==", "dev": true, "requires": { - "@storybook/client-logger": "5.3.2", - "@storybook/theming": "5.3.2", - "@types/react-syntax-highlighter": "11.0.2", - "@types/react-textarea-autosize": "^4.3.3", + "@popperjs/core": "^2.5.4", + "@storybook/client-logger": "6.1.11", + "@storybook/csf": "0.0.1", + "@storybook/theming": "6.1.11", + "@types/overlayscrollbars": "^1.9.0", + "@types/react-color": "^3.0.1", + "@types/react-syntax-highlighter": "11.0.4", "core-js": "^3.0.1", + "fast-deep-equal": "^3.1.1", "global": "^4.3.2", "lodash": "^4.17.15", - "markdown-to-jsx": "^6.9.1", + "markdown-to-jsx": "^6.11.4", "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": "^2.1.0", - "react-helmet-async": "^1.0.2", - "react-popper-tooltip": "^2.8.3", - "react-syntax-highlighter": "^11.0.2", - "react-textarea-autosize": "^7.1.0", - "simplebar-react": "^1.0.0-alpha.6", - "ts-dedent": "^1.1.0" + "overlayscrollbars": "^1.10.2", + "polished": "^3.4.4", + "react-color": "^2.17.0", + "react-popper-tooltip": "^3.1.1", + "react-syntax-highlighter": "^13.5.0", + "react-textarea-autosize": "^8.1.1", + "ts-dedent": "^2.0.0" + }, + "dependencies": { + "@popperjs/core": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.6.0.tgz", + "integrity": "sha512-cPqjjzuFWNK3BSKLm0abspP0sp/IGOli4p5I5fKFAzdS8fvjdOwDCfZqAaIiXd9lPkOWi3SUUfZof3hEb7J/uw==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + } } }, "@storybook/core": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-6.0.21.tgz", - "integrity": "sha512-/Et5NLabB12dnuPdhHDA/Q1pj0Mm2DGdL3KiLO4IC2VZeICCLGmU3/EGJBgjLK+anQ59pkclOiQ8i9eMXFiJ6A==", - "dev": true, - "requires": { - "@babel/plugin-proposal-class-properties": "^7.8.3", - "@babel/plugin-proposal-decorators": "^7.8.3", - "@babel/plugin-proposal-export-default-from": "^7.8.3", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", - "@babel/plugin-proposal-object-rest-spread": "^7.9.6", - "@babel/plugin-proposal-optional-chaining": "^7.10.1", - "@babel/plugin-proposal-private-methods": "^7.8.3", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-6.1.11.tgz", + "integrity": "sha512-pYOOQwiNJ5myLRn6p6nnLUjjjISHK/N55vS4HFnETYSaRLA++h1coN1jk7Zwt89dOQTdF0EsTJn+6snYOC+lxQ==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-decorators": "^7.12.1", + "@babel/plugin-proposal-export-default-from": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.1", + "@babel/plugin-proposal-private-methods": "^7.12.1", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.8.3", - "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.9.5", - "@babel/plugin-transform-destructuring": "^7.9.5", - "@babel/plugin-transform-for-of": "^7.9.0", - "@babel/plugin-transform-parameters": "^7.9.5", - "@babel/plugin-transform-shorthand-properties": "^7.8.3", - "@babel/plugin-transform-spread": "^7.8.3", - "@babel/plugin-transform-template-literals": "^7.8.3", - "@babel/preset-env": "^7.9.6", - "@babel/preset-react": "^7.8.3", - "@babel/preset-typescript": "^7.9.0", - "@babel/register": "^7.10.5", - "@storybook/addons": "6.0.21", - "@storybook/api": "6.0.21", - "@storybook/channel-postmessage": "6.0.21", - "@storybook/channels": "6.0.21", - "@storybook/client-api": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/components": "6.0.21", - "@storybook/core-events": "6.0.21", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.1", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.1", + "@babel/preset-typescript": "^7.12.1", + "@babel/register": "^7.12.1", + "@storybook/addons": "6.1.11", + "@storybook/api": "6.1.11", + "@storybook/channel-postmessage": "6.1.11", + "@storybook/channels": "6.1.11", + "@storybook/client-api": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/components": "6.1.11", + "@storybook/core-events": "6.1.11", "@storybook/csf": "0.0.1", - "@storybook/node-logger": "6.0.21", - "@storybook/router": "6.0.21", + "@storybook/node-logger": "6.1.11", + "@storybook/router": "6.1.11", "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.0.21", - "@storybook/ui": "6.0.21", + "@storybook/theming": "6.1.11", + "@storybook/ui": "6.1.11", "@types/glob-base": "^0.3.0", "@types/micromatch": "^4.0.1", "@types/node-fetch": "^2.5.4", @@ -7596,6 +7870,7 @@ "cli-table3": "0.6.0", "commander": "^5.0.0", "core-js": "^3.0.1", + "cpy": "^8.1.1", "css-loader": "^3.5.3", "detect-port": "^1.3.0", "dotenv-webpack": "^1.7.0", @@ -7626,209 +7901,25 @@ "qs": "^6.6.0", "raw-loader": "^4.0.1", "react-dev-utils": "^10.0.0", - "regenerator-runtime": "^0.13.3", + "regenerator-runtime": "^0.13.7", "resolve-from": "^5.0.0", "serve-favicon": "^2.5.0", - "shelljs": "^0.8.3", + "shelljs": "^0.8.4", "stable": "^0.1.8", "style-loader": "^1.2.1", + "telejson": "^5.0.2", "terser-webpack-plugin": "^3.0.0", - "ts-dedent": "^1.1.1", + "ts-dedent": "^2.0.0", "unfetch": "^4.1.0", "url-loader": "^4.0.0", "util-deprecate": "^1.0.2", - "webpack": "^4.43.0", + "webpack": "^4.44.2", "webpack-dev-middleware": "^3.7.0", + "webpack-filter-warnings-plugin": "^1.2.1", "webpack-hot-middleware": "^2.25.0", "webpack-virtual-modules": "^0.2.2" }, "dependencies": { - "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "dev": true, - "requires": { - "@emotion/memoize": "0.7.4" - } - }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "dev": true - }, - "@reach/router": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", - "integrity": "sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==", - "dev": true, - "requires": { - "create-react-context": "0.3.0", - "invariant": "^2.2.3", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4" - } - }, - "@storybook/addons": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.0.21.tgz", - "integrity": "sha512-yDttNLc3vXqBxwK795ykgzTC6MpvuXDQuF4LHSlHZQe6wsMu1m3fljnbYdafJWdx6cNZwUblU3KYcR11PqhkPg==", - "dev": true, - "requires": { - "@storybook/api": "6.0.21", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/router": "6.0.21", - "@storybook/theming": "6.0.21", - "core-js": "^3.0.1", - "global": "^4.3.2", - "regenerator-runtime": "^0.13.3" - } - }, - "@storybook/api": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.0.21.tgz", - "integrity": "sha512-cRRGf/KGFwYiDouTouEcDdp45N1AbYnAfvLqYZ3KuUTGZ+CiU/PN/vavkp07DQeM4FIQO8TLhzHdsLFpLT7Lkw==", - "dev": true, - "requires": { - "@reach/router": "^1.3.3", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/csf": "0.0.1", - "@storybook/router": "6.0.21", - "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.0.21", - "@types/reach__router": "^1.3.5", - "core-js": "^3.0.1", - "fast-deep-equal": "^3.1.1", - "global": "^4.3.2", - "lodash": "^4.17.15", - "memoizerific": "^1.11.3", - "react": "^16.8.3", - "regenerator-runtime": "^0.13.3", - "store2": "^2.7.1", - "telejson": "^5.0.2", - "ts-dedent": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/channel-postmessage": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.21.tgz", - "integrity": "sha512-ArRnoaS+b7qpAku/SO27z/yjRDCXb37mCPYGX0ntPbiQajootUbGO7otfnjFkaP44hCEC9uDYlOfMU1hYU1N6A==", - "dev": true, - "requires": { - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "core-js": "^3.0.1", - "global": "^4.3.2", - "qs": "^6.6.0", - "telejson": "^5.0.2" - } - }, - "@storybook/channels": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.21.tgz", - "integrity": "sha512-G6gjcEotSwDmOlxSmOMgsO3VhQ42RLJK7kFp6D5eg0Q6S8vsypltdT8orxdu+6+AbcBrL+5Sla8lThzaCvXsVQ==", - "dev": true, - "requires": { - "core-js": "^3.0.1", - "ts-dedent": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/client-api": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.21.tgz", - "integrity": "sha512-emBXd/ml6pc3G8gP3MsR9zQsAq1zZbqof9MxB51tG/jpTXdqWQ8ce1pt1tJS8Xj0QDM072jR6wsY+mmro0GZnA==", - "dev": true, - "requires": { - "@storybook/addons": "6.0.21", - "@storybook/channel-postmessage": "6.0.21", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/csf": "0.0.1", - "@types/qs": "^6.9.0", - "@types/webpack-env": "^1.15.2", - "core-js": "^3.0.1", - "global": "^4.3.2", - "lodash": "^4.17.15", - "memoizerific": "^1.11.3", - "qs": "^6.6.0", - "stable": "^0.1.8", - "store2": "^2.7.1", - "ts-dedent": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/client-logger": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.21.tgz", - "integrity": "sha512-8aUEbhjXV+UMYQWukVYnp+kZafF+LD4Dm7eMo37IUZvt3VIjV1VvhxIDVJtqjk2vv0KZTepESFBkZQLmBzI9Zg==", - "dev": true, - "requires": { - "core-js": "^3.0.1", - "global": "^4.3.2" - } - }, - "@storybook/components": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.0.21.tgz", - "integrity": "sha512-r6btqFW/rcXIU5v231EifZfdh9O0fy7bJDXwwDf8zVUgLx8JRc0VnSs3nvK3Is9HF1wZ9vjx/7Lh4rTIDZAjgg==", - "dev": true, - "requires": { - "@storybook/client-logger": "6.0.21", - "@storybook/csf": "0.0.1", - "@storybook/theming": "6.0.21", - "@types/overlayscrollbars": "^1.9.0", - "@types/react-color": "^3.0.1", - "@types/react-syntax-highlighter": "11.0.4", - "core-js": "^3.0.1", - "fast-deep-equal": "^3.1.1", - "global": "^4.3.2", - "lodash": "^4.17.15", - "markdown-to-jsx": "^6.11.4", - "memoizerific": "^1.11.3", - "overlayscrollbars": "^1.10.2", - "polished": "^3.4.4", - "popper.js": "^1.14.7", - "react": "^16.8.3", - "react-color": "^2.17.0", - "react-dom": "^16.8.3", - "react-popper-tooltip": "^2.11.0", - "react-syntax-highlighter": "^12.2.1", - "react-textarea-autosize": "^8.1.1", - "ts-dedent": "^1.1.1" - } - }, - "@storybook/core-events": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.0.21.tgz", - "integrity": "sha512-p84fbPcsAhnqDhp+HJ4P8+vI2BqJus4IRoVAemLAwuPjyPElrV9UvOa/RHy1BN8Z6jXwFA+FFzfGl2kPJ3WYcA==", - "dev": true, - "requires": { - "core-js": "^3.0.1" - } - }, - "@storybook/router": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.0.21.tgz", - "integrity": "sha512-46SsKJfcd12lRrISnfrWhicJx8EylkgGDGohfH0n5p7inkkGOkKV8QFZoYPRKZueMXmUKpzJ0Z3HmVsLTCrCDw==", - "dev": true, - "requires": { - "@reach/router": "^1.3.3", - "@types/reach__router": "^1.3.5", - "core-js": "^3.0.1", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "qs": "^6.6.0" - } - }, "@storybook/semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", @@ -7840,58 +7931,19 @@ }, "dependencies": { "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.1.tgz", + "integrity": "sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg==", "dev": true } } }, - "@storybook/theming": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.0.21.tgz", - "integrity": "sha512-n97DfB9kG6WrV1xBGDyeQibTrh8pBBCp3dSL3UTGH+KX3C2+4sm6QHlTgyekbi5FrbFEbnuZOKAS3YbLVONsRQ==", - "dev": true, - "requires": { - "@emotion/core": "^10.0.20", - "@emotion/is-prop-valid": "^0.8.6", - "@emotion/styled": "^10.0.17", - "@storybook/client-logger": "6.0.21", - "core-js": "^3.0.1", - "deep-object-diff": "^1.1.0", - "emotion-theming": "^10.0.19", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "polished": "^3.4.4", - "resolve-from": "^5.0.0", - "ts-dedent": "^1.1.1" - } - }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, - "@types/reach__router": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.5.tgz", - "integrity": "sha512-h0NbqXN/tJuBY/xggZSej1SKQEstbHO7J/omt1tYoFGmj3YXOodZKbbqD4mNDh7zvEGYd7YFrac1LTtAr3xsYQ==", - "dev": true, - "requires": { - "@types/history": "*", - "@types/react": "*" - } - }, - "@types/react-syntax-highlighter": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz", - "integrity": "sha512-9GfTo3a0PHwQeTVoqs0g5bS28KkSY48pp5659wA+Dp4MqceDEa8EHBqrllJvvtyusszyJhViUEap0FDvlk/9Zg==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -8068,9 +8120,9 @@ } }, "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -8096,29 +8148,6 @@ "picomatch": "^2.0.4" } }, - "autoprefixer": { - "version": "9.8.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", - "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", - "colorette": "^1.2.1", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -8176,16 +8205,10 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "caniuse-lite": { - "version": "1.0.30001124", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001124.tgz", - "integrity": "sha512-zQW8V3CdND7GHRH6rxm6s59Ww4g/qGWTheoboW9nfeMg7sUoopIfKCcNZUjwYRCOrvereh3kwDpZj4VLQ7zGtA==", - "dev": true - }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "optional": true, "requires": { @@ -8196,7 +8219,7 @@ "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" } }, "chownr": { @@ -8205,28 +8228,12 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, - "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", - "dev": true - }, "commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true }, - "create-react-context": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", - "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", - "dev": true, - "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" - } - }, "css-loader": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", @@ -8256,14 +8263,6 @@ } } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, "ejs": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz", @@ -8337,6 +8336,31 @@ "locate-path": "^3.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" + } + }, + "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" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -8356,32 +8380,6 @@ "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" - }, - "dependencies": { - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } } }, "fs-extra": { @@ -8427,29 +8425,12 @@ "is-glob": "^4.0.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==" - }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "highlight.js": { - "version": "9.15.10", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz", - "integrity": "sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -8460,12 +8441,6 @@ "binary-extensions": "^2.0.0" } }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -8482,30 +8457,6 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "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 - }, "json5": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", @@ -8513,24 +8464,24 @@ "dev": true, "requires": { "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } } }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "loader-utils": { @@ -8556,23 +8507,12 @@ } }, "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" - } - }, - "lowlight": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.12.1.tgz", - "integrity": "sha512-OqaVxMGIESnawn+TU/QMV5BJLbUghUfjDWPAtFqDYDmDtr4FnB+op8xM+pR7nKlauHNUHXGt0VgWatFB8voS5w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "fault": "^1.0.2", - "highlight.js": "~9.15.0" + "p-locate": "^4.1.0" } }, "lru-cache": { @@ -8602,16 +8542,6 @@ } } }, - "markdown-to-jsx": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz", - "integrity": "sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw==", - "dev": true, - "requires": { - "prop-types": "^15.6.2", - "unquote": "^1.1.0" - } - }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -8662,21 +8592,8 @@ "dev": true, "requires": { "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -8699,12 +8616,12 @@ } }, "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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, "p-try": { @@ -8713,6 +8630,12 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -8728,15 +8651,6 @@ "find-up": "^4.0.0" } }, - "polished": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/polished/-/polished-3.6.6.tgz", - "integrity": "sha512-yiB2ims2DZPem0kCD6V0wnhcVGFEhNh0Iw0axNpKU+oSAgFt6yx6HxIT23Qg0WWvgS379cS35zT4AOyZZRzpQQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2" - } - }, "postcss-value-parser": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", @@ -8759,44 +8673,10 @@ "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", "dev": true }, - "react-popper-tooltip": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz", - "integrity": "sha512-04A2f24GhyyMicKvg/koIOQ5BzlrRbKiAgP6L+Pdj1MVX3yJ1NeZ8+EidndQsbejFT55oW1b++wg2Z8KlAyhfQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "react-popper": "^1.3.7" - } - }, - "react-syntax-highlighter": { - "version": "12.2.1", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz", - "integrity": "sha512-CTsp0ZWijwKRYFg9xhkWD4DSpQqE4vb2NKVMdPAkomnILSmsNBHE0n5GuI5zB+PU3ySVvXvdt9jo+ViD9XibCA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.3.1", - "highlight.js": "~9.15.1", - "lowlight": "1.12.1", - "prismjs": "^1.8.4", - "refractor": "^2.4.1" - } - }, - "react-textarea-autosize": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.2.0.tgz", - "integrity": "sha512-grajUlVbkx6VdtSxCgzloUIphIZF5bKr21OYMceWPKkniy7H0mRAT/AXPrRtObAe+zUePnNlBwUc4ivVjUGIjw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.2", - "use-composed-ref": "^1.0.0", - "use-latest": "^1.0.0" - } - }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "optional": true, "requires": { @@ -8853,6 +8733,12 @@ "randombytes": "^2.1.0" } }, + "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 + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -8863,13 +8749,13 @@ } }, "style-loader": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.2.1.tgz", - "integrity": "sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", + "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", "dev": true, "requires": { "loader-utils": "^2.0.0", - "schema-utils": "^2.6.6" + "schema-utils": "^2.7.0" }, "dependencies": { "loader-utils": { @@ -8891,22 +8777,6 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, - "telejson": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.0.2.tgz", - "integrity": "sha512-XCrDHGbinczsscs8LXFr9jDhvy37yBk9piB7FJrCfxE8oP66WDkolNMpaBkWYgQqB9dQGBGtTDzGQPedc9KJmw==", - "dev": true, - "requires": { - "@types/is-function": "^1.0.0", - "global": "^4.4.0", - "is-function": "^1.0.2", - "is-regex": "^1.1.1", - "is-symbol": "^1.0.3", - "isobject": "^4.0.0", - "lodash": "^4.17.19", - "memoizerific": "^1.11.3" - } - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -8916,12 +8786,6 @@ "is-number": "^7.0.0" } }, - "ts-dedent": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-1.1.1.tgz", - "integrity": "sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg==", - "dev": true - }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -8938,14 +8802,14 @@ "dev": true }, "url-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.0.tgz", - "integrity": "sha512-IzgAAIC8wRrg6NYkFIJY09vtktQcsvU8V6HhtQj9PTefbYImzLB1hufqo4m+RyM5N3mLx5BqJKccgxJS+W3kqw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", "dev": true, "requires": { "loader-utils": "^2.0.0", - "mime-types": "^2.1.26", - "schema-utils": "^2.6.5" + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" }, "dependencies": { "loader-utils": { @@ -8958,34 +8822,36 @@ "emojis-list": "^3.0.0", "json5": "^2.1.2" } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } } } }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dev": true, "requires": { "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" + "watchpack-chokidar2": "^2.0.1" } }, "webpack": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", - "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", + "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -9085,12 +8951,6 @@ } } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -9123,12 +8983,6 @@ "ajv-keywords": "^3.1.0" } }, - "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 - }, "terser-webpack-plugin": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", @@ -9166,20 +9020,12 @@ "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" - }, - "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 - } } }, "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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yallist": { @@ -9191,9 +9037,9 @@ } }, "@storybook/core-events": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.3.2.tgz", - "integrity": "sha512-a1zVQqN8SMMAbdq0OV6Pc130VNasFYP85HO72VJf8t1aZGq40lYKFiALuF2S3Ax4ZIvJFbSrLM9OCpNNYg/ung==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.1.11.tgz", + "integrity": "sha512-hTib81W8PxepM7iXVvl3pBXSaGpChl5LTzaLCoIRO9sSB8dy0/x2DLAHzbQvShk/l1wqUc3TtOLIxq+eC9l3wg==", "dev": true, "requires": { "core-js": "^3.0.1" @@ -9209,9 +9055,9 @@ } }, "@storybook/node-logger": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.0.21.tgz", - "integrity": "sha512-KRBf+Fz7fgtwHdnYt70JTZbcYMZ1pQPtDyqbrFYCjwkbx5GPX5vMOozlxCIj9elseqPIsF8CKgHOW7cFHVyWYw==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.1.11.tgz", + "integrity": "sha512-MASonXDWpSMU9HF9mqbGOR1Ps/DTJ8AVmYD50+OnB9kXl4M42Dliobeq7JwKFMnZ42RelUCCSXdWW80hGrUKKA==", "dev": true, "requires": { "@types/npmlog": "^4.1.2", @@ -9222,158 +9068,43 @@ } }, "@storybook/postinstall": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-5.3.2.tgz", - "integrity": "sha512-SHDXiubFKSoIpV5E2R9K104Ye4qhRQuoN9SKCB400Ya2JyBSGz5FMuNVmRpO8JqJrUe9uI1d/k18/Mma1/73YA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-6.1.11.tgz", + "integrity": "sha512-ICW70RuOJOHD7PcKq62yr7hCmo04F7yRMuy5/MD/G+Neaw3YpfYTc6pQ228h5UrmXiKSKG1unPkjzuIAoIeN7w==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/react": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-6.0.21.tgz", - "integrity": "sha512-L3PcoBJq5aK1aTaJNfwsSJ8Kxgcyk0WknN4TDqhP7a+oXmuMY1YEi96hEvQVIm0TBCkQxs61K70/T7vlilEtHg==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-6.1.11.tgz", + "integrity": "sha512-EmR7yvVW6z6AYhfzAgJMGR/5+igeBGa1EePaEIibn51r5uboSB72N12NaADyF2OaycIdV+0sW6vP9Zvlvexa/w==", "dev": true, "requires": { - "@babel/preset-flow": "^7.0.0", - "@babel/preset-react": "^7.0.0", - "@storybook/addons": "6.0.21", - "@storybook/core": "6.0.21", - "@storybook/node-logger": "6.0.21", + "@babel/preset-flow": "^7.12.1", + "@babel/preset-react": "^7.12.1", + "@pmmmwh/react-refresh-webpack-plugin": "^0.4.2", + "@storybook/addons": "6.1.11", + "@storybook/core": "6.1.11", + "@storybook/node-logger": "6.1.11", "@storybook/semver": "^7.3.2", - "@svgr/webpack": "^5.4.0", - "@types/webpack-env": "^1.15.2", + "@types/webpack-env": "^1.15.3", "babel-plugin-add-react-displayname": "^0.0.5", "babel-plugin-named-asset-import": "^0.3.1", - "babel-plugin-react-docgen": "^4.1.0", + "babel-plugin-react-docgen": "^4.2.1", "core-js": "^3.0.1", "global": "^4.3.2", "lodash": "^4.17.15", "prop-types": "^15.7.2", "react-dev-utils": "^10.0.0", - "react-docgen-typescript-plugin": "^0.5.2", - "regenerator-runtime": "^0.13.3", - "ts-dedent": "^1.1.1", - "webpack": "^4.43.0" + "react-docgen-typescript-plugin": "^0.6.2", + "react-refresh": "^0.8.3", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "webpack": "^4.44.2" }, "dependencies": { - "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "dev": true, - "requires": { - "@emotion/memoize": "0.7.4" - } - }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "dev": true - }, - "@reach/router": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", - "integrity": "sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==", - "dev": true, - "requires": { - "create-react-context": "0.3.0", - "invariant": "^2.2.3", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4" - } - }, - "@storybook/addons": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.0.21.tgz", - "integrity": "sha512-yDttNLc3vXqBxwK795ykgzTC6MpvuXDQuF4LHSlHZQe6wsMu1m3fljnbYdafJWdx6cNZwUblU3KYcR11PqhkPg==", - "dev": true, - "requires": { - "@storybook/api": "6.0.21", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/router": "6.0.21", - "@storybook/theming": "6.0.21", - "core-js": "^3.0.1", - "global": "^4.3.2", - "regenerator-runtime": "^0.13.3" - } - }, - "@storybook/api": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.0.21.tgz", - "integrity": "sha512-cRRGf/KGFwYiDouTouEcDdp45N1AbYnAfvLqYZ3KuUTGZ+CiU/PN/vavkp07DQeM4FIQO8TLhzHdsLFpLT7Lkw==", - "dev": true, - "requires": { - "@reach/router": "^1.3.3", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/csf": "0.0.1", - "@storybook/router": "6.0.21", - "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.0.21", - "@types/reach__router": "^1.3.5", - "core-js": "^3.0.1", - "fast-deep-equal": "^3.1.1", - "global": "^4.3.2", - "lodash": "^4.17.15", - "memoizerific": "^1.11.3", - "react": "^16.8.3", - "regenerator-runtime": "^0.13.3", - "store2": "^2.7.1", - "telejson": "^5.0.2", - "ts-dedent": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/channels": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.21.tgz", - "integrity": "sha512-G6gjcEotSwDmOlxSmOMgsO3VhQ42RLJK7kFp6D5eg0Q6S8vsypltdT8orxdu+6+AbcBrL+5Sla8lThzaCvXsVQ==", - "dev": true, - "requires": { - "core-js": "^3.0.1", - "ts-dedent": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/client-logger": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.21.tgz", - "integrity": "sha512-8aUEbhjXV+UMYQWukVYnp+kZafF+LD4Dm7eMo37IUZvt3VIjV1VvhxIDVJtqjk2vv0KZTepESFBkZQLmBzI9Zg==", - "dev": true, - "requires": { - "core-js": "^3.0.1", - "global": "^4.3.2" - } - }, - "@storybook/core-events": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.0.21.tgz", - "integrity": "sha512-p84fbPcsAhnqDhp+HJ4P8+vI2BqJus4IRoVAemLAwuPjyPElrV9UvOa/RHy1BN8Z6jXwFA+FFzfGl2kPJ3WYcA==", - "dev": true, - "requires": { - "core-js": "^3.0.1" - } - }, - "@storybook/router": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.0.21.tgz", - "integrity": "sha512-46SsKJfcd12lRrISnfrWhicJx8EylkgGDGohfH0n5p7inkkGOkKV8QFZoYPRKZueMXmUKpzJ0Z3HmVsLTCrCDw==", - "dev": true, - "requires": { - "@reach/router": "^1.3.3", - "@types/reach__router": "^1.3.5", - "core-js": "^3.0.1", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "qs": "^6.6.0" - } - }, "@storybook/semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", @@ -9385,154 +9116,13 @@ }, "dependencies": { "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.1.tgz", + "integrity": "sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg==", "dev": true } } }, - "@storybook/theming": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.0.21.tgz", - "integrity": "sha512-n97DfB9kG6WrV1xBGDyeQibTrh8pBBCp3dSL3UTGH+KX3C2+4sm6QHlTgyekbi5FrbFEbnuZOKAS3YbLVONsRQ==", - "dev": true, - "requires": { - "@emotion/core": "^10.0.20", - "@emotion/is-prop-valid": "^0.8.6", - "@emotion/styled": "^10.0.17", - "@storybook/client-logger": "6.0.21", - "core-js": "^3.0.1", - "deep-object-diff": "^1.1.0", - "emotion-theming": "^10.0.19", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "polished": "^3.4.4", - "resolve-from": "^5.0.0", - "ts-dedent": "^1.1.1" - } - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", - "dev": true - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", - "dev": true - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", - "dev": true - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", - "dev": true - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", - "dev": true - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.4.0.tgz", - "integrity": "sha512-zLl4Fl3NvKxxjWNkqEcpdSOpQ3LGVH2BNFQ6vjaK6sFo2IrSznrhURIPI0HAphKiiIwNYjAfE0TNoQDSZv0U9A==", - "dev": true - }, - "@svgr/babel-preset": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.4.0.tgz", - "integrity": "sha512-Gyx7cCxua04DBtyILTYdQxeO/pwfTBev6+eXTbVbxe4HTGhOUW6yo7PSbG2p6eJMl44j6XSequ0ZDP7bl0nu9A==", - "dev": true, - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.4.0" - } - }, - "@svgr/core": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.4.0.tgz", - "integrity": "sha512-hWGm1DCCvd4IEn7VgDUHYiC597lUYhFau2lwJBYpQWDirYLkX4OsXu9IslPgJ9UpP7wsw3n2Ffv9sW7SXJVfqQ==", - "dev": true, - "requires": { - "@svgr/plugin-jsx": "^5.4.0", - "camelcase": "^6.0.0", - "cosmiconfig": "^6.0.0" - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.4.0.tgz", - "integrity": "sha512-+U0TZZpPsP2V1WvVhqAOSTk+N+CjYHdZx+x9UBa1eeeZDXwH8pt0CrQf2+SvRl/h2CAPRFkm+Ey96+jKP8Bsgg==", - "dev": true, - "requires": { - "@babel/types": "^7.9.5" - } - }, - "@svgr/plugin-jsx": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.4.0.tgz", - "integrity": "sha512-SGzO4JZQ2HvGRKDzRga9YFSqOqaNrgLlQVaGvpZ2Iht2gwRp/tq+18Pvv9kS9ZqOMYgyix2LLxZMY1LOe9NPqw==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@svgr/babel-preset": "^5.4.0", - "@svgr/hast-util-to-babel-ast": "^5.4.0", - "svg-parser": "^2.0.2" - } - }, - "@svgr/plugin-svgo": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.4.0.tgz", - "integrity": "sha512-3Cgv3aYi1l6SHyzArV9C36yo4kgwVdF3zPQUC6/aCDUeXAofDYwE5kk3e3oT5ZO2a0N3lB+lLGvipBG6lnG8EA==", - "dev": true, - "requires": { - "cosmiconfig": "^6.0.0", - "merge-deep": "^3.0.2", - "svgo": "^1.2.2" - } - }, - "@svgr/webpack": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.4.0.tgz", - "integrity": "sha512-LjepnS/BSAvelnOnnzr6Gg0GcpLmnZ9ThGFK5WJtm1xOqdBE/1IACZU7MMdVzjyUkfFqGz87eRE4hFaSLiUwYg==", - "dev": true, - "requires": { - "@babel/core": "^7.9.0", - "@babel/plugin-transform-react-constant-elements": "^7.9.0", - "@babel/preset-env": "^7.9.5", - "@babel/preset-react": "^7.9.4", - "@svgr/core": "^5.4.0", - "@svgr/plugin-jsx": "^5.4.0", - "@svgr/plugin-svgo": "^5.4.0", - "loader-utils": "^2.0.0" - } - }, - "@types/reach__router": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.5.tgz", - "integrity": "sha512-h0NbqXN/tJuBY/xggZSej1SKQEstbHO7J/omt1tYoFGmj3YXOodZKbbqD4mNDh7zvEGYd7YFrac1LTtAr3xsYQ==", - "dev": true, - "requires": { - "@types/history": "*", - "@types/react": "*" - } - }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -9719,14 +9309,6 @@ "picomatch": "^2.0.4" } }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -9787,27 +9369,10 @@ } } }, - "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", - "dev": true - }, - "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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "optional": true, "requires": { @@ -9818,7 +9383,7 @@ "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" } }, "chownr": { @@ -9827,125 +9392,6 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "create-react-context": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", - "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", - "dev": true, - "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dev": true, - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "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 - } - } - }, - "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", - "dev": true - }, - "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", - "dev": true, - "requires": { - "css-tree": "1.0.0-alpha.39" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", - "dev": true, - "requires": { - "mdn-data": "2.0.6", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", - "dev": true - }, - "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 - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "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" - } - }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -9975,50 +9421,6 @@ } } }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - }, - "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.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -10081,17 +9483,6 @@ "is-glob": "^4.0.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==" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -10102,18 +9493,6 @@ "binary-extensions": "^2.0.0" } }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -10131,48 +9510,24 @@ "dev": true, "optional": true }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "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 - }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "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.5" + "minimist": "^1.2.0" } }, "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", "dev": true, "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "json5": "^1.0.1" } }, "locate-path": { @@ -10211,18 +9566,6 @@ } } }, - "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 - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -10241,10 +9584,14 @@ "through2": "^2.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } }, "neo-async": { "version": "2.6.2", @@ -10259,33 +9606,6 @@ "dev": true, "optional": 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-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -10310,30 +9630,12 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "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 - }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -10385,15 +9687,6 @@ } } }, - "polished": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/polished/-/polished-3.6.6.tgz", - "integrity": "sha512-yiB2ims2DZPem0kCD6V0wnhcVGFEhNh0Iw0axNpKU+oSAgFt6yx6HxIT23Qg0WWvgS379cS35zT4AOyZZRzpQQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2" - } - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -10404,16 +9697,16 @@ "once": "^1.3.1" } }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "react-refresh": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", + "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==", "dev": true }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "optional": true, "requires": { @@ -10435,12 +9728,6 @@ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "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 - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -10459,6 +9746,12 @@ "randombytes": "^2.1.0" } }, + "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 + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -10468,69 +9761,12 @@ "figgy-pudding": "^3.5.1" } }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "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.37", - "csso": "^4.0.2", - "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" - } - }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, - "telejson": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.0.2.tgz", - "integrity": "sha512-XCrDHGbinczsscs8LXFr9jDhvy37yBk9piB7FJrCfxE8oP66WDkolNMpaBkWYgQqB9dQGBGtTDzGQPedc9KJmw==", - "dev": true, - "requires": { - "@types/is-function": "^1.0.0", - "global": "^4.4.0", - "is-function": "^1.0.2", - "is-regex": "^1.1.1", - "is-symbol": "^1.0.3", - "isobject": "^4.0.0", - "lodash": "^4.17.19", - "memoizerific": "^1.11.3" - } - }, "terser-webpack-plugin": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", @@ -10546,14 +9782,6 @@ "terser": "^4.1.2", "webpack-sources": "^1.4.0", "worker-farm": "^1.7.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 - } } }, "to-regex-range": { @@ -10566,12 +9794,6 @@ "is-number": "^7.0.0" } }, - "ts-dedent": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-1.1.1.tgz", - "integrity": "sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg==", - "dev": true - }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -10581,31 +9803,22 @@ "unique-slug": "^2.0.0" } }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dev": true, "requires": { "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" + "watchpack-chokidar2": "^2.0.1" } }, "webpack": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", - "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", + "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -10631,37 +9844,6 @@ "terser-webpack-plugin": "^1.4.3", "watchpack": "^1.7.4", "webpack-sources": "^1.4.1" - }, - "dependencies": { - "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.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } } }, "webpack-sources": { @@ -10672,20 +9854,12 @@ "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" - }, - "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 - } } }, "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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yallist": { @@ -10697,46 +9871,44 @@ } }, "@storybook/router": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-5.3.2.tgz", - "integrity": "sha512-EeM27i+89WS2mdT4j7RyVMSk7e7QiDb8bmyJAX3qyxg9ZOI4Wrvawgj6OAGuetItC1nayCPXFlXtIfHsP1h3lg==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.1.11.tgz", + "integrity": "sha512-YEYOoKMo/WI13MZCkdqI9X3H1G0Oj5OUxi7So4qd3khX3zcCjSr3LjiMDBcmIVZpFo5VAvzjhIY4KqpgvzTG0A==", "dev": true, "requires": { - "@reach/router": "^1.2.1", - "@storybook/csf": "0.0.1", - "@types/reach__router": "^1.2.3", + "@reach/router": "^1.3.3", + "@types/reach__router": "^1.3.5", "core-js": "^3.0.1", "global": "^4.3.2", - "lodash": "^4.17.15", "memoizerific": "^1.11.3", - "qs": "^6.6.0", - "util-deprecate": "^1.0.2" + "qs": "^6.6.0" }, "dependencies": { "qs": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz", - "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==", + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", "dev": true } } }, "@storybook/source-loader": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.3.2.tgz", - "integrity": "sha512-bHEWLXTSn89jip/fy/rjf2Psrmu4ZdquOD/SmB+WVuKRYE8JxcN1ybNUOhM7+XqekzIV/iw9rivhjGO1nZ7HAQ==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.1.11.tgz", + "integrity": "sha512-pEMWGn3XwZYAXwIrtmd7ziH5d1zN8NCpJM8vNJssntZFW45rDo69xgGM/PrTLPDca6f/Mhv+vqzR99tdfarJSw==", "dev": true, "requires": { - "@storybook/addons": "5.3.2", - "@storybook/client-logger": "5.3.2", + "@storybook/addons": "6.1.11", + "@storybook/client-logger": "6.1.11", "@storybook/csf": "0.0.1", "core-js": "^3.0.1", "estraverse": "^4.2.0", "global": "^4.3.2", - "loader-utils": "^1.2.3", - "prettier": "^1.16.4", - "prop-types": "^15.7.2", - "regenerator-runtime": "^0.13.3" + "loader-utils": "^2.0.0", + "lodash": "^4.17.15", + "prettier": "~2.0.5", + "regenerator-runtime": "^0.13.7", + "source-map": "^0.7.3" }, "dependencies": { "big.js": { @@ -10745,60 +9917,107 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" } }, "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "dev": true, "requires": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "dev": true }, "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true } } }, "@storybook/theming": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-5.3.2.tgz", - "integrity": "sha512-WzFVgE2v/0mlK/5CqM9kSDdCMag7uqFsjI5oe3HCWEpwrUH70ndhuVZTVpyx0fscdL74vT5XZieoy2WwpVBl5Q==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.1.11.tgz", + "integrity": "sha512-zRChacVgKoU2BmpvwK1ntiF3KIpc8QblJT7IGiKfP/BNpy9gNeXbLPLk3g/tkHszOvVYtkaZhEXni4Od8tqy1A==", "dev": true, "requires": { - "@emotion/core": "^10.0.20", - "@emotion/styled": "^10.0.17", - "@storybook/client-logger": "5.3.2", + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.6", + "@emotion/styled": "^10.0.23", + "@storybook/client-logger": "6.1.11", "core-js": "^3.0.1", "deep-object-diff": "^1.1.0", "emotion-theming": "^10.0.19", "global": "^4.3.2", "memoizerific": "^1.11.3", - "polished": "^3.3.1", - "prop-types": "^15.7.2", + "polished": "^3.4.4", "resolve-from": "^5.0.0", - "ts-dedent": "^1.1.0" + "ts-dedent": "^2.0.0" }, "dependencies": { + "@emotion/core": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.1.1.tgz", + "integrity": "sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "dev": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "dev": true + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==", + "dev": true + }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -10808,25 +10027,26 @@ } }, "@storybook/ui": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-6.0.21.tgz", - "integrity": "sha512-50QYF8tHUgpVq7B7PWp7kmyf79NySWJO0piQFjHv027vV8GfbXMWVswAXwo3IfCihPlnLKe01WbsigM/9T1HCQ==", - "dev": true, - "requires": { - "@emotion/core": "^10.0.20", - "@storybook/addons": "6.0.21", - "@storybook/api": "6.0.21", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/components": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/router": "6.0.21", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-6.1.11.tgz", + "integrity": "sha512-Qth2dxS5+VbKHcqgkiKpeD+xr/hRUuUIDUA/2Ierh/BaA8Up/krlso/mCLaQOa5E8Og9WJAdDFO0cUbt939c2Q==", + "dev": true, + "requires": { + "@emotion/core": "^10.1.1", + "@storybook/addons": "6.1.11", + "@storybook/api": "6.1.11", + "@storybook/channels": "6.1.11", + "@storybook/client-logger": "6.1.11", + "@storybook/components": "6.1.11", + "@storybook/core-events": "6.1.11", + "@storybook/router": "6.1.11", "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.0.21", + "@storybook/theming": "6.1.11", "@types/markdown-to-jsx": "^6.11.0", "copy-to-clipboard": "^3.0.8", "core-js": "^3.0.1", "core-js-pure": "^3.0.1", + "downshift": "^6.0.6", "emotion-theming": "^10.0.19", "fuse.js": "^3.6.1", "global": "^4.3.2", @@ -10835,163 +10055,35 @@ "memoizerific": "^1.11.3", "polished": "^3.4.4", "qs": "^6.6.0", - "react": "^16.8.3", - "react-dom": "^16.8.3", "react-draggable": "^4.0.3", "react-helmet-async": "^1.0.2", "react-hotkeys": "2.0.0", "react-sizeme": "^2.6.7", - "regenerator-runtime": "^0.13.3", + "regenerator-runtime": "^0.13.7", "resolve-from": "^5.0.0", "store2": "^2.7.1" }, "dependencies": { - "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "@emotion/core": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.1.1.tgz", + "integrity": "sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==", "dev": true, "requires": { - "@emotion/memoize": "0.7.4" + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" } }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==", "dev": true }, - "@reach/router": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", - "integrity": "sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==", - "dev": true, - "requires": { - "create-react-context": "0.3.0", - "invariant": "^2.2.3", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4" - } - }, - "@storybook/addons": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.0.21.tgz", - "integrity": "sha512-yDttNLc3vXqBxwK795ykgzTC6MpvuXDQuF4LHSlHZQe6wsMu1m3fljnbYdafJWdx6cNZwUblU3KYcR11PqhkPg==", - "dev": true, - "requires": { - "@storybook/api": "6.0.21", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/router": "6.0.21", - "@storybook/theming": "6.0.21", - "core-js": "^3.0.1", - "global": "^4.3.2", - "regenerator-runtime": "^0.13.3" - } - }, - "@storybook/api": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.0.21.tgz", - "integrity": "sha512-cRRGf/KGFwYiDouTouEcDdp45N1AbYnAfvLqYZ3KuUTGZ+CiU/PN/vavkp07DQeM4FIQO8TLhzHdsLFpLT7Lkw==", - "dev": true, - "requires": { - "@reach/router": "^1.3.3", - "@storybook/channels": "6.0.21", - "@storybook/client-logger": "6.0.21", - "@storybook/core-events": "6.0.21", - "@storybook/csf": "0.0.1", - "@storybook/router": "6.0.21", - "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.0.21", - "@types/reach__router": "^1.3.5", - "core-js": "^3.0.1", - "fast-deep-equal": "^3.1.1", - "global": "^4.3.2", - "lodash": "^4.17.15", - "memoizerific": "^1.11.3", - "react": "^16.8.3", - "regenerator-runtime": "^0.13.3", - "store2": "^2.7.1", - "telejson": "^5.0.2", - "ts-dedent": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/channels": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.21.tgz", - "integrity": "sha512-G6gjcEotSwDmOlxSmOMgsO3VhQ42RLJK7kFp6D5eg0Q6S8vsypltdT8orxdu+6+AbcBrL+5Sla8lThzaCvXsVQ==", - "dev": true, - "requires": { - "core-js": "^3.0.1", - "ts-dedent": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/client-logger": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.21.tgz", - "integrity": "sha512-8aUEbhjXV+UMYQWukVYnp+kZafF+LD4Dm7eMo37IUZvt3VIjV1VvhxIDVJtqjk2vv0KZTepESFBkZQLmBzI9Zg==", - "dev": true, - "requires": { - "core-js": "^3.0.1", - "global": "^4.3.2" - } - }, - "@storybook/components": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.0.21.tgz", - "integrity": "sha512-r6btqFW/rcXIU5v231EifZfdh9O0fy7bJDXwwDf8zVUgLx8JRc0VnSs3nvK3Is9HF1wZ9vjx/7Lh4rTIDZAjgg==", - "dev": true, - "requires": { - "@storybook/client-logger": "6.0.21", - "@storybook/csf": "0.0.1", - "@storybook/theming": "6.0.21", - "@types/overlayscrollbars": "^1.9.0", - "@types/react-color": "^3.0.1", - "@types/react-syntax-highlighter": "11.0.4", - "core-js": "^3.0.1", - "fast-deep-equal": "^3.1.1", - "global": "^4.3.2", - "lodash": "^4.17.15", - "markdown-to-jsx": "^6.11.4", - "memoizerific": "^1.11.3", - "overlayscrollbars": "^1.10.2", - "polished": "^3.4.4", - "popper.js": "^1.14.7", - "react": "^16.8.3", - "react-color": "^2.17.0", - "react-dom": "^16.8.3", - "react-popper-tooltip": "^2.11.0", - "react-syntax-highlighter": "^12.2.1", - "react-textarea-autosize": "^8.1.1", - "ts-dedent": "^1.1.1" - } - }, - "@storybook/core-events": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.0.21.tgz", - "integrity": "sha512-p84fbPcsAhnqDhp+HJ4P8+vI2BqJus4IRoVAemLAwuPjyPElrV9UvOa/RHy1BN8Z6jXwFA+FFzfGl2kPJ3WYcA==", - "dev": true, - "requires": { - "core-js": "^3.0.1" - } - }, - "@storybook/router": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.0.21.tgz", - "integrity": "sha512-46SsKJfcd12lRrISnfrWhicJx8EylkgGDGohfH0n5p7inkkGOkKV8QFZoYPRKZueMXmUKpzJ0Z3HmVsLTCrCDw==", - "dev": true, - "requires": { - "@reach/router": "^1.3.3", - "@types/reach__router": "^1.3.5", - "core-js": "^3.0.1", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "qs": "^6.6.0" - } - }, "@storybook/semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", @@ -11003,68 +10095,31 @@ }, "dependencies": { "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.1.tgz", + "integrity": "sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg==", "dev": true } } }, - "@storybook/theming": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.0.21.tgz", - "integrity": "sha512-n97DfB9kG6WrV1xBGDyeQibTrh8pBBCp3dSL3UTGH+KX3C2+4sm6QHlTgyekbi5FrbFEbnuZOKAS3YbLVONsRQ==", - "dev": true, - "requires": { - "@emotion/core": "^10.0.20", - "@emotion/is-prop-valid": "^0.8.6", - "@emotion/styled": "^10.0.17", - "@storybook/client-logger": "6.0.21", - "core-js": "^3.0.1", - "deep-object-diff": "^1.1.0", - "emotion-theming": "^10.0.19", - "global": "^4.3.2", - "memoizerific": "^1.11.3", - "polished": "^3.4.4", - "resolve-from": "^5.0.0", - "ts-dedent": "^1.1.1" - } - }, - "@types/reach__router": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.5.tgz", - "integrity": "sha512-h0NbqXN/tJuBY/xggZSej1SKQEstbHO7J/omt1tYoFGmj3YXOodZKbbqD4mNDh7zvEGYd7YFrac1LTtAr3xsYQ==", - "dev": true, - "requires": { - "@types/history": "*", - "@types/react": "*" - } - }, - "@types/react-syntax-highlighter": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz", - "integrity": "sha512-9GfTo3a0PHwQeTVoqs0g5bS28KkSY48pp5659wA+Dp4MqceDEa8EHBqrllJvvtyusszyJhViUEap0FDvlk/9Zg==", - "dev": true, - "requires": { - "@types/react": "*" - } + "compute-scroll-into-view": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz", + "integrity": "sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ==", + "dev": true }, - "create-react-context": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", - "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", + "downshift": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.0.7.tgz", + "integrity": "sha512-+rqgx3JTSs8b4V9q++hsLvaP8mhMOdX7u+jy5S2etg7+Y7uFLVzZaI0S7Xo2yEnNDmTcNnYZZ/vFjdWuJ2kZdg==", "dev": true, "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" + "@babel/runtime": "^7.12.5", + "compute-scroll-into-view": "^1.0.16", + "prop-types": "^15.7.2", + "react-is": "^17.0.1" } }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -11075,48 +10130,6 @@ "path-exists": "^4.0.0" } }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "highlight.js": { - "version": "9.15.10", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz", - "integrity": "sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "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 - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -11126,26 +10139,6 @@ "p-locate": "^4.1.0" } }, - "lowlight": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.12.1.tgz", - "integrity": "sha512-OqaVxMGIESnawn+TU/QMV5BJLbUghUfjDWPAtFqDYDmDtr4FnB+op8xM+pR7nKlauHNUHXGt0VgWatFB8voS5w==", - "dev": true, - "requires": { - "fault": "^1.0.2", - "highlight.js": "~9.15.0" - } - }, - "markdown-to-jsx": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz", - "integrity": "sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw==", - "dev": true, - "requires": { - "prop-types": "^15.6.2", - "unquote": "^1.1.0" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -11176,54 +10169,17 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "polished": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/polished/-/polished-3.6.6.tgz", - "integrity": "sha512-yiB2ims2DZPem0kCD6V0wnhcVGFEhNh0Iw0axNpKU+oSAgFt6yx6HxIT23Qg0WWvgS379cS35zT4AOyZZRzpQQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2" - } - }, "qs": { "version": "6.9.4", "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", "dev": true }, - "react-popper-tooltip": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz", - "integrity": "sha512-04A2f24GhyyMicKvg/koIOQ5BzlrRbKiAgP6L+Pdj1MVX3yJ1NeZ8+EidndQsbejFT55oW1b++wg2Z8KlAyhfQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "react-popper": "^1.3.7" - } - }, - "react-syntax-highlighter": { - "version": "12.2.1", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz", - "integrity": "sha512-CTsp0ZWijwKRYFg9xhkWD4DSpQqE4vb2NKVMdPAkomnILSmsNBHE0n5GuI5zB+PU3ySVvXvdt9jo+ViD9XibCA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.3.1", - "highlight.js": "~9.15.1", - "lowlight": "1.12.1", - "prismjs": "^1.8.4", - "refractor": "^2.4.1" - } - }, - "react-textarea-autosize": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.2.0.tgz", - "integrity": "sha512-grajUlVbkx6VdtSxCgzloUIphIZF5bKr21OYMceWPKkniy7H0mRAT/AXPrRtObAe+zUePnNlBwUc4ivVjUGIjw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.2", - "use-composed-ref": "^1.0.0", - "use-latest": "^1.0.0" - } + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", + "dev": true }, "regenerator-runtime": { "version": "0.13.7", @@ -11236,37 +10192,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true - }, - "telejson": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.0.2.tgz", - "integrity": "sha512-XCrDHGbinczsscs8LXFr9jDhvy37yBk9piB7FJrCfxE8oP66WDkolNMpaBkWYgQqB9dQGBGtTDzGQPedc9KJmw==", - "dev": true, - "requires": { - "@types/is-function": "^1.0.0", - "global": "^4.4.0", - "is-function": "^1.0.2", - "is-regex": "^1.1.1", - "is-symbol": "^1.0.3", - "isobject": "^4.0.0", - "lodash": "^4.17.19", - "memoizerific": "^1.11.3" - } - }, - "ts-dedent": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-1.1.1.tgz", - "integrity": "sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg==", - "dev": true - }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } } } }, @@ -12076,12 +11001,6 @@ "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", "dev": true }, - "@types/babel-types": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz", - "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ==", - "dev": true - }, "@types/babel__core": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", @@ -12123,15 +11042,6 @@ "@babel/types": "^7.3.0" } }, - "@types/babylon": { - "version": "6.16.5", - "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz", - "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==", - "dev": true, - "requires": { - "@types/babel-types": "*" - } - }, "@types/braces": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.0.tgz", @@ -12213,16 +11123,25 @@ "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.36.tgz", "integrity": "sha512-7TUK/k2/QGpEAv/BCwSHlYu3NXZhQ9ZwBYpzr9tjlPIL2C5BeGhH3DmVavRx3ZNyELX5TLC91JTz/cen6AAtIQ==" }, + "@types/hast": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz", + "integrity": "sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, "@types/history": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.4.tgz", - "integrity": "sha512-+o2igcuZA3xtOoFH56s+MCZVidwlJNcJID57DSCyawS2i910yG9vkwehCjJNZ6ImhCR5S9DbvIJKyYHcMyOfMw==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", + "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==", "dev": true }, "@types/html-minifier-terser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz", - "integrity": "sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", "dev": true }, "@types/http-cache-semantics": { @@ -12287,14 +11206,23 @@ "dev": true }, "@types/markdown-to-jsx": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.2.tgz", - "integrity": "sha512-ESuCu8Bk7jpTZ3YPdMW1+6wUj13F5N15vXfc7BuUAN0eCp0lrvVL9nzOTzoqvbRzXMciuqXr1KrHt3xQAhfwPA==", + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz", + "integrity": "sha512-30nFYpceM/ZEvhGiqWjm5quLUxNeld0HCzJEXMZZDpq53FPkS85mTwkWtCXzCqq8s5JYLgM5W392a02xn8Bdaw==", "dev": true, "requires": { "@types/react": "*" } }, + "@types/mdast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", + "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, "@types/micromatch": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/micromatch/-/micromatch-4.0.1.tgz", @@ -12389,6 +11317,12 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, + "@types/parse5": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", + "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==", + "dev": true + }, "@types/prettier": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.0.tgz", @@ -12413,9 +11347,9 @@ "dev": true }, "@types/reach__router": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.6.tgz", - "integrity": "sha512-Oh5DAVr/L2svBvubw6QEFpXGu295Y406BPs4i9t1n2pp7M+q3pmCmhzb9oZV5wncR41KCD3NHl1Yhi7uKnTPsA==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.6.tgz", + "integrity": "sha512-RHYataCUPQnt+GHoASyRLq6wmZ0n8jWlBW8Lxcwd30NN6vQfbmTeoSDfkgxO0S1lEzArp8OFDsq5KIs7FygjtA==", "dev": true, "requires": { "@types/history": "*", @@ -12439,12 +11373,13 @@ } }, "@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==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.4.tgz", + "integrity": "sha512-EswbYJDF1kkrx93/YU+BbBtb46CCtDMvTiGmcOa/c5PETnwTiSWoseJ1oSWeRl/4rUXkhME9bVURvvPg0W5YQw==", "dev": true, "requires": { - "@types/react": "*" + "@types/react": "*", + "@types/reactcss": "*" } }, "@types/react-dom": { @@ -12465,18 +11400,18 @@ } }, "@types/react-syntax-highlighter": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz", - "integrity": "sha512-iMNcixH8330f2dq0RY+VOXCP8JFehgmOhLOtnO85Ty+qu0fHXJNEqWx5VuFv8v0aEq0U/N9d/k1yvA+c6PEmPw==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz", + "integrity": "sha512-9GfTo3a0PHwQeTVoqs0g5bS28KkSY48pp5659wA+Dp4MqceDEa8EHBqrllJvvtyusszyJhViUEap0FDvlk/9Zg==", "dev": true, "requires": { "@types/react": "*" } }, - "@types/react-textarea-autosize": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/react-textarea-autosize/-/react-textarea-autosize-4.3.5.tgz", - "integrity": "sha512-PiDL83kPMTolyZAWW3lyzO6ktooTb9tFTntVy7CA83/qFLWKLJ5bLeRboy6J6j3b1e8h2Eec6gBTEOOJRjV14A==", + "@types/reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-d2gQQ0IL6hXLnoRfVYZukQNWHuVsE75DzFTLPUuyyEhJS8G2VvlE+qfQQ91SJjaMqlURRCNIsX7Jcsw6cEuJlA==", "dev": true, "requires": { "@types/react": "*" @@ -12730,9 +11665,9 @@ } }, "@types/webpack-env": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.15.2.tgz", - "integrity": "sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.0.tgz", + "integrity": "sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==", "dev": true }, "@types/webpack-sources": { @@ -13044,51 +11979,6 @@ "@xtuc/long": "4.2.2" } }, - "@webpack-contrib/schema-utils": { - "version": "1.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@webpack-contrib/schema-utils/-/schema-utils-1.0.0-beta.0.tgz", - "integrity": "sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chalk": "^2.3.2", - "strip-ansi": "^4.0.0", - "text-table": "^0.2.0", - "webpack-log": "^1.1.2" - }, - "dependencies": { - "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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "webpack-log": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", - "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "loglevelnext": "^1.0.1", - "uuid": "^3.1.0" - } - } - } - }, "@wordpress/a11y": { "version": "file:packages/a11y", "requires": { @@ -13409,6 +12299,7 @@ "lodash": "^4.17.19", "make-dir": "^3.0.0", "mustache": "^4.0.0", + "npm-package-arg": "^8.0.1", "rimraf": "^3.0.2", "write-pkg": "^4.0.0" } @@ -13691,7 +12582,6 @@ "lodash": "^4.17.19", "memize": "^1.1.0", "react-autosize-textarea": "^7.1.0", - "redux-optimist": "^1.0.0", "refx": "^3.0.0", "rememo": "^3.0.0" } @@ -14396,20 +13286,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -14440,9 +13331,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -14464,52 +13355,73 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, "object.entries": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", - "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", + "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", + "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", + "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" } }, "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -14554,28 +13466,6 @@ "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", "dev": true }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "alphanum-sort": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", @@ -22656,13 +21546,14 @@ } }, "array.prototype.flatmap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", - "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", + "es-abstract": "^1.18.0-next.1", "function-bind": "^1.1.1" }, "dependencies": { @@ -22676,20 +21567,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -22720,9 +21612,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -22744,43 +21636,64 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } }, "array.prototype.map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", - "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.3.tgz", + "integrity": "sha512-nNcb30v0wfDyIe26Yif3PcV1JXQp4zEeEfupG7L4SRjnD6HLbO5b2a7eVSba53bOx4YCHYMBHt+Fp4vYstneRA==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", + "es-abstract": "^1.18.0-next.1", "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.4" + "is-string": "^1.0.5" }, "dependencies": { "define-properties": { @@ -22793,20 +21706,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -22837,9 +21751,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -22861,29 +21775,49 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -22960,10 +21894,21 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "ast-types": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.12.4.tgz", - "integrity": "sha512-ky/YVYCbtVAS8TdMIaTiPFHwEpRB5z1hctepJplTr3UW5q8TDrpIMCILyk8pmLxGtn2KCtC/lSn7zOsaI7nzDw==", - "dev": true + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", + "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", + "dev": true, + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "dev": true + } + } }, "ast-types-flow": { "version": "0.0.7", @@ -23071,9 +22016,9 @@ "dev": true }, "axe-core": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.3.tgz", - "integrity": "sha512-HZpLE7xu05+8AbpqXITGdxp1Xwk8ysAXrg7MiKRY27py3DAyEJpoJQo1727pWF3F+O79V3r+cTWhOzfB49P89w==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.1.tgz", + "integrity": "sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ==", "dev": true }, "axobject-query": { @@ -23144,12 +22089,6 @@ } } }, - "babel-core": { - "version": "7.0.0-bridge.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", - "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", - "dev": true - }, "babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", @@ -23690,318 +22629,136 @@ "dev": true }, "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", - "dev": true, - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "babel-plugin-add-react-displayname": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz", - "integrity": "sha1-M51M3be2X9YtHfnbn+BN4TQSK9U=", - "dev": true - }, - "babel-plugin-apply-mdx-type-prop": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.5.8.tgz", - "integrity": "sha512-xYp5F9mAnZdDRFSd1vF3XQ0GQUbIulCpnuht2jCmK30GAHL8szVL7TgzwhEGamQ6yJmP/gEyYNM9OR5D2n26eA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "7.8.3", - "@mdx-js/util": "^1.5.8" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", - "dev": true - }, - "@mdx-js/util": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.5.8.tgz", - "integrity": "sha512-a7Gjjw8bfBSertA/pTWBA/9WKEhgaSxvQE2NTSUzaknrzGFOhs4alZSHh3RHmSFdSWv5pUuzAgsWseMLhWEVkQ==", - "dev": true - } - } - }, - "babel-plugin-emotion": { - "version": "10.0.33", - "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz", - "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@emotion/hash": "0.8.0", - "@emotion/memoize": "0.7.4", - "@emotion/serialize": "^0.11.16", - "babel-plugin-macros": "^2.0.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^1.0.5", - "find-root": "^1.1.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" - }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" - }, - "@emotion/serialize": { - "version": "0.11.16", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", - "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", - "requires": { - "@emotion/hash": "0.8.0", - "@emotion/memoize": "0.7.4", - "@emotion/unitless": "0.7.5", - "@emotion/utils": "0.11.3", - "csstype": "^2.5.7" - } - }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "@emotion/utils": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", - "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==" - } - } - }, - "babel-plugin-extract-import-names": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.5.8.tgz", - "integrity": "sha512-LcLfP8ZRBZMdMAXHLugyvvd5PY0gMmLMWFogWAUsG32X6TYW2Eavx+il2bw73KDbW+UdCC1bAJ3NuU25T1MI3g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "7.8.3" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", - "dev": true - } - } - }, - "babel-plugin-inline-json-import": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/babel-plugin-inline-json-import/-/babel-plugin-inline-json-import-0.3.2.tgz", - "integrity": "sha512-QNNJx08KjmMT25Cw7rAPQ6dlREDPiZGDyApHL8KQ9vrQHbrr4PTi7W8g1tMMZPz0jEMd39nx/eH7xjnDNxq5sA==", - "dev": true, - "requires": { - "decache": "^4.5.1" - } - }, - "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" - }, - "dependencies": { - "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" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "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" - } - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.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" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "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 - }, - "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": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, - "read-pkg": { + "pkg-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "find-up": "^3.0.0" } }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", "dev": true, "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" } }, - "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==", + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true + } + } + }, + "babel-plugin-add-react-displayname": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz", + "integrity": "sha1-M51M3be2X9YtHfnbn+BN4TQSK9U=", + "dev": true + }, + "babel-plugin-apply-mdx-type-prop": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", + "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.10.4", + "@mdx-js/util": "1.6.22" + } + }, + "babel-plugin-emotion": { + "version": "10.0.33", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz", + "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/serialize": "^0.11.16", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, + "@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" } + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==" } } }, + "babel-plugin-extract-import-names": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", + "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.10.4" + } + }, + "babel-plugin-inline-json-import": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-inline-json-import/-/babel-plugin-inline-json-import-0.3.2.tgz", + "integrity": "sha512-QNNJx08KjmMT25Cw7rAPQ6dlREDPiZGDyApHL8KQ9vrQHbrr4PTi7W8g1tMMZPz0jEMd39nx/eH7xjnDNxq5sA==", + "dev": true, + "requires": { + "decache": "^4.5.1" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, "babel-plugin-jest-hoist": { "version": "25.5.0", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", @@ -24161,46 +22918,20 @@ } }, "babel-plugin-named-asset-import": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz", - "integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz", + "integrity": "sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==", "dev": true }, "babel-plugin-react-docgen": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.1.0.tgz", - "integrity": "sha512-vzpnBlfGv8XOhJM2zbPyyqw2OLEbelgZZsaaRRTpVwNKuYuc+pUg4+dy7i9gCRms0uOQn4osX571HRcCJMJCmA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz", + "integrity": "sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ==", "dev": true, "requires": { + "ast-types": "^0.14.2", "lodash": "^4.17.15", - "react-docgen": "^5.0.0", - "recast": "^0.14.7" - }, - "dependencies": { - "ast-types": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", - "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", - "dev": true - }, - "recast": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz", - "integrity": "sha512-/nwm9pkrcWagN40JeJhkPaRxiHXBRkXyRh/hgU088Z/v+qCy+zIHHY6bC6o7NaKAxPqtE6nD8zBH1LfU0/Wx6A==", - "dev": true, - "requires": { - "ast-types": "0.11.3", - "esprima": "~4.0.0", - "private": "~0.1.5", - "source-map": "~0.6.1" - } - }, - "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 - } + "react-docgen": "^5.0.0" } }, "babel-plugin-react-native-classname-to-style": { @@ -24218,12 +22949,6 @@ "@babel/template": "^7.0.0-beta.49" } }, - "babel-plugin-require-context-hook": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-require-context-hook/-/babel-plugin-require-context-hook-1.0.0.tgz", - "integrity": "sha512-EMZD1563QUqLhzrqcThk759RhuNVX/ZJdrtGK6drwzgvnR+ARjWyXIHPbu+tUNaMGtPz/gQeAM2M6VUw2UiUeA==", - "dev": true - }, "babel-plugin-syntax-jsx": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", @@ -24399,56 +23124,6 @@ "lodash": "^4.17.11" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, "bail": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.3.tgz", @@ -24556,9 +23231,9 @@ } }, "better-opn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.0.0.tgz", - "integrity": "sha512-PPbGRgO/K0LowMHbH/JNvaV3qY3Vt+A2nH28fzJxy16h/DfR5OsVti6ldGl6S9SMsyUqT13sltikiAVtI6tKLA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz", + "integrity": "sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==", "dev": true, "requires": { "open": "^7.0.3" @@ -24574,9 +23249,9 @@ } }, "open": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/open/-/open-7.2.1.tgz", - "integrity": "sha512-xbYCJib4spUdmcs0g/2mK1nKo/jO2T7INClWd/beL7PFkXRWgr8B23ssDHX/USPn2M2IjDR5UdpYs6I67SnTSA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz", + "integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==", "dev": true, "requires": { "is-docker": "^2.0.0", @@ -24791,12 +23466,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -25314,6 +23988,16 @@ } } }, + "call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", @@ -25355,19 +24039,19 @@ "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==" }, "camel-case": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", - "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dev": true, "requires": { - "pascal-case": "^3.1.1", - "tslib": "^1.10.0" + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" }, "dependencies": { "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true } } @@ -25399,12 +24083,6 @@ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, - "can-use-dom": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/can-use-dom/-/can-use-dom-0.1.0.tgz", - "integrity": "sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo=", - "dev": true - }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -25449,16 +24127,6 @@ "integrity": "sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw==", "dev": true }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, "chalk": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", @@ -25535,15 +24203,6 @@ "integrity": "sha512-9NB2VbXtXYWdXzqrvAHykE/f0QJxzaKIpZ5QzNZrrgQ7Iyxr2vnfS8fCBNVW9nUEZE0lo57nxKRqnzY/dKrwlA==", "dev": true }, - "character-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", - "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", - "dev": true, - "requires": { - "is-regex": "^1.0.3" - } - }, "character-reference-invalid": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz", @@ -25718,9 +24377,9 @@ "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" }, "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", "dev": true, "requires": { "source-map": "~0.6.0" @@ -26164,9 +24823,9 @@ } }, "comma-separated-tokens": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz", - "integrity": "sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", "dev": true }, "command-exists": { @@ -26454,18 +25113,6 @@ "resolved": "https://registry.npmjs.org/consolidated-events/-/consolidated-events-2.0.2.tgz", "integrity": "sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ==" }, - "constantinople": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", - "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==", - "dev": true, - "requires": { - "@types/babel-types": "^7.0.0", - "@types/babylon": "^6.16.2", - "babel-types": "^6.26.0", - "babylon": "^6.18.0" - } - }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -27003,9 +25650,9 @@ "dev": true }, "copy-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.2.0.tgz", - "integrity": "sha512-eOZERzvCmxS8HWzugj4Uxl8OJxa7T2k1Gi0X5qavwydHIfuSHq2dTD09LOg/XyGq4Zpb5IsR/2OJ5lbOegz78w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", "dev": true, "requires": { "toggle-selection": "^1.0.6" @@ -27132,6 +25779,43 @@ } } }, + "cp-file": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", + "integrity": "sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "nested-error-stacks": "^2.0.0", + "p-event": "^4.1.0" + } + }, + "cpy": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-8.1.1.tgz", + "integrity": "sha512-vqHT+9o67sMwJ5hUd/BAOYeemkU+MuFRsK2c36Xc3eefQpAsp1kAsyDxEDcc5JS1+y9l/XHPrIsVTcyGGmkUUQ==", + "dev": true, + "requires": { + "arrify": "^2.0.1", + "cp-file": "^7.0.0", + "globby": "^9.2.0", + "has-glob": "^1.0.0", + "junk": "^3.1.0", + "nested-error-stacks": "^2.1.0", + "p-all": "^2.1.0", + "p-filter": "^2.1.0", + "p-map": "^3.0.0" + }, + "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + } + } + }, "crc": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", @@ -27224,13 +25908,13 @@ } }, "create-react-context": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz", - "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", + "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", "dev": true, "requires": { - "fbjs": "^0.8.0", - "gud": "^1.0.0" + "gud": "^1.0.0", + "warning": "^4.0.3" } }, "cross-env": { @@ -27726,16 +26410,6 @@ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", "dev": true }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, "damerau-levenshtein": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", @@ -27788,12 +26462,6 @@ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.18.tgz", "integrity": "sha512-JBMJZghNK8TtuoPnKNIzW9xavVVigld/zmZNpZSyQbkb2Opp55YIfZUpE4OEqPF/iyUVQTKcn1bC2HtC8B7s3g==" }, - "de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true - }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -27861,28 +26529,6 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.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 - } - } - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -28178,9 +26824,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detab": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.2.tgz", - "integrity": "sha512-Q57yPrxScy816TTE1P/uLRXLDKjXhvYTbfxS/e6lPD+YrqghbsMlGB9nQzj/zVtSPaF0DFPSdO916EWO4sQUyQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", + "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", "dev": true, "requires": { "repeat-string": "^1.5.4" @@ -28209,12 +26855,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, "detect-port": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", @@ -28316,12 +26956,6 @@ "esutils": "^2.0.2" } }, - "doctypes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=", - "dev": true - }, "dom-accessibility-api": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.4.3.tgz", @@ -28338,12 +26972,21 @@ } }, "dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", + "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", "dev": true, "requires": { - "@babel/runtime": "^7.1.2" + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz", + "integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==", + "dev": true + } } }, "dom-scroll-into-view": { @@ -28368,9 +27011,9 @@ } }, "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", "dev": true }, "domain-browser": { @@ -28411,19 +27054,19 @@ } }, "dot-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz", - "integrity": "sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "requires": { - "no-case": "^3.0.3", - "tslib": "^1.10.0" + "no-case": "^3.0.4", + "tslib": "^2.0.3" }, "dependencies": { "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true } } @@ -28536,9 +27179,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.564", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.564.tgz", - "integrity": "sha512-fNaYN3EtKQWLQsrKXui8mzcryJXuA0LbCLoizeX6oayG2emBaS5MauKjCPAvc29NEY4FpLHIUWiP+Y0Bfrs5dg==", + "version": "1.3.629", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.629.tgz", + "integrity": "sha512-iSPPJtPvHrMAvYOt+9cdbDmTasPqwnwz4lkP8Dn200gDNUBQOLQ96xUsWXBwXslAo5XxdoXAoQQ3RAy4uao9IQ==", "dev": true }, "elegant-spinner": { @@ -28593,16 +27236,10 @@ "hoist-non-react-statics": "^3.3.0" }, "dependencies": { - "@emotion/weak-memoize": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", - "dev": true - }, "hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "dev": true, "requires": { "react-is": "^16.7.0" @@ -29432,6 +28069,15 @@ "is-arrayish": "^0.2.1" } }, + "error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "dev": true, + "requires": { + "stackframe": "^1.1.1" + } + }, "errorhandler": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", @@ -29489,12 +28135,13 @@ "dev": true }, "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.1.tgz", + "integrity": "sha512-qorBw8Y7B15DVLaJWy6WdEV/ZkieBcu6QCq/xzWzGOKJqgG1j754vXRfZ3NY7HSShneqU43mPB4OkQBTkvHhFw==", "dev": true, "requires": { - "es-abstract": "^1.17.4", + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.1", "has-symbols": "^1.0.1", "is-arguments": "^1.0.4", "is-map": "^2.0.1", @@ -29503,112 +28150,17 @@ "isarray": "^2.0.5" }, "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.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, "isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, - "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 - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } } } }, @@ -29622,34 +28174,12 @@ "is-symbol": "^1.0.1" } }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, "es5-shim": { "version": "4.5.14", "resolved": "https://registry.npmjs.org/es5-shim/-/es5-shim-4.5.14.tgz", "integrity": "sha512-7SwlpL+2JpymWTt8sNLuC2zdhhc+wrfe5cMPI2j0o6WsPdfAiPwmFy2f0AocPB4RQVBOZ9kNTgi5YF7TdhkvEg==", "dev": true }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -29666,21 +28196,11 @@ } }, "es6-shim": { - "version": "0.35.5", - "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.5.tgz", - "integrity": "sha512-E9kK/bjtCQRpN1K28Xh4BlmP8egvZBGJJ+9GtnzOwt7mdqtrjHFuVGr7QJfdjBIKqrlU5duPf3pCBoDrkjVYFg==", + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.6.tgz", + "integrity": "sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA==", "dev": true }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -31370,23 +29890,6 @@ } } }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", - "dev": true - } - } - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -31602,12 +30105,12 @@ } }, "fault": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.3.tgz", - "integrity": "sha512-sfFuP4X0hzrbGKjAUNXYvNqsZ5F6ohx/dZ9I0KQud/aiZNwg263r5L9yGB0clvXHCkzXh5W3t7RSHchggYIFmA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", "dev": true, "requires": { - "format": "^0.2.2" + "format": "^0.2.0" } }, "faye-websocket": { @@ -31715,13 +30218,13 @@ } }, "file-loader": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.0.tgz", - "integrity": "sha512-26qPdHyTsArQ6gU4P1HJbAbnFTyT2r0pG7czh1GFAd9TZbj0n94wWbupgixZH/ET/meqi2/5+F7DhW4OAXD+Lg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dev": true, "requires": { "loader-utils": "^2.0.0", - "schema-utils": "^2.7.1" + "schema-utils": "^3.0.0" }, "dependencies": { "@types/json-schema": { @@ -31731,9 +30234,9 @@ "dev": true }, "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -31786,20 +30289,14 @@ "json5": "^2.1.2" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } } @@ -32201,12 +30698,6 @@ "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", "dev": true }, - "flow-parser": { - "version": "0.116.1", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.116.1.tgz", - "integrity": "sha512-uMbaTjiMhBKa/il1esHyWyVVWfrWdG/eLmG62MQulZ59Yghpa30H1tmukFZLptsBafZ8ddiPyf7I+SiA+euZ6A==", - "dev": true - }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -32217,12 +30708,6 @@ "readable-stream": "^2.0.4" } }, - "focus-lock": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.6.6.tgz", - "integrity": "sha512-Dx69IXGCq1qsUExWuG+5wkiMqVM/zGx/reXSJSLogECwp3x6KeNQZ+NAetgxEFpnC41rD8U3+jRCW68+LNzdtw==", - "dev": true - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -32497,6 +30982,25 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, + "get-intrinsic": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", + "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } + } + }, "get-own-enumerable-property-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", @@ -32869,9 +31373,9 @@ } }, "github-slugger": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.1.tgz", - "integrity": "sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", + "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", "dev": true, "requires": { "emoji-regex": ">=6.0.0 <=6.1.1" @@ -33309,6 +31813,26 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", + "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", + "dev": true, + "requires": { + "is-glob": "^3.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" + } + } + } + }, "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", @@ -33359,12 +31883,6 @@ "safe-buffer": "^5.0.1" } }, - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true - }, "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -33376,98 +31894,176 @@ } }, "hast-to-hyperscript": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-7.0.4.tgz", - "integrity": "sha512-vmwriQ2H0RPS9ho4Kkbf3n3lY436QKLq6VaGA1pzBh36hBi3tm1DO9bR+kaJIbpT10UqaANDkMjxvjVfr+cnOA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", + "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", "dev": true, "requires": { + "@types/unist": "^2.0.3", "comma-separated-tokens": "^1.0.0", "property-information": "^5.3.0", "space-separated-tokens": "^1.0.0", - "style-to-object": "^0.2.1", - "unist-util-is": "^3.0.0", - "web-namespaces": "^1.1.2" + "style-to-object": "^0.3.0", + "unist-util-is": "^4.0.0", + "web-namespaces": "^1.0.0" }, "dependencies": { - "style-to-object": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.2.3.tgz", - "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", - "dev": true, - "requires": { - "inline-style-parser": "0.1.1" - } - }, "unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", "dev": true } } }, "hast-util-from-parse5": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-5.0.2.tgz", - "integrity": "sha512-YXFjoRS7ES7PEoLx6uihtSfKTO1s3z/tzGiV5cVpsUiihduogFXubNRCzTIW3yOOGO1nws9CxPq4MbwD39Uo+w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", + "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", "dev": true, "requires": { - "ccount": "^1.0.3", - "hastscript": "^5.0.0", + "@types/parse5": "^5.0.0", + "hastscript": "^6.0.0", "property-information": "^5.0.0", - "web-namespaces": "^1.1.2", - "xtend": "^4.0.1" + "vfile": "^4.0.0", + "vfile-location": "^3.2.0", + "web-namespaces": "^1.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "requires": { + "@types/unist": "^2.0.2" + } + }, + "vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + } + }, + "vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "dev": true + }, + "vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + } } }, "hast-util-parse-selector": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.3.tgz", - "integrity": "sha512-nxbeqjQNxsvo/uYYAw9kij6td05YVUlf1qti09rVfbWSLT5H6wo3c+USIwX6nzXWk5kFZzXnEqO82856r0aM2Q==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", "dev": true }, "hast-util-raw": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-5.0.1.tgz", - "integrity": "sha512-iHo7G6BjRc/GU1Yun5CIEXjil0wVnIbz11C6k0JdDichSDMtYi2+NNtk6YN7EOP0JfPstX30d3pRLfaJv5CkdA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", + "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", "dev": true, "requires": { - "hast-util-from-parse5": "^5.0.0", - "hast-util-to-parse5": "^5.0.0", - "html-void-elements": "^1.0.1", - "parse5": "^5.0.0", + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^6.0.0", + "hast-util-to-parse5": "^6.0.0", + "html-void-elements": "^1.0.0", + "parse5": "^6.0.0", "unist-util-position": "^3.0.0", + "vfile": "^4.0.0", "web-namespaces": "^1.0.0", - "xtend": "^4.0.1", + "xtend": "^4.0.0", "zwitch": "^1.0.0" }, "dependencies": { + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "requires": { + "@types/unist": "^2.0.2" + } + }, + "vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + } + }, + "vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } } } }, "hast-util-to-parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-5.1.1.tgz", - "integrity": "sha512-ivCeAd5FCXr7bapJIVsWMnx/EmbjkkW2TU2hd1prq+jGwiaUoK+FcpjyPNwsC5ogzCwWO669tOqIovGeLc/ntg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", + "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", "dev": true, "requires": { - "hast-to-hyperscript": "^7.0.0", + "hast-to-hyperscript": "^9.0.0", "property-information": "^5.0.0", "web-namespaces": "^1.0.0", - "xtend": "^4.0.1", + "xtend": "^4.0.0", "zwitch": "^1.0.0" } }, "hastscript": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.1.tgz", - "integrity": "sha512-xHo1Hkcqd0LlWNuDL3/BxwhgAGp3d7uEvCMgCTrBY+zsOooPPH+8KAvW8PCgl+GB8H3H44nfSaF0A4BQ+4xlYg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", "dev": true, "requires": { + "@types/hast": "^2.0.0", "comma-separated-tokens": "^1.0.0", "hast-util-parse-selector": "^2.0.0", "property-information": "^5.0.0", @@ -33492,9 +32088,9 @@ "dev": true }, "highlight.js": { - "version": "9.13.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.13.1.tgz", - "integrity": "sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.4.1.tgz", + "integrity": "sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg==", "dev": true }, "hmac-drbg": { @@ -33575,9 +32171,9 @@ } }, "html-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.3.tgz", + "integrity": "sha512-/VulV3SYni1taM7a4RMdceqzJWR39gpZHjBwUnsCFKWV/GJkD14CJ5F7eWcZozmHJK0/f/H5U3b3SiPkuvxMgg==", "dev": true }, "html-escaper": { @@ -33601,26 +32197,11 @@ "terser": "^4.6.3" }, "dependencies": { - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, "commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true - }, - "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 } } }, @@ -33631,15 +32212,15 @@ "dev": true }, "html-void-elements": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.4.tgz", - "integrity": "sha512-yMk3naGPLrfvUV9TdDbuYXngh/TpHbA6TrOw3HL9kS8yhwx7i309BReNg7CbAJXGE+UMJ6je5OqJ7lC63o6YuQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", + "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", "dev": true }, "html-webpack-plugin": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.4.1.tgz", - "integrity": "sha512-nEtdEIsIGXdXGG7MjTTZlmhqhpHU9pJFc1OYxcP36c5/ZKP6b0BJMww2QTvJGQYA9aMxUnjDujpZdYcVOXiBCQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz", + "integrity": "sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw==", "dev": true, "requires": { "@types/html-minifier-terser": "^5.0.0", @@ -34753,10 +33334,13 @@ } }, "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } }, "is-arrayish": { "version": "0.2.1", @@ -34884,24 +33468,6 @@ "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", "dev": true }, - "is-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", - "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", - "dev": true, - "requires": { - "acorn": "~4.0.2", - "object-assign": "^4.0.1" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -34928,9 +33494,9 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", "dev": true }, "is-generator-fn": { @@ -34961,9 +33527,15 @@ "dev": true }, "is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true + }, + "is-negative-zero": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "dev": true }, "is-number": { @@ -35082,9 +33654,9 @@ "dev": true }, "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true }, "is-ssh": { @@ -38019,9 +36591,9 @@ } }, "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", "dev": true }, "jest-resolve": { @@ -40307,12 +38879,6 @@ "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", "dev": true }, - "js-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -40339,64 +38905,6 @@ "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-245459.0.0.tgz", "integrity": "sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==" }, - "jscodeshift": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.7.0.tgz", - "integrity": "sha512-Kt6rpTa1HVhAWagD6J0y6qxxqRmDgkFvczerLgOsDNSGoUZSmq2CO1vFRcda9OV1BaZKSHCIh+VREPts5tB/Ig==", - "dev": true, - "requires": { - "@babel/core": "^7.1.6", - "@babel/parser": "^7.1.6", - "@babel/plugin-proposal-class-properties": "^7.1.0", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/preset-env": "^7.1.6", - "@babel/preset-flow": "^7.0.0", - "@babel/preset-typescript": "^7.1.0", - "@babel/register": "^7.0.0", - "babel-core": "^7.0.0-bridge.0", - "colors": "^1.1.2", - "flow-parser": "0.*", - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "neo-async": "^2.5.0", - "node-dir": "^0.1.17", - "recast": "^0.18.1", - "temp": "^0.8.1", - "write-file-atomic": "^2.3.0" - }, - "dependencies": { - "ast-types": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.2.tgz", - "integrity": "sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "recast": { - "version": "0.18.5", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.18.5.tgz", - "integrity": "sha512-sD1WJrpLQAkXGyQZyGzTM75WJvyAd98II5CHdK3IYbt/cZlU0UzCRVU11nUFNXX9fBVEt4E9ajkMjBlUlG+Oog==", - "dev": true, - "requires": { - "ast-types": "0.13.2", - "esprima": "~4.0.0", - "private": "^0.1.8", - "source-map": "~0.6.1" - } - }, - "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 - } - } - }, "jsdoctypeparser": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", @@ -40643,24 +39151,6 @@ "verror": "1.10.0" } }, - "jstransformer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", - "dev": true, - "requires": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" - }, - "dependencies": { - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - } - } - }, "jsx-ast-utils": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", @@ -40682,6 +39172,12 @@ "set-immediate-shim": "~1.0.1" } }, + "junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true + }, "keyv": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.0.tgz", @@ -41294,6 +39790,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, + "lodash-es": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz", + "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==", + "dev": true + }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", @@ -41306,12 +39808,6 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -41662,16 +40158,6 @@ } } }, - "loglevelnext": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", - "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", - "dev": true, - "requires": { - "es6-symbol": "^3.1.1", - "object.assign": "^4.1.0" - } - }, "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -41681,12 +40167,6 @@ "@sinonjs/commons": "^1.7.0" } }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, "longest-streak": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.2.tgz", @@ -41712,18 +40192,18 @@ } }, "lower-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", - "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dev": true, "requires": { - "tslib": "^1.10.0" + "tslib": "^2.0.3" }, "dependencies": { "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true } } @@ -41735,13 +40215,13 @@ "dev": true }, "lowlight": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.11.0.tgz", - "integrity": "sha512-xrGGN6XLL7MbTMdPD6NfWPwY43SNkjf/d0mecSx/CW36fUZTjRHEq0/Cdug3TWKtRXLWi7iMl1eP0olYxj/a4A==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.17.0.tgz", + "integrity": "sha512-vmtBgYKD+QVNy7tIa7ulz5d//Il9R4MooOVh4nkOf9R9Cb/Dk5TXMSTieg/vDulkBkIWj59/BIlyFQxT9X1oAQ==", "dev": true, "requires": { - "fault": "^1.0.2", - "highlight.js": "~9.13.0" + "fault": "^1.0.0", + "highlight.js": "~10.4.0" } }, "lru-cache": { @@ -42015,9 +40495,9 @@ "dev": true }, "markdown-to-jsx": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.10.3.tgz", - "integrity": "sha512-PSoUyLnW/xoW6RsxZrquSSz5eGEOTwa15H5eqp3enmrp8esmgDJmhzd6zmQ9tgAA9TxJzx1Hmf3incYU/IamoQ==", + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz", + "integrity": "sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw==", "dev": true, "requires": { "prop-types": "^15.6.2", @@ -42113,12 +40593,12 @@ } }, "mdast-squeeze-paragraphs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-3.0.5.tgz", - "integrity": "sha512-xX6Vbe348Y/rukQlG4W3xH+7v4ZlzUbSY4HUIQCuYrF2DrkcHx584mCaFxkWoDZKNUfyLZItHC9VAqX3kIP7XA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", + "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", "dev": true, "requires": { - "unist-util-remove": "^1.0.0" + "unist-util-remove": "^2.0.0" } }, "mdast-util-compact": { @@ -42132,12 +40612,41 @@ } }, "mdast-util-definitions": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz", - "integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", + "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", "dev": true, "requires": { - "unist-util-visit": "^1.0.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", + "dev": true + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "mdast-util-inject": { @@ -42150,22 +40659,48 @@ } }, "mdast-util-to-hast": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-6.0.2.tgz", - "integrity": "sha512-GjcOimC9qHI0yNFAQdBesrZXzUkRdFleQlcoU8+TVNfDW6oLUazUx8MgUoTaUyCJzBOnE5AOgqhpURrSlf0QwQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", + "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", "dev": true, "requires": { - "collapse-white-space": "^1.0.0", - "detab": "^2.0.0", - "mdast-util-definitions": "^1.2.0", - "mdurl": "^1.0.1", - "trim": "0.0.1", - "trim-lines": "^1.0.0", - "unist-builder": "^1.0.1", - "unist-util-generated": "^1.1.0", + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "mdast-util-definitions": "^4.0.0", + "mdurl": "^1.0.0", + "unist-builder": "^2.0.0", + "unist-util-generated": "^1.0.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.0", - "xtend": "^4.0.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", + "dev": true + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "mdast-util-to-string": { @@ -43886,6 +42421,15 @@ "to-regex": "^3.0.1" } }, + "native-url": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.2.6.tgz", + "integrity": "sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA==", + "dev": true, + "requires": { + "querystring": "^0.2.0" + } + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -43952,10 +42496,10 @@ "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", "dev": true }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, "nice-try": { @@ -43964,19 +42508,19 @@ "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==" }, "no-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.3.tgz", - "integrity": "sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, "requires": { - "lower-case": "^2.0.1", - "tslib": "^1.10.0" + "lower-case": "^2.0.2", + "tslib": "^2.0.3" }, "dependencies": { "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true } } @@ -44251,9 +42795,9 @@ } }, "node-releases": { - "version": "1.1.60", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", - "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==", + "version": "1.1.67", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", + "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", "dev": true }, "node-watch": { @@ -45201,14 +43745,14 @@ } }, "object.fromentries": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", - "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", + "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" }, "dependencies": { @@ -45222,20 +43766,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -45266,9 +43811,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -45290,29 +43835,49 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -45605,11 +44170,28 @@ } }, "overlayscrollbars": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.0.tgz", - "integrity": "sha512-p8oHrMeRAKxXDMPI/EBNITj/zTVHKNnAnM59Im+xnoZUlV07FyTg46wom2286jJlXGGfcPFG/ba5NUiCwWNd4w==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz", + "integrity": "sha512-gIQfzgGgu1wy80EB4/6DaJGHMEGmizq27xHIESrzXq0Y/J0Ay1P3DWk6tuVmEPIZH15zaBlxeEJOqdJKmowHCQ==", "dev": true }, + "p-all": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-all/-/p-all-2.1.0.tgz", + "integrity": "sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA==", + "dev": true, + "requires": { + "p-map": "^2.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 + } + } + }, "p-cancelable": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", @@ -45636,6 +44218,23 @@ "p-timeout": "^2.0.1" } }, + "p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "requires": { + "p-map": "^2.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 + } + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -45741,19 +44340,19 @@ } }, "param-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.3.tgz", - "integrity": "sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dev": true, "requires": { - "dot-case": "^3.0.3", - "tslib": "^1.10.0" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" }, "dependencies": { "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true } } @@ -45856,19 +44455,19 @@ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, "pascal-case": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz", - "integrity": "sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "dev": true, "requires": { - "no-case": "^3.0.3", - "tslib": "^1.10.0" + "no-case": "^3.0.4", + "tslib": "^2.0.3" }, "dependencies": { "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true } } @@ -46109,6 +44708,60 @@ "find-up": "^2.1.0" } }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "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" + } + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "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 + } + } + }, "platform": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", @@ -46200,20 +44853,14 @@ } }, "polished": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/polished/-/polished-3.4.2.tgz", - "integrity": "sha512-9Rch6iMZckABr6EFCLPZsxodeBpXMo9H4fRlfR/9VjMEyy5xpo1/WgXlJGgSjPyVhEZNycbW7UmYMNyWS5MI0g==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/polished/-/polished-3.6.7.tgz", + "integrity": "sha512-b4OViUOihwV0icb9PHmWbR+vPqaSzSAEbgLskvb7ANPATVXGiYv/TQFHQo65S53WU9i5EQ1I03YDOJW7K0bmYg==", "dev": true, "requires": { - "@babel/runtime": "^7.6.3" + "@babel/runtime": "^7.9.2" } }, - "popper.js": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.0.tgz", - "integrity": "sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw==", - "dev": true - }, "portfinder": { "version": "1.0.25", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", @@ -47196,13 +45843,21 @@ } }, "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "dev": true, "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + } } }, "pretty-format": { @@ -47248,9 +45903,9 @@ "dev": true }, "prismjs": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.19.0.tgz", - "integrity": "sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.22.0.tgz", + "integrity": "sha512-lLJ/Wt9yy0AiSYBf212kK3mM5L8ycwlyTlSxHBAneXLR0nzFMlZ5y7riFPF3E33zXOF2IH95xdY5jIyZbM9z/w==", "dev": true, "requires": { "clipboard": "^2.0.0" @@ -47325,20 +45980,20 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -47369,9 +46024,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -47393,29 +46048,49 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -47441,20 +46116,20 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -47485,9 +46160,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -47509,29 +46184,49 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -47582,12 +46277,12 @@ "dev": true }, "property-information": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.3.0.tgz", - "integrity": "sha512-IslotQn1hBCZDY7SaJ3zmCjVea219VTwmOk6Pu3z9haU9m4+T8GwaDubur+6NMHEU+Fjs/6/p66z6QULPkcL1w==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", "dev": true, "requires": { - "xtend": "^4.0.1" + "xtend": "^4.0.0" } }, "proto-list": { @@ -47658,180 +46353,6 @@ "safe-buffer": "^5.1.2" } }, - "pug": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz", - "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==", - "dev": true, - "requires": { - "pug-code-gen": "^2.0.2", - "pug-filters": "^3.1.1", - "pug-lexer": "^4.1.0", - "pug-linker": "^3.0.6", - "pug-load": "^2.0.12", - "pug-parser": "^5.0.1", - "pug-runtime": "^2.0.5", - "pug-strip-comments": "^1.0.4" - } - }, - "pug-attrs": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz", - "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==", - "dev": true, - "requires": { - "constantinople": "^3.0.1", - "js-stringify": "^1.0.1", - "pug-runtime": "^2.0.5" - } - }, - "pug-code-gen": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz", - "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==", - "dev": true, - "requires": { - "constantinople": "^3.1.2", - "doctypes": "^1.1.0", - "js-stringify": "^1.0.1", - "pug-attrs": "^2.0.4", - "pug-error": "^1.3.3", - "pug-runtime": "^2.0.5", - "void-elements": "^2.0.1", - "with": "^5.0.0" - } - }, - "pug-error": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz", - "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ==", - "dev": true - }, - "pug-filters": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz", - "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==", - "dev": true, - "requires": { - "clean-css": "^4.1.11", - "constantinople": "^3.0.1", - "jstransformer": "1.0.0", - "pug-error": "^1.3.3", - "pug-walk": "^1.1.8", - "resolve": "^1.1.6", - "uglify-js": "^2.6.1" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - } - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "pug-lexer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz", - "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==", - "dev": true, - "requires": { - "character-parser": "^2.1.1", - "is-expression": "^3.0.0", - "pug-error": "^1.3.3" - } - }, - "pug-linker": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz", - "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==", - "dev": true, - "requires": { - "pug-error": "^1.3.3", - "pug-walk": "^1.1.8" - } - }, - "pug-load": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz", - "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==", - "dev": true, - "requires": { - "object-assign": "^4.1.0", - "pug-walk": "^1.1.8" - } - }, - "pug-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz", - "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==", - "dev": true, - "requires": { - "pug-error": "^1.3.3", - "token-stream": "0.0.1" - } - }, - "pug-runtime": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz", - "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==", - "dev": true - }, - "pug-strip-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz", - "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==", - "dev": true, - "requires": { - "pug-error": "^1.3.3" - } - }, - "pug-walk": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz", - "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==", - "dev": true - }, "pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", @@ -48027,9 +46548,9 @@ } }, "tar-stream": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.4.tgz", - "integrity": "sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, "requires": { "bl": "^4.0.3", @@ -48040,9 +46561,9 @@ } }, "ws": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", - "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", "dev": true }, "yauzl": { @@ -48200,13 +46721,13 @@ } }, "raw-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.1.tgz", - "integrity": "sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", + "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", "dev": true, "requires": { "loader-utils": "^2.0.0", - "schema-utils": "^2.6.5" + "schema-utils": "^3.0.0" }, "dependencies": { "@types/json-schema": { @@ -48216,9 +46737,9 @@ "dev": true }, "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -48271,20 +46792,14 @@ "json5": "^2.1.2" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } } @@ -48339,23 +46854,15 @@ "prop-types": "^15.5.6" } }, - "react-clientside-effect": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz", - "integrity": "sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A==", - "dev": true, - "requires": { - "@babel/runtime": "^7.0.0" - } - }, "react-color": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.0.tgz", - "integrity": "sha512-FyVeU1kQiSokWc8NPz22azl1ezLpJdUyTbWL0LPUpcuuYDrZ/Y1veOk9rRK5B3pMlyDGvTk4f4KJhlkIQNRjEA==", + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", + "integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==", "dev": true, "requires": { "@icons/material": "^0.2.4", - "lodash": "^4.17.11", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", "material-colors": "^1.2.1", "prop-types": "^15.5.10", "reactcss": "^1.2.0", @@ -48482,9 +46989,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001124", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001124.tgz", - "integrity": "sha512-zQW8V3CdND7GHRH6rxm6s59Ww4g/qGWTheoboW9nfeMg7sUoopIfKCcNZUjwYRCOrvereh3kwDpZj4VLQ7zGtA==", + "version": "1.0.30001168", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001168.tgz", + "integrity": "sha512-P2zmX7swIXKu+GMMR01TWa4csIKELTNnZKc+f1CjebmZJQtTAEXmpQSoKVJVVcvPGAA0TEYTOUp3VehavZSFPQ==", "dev": true }, "chalk": { @@ -48507,9 +47014,9 @@ } }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "requires": { "anymatch": "~3.1.1", @@ -48519,7 +47026,7 @@ "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" } }, "cli-cursor": { @@ -48623,32 +47130,6 @@ "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" - }, - "dependencies": { - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } } }, "fork-ts-checker-webpack-plugin": { @@ -48796,13 +47277,12 @@ } }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "mimic-fn": { @@ -48833,9 +47313,9 @@ } }, "open": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/open/-/open-7.2.1.tgz", - "integrity": "sha512-xbYCJib4spUdmcs0g/2mK1nKo/jO2T7INClWd/beL7PFkXRWgr8B23ssDHX/USPn2M2IjDR5UdpYs6I67SnTSA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz", + "integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==", "dev": true, "requires": { "is-docker": "^2.0.0", @@ -48852,12 +47332,12 @@ } }, "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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, "p-try": { @@ -48866,6 +47346,12 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -48878,30 +47364,10 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "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" - } - } - } - }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -49034,14 +47500,14 @@ } }, "react-docgen": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-5.3.0.tgz", - "integrity": "sha512-hUrv69k6nxazOuOmdGeOpC/ldiKy7Qj/UFpxaQi0eDMrUFUTIPGtY5HJu7BggSmiyAMfREaESbtBL9UzdQ+hyg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-5.3.1.tgz", + "integrity": "sha512-YG7YujVTwlLslr2Ny8nQiUfbBuEwKsLHJdQTSdEga1eY/nRFh/7LjCWUn6ogYhu2WDKg4z+6W/BJtUi+DPUIlA==", "dev": true, "requires": { "@babel/core": "^7.7.5", "@babel/runtime": "^7.7.6", - "ast-types": "^0.13.2", + "ast-types": "^0.14.2", "commander": "^2.19.0", "doctrine": "^3.0.0", "neo-async": "^2.6.1", @@ -49049,15 +47515,6 @@ "strip-indent": "^3.0.0" }, "dependencies": { - "ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "requires": { - "tslib": "^2.0.1" - } - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -49087,77 +47544,25 @@ "requires": { "min-indent": "^1.0.0" } - }, - "tslib": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", - "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", - "dev": true } } }, "react-docgen-typescript": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-1.20.4.tgz", - "integrity": "sha512-gE2SeseJd6+o981qr9VQJRbvFJ5LjLSKQiwhHsuLN4flt+lheKtG1jp2BPzrv2MKR5gmbLwpmNtK4wbLCPSZAw==", + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-1.20.5.tgz", + "integrity": "sha512-AbLGMtn76bn7SYBJSSaKJrZ0lgNRRR3qL60PucM5M4v/AXyC8221cKBXW5Pyt9TfDRfe+LDnPNlg7TibxX0ovA==", "dev": true }, - "react-docgen-typescript-loader": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/react-docgen-typescript-loader/-/react-docgen-typescript-loader-3.7.2.tgz", - "integrity": "sha512-fNzUayyUGzSyoOl7E89VaPKJk9dpvdSgyXg81cUkwy0u+NBvkzQG3FC5WBIlXda0k/iaxS+PWi+OC+tUiGxzPA==", - "dev": true, - "requires": { - "@webpack-contrib/schema-utils": "^1.0.0-beta.0", - "loader-utils": "^1.2.3", - "react-docgen-typescript": "^1.15.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 - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "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.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, "react-docgen-typescript-plugin": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-0.5.2.tgz", - "integrity": "sha512-NQfWyWLmzUnedkiN2nPDb6Nkm68ik6fqbC3UvgjqYSeZsbKijXUA4bmV6aU7qICOXdop9PevPdjEgJuAN0nNVQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-0.6.3.tgz", + "integrity": "sha512-av1S/fmWBNFGgNa4qtkidFjjOz23eEi6EdCtwSWo9WNhGzUMyMygbD/DosMWoeFlZpk9R3MXPkRE7PDH6j5GMQ==", "dev": true, "requires": { "debug": "^4.1.1", "endent": "^2.0.1", "micromatch": "^4.0.2", - "react-docgen-typescript": "^1.20.1", - "react-docgen-typescript-loader": "^3.7.2", + "react-docgen-typescript": "^1.20.5", "tslib": "^2.0.0" }, "dependencies": { @@ -49171,12 +47576,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "fill-range": { @@ -49220,9 +47625,9 @@ } }, "tslib": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", - "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true } } @@ -49275,68 +47680,45 @@ } }, "react-element-to-jsx-string": { - "version": "14.3.1", - "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.1.tgz", - "integrity": "sha512-LRdQWRB+xcVPOL4PU4RYuTg6dUJ/FNmaQ8ls6w38YbzkbV6Yr5tFNESroub9GiSghtnMq8dQg2LcNN5aMIDzVg==", + "version": "14.3.2", + "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.2.tgz", + "integrity": "sha512-WZbvG72cjLXAxV7VOuSzuHEaI3RHj10DZu8EcKQpkKcAj7+qAkG5XUeSdX5FXrA0vPrlx0QsnAzZEBJwzV0e+w==", "dev": true, "requires": { "@base2/pretty-print-object": "1.0.0", - "is-plain-object": "3.0.0" + "is-plain-object": "3.0.1" }, "dependencies": { "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==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", "dev": true } } }, "react-error-overlay": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", - "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.8.tgz", + "integrity": "sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw==", "dev": true }, "react-fast-compare": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", - "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==", "dev": true }, - "react-focus-lock": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.2.1.tgz", - "integrity": "sha512-47g0xYcCTZccdzKRGufepY8oZ3W1Qg+2hn6u9SHZ0zUB6uz/4K4xJe7yYFNZ1qT6m+2JDm82F6QgKeBTbjW4PQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.0.0", - "focus-lock": "^0.6.6", - "prop-types": "^15.6.2", - "react-clientside-effect": "^1.2.2", - "use-callback-ref": "^1.2.1", - "use-sidecar": "^1.0.1" - } - }, "react-helmet-async": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.0.4.tgz", - "integrity": "sha512-KTGHE9sz8N7+fCkZ2a3vzXH9eIkiTNhL2NhKR7XzzQl3WsGlCHh76arauJUIiGdfhjeMp7DY7PkASAmYFXeJYg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.0.7.tgz", + "integrity": "sha512-By90p5uxAriGukbyejq2poK41DwTxpNWOpOjN8mIyX/BKrCd3+sXZ5pHUZXjHyjR5OYS7PGsOD9dbM61YxfFmA==", "dev": true, "requires": { - "@babel/runtime": "^7.3.4", + "@babel/runtime": "^7.11.2", "invariant": "^2.2.4", "prop-types": "^15.7.2", - "react-fast-compare": "^2.0.4", + "react-fast-compare": "^3.2.0", "shallowequal": "^1.1.0" } }, @@ -50458,49 +48840,32 @@ } }, "react-popper": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz", - "integrity": "sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.4.tgz", + "integrity": "sha512-NacOu4zWupdQjVXq02XpTD3yFPSfg5a7fex0wa3uGKVkFK7UN6LvVxgcb+xYr56UCuWiNPMH20tntdVdJRwYew==", "dev": true, "requires": { - "@babel/runtime": "^7.1.2", - "create-react-context": "^0.3.0", - "deep-equal": "^1.1.1", - "popper.js": "^1.14.4", - "prop-types": "^15.6.1", - "typed-styles": "^0.0.7", + "react-fast-compare": "^3.0.1", "warning": "^4.0.2" - }, - "dependencies": { - "create-react-context": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", - "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", - "dev": true, - "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" - } - }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - } } }, "react-popper-tooltip": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/react-popper-tooltip/-/react-popper-tooltip-2.10.1.tgz", - "integrity": "sha512-cib8bKiyYcrIlHo9zXx81G0XvARfL8Jt+xum709MFCgQa3HTqTi4au3iJ9tm7vi7WU7ngnqbpWkMinBOtwo+IQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/react-popper-tooltip/-/react-popper-tooltip-3.1.1.tgz", + "integrity": "sha512-EnERAnnKRptQBJyaee5GJScWNUKQPDD2ywvzZyUjst/wj5U64C8/CnSYLNEmP2hG0IJ3ZhtDxE8oDN+KOyavXQ==", "dev": true, "requires": { - "@babel/runtime": "^7.7.4", - "react-popper": "^1.3.6" + "@babel/runtime": "^7.12.5", + "@popperjs/core": "^2.5.4", + "react-popper": "^2.2.4" + }, + "dependencies": { + "@popperjs/core": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.6.0.tgz", + "integrity": "sha512-cPqjjzuFWNK3BSKLm0abspP0sp/IGOli4p5I5fKFAzdS8fvjdOwDCfZqAaIiXd9lPkOWi3SUUfZof3hEb7J/uw==", + "dev": true + } } }, "react-portal": { @@ -50511,37 +48876,6 @@ "prop-types": "^15.5.8" } }, - "react-redux": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.1.3.tgz", - "integrity": "sha512-uI1wca+ECG9RoVkWQFF4jDMqmaw0/qnvaSvOoL/GA4dNxf6LoV8sUAcNDvE5NWKs4hFpn0t6wswNQnY3f7HT3w==", - "dev": true, - "requires": { - "@babel/runtime": "^7.5.5", - "hoist-non-react-statics": "^3.3.0", - "invariant": "^2.2.4", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^16.9.0" - }, - "dependencies": { - "hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw==", - "dev": true, - "requires": { - "react-is": "^16.7.0" - } - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", - "dev": true - } - } - }, "react-refresh": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.2.tgz", @@ -50553,9 +48887,9 @@ "integrity": "sha512-HdPzwdcAv+BMFQEgyacFB40G4IxNMO7tSqaMjbnAouot8LXi5/Rx3/Fv+LU2cQekqiivE1LF4sGnwQ7SnoHrpg==" }, "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==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.1.tgz", + "integrity": "sha512-HjC6jT2BhUxbIbxMZWqVcDibrEpdUJCfGicN0MMV+BQyKtCaPTgFekKWiOizSCy4jdsLMGjLqcFGJMhVGWB0Dg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", @@ -50565,7 +48899,7 @@ "memoize-one": "^5.0.0", "prop-types": "^15.6.0", "react-input-autosize": "^2.2.2", - "react-transition-group": "^2.2.1" + "react-transition-group": "^4.3.0" } }, "react-sizeme": { @@ -50590,16 +48924,16 @@ } }, "react-syntax-highlighter": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz", - "integrity": "sha512-kqmpM2OH5OodInbEADKARwccwSQWBfZi0970l5Jhp4h39q9Q65C4frNcnd6uHE5pR00W8pOWj9HDRntj2G4Rww==", + "version": "13.5.3", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz", + "integrity": "sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg==", "dev": true, "requires": { "@babel/runtime": "^7.3.1", - "highlight.js": "~9.13.0", - "lowlight": "~1.11.0", - "prismjs": "^1.8.4", - "refractor": "^2.4.1" + "highlight.js": "^10.1.1", + "lowlight": "^1.14.0", + "prismjs": "^1.21.0", + "refractor": "^3.1.0" } }, "react-test-renderer": { @@ -50633,25 +48967,26 @@ } }, "react-textarea-autosize": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-7.1.2.tgz", - "integrity": "sha512-uH3ORCsCa3C6LHxExExhF4jHoXYCQwE5oECmrRsunlspaDAbS4mGKNlWZqjLfInWtFQcf0o1n1jC/NGXFdUBCg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz", + "integrity": "sha512-3GLWFAan2pbwBeoeNDoqGmSbrShORtgWfaWX0RJDivsUrpShh01saRM5RU/i4Zmf+whpBVEY5cA90Eq8Ub1N3w==", "dev": true, "requires": { - "@babel/runtime": "^7.1.2", - "prop-types": "^15.6.0" + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.0.0", + "use-latest": "^1.0.0" } }, "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==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", "dev": true, "requires": { - "dom-helpers": "^3.4.0", + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" + "prop-types": "^15.6.2" } }, "react-use-gesture": { @@ -50870,35 +49205,6 @@ "reakit-utils": "^0.13.0" } }, - "realpath-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", - "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "dev": true, - "requires": { - "util.promisify": "^1.0.0" - } - }, - "recast": { - "version": "0.17.6", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.17.6.tgz", - "integrity": "sha512-yoQRMRrK1lszNtbkGyM4kN45AwylV5hMiuEveUBlxytUViWevjvX6w+tzJt1LH4cfUhWt4NZvy3ThIhu6+m5wQ==", - "dev": true, - "requires": { - "ast-types": "0.12.4", - "esprima": "~4.0.0", - "private": "^0.1.8", - "source-map": "~0.6.1" - }, - "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 - } - } - }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -50941,34 +49247,34 @@ "resolved": "https://registry.npmjs.org/redux-multi/-/redux-multi-0.1.12.tgz", "integrity": "sha1-KOH+XklnLLxb2KB/Cyrq8O+DVcI=" }, - "redux-optimist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redux-optimist/-/redux-optimist-1.0.0.tgz", - "integrity": "sha512-AG1v8o6UZcGXTEH2jVcWG6KD+gEix+Cj9JXAAzln9MPkauSVd98H7N7EOOyT/v4c9N1mJB4sm1zfspGlLDkUEw==" - }, "reflect.ownkeys": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" }, "refractor": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-2.10.0.tgz", - "integrity": "sha512-maW2ClIkm9IYruuFYGTqKzj+m31heq92wlheW4h7bOstP+gf8bocmMec+j7ljLcaB1CAID85LMB3moye31jH1g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.2.0.tgz", + "integrity": "sha512-hSo+EyMIZTLBvNNgIU5lW4yjCzNYMZ4dcEhBq/3nReGfqzd2JfVhdlPDfU9rEsgcAyWx+OimIIUoL4ZU7NtYHQ==", "dev": true, "requires": { - "hastscript": "^5.0.0", - "parse-entities": "^1.1.2", - "prismjs": "~1.17.0" + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.22.0" }, "dependencies": { - "prismjs": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", - "integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==", + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dev": true, "requires": { - "clipboard": "^2.0.0" + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" } } } @@ -51179,16 +49485,16 @@ } }, "remark-external-links": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-external-links/-/remark-external-links-5.0.0.tgz", - "integrity": "sha512-lYnZGNN10N3YGMvO95Zup4hZ+VHI82JgcrGJfuxOLQExoho/iNhlrPVSkmdapYQl928pkOn4YOgJf/0pdZkteA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/remark-external-links/-/remark-external-links-6.1.0.tgz", + "integrity": "sha512-dJr+vhe3wuh1+E9jltQ+efRMqtMDOOnfFkhtoArOmhnBcPQX6THttXMkc/H0kdnAvkXTk7f2QdOYm5qo/sGqdw==", "dev": true, "requires": { "extend": "^3.0.0", "is-absolute-url": "^3.0.0", - "mdast-util-definitions": "^1.2.3", - "space-separated-tokens": "^1.1.2", - "unist-util-visit": "^1.4.0" + "mdast-util-definitions": "^2.0.0", + "space-separated-tokens": "^1.0.0", + "unist-util-visit": "^2.0.0" }, "dependencies": { "is-absolute-url": { @@ -51196,105 +49502,77 @@ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "dev": true - } - } - }, - "remark-mdx": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.5.5.tgz", - "integrity": "sha512-w1XW9UzsQ6XAecV59dP8LJWn4tMftaXGwH5LEvUU5uIEJEJvHDE1jkKiPr3ow2IuhjuRfWs3b079Jtnk5qlUgQ==", - "dev": true, - "requires": { - "@babel/core": "7.8.0", - "@babel/helper-plugin-utils": "7.8.0", - "@babel/plugin-proposal-object-rest-spread": "7.8.0", - "@babel/plugin-syntax-jsx": "7.8.0", - "@mdx-js/util": "^1.5.5", - "is-alphabetical": "1.0.3", - "remark-parse": "7.0.2", - "unified": "8.4.2" - }, - "dependencies": { - "@babel/core": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.0.tgz", - "integrity": "sha512-3rqPi/bv/Xfu2YzHvBz4XqMI1fKVwnhntPA1/fjoECrSjrhbOCxlTrbVu5gUtr8zkxW+RpkDOa/HCW93gzS2Dw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.0", - "@babel/generator": "^7.8.0", - "@babel/helpers": "^7.8.0", - "@babel/parser": "^7.8.0", - "@babel/template": "^7.8.0", - "@babel/traverse": "^7.8.0", - "@babel/types": "^7.8.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.0.tgz", - "integrity": "sha512-+hAlRGdf8fHQAyNnDBqTHQhwdLURLdrCROoWaEQYiQhk2sV9Rhs+GoFZZfMJExTq9HG8o2NX3uN2G90bFtmFdA==", - "dev": true }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.0.tgz", - "integrity": "sha512-SjJ2ZXCylpWC+5DTES0/pbpNmw/FnjU/3dF068xF0DU9aN+oOKah+3MCSFcb4pnZ9IwmxfOy4KnbGJSQR+hAZA==", + "mdast-util-definitions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-2.0.1.tgz", + "integrity": "sha512-Co+DQ6oZlUzvUR7JCpP249PcexxygiaKk9axJh+eRzHDZJk2julbIdKB4PXHVxdBuLzvJ1Izb+YDpj2deGMOuA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + "unist-util-visit": "^2.0.0" } }, - "@babel/plugin-syntax-jsx": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.0.tgz", - "integrity": "sha512-zLDUckAuKeOtxJhfNE0TlR7iEApb2u7EYRlh5cxKzq6A5VzUbYEdyJGJlug41jDbjRbHTtsLKZUnUcy/8V3xZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "unist-util-is": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", + "dev": true }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dev": true, "requires": { - "safe-buffer": "~5.1.1" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", "dev": true, "requires": { - "ms": "^2.1.1" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" } - }, - "globals": { - "version": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, + } + } + }, + "remark-footnotes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", + "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==", + "dev": true + }, + "remark-mdx": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", + "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", + "dev": true, + "requires": { + "@babel/core": "7.12.9", + "@babel/helper-plugin-utils": "7.10.4", + "@babel/plugin-proposal-object-rest-spread": "7.12.1", + "@babel/plugin-syntax-jsx": "7.12.1", + "@mdx-js/util": "1.6.22", + "is-alphabetical": "1.0.4", + "remark-parse": "8.0.3", + "unified": "9.2.0" + }, + "dependencies": { "is-alphabetical": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", - "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "dev": true }, "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true }, "is-plain-obj": { @@ -51303,89 +49581,125 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, - "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dev": true, "requires": { - "minimist": "^1.2.0" + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" } }, - "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 - }, "remark-parse": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-7.0.2.tgz", - "integrity": "sha512-9+my0lQS80IQkYXsMA8Sg6m9QfXYJBnXjWYN5U+kFc5/n69t+XZVXU/ZBYr3cYH8FheEGf1v87rkFDhJ8bVgMA==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", + "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", "dev": true, "requires": { + "ccount": "^1.0.0", "collapse-white-space": "^1.0.2", "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0", "is-whitespace-character": "^1.0.0", "is-word-character": "^1.0.0", "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", + "parse-entities": "^2.0.0", "repeat-string": "^1.5.4", "state-toggle": "^1.0.0", "trim": "0.0.1", "trim-trailing-lines": "^1.0.0", "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", + "unist-util-remove-position": "^2.0.0", + "vfile-location": "^3.0.0", "xtend": "^4.0.1" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "unified": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz", - "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", "dev": true, "requires": { "bail": "^1.0.0", "extend": "^3.0.0", + "is-buffer": "^2.0.0", "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" } }, + "unist-util-is": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", + "dev": true + }, + "unist-util-remove-position": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", + "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", + "dev": true, + "requires": { + "unist-util-visit": "^2.0.0" + } + }, "unist-util-stringify-position": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz", - "integrity": "sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dev": true, "requires": { "@types/unist": "^2.0.2" } }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, "vfile": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.0.2.tgz", - "integrity": "sha512-yhoTU5cDMSsaeaMfJ5g0bUKYkYmZhAh9fn9TZicxqn+Cw4Z439il2v3oT9S0yjlpqlI74aFOQCt3nOV+pxzlkw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "dev": true, "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" } }, + "vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "dev": true + }, "vfile-message": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.2.tgz", - "integrity": "sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -51418,23 +49732,52 @@ } }, "remark-slug": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-5.1.2.tgz", - "integrity": "sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-6.0.0.tgz", + "integrity": "sha512-ln67v5BrGKHpETnm6z6adlJPhESFJwfuZZ3jrmi+lKTzeZxh2tzFzUfDD4Pm2hRGOarHLuGToO86MNMZ/hA67Q==", "dev": true, "requires": { "github-slugger": "^1.0.0", "mdast-util-to-string": "^1.0.0", - "unist-util-visit": "^1.0.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", + "dev": true + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-squeeze-paragraphs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-3.0.4.tgz", - "integrity": "sha512-Wmz5Yj9q+W1oryo8BV17JrOXZgUKVcpJ2ApE2pwnoHwhFKSk4Wp2PmFNbmJMgYSqAdFwfkoe+TSYop5Fy8wMgA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", + "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", "dev": true, "requires": { - "mdast-squeeze-paragraphs": "^3.0.0" + "mdast-squeeze-paragraphs": "^4.0.0" } }, "remark-stringify": { @@ -51470,16 +49813,16 @@ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.4.tgz", + "integrity": "sha512-K2eXrSOJdq+HuKzlcjOlGoOarUu5SDguDEhE7+Ah4zuOWL40j8A/oHvLlLob9PSTNvVnBd+/q0Er1QfpEuem5g==", "dev": true, "requires": { "css-select": "^1.1.0", "dom-converter": "^0.2", "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" + "lodash": "^4.17.20", + "strip-ansi": "^3.0.0" }, "dependencies": { "ansi-regex": { @@ -51488,6 +49831,12 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -51591,12 +49940,6 @@ "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true }, - "resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", - "dev": true - }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -51720,15 +50063,6 @@ "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", "dev": true }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "^0.1.1" - } - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -52649,30 +50983,6 @@ } } }, - "simplebar": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/simplebar/-/simplebar-4.2.3.tgz", - "integrity": "sha512-9no0pK7/1y+8/oTF3sy/+kx0PjQ3uk4cYwld5F1CJGk2gx+prRyUq8GRfvcVLq5niYWSozZdX73a2wIr1o9l/g==", - "dev": true, - "requires": { - "can-use-dom": "^0.1.0", - "core-js": "^3.0.1", - "lodash.debounce": "^4.0.8", - "lodash.memoize": "^4.1.2", - "lodash.throttle": "^4.1.1", - "resize-observer-polyfill": "^1.5.1" - } - }, - "simplebar-react": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/simplebar-react/-/simplebar-react-1.2.3.tgz", - "integrity": "sha512-1EOWJzFC7eqHUp1igD1/tb8GBv5aPQA5ZMvpeDnVkpNJ3jAuvmrL2kir3HuijlxhG7njvw9ssxjjBa89E5DrJg==", - "dev": true, - "requires": { - "prop-types": "^15.6.1", - "simplebar": "^4.2.3" - } - }, "sisteransi": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", @@ -52901,9 +51211,9 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "space-separated-tokens": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz", - "integrity": "sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", "dev": true }, "spawn-command": { @@ -53039,6 +51349,12 @@ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=" }, + "stackframe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", + "dev": true + }, "stacktrace-parser": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.8.tgz", @@ -53091,9 +51407,9 @@ "dev": true }, "store2": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/store2/-/store2-2.10.0.tgz", - "integrity": "sha512-tWEpK0snS2RPUq1i3R6OahfJNjWCQYNxq0+by1amCSuw0mXtymJpzmZIeYpA1UAa+7B0grCpNYIbDcd7AgTbFg==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/store2/-/store2-2.12.0.tgz", + "integrity": "sha512-7t+/wpKLanLzSnQPX8WAcuLCCeuSHoWdQuh9SB3xD0kNOM38DNf+0Oa+wmvxmYueRzkmh6IcdKFtvTa+ecgPDw==", "dev": true }, "stream-browserify": { @@ -53314,13 +51630,14 @@ } }, "string.prototype.padend": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz", - "integrity": "sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.1.tgz", + "integrity": "sha512-eCzTASPnoCr5Ht+Vn1YXgm8SB015hHKgEIMu9Nr9bQmLhRBxKRfmzSj/IQsxDFc8JInJDDFA0qXwK+xxI7wDkg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "es-abstract": "^1.18.0-next.1" }, "dependencies": { "define-properties": { @@ -53333,20 +51650,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -53377,9 +51695,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -53401,41 +51719,62 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } }, "string.prototype.padstart": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.padstart/-/string.prototype.padstart-3.1.0.tgz", - "integrity": "sha512-envqZvUp2JItI+OeQ5UAh1ihbAV5G/2bixTojvlIa090GGqF+NQRxbWb2nv9fTGrZABv6+pE6jXoAZhhS2k4Hw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.padstart/-/string.prototype.padstart-3.1.1.tgz", + "integrity": "sha512-kcFjKhQYg40AK9MITCWYr/vIebruAD01sc/fxi8szHJaEG7Rke4XHw6LU9c1VWXh/+J/PxvWLLf/aIAGKhXkAQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "es-abstract": "^1.18.0-next.1" }, "dependencies": { "define-properties": { @@ -53448,20 +51787,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, @@ -53492,9 +51832,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -53516,29 +51856,49 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "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 + } + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -54815,13 +53175,15 @@ "dev": true }, "symbol.prototype.description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/symbol.prototype.description/-/symbol.prototype.description-1.0.2.tgz", - "integrity": "sha512-2CW5SU4/Ki1cYOOHcL2cXK4rxSg5hCU1TwZ7X4euKhV9VnfqKslh7T6/UyKkubA8cq2tOmsOv7m3ZUmQslBRuw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/symbol.prototype.description/-/symbol.prototype.description-1.0.3.tgz", + "integrity": "sha512-NvwWb5AdyTtmFNa1x0ksJakFUV/WJ+z7iRrYGU1xZew77Qd+kMrZKsk3uatCckk6yPNpbHhRcOO+JBU+ohcMBw==", "dev": true, "requires": { - "es-abstract": "^1.17.0-next.1", - "has-symbols": "^1.0.1" + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" }, "dependencies": { "define-properties": { @@ -54834,20 +53196,21 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" } @@ -54870,9 +53233,9 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, "is-regex": { @@ -54894,9 +53257,9 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, "object-keys": { @@ -54905,24 +53268,47 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "object.getownpropertydescriptors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz", + "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "es-abstract": "^1.18.0-next.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -55071,18 +53457,18 @@ } }, "telejson": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-3.3.0.tgz", - "integrity": "sha512-er08AylQ+LEbDLp1GRezORZu5wKOHaBczF6oYJtgC3Idv10qZ8A3p6ffT+J5BzDKkV9MqBvu8HAKiIIOp6KJ2w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.1.0.tgz", + "integrity": "sha512-Yy0N2OV0mosmr1SCZEm3Ezhu/oi5Dbao5RqauZu4+VI5I/XtVBHXajRk0txuqbFYtKdzzWGDZFGSif9ovVLjEA==", "dev": true, "requires": { "@types/is-function": "^1.0.0", "global": "^4.4.0", - "is-function": "^1.0.1", - "is-regex": "^1.0.4", + "is-function": "^1.0.2", + "is-regex": "^1.1.1", "is-symbol": "^1.0.3", "isobject": "^4.0.0", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "memoizerific": "^1.11.3" }, "dependencies": { @@ -55092,6 +53478,15 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -55106,6 +53501,12 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true } } }, @@ -55169,9 +53570,9 @@ } }, "term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "dev": true }, "terminal-link": { @@ -55656,9 +54057,9 @@ "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=" }, "throttle-debounce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.1.0.tgz", - "integrity": "sha512-AOvyNahXQuU7NN+VVvOOX+uW6FPaWdAOdRP5HfwYxAfCzXTFKRMoIMk+n+po318+ktcChx+F1Dd91G3YHeMKyg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz", + "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==", "dev": true }, "through": { @@ -55805,12 +54206,6 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, - "token-stream": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", - "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=", - "dev": true - }, "toolkit.ts": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/toolkit.ts/-/toolkit.ts-0.0.2.tgz", @@ -55860,12 +54255,6 @@ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", "dev": true }, - "trim-lines": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.2.tgz", - "integrity": "sha512-3GOuyNeTqk3FAqc3jOJtw7FTjYl94XBR5aD9QnDbK/T4CA9sW/J0l9RoaRPE9wyPP7NF331qnHnvJFBJ+IDkmQ==", - "dev": true - }, "trim-newlines": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", @@ -55897,9 +54286,9 @@ "dev": true }, "ts-dedent": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-1.1.0.tgz", - "integrity": "sha512-CVCvDwMBWZKjDxpN3mU/Dx1v3k+sJgE8nrhXcC9vRopRfoa7vVzilNvHEAUi5jQnmFHpnxDx5jZdI1TpG8ny2g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.0.0.tgz", + "integrity": "sha512-DfxKjSFQfw9+uf7N9Cy8Ebx9fv5fquK4hZ6SD3Rzr+1jKP6AVA6H8+B5457ZpUs0JKsGpGqIevbpZ9DMQJDp1A==", "dev": true }, "ts-essentials": { @@ -55908,12 +54297,6 @@ "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==", "dev": true }, - "ts-map": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-map/-/ts-map-1.0.3.tgz", - "integrity": "sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==", - "dev": true - }, "ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", @@ -55962,12 +54345,6 @@ "dev": true, "optional": true }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -56015,12 +54392,6 @@ } } }, - "typed-styles": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", - "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==", - "dev": true - }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -56100,13 +54471,6 @@ } } }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, - "optional": true - }, "uid-number": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", @@ -56165,9 +54529,9 @@ "dev": true }, "unfetch": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.1.0.tgz", - "integrity": "sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", "dev": true }, "unherit": { @@ -56262,13 +54626,10 @@ } }, "unist-builder": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz", - "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==", - "dev": true, - "requires": { - "object-assign": "^4.1.0" - } + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", + "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==", + "dev": true }, "unist-util-find-all-after": { "version": "3.0.1", @@ -56288,9 +54649,9 @@ } }, "unist-util-generated": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.5.tgz", - "integrity": "sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", + "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", "dev": true }, "unist-util-is": { @@ -56309,24 +54670,24 @@ } }, "unist-util-position": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.4.tgz", - "integrity": "sha512-tWvIbV8goayTjobxDIr4zVTyG+Q7ragMSMeKC3xnPl9xzIc0+she8mxXLM3JVNDDsfARPbCd3XdzkyLdo7fF3g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", "dev": true }, "unist-util-remove": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-1.0.3.tgz", - "integrity": "sha512-mB6nCHCQK0pQffUAcCVmKgIWzG/AXs/V8qpS8K72tMPtOSCMSjDeMc5yN+Ye8rB0FhcE+JvW++o1xRNc0R+++g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.0.1.tgz", + "integrity": "sha512-YtuetK6o16CMfG+0u4nndsWpujgsHDHHLyE0yGpJLLn5xSjKeyGyzEBOI2XbmoUHCYabmNgX52uxlWoQhcvR7Q==", "dev": true, "requires": { - "unist-util-is": "^3.0.0" + "unist-util-is": "^4.0.0" }, "dependencies": { "unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", "dev": true } } @@ -56523,31 +54884,25 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, - "use-callback-ref": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.1.tgz", - "integrity": "sha512-C3nvxh0ZpaOxs9RCnWwAJ+7bJPwQI8LHF71LzbQ3BvzH5XkdtlkMadqElGevg5bYBDFip4sAnD4m06zAKebg1w==", - "dev": true - }, "use-composed-ref": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.0.0.tgz", - "integrity": "sha512-RVqY3NFNjZa0xrmK3bIMWNmQ01QjKPDc7DeWR3xa/N8aliVppuutOE5bZzPkQfvL+5NRWMMp0DJ99Trd974FIw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz", + "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", "dev": true, "requires": { "ts-essentials": "^2.0.3" } }, "use-isomorphic-layout-effect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.0.0.tgz", - "integrity": "sha512-JMwJ7Vd86NwAt1jH7q+OIozZSIxA4ND0fx6AsOe2q1H8ooBUp5aN6DvVCqZiIaYU6JaMRJGyR0FO7EBCIsb/Rg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.0.tgz", + "integrity": "sha512-kady5Z1O1qx5RitodCCKbpJSVEtECXYcnBnb5Q48Bz5V6gBmTu85ZcGdVwVFs8+DaOurNb/L5VdGHoQRMknghw==", "dev": true }, "use-latest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.1.0.tgz", - "integrity": "sha512-gF04d0ZMV3AMB8Q7HtfkAWe+oq1tFXP6dZKwBHQF5nVXtGsh2oAYeeqma5ZzxtlpOcW8Ro/tLcfmEodjDeqtuw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.0.tgz", + "integrity": "sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw==", "dev": true, "requires": { "use-isomorphic-layout-effect": "^1.0.0" @@ -56558,16 +54913,6 @@ "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.1.tgz", "integrity": "sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ==" }, - "use-sidecar": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.2.tgz", - "integrity": "sha512-287RZny6m5KNMTb/Kq9gmjafi7lQL0YHO1lYolU6+tY1h9+Z3uCtkJJ3OSOq3INwYf2hBryCcDh4520AhJibMA==", - "dev": true, - "requires": { - "detect-node": "^2.0.4", - "tslib": "^1.9.3" - } - }, "use-subscription": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.0.tgz", @@ -56751,97 +55096,6 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "vue-docgen-api": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/vue-docgen-api/-/vue-docgen-api-4.7.0.tgz", - "integrity": "sha512-yAzaM5NNuJKouzAaUeLdopcRW4J2BmD+aNXJGTyFVhr83yyTjDQz4QuwugcTJXGpStGGAXR1mOcAOitx59DC0g==", - "dev": true, - "requires": { - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0", - "ast-types": "^0.12.2", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.5", - "pug": "^2.0.3", - "recast": "^0.17.3", - "ts-map": "^1.0.3", - "vue-template-compiler": "^2.0.0" - }, - "dependencies": { - "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" - } - } - } - }, - "vue-docgen-loader": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/vue-docgen-loader/-/vue-docgen-loader-1.3.0.tgz", - "integrity": "sha512-K/r3IulRQlZpRIvR0Ed8vdPQCCd1WbcajOgm/4fdwtO4pWorLLX9o0YGM1rlkX3DXybqOolQ5LEh7E3kTer1qg==", - "dev": true, - "requires": { - "clone": "^2.1.2", - "jscodeshift": "^0.7.0", - "loader-utils": "^1.2.3", - "querystring": "^0.2.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 - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "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" - } - } - } - }, - "vue-template-compiler": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz", - "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==", - "dev": true, - "requires": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, "w3c-hr-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", @@ -56943,9 +55197,9 @@ } }, "warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", "dev": true, "requires": { "loose-envify": "^1.0.0" @@ -56963,9 +55217,9 @@ } }, "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", "dev": true, "optional": true, "requires": { @@ -56996,9 +55250,9 @@ } }, "web-namespaces": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.3.tgz", - "integrity": "sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", "dev": true }, "webidl-conversions": { @@ -57720,9 +55974,9 @@ } }, "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", "dev": true, "requires": { "memory-fs": "^0.4.1", @@ -57740,6 +55994,12 @@ } } }, + "webpack-filter-warnings-plugin": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz", + "integrity": "sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg==", + "dev": true + }, "webpack-hot-middleware": { "version": "2.25.0", "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz", @@ -57990,12 +56250,6 @@ } } }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, "windows-release": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", @@ -58060,41 +56314,6 @@ } } }, - "with": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", - "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", - "dev": true, - "requires": { - "acorn": "^3.1.0", - "acorn-globals": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - }, - "acorn-globals": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", - "dev": true, - "requires": { - "acorn": "^4.0.4" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } - } - } - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -58539,9 +56758,9 @@ } }, "zwitch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.4.tgz", - "integrity": "sha512-YO803/X+13GNaZB7fVopjvHH0uWQKgJkgKnU1YCjxShjKGVuN9PPHHW8g+uFDpkHpSTNi3rCMKMewIcbC1BAYg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", "dev": true } } diff --git a/package.json b/package.json index ecec9a29644009..e9563345484ba3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "9.6.0-rc.1", + "version": "9.7.0-rc.1", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", @@ -89,12 +89,12 @@ "@jest/types": "25.3.0", "@octokit/rest": "16.26.0", "@octokit/webhooks": "7.1.0", - "@storybook/addon-a11y": "5.3.2", - "@storybook/addon-docs": "5.3.2", - "@storybook/addon-knobs": "5.3.2", - "@storybook/addon-storysource": "5.3.2", - "@storybook/addon-viewport": "5.3.2", - "@storybook/react": "6.0.21", + "@storybook/addon-a11y": "6.1.11", + "@storybook/addon-docs": "6.1.11", + "@storybook/addon-knobs": "6.1.11", + "@storybook/addon-storysource": "6.1.11", + "@storybook/addon-viewport": "6.1.11", + "@storybook/react": "6.1.11", "@testing-library/react": "10.0.2", "@types/classnames": "2.2.10", "@types/eslint": "6.8.0", @@ -141,7 +141,6 @@ "babel-plugin-inline-json-import": "0.3.2", "babel-plugin-react-native-classname-to-style": "1.2.2", "babel-plugin-react-native-platform-specific-extensions": "1.1.1", - "babel-plugin-require-context-hook": "1.0.0", "benchmark": "2.1.4", "browserslist": "4.15.0", "chalk": "4.0.0", @@ -262,13 +261,9 @@ "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", "prestorybook:build": "npm run build:packages", - "storybook:build": "build-storybook -c ./storybook -o ./playground/dist", + "storybook:build": "build-storybook -c ./storybook -o ./storybook/build", "prestorybook:dev": "npm run build:packages", "storybook:dev": "concurrently \"npm run dev:packages\" \"start-storybook -c ./storybook -p 50240\"", - "design-system:build": "echo \"Please use storybook:build instead.\"", - "design-system:dev": "echo \"Please use storybook:dev instead.\"", - "playground:build": "npm run storybook:build", - "playground:dev": "echo \"Please use storybook:dev instead.\"", "env": "wp-scripts env", "wp-env": "wp-env" }, diff --git a/packages/block-directory/src/components/downloadable-blocks-list/index.js b/packages/block-directory/src/components/downloadable-blocks-list/index.js index d732b7bc800d5f..377bac14f208de 100644 --- a/packages/block-directory/src/components/downloadable-blocks-list/index.js +++ b/packages/block-directory/src/components/downloadable-blocks-list/index.js @@ -7,6 +7,7 @@ import { noop } from 'lodash'; * WordPress dependencies */ import { useDispatch } from '@wordpress/data'; +import { store as editPostStore } from '@wordpress/edit-post'; /** * Internal dependencies @@ -16,7 +17,7 @@ import { store as blockDirectoryStore } from '../../store'; function DownloadableBlocksList( { items, onHover = noop, onSelect } ) { const { installBlockType } = useDispatch( blockDirectoryStore ); - const { setIsInserterOpened } = useDispatch( 'core/edit-post' ); + const { setIsInserterOpened } = useDispatch( editPostStore ); if ( ! items.length ) { return null; diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index cfadf407b3b655..95611432d3e1bb 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -19,12 +19,12 @@ import { BlockEditorProvider, BlockList, WritingFlow, - ObserveTyping + ObserveTyping, } from '@wordpress/block-editor'; import { SlotFillProvider, Popover } from '@wordpress/components'; import { useState } from '@wordpress/element'; -function MyEditorComponent () { +function MyEditorComponent() { const [ blocks, updateBlocks ] = useState( [] ); return ( @@ -490,7 +490,6 @@ _Properties_ - _hasFixedToolbar_ `boolean`: Whether or not the editor toolbar is fixed - _focusMode_ `boolean`: Whether the focus mode is enabled or not - _styles_ `Array`: Editor Styles -- _isRTL_ `boolean`: Whether the editor is in RTL mode - _keepCaretInsideBlock_ `boolean`: Whether caret should move between blocks in edit mode - _bodyPlaceholder_ `string`: Empty post placeholder - _titlePlaceholder_ `string`: Empty title placeholder @@ -569,6 +568,26 @@ _Related_ - +# **useBlockDisplayInformation** + +Hook used to try to find a matching block variation and return +the appropriate information for display reasons. In order to +to try to find a match we need to things: +1\. Block's client id to extract it's current attributes. +2\. A block variation should have set `isActive` prop to a proper function. + +If for any reason a block variaton match cannot be found, +the returned information come from the Block Type. +If no blockType is found with the provided clientId, returns null. + +_Parameters_ + +- _clientId_ `string`: Block's client id. + +_Returns_ + +- `?WPBlockDisplayInformation`: Block's display information, or `null` when the block or its type not found. + # **useBlockEditContext** Undocumented declaration. diff --git a/packages/block-editor/src/autocompleters/block.js b/packages/block-editor/src/autocompleters/block.js index aa7dfa160ed738..6495956da0dadf 100644 --- a/packages/block-editor/src/autocompleters/block.js +++ b/packages/block-editor/src/autocompleters/block.js @@ -22,18 +22,11 @@ import BlockIcon from '../components/block-icon'; const SHOWN_BLOCK_TYPES = 9; -/** @typedef {import('@wordpress/block-editor').WPEditorInserterItem} WPEditorInserterItem */ - /** @typedef {import('@wordpress/components').WPCompleter} WPCompleter */ /** * Creates a blocks repeater for replacing the current block with a selected block type. * - * @param {Object} props Component props. - * @param {string} [props.getBlockInsertionParentClientId] Client ID of the parent. - * @param {string} [props.getInserterItems] Inserter items for parent. - * @param {string} [props.getSelectedBlockName] Name of selected block or null. - * * @return {WPCompleter} A blocks completer. */ function createBlockCompleter() { diff --git a/packages/block-editor/src/components/alignment-toolbar/index.js b/packages/block-editor/src/components/alignment-toolbar/index.js index 4136f5f7a4c9e3..8eed48b364e480 100644 --- a/packages/block-editor/src/components/alignment-toolbar/index.js +++ b/packages/block-editor/src/components/alignment-toolbar/index.js @@ -6,7 +6,7 @@ import { find } from 'lodash'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, isRTL } from '@wordpress/i18n'; import { ToolbarGroup } from '@wordpress/components'; import { alignLeft, alignRight, alignCenter } from '@wordpress/icons'; @@ -40,7 +40,6 @@ export function AlignmentToolbar( props ) { alignmentControls = DEFAULT_ALIGNMENT_CONTROLS, label = __( 'Change text alignment' ), isCollapsed = true, - isRTL, } = props; function applyOrUnset( align ) { @@ -54,7 +53,7 @@ export function AlignmentToolbar( props ) { function setIcon() { if ( activeAlignment ) return activeAlignment.icon; - return isRTL ? alignRight : alignLeft; + return isRTL() ? alignRight : alignLeft; } return ( diff --git a/packages/block-editor/src/components/block-card/index.js b/packages/block-editor/src/components/block-card/index.js index c209ea39b5c73e..60f8616b5f49dd 100644 --- a/packages/block-editor/src/components/block-card/index.js +++ b/packages/block-editor/src/components/block-card/index.js @@ -1,9 +1,20 @@ +/** + * WordPress dependencies + */ +import deprecated from '@wordpress/deprecated'; + /** * Internal dependencies */ import BlockIcon from '../block-icon'; -function BlockCard( { blockType: { icon, title, description } } ) { +function BlockCard( { title, icon, description, blockType } ) { + if ( blockType ) { + deprecated( '`blockType` property in `BlockCard component`', { + alternative: '`title, icon and description` properties', + } ); + ( { title, icon, description } = blockType ); + } return (
diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index be2433edbe39da..dd6edc46f5be04 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -25,6 +25,8 @@ import BlockStyles from '../block-styles'; import MultiSelectionInspector from '../multi-selection-inspector'; import DefaultStylePicker from '../default-style-picker'; import BlockVariationTransforms from '../block-variation-transforms'; +import useBlockDisplayInformation from '../use-block-display-information'; + const BlockInspector = ( { blockType, count, @@ -64,22 +66,36 @@ const BlockInspector = ( { } return null; } + return ( + + ); +}; +const BlockInspectorSingleBlock = ( { + clientId, + blockName, + hasBlockStyles, + bubblesVirtually, +} ) => { + const blockInformation = useBlockDisplayInformation( clientId ); return (
- - + + { hasBlockStyles && (
- + { hasBlockSupport( - blockType.name, + blockName, 'defaultStylePicker', true - ) && ( - - ) } + ) && }
) } diff --git a/packages/block-editor/src/components/block-list/block-list-item.native.js b/packages/block-editor/src/components/block-list/block-list-item.native.js index 8623514b1b44c2..230b8d720e6b71 100644 --- a/packages/block-editor/src/components/block-list/block-list-item.native.js +++ b/packages/block-editor/src/components/block-list/block-list-item.native.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { View } from 'react-native'; +import { View, Dimensions } from 'react-native'; /** * WordPress dependencies @@ -9,11 +9,7 @@ import { View } from 'react-native'; import { Component } from '@wordpress/element'; import { withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; -import { - ReadableContentView, - WIDE_ALIGNMENTS, - ALIGNMENT_BREAKPOINTS, -} from '@wordpress/components'; +import { ReadableContentView, alignmentHelpers } from '@wordpress/components'; /** * Internal dependencies @@ -26,6 +22,13 @@ const stretchStyle = { flex: 1, }; +const { + isFullWidth, + isWideWidth, + isWider, + isContainerRelated, +} = alignmentHelpers; + export class BlockListItem extends Component { constructor() { super( ...arguments ); @@ -51,39 +54,69 @@ export class BlockListItem extends Component { blockAlignment, marginHorizontal, parentBlockAlignment, + hasParents, + blockName, + parentBlockName, + parentWidth, } = this.props; const { blockWidth } = this.state; - if ( blockAlignment === WIDE_ALIGNMENTS.alignments.full ) { - return 0; + if ( isFullWidth( blockAlignment ) ) { + if ( ! hasParents ) { + return 0; + } + return marginHorizontal; } - - if ( blockAlignment === WIDE_ALIGNMENTS.alignments.wide ) { + if ( isWideWidth( blockAlignment ) ) { return marginHorizontal; } + const screenWidth = Math.floor( Dimensions.get( 'window' ).width ); + if ( - parentBlockAlignment === WIDE_ALIGNMENTS.alignments.full && - blockWidth <= ALIGNMENT_BREAKPOINTS.medium + isFullWidth( parentBlockAlignment ) && + ! isWider( blockWidth, 'medium' ) ) { + if ( + isContainerRelated( blockName ) || + isWider( screenWidth, 'mobile' ) + ) { + return marginHorizontal; + } return marginHorizontal * 2; } + if ( + isContainerRelated( parentBlockName ) && + ! isContainerRelated( blockName ) + ) { + const isScreenWidthEqual = parentWidth === screenWidth; + if ( isScreenWidthEqual || isWider( screenWidth, 'mobile' ) ) { + return marginHorizontal * 2; + } + } + return marginHorizontal; } getContentStyles( readableContentViewStyle ) { - const { blockAlignment, hasParents } = this.props; - const isFullWidth = blockAlignment === WIDE_ALIGNMENTS.alignments.full; + const { + blockAlignment, + blockName, + hasParents, + parentBlockName, + } = this.props; return [ readableContentViewStyle, - isFullWidth && + isFullWidth( blockAlignment ) && ! hasParents && { width: styles.fullAlignment.width, }, - isFullWidth && - hasParents && { + ! blockAlignment && + hasParents && + ! isContainerRelated( parentBlockName ) && + isContainerRelated( blockName ) && { paddingHorizontal: styles.fullAlignmentPadding.paddingLeft, }, ]; @@ -98,15 +131,23 @@ export class BlockListItem extends Component { shouldShowInsertionPointAfter, contentResizeMode, shouldShowInnerBlockAppender, + parentWidth, + marginHorizontal, + blockName, ...restProps } = this.props; const readableContentViewStyle = contentResizeMode === 'stretch' && stretchStyle; - return ( @@ -169,7 +211,7 @@ export default compose( [ const isReadOnly = getSettings().readOnly; const block = __unstableGetBlockWithoutInnerBlocks( clientId ); - const { attributes } = block || {}; + const { attributes, name } = block || {}; const { align } = attributes || {}; const parents = getBlockParents( clientId, true ); const hasParents = !! parents.length; @@ -178,6 +220,7 @@ export default compose( [ : {}; const { align: parentBlockAlignment } = parentBlock?.attributes || {}; + const { name: parentBlockName } = parentBlock || {}; return { shouldShowInsertionPointBefore, @@ -186,6 +229,8 @@ export default compose( [ hasParents, blockAlignment: align, parentBlockAlignment, + blockName: name, + parentBlockName, }; } ), 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 27df35cf3242a3..d07512fca1bd54 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -10,7 +10,7 @@ import { Component, createRef } from '@wordpress/element'; import { GlobalStylesContext, getMergedGlobalStyles, - WIDE_ALIGNMENTS, + alignmentHelpers, } from '@wordpress/components'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose, withPreferredColorScheme } from '@wordpress/compose'; @@ -28,6 +28,8 @@ import BlockEdit from '../block-edit'; import BlockInvalidWarning from './block-invalid-warning'; import BlockMobileToolbar from '../block-mobile-toolbar'; +const { isFullWidth, isWider, isContainerRelated } = alignmentHelpers; + function BlockForType( { attributes, clientId, @@ -122,9 +124,10 @@ class BlockListBlock extends Component { getBlockWidth( { nativeEvent } ) { const { layout } = nativeEvent; const { blockWidth } = this.state; + const layoutWidth = Math.floor( layout.width ); - if ( blockWidth !== layout.width ) { - this.setState( { blockWidth: layout.width } ); + if ( blockWidth !== layoutWidth ) { + this.setState( { blockWidth: layoutWidth } ); } } @@ -166,12 +169,12 @@ class BlockListBlock extends Component { marginVertical, marginHorizontal, isInnerBlockSelected, + name, } = this.props; if ( ! attributes || ! blockType ) { return null; } - const { blockWidth } = this.state; const { align } = attributes; const accessibilityLabel = getAccessibleBlockLabel( @@ -181,8 +184,10 @@ class BlockListBlock extends Component { ); const accessible = ! ( isSelected || isInnerBlockSelected ); - const isFullWidth = align === WIDE_ALIGNMENTS.alignments.full; const screenWidth = Math.floor( Dimensions.get( 'window' ).width ); + const isScreenWidthEqual = blockWidth === screenWidth; + const isScreenWidthWider = blockWidth < screenWidth; + const isFullWidthToolbar = isFullWidth( align ) || isScreenWidthEqual; return ( ) } { isSelected && ( @@ -249,7 +264,7 @@ class BlockListBlock extends Component { } blockWidth={ blockWidth } anchorNodeRef={ this.anchorNodeRef.current } - isFullWidth={ isFullWidth } + isFullWidth={ isFullWidthToolbar } /> ) } diff --git a/packages/block-editor/src/components/block-list/block.native.scss b/packages/block-editor/src/components/block-list/block.native.scss index 62be86ec7662d5..e9ee6b35334f82 100644 --- a/packages/block-editor/src/components/block-list/block.native.scss +++ b/packages/block-editor/src/components/block-list/block.native.scss @@ -23,6 +23,11 @@ right: 0; } +.containerBorderFullWidth { + left: -$solid-border-space / 2; + right: -$solid-border-space / 2; +} + .dimmed { opacity: $dimmed-opacity; } @@ -51,6 +56,11 @@ margin-right: -$block-edge-to-content; } +.containerToolbar { + width: 100%; + align-self: center; +} + .solidBorder { position: absolute; top: -$solid-border-space; diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 9de0481d9332ea..f8f029e04773ac 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -121,6 +121,7 @@ function Items( { value={ ! isBlockInSelection } > 1; + return ( - { showInsertionPoint && ( + { ( showInsertionPoint || + isInserterShown || + isInserterForced ) && (
) } { ( isInserterShown || isInserterForced ) && ( diff --git a/packages/block-editor/src/components/block-list/style.native.scss b/packages/block-editor/src/components/block-list/style.native.scss index 8beb72b50fb309..66436c6592358b 100644 --- a/packages/block-editor/src/components/block-list/style.native.scss +++ b/packages/block-editor/src/components/block-list/style.native.scss @@ -9,11 +9,18 @@ flex-wrap: wrap; justify-content: flex-start; align-items: stretch; - max-width: $content-width; overflow: visible; width: 100%; } +.horizontalContentContainerStretch { + justify-content: space-evenly; +} + +.horizontalContentContainerCenter { + justify-content: center; +} + .switch { flex-direction: row; justify-content: flex-start; diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index 027337857332ff..c8b9a36726d39b 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -394,6 +394,10 @@ left: 0; right: 0; background: var(--wp-admin-theme-color); + + animation: block-editor-inserter__toggle__fade-in-animation 0.3s ease; + animation-fill-mode: forwards; + @include reduce-motion("animation"); } // This is the clickable plus. diff --git a/packages/block-editor/src/components/block-list/subdirectory-icon.js b/packages/block-editor/src/components/block-list/subdirectory-icon.js index 432f545e4524d8..085bc6830bda68 100644 --- a/packages/block-editor/src/components/block-list/subdirectory-icon.js +++ b/packages/block-editor/src/components/block-list/subdirectory-icon.js @@ -2,8 +2,9 @@ * WordPress dependencies */ import { SVG, Path } from '@wordpress/components'; +import { isRTL } from '@wordpress/i18n'; -const Subdirectory = ( { isRTL, ...extraProps } ) => ( +const Subdirectory = ( { ...extraProps } ) => ( ( > ); diff --git a/packages/block-editor/src/components/block-mobile-toolbar/index.native.js b/packages/block-editor/src/components/block-mobile-toolbar/index.native.js index 4faa75b76f04c6..3606e7ba95d123 100644 --- a/packages/block-editor/src/components/block-mobile-toolbar/index.native.js +++ b/packages/block-editor/src/components/block-mobile-toolbar/index.native.js @@ -34,12 +34,28 @@ const BlockMobileToolbar = ( { isFullWidth, } ) => { const [ fillsLength, setFillsLength ] = useState( null ); - const wrapBlockSettings = blockWidth < BREAKPOINTS.wrapSettings; - const wrapBlockMover = blockWidth <= BREAKPOINTS.wrapMover; + const [ appenderWidth, setAppenderWidth ] = useState( 0 ); + const spacingValue = styles.toolbar.marginLeft * 2; + + function onLayout( { nativeEvent } ) { + const { layout } = nativeEvent; + const layoutWidth = Math.floor( layout.width ); + if ( layoutWidth !== appenderWidth ) { + setAppenderWidth( nativeEvent.layout.width ); + } + } + + const wrapBlockSettings = + blockWidth < BREAKPOINTS.wrapSettings || + appenderWidth - spacingValue < BREAKPOINTS.wrapSettings; + const wrapBlockMover = + blockWidth <= BREAKPOINTS.wrapMover || + appenderWidth - spacingValue <= BREAKPOINTS.wrapMover; return ( { ! wrapBlockMover && ( { +const getArrowIcon = ( direction, orientation ) => { if ( direction === 'up' ) { if ( orientation === 'horizontal' ) { - return isRTL ? chevronRight : chevronLeft; + return isRTL() ? chevronRight : chevronLeft; } return chevronUp; } else if ( direction === 'down' ) { if ( orientation === 'horizontal' ) { - return isRTL ? chevronLeft : chevronRight; + return isRTL() ? chevronLeft : chevronRight; } return chevronDown; } return null; }; -const getMovementDirectionLabel = ( moveDirection, orientation, isRTL ) => { +const getMovementDirectionLabel = ( moveDirection, orientation ) => { if ( moveDirection === 'up' ) { if ( orientation === 'horizontal' ) { - return isRTL ? __( 'Move right' ) : __( 'Move left' ); + return isRTL() ? __( 'Move right' ) : __( 'Move left' ); } return __( 'Move up' ); } else if ( moveDirection === 'down' ) { if ( orientation === 'horizontal' ) { - return isRTL ? __( 'Move left' ) : __( 'Move right' ); + return isRTL() ? __( 'Move left' ) : __( 'Move right' ); } return __( 'Move down' ); } @@ -70,7 +70,6 @@ const BlockMoverButton = forwardRef( isFirst, isLast, firstIndex, - isRTL, orientation = 'vertical', } = useSelect( ( select ) => { @@ -79,7 +78,6 @@ const BlockMoverButton = forwardRef( getBlockRootClientId, getBlockOrder, getBlock, - getSettings, getBlockListSettings, } = select( 'core/block-editor' ); const normalizedClientIds = castArray( clientIds ); @@ -107,7 +105,6 @@ const BlockMoverButton = forwardRef( firstIndex: firstBlockIndex, isFirst: isFirstBlock, isLast: isLastBlock, - isRTL: getSettings().isRTL, orientation: moverOrientation || blockListOrientation, }; }, @@ -137,11 +134,10 @@ const BlockMoverButton = forwardRef( 'block-editor-block-mover-button', `is-${ direction }-button` ) } - icon={ getArrowIcon( direction, orientation, isRTL ) } + icon={ getArrowIcon( direction, orientation ) } label={ getMovementDirectionLabel( direction, - orientation, - isRTL + orientation ) } aria-describedby={ descriptionId } { ...props } @@ -159,8 +155,7 @@ const BlockMoverButton = forwardRef( isFirst, isLast, direction === 'up' ? -1 : 1, - orientation, - isRTL + orientation ) } diff --git a/packages/block-editor/src/components/block-mover/index.native.js b/packages/block-editor/src/components/block-mover/index.native.js index aa1892c33e8042..d64509ff17726e 100644 --- a/packages/block-editor/src/components/block-mover/index.native.js +++ b/packages/block-editor/src/components/block-mover/index.native.js @@ -2,29 +2,52 @@ * External dependencies */ import { first, last, partial, castArray } from 'lodash'; +import { Platform } from 'react-native'; /** * WordPress dependencies */ -import { ToolbarButton } from '@wordpress/components'; -import { withSelect, withDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { Picker, ToolbarButton } from '@wordpress/components'; import { withInstanceId, compose } from '@wordpress/compose'; +import { withSelect, withDispatch } from '@wordpress/data'; +import { useRef, useState } from '@wordpress/element'; /** * Internal dependencies */ import { getMoversSetup } from './mover-description'; -const BlockMover = ( { +export const BLOCK_MOVER_DIRECTION_TOP = 'blockPageMoverOptions-moveToTop'; +export const BLOCK_MOVER_DIRECTION_BOTTOM = + 'blockPageMoverOptions-moveToBottom'; + +export const BlockMover = ( { isFirst, isLast, isLocked, onMoveDown, onMoveUp, + onLongMove, firstIndex, + numberOfBlocks, rootClientId, isStackedHorizontally, } ) => { + const pickerRef = useRef(); + const [ blockPageMoverState, setBlockPageMoverState ] = useState( + undefined + ); + const showBlockPageMover = ( direction ) => () => { + if ( ! pickerRef.current ) { + setBlockPageMoverState( undefined ); + return; + } + + setBlockPageMoverState( direction ); + pickerRef.current.presentPicker(); + }; + const { description: { backwardButtonHint, @@ -36,6 +59,32 @@ const BlockMover = ( { title: { backward: backwardButtonTitle, forward: forwardButtonTitle }, } = getMoversSetup( isStackedHorizontally, { firstIndex } ); + const blockPageMoverOptions = [ + { + icon: backwardButtonIcon, + label: __( 'Move to top' ), + value: BLOCK_MOVER_DIRECTION_TOP, + onSelect: () => { + onLongMove()( 0 ); + }, + }, + { + icon: forwardButtonIcon, + label: __( 'Move to bottom' ), + value: BLOCK_MOVER_DIRECTION_BOTTOM, + onSelect: () => { + onLongMove()( numberOfBlocks ); + }, + }, + ].filter( ( el ) => el.value === blockPageMoverState ); + + const onPickerSelect = ( value ) => { + const option = blockPageMoverOptions.find( + ( el ) => el.value === value + ); + if ( option && option.onSelect ) option.onSelect(); + }; + if ( isLocked || ( isFirst && isLast && ! rootClientId ) ) { return null; } @@ -46,6 +95,7 @@ const BlockMover = ( { title={ ! isFirst ? backwardButtonTitle : firstBlockTitle } isDisabled={ isFirst } onClick={ onMoveUp } + onLongPress={ showBlockPageMover( BLOCK_MOVER_DIRECTION_TOP ) } icon={ backwardButtonIcon } extraProps={ { hint: backwardButtonHint } } /> @@ -54,11 +104,23 @@ const BlockMover = ( { title={ ! isLast ? forwardButtonTitle : lastBlockTitle } isDisabled={ isLast } onClick={ onMoveDown } + onLongPress={ showBlockPageMover( + BLOCK_MOVER_DIRECTION_BOTTOM + ) } icon={ forwardButtonIcon } extraProps={ { hint: forwardButtonHint, } } /> + + ); }; @@ -83,6 +145,7 @@ export default compose( return { firstIndex, + numberOfBlocks: blockOrder.length - 1, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, isLocked: getTemplateLock( rootClientId ) === 'all', @@ -90,12 +153,19 @@ export default compose( }; } ), withDispatch( ( dispatch, { clientIds, rootClientId } ) => { - const { moveBlocksDown, moveBlocksUp } = dispatch( + const { moveBlocksDown, moveBlocksUp, moveBlocksToPosition } = dispatch( 'core/block-editor' ); return { onMoveDown: partial( moveBlocksDown, clientIds, rootClientId ), onMoveUp: partial( moveBlocksUp, clientIds, rootClientId ), + onLongMove: ( targetIndex ) => + partial( + moveBlocksToPosition, + clientIds, + rootClientId, + targetIndex + ), }; } ), withInstanceId 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 fbdc10cb256138..c84a99469980fc 100644 --- a/packages/block-editor/src/components/block-mover/mover-description.js +++ b/packages/block-editor/src/components/block-mover/mover-description.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { __, _n, sprintf } from '@wordpress/i18n'; +import { __, _n, sprintf, isRTL } from '@wordpress/i18n'; /** * Return a label for the block movement controls depending on block position. @@ -16,7 +16,6 @@ import { __, _n, sprintf } from '@wordpress/i18n'; * 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. */ @@ -27,20 +26,19 @@ export function getBlockMoverDescription( isFirst, isLast, dir, - orientation, - isRTL + orientation ) { const position = firstIndex + 1; const getMovementDirection = ( moveDirection ) => { if ( moveDirection === 'up' ) { if ( orientation === 'horizontal' ) { - return isRTL ? 'right' : 'left'; + return isRTL() ? 'right' : 'left'; } return 'up'; } else if ( moveDirection === 'down' ) { if ( orientation === 'horizontal' ) { - return isRTL ? 'left' : 'right'; + return isRTL() ? 'left' : 'right'; } return 'down'; } diff --git a/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap b/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap new file mode 100644 index 00000000000000..65269234f413f3 --- /dev/null +++ b/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Block Mover Picker should match snapshot 1`] = ` + + + + + } + onLongPress={[Function]} + title="Move block up from row NaN to row NaN" + /> + + + + } + onLongPress={[Function]} + title="Move block down from row NaN to row NaN" + /> + + +`; diff --git a/packages/block-editor/src/components/block-mover/test/index.native.js b/packages/block-editor/src/components/block-mover/test/index.native.js new file mode 100644 index 00000000000000..113d61e84cf254 --- /dev/null +++ b/packages/block-editor/src/components/block-mover/test/index.native.js @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import { BlockMover } from '../index'; + +describe( 'Block Mover Picker', () => { + it( 'renders without crashing', () => { + const wrapper = shallow( , { + context: { + isFirst: false, + isLast: true, + isLocked: false, + numberOfBlocks: 2, + firstIndex: 1, + + onMoveDown: jest.fn(), + onMoveUp: jest.fn(), + onLongPress: jest.fn(), + + rootClientId: '', + isStackedHorizontally: true, + }, + } ); + expect( wrapper ).toBeTruthy(); + } ); + + it( 'should match snapshot', () => { + const wrapper = shallow( , { + context: { + isFirst: false, + isLast: true, + isLocked: false, + numberOfBlocks: 2, + firstIndex: 1, + + onMoveDown: jest.fn(), + onMoveUp: jest.fn(), + onLongPress: jest.fn(), + + rootClientId: '', + isStackedHorizontally: true, + }, + } ); + expect( wrapper ).toMatchSnapshot(); + } ); +} ); diff --git a/packages/block-editor/src/components/block-navigation/block-select-button.js b/packages/block-editor/src/components/block-navigation/block-select-button.js index 2e9956d5387e18..e6f40a1ed62092 100644 --- a/packages/block-editor/src/components/block-navigation/block-select-button.js +++ b/packages/block-editor/src/components/block-navigation/block-select-button.js @@ -19,12 +19,13 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import BlockIcon from '../block-icon'; +import useBlockDisplayInformation from '../use-block-display-information'; import { getBlockPositionDescription } from './utils'; function BlockNavigationBlockSelectButton( { className, - block, + block: { clientId, name, attributes }, isSelected, onClick, position, @@ -38,12 +39,15 @@ function BlockNavigationBlockSelectButton( }, ref ) { - const { name, attributes } = block; - - const blockType = getBlockType( name ); - const blockDisplayName = getBlockLabel( blockType, attributes ); + const blockInformation = useBlockDisplayInformation( clientId ); const instanceId = useInstanceId( BlockNavigationBlockSelectButton ); const descriptionId = `block-navigation-block-select-button__${ instanceId }`; + const blockType = getBlockType( name ); + const blockLabel = getBlockLabel( blockType, attributes ); + // If label is defined we prioritize it over possible possible + // block variation match title. + const blockDisplayName = + blockLabel !== blockType.title ? blockLabel : blockInformation?.title; const blockPositionDescription = getBlockPositionDescription( position, siblingBlockCount, @@ -66,7 +70,7 @@ function BlockNavigationBlockSelectButton( onDragEnd={ onDragEnd } draggable={ draggable } > - + { blockDisplayName } { isSelected && ( diff --git a/packages/block-editor/src/components/block-patterns-list/index.js b/packages/block-editor/src/components/block-patterns-list/index.js index 140c0a4feb9718..2dc6eb7c86d536 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -11,37 +11,53 @@ import { useInstanceId } from '@wordpress/compose'; * Internal dependencies */ import BlockPreview from '../block-preview'; +import InserterDraggableBlocks from '../inserter-draggable-blocks'; -function BlockPattern( { pattern, onClick } ) { +function BlockPattern( { isDraggable, pattern, onClick } ) { const { content, viewportWidth } = pattern; const blocks = useMemo( () => parse( content ), [ content ] ); const instanceId = useInstanceId( BlockPattern ); const descriptionId = `block-editor-block-patterns-list__item-description-${ instanceId }`; return ( -
onClick( pattern, blocks ) } - onKeyDown={ ( event ) => { - if ( ENTER === event.keyCode || SPACE === event.keyCode ) { - onClick( pattern, blocks ); - } - } } - tabIndex={ 0 } - aria-label={ pattern.title } - aria-describedby={ pattern.description ? descriptionId : undefined } - > - -
- { pattern.title } -
- { !! pattern.description && ( - - { pattern.description } - + + { ( { draggable, onDragStart, onDragEnd } ) => ( +
onClick( pattern, blocks ) } + onKeyDown={ ( event ) => { + if ( + ENTER === event.keyCode || + SPACE === event.keyCode + ) { + onClick( pattern, blocks ); + } + } } + tabIndex={ 0 } + aria-label={ pattern.title } + aria-describedby={ + pattern.description ? descriptionId : undefined + } + draggable={ draggable } + onDragStart={ onDragStart } + onDragEnd={ onDragEnd } + > + +
+ { pattern.title } +
+ { !! pattern.description && ( + + { pattern.description } + + ) } +
) } -
+ ); } @@ -51,7 +67,12 @@ function BlockPatternPlaceholder() { ); } -function BlockPatternList( { blockPatterns, shownPatterns, onClickPattern } ) { +function BlockPatternList( { + isDraggable, + blockPatterns, + shownPatterns, + onClickPattern, +} ) { return blockPatterns.map( ( pattern ) => { const isShown = shownPatterns.includes( pattern ); return isShown ? ( @@ -59,6 +80,7 @@ function BlockPatternList( { blockPatterns, shownPatterns, onClickPattern } ) { key={ pattern.name } pattern={ pattern } onClick={ onClickPattern } + isDraggable={ isDraggable } /> ) : ( diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index f66019261d0b40..9eb0f52acab721 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -21,6 +21,10 @@ &.is-placeholder { min-height: 100px; } + + &[draggable="true"] .block-editor-block-preview__container { + cursor: grab; + } } .block-editor-block-patterns-list__item-title { diff --git a/packages/block-editor/src/components/block-selection-clearer/index.js b/packages/block-editor/src/components/block-selection-clearer/index.js index 3806dae48d29dd..8501d3179eacd1 100644 --- a/packages/block-editor/src/components/block-selection-clearer/index.js +++ b/packages/block-editor/src/components/block-selection-clearer/index.js @@ -19,19 +19,14 @@ export function useBlockSelectionClearer( ref ) { return; } - function onMouseDown( event ) { - // Only handle clicks on the canvas, not the content. - if ( event.target.closest( '.wp-block' ) ) { - return; - } - + function onFocus() { clearSelectedBlock(); } - ref.current.addEventListener( 'mousedown', onMouseDown ); + ref.current.addEventListener( 'focus', onFocus ); return () => { - ref.current.removeEventListener( 'mousedown', onMouseDown ); + ref.current.removeEventListener( 'focus', onFocus ); }; }, [ hasSelection, clearSelectedBlock ] ); } @@ -39,5 +34,5 @@ export function useBlockSelectionClearer( ref ) { export default function BlockSelectionClearer( props ) { const ref = useRef(); useBlockSelectionClearer( ref ); - return
; + return
; } diff --git a/packages/block-editor/src/components/block-switcher/block-styles-menu.js b/packages/block-editor/src/components/block-switcher/block-styles-menu.js new file mode 100644 index 00000000000000..7ca6336c5f9176 --- /dev/null +++ b/packages/block-editor/src/components/block-switcher/block-styles-menu.js @@ -0,0 +1,56 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { MenuGroup } from '@wordpress/components'; +import { useState } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { cloneBlock, getBlockFromExample } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import BlockStyles from '../block-styles'; +import PreviewBlockPopover from './preview-block-popover'; + +export default function BlockStylesMenu( { + hoveredBlock: { name, clientId }, + onSwitch, +} ) { + const [ hoveredClassName, setHoveredClassName ] = useState(); + const blockType = useSelect( + ( select ) => select( 'core/blocks' ).getBlockType( name ), + [ name ] + ); + + return ( + + { hoveredClassName && ( + + ) } + + + ); +} diff --git a/packages/block-editor/src/components/block-switcher/block-transformations-menu.js b/packages/block-editor/src/components/block-switcher/block-transformations-menu.js index fb70c053dac781..49f1d3044ee791 100644 --- a/packages/block-editor/src/components/block-switcher/block-transformations-menu.js +++ b/packages/block-editor/src/components/block-switcher/block-transformations-menu.js @@ -3,22 +3,40 @@ */ import { __ } from '@wordpress/i18n'; import { MenuGroup, MenuItem } from '@wordpress/components'; -import { getBlockMenuDefaultClassName } from '@wordpress/blocks'; +import { + getBlockMenuDefaultClassName, + switchToBlockType, +} from '@wordpress/blocks'; +import { useState } from '@wordpress/element'; /** * Internal dependencies */ import BlockIcon from '../block-icon'; +import PreviewBlockPopover from './preview-block-popover'; const BlockTransformationsMenu = ( { className, possibleBlockTransformations, onSelect, + blocks, } ) => { + const [ + hoveredTransformItemName, + setHoveredTransformItemName, + ] = useState(); return ( + { hoveredTransformItemName && ( + + ) } { possibleBlockTransformations.map( ( item ) => { - const { name, icon, title } = item; + const { name, icon, title, isDisabled } = item; return ( + setHoveredTransformItemName( null ) + } + onMouseEnter={ () => + setHoveredTransformItemName( name ) + } > { title } diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js index 7ebb59c16cda30..9428084a21c57b 100644 --- a/packages/block-editor/src/components/block-switcher/index.js +++ b/packages/block-editor/src/components/block-switcher/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { castArray, filter, mapKeys, orderBy, uniq, map } from 'lodash'; +import { castArray, uniq } from 'lodash'; /** * WordPress dependencies @@ -12,252 +12,144 @@ import { ToolbarButton, ToolbarGroup, ToolbarItem, - MenuGroup, - Popover, } from '@wordpress/components'; -import { - getBlockType, - getPossibleBlockTransformations, - switchToBlockType, - cloneBlock, - getBlockFromExample, - store as blocksStore, -} from '@wordpress/blocks'; -import { Component } from '@wordpress/element'; -import { withSelect, withDispatch } from '@wordpress/data'; -import { compose } from '@wordpress/compose'; +import { switchToBlockType, store as blocksStore } from '@wordpress/blocks'; +import { useSelect, useDispatch } from '@wordpress/data'; import { stack } from '@wordpress/icons'; /** * Internal dependencies */ import BlockIcon from '../block-icon'; -import BlockStyles from '../block-styles'; -import BlockPreview from '../block-preview'; import BlockTransformationsMenu from './block-transformations-menu'; +import BlockStylesMenu from './block-styles-menu'; -function PreviewBlockPopover( { hoveredBlock, hoveredClassName } ) { - const hoveredBlockType = getBlockType( hoveredBlock.name ); - return ( -
-
- -
-
- { __( 'Preview' ) } -
- -
-
-
-
+const BlockSwitcher = ( { clientIds } ) => { + const { replaceBlocks } = useDispatch( 'core/block-editor' ); + const { + blocks, + possibleBlockTransformations, + hasBlockStyles, + icon, + } = useSelect( + ( select ) => { + const { + getBlocksByClientId, + getBlockRootClientId, + getBlockTransformItems, + } = select( 'core/block-editor' ); + const { getBlockStyles, getBlockType } = select( blocksStore ); + const rootClientId = getBlockRootClientId( + castArray( clientIds )[ 0 ] + ); + const _blocks = getBlocksByClientId( clientIds ); + const isSingleBlockSelected = _blocks?.length === 1; + const firstBlock = !! _blocks?.length ? _blocks[ 0 ] : null; + const styles = + isSingleBlockSelected && getBlockStyles( firstBlock.name ); + // When selection consists of blocks of multiple types, display an + // appropriate icon to communicate the non-uniformity. + const isSelectionOfSameType = + uniq( ( _blocks || [] ).map( ( { name } ) => name ) ).length === + 1; + return { + blocks: _blocks, + possibleBlockTransformations: + _blocks && getBlockTransformItems( _blocks, rootClientId ), + hasBlockStyles: !! styles?.length, + icon: isSelectionOfSameType + ? getBlockType( firstBlock.name )?.icon + : stack, + }; + }, + [ clientIds ] ); -} - -export class BlockSwitcher extends Component { - constructor() { - super( ...arguments ); - this.state = { - hoveredClassName: null, - }; - this.onHoverClassName = this.onHoverClassName.bind( this ); - } - - onHoverClassName( className ) { - this.setState( { hoveredClassName: className } ); - } - - render() { - const { - blocks, - onTransform, - inserterItems, - hasBlockStyles, - } = this.props; - const { hoveredClassName } = this.state; - - if ( ! Array.isArray( blocks ) || ! blocks.length ) { - return null; - } - - const [ hoveredBlock ] = blocks; - const itemsByName = mapKeys( inserterItems, ( { name } ) => name ); - const possibleBlockTransformations = orderBy( - filter( - getPossibleBlockTransformations( blocks ), - ( block ) => block && !! itemsByName[ block.name ] - ), - ( block ) => itemsByName[ block.name ].frecency, - 'desc' - ); - - // When selection consists of blocks of multiple types, display an - // appropriate icon to communicate the non-uniformity. - const isSelectionOfSameType = - uniq( map( blocks, 'name' ) ).length === 1; - let icon; - if ( isSelectionOfSameType ) { - const sourceBlockName = hoveredBlock.name; - const blockType = getBlockType( sourceBlockName ); - icon = blockType.icon; - } else { - icon = stack; - } + if ( ! blocks?.length ) return null; - const hasPossibleBlockTransformations = !! possibleBlockTransformations.length; - - if ( ! hasBlockStyles && ! hasPossibleBlockTransformations ) { - return ( - - } - /> - - ); - } - - const blockSwitcherLabel = - 1 === blocks.length - ? __( 'Change block type or style' ) - : sprintf( - /* translators: %s: number of blocks. */ - _n( - 'Change type of %d block', - 'Change type of %d blocks', - blocks.length - ), - blocks.length - ); + const onTransform = ( name ) => + replaceBlocks( clientIds, switchToBlockType( blocks, name ) ); + const hasPossibleBlockTransformations = !! possibleBlockTransformations.length; + if ( ! hasBlockStyles && ! hasPossibleBlockTransformations ) { return ( - - { ( toggleProps ) => ( - - } - toggleProps={ toggleProps } - menuProps={ { orientation: 'both' } } - > - { ( { onClose } ) => - ( hasBlockStyles || - hasPossibleBlockTransformations ) && ( -
- { hasPossibleBlockTransformations && ( - { - onTransform( blocks, name ); - onClose(); - } } - /> - ) } - { hasBlockStyles && ( - - { hoveredClassName !== null && ( - - ) } - - - ) } -
- ) - } -
- ) } -
+ } + />
); } -} -export default compose( - withSelect( ( select, { clientIds } ) => { - const { - getBlocksByClientId, - getBlockRootClientId, - getInserterItems, - } = select( 'core/block-editor' ); - const { getBlockStyles } = select( blocksStore ); - const rootClientId = getBlockRootClientId( - castArray( clientIds )[ 0 ] - ); - const blocks = getBlocksByClientId( clientIds ); - const firstBlock = blocks && blocks.length === 1 ? blocks[ 0 ] : null; - const styles = firstBlock && getBlockStyles( firstBlock.name ); - return { - blocks, - inserterItems: getInserterItems( rootClientId ), - hasBlockStyles: styles && styles.length > 0, - }; - } ), - withDispatch( ( dispatch, ownProps ) => ( { - onTransform( blocks, name ) { - dispatch( 'core/block-editor' ).replaceBlocks( - ownProps.clientIds, - switchToBlockType( blocks, name ) - ); - }, - } ) ) -)( BlockSwitcher ); + const blockSwitcherLabel = + 1 === blocks.length + ? __( 'Change block type or style' ) + : sprintf( + /* translators: %s: number of blocks. */ + _n( + 'Change type of %d block', + 'Change type of %d blocks', + blocks.length + ), + blocks.length + ); + + return ( + + + { ( toggleProps ) => ( + + } + toggleProps={ toggleProps } + menuProps={ { orientation: 'both' } } + > + { ( { onClose } ) => + ( hasBlockStyles || + hasPossibleBlockTransformations ) && ( +
+ { hasPossibleBlockTransformations && ( + { + onTransform( name ); + onClose(); + } } + /> + ) } + { hasBlockStyles && ( + + ) } +
+ ) + } +
+ ) } +
+
+ ); +}; + +export default BlockSwitcher; diff --git a/packages/block-editor/src/components/block-switcher/preview-block-popover.js b/packages/block-editor/src/components/block-switcher/preview-block-popover.js new file mode 100644 index 00000000000000..53adb87f337ad7 --- /dev/null +++ b/packages/block-editor/src/components/block-switcher/preview-block-popover.js @@ -0,0 +1,31 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Popover } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import BlockPreview from '../block-preview'; + +export default function PreviewBlockPopover( { blocks } ) { + return ( +
+
+ +
+
+ { __( 'Preview' ) } +
+ +
+
+
+
+ ); +} diff --git a/packages/block-editor/src/components/block-switcher/test/index.js b/packages/block-editor/src/components/block-switcher/test/index.js index a5879995c271d2..b18f72b4d59385 100644 --- a/packages/block-editor/src/components/block-switcher/test/index.js +++ b/packages/block-editor/src/components/block-switcher/test/index.js @@ -6,14 +6,18 @@ import { shallow, mount } from 'enzyme'; /** * WordPress dependencies */ +import { useSelect } from '@wordpress/data'; import { registerBlockType, unregisterBlockType } from '@wordpress/blocks'; import { DOWN } from '@wordpress/keycodes'; import { Button } from '@wordpress/components'; +import { stack } from '@wordpress/icons'; /** * Internal dependencies */ -import { BlockSwitcher } from '../'; +import BlockSwitcher from '../'; + +jest.mock( '@wordpress/data/src/components/use-select', () => jest.fn() ); describe( 'BlockSwitcher', () => { const headingBlock1 = { @@ -94,75 +98,55 @@ describe( 'BlockSwitcher', () => { } ); test( 'should not render block switcher without blocks', () => { + useSelect.mockImplementation( () => ( {} ) ); const wrapper = shallow( ); - expect( wrapper.html() ).toBeNull(); } ); test( 'should render switcher with blocks', () => { - const blocks = [ headingBlock1 ]; - const inserterItems = [ - { name: 'core/heading', frecency: 1 }, - { name: 'core/paragraph', frecency: 1 }, - ]; - - const wrapper = shallow( - - ); - + useSelect.mockImplementation( () => ( { + blocks: [ headingBlock1 ], + possibleBlockTransformations: [ + { name: 'core/heading', frecency: 1 }, + { name: 'core/paragraph', frecency: 1 }, + ], + } ) ); + const wrapper = shallow( ); expect( wrapper ).toMatchSnapshot(); } ); test( 'should render disabled block switcher with multi block of different types when no transforms', () => { - const blocks = [ headingBlock1, textBlock ]; - const inserterItems = [ - { name: 'core/heading', frecency: 1 }, - { name: 'core/paragraph', frecency: 1 }, - ]; - - const wrapper = shallow( - - ); - + useSelect.mockImplementation( () => ( { + blocks: [ headingBlock1, textBlock ], + possibleBlockTransformations: [], + icon: stack, + } ) ); + const wrapper = shallow( ); expect( wrapper ).toMatchSnapshot(); } ); test( 'should render enabled block switcher with multi block when transforms exist', () => { - const blocks = [ headingBlock1, headingBlock2 ]; - const inserterItems = [ - { name: 'core/heading', frecency: 1 }, - { name: 'core/paragraph', frecency: 1 }, - ]; - - const wrapper = shallow( - - ); - + useSelect.mockImplementation( () => ( { + blocks: [ headingBlock1, headingBlock2 ], + possibleBlockTransformations: [ + { name: 'core/heading', frecency: 1 }, + { name: 'core/paragraph', frecency: 1 }, + ], + } ) ); + const wrapper = shallow( ); expect( wrapper ).toMatchSnapshot(); } ); describe( 'Dropdown', () => { - const blocks = [ headingBlock1 ]; - - const inserterItems = [ - { name: 'core/quote', frecency: 1 }, - { name: 'core/cover-image', frecency: 2 }, - { name: 'core/paragraph', frecency: 3 }, - { name: 'core/heading', frecency: 4 }, - { name: 'core/text', frecency: 5 }, - ]; - - const onTransformStub = jest.fn(); - const getDropdown = () => { - const blockSwitcher = mount( - - ); - return blockSwitcher.find( 'Dropdown' ); - }; + beforeAll( () => { + useSelect.mockImplementation( () => ( { + blocks: [ headingBlock1 ], + possibleBlockTransformations: [ + { name: 'core/paragraph', frecency: 3 }, + ], + } ) ); + } ); + const getDropdown = () => mount( ).find( 'Dropdown' ); test( 'should dropdown exist', () => { expect( getDropdown() ).toHaveLength( 1 ); diff --git a/packages/block-editor/src/components/block-title/index.js b/packages/block-editor/src/components/block-title/index.js index 3a36d53e12e17c..c7701527e07a09 100644 --- a/packages/block-editor/src/components/block-title/index.js +++ b/packages/block-editor/src/components/block-title/index.js @@ -12,6 +12,11 @@ import { __experimentalGetBlockLabel as getBlockLabel, } from '@wordpress/blocks'; +/** + * Internal dependencies + */ +import useBlockDisplayInformation from '../use-block-display-information'; + /** * Renders the block's configured title as a string, or empty if the title * cannot be determined. @@ -44,22 +49,16 @@ export default function BlockTitle( { clientId } ) { [ clientId ] ); - if ( ! name ) { - return null; - } - + const blockInformation = useBlockDisplayInformation( clientId ); + if ( ! name || ! blockInformation ) return null; const blockType = getBlockType( name ); - if ( ! blockType ) { - return null; - } - - const { title } = blockType; const label = getBlockLabel( blockType, attributes ); - - // Label will often fall back to the title if no label is defined for the + // Label will fallback to the title if no label is defined for the // current label context. We do not want "Paragraph: Paragraph". - if ( label !== title ) { - return `${ title }: ${ truncate( label, { length: 15 } ) }`; + // If label is defined we prioritize it over possible possible + // block variation match title. + if ( label !== blockType.title ) { + return `${ blockType.title }: ${ truncate( label, { length: 15 } ) }`; } - return title; + return blockInformation.title; } diff --git a/packages/block-editor/src/components/block-title/test/index.js b/packages/block-editor/src/components/block-title/test/index.js index d268699d09668d..23af6288130e01 100644 --- a/packages/block-editor/src/components/block-title/test/index.js +++ b/packages/block-editor/src/components/block-title/test/index.js @@ -45,6 +45,15 @@ jest.mock( '@wordpress/blocks', () => { }; } ); +jest.mock( '../../use-block-display-information', () => { + const resultsMap = { + 'id-name-exists': { title: 'Block Title' }, + 'id-name-with-label': { title: 'Block With Label' }, + 'id-name-with-long-label': { title: 'Block With Long Label' }, + }; + return jest.fn( ( clientId ) => resultsMap[ clientId ] ); +} ); + jest.mock( '@wordpress/data/src/components/use-select', () => { // This allows us to tweak the returned value on each test const mock = jest.fn(); @@ -81,9 +90,7 @@ describe( 'BlockTitle', () => { attributes: null, } ) ); - const wrapper = shallow( - - ); + const wrapper = shallow( ); expect( wrapper.text() ).toBe( 'Block Title' ); } ); @@ -94,9 +101,7 @@ describe( 'BlockTitle', () => { attributes: null, } ) ); - const wrapper = shallow( - - ); + const wrapper = shallow( ); expect( wrapper.text() ).toBe( 'Block With Label: Test Label' ); } ); @@ -108,7 +113,7 @@ describe( 'BlockTitle', () => { } ) ); const wrapper = shallow( - + ); expect( wrapper.text() ).toBe( diff --git a/packages/block-editor/src/components/contrast-checker/README.md b/packages/block-editor/src/components/contrast-checker/README.md new file mode 100644 index 00000000000000..b663b63fac5142 --- /dev/null +++ b/packages/block-editor/src/components/contrast-checker/README.md @@ -0,0 +1,73 @@ +# ContrastChecker + +ContrastChecker component determines if contrast for text styles is sufficient (WCAG 2.0 AA) when used with a given background color. ContrastCheker also accounts for background color transparency (alpha) as well as font sizes. + +A notice will be rendered if the color combination of text and background colors are low. + +## Table of contents + +1. [Development guidelines](#development-guidelines) + +## Developer guidelines + +### Usage + +Checks the contrast of a `13px` dark gray font against a light gray background. + +```jsx +import { ContrastChecker } from '@wordpress/block-editor'; + +const Example = () => { + return ( + + ); +}; +``` + +### Props + +#### backgroundColor + +The background color to check the contrast of text against. + +- Type: `String` +- Required: No + +#### fallbackBackgroundColor + +A fallback background color value, in case `backgroundColor` is not available. + +- Type: `String` +- Required: No + +#### fallbackTextColor + +A fallback text color value, in case `textColor` is not available. + +- Type: `String` +- Required: No + +#### fontSize + +The font-size (as a `px` value) of the text to check the contrast against. + +- Type: `Number` +- Required: No + +#### isLargeText + +Whether the text is large (approximately `24px` or higher). + +- Type: `Boolean` +- Required: No + +#### textColor + +The text color to check the contrast of the background against. + +- Type: `String` +- Required: No diff --git a/packages/block-editor/src/components/floating-toolbar/nav-up-icon.js b/packages/block-editor/src/components/floating-toolbar/nav-up-icon.js index 029b667dfb498c..15634076d17b00 100644 --- a/packages/block-editor/src/components/floating-toolbar/nav-up-icon.js +++ b/packages/block-editor/src/components/floating-toolbar/nav-up-icon.js @@ -2,8 +2,9 @@ * WordPress dependencies */ import { SVG, Path } from '@wordpress/components'; +import { isRTL } from '@wordpress/i18n'; -const NavigateUp = ( { isRTL } ) => ( +const NavigateUp = () => ( ( fillRule="evenodd" clipRule="evenodd" d="M17,11 z L15.58,12.42 L12,8.83 L12,18 L22,18 L22,20 L10,20 L10,8.83 L6.42,12.42 L5,11 L11,5 L17,11" - transform={ isRTL ? 'scale(-1,1) translate(-24,0)' : undefined } + transform={ isRTL() ? 'scale(-1,1) translate(-24,0)' : undefined } /> ); diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 3e845204bed823..551f83f8b4d663 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -118,6 +118,7 @@ export { export { default as Warning } from './warning'; export { default as WritingFlow } from './writing-flow'; export { useCanvasClickRedirect as __unstableUseCanvasClickRedirect } from './use-canvas-click-redirect'; +export { default as useBlockDisplayInformation } from './use-block-display-information'; /* * State Related Components 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 db5ed47ecfb17d..aa9646bcad84ac 100644 --- a/packages/block-editor/src/components/inner-blocks/index.native.js +++ b/packages/block-editor/src/components/inner-blocks/index.native.js @@ -50,6 +50,7 @@ function UncontrolledInnerBlocks( props ) { marginHorizontal, horizontalAlignment, filterInnerBlocks, + blockWidth, __experimentalLayout: layout = defaultLayout, } = props; @@ -84,6 +85,7 @@ function UncontrolledInnerBlocks( props ) { onAddBlock={ onAddBlock } onDeleteBlock={ onDeleteBlock } filterInnerBlocks={ filterInnerBlocks } + blockWidth={ blockWidth } /> ); diff --git a/packages/block-editor/src/components/inserter-list-item/draggable.js b/packages/block-editor/src/components/inserter-draggable-blocks/index.js similarity index 84% rename from packages/block-editor/src/components/inserter-list-item/draggable.js rename to packages/block-editor/src/components/inserter-draggable-blocks/index.js index 92539d62666452..5d01ecc02515bc 100644 --- a/packages/block-editor/src/components/inserter-list-item/draggable.js +++ b/packages/block-editor/src/components/inserter-draggable-blocks/index.js @@ -7,7 +7,7 @@ import { Draggable } from '@wordpress/components'; */ import BlockDraggableChip from '../block-draggable/draggable-chip'; -const InserterListItemDraggable = ( { isEnabled, blocks, icon, children } ) => { +const InserterDraggableBlocks = ( { isEnabled, blocks, icon, children } ) => { const transferData = { type: 'inserter', blocks, @@ -31,4 +31,4 @@ const InserterListItemDraggable = ( { isEnabled, blocks, icon, children } ) => { ); }; -export default InserterListItemDraggable; +export default InserterDraggableBlocks; diff --git a/packages/block-editor/src/components/inserter-list-item/index.js b/packages/block-editor/src/components/inserter-list-item/index.js index f0770e596ebd50..81c66c69ee58dd 100644 --- a/packages/block-editor/src/components/inserter-list-item/index.js +++ b/packages/block-editor/src/components/inserter-list-item/index.js @@ -18,7 +18,7 @@ import { useMemo, useRef } from '@wordpress/element'; * Internal dependencies */ import BlockIcon from '../block-icon'; -import InserterListItemDraggable from './draggable'; +import InserterDraggableBlocks from '../inserter-draggable-blocks'; function InserterListItem( { className, @@ -47,7 +47,7 @@ function InserterListItem( { }, [ item.name, item.initialAttributes, item.initialAttributes ] ); return ( -
) } - + ); } diff --git a/packages/block-editor/src/components/inserter/block-patterns-tab.js b/packages/block-editor/src/components/inserter/block-patterns-tab.js index ddd8fc64693951..0a11200cab7e75 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -103,7 +103,6 @@ function BlockPatternsCategory( { <> { !! currentCategoryPatterns.length && ( ) } diff --git a/packages/block-editor/src/components/inserter/preview-panel.js b/packages/block-editor/src/components/inserter/preview-panel.js index 11c87d647097d6..3242ca306ffaeb 100644 --- a/packages/block-editor/src/components/inserter/preview-panel.js +++ b/packages/block-editor/src/components/inserter/preview-panel.js @@ -16,11 +16,13 @@ import BlockCard from '../block-card'; import BlockPreview from '../block-preview'; function InserterPreviewPanel( { item } ) { - const hoveredItemBlockType = getBlockType( item.name ); + const { name, title, icon, description, initialAttributes } = item; + const hoveredItemBlockType = getBlockType( name ); + const isReusable = isReusableBlock( item ); return (
- { isReusableBlock( item ) || hoveredItemBlockType.example ? ( + { isReusable || hoveredItemBlockType.example ? (
@@ -53,7 +52,13 @@ function InserterPreviewPanel( { item } ) {
) }
- { ! isReusableBlock( item ) && } + { ! isReusable && ( + + ) }
); } diff --git a/packages/block-editor/src/components/inserter/search-results.js b/packages/block-editor/src/components/inserter/search-results.js index 0285fd4a872edf..511813003cceb4 100644 --- a/packages/block-editor/src/components/inserter/search-results.js +++ b/packages/block-editor/src/components/inserter/search-results.js @@ -140,6 +140,7 @@ function InserterSearchResults( { shownPatterns={ currentShownPatterns } blockPatterns={ filteredBlockPatterns } onClickPattern={ onSelectBlockPattern } + isDraggable={ isDraggable } />
diff --git a/packages/block-editor/src/components/link-control/link-preview.js b/packages/block-editor/src/components/link-control/link-preview.js index 673ba1a7a7449a..ef6bd09fcf270f 100644 --- a/packages/block-editor/src/components/link-control/link-preview.js +++ b/packages/block-editor/src/components/link-control/link-preview.js @@ -17,7 +17,8 @@ import { ViewerSlot } from './viewer-slot'; export default function LinkPreview( { value, onEditClick } ) { const displayURL = - ( value && filterURLForDisplay( safeDecodeURI( value.url ) ) ) || ''; + ( value && filterURLForDisplay( safeDecodeURI( value.url ), 16 ) ) || + ''; return (
{ expect( onChange ).not.toHaveBeenCalled(); expect( onInput ).not.toHaveBeenCalled(); expect( resetBlocks ).not.toHaveBeenCalled(); - expect( replaceInnerBlocks ).toHaveBeenCalledWith( 'test', testBlocks ); + // We can't check the args because the blocks are cloned. + expect( replaceInnerBlocks ).toHaveBeenCalled(); } ); it( 'does not add the controlled blocks to the block-editor store if the store already contains them', async () => { @@ -200,7 +201,6 @@ describe( 'useBlockSync hook', () => { it( 'calls onInput when a non-persistent block change occurs', async () => { const onChange = jest.fn(); const onInput = jest.fn(); - const value1 = [ { clientId: 'a', innerBlocks: [], attributes: { foo: 1 } }, ]; diff --git a/packages/block-editor/src/components/provider/use-block-sync.js b/packages/block-editor/src/components/provider/use-block-sync.js index 6a2f04c3f86b7c..6eba648f4d7027 100644 --- a/packages/block-editor/src/components/provider/use-block-sync.js +++ b/packages/block-editor/src/components/provider/use-block-sync.js @@ -8,6 +8,7 @@ import { last, noop } from 'lodash'; */ import { useEffect, useRef } from '@wordpress/element'; import { useRegistry } from '@wordpress/data'; +import { cloneBlock } from '@wordpress/blocks'; /** * A function to call when the block value has been updated in the block-editor @@ -83,6 +84,7 @@ export default function useBlockSync( { const { getBlockName, getBlocks } = registry.select( 'core/block-editor' ); const pendingChanges = useRef( { incoming: null, outgoing: [] } ); + const subscribed = useRef( false ); const setControlledBlocks = () => { if ( ! controlledBlocks ) { @@ -96,8 +98,17 @@ export default function useBlockSync( { if ( clientId ) { setHasControlledInnerBlocks( clientId, true ); __unstableMarkNextChangeAsNotPersistent(); - replaceInnerBlocks( clientId, controlledBlocks ); + const storeBlocks = controlledBlocks.map( ( block ) => + cloneBlock( block ) + ); + if ( subscribed.current ) { + pendingChanges.current.incoming = storeBlocks; + } + replaceInnerBlocks( clientId, storeBlocks ); } else { + if ( subscribed.current ) { + pendingChanges.current.incoming = controlledBlocks; + } resetBlocks( controlledBlocks ); } }; @@ -113,6 +124,37 @@ export default function useBlockSync( { onChangeRef.current = onChange; }, [ onInput, onChange ] ); + // Determine if blocks need to be reset when they change. + useEffect( () => { + if ( pendingChanges.current.outgoing.includes( controlledBlocks ) ) { + // Skip block reset if the value matches expected outbound sync + // triggered by this component by a preceding change detection. + // Only skip if the value matches expectation, since a reset should + // still occur if the value is modified (not equal by reference), + // to allow that the consumer may apply modifications to reflect + // back on the editor. + if ( + last( pendingChanges.current.outgoing ) === controlledBlocks + ) { + pendingChanges.current.outgoing = []; + } + } else if ( getBlocks( clientId ) !== controlledBlocks ) { + // Reset changing value in all other cases than the sync described + // above. Since this can be reached in an update following an out- + // bound sync, unset the outbound value to avoid considering it in + // subsequent renders. + pendingChanges.current.outgoing = []; + setControlledBlocks(); + + if ( controlledSelectionStart && controlledSelectionEnd ) { + resetSelection( + controlledSelectionStart, + controlledSelectionEnd + ); + } + } + }, [ controlledBlocks, clientId ] ); + useEffect( () => { const { getSelectionStart, @@ -121,10 +163,11 @@ export default function useBlockSync( { __unstableIsLastBlockChangeIgnored, } = registry.select( 'core/block-editor' ); - let blocks; + let blocks = getBlocks( clientId ); let isPersistent = isLastBlockChangePersistent(); let previousAreBlocksDifferent = false; + subscribed.current = true; const unsubscribe = registry.subscribe( () => { // Sometimes, when changing block lists, lingering subscriptions // might trigger before they are cleaned up. If the block for which @@ -184,36 +227,4 @@ export default function useBlockSync( { return () => unsubscribe(); }, [ registry, clientId ] ); - - // Determine if blocks need to be reset when they change. - useEffect( () => { - if ( pendingChanges.current.outgoing.includes( controlledBlocks ) ) { - // Skip block reset if the value matches expected outbound sync - // triggered by this component by a preceding change detection. - // Only skip if the value matches expectation, since a reset should - // still occur if the value is modified (not equal by reference), - // to allow that the consumer may apply modifications to reflect - // back on the editor. - if ( - last( pendingChanges.current.outgoing ) === controlledBlocks - ) { - pendingChanges.current.outgoing = []; - } - } else if ( getBlocks( clientId ) !== controlledBlocks ) { - // Reset changing value in all other cases than the sync described - // above. Since this can be reached in an update following an out- - // bound sync, unset the outbound value to avoid considering it in - // subsequent renders. - pendingChanges.current.outgoing = []; - pendingChanges.current.incoming = controlledBlocks; - setControlledBlocks(); - - if ( controlledSelectionStart && controlledSelectionEnd ) { - resetSelection( - controlledSelectionStart, - controlledSelectionEnd - ); - } - } - }, [ controlledBlocks, clientId ] ); } diff --git a/packages/block-editor/src/components/url-popover/README.md b/packages/block-editor/src/components/url-popover/README.md index 1af8eeb670ad2f..defa20050cdcf9 100644 --- a/packages/block-editor/src/components/url-popover/README.md +++ b/packages/block-editor/src/components/url-popover/README.md @@ -16,7 +16,7 @@ class MyURLPopover extends Component { super( ...arguments ); this.onChangeURL = this.onChangeURL.bind( this ); - this.openURLPopover = this.closeURLPopover.bind( this ); + this.openURLPopover = this.openURLPopover.bind( this ); this.closeURLPopover = this.closeURLPopover.bind( this ); this.submitURL = this.submitURL.bind( this ); this.setTarget = this.setTarget.bind( this ); diff --git a/packages/block-editor/src/components/use-block-display-information/README.md b/packages/block-editor/src/components/use-block-display-information/README.md new file mode 100644 index 00000000000000..6d52ee452cc48a --- /dev/null +++ b/packages/block-editor/src/components/use-block-display-information/README.md @@ -0,0 +1,42 @@ +# useBlockDisplayInformation + +A React Hook that tries to find a matching block variation and returns the appropriate information for display reasons. In order to try to find a match we need two things: + +1. Block's client id to extract its current attributes. +2. A block variation has `isActive` prop defined with a matcher function. + +If for any reason a block variaton match cannot be found, the returned information come from the Block Type. + +### Usage + +The hook returns an object which contains the block's title, icon, and description. If no block type is found for the provided `clientId`, it returns `null`. + +```jsx +import { + BlockIcon, + useBlockDisplayInformation, +} from '@wordpress/block-editor'; + +function DemoBlockCard( { clientId } ) { + const blockInformation = useBlockDisplayInformation( clientId ); + const { title, icon, description } = blockInformation; + return ( +
+ +

{ title }

+

{ description }

+
+ ); +} +``` + +## Props + +The hook accepts the following props. + +### clientId + +A block's clientId + +- Type: `String` +- Required: Yes diff --git a/packages/block-editor/src/components/use-block-display-information/index.js b/packages/block-editor/src/components/use-block-display-information/index.js new file mode 100644 index 00000000000000..7ee0d350ffef8a --- /dev/null +++ b/packages/block-editor/src/components/use-block-display-information/index.js @@ -0,0 +1,70 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { store as blocksStore } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; + +/** @typedef {import('@wordpress/blocks').WPIcon} WPIcon */ + +/** + * Contains basic block's information for display reasons. + * + * @typedef {Object} WPBlockDisplayInformation + * + * @property {string} title Human-readable block type label. + * @property {WPIcon} icon Block type icon. + * @property {string} description A detailed block type description. + */ + +/** + * Hook used to try to find a matching block variation and return + * the appropriate information for display reasons. In order to + * to try to find a match we need to things: + * 1. Block's client id to extract it's current attributes. + * 2. A block variation should have set `isActive` prop to a proper function. + * + * If for any reason a block variaton match cannot be found, + * the returned information come from the Block Type. + * If no blockType is found with the provided clientId, returns null. + * + * @param {string} clientId Block's client id. + * @return {?WPBlockDisplayInformation} Block's display information, or `null` when the block or its type not found. + */ + +export default function useBlockDisplayInformation( clientId ) { + return useSelect( + ( select ) => { + if ( ! clientId ) return null; + const { getBlockName, getBlockAttributes } = select( + blockEditorStore + ); + const { getBlockType, getBlockVariations } = select( blocksStore ); + const blockName = getBlockName( clientId ); + const blockType = getBlockType( blockName ); + if ( ! blockType ) return null; + const variations = getBlockVariations( blockName ); + const blockTypeInfo = { + title: blockType.title, + icon: blockType.icon, + description: blockType.description, + }; + if ( ! variations?.length ) return blockTypeInfo; + const attributes = getBlockAttributes( clientId ); + const match = variations.find( ( variation ) => + variation.isActive?.( attributes, variation.attributes ) + ); + if ( ! match ) return blockTypeInfo; + return { + title: match.title || blockType.title, + icon: match.icon || blockType.icon, + description: match.description || blockType.description, + }; + }, + [ clientId ] + ); +} diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index 125a850836f103..85b8247743b385 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { has, get, startsWith, mapValues } from 'lodash'; +import { capitalize, has, get, startsWith } from 'lodash'; /** * WordPress dependencies @@ -54,18 +54,21 @@ function compileStyleValue( uncompiledValue ) { */ export function getInlineStyles( styles = {} ) { const output = {}; - const styleProperties = mapValues( STYLE_PROPERTY, ( prop ) => prop.value ); - Object.entries( styleProperties ).forEach( - ( [ styleKey, ...otherObjectKeys ] ) => { - const [ objectKeys ] = otherObjectKeys; - - if ( has( styles, objectKeys ) ) { - output[ styleKey ] = compileStyleValue( - get( styles, objectKeys ) - ); + Object.keys( STYLE_PROPERTY ).forEach( ( propKey ) => { + const path = STYLE_PROPERTY[ propKey ].value; + const subPaths = STYLE_PROPERTY[ propKey ].properties; + if ( has( styles, path ) ) { + if ( !! subPaths ) { + subPaths.forEach( ( suffix ) => { + output[ + propKey + capitalize( suffix ) + ] = compileStyleValue( get( styles, [ ...path, suffix ] ) ); + } ); + } else { + output[ propKey ] = compileStyleValue( get( styles, path ) ); } } - ); + } ); return output; } diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index 8bbcbff537dbb8..ba608d34a35f87 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -20,7 +20,6 @@ export const PREFERENCES_DEFAULTS = { * @property {boolean} hasFixedToolbar Whether or not the editor toolbar is fixed * @property {boolean} focusMode Whether the focus mode is enabled or not * @property {Array} styles Editor Styles - * @property {boolean} isRTL Whether the editor is in RTL mode * @property {boolean} keepCaretInsideBlock Whether caret should move between blocks in edit mode * @property {string} bodyPlaceholder Empty post placeholder * @property {string} titlePlaceholder Empty title placeholder diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index c2153ee33cb4b1..764f8350b986d9 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -13,6 +13,8 @@ import { some, find, filter, + mapKeys, + orderBy, } from 'lodash'; import createSelector from 'rememo'; @@ -23,6 +25,7 @@ import { getBlockType, getBlockTypes, hasBlockSupport, + getPossibleBlockTransformations, parse, } from '@wordpress/blocks'; import { SVG, Rect, G, Path } from '@wordpress/components'; @@ -1400,6 +1403,85 @@ const getItemFromVariation = ( item ) => ( variation ) => ( { keywords: variation.keywords || item.keywords, } ); +/** + * Returns the calculated frecency. + * + * 'frecency' is a heuristic (https://en.wikipedia.org/wiki/Frecency) + * that combines block usage frequenty and recency. + * + * @param {number} time When the last insert occurred as a UNIX epoch + * @param {number} count The number of inserts that have occurred. + * + * @return {number} The calculated frecency. + */ +const calculateFrecency = ( time, count ) => { + if ( ! time ) { + return count; + } + // The selector is cached, which means Date.now() is the last time that the + // relevant state changed. This suits our needs. + const duration = Date.now() - time; + switch ( true ) { + case duration < MILLISECONDS_PER_HOUR: + return count * 4; + case duration < MILLISECONDS_PER_DAY: + return count * 2; + case duration < MILLISECONDS_PER_WEEK: + return count / 2; + default: + return count / 4; + } +}; + +/** + * Returns a function that accepts a block type and builds an item to be shown + * in a specific context. It's used for building items for Inserter and available + * block Transfroms list. + * + * @param {Object} state Editor state. + * @param {Object} options Options object for handling the building of a block type. + * @param {string} options.buildScope The scope for which the item is going to be used. + * @return {Function} Function returns an item to be shown in a specific context (Inserter|Transforms list). + */ +const buildBlockTypeItem = ( state, { buildScope = 'inserter' } ) => ( + blockType +) => { + const id = blockType.name; + + let isDisabled = false; + if ( ! hasBlockSupport( blockType.name, 'multiple', true ) ) { + isDisabled = some( + getBlocksByClientId( state, getClientIdsWithDescendants( state ) ), + { name: blockType.name } + ); + } + + const { time, count = 0 } = getInsertUsage( state, id ) || {}; + const blockItemBase = { + id, + name: blockType.name, + title: blockType.title, + icon: blockType.icon, + isDisabled, + frecency: calculateFrecency( time, count ), + }; + if ( buildScope === 'transform' ) return blockItemBase; + + const inserterVariations = blockType.variations.filter( + ( { scope } ) => ! scope || scope.includes( 'inserter' ) + ); + return { + ...blockItemBase, + initialAttributes: {}, + description: blockType.description, + category: blockType.category, + keywords: blockType.keywords, + variations: inserterVariations, + example: blockType.example, + utility: 1, // deprecated + }; +}; + /** * Determines the items that appear in the inserter. Includes both static * items (e.g. a regular block type) and dynamic items (e.g. a reusable block). @@ -1431,64 +1513,9 @@ const getItemFromVariation = ( item ) => ( variation ) => ( { */ export const getInserterItems = createSelector( ( state, rootClientId = null ) => { - const calculateFrecency = ( time, count ) => { - if ( ! time ) { - return count; - } - - // The selector is cached, which means Date.now() is the last time that the - // relevant state changed. This suits our needs. - const duration = Date.now() - time; - - switch ( true ) { - case duration < MILLISECONDS_PER_HOUR: - return count * 4; - case duration < MILLISECONDS_PER_DAY: - return count * 2; - case duration < MILLISECONDS_PER_WEEK: - return count / 2; - default: - return count / 4; - } - }; - - const buildBlockTypeInserterItem = ( blockType ) => { - const id = blockType.name; - - let isDisabled = false; - if ( ! hasBlockSupport( blockType.name, 'multiple', true ) ) { - isDisabled = some( - getBlocksByClientId( - state, - getClientIdsWithDescendants( state ) - ), - { - name: blockType.name, - } - ); - } - - const { time, count = 0 } = getInsertUsage( state, id ) || {}; - const inserterVariations = blockType.variations.filter( - ( { scope } ) => ! scope || scope.includes( 'inserter' ) - ); - - return { - id, - name: blockType.name, - initialAttributes: {}, - title: blockType.title, - description: blockType.description, - icon: blockType.icon, - category: blockType.category, - keywords: blockType.keywords, - variations: inserterVariations, - example: blockType.example, - isDisabled, - utility: 1, // deprecated - frecency: calculateFrecency( time, count ), - }; - }; + const buildBlockTypeInserterItem = buildBlockTypeItem( state, { + buildScope: 'inserter', + } ); const buildReusableBlockInserterItem = ( reusableBlock ) => { const id = `core/block/${ reusableBlock.id }`; @@ -1572,6 +1599,71 @@ export const getInserterItems = createSelector( ] ); +/** + * Determines the items that appear in the available block transforms list. + * + * Each item object contains what's necessary to display a menu item in the + * transform list and handle its selection. + * + * The 'frecency' property is a heuristic (https://en.wikipedia.org/wiki/Frecency) + * that combines block usage frequenty and recency. + * + * Items are returned ordered descendingly by their 'frecency'. + * + * @param {Object} state Editor state. + * @param {?string} rootClientId Optional root client ID of block list. + * + * @return {WPEditorTransformItem[]} Items that appear in inserter. + * + * @typedef {Object} WPEditorTransformItem + * @property {string} id Unique identifier for the item. + * @property {string} name The type of block to create. + * @property {string} title Title of the item, as it appears in the inserter. + * @property {string} icon Dashicon for the item, as it appears in the inserter. + * @property {boolean} isDisabled Whether or not the user should be prevented from inserting + * this item. + * @property {number} frecency Heuristic that combines frequency and recency. + */ +export const getBlockTransformItems = createSelector( + ( state, blocks, rootClientId = null ) => { + const buildBlockTypeTransformItem = buildBlockTypeItem( state, { + buildScope: 'transform', + } ); + const blockTypeTransformItems = getBlockTypes() + .filter( ( blockType ) => + canIncludeBlockTypeInInserter( state, blockType, rootClientId ) + ) + .map( buildBlockTypeTransformItem ); + + const itemsByName = mapKeys( + blockTypeTransformItems, + ( { name } ) => name + ); + const possibleTransforms = getPossibleBlockTransformations( + blocks + ).reduce( ( accumulator, block ) => { + if ( itemsByName[ block?.name ] ) { + accumulator.push( itemsByName[ block.name ] ); + } + return accumulator; + }, [] ); + const possibleBlockTransformations = orderBy( + possibleTransforms, + ( block ) => itemsByName[ block.name ].frecency, + 'desc' + ); + return possibleBlockTransformations; + }, + ( state, rootClientId ) => [ + state.blockListSettings[ rootClientId ], + state.blocks.byClientId, + state.preferences.insertUsage, + state.settings.allowedBlockTypes, + state.settings.templateLock, + getBlockTypes(), + ] +); + /** * Determines whether there are items to show in the inserter. * diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index d11e53a9e74853..a0803a0e5b2c20 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -61,6 +61,7 @@ const { canInsertBlockType, canInsertBlocks, getInserterItems, + getBlockTransformItems, isValidTemplate, getTemplate, getTemplateLock, @@ -2675,6 +2676,222 @@ describe( 'selectors', () => { } ); } ); + describe( 'getBlockTransformItems', () => { + beforeAll( () => { + registerBlockType( 'core/with-tranforms-a', { + category: 'text', + title: 'Tranforms a', + edit: () => {}, + save: () => {}, + transforms: { + to: [ + { + type: 'block', + blocks: [ 'core/with-tranforms-b' ], + transform: () => {}, + }, + { + type: 'block', + blocks: [ 'core/with-tranforms-c' ], + transform: () => {}, + }, + { + type: 'block', + blocks: [ + 'core/with-tranforms-b', + 'core/with-tranforms-c', + ], + transform: () => {}, + isMultiBlock: true, + }, + ], + }, + } ); + registerBlockType( 'core/with-tranforms-b', { + category: 'text', + title: 'Tranforms b', + edit: () => {}, + save: () => {}, + transforms: { + to: [ + { + type: 'block', + blocks: [ 'core/with-tranforms-a' ], + transform: () => {}, + }, + ], + }, + } ); + registerBlockType( 'core/with-tranforms-c', { + category: 'text', + title: 'Tranforms c', + edit: () => {}, + save: () => {}, + transforms: { + to: [ + { + type: 'block', + blocks: [ 'core/with-tranforms-a' ], + transform: () => {}, + }, + ], + }, + supports: { multiple: false }, + } ); + } ); + afterAll( () => { + [ + 'core/with-tranforms-a', + 'core/with-tranforms-b', + 'core/with-tranforms-c', + ].forEach( unregisterBlockType ); + } ); + it( 'should properly return block type items', () => { + const state = { + blocks: { + byClientId: {}, + attributes: {}, + order: {}, + parents: {}, + cache: {}, + }, + settings: {}, + preferences: {}, + blockListSettings: {}, + }; + const blocks = [ { name: 'core/with-tranforms-a' } ]; + const items = getBlockTransformItems( state, blocks ); + expect( items ).toHaveLength( 2 ); + const returnedProps = Object.keys( items[ 0 ] ); + // Verify we have only the wanted props. + expect( returnedProps ).toHaveLength( 6 ); + expect( returnedProps ).toEqual( + expect.arrayContaining( [ + 'id', + 'name', + 'title', + 'icon', + 'frecency', + 'isDisabled', + ] ) + ); + expect( items ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + name: 'core/with-tranforms-b', + } ), + expect.objectContaining( { + name: 'core/with-tranforms-c', + } ), + ] ) + ); + } ); + it( 'should return only eligible blocks for transformation - `allowedBlocks`', () => { + const state = { + blocks: { + byClientId: { + block1: { name: 'core/with-tranforms-b' }, + block2: { name: 'core/with-tranforms-a' }, + }, + attributes: { + block1: {}, + block2: {}, + }, + order: {}, + parents: { + block1: '', + block2: 'block1', + }, + cache: {}, + controlledInnerBlocks: {}, + }, + settings: {}, + preferences: {}, + blockListSettings: { + block1: { + allowedBlocks: [ 'core/with-tranforms-c' ], + }, + block2: {}, + }, + }; + const blocks = [ + { clientId: 'block2', name: 'core/with-tranforms-a' }, + ]; + const items = getBlockTransformItems( state, blocks, 'block1' ); + expect( items ).toHaveLength( 1 ); + expect( items[ 0 ].name ).toEqual( 'core/with-tranforms-c' ); + } ); + it( 'should take into account the usage of blocks settings `multiple` - if multiple blocks of the same type are allowed', () => { + const state = { + blocks: { + byClientId: { + block1: { + clientId: 'block1', + name: 'core/with-tranforms-c', + }, + }, + attributes: { + block1: { attribute: {} }, + }, + order: { + '': [ 'block1' ], + }, + cache: { + block1: {}, + }, + controlledInnerBlocks: {}, + }, + preferences: { + insertUsage: {}, + }, + blockListSettings: {}, + settings: {}, + }; + const blocks = [ { name: 'core/with-tranforms-a' } ]; + const items = getBlockTransformItems( state, blocks ); + expect( items ).toHaveLength( 2 ); + expect( items ).toEqual( + expect.arrayContaining( [ + expect.objectContaining( { + name: 'core/with-tranforms-b', + isDisabled: false, + } ), + expect.objectContaining( { + name: 'core/with-tranforms-c', + isDisabled: true, + } ), + ] ) + ); + } ); + it( 'should set frecency', () => { + const state = { + blocks: { + byClientId: {}, + attributes: {}, + order: {}, + parents: {}, + cache: {}, + }, + preferences: { + insertUsage: { + 'core/with-tranforms-a': { count: 10, time: 1000 }, + }, + }, + blockListSettings: {}, + settings: {}, + }; + const blocks = [ { name: 'core/with-tranforms-c' } ]; + const items = getBlockTransformItems( state, blocks ); + expect( items ).toHaveLength( 1 ); + expect( items[ 0 ] ).toEqual( + expect.objectContaining( { + name: 'core/with-tranforms-a', + frecency: 2.5, + } ) + ); + } ); + } ); + describe( 'isValidTemplate', () => { it( 'should return true if template is valid', () => { const state = { diff --git a/packages/block-library/src/block/edit-panel/editor.scss b/packages/block-library/src/block/edit-panel/editor.scss deleted file mode 100644 index 702f72e4dbace1..00000000000000 --- a/packages/block-library/src/block/edit-panel/editor.scss +++ /dev/null @@ -1,60 +0,0 @@ -.block-editor-block-list__layout .reusable-block-edit-panel { - align-items: center; - display: flex; - flex-wrap: wrap; - font-family: $default-font; - font-size: $default-font-size; - padding: ($grid-unit-10 - $border-width - $border-width) $grid-unit-15; - - // Block UI appearance. - border-radius: $radius-block-ui; - background-color: $white; - box-shadow: 0 0 0 $border-width $gray-900; - outline: 1px solid transparent; // Shown for Windows 10 High Contrast mode. - - .reusable-block-edit-panel__info { - margin-right: auto; - } - - .reusable-block-edit-panel__label { - margin-right: $grid-unit-10; - white-space: nowrap; - font-family: $default-font; - font-size: $default-font-size; - } - - .reusable-block-edit-panel__title { - flex: 1 1 100%; - } - - .components-button.reusable-block-edit-panel__button { - // Prevent button shrinking in IE11 when other items have a 100% flex basis. - // This should be safe to apply in all browsers because we don't want these - // buttons to shrink anyway. - flex-shrink: 0; - } - - @include break-large() { - flex-wrap: nowrap; - - .reusable-block-edit-panel__title { - margin: 0; - } - - .components-button.reusable-block-edit-panel__button { - margin: 0 0 0 $grid-unit-10; - } - } -} - -.reusable-block-edit-panel__title[type="text"] { - @include input-control; -} - -.is-navigate-mode .is-selected .reusable-block-edit-panel { - box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color); - - .is-dark-theme & { - box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color); - } -} diff --git a/packages/block-library/src/block/edit-panel/index.js b/packages/block-library/src/block/edit-panel/index.js deleted file mode 100644 index c3b60a963cf3e2..00000000000000 --- a/packages/block-library/src/block/edit-panel/index.js +++ /dev/null @@ -1,129 +0,0 @@ -/** - * WordPress dependencies - */ -import { Button } from '@wordpress/components'; -import { useInstanceId, usePrevious } from '@wordpress/compose'; -import { useEffect, useRef } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; - -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ - -/** - * ReusableBlockEditPanel props. - * - * @typedef WPReusableBlockEditPanelProps - * - * @property {boolean} isEditDisabled Is editing the reusable - * block disabled. - * @property {boolean} isEditing Is the reusable block - * being edited. - * @property {boolean} isSaving Is the reusable block - * being saved. - * @property {()=>void} onCancel Callback to run when - * editing is canceled. - * @property {(newTitle:string)=>void} onChangeTitle Callback to run when the - * title input value is - * changed. - * @property {()=>void} onEdit Callback to run when - * editing begins. - * @property {()=>void} onSave Callback to run when - * saving. - * @property {string} title Title of the reusable - * block. - */ - -/** - * Panel for enabling the editing and saving of a reusable block. - * - * @param {WPReusableBlockEditPanelProps} props Component props. - * - * @return {WPComponent} The panel. - */ -export default function ReusableBlockEditPanel( { - isEditDisabled, - isEditing, - isSaving, - onChangeTitle, - onEdit, - onSave, - title, -} ) { - const instanceId = useInstanceId( ReusableBlockEditPanel ); - const titleField = useRef(); - const editButton = useRef(); - const wasEditing = usePrevious( isEditing ); - const wasSaving = usePrevious( isSaving ); - - // Select the title input when the form opens. - useEffect( () => { - if ( ! wasEditing && isEditing ) { - titleField.current.select(); - } - }, [ isEditing ] ); - - // Move focus back to the Edit button after pressing the Escape key or Save. - useEffect( () => { - if ( ( wasEditing || wasSaving ) && ! isEditing && ! isSaving ) { - editButton.current.focus(); - } - }, [ isEditing, isSaving ] ); - - function handleFormSubmit( event ) { - event.preventDefault(); - onSave(); - } - - function handleTitleChange( event ) { - onChangeTitle( event.target.value ); - } - - return ( - <> - { ! isEditing && ! isSaving && ( -
- { title } - -
- ) } - { ( isEditing || isSaving ) && ( -
- - - -
- ) } - - ); -} diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 1c7b9b039252ca..6e3f999ba36380 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -2,101 +2,76 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { useEntityBlockEditor } from '@wordpress/core-data'; -import { useCallback } from '@wordpress/element'; +import { + useEntityBlockEditor, + useEntityProp, + store as coreStore, +} from '@wordpress/core-data'; import { Placeholder, Spinner, - Disabled, ToolbarGroup, ToolbarButton, + TextControl, + PanelBody, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { - BlockEditorProvider, - WritingFlow, - BlockList, + __experimentalUseInnerBlocksProps as useInnerBlocksProps, + InnerBlocks, BlockControls, + InspectorControls, useBlockProps, } from '@wordpress/block-editor'; -import { store as noticesStore } from '@wordpress/notices'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; /** * Internal dependencies */ -import ReusableBlockEditPanel from './edit-panel'; -export default function ReusableBlockEdit( { - attributes: { ref }, - clientId, - isSelected, -} ) { +export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { const recordArgs = [ 'postType', 'wp_block', ref ]; - const { - reusableBlock, - hasResolved, - isEditing, - isSaving, - canUserUpdate, - settings, - } = useSelect( + const { reusableBlock, hasResolved } = useSelect( ( select ) => ( { - reusableBlock: select( 'core' ).getEditedEntityRecord( + reusableBlock: select( coreStore ).getEditedEntityRecord( ...recordArgs ), - hasResolved: select( 'core' ).hasFinishedResolution( + hasResolved: select( coreStore ).hasFinishedResolution( 'getEditedEntityRecord', recordArgs ), - isSaving: select( 'core' ).isSavingEntityRecord( ...recordArgs ), - canUserUpdate: select( 'core' ).canUser( 'update', 'blocks', ref ), - isEditing: select( - reusableBlocksStore - ).__experimentalIsEditingReusableBlock( clientId ), - settings: select( 'core/block-editor' ).getSettings(), } ), [ ref, clientId ] ); - const { clearSelectedBlock } = useDispatch( 'core/block-editor' ); - const { editEntityRecord, saveEditedEntityRecord } = useDispatch( 'core' ); - const { __experimentalSetEditingReusableBlock } = useDispatch( - reusableBlocksStore - ); - const setIsEditing = useCallback( - ( value ) => { - __experimentalSetEditingReusableBlock( clientId, value ); - }, - [ clientId ] - ); - const { __experimentalConvertBlockToStatic: convertBlockToStatic, } = useDispatch( reusableBlocksStore ); - const { createSuccessNotice, createErrorNotice } = useDispatch( - noticesStore - ); - const save = useCallback( async function () { - try { - await saveEditedEntityRecord( ...recordArgs ); - createSuccessNotice( __( 'Block updated.' ), { - type: 'snackbar', - } ); - } catch ( error ) { - createErrorNotice( error.message, { - type: 'snackbar', - } ); - } - }, recordArgs ); - const [ blocks, onInput, onChange ] = useEntityBlockEditor( 'postType', 'wp_block', { id: ref } ); + const [ title, setTitle ] = useEntityProp( + 'postType', + 'wp_block', + 'title', + ref + ); + + const innerBlocksProps = useInnerBlocksProps( + {}, + { + value: blocks, + onInput, + onChange, + renderAppender: blocks?.length + ? undefined + : InnerBlocks.ButtonBlockAppender, + } + ); const blockProps = useBlockProps(); @@ -120,34 +95,6 @@ export default function ReusableBlockEdit( { ); } - /** - * Clear the selected block when focus moves to the reusable block list. - * These blocks are in different stores and only one block should be - * selected at a time. - */ - function onFocus() { - clearSelectedBlock(); - } - - let element = ( - -
- - - -
-
- ); - - if ( ! isEditing ) { - element = { element }; - } - return (
@@ -159,25 +106,17 @@ export default function ReusableBlockEdit( { - -
- { ( isSelected || isEditing ) && ( - setIsEditing( true ) } - onChangeTitle={ ( title ) => - editEntityRecord( ...recordArgs, { title } ) - } - onSave={ () => { - save(); - setIsEditing( false ); - } } + + + - ) } - { element } + + +
+ {
}
); diff --git a/packages/block-library/src/code/style.scss b/packages/block-library/src/code/style.scss index f40e238f6b21bd..35cab12be3c1eb 100644 --- a/packages/block-library/src/code/style.scss +++ b/packages/block-library/src/code/style.scss @@ -1,10 +1,6 @@ // Provide a minimum of overflow handling. -.wp-block-code { - font-size: 0.9em; - - code { - display: block; - white-space: pre-wrap; - overflow-wrap: break-word; - } +.wp-block-code code { + display: block; + white-space: pre-wrap; + overflow-wrap: break-word; } diff --git a/packages/block-library/src/column/edit.native.js b/packages/block-library/src/column/edit.native.js index 16e03fadc5fdd3..4fec805c235ea4 100644 --- a/packages/block-library/src/column/edit.native.js +++ b/packages/block-library/src/column/edit.native.js @@ -1,14 +1,14 @@ /** * External dependencies */ -import { View } from 'react-native'; +import { View, Dimensions } from 'react-native'; /** * WordPress dependencies */ import { withSelect } from '@wordpress/data'; import { compose, withPreferredColorScheme } from '@wordpress/compose'; -import { useEffect, useState } from '@wordpress/element'; +import { useEffect, useState, useCallback } from '@wordpress/element'; import { InnerBlocks, BlockControls, @@ -20,6 +20,7 @@ import { FooterMessageControl, UnitControl, getValueAndUnit, + alignmentHelpers, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; /** @@ -27,7 +28,14 @@ import { __ } from '@wordpress/i18n'; */ import styles from './editor.scss'; import ColumnsPreview from './column-preview'; -import { getWidths, getWidthWithUnit, CSS_UNITS } from '../columns/utils'; +import { + getWidths, + getWidthWithUnit, + isPercentageUnit, + CSS_UNITS, +} from '../columns/utils'; + +const { isWider } = alignmentHelpers; function ColumnEdit( { attributes, @@ -40,11 +48,14 @@ function ColumnEdit( { columns, selectedColumnIndex, parentAlignment, + clientId, } ) { const { verticalAlignment, width } = attributes; const { valueUnit = '%' } = getValueAndUnit( width ) || {}; - const [ widthUnit, setWidthUnit ] = useState( valueUnit ); + const screenWidth = Math.floor( Dimensions.get( 'window' ).width ); + + const [ widthUnit, setWidthUnit ] = useState( valueUnit || '%' ); const updateAlignment = ( alignment ) => { setAttributes( { verticalAlignment: alignment } ); @@ -70,15 +81,44 @@ function ColumnEdit( { const onChangeUnit = ( nextUnit ) => { setWidthUnit( nextUnit ); - const tempWidth = parseFloat( + const widthWithoutUnit = parseFloat( width || getWidths( columns )[ selectedColumnIndex ] ); setAttributes( { - width: getWidthWithUnit( tempWidth, nextUnit ), + width: getWidthWithUnit( widthWithoutUnit, nextUnit ), } ); }; + const onChange = ( nextWidth ) => { + if ( isPercentageUnit( widthUnit ) || ! widthUnit ) { + return; + } + onChangeWidth( nextWidth ); + }; + + const renderAppender = useCallback( () => { + const { width: blockWidth } = contentStyle[ clientId ]; + const isScreenWidthEqual = blockWidth === screenWidth; + + if ( isSelected ) { + return ( + + + + ); + } + return null; + }, [ contentStyle[ clientId ], screenWidth, isSelected, hasChildren ] ); + if ( ! isSelected && ! hasChildren ) { return ( ); @@ -108,11 +148,12 @@ function ColumnEdit( { diff --git a/packages/block-library/src/column/editor.native.scss b/packages/block-library/src/column/editor.native.scss index e5e2e853f59b73..6c52b88af035e4 100644 --- a/packages/block-library/src/column/editor.native.scss +++ b/packages/block-library/src/column/editor.native.scss @@ -16,7 +16,7 @@ } .innerBlocksBottomSpace { - margin-bottom: $block-selected-to-content; + margin-bottom: $block-edge-to-content; } .is-vertically-aligned-top { @@ -57,3 +57,13 @@ .columnIndicatorDark { background-color: $gray-20; } + +.columnAppender { + margin-left: $grid-unit-20; + margin-right: $grid-unit-20; +} + +.wideColumnAppender { + margin-left: $grid-unit-10; + margin-right: $grid-unit-10; +} diff --git a/packages/block-library/src/columns/columnCalculations.native.js b/packages/block-library/src/columns/columnCalculations.native.js new file mode 100644 index 00000000000000..46d334b9d0e8ea --- /dev/null +++ b/packages/block-library/src/columns/columnCalculations.native.js @@ -0,0 +1,178 @@ +/** + * WordPress dependencies + */ +import { + ALIGNMENT_BREAKPOINTS, + convertUnitToMobile, +} from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { getColumnWidths, getWidths } from './utils'; +import styles from './editor.scss'; + +/** + * Maximum number of columns in a row + * + * @type {number} + */ +const MAX_COLUMNS_NUM_IN_ROW = 3; + +/** + * Minimum width of column + * + * @type {number} + */ +const MIN_WIDTH = styles.columnsContainer?.minWidth; + +/** + * Container margin value + * + * @type {number} + */ +const MARGIN = styles.columnsContainer?.marginLeft; + +export const getColumnsInRow = ( width, columnCount ) => { + if ( width ) { + if ( width < ALIGNMENT_BREAKPOINTS.mobile ) { + // show only 1 Column in row for mobile breakpoint container width + return 1; + } else if ( width <= ALIGNMENT_BREAKPOINTS.medium ) { + // show the maximum number of columns in a row for large breakpoint container width + return Math.min( + Math.max( 1, columnCount ), + MAX_COLUMNS_NUM_IN_ROW + ); + } + // show all Column in one row + return columnCount; + } +}; + +export const calculateContainerWidth = ( containerWidth, columnsInRow ) => + 2 * MARGIN + containerWidth - columnsInRow * 2 * MARGIN; + +export const getContentWidths = ( + columnsInRow, + width, + columnCount, + innerColumns, + globalStyles +) => { + const widths = {}; + const columnWidthsWithUnits = getWidths( innerColumns, false ); + const columnWidths = getColumnWidths( innerColumns, columnCount ); + + // Array of column width attribute values + const columnWidthsValues = columnWidthsWithUnits.map( ( v ) => + convertUnitToMobile( { width }, globalStyles, v ) + ); + + // The sum of column width attribute values + const columnWidthsSum = columnWidthsValues.reduce( + ( acc, curr ) => acc + curr, + 0 + ); + + // Array of ratios of each column width attribute value to their sum + const columnRatios = columnWidthsValues.map( + ( colWidth ) => colWidth / columnWidthsSum + ); + + // Array of calculated column width for its ratio + const columnWidthsPerRatio = columnRatios.map( + ( columnRatio ) => + columnRatio * calculateContainerWidth( width, columnsInRow ) + ); + + // Array of columns whose calculated width is lower than minimum width value + const filteredColumnWidthsPerRatio = columnWidthsPerRatio.filter( + ( columnWidthPerRatio ) => columnWidthPerRatio <= MIN_WIDTH + ); + + // Container width to be divided. If there are some results within `filteredColumnWidthsPerRatio` + // there is a need to reduce the main width by multiplying number + // of results in `filteredColumnWidthsPerRatio` and minimum width value + const baseContainerWidth = + width - filteredColumnWidthsPerRatio.length * MIN_WIDTH; + + // The minimum percentage ratio for which column width is equal minimum width value + const minPercentageRatio = + MIN_WIDTH / calculateContainerWidth( width, columnsInRow ); + + // The sum of column widths which ratio is higher than `minPercentageRatio` + const largeColumnsWidthsSum = columnRatios + .map( ( ratio, index ) => { + if ( ratio > minPercentageRatio ) { + return columnWidthsValues[ index ]; + } + return 0; + } ) + .reduce( ( acc, curr ) => acc + curr, 0 ); + + const containerWidth = calculateContainerWidth( + baseContainerWidth, + columnsInRow + ); + + let columnWidth = + calculateContainerWidth( width, columnsInRow ) / columnsInRow; + let maxColumnWidth = columnWidth; + + innerColumns.forEach( + ( { attributes: innerColumnAttributes, clientId } ) => { + const attributeWidth = convertUnitToMobile( + { width }, + globalStyles, + innerColumnAttributes.width || columnWidths[ clientId ] + ); + const proportionalRatio = attributeWidth / columnWidthsSum; + const percentageRatio = attributeWidth / width; + const initialColumnWidth = proportionalRatio * containerWidth; + + if ( columnCount === 1 && width > ALIGNMENT_BREAKPOINTS.medium ) { + // Exactly one column inside columns on the breakpoint higher than medium + // has to take a percentage of the full width + columnWidth = percentageRatio * containerWidth; + } else if ( columnsInRow > 1 ) { + if ( width > ALIGNMENT_BREAKPOINTS.medium ) { + if ( initialColumnWidth <= MIN_WIDTH ) { + // Column width cannot be lower than minimum 32px + columnWidth = MIN_WIDTH; + } else if ( initialColumnWidth > MIN_WIDTH ) { + // Column width has to be the result of multiplying the container width and + // the ratio of attribute and the sum of widths of columns wider than 32px + columnWidth = + ( attributeWidth / largeColumnsWidthsSum ) * + containerWidth; + } + + maxColumnWidth = columnWidth; + + if ( Math.round( columnWidthsSum ) < width ) { + // In case that column width attribute values does not exceed 100, each column + // should have attribute percentage of container width + const newColumnWidth = percentageRatio * containerWidth; + if ( newColumnWidth <= MIN_WIDTH ) { + columnWidth = MIN_WIDTH; + } else { + columnWidth = newColumnWidth; + } + } + } else if ( width < ALIGNMENT_BREAKPOINTS.medium ) { + // On the breakpoint lower than medium each column inside columns + // has to take equal part of container width + columnWidth = + calculateContainerWidth( width, columnsInRow ) / + columnsInRow; + } + } + widths[ clientId ] = { + width: Math.floor( columnWidth ), + maxWidth: Math.floor( maxColumnWidth ), + }; + } + ); + return widths; +}; diff --git a/packages/block-library/src/columns/edit.native.js b/packages/block-library/src/columns/edit.native.js index 453cf8f9eed3f0..68de0e05ca1b81 100644 --- a/packages/block-library/src/columns/edit.native.js +++ b/packages/block-library/src/columns/edit.native.js @@ -1,9 +1,8 @@ /** * External dependencies */ -import { View } from 'react-native'; +import { View, Dimensions } from 'react-native'; import { dropRight, times, map, compact, delay } from 'lodash'; - /** * WordPress dependencies */ @@ -14,6 +13,8 @@ import { FooterMessageControl, UnitControl, getValueAndUnit, + GlobalStylesContext, + alignmentHelpers, } from '@wordpress/components'; import { InspectorControls, @@ -23,7 +24,13 @@ import { BlockVariationPicker, } from '@wordpress/block-editor'; import { withDispatch, useSelect } from '@wordpress/data'; -import { useEffect, useState, useMemo } from '@wordpress/element'; +import { + useEffect, + useState, + useContext, + useMemo, + useCallback, +} from '@wordpress/element'; import { useResizeObserver } from '@wordpress/compose'; import { createBlock } from '@wordpress/blocks'; import { columns } from '@wordpress/icons'; @@ -39,8 +46,14 @@ import { toWidthPrecision, getWidths, getWidthWithUnit, + isPercentageUnit, CSS_UNITS, } from './utils'; +import { + getColumnsInRow, + calculateContainerWidth, + getContentWidths, +} from './columnCalculations.native'; import ColumnsPreview from '../column/column-preview'; /** @@ -69,17 +82,7 @@ const DEFAULT_COLUMNS_NUM = 2; */ const MIN_COLUMNS_NUM = 1; -/** - * Maximum number of columns in a row - * - * @type {number} - */ -const MAX_COLUMNS_NUM_IN_ROW = 3; - -const BREAKPOINTS = { - mobile: 480, - large: 768, -}; +const { isWider, isFullWidth } = alignmentHelpers; function ColumnsEditContainer( { attributes, @@ -87,71 +90,48 @@ function ColumnsEditContainer( { updateColumns, columnCount, isSelected, - onAddNextColumn, onDeleteBlock, innerColumns, updateInnerColumnWidth, + editorSidebarOpened, } ) { const [ resizeListener, sizes ] = useResizeObserver(); const [ columnsInRow, setColumnsInRow ] = useState( MIN_COLUMNS_NUM ); + const screenWidth = Math.floor( Dimensions.get( 'window' ).width ); + const globalStyles = useContext( GlobalStylesContext ); - const { verticalAlignment } = attributes; + const { verticalAlignment, align } = attributes; const { width } = sizes || {}; - const newColumnCount = columnCount || DEFAULT_COLUMNS_NUM; - useEffect( () => { - updateColumns( columnCount, newColumnCount ); - }, [] ); + if ( columnCount === 0 ) { + const newColumnCount = columnCount || DEFAULT_COLUMNS_NUM; - useEffect( () => { - if ( width ) { - setColumnsInRow( getColumnsInRow( width, newColumnCount ) ); + updateColumns( columnCount, newColumnCount ); } - }, [ columnCount ] ); + }, [] ); useEffect( () => { if ( width ) { - setColumnsInRow( getColumnsInRow( width, columnCount ) ); - } - }, [ width ] ); - - const contentStyle = useMemo( () => { - const minWidth = Math.min( width, styles.columnsContainer.maxWidth ); - const columnBaseWidth = minWidth / columnsInRow; - - let columnWidth = columnBaseWidth; - if ( columnsInRow > 1 ) { - const margins = - columnsInRow * - Math.min( columnsInRow, MAX_COLUMNS_NUM_IN_ROW ) * - styles.columnMargin.marginLeft; - columnWidth = ( minWidth - margins ) / columnsInRow; - } - return { width: columnWidth }; - }, [ width, columnsInRow ] ); - - const getColumnsInRow = ( containerWidth, columnsNumber ) => { - if ( containerWidth < BREAKPOINTS.mobile ) { - // show only 1 Column in row for mobile breakpoint container width - return 1; - } else if ( containerWidth < BREAKPOINTS.large ) { - // show the maximum number of columns in a row for large breakpoint container width - return Math.min( - Math.max( 1, columnCount ), - MAX_COLUMNS_NUM_IN_ROW - ); + if ( getColumnsInRow( width, columnCount ) !== columnsInRow ) { + setColumnsInRow( getColumnsInRow( width, columnCount ) ); + } } - // show all Column in one row - return Math.max( 1, columnsNumber ); - }; + }, [ width, columnCount ] ); const renderAppender = () => { + const isEqualWidth = width === screenWidth; + if ( isSelected ) { return ( - + ); @@ -159,6 +139,22 @@ function ColumnsEditContainer( { return null; }; + const contentWidths = useMemo( + () => + getContentWidths( + columnsInRow, + width, + columnCount, + innerColumns, + globalStyles + ), + [ width, columnsInRow, columnCount, innerColumns, globalStyles ] + ); + + const onAddBlock = useCallback( () => { + updateColumns( columnCount, columnCount + 1 ); + }, [ columnCount ] ); + const onChangeWidth = ( nextWidth, valueUnit, columnId ) => { const widthWithUnit = getWidthWithUnit( nextWidth, valueUnit ); @@ -166,13 +162,26 @@ function ColumnsEditContainer( { }; const onChangeUnit = ( nextUnit, index, columnId ) => { - const tempWidth = parseFloat( getWidths( innerColumns )[ index ] ); - const widthWithUnit = getWidthWithUnit( tempWidth, nextUnit ); + const widthWithoutUnit = parseFloat( + getWidths( innerColumns )[ index ] + ); + const widthWithUnit = getWidthWithUnit( widthWithoutUnit, nextUnit ); updateInnerColumnWidth( widthWithUnit, columnId ); }; + const onChange = ( nextWidth, valueUnit, columnId ) => { + if ( isPercentageUnit( valueUnit ) || ! valueUnit ) { + return; + } + onChangeWidth( nextWidth, valueUnit, columnId ); + }; + const getColumnsSliders = () => { + if ( ! editorSidebarOpened || ! isSelected ) { + return null; + } + return innerColumns.map( ( column, index ) => { const { valueUnit = '%' } = getValueAndUnit( column.attributes.width ) || {}; @@ -183,15 +192,22 @@ function ColumnsEditContainer( { getWidths( innerColumns ).length }` } min={ 1 } - max={ valueUnit === '%' || ! valueUnit ? 100 : undefined } + max={ + isPercentageUnit( valueUnit ) || ! valueUnit + ? 100 + : undefined + } decimalNum={ 1 } value={ getWidths( innerColumns )[ index ] } onChange={ ( nextWidth ) => { - onChangeWidth( nextWidth, valueUnit, column.clientId ); + onChange( nextWidth, valueUnit, column.clientId ); } } onUnitChange={ ( nextUnit ) => onChangeUnit( nextUnit, index, column.clientId ) } + onComplete={ ( nextWidth ) => { + onChangeWidth( nextWidth, valueUnit, column.clientId ); + } } unit={ valueUnit } units={ CSS_UNITS } preview={ @@ -247,12 +263,17 @@ function ColumnsEditContainer( { horizontal={ true } allowedBlocks={ ALLOWED_BLOCKS } contentResizeMode="stretch" - onAddBlock={ onAddNextColumn } + onAddBlock={ onAddBlock } onDeleteBlock={ columnCount === 1 ? onDeleteBlock : undefined } - contentStyle={ contentStyle } - parentWidth={ width } + blockWidth={ width } + contentStyle={ contentWidths } + parentWidth={ + isFullWidth( align ) && columnCount === 0 + ? screenWidth + : calculateContainerWidth( width, columnsInRow ) + } /> ) } diff --git a/packages/block-library/src/columns/editor.native.scss b/packages/block-library/src/columns/editor.native.scss index bae76a50d6d2e1..d212677477927a 100644 --- a/packages/block-library/src/columns/editor.native.scss +++ b/packages/block-library/src/columns/editor.native.scss @@ -1,5 +1,6 @@ .columnsContainer { - max-width: $content-width; + min-width: $block-edge-to-content * 2; + margin-left: $block-edge-to-content; } .innerBlocksSelected { @@ -10,3 +11,7 @@ margin: $block-edge-to-content / 2; } +.columnAppender { + margin-left: $grid-unit-20; + margin-right: $grid-unit-20; +} diff --git a/packages/block-library/src/columns/utils.js b/packages/block-library/src/columns/utils.js index 70fcc5841d41a0..0d9c5d9db59623 100644 --- a/packages/block-library/src/columns/utils.js +++ b/packages/block-library/src/columns/utils.js @@ -162,7 +162,7 @@ export function getWidths( blocks, withParsing = true ) { export function getWidthWithUnit( width, unit ) { width = 0 > parseFloat( width ) ? '0' : width; - if ( unit === '%' ) { + if ( isPercentageUnit( unit ) ) { width = Math.min( width, 100 ); } @@ -198,3 +198,14 @@ export const CSS_UNITS = [ default: '', }, ]; + +/** + * Returns a boolean whether passed unit is percentage + * + * @param {string} unit Column width unit. + * + * @return {boolean} Whether unit is '%'. + */ +export function isPercentageUnit( unit ) { + return unit === '%'; +} diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index 0ece7da318dc6a..c9aee9f8c1be7a 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -52,11 +52,6 @@ @import "./query/editor.scss"; @import "./post-featured-image/editor.scss"; -/** - * Import styles from internal editor components used by the blocks. - */ -@import "./block/edit-panel/editor.scss"; - :root .editor-styles-wrapper { // Background colors. @include background-colors(); diff --git a/packages/block-library/src/embed/variations.js b/packages/block-library/src/embed/variations.js index 34a1b8f66f43c9..02c68d0cb88cad 100644 --- a/packages/block-library/src/embed/variations.js +++ b/packages/block-library/src/embed/variations.js @@ -339,4 +339,16 @@ const variations = [ }, ]; +/** + * Add `isActive` function to all `embed` variations, if not defined. + * `isActive` function is used to find a variation match from a created + * Block by providing its attributes. + */ +variations.forEach( ( variation ) => { + if ( variation.isActive ) return; + variation.isActive = ( blockAttributes, variationAttributes ) => + blockAttributes.providerNameSlug === + variationAttributes.providerNameSlug; +} ); + export default variations; diff --git a/packages/block-library/src/gallery/edit.js b/packages/block-library/src/gallery/edit.js index 598f12ae2dd619..8482e29812516c 100644 --- a/packages/block-library/src/gallery/edit.js +++ b/packages/block-library/src/gallery/edit.js @@ -281,7 +281,7 @@ function GalleryEdit( props ) { }; } ); - setAttributes( { images: updatedImages, newSizeSlug } ); + setAttributes( { images: updatedImages, sizeSlug: newSizeSlug } ); } useEffect( () => { diff --git a/packages/block-library/src/gallery/gallery.native.js b/packages/block-library/src/gallery/gallery.native.js index d465ca7daa4d9a..e83e89417177f0 100644 --- a/packages/block-library/src/gallery/gallery.native.js +++ b/packages/block-library/src/gallery/gallery.native.js @@ -20,7 +20,7 @@ import { BlockCaption } from '@wordpress/block-editor'; import { useState, useEffect } from '@wordpress/element'; import { mediaUploadSync } from '@wordpress/react-native-bridge'; import { useSelect } from '@wordpress/data'; -import { WIDE_ALIGNMENTS } from '@wordpress/components'; +import { alignmentHelpers } from '@wordpress/components'; const TILE_SPACING = 15; @@ -28,6 +28,8 @@ const TILE_SPACING = 15; const MAX_DISPLAYED_COLUMNS = 4; const MAX_DISPLAYED_COLUMNS_NARROW = 2; +const { isFullWidth } = alignmentHelpers; + export const Gallery = ( props ) => { const [ isCaptionSelected, setIsCaptionSelected ] = useState( false ); useEffect( mediaUploadSync, [] ); @@ -84,8 +86,6 @@ export const Gallery = ( props ) => { onFocusGalleryCaption(); }; - const isFullWidth = align === WIDE_ALIGNMENTS.alignments.full; - return ( { ); } ) } - + { mediaPlaceholder } ( ), - [ align, hasInnerBlocks ] + [ align, hasInnerBlocks, width ] ); if ( ! isSelected && ! hasInnerBlocks ) { @@ -62,10 +76,6 @@ function GroupEdit( { - + { resizeObserver } + ); } @@ -87,7 +101,9 @@ export default compose( [ getBlock, getBlockIndex, hasSelectedInnerBlock, + getBlockRootClientId, getSelectedBlockClientId, + getBlockAttributes, } = select( 'core/block-editor' ); const block = getBlock( clientId ); @@ -104,9 +120,13 @@ export default compose( [ isLastInnerBlockSelected = totalInnerBlocks === blockIndex; } + const parentId = getBlockRootClientId( clientId ); + const parentBlockAlignment = getBlockAttributes( parentId )?.align; + return { hasInnerBlocks, isLastInnerBlockSelected, + parentBlockAlignment, }; } ), withPreferredColorScheme, diff --git a/packages/block-library/src/group/editor.native.scss b/packages/block-library/src/group/editor.native.scss index d33982b2b36bf9..af4616c8e74a5a 100644 --- a/packages/block-library/src/group/editor.native.scss +++ b/packages/block-library/src/group/editor.native.scss @@ -32,9 +32,14 @@ margin-right: $block-edge-to-content; } -.fullWidthAppender { - margin-left: $block-edge-to-content; - margin-right: $block-edge-to-content; +.groupAppender { + margin-left: $grid-unit-20; + margin-right: $grid-unit-20; +} + +.wideGroupAppender { + margin-left: $grid-unit-10; + margin-right: $grid-unit-10; } .hasBackgroundAppender { diff --git a/packages/block-library/src/html/edit.js b/packages/block-library/src/html/edit.js index c94ed81f3b5464..2f0cc65dde7ccc 100644 --- a/packages/block-library/src/html/edit.js +++ b/packages/block-library/src/html/edit.js @@ -49,7 +49,7 @@ export default function HTMLEdit( { attributes, setAttributes, isSelected } ) { } return ( -
+
+ href === undefined + ? setAttributes( restAttributes ) + : setAttributes( { ...restAttributes, href } ); + + const options = { + url: { + label: __( 'Image Link URL' ), + placeholder: __( 'Add URL' ), + autoFocus: false, + autoFill: true, + }, + openInNewTab: { + label: __( 'Open in new tab' ), + }, + linkRel: { + label: __( 'Link Rel' ), + placeholder: __( 'None' ), + }, + }; + + return ( + + ); + } + render() { const { isCaptionSelected } = this.state; const { @@ -347,16 +388,7 @@ export class ImageEdit extends React.Component { imageSizes, clientId, } = this.props; - const { - align, - url, - alt, - href, - id, - linkTarget, - sizeSlug, - className, - } = attributes; + const { align, url, alt, id, sizeSlug, className } = attributes; const sizeOptions = map( imageSizes, ( { name, slug } ) => ( { value: slug, @@ -392,22 +424,6 @@ export class ImageEdit extends React.Component { ) } - - { image && sizeOptionsValid && ( + + { this.getLinkSettings( true ) } + ); diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js index 27891132e9bca3..808c02b30afdbe 100644 --- a/packages/block-library/src/image/image.js +++ b/packages/block-library/src/image/image.js @@ -29,7 +29,7 @@ import { MediaReplaceFlow, } from '@wordpress/block-editor'; import { useEffect, useState, useRef } from '@wordpress/element'; -import { __, sprintf } from '@wordpress/i18n'; +import { __, sprintf, isRTL } from '@wordpress/i18n'; import { getPath } from '@wordpress/url'; import { createBlock } from '@wordpress/blocks'; import { crop, upload } from '@wordpress/icons'; @@ -102,22 +102,17 @@ export default function Image( { }, [ id, isSelected ] ); - const { - imageEditing, - imageSizes, - isRTL, - maxWidth, - mediaUpload, - } = useSelect( ( select ) => { - const { getSettings } = select( 'core/block-editor' ); - return pick( getSettings(), [ - 'imageEditing', - 'imageSizes', - 'isRTL', - 'maxWidth', - 'mediaUpload', - ] ); - } ); + const { imageEditing, imageSizes, maxWidth, mediaUpload } = useSelect( + ( select ) => { + const { getSettings } = select( 'core/block-editor' ); + return pick( getSettings(), [ + 'imageEditing', + 'imageSizes', + 'maxWidth', + 'mediaUpload', + ] ); + } + ); const { toggleSelection } = useDispatch( 'core/block-editor' ); const { createErrorNotice, createSuccessNotice } = useDispatch( noticesStore @@ -456,7 +451,7 @@ export default function Image( { // When the image is centered, show both handles. showRightHandle = true; showLeftHandle = true; - } else if ( isRTL ) { + } else if ( isRTL() ) { // In RTL mode the image is on the right by default. // Show the right handle and hide the left handle only when it is // aligned left. Otherwise always show the left handle. diff --git a/packages/block-library/src/list/edit.js b/packages/block-library/src/list/edit.js index 867c0b1e03c272..b653e39e3dfb50 100644 --- a/packages/block-library/src/list/edit.js +++ b/packages/block-library/src/list/edit.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { __, _x } from '@wordpress/i18n'; +import { __, _x, isRTL } from '@wordpress/i18n'; import { createBlock } from '@wordpress/blocks'; import { RichText, @@ -29,7 +29,6 @@ import { formatOutdent, formatOutdentRTL, } from '@wordpress/icons'; -import { useSelect } from '@wordpress/data'; /** * Internal dependencies @@ -47,10 +46,6 @@ export default function ListEdit( { const { ordered, values, type, reversed, start } = attributes; const tagName = ordered ? 'ol' : 'ul'; - const isRTL = useSelect( ( select ) => { - return !! select( 'core/block-editor' ).getSettings().isRTL; - }, [] ); - const controls = ( { value, onChange, onFocus } ) => ( <> { isSelected && ( @@ -93,7 +88,7 @@ export default function ListEdit( { { - return !! select( 'core/block-editor' ).getSettings().isRTL; - }, [] ); - return ( - isRTL && ( + isRTL() && ( $classes ) ); - $output = sprintf( '
', esc_attr( $wrapper_attributes ) ) . '

' . get_the_excerpt( $block->context['postId'] ); + $output = sprintf( '

', $wrapper_attributes ) . '

' . get_the_excerpt( $block->context['postId'] ); if ( ! isset( $attributes['showMoreOnNewLine'] ) || $attributes['showMoreOnNewLine'] ) { $output .= '

' . '

' . $more_text . '

'; } else { diff --git a/packages/block-library/src/query-loop/edit.js b/packages/block-library/src/query-loop/edit.js index 4d62b24356bb59..370eb45e08a7d5 100644 --- a/packages/block-library/src/query-loop/edit.js +++ b/packages/block-library/src/query-loop/edit.js @@ -82,17 +82,19 @@ export default function QueryLoopEdit( { // When you insert this block outside of the edit site then store // does not exist therefore we check for its existence. + // TODO: remove this code, edit-site shouldn't be called in block-library. + // This creates a cycle dependency. if ( inherit && select( 'core/edit-site' ) ) { // This should be passed from the context exposed by edit site. - const { getTemplateId, getTemplateType } = select( + const { getEditedPostType, getEditedPostId } = select( 'core/edit-site' ); - if ( 'wp_template' === getTemplateType() ) { + if ( 'wp_template' === getEditedPostType() ) { const { slug } = select( 'core' ).getEntityRecord( 'postType', 'wp_template', - getTemplateId() + getEditedPostId() ); // Change the post-type if needed. diff --git a/packages/block-library/src/rss/editor.scss b/packages/block-library/src/rss/editor.scss index 48d14bc25631c5..aa6288897aea4b 100644 --- a/packages/block-library/src/rss/editor.scss +++ b/packages/block-library/src/rss/editor.scss @@ -1,9 +1,3 @@ -.wp-block-rss { - padding-left: 2.5em; - &.is-grid { - padding-left: 0; - } -} .wp-block-rss li a > div { display: inline; } diff --git a/packages/block-library/src/rss/style.scss b/packages/block-library/src/rss/style.scss index a2727bab04f560..3a3995cf6e384e 100644 --- a/packages/block-library/src/rss/style.scss +++ b/packages/block-library/src/rss/style.scss @@ -1,4 +1,9 @@ .wp-block-rss { + // This needs extra specificity due to the reset mixin on the parent: https://github.com/WordPress/gutenberg/blob/a250e9e5fe00dd5195624f96a3d924e7078951c3/packages/edit-post/src/style.scss#L54 + &.wp-block-rss { + box-sizing: border-box; + } + &.alignleft { /*rtl:ignore*/ margin-right: 2em; diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js index f19f2076eeaac8..39681475fad943 100644 --- a/packages/block-library/src/site-logo/edit.js +++ b/packages/block-library/src/site-logo/edit.js @@ -9,7 +9,7 @@ import { includes, pick } from 'lodash'; */ import { isBlobURL } from '@wordpress/blob'; import { useState, useRef } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; +import { __, isRTL } from '@wordpress/i18n'; import { Notice, PanelBody, @@ -63,7 +63,7 @@ const SiteLogo = ( { const classes = classnames( { 'is-transient': isBlobURL( logoUrl ), } ); - const { maxWidth, isRTL, title } = useSelect( ( select ) => { + const { maxWidth, title } = useSelect( ( select ) => { const { getSettings } = select( 'core/block-editor' ); const siteEntities = select( 'core' ).getEditedEntityRecord( 'root', @@ -71,7 +71,7 @@ const SiteLogo = ( { ); return { title: siteEntities.title, - ...pick( getSettings(), [ 'imageSizes', 'isRTL', 'maxWidth' ] ), + ...pick( getSettings(), [ 'imageSizes', 'maxWidth' ] ), }; } ); @@ -151,7 +151,7 @@ const SiteLogo = ( { // When the image is centered, show both handles. showRightHandle = true; showLeftHandle = true; - } else if ( isRTL ) { + } else if ( isRTL() ) { // In RTL mode the image is on the right by default. // Show the right handle and hide the left handle only when it is // aligned left. Otherwise always show the left handle. diff --git a/packages/block-library/src/site-logo/index.php b/packages/block-library/src/site-logo/index.php index 3b24c721a854ba..1d1659d20bc98d 100644 --- a/packages/block-library/src/site-logo/index.php +++ b/packages/block-library/src/site-logo/index.php @@ -33,7 +33,7 @@ function render_block_core_site_logo( $attributes ) { } $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) ); - $html = sprintf( '', $wrapper_attributes, $custom_logo ); + $html = sprintf( '
%s
', $wrapper_attributes, $custom_logo ); remove_filter( 'wp_get_attachment_image_src', $adjust_width_height_filter ); return $html; } diff --git a/packages/block-library/src/social-link/variations.js b/packages/block-library/src/social-link/variations.js index 4297ced3c41718..a2f259feaaabbd 100644 --- a/packages/block-library/src/social-link/variations.js +++ b/packages/block-library/src/social-link/variations.js @@ -304,4 +304,15 @@ const variations = [ }, ]; +/** + * Add `isActive` function to all `social link` variations, if not defined. + * `isActive` function is used to find a variation match from a created + * Block by providing its attributes. + */ +variations.forEach( ( variation ) => { + if ( variation.isActive ) return; + variation.isActive = ( blockAttributes, variationAttributes ) => + blockAttributes.service === variationAttributes.service; +} ); + export default variations; diff --git a/packages/block-library/src/tag-cloud/edit.js b/packages/block-library/src/tag-cloud/edit.js index e060c50d3f930b..431187b99b0dda 100644 --- a/packages/block-library/src/tag-cloud/edit.js +++ b/packages/block-library/src/tag-cloud/edit.js @@ -72,6 +72,6 @@ function TagCloudEdit( { attributes, setAttributes, taxonomies } ) { export default withSelect( ( select ) => { return { - taxonomies: select( 'core' ).getTaxonomies(), + taxonomies: select( 'core' ).getTaxonomies( { per_page: -1 } ), }; } )( TagCloudEdit ); diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index 8612244ff09840..eb95932528aee4 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -53,21 +53,10 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { value: [ 'typography', 'lineHeight' ], support: [ 'lineHeight' ], }, - paddingBottom: { - value: [ 'spacing', 'padding', 'bottom' ], - support: [ 'spacing', 'padding' ], - }, - paddingLeft: { - value: [ 'spacing', 'padding', 'left' ], - support: [ 'spacing', 'padding' ], - }, - paddingRight: { - value: [ 'spacing', 'padding', 'right' ], - support: [ 'spacing', 'padding' ], - }, - paddingTop: { - value: [ 'spacing', 'padding', 'top' ], + padding: { + value: [ 'spacing', 'padding' ], support: [ 'spacing', 'padding' ], + properties: [ 'top', 'right', 'bottom', 'left' ], }, textDecoration: { value: [ 'typography', 'textDecoration' ], diff --git a/packages/blocks/src/api/raw-handling/get-raw-transforms.js b/packages/blocks/src/api/raw-handling/get-raw-transforms.js new file mode 100644 index 00000000000000..cc7d77053a9101 --- /dev/null +++ b/packages/blocks/src/api/raw-handling/get-raw-transforms.js @@ -0,0 +1,24 @@ +/** + * External dependencies + */ +import { filter } from 'lodash'; + +/** + * Internal dependencies + */ +import { getBlockTransforms } from '../factory'; + +export function getRawTransforms() { + return filter( getBlockTransforms( 'from' ), { type: 'raw' } ).map( + ( transform ) => { + return transform.isMatch + ? transform + : { + ...transform, + isMatch: ( node ) => + transform.selector && + node.matches( transform.selector ), + }; + } + ); +} diff --git a/packages/blocks/src/api/raw-handling/html-to-blocks.js b/packages/blocks/src/api/raw-handling/html-to-blocks.js new file mode 100644 index 00000000000000..a3cdfae5168f52 --- /dev/null +++ b/packages/blocks/src/api/raw-handling/html-to-blocks.js @@ -0,0 +1,47 @@ +/** + * Internal dependencies + */ +import { createBlock, findTransform } from '../factory'; +import { getBlockAttributes } from '../parser'; +import { getRawTransforms } from './get-raw-transforms'; + +/** + * Converts HTML directly to blocks. Looks for a matching transform for each + * top-level tag. The HTML should be filtered to not have any text between + * top-level tags and formatted in a way that blocks can handle the HTML. + * + * @param {string} html HTML to convert. + * + * @return {Array} An array of blocks. + */ +export function htmlToBlocks( html ) { + const doc = document.implementation.createHTMLDocument( '' ); + + doc.body.innerHTML = html; + + return Array.from( doc.body.children ).map( ( node ) => { + const rawTransform = findTransform( + getRawTransforms(), + ( { isMatch } ) => isMatch( node ) + ); + + if ( ! rawTransform ) { + return createBlock( + // Should not be hardcoded. + 'core/html', + getBlockAttributes( 'core/html', node.outerHTML ) + ); + } + + const { transform, blockName } = rawTransform; + + if ( transform ) { + return transform( node ); + } + + return createBlock( + blockName, + getBlockAttributes( blockName, node.outerHTML ) + ); + } ); +} diff --git a/packages/blocks/src/api/raw-handling/index.js b/packages/blocks/src/api/raw-handling/index.js index f0e51d23dbb80c..3d062892e7fa7f 100644 --- a/packages/blocks/src/api/raw-handling/index.js +++ b/packages/blocks/src/api/raw-handling/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { flatMap, filter, compact } from 'lodash'; +import { flatMap, compact } from 'lodash'; /** * WordPress dependencies @@ -12,8 +12,8 @@ import { getPhrasingContentSchema } from '@wordpress/dom'; /** * Internal dependencies */ -import { createBlock, getBlockTransforms, findTransform } from '../factory'; -import { getBlockAttributes, parseWithGrammar } from '../parser'; +import { htmlToBlocks } from './html-to-blocks'; +import { parseWithGrammar } from '../parser'; import normaliseBlocks from './normalise-blocks'; import specialCommentConverter from './special-comment-converter'; import listReducer from './list-reducer'; @@ -31,63 +31,6 @@ export function deprecatedGetPhrasingContentSchema( context ) { return getPhrasingContentSchema( context ); } -function getRawTransformations() { - return filter( getBlockTransforms( 'from' ), { type: 'raw' } ).map( - ( transform ) => { - return transform.isMatch - ? transform - : { - ...transform, - isMatch: ( node ) => - transform.selector && - node.matches( transform.selector ), - }; - } - ); -} - -/** - * Converts HTML directly to blocks. Looks for a matching transform for each - * top-level tag. The HTML should be filtered to not have any text between - * top-level tags and formatted in a way that blocks can handle the HTML. - * - * @param {Object} $1 Named parameters. - * @param {string} $1.html HTML to convert. - * @param {Array} $1.rawTransforms Transforms that can be used. - * - * @return {Array} An array of blocks. - */ -function htmlToBlocks( { html, rawTransforms } ) { - const doc = document.implementation.createHTMLDocument( '' ); - - doc.body.innerHTML = html; - - return Array.from( doc.body.children ).map( ( node ) => { - const rawTransform = findTransform( rawTransforms, ( { isMatch } ) => - isMatch( node ) - ); - - if ( ! rawTransform ) { - return createBlock( - // Should not be hardcoded. - 'core/html', - getBlockAttributes( 'core/html', node.outerHTML ) - ); - } - - const { transform, blockName } = rawTransform; - - if ( transform ) { - return transform( node ); - } - - return createBlock( - blockName, - getBlockAttributes( blockName, node.outerHTML ) - ); - } ); -} - /** * Converts an HTML string to known blocks. * @@ -105,12 +48,7 @@ export function rawHandler( { HTML = '' } ) { // An array of HTML strings and block objects. The blocks replace matched // shortcodes. const pieces = shortcodeConverter( HTML ); - const rawTransforms = getRawTransformations(); - const phrasingContentSchema = getPhrasingContentSchema(); - const blockContentSchema = getBlockContentSchema( - rawTransforms, - phrasingContentSchema - ); + const blockContentSchema = getBlockContentSchema(); return compact( flatMap( pieces, ( piece ) => { @@ -137,7 +75,7 @@ export function rawHandler( { HTML = '' } ) { piece = deepFilterHTML( piece, filters, blockContentSchema ); piece = normaliseBlocks( piece ); - return htmlToBlocks( { html: piece, rawTransforms } ); + return htmlToBlocks( piece ); } ) ); } diff --git a/packages/blocks/src/api/raw-handling/paste-handler.js b/packages/blocks/src/api/raw-handling/paste-handler.js index 41129299cc354f..665cdc46136e9b 100644 --- a/packages/blocks/src/api/raw-handling/paste-handler.js +++ b/packages/blocks/src/api/raw-handling/paste-handler.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { flatMap, filter, compact } from 'lodash'; +import { flatMap, compact } from 'lodash'; /** * WordPress dependencies @@ -11,10 +11,10 @@ import { getPhrasingContentSchema, removeInvalidHTML } from '@wordpress/dom'; /** * Internal dependencies */ -import { createBlock, getBlockTransforms, findTransform } from '../factory'; +import { htmlToBlocks } from './html-to-blocks'; import { hasBlockSupport } from '../registration'; import { getBlockContent } from '../serializer'; -import { getBlockAttributes, parseWithGrammar } from '../parser'; +import { parseWithGrammar } from '../parser'; import normaliseBlocks from './normalise-blocks'; import specialCommentConverter from './special-comment-converter'; import commentRemover from './comment-remover'; @@ -68,63 +68,6 @@ function filterInlineHTML( HTML, preserveWhiteSpace ) { return HTML; } -function getRawTransformations() { - return filter( getBlockTransforms( 'from' ), { type: 'raw' } ).map( - ( transform ) => { - return transform.isMatch - ? transform - : { - ...transform, - isMatch: ( node ) => - transform.selector && - node.matches( transform.selector ), - }; - } - ); -} - -/** - * Converts HTML directly to blocks. Looks for a matching transform for each - * top-level tag. The HTML should be filtered to not have any text between - * top-level tags and formatted in a way that blocks can handle the HTML. - * - * @param {Object} $1 Named parameters. - * @param {string} $1.html HTML to convert. - * @param {Array} $1.rawTransforms Transforms that can be used. - * - * @return {Array} An array of blocks. - */ -function htmlToBlocks( { html, rawTransforms } ) { - const doc = document.implementation.createHTMLDocument( '' ); - - doc.body.innerHTML = html; - - return Array.from( doc.body.children ).map( ( node ) => { - const rawTransform = findTransform( rawTransforms, ( { isMatch } ) => - isMatch( node ) - ); - - if ( ! rawTransform ) { - return createBlock( - // Should not be hardcoded. - 'core/html', - getBlockAttributes( 'core/html', node.outerHTML ) - ); - } - - const { transform, blockName } = rawTransform; - - if ( transform ) { - return transform( node ); - } - - return createBlock( - blockName, - getBlockAttributes( blockName, node.outerHTML ) - ); - } ); -} - /** * Converts an HTML string to known blocks. Strips everything else. * @@ -222,13 +165,8 @@ export function pasteHandler( { return filterInlineHTML( HTML, preserveWhiteSpace ); } - const rawTransforms = getRawTransformations(); const phrasingContentSchema = getPhrasingContentSchema( 'paste' ); - const blockContentSchema = getBlockContentSchema( - rawTransforms, - phrasingContentSchema, - true - ); + const blockContentSchema = getBlockContentSchema( 'paste' ); const blocks = compact( flatMap( pieces, ( piece ) => { @@ -269,7 +207,7 @@ export function pasteHandler( { // Allows us to ask for this information when we get a report. console.log( 'Processed HTML piece:\n\n', piece ); - return htmlToBlocks( { html: piece, rawTransforms } ); + return htmlToBlocks( piece ); } ) ); diff --git a/packages/blocks/src/api/raw-handling/test/utils.js b/packages/blocks/src/api/raw-handling/test/utils.js index d6a800e5383a26..c414f3ae24eeeb 100644 --- a/packages/blocks/src/api/raw-handling/test/utils.js +++ b/packages/blocks/src/api/raw-handling/test/utils.js @@ -6,7 +6,7 @@ import deepFreeze from 'deep-freeze'; /** * Internal dependencies */ -import { getBlockContentSchema, isPlain } from '../utils'; +import { getBlockContentSchemaFromTransforms, isPlain } from '../utils'; import { store as mockStore } from '../../../store'; import { STORE_NAME as mockStoreName } from '../../../store/constants'; @@ -87,7 +87,9 @@ describe( 'getBlockContentSchema', () => { isMatch: undefined, }, }; - expect( getBlockContentSchema( transforms ) ).toEqual( output ); + expect( getBlockContentSchemaFromTransforms( transforms ) ).toEqual( + output + ); } ); it( 'should handle multiple raw transforms', () => { @@ -127,7 +129,9 @@ describe( 'getBlockContentSchema', () => { isMatch: preformattedIsMatch, }, }; - expect( getBlockContentSchema( transforms ) ).toEqual( output ); + expect( getBlockContentSchemaFromTransforms( transforms ) ).toEqual( + output + ); } ); it( 'should correctly merge the children', () => { @@ -165,7 +169,9 @@ describe( 'getBlockContentSchema', () => { }, }, }; - expect( getBlockContentSchema( transforms ) ).toEqual( output ); + expect( getBlockContentSchemaFromTransforms( transforms ) ).toEqual( + output + ); } ); it( 'should correctly merge the attributes', () => { @@ -197,6 +203,8 @@ describe( 'getBlockContentSchema', () => { attributes: [ 'data-chicken', 'data-ribs' ], }, }; - expect( getBlockContentSchema( transforms ) ).toEqual( output ); + expect( getBlockContentSchemaFromTransforms( transforms ) ).toEqual( + output + ); } ); } ); diff --git a/packages/blocks/src/api/raw-handling/utils.js b/packages/blocks/src/api/raw-handling/utils.js index 706bb566399b0b..7517e5ed1696b3 100644 --- a/packages/blocks/src/api/raw-handling/utils.js +++ b/packages/blocks/src/api/raw-handling/utils.js @@ -6,33 +6,21 @@ import { mapValues, mergeWith, isFunction } from 'lodash'; /** * WordPress dependencies */ -import { isPhrasingContent } from '@wordpress/dom'; +import { isPhrasingContent, getPhrasingContentSchema } from '@wordpress/dom'; /** * Internal dependencies */ import { hasBlockSupport } from '..'; +import { getRawTransforms } from './get-raw-transforms'; -/** - * Given raw transforms from blocks, merges all schemas into one. - * - * @param {Array} transforms Block transforms, of the `raw` type. - * @param {Object} phrasingContentSchema The phrasing content schema. - * @param {Object} isPaste Whether the context is pasting or not. - * - * @return {Object} A complete block content schema. - */ -export function getBlockContentSchema( - transforms, - phrasingContentSchema, - isPaste -) { +export function getBlockContentSchemaFromTransforms( transforms, context ) { + const phrasingContentSchema = getPhrasingContentSchema( context ); + const schemaArgs = { phrasingContentSchema, isPaste: context === 'paste' }; const schemas = transforms.map( ( { isMatch, blockName, schema } ) => { const hasAnchorSupport = hasBlockSupport( blockName, 'anchor' ); - schema = isFunction( schema ) - ? schema( { phrasingContentSchema, isPaste } ) - : schema; + schema = isFunction( schema ) ? schema( schemaArgs ) : schema; // If the block does not has anchor support and the transform does not // provides an isMatch we can return the schema right away. @@ -83,6 +71,19 @@ export function getBlockContentSchema( } ); } +/** + * Gets the block content schema, which is extracted and merged from all + * registered blocks with raw transfroms. + * + * @param {string} context Set to "paste" when in paste context, where the + * schema is more strict. + * + * @return {Object} A complete block content schema. + */ +export function getBlockContentSchema( context ) { + return getBlockContentSchemaFromTransforms( getRawTransforms(), context ); +} + /** * Checks wether HTML can be considered plain text. That is, it does not contain * any elements that are not line breaks. diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index d628cdfae0306c..7c1ce2c1643384 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -97,6 +97,14 @@ import { store as blocksStore } from '../store'; * @property {string[]} [keywords] An array of terms (which can be translated) * that help users discover the variation * while searching. + * @property {Function} [isActive] A function that accepts a block's attributes + * and the variation's attributes and determines + * if a variation is active. This function doesn't + * try to find a match dynamically based on all + * block's attributes, as in many cases some + * attributes are irrelevant. An example would + * be for `embed` block where we only care about + * `providerNameSlug` attribute's value. */ /** diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index d82af59b153430..1748317bc6bbf6 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -4,6 +4,9 @@ ## 12.0.0 (2020-12-17) +### Enhancements +- ComboboxControl: Deburr option labels before filter + ### Breaking Change - Introduce support for other units and advanced CSS properties on `FontSizePicker`. Provided the value passed to the `FontSizePicker` is a string or one of the size options passed is a string, onChange will start to be called with a string value instead of a number. On WordPress usage, font size options are now automatically converted to strings with the default "px" unit added. diff --git a/packages/components/src/alignment-matrix-control/index.js b/packages/components/src/alignment-matrix-control/index.js index cce4cd59a096a4..28e41f9c65d4f1 100644 --- a/packages/components/src/alignment-matrix-control/index.js +++ b/packages/components/src/alignment-matrix-control/index.js @@ -8,7 +8,7 @@ import { useCompositeState, Composite, CompositeGroup } from 'reakit'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, isRTL } from '@wordpress/i18n'; import { useInstanceId } from '@wordpress/compose'; import { useState, useEffect } from '@wordpress/element'; @@ -17,7 +17,6 @@ import { useState, useEffect } from '@wordpress/element'; */ import Cell from './cell'; import { Root, Row } from './styles/alignment-matrix-control-styles'; -import { useRTL } from '../utils/rtl'; import AlignmentMatrixControlIcon from './icon'; import { GRID, getItemId } from './utils'; @@ -41,14 +40,13 @@ export default function AlignmentMatrixControl( { ...props } ) { const [ immutableDefaultValue ] = useState( value ?? defaultValue ); - const isRTL = useRTL(); const baseId = useBaseId( id ); const initialCurrentId = getItemId( baseId, immutableDefaultValue ); const composite = useCompositeState( { baseId, currentId: initialCurrentId, - rtl: isRTL, + rtl: isRTL(), } ); const handleOnChange = ( nextValue ) => { diff --git a/packages/components/src/base-control/README.md b/packages/components/src/base-control/README.md index 7b20ced34734d9..854a2420c9497d 100644 --- a/packages/components/src/base-control/README.md +++ b/packages/components/src/base-control/README.md @@ -82,7 +82,7 @@ import { BaseControl } from '@wordpress/components'; const MyBaseControl = () => ( Author diff --git a/packages/components/src/combobox-control/index.js b/packages/components/src/combobox-control/index.js index d1434c1787cfd6..fdd406530ee297 100644 --- a/packages/components/src/combobox-control/index.js +++ b/packages/components/src/combobox-control/index.js @@ -2,7 +2,7 @@ * External dependencies */ import classnames from 'classnames'; - +import { deburr } from 'lodash'; /** * WordPress dependencies */ @@ -66,9 +66,11 @@ function ComboboxControl( { const matchingSuggestions = useMemo( () => { const startsWithMatch = []; const containsMatch = []; - const match = inputValue.toLocaleLowerCase(); + const match = deburr( inputValue.toLocaleLowerCase() ); options.forEach( ( option ) => { - const index = option.label.toLocaleLowerCase().indexOf( match ); + const index = deburr( option.label ) + .toLocaleLowerCase() + .indexOf( match ); if ( index === 0 ) { startsWithMatch.push( option ); } else if ( index > 0 ) { diff --git a/packages/components/src/combobox-control/stories/index.js b/packages/components/src/combobox-control/stories/index.js index a7f250e38573e1..8bca43c948fd34 100644 --- a/packages/components/src/combobox-control/stories/index.js +++ b/packages/components/src/combobox-control/stories/index.js @@ -276,17 +276,8 @@ function ComboboxControlWithState() { onChange={ setValue } label="Select a country" options={ filteredOptions } - onFilterValueChange={ ( filter ) => - setFilteredOptions( - countries - .filter( ( country ) => - country.name - .toLowerCase() - .startsWith( filter.toLowerCase() ) - ) - .slice( 0, 20 ) - .map( mapCountryOption ) - ) + onFilterValueChange={ () => + setFilteredOptions( countries.map( mapCountryOption ) ) } />

Value: { value }

diff --git a/packages/components/src/date-time/date.js b/packages/components/src/date-time/date.js index 0b1ba7c19aa5fc..6461cc00c9b902 100644 --- a/packages/components/src/date-time/date.js +++ b/packages/components/src/date-time/date.js @@ -10,12 +10,12 @@ import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerS * WordPress dependencies */ import { Component, createRef } from '@wordpress/element'; +import { isRTL } from '@wordpress/i18n'; /** * Module Constants */ const TIMEZONELESS_FORMAT = 'YYYY-MM-DDTHH:mm:ss'; -const isRTL = () => document.documentElement.dir === 'rtl'; class DatePicker extends Component { constructor() { diff --git a/packages/components/src/date-time/stories/index.js b/packages/components/src/date-time/stories/index.js index 1fa91a6470859c..e929e9ab999555 100644 --- a/packages/components/src/date-time/stories/index.js +++ b/packages/components/src/date-time/stories/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { boolean } from '@storybook/addon-knobs'; +import { boolean, button } from '@storybook/addon-knobs'; /** * WordPress dependencies @@ -11,7 +11,7 @@ import { useState } from '@wordpress/element'; /** * Internal dependencies */ -import { DateTimePicker } from '../'; +import DateTimePicker from '../'; export default { title: 'Components/DateTimePicker', @@ -34,3 +34,36 @@ export const _default = () => { const is12Hour = boolean( 'Is 12 hour (shows AM/PM)', false ); return ; }; + +// Date utils, for demo purposes. +const DAY_IN_MS = 24 * 60 * 60 * 1000; +const aFewDaysAfter = ( date ) => { + // eslint-disable-next-line no-restricted-syntax + return new Date( date.getTime() + ( 1 + Math.random() * 5 ) * DAY_IN_MS ); +}; + +const now = new Date(); + +export const WithDaysHighlighted = () => { + const [ date, setDate ] = useState( now ); + + const [ highlights, setHighlights ] = useState( [ + { date: aFewDaysAfter( now ) }, + ] ); + + button( 'Add random highlight', () => { + const lastHighlight = highlights[ highlights.length - 1 ]; + setHighlights( [ + ...highlights, + { date: aFewDaysAfter( lastHighlight.date ) }, + ] ); + } ); + + return ( + + ); +}; diff --git a/packages/components/src/date-time/stories/with-days-highlighted.js b/packages/components/src/date-time/stories/with-days-highlighted.js deleted file mode 100644 index 81838bea518381..00000000000000 --- a/packages/components/src/date-time/stories/with-days-highlighted.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * External dependencies - */ -import { button } from '@storybook/addon-knobs'; - -/** - * WordPress dependencies - */ -import { useState } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import { DateTimePicker } from '..'; - -export default { - title: 'Components/DateTimePicker', - component: DateTimePicker, -}; - -// Date utils, for demo purposes. -const DAY_IN_MS = 24 * 60 * 60 * 1000; -const aFewDaysAfter = ( date ) => { - // eslint-disable-next-line no-restricted-syntax - return new Date( date.getTime() + ( 1 + Math.random() * 5 ) * DAY_IN_MS ); -}; - -const now = new Date(); - -export const WithDaysHighlighted = () => { - const [ date, setDate ] = useState( now ); - - const [ highlights, setHighlights ] = useState( [ - { date: aFewDaysAfter( now ) }, - ] ); - - button( 'Add random highlight', () => { - const lastHighlight = highlights[ highlights.length - 1 ]; - setHighlights( [ - ...highlights, - { date: aFewDaysAfter( lastHighlight.date ) }, - ] ); - } ); - - return ( - - ); -}; diff --git a/packages/components/src/focal-point-picker/README.md b/packages/components/src/focal-point-picker/README.md index 9100e4734f2119..7989f7e8ec90c9 100644 --- a/packages/components/src/focal-point-picker/README.md +++ b/packages/components/src/focal-point-picker/README.md @@ -65,7 +65,7 @@ Autoplays HTML5 video. This only applies to video sources (`url`). - Type: `Object` - Required: Yes -An object describing the height and width of the image. Requires two paramaters: `height`, `width`. +An object describing the height and width of the image. Requires two parameters: `height`, `width`. ### `value` diff --git a/packages/components/src/higher-order/with-notices/README.md b/packages/components/src/higher-order/with-notices/README.md index 1ae0f1edab407b..a70d20eca4f75f 100644 --- a/packages/components/src/higher-order/with-notices/README.md +++ b/packages/components/src/higher-order/with-notices/README.md @@ -1,5 +1,38 @@ # withNotices +`withNotices` is a React [higher-order component](https://facebook.github.io/react/docs/higher-order-components.html) used typically in adding the ability to post notice messages within the original component. + +Wrapping the original component with `withNotices` encapsulates the component with the additional props `noticeOperations` and `noticeUI`. + +**noticeOperations** +Contains a number of useful functions to add notices to your site. + +# **createNotice** +Function passed down as a prop that adds a new notice. + +_Parameters_ +- _notice_ `object`: Notice to add. + +# **createErrorNotice** +Function passed as a prop that adds a new error notice. + +_Parameters_ +- _msg_ `string`: Error message of the notice. + + +# **removeAllNotices** +Function that removes all notices. + +# **removeNotice** +Function that removes notice by ID. + +_Parameters_ +- _id_ `string`: ID of notice to remove. + +#**noticeUi** +The rendered `NoticeList`. + + ## Usage ```jsx diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index ccfdaf84e17be1..57e33a8a0350f1 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -87,10 +87,12 @@ export { colorsUtils } from './mobile/color-settings/utils'; export { WIDE_ALIGNMENTS, ALIGNMENT_BREAKPOINTS, + alignmentHelpers, } from './mobile/utils/alignments'; // Hooks export { + convertUnitToMobile, useConvertUnitToMobile, getValueAndUnit, } from './mobile/utils/use-unit-converter-to-mobile'; diff --git a/packages/components/src/mobile/bottom-sheet/range-cell.native.js b/packages/components/src/mobile/bottom-sheet/range-cell.native.js index b7a37c66b9b61c..f041b2969fea3f 100644 --- a/packages/components/src/mobile/bottom-sheet/range-cell.native.js +++ b/packages/components/src/mobile/bottom-sheet/range-cell.native.js @@ -66,11 +66,12 @@ class BottomSheetRangeCell extends Component { } onChange( nextValue ) { - const { onChange } = this.props; + const { onChange, onComplete } = this.props; this.setState( { sliderValue: nextValue, } ); onChange( nextValue ); + onComplete( nextValue ); } render() { @@ -89,6 +90,7 @@ class BottomSheetRangeCell extends Component { thumbTintColor = ! isIOS && '#00669b', preview, cellContainerStyle, + onComplete, shouldDisplayTextInput = true, children, decimalNum, @@ -146,6 +148,7 @@ class BottomSheetRangeCell extends Component { maximumTrackTintColor={ maximumTrackTintColor } thumbTintColor={ thumbTintColor } onValueChange={ this.onChangeValue } + onSlidingComplete={ onComplete } ref={ ( slider ) => { this.sliderRef = slider; } } diff --git a/packages/components/src/mobile/bottom-sheet/range-text-input.native.js b/packages/components/src/mobile/bottom-sheet/range-text-input.native.js index 0be4ca8dbb5633..efb9e64d85125d 100644 --- a/packages/components/src/mobile/bottom-sheet/range-text-input.native.js +++ b/packages/components/src/mobile/bottom-sheet/range-text-input.native.js @@ -39,8 +39,11 @@ class RangeTextInput extends Component { this.onSubmitEditing = this.onSubmitEditing.bind( this ); this.onChangeText = this.onChangeText.bind( this ); - const { value, defaultValue, min } = props; - const initialValue = value || defaultValue || min; + const { value, defaultValue, min, decimalNum } = props; + const initialValue = toFixed( + value || defaultValue || min, + decimalNum + ); const fontScale = this.getFontScale(); @@ -128,13 +131,6 @@ class RangeTextInput extends Component { onChange( validValue ); } - onChangeValue( initialValue ) { - const { decimalNum } = this.props; - initialValue = toFixed( initialValue, decimalNum ); - this.setState( { inputValue: initialValue } ); - this.updateValue( initialValue ); - } - onChangeText( textValue ) { const { decimalNum } = this.props; const inputValue = removeNonDigit( textValue, decimalNum ); @@ -194,7 +190,7 @@ class RangeTextInput extends Component { const valueFinalStyle = [ ! isIOS ? inputBorderStyles : verticalBorderStyle, { - width: 40 * fontScale, + width: 50 * fontScale, }, ]; diff --git a/packages/components/src/mobile/link-settings/index.native.js b/packages/components/src/mobile/link-settings/index.native.js index ddd7b9e4ce58ad..4d5b2a496a2999 100644 --- a/packages/components/src/mobile/link-settings/index.native.js +++ b/packages/components/src/mobile/link-settings/index.native.js @@ -224,26 +224,30 @@ function LinkSettings( { onChange={ onChangeLabel } /> ) } - { options.openInNewTab && ( - - ) } - { options.linkRel && ( - + { !! urlInputValue && ( + <> + { options.openInNewTab && ( + + ) } + { options.linkRel && ( + + ) } + ) } ); diff --git a/packages/components/src/mobile/utils/alignments.native.js b/packages/components/src/mobile/utils/alignments.native.js index 03fdcbd93f5e86..219bdefb8a721c 100644 --- a/packages/components/src/mobile/utils/alignments.native.js +++ b/packages/components/src/mobile/utils/alignments.native.js @@ -3,7 +3,10 @@ export const WIDE_ALIGNMENTS = { wide: 'wide', full: 'full', }, - excludeBlocks: [ 'core/columns', 'core/heading' ], + // `innerContainers`: Group of blocks based on `InnerBlocks` component, + // used to nest other blocks inside + innerContainers: [ 'core/group', 'core/columns', 'core/column' ], + excludeBlocks: [ 'core/heading' ], }; export const ALIGNMENT_BREAKPOINTS = { @@ -11,4 +14,22 @@ export const ALIGNMENT_BREAKPOINTS = { large: 820, medium: 768, small: 680, + mobile: 480, +}; + +const isFullWidth = ( align ) => align === WIDE_ALIGNMENTS.alignments.full; + +const isWideWidth = ( align ) => align === WIDE_ALIGNMENTS.alignments.wide; + +const isWider = ( width, breakpoint ) => + width > ALIGNMENT_BREAKPOINTS[ breakpoint ]; + +const isContainerRelated = ( blockName ) => + WIDE_ALIGNMENTS.innerContainers.includes( blockName ); + +export const alignmentHelpers = { + isFullWidth, + isWideWidth, + isWider, + isContainerRelated, }; diff --git a/packages/components/src/mobile/utils/use-unit-converter-to-mobile.native.js b/packages/components/src/mobile/utils/use-unit-converter-to-mobile.native.js index ec34c1b7880217..cf8a77b8d0e561 100644 --- a/packages/components/src/mobile/utils/use-unit-converter-to-mobile.native.js +++ b/packages/components/src/mobile/utils/use-unit-converter-to-mobile.native.js @@ -35,7 +35,32 @@ const getValueAndUnit = ( value, unit ) => { return undefined; }; +const convertUnitToMobile = ( containerSize, globalStyles, value, unit ) => { + const { width, height } = containerSize; + const { valueToConvert, valueUnit } = getValueAndUnit( value, unit ); + const { fontSize = 16 } = globalStyles || {}; + + switch ( valueUnit ) { + case 'rem': + case 'em': + return valueToConvert * fontSize; + case '%': + return Number( valueToConvert / 100 ) * width; + case 'px': + return Number( valueToConvert ); + case 'vw': + const vw = width / 100; + return Math.round( valueToConvert * vw ); + case 'vh': + const vh = height / 100; + return Math.round( valueToConvert * vh ); + default: + return Number( valueToConvert / 100 ) * width; + } +}; + const useConvertUnitToMobile = ( value, unit ) => { + const { globalStyles: styles } = useContext( GlobalStylesContext ); const [ windowSizes, setWindowSizes ] = useState( Dimensions.get( 'window' ) ); @@ -47,36 +72,21 @@ const useConvertUnitToMobile = ( value, unit ) => { Dimensions.removeEventListener( 'change', onDimensionsChange ); }; }, [] ); - const { globalStyles: styles } = useContext( GlobalStylesContext ); const onDimensionsChange = useCallback( ( { window } ) => { setWindowSizes( window ); }, [] ); return useMemo( () => { - const { width, height } = windowSizes; - const { fontSize = 16 } = styles || {}; - const { valueToConvert, valueUnit } = getValueAndUnit( value, unit ); - switch ( valueUnit ) { - case 'rem': - case 'em': - return valueToConvert * fontSize; - case '%': - return Number( valueToConvert / 100 ) * width; - case 'px': - return Number( valueToConvert ); - case 'vw': - const vw = width / 100; - return Math.round( valueToConvert * vw ); - case 'vh': - const vh = height / 100; - return Math.round( valueToConvert * vh ); - default: - return Number( valueToConvert / 100 ) * width; - } + return convertUnitToMobile( + windowSizes, + styles, + valueToConvert, + valueUnit + ); }, [ windowSizes, value, unit ] ); }; -export { useConvertUnitToMobile, getValueAndUnit }; +export { convertUnitToMobile, useConvertUnitToMobile, getValueAndUnit }; diff --git a/packages/components/src/navigation/back-button/index.js b/packages/components/src/navigation/back-button/index.js index 9a5d750681ff3f..c52932bb8e8624 100644 --- a/packages/components/src/navigation/back-button/index.js +++ b/packages/components/src/navigation/back-button/index.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; * WordPress dependencies */ import { forwardRef } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; +import { __, isRTL } from '@wordpress/i18n'; import { Icon, chevronLeft, chevronRight } from '@wordpress/icons'; /** @@ -14,7 +14,6 @@ import { Icon, chevronLeft, chevronRight } from '@wordpress/icons'; */ import { useNavigationContext } from '../context'; import { MenuBackButtonUI } from '../styles/navigation-styles'; -import { getRTL } from '../../utils/rtl'; function NavigationBackButton( { backButtonLabel, className, href, onClick, parentMenu }, @@ -34,12 +33,12 @@ function NavigationBackButton( onClick( event ); } - const animationDirection = getRTL() ? 'left' : 'right'; + const animationDirection = isRTL() ? 'left' : 'right'; if ( parentMenu && ! event.defaultPrevented ) { setActiveMenu( parentMenu, animationDirection ); } }; - const icon = getRTL() ? chevronRight : chevronLeft; + const icon = isRTL() ? chevronRight : chevronLeft; return ( { title } diff --git a/packages/components/src/navigation/index.js b/packages/components/src/navigation/index.js index 859a20319ccec3..8f9f2bba506c36 100644 --- a/packages/components/src/navigation/index.js +++ b/packages/components/src/navigation/index.js @@ -8,6 +8,7 @@ import { noop } from 'lodash'; * WordPress dependencies */ import { useEffect, useRef, useState } from '@wordpress/element'; +import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies @@ -17,7 +18,6 @@ import { ROOT_MENU } from './constants'; import { NavigationContext } from './context'; import { NavigationUI } from './styles/navigation-styles'; import { useCreateNavigationTree } from './use-create-navigation-tree'; -import { useRTL } from '../utils/rtl'; export default function Navigation( { activeItem, @@ -29,7 +29,7 @@ export default function Navigation( { const [ menu, setMenu ] = useState( activeMenu ); const [ slideOrigin, setSlideOrigin ] = useState(); const navigationTree = useCreateNavigationTree(); - const defaultSlideOrigin = useRTL() ? 'right' : 'left'; + const defaultSlideOrigin = isRTL() ? 'right' : 'left'; const setActiveMenu = ( menuId, slideInOrigin = defaultSlideOrigin ) => { if ( ! navigationTree.getMenu( menuId ) ) { diff --git a/packages/components/src/navigation/item/base-content.js b/packages/components/src/navigation/item/base-content.js index 93c8aef9193391..f4b6fc5b41a8a8 100644 --- a/packages/components/src/navigation/item/base-content.js +++ b/packages/components/src/navigation/item/base-content.js @@ -1,12 +1,10 @@ /** * Internal dependencies */ -import { useRTL } from '../../utils'; import { ItemBadgeUI, ItemTitleUI } from '../styles/navigation-styles'; export default function NavigationItemBaseContent( props ) { const { badge, title } = props; - const isRTL = useRTL(); return ( <> @@ -14,7 +12,6 @@ export default function NavigationItemBaseContent( props ) { { title } @@ -22,10 +19,7 @@ export default function NavigationItemBaseContent( props ) { ) } { badge && ( - + { badge } ) } diff --git a/packages/components/src/navigation/item/index.js b/packages/components/src/navigation/item/index.js index 4514633b3d4593..625a5f3cb7265a 100644 --- a/packages/components/src/navigation/item/index.js +++ b/packages/components/src/navigation/item/index.js @@ -8,6 +8,7 @@ import { noop } from 'lodash'; * WordPress dependencies */ import { Icon, chevronLeft, chevronRight } from '@wordpress/icons'; +import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies @@ -15,7 +16,6 @@ import { Icon, chevronLeft, chevronRight } from '@wordpress/icons'; import Button from '../../button'; import { useNavigationContext } from '../context'; import { ItemUI } from '../styles/navigation-styles'; -import { useRTL } from '../../utils/rtl'; import NavigationItemBaseContent from './base-content'; import NavigationItemBase from './base'; @@ -39,7 +39,6 @@ export default function NavigationItem( props ) { setActiveMenu, navigationTree: { isMenuEmpty }, } = useNavigationContext(); - const isRTL = useRTL(); // If hideIfTargetMenuEmpty prop is true // And the menu we are supposed to navigate to @@ -63,7 +62,7 @@ export default function NavigationItem( props ) { onClick( event ); }; - const icon = isRTL ? chevronLeft : chevronRight; + const icon = isRTL() ? chevronLeft : chevronRight; const baseProps = isText ? restProps : { as: Button, href, onClick: onItemClick, ...restProps }; diff --git a/packages/components/src/navigation/menu/menu-title.js b/packages/components/src/navigation/menu/menu-title.js index 7d36f01cf85d19..2cb860c2758d37 100644 --- a/packages/components/src/navigation/menu/menu-title.js +++ b/packages/components/src/navigation/menu/menu-title.js @@ -18,7 +18,6 @@ import { } from '../styles/navigation-styles'; import { useNavigationMenuContext } from './context'; import { SEARCH_FOCUS_DELAY } from '../constants'; -import { useRTL } from '../../utils/rtl'; export default function NavigationMenuTitle( { hasSearch, @@ -30,7 +29,6 @@ export default function NavigationMenuTitle( { const [ isSearching, setIsSearching ] = useState( false ); const { menu } = useNavigationMenuContext(); const searchButtonRef = useRef(); - const isRTL = useRTL(); if ( ! title ) { return null; @@ -57,7 +55,6 @@ export default function NavigationMenuTitle( { as="h2" className="components-navigation__menu-title-heading" variant="title.small" - isRTL={ isRTL } > { title } diff --git a/packages/components/src/navigation/styles/navigation-styles.js b/packages/components/src/navigation/styles/navigation-styles.js index 65d2c1f2151def..4e5c76ad36206f 100644 --- a/packages/components/src/navigation/styles/navigation-styles.js +++ b/packages/components/src/navigation/styles/navigation-styles.js @@ -3,6 +3,11 @@ */ import styled from '@emotion/styled'; +/** + * WordPress dependencies + */ +import { isRTL } from '@wordpress/i18n'; + /** * Internal dependencies */ @@ -66,8 +71,8 @@ export const MenuTitleHeadingUI = styled( Text )` display: flex; justify-content: space-between; margin-bottom: ${ space( 1 ) }; - padding: ${ ( props ) => - props.isRTL + padding: ${ () => + isRTL() ? `${ space( 0.5 ) } ${ space( 2 ) } ${ space( 0.5 ) } ${ space( 1.5 ) }` @@ -139,8 +144,8 @@ export const MenuTitleSearchUI = styled.div` export const GroupTitleUI = styled( Text )` margin-top: ${ space( 1 ) }; - padding: ${ ( props ) => - props.isRTL + padding: ${ () => + isRTL() ? `${ space( 0.5 ) } ${ space( 2 ) } ${ space( 0.5 ) } 0` : `${ space( 0.5 ) } 0 ${ space( 0.5 ) } ${ space( 2 ) }` }; text-transform: uppercase; @@ -190,8 +195,8 @@ export const ItemUI = styled.div` `; export const ItemBadgeUI = styled.span` - margin-left: ${ ( props ) => ( props.isRTL ? '0' : space( 1 ) ) }; - margin-right: ${ ( props ) => ( props.isRTL ? space( 1 ) : '0' ) }; + margin-left: ${ () => ( isRTL() ? '0' : space( 1 ) ) }; + margin-right: ${ () => ( isRTL() ? space( 1 ) : '0' ) }; display: inline-flex; padding: ${ space( 0.5 ) } ${ space( 1.5 ) }; border-radius: 2px; @@ -210,7 +215,6 @@ export const ItemBadgeUI = styled.span` `; export const ItemTitleUI = styled( Text )` - ${ ( props ) => - props.isRTL ? 'margin-left: auto;' : 'margin-right: auto;' } + ${ () => ( isRTL() ? 'margin-left: auto;' : 'margin-right: auto;' ) } font-size: 13px; `; diff --git a/packages/components/src/number-control/index.js b/packages/components/src/number-control/index.js index b3b7944123d25a..cbcca8ed0e20f1 100644 --- a/packages/components/src/number-control/index.js +++ b/packages/components/src/number-control/index.js @@ -7,6 +7,7 @@ import classNames from 'classnames'; * WordPress dependencies */ import { forwardRef } from '@wordpress/element'; +import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies @@ -16,7 +17,6 @@ import { inputControlActionTypes, composeStateReducers, } from '../input-control/state'; -import { useRTL } from '../utils/style-mixins'; import { add, subtract, roundClamp } from '../utils/math'; import { useJumpStep } from '../utils/hooks'; import { isValueEmpty } from '../utils/values'; @@ -40,7 +40,6 @@ export function NumberControl( }, ref ) { - const isRtl = useRTL(); const baseValue = roundClamp( 0, min, max, step ); const jumpStep = useJumpStep( { @@ -120,7 +119,7 @@ export function NumberControl( case 'e': directionBaseValue = x; - directionModifier = isRtl ? -1 : 1; + directionModifier = isRTL() ? -1 : 1; break; case 's': @@ -130,7 +129,7 @@ export function NumberControl( case 'w': directionBaseValue = x; - directionModifier = isRtl ? 1 : -1; + directionModifier = isRTL() ? 1 : -1; break; } diff --git a/packages/components/src/popover/README.md b/packages/components/src/popover/README.md index a45dfc701ebcd2..f31c90a56ca262 100644 --- a/packages/components/src/popover/README.md +++ b/packages/components/src/popover/README.md @@ -138,7 +138,7 @@ A callback function which is used to override the anchor value computation algor If you need the `DOMRect` object i.e., the position of popover to be calculated on every time, the popover re-renders, then use `getAnchorRect`. -`getAnchorRect` callback function receives a reference to the popover anchor element as a function parameter and it should return a `DOMRect` objcet. +`getAnchorRect` callback function receives a reference to the popover anchor element as a function parameter and it should return a `DOMRect` object. - Type: `Function` - Required: No diff --git a/packages/components/src/popover/utils.js b/packages/components/src/popover/utils.js index 6f566916c66c7e..e807274b774826 100644 --- a/packages/components/src/popover/utils.js +++ b/packages/components/src/popover/utils.js @@ -1,3 +1,8 @@ +/** + * WordPress dependencies + */ +import { isRTL } from '@wordpress/i18n'; + /** * Module constants */ @@ -30,18 +35,17 @@ export function computePopoverXAxisPosition( forcePosition ) { const { width } = contentSize; - const isRTL = document.documentElement.dir === 'rtl'; // Correct xAxis for RTL support - if ( xAxis === 'left' && isRTL ) { + if ( xAxis === 'left' && isRTL() ) { xAxis = 'right'; - } else if ( xAxis === 'right' && isRTL ) { + } else if ( xAxis === 'right' && isRTL() ) { xAxis = 'left'; } - if ( corner === 'left' && isRTL ) { + if ( corner === 'left' && isRTL() ) { corner = 'right'; - } else if ( corner === 'right' && isRTL ) { + } else if ( corner === 'right' && isRTL() ) { corner = 'left'; } diff --git a/packages/components/src/range-control/README.md b/packages/components/src/range-control/README.md index f5e38538369823..0ebf28bb67a1eb 100644 --- a/packages/components/src/range-control/README.md +++ b/packages/components/src/range-control/README.md @@ -213,7 +213,7 @@ const MyRangeControl() { #### onChange -A function that receives the new value. The value will be less than `max` and more than `min` unless a reset (enabled by `allowReset`) has occured. In which case the value will be either that of `resetFallbackValue` if it has been specified or otherwise `undefined`. +A function that receives the new value. The value will be less than `max` and more than `min` unless a reset (enabled by `allowReset`) has occurred. In which case the value will be either that of `resetFallbackValue` if it has been specified or otherwise `undefined`. - Type: `function` - Required: Yes diff --git a/packages/components/src/range-control/index.js b/packages/components/src/range-control/index.js index 543d25accfcfbd..976ec27b40cc97 100644 --- a/packages/components/src/range-control/index.js +++ b/packages/components/src/range-control/index.js @@ -7,7 +7,7 @@ import { clamp, isFinite, noop } from 'lodash'; /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, isRTL } from '@wordpress/i18n'; import { useRef, useState, forwardRef } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; @@ -33,7 +33,6 @@ import { Thumb, Wrapper, } from './styles/range-control-styles'; -import { useRTL } from '../utils/rtl'; function RangeControl( { @@ -69,8 +68,6 @@ function RangeControl( }, ref ) { - const isRTL = useRTL(); - const [ value, setValue ] = useControlledRangeValue( { min, max, @@ -190,7 +187,7 @@ function RangeControl( }; const offsetStyle = { - [ isRTL ? 'right' : 'left' ]: fillValueOffset, + [ isRTL() ? 'right' : 'left' ]: fillValueOffset, }; return ( @@ -200,7 +197,7 @@ function RangeControl( id={ id } help={ help } > - + { beforeIcon && ( diff --git a/packages/components/src/range-control/rail.js b/packages/components/src/range-control/rail.js index 51c188e8f46493..8f1794883e2dd5 100644 --- a/packages/components/src/range-control/rail.js +++ b/packages/components/src/range-control/rail.js @@ -1,3 +1,8 @@ +/** + * WordPress dependencies + */ +import { isRTL } from '@wordpress/i18n'; + /** * Internal dependencies */ @@ -58,8 +63,6 @@ function Marks( { } function useMarks( { marks, min = 0, max = 100, step = 1, value = 0 } ) { - const isRTL = document.documentElement.dir === 'rtl'; - if ( ! marks ) { return []; } @@ -81,7 +84,7 @@ function useMarks( { marks, min = 0, max = 100, step = 1, value = 0 } ) { const offset = `${ ( ( mark.value - min ) / range ) * 100 }%`; const offsetStyle = { - [ isRTL ? 'right' : 'left' ]: offset, + [ isRTL() ? 'right' : 'left' ]: offset, }; placedMarks.push( { diff --git a/packages/components/src/range-control/stories/index.js b/packages/components/src/range-control/stories/index.js index e91fde04b8fbc3..f65983161c5a3b 100644 --- a/packages/components/src/range-control/stories/index.js +++ b/packages/components/src/range-control/stories/index.js @@ -7,7 +7,7 @@ import { boolean, number, text } from '@storybook/addon-knobs'; /** * WordPress dependencies */ -import { useEffect, useState } from '@wordpress/element'; +import { useState } from '@wordpress/element'; /** * Internal dependencies @@ -25,7 +25,6 @@ const RangeControlWithState = ( props ) => { }; const DefaultExample = () => { - const [ isRtl, setIsRtl ] = useState( false ); const [ value, setValue ] = useState( undefined ); const props = { @@ -48,26 +47,6 @@ const DefaultExample = () => { onChange: setValue, }; - const rtl = boolean( 'RTL', false ); - - useEffect( () => { - if ( rtl !== isRtl ) { - setIsRtl( rtl ); - } - }, [ rtl, isRtl ] ); - - useEffect( () => { - if ( isRtl ) { - document.documentElement.setAttribute( 'dir', 'rtl' ); - } else { - document.documentElement.setAttribute( 'dir', 'ltr' ); - } - - return () => { - document.documentElement.setAttribute( 'dir', 'ltr' ); - }; - }, [ isRtl ] ); - return ( diff --git a/packages/components/src/resizable-box/resize-tooltip/label.js b/packages/components/src/resizable-box/resize-tooltip/label.js index b63e4fd9e50c62..d95c73f335daff 100644 --- a/packages/components/src/resizable-box/resize-tooltip/label.js +++ b/packages/components/src/resizable-box/resize-tooltip/label.js @@ -2,12 +2,12 @@ * WordPress dependencies */ import { forwardRef } from '@wordpress/element'; +import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies */ import { POSITIONS } from './utils'; -import { useRTL } from '../../utils/style-mixins'; import { TooltipWrapper, Tooltip, @@ -21,8 +21,6 @@ function Label( { label, position = POSITIONS.corner, zIndex = 1000, ...props }, ref ) { - const isRTL = useRTL(); - const showLabel = !! label; const isBottom = position === POSITIONS.bottom; @@ -56,8 +54,8 @@ function Label( ...style, position: 'absolute', top: CORNER_OFFSET, - right: isRTL ? null : CORNER_OFFSET, - left: isRTL ? CORNER_OFFSET : null, + right: isRTL() ? null : CORNER_OFFSET, + left: isRTL() ? CORNER_OFFSET : null, }; } diff --git a/packages/components/src/text-highlight/README.md b/packages/components/src/text-highlight/README.md index e8a1e4be5d8429..91ed7021fd4628 100644 --- a/packages/components/src/text-highlight/README.md +++ b/packages/components/src/text-highlight/README.md @@ -1,12 +1,12 @@ # TextHighlight -Highlights occurances of a given string within another string of text. Wraps each match with a [`` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark) which provides browser default styling. +Highlights occurrences of a given string within another string of text. Wraps each match with a [`` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark) which provides browser default styling. ## Usage -Pass in the `text` and the `highlight` string to be matched against. +Pass in the `text` and the `highlight` string to be matched against. -In the example below, the string `Gutenberg` would be highlighted twice. +In the example below, the string `Gutenberg` would be highlighted twice. ```jsx import { TextHighlight } from '@wordpress/components'; @@ -21,11 +21,11 @@ const MyTextHighlight = () => ( ## Props -The component accepts the following props. +The component accepts the following props. ### text -The string of text to be tested for occurances of then given `highlight`. +The string of text to be tested for occurrences of then given `highlight`. - Type: `String` - Required: Yes diff --git a/packages/components/src/toolbar-button/README.md b/packages/components/src/toolbar-button/README.md index 5d7f8f1fb19551..1ddccac0c75fa0 100644 --- a/packages/components/src/toolbar-button/README.md +++ b/packages/components/src/toolbar-button/README.md @@ -27,7 +27,7 @@ function MyToolbar() { ### Inside BlockControls -If you're working on a custom block and you want to add controls to the block toolbar, you should use [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md) instead. Optinally wrapping it with [ToolbarGroup](/packages/components/src/toolbar-group/README.md). +If you're working on a custom block and you want to add controls to the block toolbar, you should use [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md) instead. Optionally wrapping it with [ToolbarGroup](/packages/components/src/toolbar-group/README.md). ```jsx import { BlockControls } from '@wordpress/block-editor'; diff --git a/packages/components/src/toolbar-item/README.md b/packages/components/src/toolbar-item/README.md index db6d38da041688..1df563778a0e11 100644 --- a/packages/components/src/toolbar-item/README.md +++ b/packages/components/src/toolbar-item/README.md @@ -49,7 +49,7 @@ function MyToolbar() { ### Inside BlockControls -If you're working on a custom block and you want to add controls to the block toolbar, you should use [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md) instead. Optinally wrapping it with [ToolbarGroup](/packages/components/src/toolbar-group/README.md). +If you're working on a custom block and you want to add controls to the block toolbar, you should use [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md) instead. Optionally wrapping it with [ToolbarGroup](/packages/components/src/toolbar-group/README.md). ```jsx import { BlockControls } from '@wordpress/block-editor'; diff --git a/packages/components/src/toolbar/toolbar-container.js b/packages/components/src/toolbar/toolbar-container.js index df4f29c5afc799..4e39fb0990677b 100644 --- a/packages/components/src/toolbar/toolbar-container.js +++ b/packages/components/src/toolbar/toolbar-container.js @@ -7,12 +7,12 @@ import { useToolbarState, Toolbar } from 'reakit/Toolbar'; * WordPress dependencies */ import { forwardRef } from '@wordpress/element'; +import { isRTL } from '@wordpress/i18n'; /** * Internal dependencies */ import ToolbarContext from '../toolbar-context'; -import { getRTL } from '../utils/rtl'; function ToolbarContainer( { label, ...props }, ref ) { // https://reakit.io/docs/basic-concepts/#state-hooks @@ -21,7 +21,7 @@ function ToolbarContainer( { label, ...props }, ref ) { const toolbarState = useToolbarState( { loop: true, baseId: props.id, - rtl: getRTL(), + rtl: isRTL(), } ); return ( diff --git a/packages/components/src/utils/rtl.js b/packages/components/src/utils/rtl.js index 89fefa7508b65c..7e46a4bf6a2725 100644 --- a/packages/components/src/utils/rtl.js +++ b/packages/components/src/utils/rtl.js @@ -4,29 +4,16 @@ import { css } from '@emotion/core'; import { mapKeys } from 'lodash'; +/** + * WordPress dependencies + */ +import { isRTL } from '@wordpress/i18n'; + const LOWER_LEFT_REGEXP = new RegExp( /-left/g ); const LOWER_RIGHT_REGEXP = new RegExp( /-right/g ); const UPPER_LEFT_REGEXP = new RegExp( /Left/g ); const UPPER_RIGHT_REGEXP = new RegExp( /Right/g ); -/** - * Checks to see whether the document is set to rtl. - * - * @return {boolean} Whether document is RTL. - */ -export function getRTL() { - return !! ( document && document.documentElement.dir === 'rtl' ); -} - -/** - * Simple hook to retrieve RTL direction value - * - * @return {boolean} Whether document is RTL. - */ -export function useRTL() { - return getRTL(); -} - /** * Flips a CSS property from left <-> right. * @@ -83,14 +70,12 @@ export const convertLTRToRTL = ( ltrStyles = {} ) => { */ export function rtl( ltrStyles = {}, rtlStyles ) { return () => { - const isRTL = getRTL(); - if ( rtlStyles ) { // @ts-ignore: `css` types are wrong, it can accept an object: https://emotion.sh/docs/object-styles#with-css - return isRTL ? css( rtlStyles ) : css( ltrStyles ); + return isRTL() ? css( rtlStyles ) : css( ltrStyles ); } // @ts-ignore: `css` types are wrong, it can accept an object: https://emotion.sh/docs/object-styles#with-css - return isRTL ? css( convertLTRToRTL( ltrStyles ) ) : css( ltrStyles ); + return isRTL() ? css( convertLTRToRTL( ltrStyles ) ) : css( ltrStyles ); }; } diff --git a/packages/components/src/utils/style-mixins.js b/packages/components/src/utils/style-mixins.js index 74c9074a6c826f..5b82fd98343540 100644 --- a/packages/components/src/utils/style-mixins.js +++ b/packages/components/src/utils/style-mixins.js @@ -1,6 +1,6 @@ export { color, rgba } from './colors'; export { reduceMotion } from './reduce-motion'; -export { rtl, getRTL, useRTL } from './rtl'; +export { rtl } from './rtl'; export { space } from './space'; export { font } from './font'; export { breakpoint } from './breakpoint'; diff --git a/packages/compose/src/hooks/use-resize-observer/index.native.js b/packages/compose/src/hooks/use-resize-observer/index.native.js index 26e6f647f5b5a7..477b4b77d993b0 100644 --- a/packages/compose/src/hooks/use-resize-observer/index.native.js +++ b/packages/compose/src/hooks/use-resize-observer/index.native.js @@ -39,7 +39,10 @@ const useResizeObserver = () => { prevState.width !== width || prevState.height !== height ) { - return { width, height }; + return { + width: Math.floor( width ), + height: Math.floor( height ), + }; } return prevState; } ); diff --git a/packages/core-data/README.md b/packages/core-data/README.md index bc887ad571c7cd..3829c1509b8c41 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -145,7 +145,8 @@ _Parameters_ - _name_ `string`: Name of the received entity. - _records_ `(Array|Object)`: Records received. - _query_ `?Object`: Query Object. -- _invalidateCache_ `?boolean`: Should invalidate query caches +- _invalidateCache_ `?boolean`: Should invalidate query caches. +- _edits_ `?Object`: Edits to reset. _Returns_ diff --git a/packages/core-data/src/actions.js b/packages/core-data/src/actions.js index 03a675531cbc04..b3d9f4bd23a34c 100644 --- a/packages/core-data/src/actions.js +++ b/packages/core-data/src/actions.js @@ -72,8 +72,8 @@ export function addEntities( entities ) { * @param {string} name Name of the received entity. * @param {Array|Object} records Records received. * @param {?Object} query Query Object. - * @param {?boolean} invalidateCache Should invalidate query caches - * + * @param {?boolean} invalidateCache Should invalidate query caches. + * @param {?Object} edits Edits to reset. * @return {Object} Action object. */ export function receiveEntityRecords( @@ -81,7 +81,8 @@ export function receiveEntityRecords( name, records, query, - invalidateCache = false + invalidateCache = false, + edits ) { // Auto drafts should not have titles, but some plugins rely on them so we can't filter this // on the server. @@ -92,9 +93,9 @@ export function receiveEntityRecords( } let action; if ( query ) { - action = receiveQueriedItems( records, query ); + action = receiveQueriedItems( records, query, edits ); } else { - action = receiveItems( records ); + action = receiveItems( records, edits ); } return { @@ -389,8 +390,6 @@ export function* saveEntityRecord( }; let updatedRecord; let error; - let persistedEntity; - let currentEdits; try { const path = `${ entity.baseURL }${ recordId ? '/' + recordId : '' @@ -512,31 +511,6 @@ export function* saveEntityRecord( }; } - // Get the full local version of the record before the update, - // to merge it with the edits and then propagate it to subscribers - persistedEntity = yield controls.select( - 'core', - '__experimentalGetEntityRecordNoResolver', - kind, - name, - recordId - ); - currentEdits = yield controls.select( - 'core', - 'getEntityRecordEdits', - kind, - name, - recordId - ); - yield receiveEntityRecords( - kind, - name, - { ...persistedEntity, ...edits }, - undefined, - // This must be false or it will trigger a GET request in parallel to the PUT/POST below - false - ); - updatedRecord = yield apiFetch( { path, method: recordId ? 'PUT' : 'POST', @@ -547,39 +521,12 @@ export function* saveEntityRecord( name, updatedRecord, undefined, - true + true, + edits ); } } catch ( _error ) { error = _error; - - // If we got to the point in the try block where we made an optimistic update, - // we need to roll it back here. - if ( persistedEntity && currentEdits ) { - yield receiveEntityRecords( - kind, - name, - persistedEntity, - undefined, - true - ); - yield editEntityRecord( - kind, - name, - recordId, - { - ...currentEdits, - ...( yield controls.select( - 'core', - 'getEntityRecordEdits', - kind, - name, - recordId - ) ), - }, - { undoIgnore: true } - ); - } } yield { type: 'SAVE_ENTITY_RECORD_FINISH', diff --git a/packages/core-data/src/entity-provider.js b/packages/core-data/src/entity-provider.js index afd0f8460f3f54..9deed11ba00cd7 100644 --- a/packages/core-data/src/entity-provider.js +++ b/packages/core-data/src/entity-provider.js @@ -6,11 +6,12 @@ import { useContext, useCallback, useEffect, - useMemo, } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { parse, serialize } from '@wordpress/blocks'; +const EMPTY_ARRAY = []; + /** * Internal dependencies */ @@ -129,56 +130,35 @@ export function useEntityProp( kind, type, prop, _id ) { * @param {string} kind The entity kind. * @param {string} type The entity type. * @param {Object} options - * @param {Object} [options.initialEdits] Initial edits object for the entity record. - * @param {string} [options.blocksProp='blocks'] The name of the entity prop that holds the blocks array. - * @param {string} [options.contentProp='content'] The name of the entity prop that holds the serialized blocks. * @param {string} [options.id] An entity ID to use instead of the context-provided one. * * @return {[WPBlock[], Function, Function]} The block array and setters. */ -export function useEntityBlockEditor( - kind, - type, - { - initialEdits, - blocksProp = 'blocks', - contentProp = 'content', - id: _id, - } = {} -) { +export function useEntityBlockEditor( kind, type, { id: _id } = {} ) { const providerId = useEntityId( kind, type ); const id = _id ?? providerId; - const [ content, setContent ] = useEntityProp( - kind, - type, - contentProp, - id - ); + const [ content, setContent ] = useEntityProp( kind, type, 'content', id ); + const [ blocks, onInput ] = useEntityProp( kind, type, 'blocks', id ); const { editEntityRecord } = useDispatch( 'core' ); useEffect( () => { - if ( initialEdits ) { - editEntityRecord( kind, type, id, initialEdits, { - undoIgnore: true, - } ); - } - }, [ id ] ); - const initialBlocks = useMemo( () => { + // Load the blocks from the content if not already in state // Guard against other instances that might have // set content to a function already. if ( content && typeof content !== 'function' ) { const parsedContent = parse( content ); - return parsedContent.length ? parsedContent : []; + editEntityRecord( + kind, + type, + id, + { + blocks: parsedContent, + }, + { undoIgnore: true } + ); } - return []; }, [ content ] ); - const [ blocks = initialBlocks, onInput ] = useEntityProp( - kind, - type, - blocksProp, - id - ); const onChange = useCallback( ( nextBlocks ) => { @@ -190,5 +170,5 @@ export function useEntityBlockEditor( }, [ onInput, setContent ] ); - return [ blocks, onInput, onChange ]; + return [ blocks ?? EMPTY_ARRAY, onInput, onChange ]; } diff --git a/packages/core-data/src/queried-data/actions.js b/packages/core-data/src/queried-data/actions.js index d44d7876dd1121..c88eb364ea8451 100644 --- a/packages/core-data/src/queried-data/actions.js +++ b/packages/core-data/src/queried-data/actions.js @@ -6,14 +6,16 @@ import { castArray } from 'lodash'; /** * Returns an action object used in signalling that items have been received. * - * @param {Array} items Items received. + * @param {Array} items Items received. + * @param {?Object} edits Optional edits to reset. * * @return {Object} Action object. */ -export function receiveItems( items ) { +export function receiveItems( items, edits ) { return { type: 'RECEIVE_ITEMS', items: castArray( items ), + persistedEdits: edits, }; } @@ -43,12 +45,13 @@ export function removeItems( kind, name, records, invalidateCache = false ) { * * @param {Array} items Queried items received. * @param {?Object} query Optional query object. + * @param {?Object} edits Optional edits to reset. * * @return {Object} Action object. */ -export function receiveQueriedItems( items, query = {} ) { +export function receiveQueriedItems( items, query = {}, edits ) { return { - ...receiveItems( items ), + ...receiveItems( items, edits ), query, }; } diff --git a/packages/core-data/src/reducer.js b/packages/core-data/src/reducer.js index 5bbe9ccbb855a2..51c43a529d9ab5 100644 --- a/packages/core-data/src/reducer.js +++ b/packages/core-data/src/reducer.js @@ -221,7 +221,14 @@ function entity( entityConfig ) { 'raw', record[ key ] ) - ) + ) && + // Sometimes the server alters the sent value which means + // we need to also remove the edits before the api request. + ( ! action.persistedEdits || + ! isEqual( + edits[ key ], + action.persistedEdits[ key ] + ) ) ) { acc[ key ] = edits[ key ]; } diff --git a/packages/core-data/src/test/actions.js b/packages/core-data/src/test/actions.js index 4dbad511f4503f..cf0bc142348ca4 100644 --- a/packages/core-data/src/test/actions.js +++ b/packages/core-data/src/test/actions.js @@ -115,16 +115,7 @@ describe( 'saveEntityRecord', () => { 'SAVE_ENTITY_RECORD_START' ); - // Should select __experimentalGetEntityRecordNoResolver selector (as opposed to getEntityRecord) - // see https://github.com/WordPress/gutenberg/pull/19752#discussion_r368498318. expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - expect( fulfillment.next().value.selectorName ).toBe( - '__experimentalGetEntityRecordNoResolver' - ); - expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - const receiveItems = fulfillment.next().value; - expect( receiveItems.type ).toBe( 'RECEIVE_ITEMS' ); - expect( receiveItems.invalidateCache ).toBe( false ); const { value: apiFetchAction } = fulfillment.next( {} ); expect( apiFetchAction.request ).toEqual( { path: '/wp/v2/posts', @@ -140,7 +131,8 @@ describe( 'saveEntityRecord', () => { 'post', updatedRecord, undefined, - true + true, + { title: 'new post' } ) ); expect( fulfillment.next().value.type ).toBe( @@ -173,11 +165,6 @@ describe( 'saveEntityRecord', () => { 'SAVE_ENTITY_RECORD_START' ); expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - const receiveItems = fulfillment.next().value; - expect( receiveItems.type ).toBe( 'RECEIVE_ITEMS' ); - expect( receiveItems.invalidateCache ).toBe( false ); const { value: apiFetchAction } = fulfillment.next( {} ); expect( apiFetchAction.request ).toEqual( { path: '/wp/v2/posts/10', @@ -187,7 +174,10 @@ describe( 'saveEntityRecord', () => { // Provide response and trigger action const { value: received } = fulfillment.next( post ); expect( received ).toEqual( - receiveEntityRecords( 'postType', 'post', post, undefined, true ) + receiveEntityRecords( 'postType', 'post', post, undefined, true, { + title: 'new post', + id: 10, + } ) ); expect( fulfillment.next().value.type ).toBe( 'SAVE_ENTITY_RECORD_FINISH' @@ -222,9 +212,6 @@ describe( 'saveEntityRecord', () => { 'SAVE_ENTITY_RECORD_START' ); expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - expect( fulfillment.next().value.type ).toBe( '@@data/SELECT' ); - expect( fulfillment.next().value.type ).toBe( 'RECEIVE_ITEMS' ); const { value: apiFetchAction } = fulfillment.next( {} ); expect( apiFetchAction.request ).toEqual( { path: '/wp/v2/types/page', @@ -239,7 +226,8 @@ describe( 'saveEntityRecord', () => { 'postType', postType, undefined, - true + true, + { slug: 'page', title: 'Pages' } ) ); expect( fulfillment.next().value.type ).toBe( diff --git a/packages/create-block/CHANGELOG.md b/packages/create-block/CHANGELOG.md index 1c188fb17c0da3..d158f47b48e275 100644 --- a/packages/create-block/CHANGELOG.md +++ b/packages/create-block/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +### New Feature + +- Adds the `npmPackages` field to the template configuration. It allows listing remote npm packages that will be installed in the scaffolded project ([#27880](https://github.com/WordPress/gutenberg/pull/27880)). +- Installs WordPress npm dependencies used in the `esnext` template during the scaffolding process ([#27880](https://github.com/WordPress/gutenberg/pull/27880)). + +### Bug Fix + +- Print the block class name in the `save` method in scaffolded templates ([#27988](https://github.com/WordPress/gutenberg/pull/27988)). + ## 1.0.2 (2020-12-17) ### Bug Fix diff --git a/packages/create-block/README.md b/packages/create-block/README.md index f6b3f15d983b05..2d42d5eb8665e2 100644 --- a/packages/create-block/README.md +++ b/packages/create-block/README.md @@ -160,6 +160,7 @@ The following configurable variables are used with the template files. Template - `licenseURI` (default: `'https://www.gnu.org/licenses/gpl-2.0.html'`) - `version` (default: `'0.1.0'`) - `wpScripts` (default: `true`) +- `npmDependencies` (default: `[]`) – the list of remote npm packages to be installed in the project with [`npm install`](https://docs.npmjs.com/cli/v6/commands/npm-install). - `editorScript` (default: `'file:./build/index.js'`) - `editorStyle` (default: `'file:./build/index.css'`) - `style` (default: `'file:./build/style-index.css'`) diff --git a/packages/create-block/lib/init-package-json.js b/packages/create-block/lib/init-package-json.js index 3ed9d619a8871d..8c2ede2bc3dca9 100644 --- a/packages/create-block/lib/init-package-json.js +++ b/packages/create-block/lib/init-package-json.js @@ -1,14 +1,16 @@ /** * External dependencies */ -const { isEmpty, omitBy } = require( 'lodash' ); +const { command } = require( 'execa' ); +const { isEmpty, omitBy, size } = require( 'lodash' ); +const npmPackageArg = require( 'npm-package-arg' ); const { join } = require( 'path' ); const writePkg = require( 'write-pkg' ); /** * Internal dependencies */ -const { info } = require( './log' ); +const { info, error } = require( './log' ); module.exports = async ( { author, @@ -17,6 +19,7 @@ module.exports = async ( { slug, version, wpScripts, + npmDependencies, } ) => { const cwd = join( process.cwd(), slug ); @@ -44,4 +47,32 @@ module.exports = async ( { isEmpty ) ); + + if ( size( npmDependencies ) ) { + info( '' ); + info( + 'Installing npm dependencies. It might take a couple of minutes...' + ); + for ( const packageArg of npmDependencies ) { + try { + const { type } = npmPackageArg( packageArg ); + if ( + ! [ 'git', 'tag', 'version', 'range', 'remote' ].includes( + type + ) + ) { + throw new Error( + `Provided package type "${ type }" is not supported.` + ); + } + await command( `npm install ${ packageArg }`, { + cwd, + } ); + } catch ( { message } ) { + info( '' ); + info( `Skipping "${ packageArg }" npm dependency. Reason:` ); + error( message ); + } + } + } }; diff --git a/packages/create-block/lib/init-wp-scripts.js b/packages/create-block/lib/init-wp-scripts.js index f375cd82398841..fa1eba8862d3e4 100644 --- a/packages/create-block/lib/init-wp-scripts.js +++ b/packages/create-block/lib/init-wp-scripts.js @@ -13,7 +13,9 @@ module.exports = async ( { slug } ) => { const cwd = join( process.cwd(), slug ); info( '' ); - info( 'Installing packages. It might take a couple of minutes...' ); + info( + 'Installing `@wordpress/scripts` package. It might take a couple of minutes...' + ); await command( 'npm install @wordpress/scripts --save-dev', { cwd, } ); diff --git a/packages/create-block/lib/scaffold.js b/packages/create-block/lib/scaffold.js index bbdd536c9af245..2da6aee7a9e050 100644 --- a/packages/create-block/lib/scaffold.js +++ b/packages/create-block/lib/scaffold.js @@ -30,6 +30,7 @@ module.exports = async ( licenseURI, version, wpScripts, + npmDependencies, editorScript, editorStyle, style, @@ -57,10 +58,11 @@ module.exports = async ( license, licenseURI, textdomain: slug, + wpScripts, + npmDependencies, editorScript, editorStyle, style, - wpScripts, }; await Promise.all( Object.keys( outputTemplates ).map( async ( outputFile ) => { diff --git a/packages/create-block/lib/templates.js b/packages/create-block/lib/templates.js index eadf0be6a5211e..3e1c95fa1a4987 100644 --- a/packages/create-block/lib/templates.js +++ b/packages/create-block/lib/templates.js @@ -37,6 +37,11 @@ const predefinedBlockTemplates = { description: 'Example block written with ESNext standard and JSX support – build step required.', dashicon: 'smiley', + npmDependencies: [ + '@wordpress/block-editor', + '@wordpress/blocks', + '@wordpress/i18n', + ], }, }, }; @@ -138,6 +143,7 @@ const getDefaultValues = ( blockTemplate ) => { licenseURI: 'https://www.gnu.org/licenses/gpl-2.0.html', version: '0.1.0', wpScripts: true, + npmDependencies: [], editorScript: 'file:./build/index.js', editorStyle: 'file:./build/index.css', style: 'file:./build/style-index.css', diff --git a/packages/create-block/lib/templates/es5/index.js.mustache b/packages/create-block/lib/templates/es5/index.js.mustache index 318bd7f21dba17..fd286d0a101edd 100644 --- a/packages/create-block/lib/templates/es5/index.js.mustache +++ b/packages/create-block/lib/templates/es5/index.js.mustache @@ -107,7 +107,7 @@ save: function() { return el( 'p', - {}, + useBlockProps.save(), __( '{{title}} – hello from the saved content!', '{{textdomain}}' ) ); }, diff --git a/packages/create-block/lib/templates/esnext/src/save.js.mustache b/packages/create-block/lib/templates/esnext/src/save.js.mustache index 403eb2f1965553..4493a836019ee8 100644 --- a/packages/create-block/lib/templates/esnext/src/save.js.mustache +++ b/packages/create-block/lib/templates/esnext/src/save.js.mustache @@ -5,6 +5,14 @@ */ import { __ } from '@wordpress/i18n'; +/** + * React hook that is used to mark the block wrapper element. + * It provides all the necessary props like the class name. + * + * @see https://developer.wordpress.org/block-editor/packages/packages-block-editor/#useBlockProps + */ +import { useBlockProps } from '@wordpress/block-editor'; + /** * The save function defines the way in which the different attributes should * be combined into the final markup, which is then serialized by the block @@ -16,7 +24,7 @@ import { __ } from '@wordpress/i18n'; */ export default function save() { return ( -

+

{ __( '{{title}} – hello from the saved content!', '{{textdomain}}' diff --git a/packages/create-block/package.json b/packages/create-block/package.json index a74b66c5fe90f0..3af07b5094ef3c 100644 --- a/packages/create-block/package.json +++ b/packages/create-block/package.json @@ -41,6 +41,7 @@ "lodash": "^4.17.19", "make-dir": "^3.0.0", "mustache": "^4.0.0", + "npm-package-arg": "^8.0.1", "rimraf": "^3.0.2", "write-pkg": "^4.0.0" }, diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index c3d31299f3e42b..800148d2c39e17 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -131,9 +131,9 @@ export async function searchForReusableBlock( searchTerm ) { */ export async function insertBlock( searchTerm ) { await searchForBlock( searchTerm ); - const insertButton = ( - await page.$x( `//button//span[contains(text(), '${ searchTerm }')]` ) - )[ 0 ]; + const insertButton = await page.waitForXPath( + `//button//span[contains(text(), '${ searchTerm }')]` + ); await insertButton.click(); // We should wait until the inserter closes and the focus moves to the content. await waitForInserterCloseAndContentFocus(); @@ -164,9 +164,9 @@ export async function insertPattern( searchTerm ) { */ export async function insertReusableBlock( searchTerm ) { await searchForReusableBlock( searchTerm ); - const insertButton = ( - await page.$x( `//button//span[contains(text(), '${ searchTerm }')]` ) - )[ 0 ]; + const insertButton = await page.waitForXPath( + `//button//span[contains(text(), '${ searchTerm }')]` + ); await insertButton.click(); // We should wait until the inserter closes and the focus moves to the content. await waitForInserterCloseAndContentFocus(); diff --git a/packages/e2e-test-utils/src/save-draft.js b/packages/e2e-test-utils/src/save-draft.js index aa914c2e577e31..8660910837026e 100644 --- a/packages/e2e-test-utils/src/save-draft.js +++ b/packages/e2e-test-utils/src/save-draft.js @@ -5,6 +5,7 @@ * @return {Promise} Promise resolving when draft save is complete. */ export async function saveDraft() { + await page.waitForSelector( '.editor-post-save-draft' ); await page.click( '.editor-post-save-draft' ); return page.waitForSelector( '.editor-post-saved-state.is-saved' ); } diff --git a/packages/e2e-tests/config/setup-test-framework.js b/packages/e2e-tests/config/setup-test-framework.js index eabeb0fe38da4d..39b2a04ddc7604 100644 --- a/packages/e2e-tests/config/setup-test-framework.js +++ b/packages/e2e-tests/config/setup-test-framework.js @@ -174,54 +174,6 @@ function observeConsoleLogging() { } ); } -/** - * Runs Axe tests when the block editor is found on the current page. - * - * @return {?Promise} Promise resolving once Axe texts are finished. - */ -async function runAxeTestsForBlockEditor() { - if ( ! ( await page.$( '.block-editor' ) ) ) { - return; - } - - await expect( page ).toPassAxeTests( { - // Temporary disabled rules to enable initial integration. - // See: https://github.com/WordPress/gutenberg/pull/15018. - disabledRules: [ - 'aria-allowed-role', - 'aria-allowed-attr', - 'aria-hidden-focus', - 'aria-input-field-name', - 'aria-valid-attr-value', - 'button-name', - 'color-contrast', - 'dlitem', - 'duplicate-id', - 'label', - 'landmark-one-main', - 'link-name', - 'listitem', - 'region', - 'aria-required-children', - 'aria-required-parent', - 'frame-title', - ], - exclude: [ - // Ignores elements created by metaboxes. - '.edit-post-layout__metaboxes', - // Ignores elements created by TinyMCE. - '.mce-container', - // These properties were not included in the 1.1 spec - // through error, they should be allowed on role="row": - // https://github.com/w3c/aria/issues/558 - '[role="treegrid"] [aria-posinset]', - '[role="treegrid"] [aria-setsize]', - // Ignore block previews. - '.block-editor-block-preview__content', - ], - } ); -} - /** * Simulate slow network or throttled CPU if provided via environment variables. */ @@ -271,7 +223,6 @@ beforeAll( async () => { } ); afterEach( async () => { - await runAxeTestsForBlockEditor(); await setupBrowser(); } ); diff --git a/packages/e2e-tests/plugins/block-variations/index.js b/packages/e2e-tests/plugins/block-variations/index.js index 3a76ae7d42db66..219eedd6bec5e9 100644 --- a/packages/e2e-tests/plugins/block-variations/index.js +++ b/packages/e2e-tests/plugins/block-variations/index.js @@ -40,6 +40,8 @@ }, icon: 'yes-alt', scope: [ 'inserter' ], + isActive: ( { backgroundColor }, variationAttributes ) => + backgroundColor === variationAttributes.backgroundColor, } ); registerBlockVariation( 'core/paragraph', { @@ -52,6 +54,8 @@ }, icon: 'warning', scope: [ 'inserter' ], + isActive: ( { backgroundColor }, variationAttributes ) => + backgroundColor === variationAttributes.backgroundColor, } ); registerBlockVariation( 'core/columns', { diff --git a/packages/e2e-tests/specs/editor/plugins/block-variations.js b/packages/e2e-tests/specs/editor/plugins/block-variations.js index ef4a17360284a3..81862f42a5e304 100644 --- a/packages/e2e-tests/specs/editor/plugins/block-variations.js +++ b/packages/e2e-tests/specs/editor/plugins/block-variations.js @@ -7,6 +7,8 @@ import { deactivatePlugin, insertBlock, searchForBlock, + pressKeyWithModifier, + openDocumentSettingsSidebar, } from '@wordpress/e2e-test-utils'; describe( 'Block variations', () => { @@ -103,4 +105,75 @@ describe( 'Block variations', () => { ) ).toHaveLength( 4 ); } ); + // @see @wordpres/block-editor/src/components/use-block-display-information (`useBlockDisplayInformation` hook). + describe( 'testing block display information with matching variations', () => { + const getActiveBreadcrumb = async () => + page.evaluate( + () => + document.querySelector( + '.block-editor-block-breadcrumb__current' + ).textContent + ); + const getFirstNavigationItem = async () => { + await pressKeyWithModifier( 'access', 'o' ); + // This also returns the visually hidden text `(selected block)`. + // For example `Paragraph(selected block)`. In order to hide this + // implementation detail and search for childNodes, we choose to + // test with `String.prototype.startsWith()`. + return page.evaluate( + () => + document.querySelector( + '.block-editor-block-navigation-block-select-button' + ).textContent + ); + }; + const getBlockCardDescription = async () => { + await openDocumentSettingsSidebar(); + return page.evaluate( + () => + document.querySelector( + '.block-editor-block-card__description' + ).textContent + ); + }; + + it( 'should show block information when no matching variation is found', async () => { + await insertBlock( 'Large Quote' ); + const breadcrumb = await getActiveBreadcrumb(); + expect( breadcrumb ).toEqual( 'Quote' ); + const navigationItem = await getFirstNavigationItem(); + expect( navigationItem.startsWith( 'Quote' ) ).toBeTruthy(); + const description = await getBlockCardDescription(); + expect( description ).toEqual( + 'Give quoted text visual emphasis. "In quoting others, we cite ourselves." — Julio Cortázar' + ); + } ); + it( 'should display variations info if all declared', async () => { + await insertBlock( 'Success Message' ); + const breadcrumb = await getActiveBreadcrumb(); + expect( breadcrumb ).toEqual( 'Success Message' ); + const navigationItem = await getFirstNavigationItem(); + expect( + navigationItem.startsWith( 'Success Message' ) + ).toBeTruthy(); + const description = await getBlockCardDescription(); + expect( description ).toEqual( + 'This block displays a success message. This description overrides the default one provided for the Paragraph block.' + ); + } ); + it( 'should display mixed block and variation match information', async () => { + // Warning Message variation is missing the `description`. + await insertBlock( 'Warning Message' ); + const breadcrumb = await getActiveBreadcrumb(); + expect( breadcrumb ).toEqual( 'Warning Message' ); + const navigationItem = await getFirstNavigationItem(); + expect( + navigationItem.startsWith( 'Warning Message' ) + ).toBeTruthy(); + const description = await getBlockCardDescription(); + expect( description ).toEqual( + 'Start with the building block of all narrative.' + ); + } ); + } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap index a266c0df25c180..a0df67f902d1fe 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Reusable blocks multi-selection reusable block can be converted back to regular blocks 1`] = ` +exports[`Reusable blocks can be created from multiselection and converted back to regular blocks 1`] = ` "

Hello there!

diff --git a/packages/e2e-tests/specs/editor/various/change-detection.test.js b/packages/e2e-tests/specs/editor/various/change-detection.test.js index 8bac378e8aaa1a..413aeda6adf09f 100644 --- a/packages/e2e-tests/specs/editor/various/change-detection.test.js +++ b/packages/e2e-tests/specs/editor/various/change-detection.test.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { first } from 'lodash'; + /** * WordPress dependencies */ @@ -10,6 +15,7 @@ import { saveDraft, openDocumentSettingsSidebar, isCurrentURL, + pressKeyTimes, } from '@wordpress/e2e-test-utils'; describe( 'Change detection', () => { @@ -132,9 +138,11 @@ describe( 'Change detection', () => { await page.type( '.editor-post-title__input', '!' ); await Promise.all( [ - page.waitForSelector( '.editor-post-publish-button.is-busy' ), page.waitForSelector( - '.editor-post-publish-button:not( .is-busy )' + '.editor-post-publish-button[aria-disabled="true"]' + ), + page.waitForSelector( + '.editor-post-publish-button[aria-disabled="false"]' ), page.evaluate( () => window.wp.data.dispatch( 'core/editor' ).autosave() @@ -356,6 +364,8 @@ describe( 'Change detection', () => { } ); it( 'consecutive edits to the same attribute should mark the post as dirty after a save', async () => { + const FONT_SIZE_LABEL_SELECTOR = + "//label[contains(text(), 'Font size')]"; // Open the sidebar block settings. await openDocumentSettingsSidebar(); await page.click( '.edit-post-sidebar__panel-tab[data-label="Block"]' ); @@ -372,10 +382,9 @@ describe( 'Change detection', () => { // Increase the paragraph's font size. await page.click( '[data-type="core/paragraph"]' ); - await page.click( '.components-font-size-picker__select' ); - await page.click( - '.components-custom-select-control__item:nth-child(3)' - ); + await first( await page.$x( FONT_SIZE_LABEL_SELECTOR ) ).click(); + await pressKeyTimes( 'ArrowDown', 2 ); + await page.keyboard.press( 'Enter' ); await page.click( '[data-type="core/paragraph"]' ); // Check that the post is dirty. @@ -389,10 +398,9 @@ describe( 'Change detection', () => { // Increase the paragraph's font size again. await page.click( '[data-type="core/paragraph"]' ); - await page.click( '.components-font-size-picker__select' ); - await page.click( - '.components-custom-select-control__item:nth-child(4)' - ); + await first( await page.$x( FONT_SIZE_LABEL_SELECTOR ) ).click(); + await pressKeyTimes( 'ArrowDown', 3 ); + await page.keyboard.press( 'Enter' ); await page.click( '[data-type="core/paragraph"]' ); // Check that the post is dirty. diff --git a/packages/e2e-tests/specs/editor/various/editor-modes.test.js b/packages/e2e-tests/specs/editor/various/editor-modes.test.js index 82e481ead2da25..48056ccde42763 100644 --- a/packages/e2e-tests/specs/editor/various/editor-modes.test.js +++ b/packages/e2e-tests/specs/editor/various/editor-modes.test.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { first } from 'lodash'; + /** * WordPress dependencies */ @@ -54,8 +59,8 @@ describe( 'Editing modes (visual/HTML)', () => { // The font size picker for the paragraph block should appear, even in // HTML editing mode. - const fontSizePicker = await page.$$( - '.edit-post-sidebar .components-font-size-picker__controls' + const fontSizePicker = await page.$x( + "//label[contains(text(), 'Font size')]" ); expect( fontSizePicker ).toHaveLength( 1 ); } ); @@ -73,13 +78,11 @@ describe( 'Editing modes (visual/HTML)', () => { expect( htmlBlockContent ).toEqual( '

Hello world!

' ); // Change the font size using the sidebar. - await page.click( '.components-font-size-picker__select' ); - await page.click( - '.components-custom-select-control__item:nth-child(5)' - ); - await page.waitForXPath( - `//button[contains(@class, "components-custom-select-control__button") and contains(text(), 'Large')]` - ); + await first( + await page.$x( "//label[contains(text(), 'Font size')]" ) + ).click(); + await pressKeyTimes( 'ArrowDown', 4 ); + await page.keyboard.press( 'Enter' ); // Make sure the HTML content updated. htmlBlockContent = await page.$eval( diff --git a/packages/e2e-tests/specs/editor/various/font-size-picker.test.js b/packages/e2e-tests/specs/editor/various/font-size-picker.test.js index a7125e39f920a8..84edbd564b5352 100644 --- a/packages/e2e-tests/specs/editor/various/font-size-picker.test.js +++ b/packages/e2e-tests/specs/editor/various/font-size-picker.test.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { first } from 'lodash'; + /** * WordPress dependencies */ @@ -9,6 +14,9 @@ import { } from '@wordpress/e2e-test-utils'; describe( 'Font Size Picker', () => { + const FONT_SIZE_LABEL_SELECTOR = "//label[contains(text(), 'Font size')]"; + const CUSTOM_FONT_SIZE_LABEL_SELECTOR = + "//fieldset[legend[contains(text(),'Font size')]]//label[contains(text(), 'Custom')]"; beforeEach( async () => { await createNewPost(); } ); @@ -17,14 +25,25 @@ describe( 'Font Size Picker', () => { // Create a paragraph block with some content. await clickBlockAppender(); await page.keyboard.type( 'Paragraph to be made "large"' ); - await page.click( '.components-font-size-picker__select' ); - await page.click( - '.components-custom-select-control__item:nth-child(5)' - ); - await page.waitForXPath( - `//button[contains(@class, "components-custom-select-control__button") and contains(text(), 'Large')]` + await first( await page.$x( FONT_SIZE_LABEL_SELECTOR ) ).click(); + await pressKeyTimes( 'ArrowDown', 4 ); + await page.keyboard.press( 'Enter' ); + const selectedFontSize = await page.evaluate( + ( selector ) => + document + .evaluate( + selector, + document, + null, + XPathResult.ANY_TYPE, + null + ) + .iterateNext().control.textContent, + FONT_SIZE_LABEL_SELECTOR ); + expect( selectedFontSize ).toBe( 'Large' ); + // Ensure content matches snapshot. const content = await getEditedPostContent(); expect( content ).toMatchSnapshot(); @@ -35,11 +54,10 @@ describe( 'Font Size Picker', () => { await clickBlockAppender(); await page.keyboard.type( 'Paragraph to be made "small"' ); - await page.click( - '.components-font-size-picker__controls .components-font-size-picker__number' - ); + await first( await page.$x( CUSTOM_FONT_SIZE_LABEL_SELECTOR ) ).click(); // This should be the "small" font-size of the editor defaults. await page.keyboard.type( '13' ); + await page.keyboard.press( 'Enter' ); // Ensure content matches snapshot. const content = await getEditedPostContent(); @@ -51,10 +69,9 @@ describe( 'Font Size Picker', () => { await clickBlockAppender(); await page.keyboard.type( 'Paragraph to be made "small"' ); - await page.click( - '.components-font-size-picker__controls .components-font-size-picker__number' - ); + await first( await page.$x( CUSTOM_FONT_SIZE_LABEL_SELECTOR ) ).click(); await page.keyboard.type( '23' ); + await page.keyboard.press( 'Enter' ); // Ensure content matches snapshot. const content = await getEditedPostContent(); @@ -68,17 +85,13 @@ describe( 'Font Size Picker', () => { 'Paragraph with font size reset using button' ); - await page.click( '.components-font-size-picker__select' ); - await page.click( - '.components-custom-select-control__item:nth-child(2)' - ); + await first( await page.$x( FONT_SIZE_LABEL_SELECTOR ) ).click(); + await pressKeyTimes( 'ArrowDown', 2 ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.press( 'Tab' ); + await page.keyboard.press( 'Tab' ); - const resetButton = ( - await page.$x( - '//*[contains(concat(" ", @class, " "), " components-font-size-picker__controls ")]//*[text()=\'Reset\']' - ) - )[ 0 ]; - await resetButton.click(); + await page.keyboard.press( 'Enter' ); // Ensure content matches snapshot. const content = await getEditedPostContent(); @@ -92,17 +105,14 @@ describe( 'Font Size Picker', () => { 'Paragraph with font size reset using input field' ); - await page.click( '.components-font-size-picker__select' ); - await page.click( - '.components-custom-select-control__item:nth-child(3)' - ); + await first( await page.$x( FONT_SIZE_LABEL_SELECTOR ) ).click(); + await pressKeyTimes( 'ArrowDown', 2 ); + await page.keyboard.press( 'Enter' ); - // Clear the custom font size input. - await page.click( - '.components-font-size-picker__controls .components-font-size-picker__number' - ); + await first( await page.$x( CUSTOM_FONT_SIZE_LABEL_SELECTOR ) ).click(); await pressKeyTimes( 'ArrowRight', 5 ); await pressKeyTimes( 'Backspace', 5 ); + await page.keyboard.press( 'Enter' ); // Ensure content matches snapshot. const content = await getEditedPostContent(); @@ -114,18 +124,14 @@ describe( 'Font Size Picker', () => { await clickBlockAppender(); await page.keyboard.type( 'Paragraph to be made "small"' ); - await page.click( - '.components-font-size-picker__controls .components-font-size-picker__number' - ); + await first( await page.$x( CUSTOM_FONT_SIZE_LABEL_SELECTOR ) ).click(); await page.keyboard.type( '23' ); + await page.keyboard.press( 'Enter' ); - await page.keyboard.press( 'Backspace' ); - - await page.click( - '.components-font-size-picker__controls .components-font-size-picker__number' - ); + await first( await page.$x( CUSTOM_FONT_SIZE_LABEL_SELECTOR ) ).click(); await page.keyboard.press( 'Backspace' ); await page.keyboard.press( 'Backspace' ); + await page.keyboard.press( 'Enter' ); // Ensure content matches snapshot. const content = await getEditedPostContent(); diff --git a/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js b/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js index 2b092c9b466906..730af28bdb10a0 100644 --- a/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js @@ -108,10 +108,10 @@ describe( 'Order of block keyboard navigation', () => { await page.keyboard.type( paragraphBlock ); } - // Clear the selected block. - const paragraph = await page.$( '[data-type="core/paragraph"]' ); - const box = await paragraph.boundingBox(); - await page.mouse.click( box.x - 1, box.y ); + // Clear the selected block and put focus in front of the block list. + await page.evaluate( () => { + document.querySelector( '.editor-styles-wrapper' ).focus(); + } ); await page.keyboard.press( 'Tab' ); await expect( @@ -143,13 +143,9 @@ describe( 'Order of block keyboard navigation', () => { await page.keyboard.type( paragraphBlock ); } - // Clear the selected block. - const paragraph = await page.$( '[data-type="core/paragraph"]' ); - const box = await paragraph.boundingBox(); - await page.mouse.click( box.x - 1, box.y ); - - // Put focus behind the block list. + // Clear the selected block and put focus behind the block list. await page.evaluate( () => { + document.querySelector( '.editor-styles-wrapper' ).focus(); document .querySelector( '.interface-interface-skeleton__sidebar' ) .focus(); diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js index 0d7c6d8baf236f..46d887e4376efb 100644 --- a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js @@ -12,8 +12,70 @@ import { trashAllPosts, visitAdminPage, toggleGlobalBlockInserter, + openDocumentSettingsSidebar, + saveDraft, } from '@wordpress/e2e-test-utils'; +const reusableBlockNameInputSelector = + '.block-editor-block-inspector .components-text-control__input'; + +const saveAll = async () => { + await page.click( '.editor-post-publish-button__button.has-changes-dot' ); + await page.waitForSelector( + 'button.editor-entities-saved-states__save-button' + ); + await page.click( 'button.editor-entities-saved-states__save-button' ); + + // no need to publish the post. + const cancelPublish = await page.waitForSelector( + '.editor-post-publish-panel__header-cancel-button button' + ); + await cancelPublish.click(); +}; + +const clearAllBlocks = async () => { + // Remove all blocks from the post so that we're working with a clean slate + await page.evaluate( () => { + const blocks = wp.data.select( 'core/block-editor' ).getBlocks(); + const clientIds = blocks.map( ( block ) => block.clientId ); + wp.data.dispatch( 'core/block-editor' ).removeBlocks( clientIds ); + } ); +}; + +const createReusableBlock = async ( content, title ) => { + // Insert a paragraph block + await insertBlock( 'Paragraph' ); + await page.keyboard.type( content ); + + await clickBlockToolbarButton( 'More options' ); + await clickMenuItem( 'Add to Reusable blocks' ); + + // Wait for creation to finish + await page.waitForXPath( + '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' + ); + + // Check that we have a reusable block on the page + const block = await page.waitForSelector( + '.block-editor-block-list__block[data-type="core/block"]' + ); + expect( block ).not.toBeNull(); + + await openDocumentSettingsSidebar(); + const nameInput = await page.waitForSelector( + reusableBlockNameInputSelector + ); + if ( title ) { + await nameInput.click(); + + // Select all of the text in the title field. + await pressKeyWithModifier( 'primary', 'a' ); + + // Give the reusable block a title + await page.keyboard.type( title ); + } +}; + describe( 'Reusable blocks', () => { beforeAll( async () => { await createNewPost(); @@ -24,112 +86,40 @@ describe( 'Reusable blocks', () => { } ); beforeEach( async () => { - // Remove all blocks from the post so that we're working with a clean slate - await page.evaluate( () => { - const blocks = wp.data.select( 'core/block-editor' ).getBlocks(); - const clientIds = blocks.map( ( block ) => block.clientId ); - wp.data.dispatch( 'core/block-editor' ).removeBlocks( clientIds ); - } ); - } ); - - it( 'can be created', async () => { - // Insert a paragraph block - await insertBlock( 'Paragraph' ); - await page.keyboard.type( 'Hello there!' ); - - await clickBlockToolbarButton( 'More options' ); - await clickMenuItem( 'Add to Reusable blocks' ); - - // Wait for creation to finish - await page.waitForXPath( - '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' - ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' - ); - - // Select all of the text in the title field. - await pressKeyWithModifier( 'primary', 'a' ); - - // Give the reusable block a title - await page.keyboard.type( 'Greeting block' ); - - // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); - - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); - - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); - - // Check that its title is displayed - const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText - ); - expect( title ).toBe( 'Greeting block' ); + await clearAllBlocks(); } ); it( 'can be created with no title', async () => { - // Insert a paragraph block - await insertBlock( 'Paragraph' ); - await page.keyboard.type( 'Hello there!' ); - - await clickBlockToolbarButton( 'More options' ); - await clickMenuItem( 'Add to Reusable blocks' ); - - // Wait for creation to finish - await page.waitForXPath( - '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' - ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' - ); - - // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); - - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); - - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); - - // Check that it is untitled + await createReusableBlock( 'Hello there!' ); + await openDocumentSettingsSidebar(); const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText + reusableBlockNameInputSelector, + ( element ) => element.value ); expect( title ).toBe( 'Untitled Reusable Block' ); } ); - it( 'can be inserted and edited', async () => { + it( 'can be created, inserted, edited and converted to a regular block.', async () => { + await createReusableBlock( 'Hello there!', 'Greeting block' ); + await saveAll(); + await clearAllBlocks(); + // Insert the reusable block we created above await insertReusableBlock( 'Greeting block' ); - // Put the reusable block in edit mode - const editButton = await page.waitForXPath( - '//button[text()="Edit" and not(@disabled)]' - ); - await editButton.click(); - // Change the block's title + await openDocumentSettingsSidebar(); + const nameInput = await page.waitForSelector( + reusableBlockNameInputSelector + ); + await nameInput.click(); + await pressKeyWithModifier( 'primary', 'a' ); await page.keyboard.type( 'Surprised greeting block' ); - // Tab three times to navigate to the block's content - await page.keyboard.press( 'Tab' ); - await page.keyboard.press( 'Tab' ); - // Quickly focus the paragraph block + await page.click( + '.block-editor-block-list__block[data-type="core/block"] p' + ); await page.keyboard.press( 'Escape' ); // Enter navigation mode await page.keyboard.press( 'Enter' ); // Enter edit mode @@ -137,24 +127,7 @@ describe( 'Reusable blocks', () => { await page.keyboard.type( 'Oh! ' ); // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); - - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); - - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); - - // Check that its title is displayed - const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText - ); - expect( title ).toBe( 'Surprised greeting block' ); + await saveAll(); // Check that its content is up to date const text = await page.$eval( @@ -162,79 +135,51 @@ describe( 'Reusable blocks', () => { ( element ) => element.innerText ); expect( text ).toMatch( 'Oh! Hello there!' ); - } ); - it( 'can be inserted after refresh', async () => { - // Step 1. Insert a paragraph block + await clearAllBlocks(); - await insertBlock( 'Paragraph' ); - await page.keyboard.type( 'Awesome Paragraph' ); + // Insert the reusable block we edited above + await insertReusableBlock( 'Surprised greeting block' ); - await clickBlockToolbarButton( 'More options' ); - await clickMenuItem( 'Add to Reusable blocks' ); + // Convert block to a regular block + await clickBlockToolbarButton( 'Convert to regular blocks', 'content' ); - // Wait for creation to finish - await page.waitForXPath( - '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' - ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' + // Check that we have a paragraph block on the page + const paragraphBlock = await page.$( + '.block-editor-block-list__block[data-type="core/paragraph"]' ); + expect( paragraphBlock ).not.toBeNull(); - // Select all of the text in the title field. - await pressKeyWithModifier( 'primary', 'a' ); + // Check that its content is up to date + const paragraphContent = await page.$eval( + '.block-editor-block-list__block[data-type="core/paragraph"]', + ( element ) => element.innerText + ); + expect( paragraphContent ).toMatch( 'Oh! Hello there!' ); + } ); - // Give the reusable block a title - await page.keyboard.type( 'Awesome block' ); + it( 'can be inserted after refresh', async () => { + await createReusableBlock( 'Awesome Paragraph', 'Awesome block' ); // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); + await saveAll(); // Step 2. Create new post. - await createNewPost(); // Step 3. Insert the block created in Step 1. - await insertReusableBlock( 'Awesome block' ); - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); - - // Check that its title is displayed + // Check the title. + await openDocumentSettingsSidebar(); const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText + reusableBlockNameInputSelector, + ( element ) => element.value ); expect( title ).toBe( 'Awesome block' ); } ); - it( 'can be converted to a regular block', async () => { - // Insert the reusable block we edited above - await insertReusableBlock( 'Surprised greeting block' ); - - // Convert block to a regular block - await clickBlockToolbarButton( 'Convert to regular blocks', 'content' ); - - // Check that we have a paragraph block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/paragraph"]' - ); - expect( block ).not.toBeNull(); - - // Check that its content is up to date - const text = await page.$eval( - '.block-editor-block-list__block[data-type="core/paragraph"]', - ( element ) => element.innerText - ); - expect( text ).toMatch( 'Oh! Hello there!' ); - } ); - - it( 'can be created from multiselection', async () => { + it( 'can be created from multiselection and converted back to regular blocks', async () => { await createNewPost(); // Insert a Two paragraphs block @@ -255,38 +200,21 @@ describe( 'Reusable blocks', () => { await page.waitForXPath( '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' - ); - // Select all of the text in the title field. + // Set title. + await openDocumentSettingsSidebar(); + const nameInput = await page.waitForSelector( + reusableBlockNameInputSelector + ); + await nameInput.click(); await pressKeyWithModifier( 'primary', 'a' ); - - // Give the reusable block a title await page.keyboard.type( 'Multi-selection reusable block' ); // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); - - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); + await saveAll(); - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); + await clearAllBlocks(); - // Check that its title is displayed - const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText - ); - expect( title ).toBe( 'Multi-selection reusable block' ); - } ); - - it( 'multi-selection reusable block can be converted back to regular blocks', async () => { // Insert the reusable block we edited above await insertReusableBlock( 'Multi-selection reusable block' ); @@ -298,12 +226,18 @@ describe( 'Reusable blocks', () => { } ); it( 'will not break the editor if empty', async () => { - await insertReusableBlock( 'Awesome block' ); + await createReusableBlock( + 'Awesome Paragraph', + 'Random reusable block' + ); + await saveAll(); + await clearAllBlocks(); + await insertReusableBlock( 'Random reusable block' ); await visitAdminPage( 'edit.php', [ 'post_type=wp_block' ] ); const [ editButton ] = await page.$x( - `//a[contains(@aria-label, 'Awesome block')]` + `//a[contains(@aria-label, 'Random reusable block')]` ); await editButton.click(); @@ -339,4 +273,40 @@ describe( 'Reusable blocks', () => { expect( console ).not.toHaveErrored(); } ); + + it( 'should be able to insert a reusable block twice', async () => { + await createReusableBlock( + 'Awesome Paragraph', + 'Duplicated reusable block' + ); + await saveAll(); + await clearAllBlocks(); + await insertReusableBlock( 'Duplicated reusable block' ); + await insertReusableBlock( 'Duplicated reusable block' ); + await saveDraft(); + await page.reload(); + + // Replace the content of the first paragraph + const paragraphBlock = await page.waitForSelector( + '.block-editor-block-list__block[data-type="core/paragraph"]' + ); + paragraphBlock.focus(); + await pressKeyWithModifier( 'primary', 'a' ); + await page.keyboard.press( 'ArrowRight' ); + await page.keyboard.type( ' modified' ); + + // Wait for async mode to dispatch the update. + // eslint-disable-next-line no-restricted-syntax + await page.waitFor( 1000 ); + + // Check that the content of the second reusable block has been updated. + const reusableBlocks = await page.$$( '.wp-block-block' ); + reusableBlocks.forEach( async ( paragraph ) => { + const content = await paragraph.$eval( + 'p', + ( element ) => element.textContent + ); + expect( content ).toEqual( 'Awesome Paragraph modified' ); + } ); + } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/rtl.test.js b/packages/e2e-tests/specs/editor/various/rtl.test.js index 67f66ee77cc63a..f14219d5b17f64 100644 --- a/packages/e2e-tests/specs/editor/various/rtl.test.js +++ b/packages/e2e-tests/specs/editor/various/rtl.test.js @@ -17,6 +17,7 @@ describe( 'RTL', () => { await createNewPost(); await page.evaluate( () => { document.querySelector( '.is-root-container' ).dir = 'rtl'; + wp.i18n.isRTL = () => true; } ); } ); diff --git a/packages/e2e-tests/specs/experiments/blocks/post-title.test.js b/packages/e2e-tests/specs/experiments/blocks/post-title.test.js index 5e307541ff9cde..6bd00baba6d827 100644 --- a/packages/e2e-tests/specs/experiments/blocks/post-title.test.js +++ b/packages/e2e-tests/specs/experiments/blocks/post-title.test.js @@ -11,7 +11,7 @@ import { describe( 'Post Title block', () => { beforeAll( async () => { - await activateTheme( 'twentytwentyone-blocks' ); + await activateTheme( 'tt1-blocks' ); } ); afterAll( async () => { diff --git a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js index 3a8e75b31158c6..845b2e4044e98d 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-editing.test.js @@ -127,7 +127,7 @@ const removeErrorMocks = () => { describe( 'Multi-entity editor states', () => { beforeAll( async () => { - await activateTheme( 'twentytwentyone-blocks' ); + await activateTheme( 'tt1-blocks' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); diff --git a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js index 1cb3f8aaf773bf..7e2a1e127be5ff 100644 --- a/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js +++ b/packages/e2e-tests/specs/experiments/multi-entity-saving.test.js @@ -45,7 +45,7 @@ describe( 'Multi-entity save flow', () => { }; beforeAll( async () => { - await activateTheme( 'twentytwentyone-blocks' ); + await activateTheme( 'tt1-blocks' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); @@ -83,7 +83,6 @@ describe( 'Multi-entity save flow', () => { }; it( 'Save flow should work as expected.', async () => { - expect.assertions( 27 ); await createNewPost(); // Edit the page some. await page.click( '.editor-post-title' ); @@ -185,7 +184,6 @@ describe( 'Multi-entity save flow', () => { const saveA11ySelector = '.edit-site-editor__toggle-save-panel-button'; it( 'Save flow should work as expected', async () => { - expect.assertions( 5 ); // Navigate to site editor. const query = addQueryArgs( '', { page: 'gutenberg-edit-site', diff --git a/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js b/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js index 31a795a1b2d2f4..140f567e4d74fe 100644 --- a/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js +++ b/packages/e2e-tests/specs/experiments/post-editor-template-mode.test.js @@ -13,7 +13,7 @@ import { describe( 'Post Editor Template mode', () => { beforeAll( async () => { - await activateTheme( 'twentytwentyone-blocks' ); + await activateTheme( 'tt1-blocks' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); diff --git a/packages/e2e-tests/specs/experiments/template-part.test.js b/packages/e2e-tests/specs/experiments/template-part.test.js index e531067f277aaa..112f6bfc596818 100644 --- a/packages/e2e-tests/specs/experiments/template-part.test.js +++ b/packages/e2e-tests/specs/experiments/template-part.test.js @@ -21,7 +21,7 @@ import { navigationPanel } from '../../experimental-features'; describe( 'Template Part', () => { beforeAll( async () => { - await activateTheme( 'twentytwentyone-blocks' ); + await activateTheme( 'tt1-blocks' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template_part' ); } ); diff --git a/packages/e2e-tests/specs/performance/site-editor.test.js b/packages/e2e-tests/specs/performance/site-editor.test.js index ef468fe0453e9d..b638c1db1c3027 100644 --- a/packages/e2e-tests/specs/performance/site-editor.test.js +++ b/packages/e2e-tests/specs/performance/site-editor.test.js @@ -18,7 +18,7 @@ jest.setTimeout( 1000000 ); describe( 'Site Editor Performance', () => { beforeAll( async () => { - await activateTheme( 'twentytwentyone-blocks' ); + await activateTheme( 'tt1-blocks' ); await trashAllPosts( 'wp_template' ); await trashAllPosts( 'wp_template', 'auto-draft' ); await trashAllPosts( 'wp_template_part' ); diff --git a/packages/edit-post/README.md b/packages/edit-post/README.md index 485fbdea87427b..1aa9181145c28f 100644 --- a/packages/edit-post/README.md +++ b/packages/edit-post/README.md @@ -507,6 +507,18 @@ _Parameters_ - _settings_ `?Object`: Editor settings object. - _initialEdits_ `Object`: Programmatic edits to apply initially, to be considered as non-user-initiated (bypass for unsaved changes prompt). +# **store** + +Store definition for the edit post namespace. + +_Related_ + +- + +_Type_ + +- `Object` + diff --git a/packages/edit-post/src/components/device-preview/index.js b/packages/edit-post/src/components/device-preview/index.js index 742790caf0a245..3aaa5d8a04d103 100644 --- a/packages/edit-post/src/components/device-preview/index.js +++ b/packages/edit-post/src/components/device-preview/index.js @@ -8,6 +8,11 @@ import { __ } from '@wordpress/i18n'; import { __experimentalPreviewOptions as PreviewOptions } from '@wordpress/block-editor'; import { useDispatch, useSelect } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + export default function DevicePreview() { const { hasActiveMetaboxes, @@ -16,18 +21,18 @@ export default function DevicePreview() { deviceType, } = useSelect( ( select ) => ( { - hasActiveMetaboxes: select( 'core/edit-post' ).hasMetaBoxes(), - isSaving: select( 'core/edit-post' ).isSavingMetaBoxes(), + hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), + isSaving: select( editPostStore ).isSavingMetaBoxes(), isPostSaveable: select( 'core/editor' ).isEditedPostSaveable(), deviceType: select( - 'core/edit-post' + editPostStore ).__experimentalGetPreviewDeviceType(), } ), [] ); const { __experimentalSetPreviewDeviceType: setPreviewDeviceType, - } = useDispatch( 'core/edit-post' ); + } = useDispatch( editPostStore ); return ( ( { - isActive: select( 'core/edit-post' ).isFeatureActive( feature ), + isActive: select( editPostStore ).isFeatureActive( feature ), } ) ), withDispatch( ( dispatch, ownProps ) => ( { onToggle() { - dispatch( 'core/edit-post' ).toggleFeature( ownProps.feature ); + dispatch( editPostStore ).toggleFeature( ownProps.feature ); }, } ) ), ] )( FeatureToggle ); diff --git a/packages/edit-post/src/components/header/fullscreen-mode-close/index.js b/packages/edit-post/src/components/header/fullscreen-mode-close/index.js index 93d7f680487930..391d915d39d729 100644 --- a/packages/edit-post/src/components/header/fullscreen-mode-close/index.js +++ b/packages/edit-post/src/components/header/fullscreen-mode-close/index.js @@ -12,11 +12,16 @@ import { __ } from '@wordpress/i18n'; import { addQueryArgs } from '@wordpress/url'; import { wordpress } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + function FullscreenModeClose( { showTooltip, icon, href } ) { const { isActive, isRequestingSiteIcon, postType, siteIconUrl } = useSelect( ( select ) => { const { getCurrentPostType } = select( 'core/editor' ); - const { isFeatureActive } = select( 'core/edit-post' ); + const { isFeatureActive } = select( editPostStore ); const { isResolving } = select( 'core/data' ); const { getEntityRecord, getPostType } = select( 'core' ); const siteData = diff --git a/packages/edit-post/src/components/header/header-toolbar/index.js b/packages/edit-post/src/components/header/header-toolbar/index.js index 1349d67ffbc612..cc2efea4bf657a 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.js @@ -34,10 +34,11 @@ import { useRef } from '@wordpress/element'; * Internal dependencies */ import TemplateTitle from '../template-title'; +import { store as editPostStore } from '../../../store'; function HeaderToolbar() { const inserterButton = useRef(); - const { setIsInserterOpened } = useDispatch( 'core/edit-post' ); + const { setIsInserterOpened } = useDispatch( editPostStore ); const { hasFixedToolbar, isInserterEnabled, @@ -54,28 +55,28 @@ function HeaderToolbar() { getBlockSelectionEnd, } = select( 'core/block-editor' ); return { - hasFixedToolbar: select( 'core/edit-post' ).isFeatureActive( + hasFixedToolbar: select( editPostStore ).isFeatureActive( 'fixedToolbar' ), // This setting (richEditingEnabled) should not live in the block editor's setting. isInserterEnabled: - select( 'core/edit-post' ).getEditorMode() === 'visual' && + select( editPostStore ).getEditorMode() === 'visual' && select( 'core/editor' ).getEditorSettings() .richEditingEnabled && hasInserterItems( getBlockRootClientId( getBlockSelectionEnd() ) ), - isInserterOpened: select( 'core/edit-post' ).isInserterOpened(), + isInserterOpened: select( editPostStore ).isInserterOpened(), isTextModeEnabled: - select( 'core/edit-post' ).getEditorMode() === 'text', + select( editPostStore ).getEditorMode() === 'text', previewDeviceType: select( - 'core/edit-post' + editPostStore ).__experimentalGetPreviewDeviceType(), - showIconLabels: select( 'core/edit-post' ).isFeatureActive( + showIconLabels: select( editPostStore ).isFeatureActive( 'showIconLabels' ), isNavigationTool: select( 'core/block-editor' ).isNavigationMode(), - isTemplateMode: select( 'core/edit-post' ).isEditingTemplate(), + isTemplateMode: select( editPostStore ).isEditingTemplate(), }; }, [] ); const isLargeViewport = useViewportMatch( 'medium' ); diff --git a/packages/edit-post/src/components/header/header-toolbar/index.native.js b/packages/edit-post/src/components/header/header-toolbar/index.native.js index 39fa0544fe4a22..26c0717b4f05fc 100644 --- a/packages/edit-post/src/components/header/header-toolbar/index.native.js +++ b/packages/edit-post/src/components/header/header-toolbar/index.native.js @@ -23,6 +23,7 @@ import { * Internal dependencies */ import styles from './style.scss'; +import { store as editPostStore } from '../../../store'; function HeaderToolbar( { hasRedo, @@ -110,10 +111,9 @@ export default compose( [ hasUndo: select( 'core/editor' ).hasEditorUndo(), // This setting (richEditingEnabled) should not live in the block editor's setting. showInserter: - select( 'core/edit-post' ).getEditorMode() === 'visual' && + select( editPostStore ).getEditorMode() === 'visual' && select( 'core/editor' ).getEditorSettings().richEditingEnabled, - isTextModeEnabled: - select( 'core/edit-post' ).getEditorMode() === 'text', + isTextModeEnabled: select( editPostStore ).getEditorMode() === 'text', isRTL: select( 'core/block-editor' ).getSettings().isRTL, } ) ), withDispatch( ( dispatch ) => { diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index 639ba8424aeab8..6d30a275c10ad5 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -21,6 +21,7 @@ import PostPublishButtonOrToggle from './post-publish-button-or-toggle'; import { default as DevicePreview } from '../device-preview'; import MainDashboardButton from './main-dashboard-button'; import TemplateSaveButton from './template-save-button'; +import { store as editPostStore } from '../../store'; function Header( { setEntitiesSavedStatesCallback } ) { const { @@ -32,18 +33,18 @@ function Header( { setEntitiesSavedStatesCallback } ) { isEditingTemplate, } = useSelect( ( select ) => ( { - hasActiveMetaboxes: select( 'core/edit-post' ).hasMetaBoxes(), + hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), isPublishSidebarOpened: select( - 'core/edit-post' + editPostStore ).isPublishSidebarOpened(), - isSaving: select( 'core/edit-post' ).isSavingMetaBoxes(), - showIconLabels: select( 'core/edit-post' ).isFeatureActive( + isSaving: select( editPostStore ).isSavingMetaBoxes(), + showIconLabels: select( editPostStore ).isFeatureActive( 'showIconLabels' ), - hasReducedUI: select( 'core/edit-post' ).isFeatureActive( + hasReducedUI: select( editPostStore ).isFeatureActive( 'reducedUI' ), - isEditingTemplate: select( 'core/edit-post' ).isEditingTemplate(), + isEditingTemplate: select( editPostStore ).isEditingTemplate(), } ), [] ); diff --git a/packages/edit-post/src/components/header/mode-switcher/index.js b/packages/edit-post/src/components/header/mode-switcher/index.js index fa32c71f6d3f3d..0605188d474712 100644 --- a/packages/edit-post/src/components/header/mode-switcher/index.js +++ b/packages/edit-post/src/components/header/mode-switcher/index.js @@ -6,6 +6,11 @@ import { MenuItemsChoice, MenuGroup } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + /** * Set of available mode options. * @@ -37,11 +42,11 @@ function ModeSwitcher() { .richEditingEnabled, isCodeEditingEnabled: select( 'core/editor' ).getEditorSettings() .codeEditingEnabled, - mode: select( 'core/edit-post' ).getEditorMode(), + mode: select( editPostStore ).getEditorMode(), } ), [] ); - const { switchEditorMode } = useDispatch( 'core/edit-post' ); + const { switchEditorMode } = useDispatch( editPostStore ); if ( ! isRichEditingEnabled || ! isCodeEditingEnabled ) { return null; diff --git a/packages/edit-post/src/components/header/post-publish-button-or-toggle.js b/packages/edit-post/src/components/header/post-publish-button-or-toggle.js index bf91d0c23645df..2be75c4d0927f6 100644 --- a/packages/edit-post/src/components/header/post-publish-button-or-toggle.js +++ b/packages/edit-post/src/components/header/post-publish-button-or-toggle.js @@ -10,6 +10,11 @@ import { useViewportMatch, compose } from '@wordpress/compose'; import { withDispatch, withSelect } from '@wordpress/data'; import { PostPublishButton } from '@wordpress/editor'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + export function PostPublishButtonOrToggle( { forceIsDirty, forceIsSaving, @@ -90,12 +95,12 @@ export default compose( 'core/editor' ).isPublishSidebarEnabled(), isPublishSidebarOpened: select( - 'core/edit-post' + editPostStore ).isPublishSidebarOpened(), isScheduled: select( 'core/editor' ).isCurrentPostScheduled(), } ) ), withDispatch( ( dispatch ) => { - const { togglePublishSidebar } = dispatch( 'core/edit-post' ); + const { togglePublishSidebar } = dispatch( editPostStore ); return { togglePublishSidebar, }; diff --git a/packages/edit-post/src/components/header/preferences-menu-item/index.js b/packages/edit-post/src/components/header/preferences-menu-item/index.js index f12ef2c422f908..163ef900f362e5 100644 --- a/packages/edit-post/src/components/header/preferences-menu-item/index.js +++ b/packages/edit-post/src/components/header/preferences-menu-item/index.js @@ -5,6 +5,11 @@ import { withDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { MenuItem } from '@wordpress/components'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + export function PreferencesMenuItem( { openModal } ) { return ( { - const { openModal } = dispatch( 'core/edit-post' ); + const { openModal } = dispatch( editPostStore ); return { openModal, diff --git a/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js b/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js index 9c269c4a1be751..a05e3f20ba4a3d 100644 --- a/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js +++ b/packages/edit-post/src/components/keyboard-shortcut-help-modal/index.js @@ -22,6 +22,7 @@ import { compose } from '@wordpress/compose'; import { textFormattingShortcuts } from './config'; import Shortcut from './shortcut'; import DynamicShortcut from './dynamic-shortcut'; +import { store as editPostStore } from '../../store'; const MODAL_NAME = 'edit-post/keyboard-shortcut-help'; @@ -143,10 +144,10 @@ export function KeyboardShortcutHelpModal( { isModalActive, toggleModal } ) { export default compose( [ withSelect( ( select ) => ( { - isModalActive: select( 'core/edit-post' ).isModalActive( MODAL_NAME ), + isModalActive: select( editPostStore ).isModalActive( MODAL_NAME ), } ) ), withDispatch( ( dispatch, { isModalActive } ) => { - const { openModal, closeModal } = dispatch( 'core/edit-post' ); + const { openModal, closeModal } = dispatch( editPostStore ); return { toggleModal: () => diff --git a/packages/edit-post/src/components/keyboard-shortcuts/index.js b/packages/edit-post/src/components/keyboard-shortcuts/index.js index 65facebd21891a..4e7a46a92bf66f 100644 --- a/packages/edit-post/src/components/keyboard-shortcuts/index.js +++ b/packages/edit-post/src/components/keyboard-shortcuts/index.js @@ -9,6 +9,11 @@ import { } from '@wordpress/keyboard-shortcuts'; import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + function KeyboardShortcuts() { const { getBlockSelectionStart, @@ -21,8 +26,8 @@ function KeyboardShortcuts() { return { getBlockSelectionStart: select( 'core/block-editor' ) .getBlockSelectionStart, - getEditorMode: select( 'core/edit-post' ).getEditorMode, - isEditorSidebarOpened: select( 'core/edit-post' ) + getEditorMode: select( editPostStore ).getEditorMode, + isEditorSidebarOpened: select( editPostStore ) .isEditorSidebarOpened, richEditingEnabled: settings.richEditingEnabled, codeEditingEnabled: settings.codeEditingEnabled, @@ -34,7 +39,7 @@ function KeyboardShortcuts() { openGeneralSidebar, closeGeneralSidebar, toggleFeature, - } = useDispatch( 'core/edit-post' ); + } = useDispatch( editPostStore ); const { registerShortcut } = useDispatch( keyboardShortcutsStore ); useEffect( () => { diff --git a/packages/edit-post/src/components/layout/actions-panel.js b/packages/edit-post/src/components/layout/actions-panel.js index e1ad347a4bf7d7..44d3d1944428b9 100644 --- a/packages/edit-post/src/components/layout/actions-panel.js +++ b/packages/edit-post/src/components/layout/actions-panel.js @@ -11,6 +11,7 @@ import { useCallback } from '@wordpress/element'; */ import PluginPostPublishPanel from '../sidebar/plugin-post-publish-panel'; import PluginPrePublishPanel from '../sidebar/plugin-pre-publish-panel'; +import { store as editPostStore } from '../../store'; const { Fill, Slot } = createSlotFill( 'ActionsPanel' ); @@ -22,7 +23,7 @@ export default function ActionsPanel( { isEntitiesSavedStatesOpen, } ) { const { closePublishSidebar, togglePublishSidebar } = useDispatch( - 'core/edit-post' + editPostStore ); const { publishSidebarOpened, @@ -32,10 +33,10 @@ export default function ActionsPanel( { } = useSelect( ( select ) => { return { publishSidebarOpened: select( - 'core/edit-post' + editPostStore ).isPublishSidebarOpened(), - hasActiveMetaboxes: select( 'core/edit-post' ).hasMetaBoxes(), - isSavingMetaBoxes: select( 'core/edit-post' ).isSavingMetaBoxes(), + hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), + isSavingMetaBoxes: select( editPostStore ).isSavingMetaBoxes(), hasNonPostEntityChanges: select( 'core/editor' ).hasNonPostEntityChanges(), diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 013c9d18daccba..67628820b61550 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -55,6 +55,7 @@ import SettingsSidebar from '../sidebar/settings-sidebar'; import MetaBoxes from '../meta-boxes'; import WelcomeGuide from '../welcome-guide'; import ActionsPanel from './actions-panel'; +import { store as editPostStore } from '../../store'; const interfaceLabels = { secondarySidebar: __( 'Block library' ), @@ -77,7 +78,7 @@ function Layout( { settings } ) { openGeneralSidebar, closeGeneralSidebar, setIsInserterOpened, - } = useDispatch( 'core/edit-post' ); + } = useDispatch( editPostStore ); const { mode, isFullscreenActive, @@ -94,25 +95,25 @@ function Layout( { settings } ) { hasReducedUI, } = useSelect( ( select ) => { return { - hasFixedToolbar: select( 'core/edit-post' ).isFeatureActive( + hasFixedToolbar: select( editPostStore ).isFeatureActive( 'fixedToolbar' ), sidebarIsOpened: !! ( select( 'core/interface' ).getActiveComplementaryArea( - 'core/edit-post' - ) || select( 'core/edit-post' ).isPublishSidebarOpened() + editPostStore.name + ) || select( editPostStore ).isPublishSidebarOpened() ), - isFullscreenActive: select( 'core/edit-post' ).isFeatureActive( + isFullscreenActive: select( editPostStore ).isFeatureActive( 'fullscreenMode' ), - showMostUsedBlocks: select( 'core/edit-post' ).isFeatureActive( + showMostUsedBlocks: select( editPostStore ).isFeatureActive( 'mostUsedBlocks' ), - isInserterOpened: select( 'core/edit-post' ).isInserterOpened(), - mode: select( 'core/edit-post' ).getEditorMode(), + isInserterOpened: select( editPostStore ).isInserterOpened(), + mode: select( editPostStore ).getEditorMode(), isRichEditingEnabled: select( 'core/editor' ).getEditorSettings() .richEditingEnabled, - hasActiveMetaboxes: select( 'core/edit-post' ).hasMetaBoxes(), + hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), previousShortcut: select( keyboardShortcutsStore ).getAllShortcutRawKeyCombinations( @@ -121,10 +122,10 @@ function Layout( { settings } ) { nextShortcut: select( keyboardShortcutsStore ).getAllShortcutRawKeyCombinations( 'core/edit-post/next-region' ), - showIconLabels: select( 'core/edit-post' ).isFeatureActive( + showIconLabels: select( editPostStore ).isFeatureActive( 'showIconLabels' ), - hasReducedUI: select( 'core/edit-post' ).isFeatureActive( + hasReducedUI: select( editPostStore ).isFeatureActive( 'reducedUI' ), }; diff --git a/packages/edit-post/src/components/layout/index.native.js b/packages/edit-post/src/components/layout/index.native.js index 3664262f147ae1..14c08553c5b94a 100644 --- a/packages/edit-post/src/components/layout/index.native.js +++ b/packages/edit-post/src/components/layout/index.native.js @@ -31,6 +31,7 @@ import styles from './style.scss'; import headerToolbarStyles from '../header/header-toolbar/style.scss'; import Header from '../header'; import VisualEditor from '../visual-editor'; +import { store as editPostStore } from '../../store'; class Layout extends Component { constructor() { @@ -174,7 +175,7 @@ export default compose( [ const { __unstableIsEditorReady: isEditorReady } = select( 'core/editor' ); - const { getEditorMode } = select( 'core/edit-post' ); + const { getEditorMode } = select( editPostStore ); const { getSettings } = select( 'core/block-editor' ); return { isReady: isEditorReady(), diff --git a/packages/edit-post/src/components/manage-blocks-modal/category.js b/packages/edit-post/src/components/manage-blocks-modal/category.js index 3169115c86b83b..3583f47b9e7211 100644 --- a/packages/edit-post/src/components/manage-blocks-modal/category.js +++ b/packages/edit-post/src/components/manage-blocks-modal/category.js @@ -16,6 +16,7 @@ import { CheckboxControl } from '@wordpress/components'; */ import BlockTypesChecklist from './checklist'; import EditPostSettings from '../edit-post-settings'; +import { store as editPostStore } from '../../store'; function BlockManagerCategory( { instanceId, @@ -84,14 +85,14 @@ function BlockManagerCategory( { export default compose( [ withInstanceId, withSelect( ( select ) => { - const { getPreference } = select( 'core/edit-post' ); + const { getPreference } = select( editPostStore ); return { hiddenBlockTypes: getPreference( 'hiddenBlockTypes' ), }; } ), withDispatch( ( dispatch, ownProps ) => { - const { showBlockTypes, hideBlockTypes } = dispatch( 'core/edit-post' ); + const { showBlockTypes, hideBlockTypes } = dispatch( editPostStore ); return { toggleVisible( blockName, nextIsChecked ) { diff --git a/packages/edit-post/src/components/manage-blocks-modal/index.js b/packages/edit-post/src/components/manage-blocks-modal/index.js index ee88068ad6d6e1..9bba595ed0be6d 100644 --- a/packages/edit-post/src/components/manage-blocks-modal/index.js +++ b/packages/edit-post/src/components/manage-blocks-modal/index.js @@ -10,6 +10,7 @@ import { compose } from '@wordpress/compose'; * Internal dependencies */ import BlockManager from './manager'; +import { store as editPostStore } from '../../store'; /** * Unique identifier for Manage Blocks modal. @@ -37,14 +38,14 @@ export function ManageBlocksModal( { isActive, closeModal } ) { export default compose( [ withSelect( ( select ) => { - const { isModalActive } = select( 'core/edit-post' ); + const { isModalActive } = select( editPostStore ); return { isActive: isModalActive( MODAL_NAME ), }; } ), withDispatch( ( dispatch ) => { - const { closeModal } = dispatch( 'core/edit-post' ); + const { closeModal } = dispatch( editPostStore ); return { closeModal, diff --git a/packages/edit-post/src/components/manage-blocks-modal/manager.js b/packages/edit-post/src/components/manage-blocks-modal/manager.js index 85c2af7917c775..b6df0ee16e41d3 100644 --- a/packages/edit-post/src/components/manage-blocks-modal/manager.js +++ b/packages/edit-post/src/components/manage-blocks-modal/manager.js @@ -16,6 +16,7 @@ import { __, _n, sprintf } from '@wordpress/i18n'; * Internal dependencies */ import BlockManagerCategory from './category'; +import { store as editPostStore } from '../../store'; function BlockManager( { search, @@ -104,7 +105,7 @@ export default compose( [ hasBlockSupport, isMatchingSearchTerm, } = select( blocksStore ); - const { getPreference } = select( 'core/edit-post' ); + const { getPreference } = select( editPostStore ); const hiddenBlockTypes = getPreference( 'hiddenBlockTypes' ); const numberOfHiddenBlocks = isArray( hiddenBlockTypes ) && hiddenBlockTypes.length; diff --git a/packages/edit-post/src/components/meta-boxes/index.js b/packages/edit-post/src/components/meta-boxes/index.js index 35ef20f04a2df3..e5e3e2ac2066df 100644 --- a/packages/edit-post/src/components/meta-boxes/index.js +++ b/packages/edit-post/src/components/meta-boxes/index.js @@ -13,6 +13,7 @@ import { withSelect } from '@wordpress/data'; */ import MetaBoxesArea from './meta-boxes-area'; import MetaBoxVisibility from './meta-box-visibility'; +import { store as editPostStore } from '../../store'; function MetaBoxes( { location, isVisible, metaBoxes } ) { return ( @@ -27,7 +28,7 @@ function MetaBoxes( { location, isVisible, metaBoxes } ) { export default withSelect( ( select, { location } ) => { const { isMetaBoxLocationVisible, getMetaBoxesPerLocation } = select( - 'core/edit-post' + editPostStore ); return { diff --git a/packages/edit-post/src/components/meta-boxes/meta-box-visibility.js b/packages/edit-post/src/components/meta-boxes/meta-box-visibility.js index c6af87bebb2607..488d73e1a76e03 100644 --- a/packages/edit-post/src/components/meta-boxes/meta-box-visibility.js +++ b/packages/edit-post/src/components/meta-boxes/meta-box-visibility.js @@ -4,6 +4,11 @@ import { Component } from '@wordpress/element'; import { withSelect } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + class MetaBoxVisibility extends Component { componentDidMount() { this.updateDOM(); @@ -36,7 +41,7 @@ class MetaBoxVisibility extends Component { } export default withSelect( ( select, { id } ) => ( { - isVisible: select( 'core/edit-post' ).isEditorPanelEnabled( + isVisible: select( editPostStore ).isEditorPanelEnabled( `meta-box-${ id }` ), } ) )( MetaBoxVisibility ); diff --git a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js index 239d013be69b98..d5e8a13458bb0e 100644 --- a/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js +++ b/packages/edit-post/src/components/meta-boxes/meta-boxes-area/index.js @@ -10,6 +10,11 @@ import { Component } from '@wordpress/element'; import { Spinner } from '@wordpress/components'; import { withSelect } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + class MetaBoxesArea extends Component { /** * @inheritdoc @@ -78,6 +83,6 @@ class MetaBoxesArea extends Component { export default withSelect( ( select ) => { return { - isSaving: select( 'core/edit-post' ).isSavingMetaBoxes(), + isSaving: select( editPostStore ).isSavingMetaBoxes(), }; } )( MetaBoxesArea ); diff --git a/packages/edit-post/src/components/preferences-modal/index.js b/packages/edit-post/src/components/preferences-modal/index.js index 1066c718a29d55..e237984e29df7c 100644 --- a/packages/edit-post/src/components/preferences-modal/index.js +++ b/packages/edit-post/src/components/preferences-modal/index.js @@ -29,6 +29,7 @@ import { EnableFeature, } from './options'; import MetaBoxesSection from './meta-boxes-section'; +import { store as editPostStore } from '../../store'; const MODAL_NAME = 'edit-post/preferences'; @@ -154,15 +155,13 @@ export default compose( const postType = getPostType( getEditedPostAttribute( 'type' ) ); return { - isModalActive: select( 'core/edit-post' ).isModalActive( - MODAL_NAME - ), + isModalActive: select( editPostStore ).isModalActive( MODAL_NAME ), isViewable: get( postType, [ 'viewable' ], false ), }; } ), withDispatch( ( dispatch ) => { return { - closeModal: () => dispatch( 'core/edit-post' ).closeModal(), + closeModal: () => dispatch( editPostStore ).closeModal(), }; } ) )( PreferencesModal ); diff --git a/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js b/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js index 802f8a88955a26..54c388616436cb 100644 --- a/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js +++ b/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js @@ -14,6 +14,7 @@ import { withSelect } from '@wordpress/data'; */ import Section from './section'; import { EnableCustomFieldsOption, EnablePanelOption } from './options'; +import { store as editPostStore } from '../../store'; export function MetaBoxesSection( { areCustomFieldsRegistered, @@ -48,7 +49,7 @@ export function MetaBoxesSection( { export default withSelect( ( select ) => { const { getEditorSettings } = select( 'core/editor' ); - const { getAllMetaBoxes } = select( 'core/edit-post' ); + const { getAllMetaBoxes } = select( editPostStore ); return { // This setting should not live in the block editor's store. diff --git a/packages/edit-post/src/components/preferences-modal/options/enable-feature.js b/packages/edit-post/src/components/preferences-modal/options/enable-feature.js index 4868b2f09a7b72..315dd2ed656e50 100644 --- a/packages/edit-post/src/components/preferences-modal/options/enable-feature.js +++ b/packages/edit-post/src/components/preferences-modal/options/enable-feature.js @@ -8,16 +8,16 @@ import { withSelect, withDispatch } from '@wordpress/data'; * Internal dependencies */ import BaseOption from './base'; +import { store as editPostStore } from '../../../store'; export default compose( withSelect( ( select, { featureName } ) => { - const { isFeatureActive } = select( 'core/edit-post' ); + const { isFeatureActive } = select( editPostStore ); return { isChecked: isFeatureActive( featureName ), }; } ), withDispatch( ( dispatch, { featureName } ) => ( { - onChange: () => - dispatch( 'core/edit-post' ).toggleFeature( featureName ), + onChange: () => dispatch( editPostStore ).toggleFeature( featureName ), } ) ) )( BaseOption ); diff --git a/packages/edit-post/src/components/preferences-modal/options/enable-panel.js b/packages/edit-post/src/components/preferences-modal/options/enable-panel.js index 57d134c0e6ef68..0a25b4ad4d86a7 100644 --- a/packages/edit-post/src/components/preferences-modal/options/enable-panel.js +++ b/packages/edit-post/src/components/preferences-modal/options/enable-panel.js @@ -8,11 +8,12 @@ import { withSelect, withDispatch } from '@wordpress/data'; * Internal dependencies */ import BaseOption from './base'; +import { store as editPostStore } from '../../../store'; export default compose( withSelect( ( select, { panelName } ) => { const { isEditorPanelEnabled, isEditorPanelRemoved } = select( - 'core/edit-post' + editPostStore ); return { isRemoved: isEditorPanelRemoved( panelName ), @@ -22,6 +23,6 @@ export default compose( ifCondition( ( { isRemoved } ) => ! isRemoved ), withDispatch( ( dispatch, { panelName } ) => ( { onChange: () => - dispatch( 'core/edit-post' ).toggleEditorPanelEnabled( panelName ), + dispatch( editPostStore ).toggleEditorPanelEnabled( panelName ), } ) ) )( BaseOption ); diff --git a/packages/edit-post/src/components/sidebar/discussion-panel/index.js b/packages/edit-post/src/components/sidebar/discussion-panel/index.js index 47ea5ae4e500b5..cc72cb245b0576 100644 --- a/packages/edit-post/src/components/sidebar/discussion-panel/index.js +++ b/packages/edit-post/src/components/sidebar/discussion-panel/index.js @@ -11,6 +11,11 @@ import { import { compose } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + /** * Module Constants */ @@ -47,17 +52,15 @@ function DiscussionPanel( { isEnabled, isOpened, onTogglePanel } ) { export default compose( [ withSelect( ( select ) => { return { - isEnabled: select( 'core/edit-post' ).isEditorPanelEnabled( - PANEL_NAME - ), - isOpened: select( 'core/edit-post' ).isEditorPanelOpened( + isEnabled: select( editPostStore ).isEditorPanelEnabled( PANEL_NAME ), + isOpened: select( editPostStore ).isEditorPanelOpened( PANEL_NAME ), }; } ), withDispatch( ( dispatch ) => ( { onTogglePanel() { - return dispatch( 'core/edit-post' ).toggleEditorPanelOpened( + return dispatch( editPostStore ).toggleEditorPanelOpened( PANEL_NAME ); }, diff --git a/packages/edit-post/src/components/sidebar/featured-image/index.js b/packages/edit-post/src/components/sidebar/featured-image/index.js index 63a95fb76178b5..3c6fd8e286d002 100644 --- a/packages/edit-post/src/components/sidebar/featured-image/index.js +++ b/packages/edit-post/src/components/sidebar/featured-image/index.js @@ -12,6 +12,11 @@ import { PostFeaturedImage, PostFeaturedImageCheck } from '@wordpress/editor'; import { compose } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + /** * Module Constants */ @@ -43,7 +48,7 @@ const applyWithSelect = withSelect( ( select ) => { const { getEditedPostAttribute } = select( 'core/editor' ); const { getPostType } = select( 'core' ); const { isEditorPanelEnabled, isEditorPanelOpened } = select( - 'core/edit-post' + editPostStore ); return { @@ -54,7 +59,7 @@ const applyWithSelect = withSelect( ( select ) => { } ); const applyWithDispatch = withDispatch( ( dispatch ) => { - const { toggleEditorPanelOpened } = dispatch( 'core/edit-post' ); + const { toggleEditorPanelOpened } = dispatch( editPostStore ); return { onTogglePanel: partial( toggleEditorPanelOpened, PANEL_NAME ), diff --git a/packages/edit-post/src/components/sidebar/page-attributes/index.js b/packages/edit-post/src/components/sidebar/page-attributes/index.js index 97e7199ef41871..bdbf94c6f2de53 100644 --- a/packages/edit-post/src/components/sidebar/page-attributes/index.js +++ b/packages/edit-post/src/components/sidebar/page-attributes/index.js @@ -17,6 +17,11 @@ import { } from '@wordpress/editor'; import { withSelect, withDispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + /** * Module Constants */ @@ -55,7 +60,7 @@ export function PageAttributes( { const applyWithSelect = withSelect( ( select ) => { const { getEditedPostAttribute } = select( 'core/editor' ); const { isEditorPanelEnabled, isEditorPanelOpened } = select( - 'core/edit-post' + editPostStore ); const { getPostType } = select( 'core' ); return { @@ -66,7 +71,7 @@ const applyWithSelect = withSelect( ( select ) => { } ); const applyWithDispatch = withDispatch( ( dispatch ) => { - const { toggleEditorPanelOpened } = dispatch( 'core/edit-post' ); + const { toggleEditorPanelOpened } = dispatch( editPostStore ); return { onTogglePanel: partial( toggleEditorPanelOpened, PANEL_NAME ), 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 681897d5f26716..b7ceebd3031f5d 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 @@ -15,6 +15,7 @@ import warning from '@wordpress/warning'; * Internal dependencies */ import { EnablePluginDocumentSettingPanelOption } from '../../preferences-modal/options'; +import { store as editPostStore } from '../../../store'; export const { Fill, Slot } = createSlotFill( 'PluginDocumentSettingPanel' ); @@ -115,15 +116,15 @@ const PluginDocumentSettingPanel = compose( } ), withSelect( ( select, { panelName } ) => { return { - opened: select( 'core/edit-post' ).isEditorPanelOpened( panelName ), - isEnabled: select( 'core/edit-post' ).isEditorPanelEnabled( + opened: select( editPostStore ).isEditorPanelOpened( panelName ), + isEnabled: select( editPostStore ).isEditorPanelEnabled( panelName ), }; } ), withDispatch( ( dispatch, { panelName } ) => ( { onToggle() { - return dispatch( 'core/edit-post' ).toggleEditorPanelOpened( + return dispatch( editPostStore ).toggleEditorPanelOpened( panelName ); }, 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 d6193b0448979e..b1f6cb517145ad 100644 --- a/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/plugin-sidebar/index.js @@ -6,6 +6,11 @@ import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + /** * Renders a sidebar when activated. The contents within the `PluginSidebar` will appear as content within the sidebar. * If you wish to display the sidebar, you can with use the `PluginSidebarMoreMenuItem` component or the `wp.data.dispatch` API: @@ -81,7 +86,7 @@ export default function PluginSidebarEditPost( { className, ...props } ) { shortcut: select( keyboardShortcutsStore ).getShortcutRepresentation( 'core/edit-post/toggle-sidebar' ), - showIconLabels: select( 'core/edit-post' ).isFeatureActive( + showIconLabels: select( editPostStore ).isFeatureActive( 'showIconLabels' ), }; diff --git a/packages/edit-post/src/components/sidebar/post-excerpt/index.js b/packages/edit-post/src/components/sidebar/post-excerpt/index.js index 1502bc7e7a3de2..208fa733fc7289 100644 --- a/packages/edit-post/src/components/sidebar/post-excerpt/index.js +++ b/packages/edit-post/src/components/sidebar/post-excerpt/index.js @@ -10,6 +10,11 @@ import { import { compose } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + /** * Module Constants */ @@ -36,17 +41,15 @@ function PostExcerpt( { isEnabled, isOpened, onTogglePanel } ) { export default compose( [ withSelect( ( select ) => { return { - isEnabled: select( 'core/edit-post' ).isEditorPanelEnabled( - PANEL_NAME - ), - isOpened: select( 'core/edit-post' ).isEditorPanelOpened( + isEnabled: select( editPostStore ).isEditorPanelEnabled( PANEL_NAME ), + isOpened: select( editPostStore ).isEditorPanelOpened( PANEL_NAME ), }; } ), withDispatch( ( dispatch ) => ( { onTogglePanel() { - return dispatch( 'core/edit-post' ).toggleEditorPanelOpened( + return dispatch( editPostStore ).toggleEditorPanelOpened( PANEL_NAME ); }, diff --git a/packages/edit-post/src/components/sidebar/post-link/index.js b/packages/edit-post/src/components/sidebar/post-link/index.js index 3a73af2e6da7dd..c765f3a320b62d 100644 --- a/packages/edit-post/src/components/sidebar/post-link/index.js +++ b/packages/edit-post/src/components/sidebar/post-link/index.js @@ -13,6 +13,11 @@ import { compose, ifCondition, withState } from '@wordpress/compose'; import { cleanForSlug } from '@wordpress/editor'; import { safeDecodeURIComponent } from '@wordpress/url'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + /** * Module Constants */ @@ -133,7 +138,7 @@ export default compose( [ getEditedPostSlug, } = select( 'core/editor' ); const { isEditorPanelEnabled, isEditorPanelOpened } = select( - 'core/edit-post' + editPostStore ); const { getPostType } = select( 'core' ); @@ -161,7 +166,7 @@ export default compose( [ return isEnabled && postLink && isViewable && hasPermalinkParts; } ), withDispatch( ( dispatch ) => { - const { toggleEditorPanelOpened } = dispatch( 'core/edit-post' ); + const { toggleEditorPanelOpened } = dispatch( editPostStore ); const { editPost } = dispatch( 'core/editor' ); return { onTogglePanel: () => toggleEditorPanelOpened( PANEL_NAME ), 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 ad2437e4c1f1a0..43fb7d1646fec1 100644 --- a/packages/edit-post/src/components/sidebar/post-status/index.js +++ b/packages/edit-post/src/components/sidebar/post-status/index.js @@ -19,6 +19,7 @@ import PostFormat from '../post-format'; import PostPendingStatus from '../post-pending-status'; import PluginPostStatusInfo from '../plugin-post-status-info'; import PostTemplate from '../post-template'; +import { store as editPostStore } from '../../../store'; /** * Module Constants @@ -58,7 +59,7 @@ export default compose( [ // We use isEditorPanelRemoved to hide the panel if it was programatically removed. We do // not use isEditorPanelEnabled since this panel should not be disabled through the UI. const { isEditorPanelRemoved, isEditorPanelOpened } = select( - 'core/edit-post' + editPostStore ); return { isRemoved: isEditorPanelRemoved( PANEL_NAME ), @@ -68,7 +69,7 @@ export default compose( [ ifCondition( ( { isRemoved } ) => ! isRemoved ), withDispatch( ( dispatch ) => ( { onTogglePanel() { - return dispatch( 'core/edit-post' ).toggleEditorPanelOpened( + return dispatch( editPostStore ).toggleEditorPanelOpened( PANEL_NAME ); }, diff --git a/packages/edit-post/src/components/sidebar/post-taxonomies/taxonomy-panel.js b/packages/edit-post/src/components/sidebar/post-taxonomies/taxonomy-panel.js index 59febc55554a39..aaa92ae63bcfba 100644 --- a/packages/edit-post/src/components/sidebar/post-taxonomies/taxonomy-panel.js +++ b/packages/edit-post/src/components/sidebar/post-taxonomies/taxonomy-panel.js @@ -10,6 +10,11 @@ import { compose } from '@wordpress/compose'; import { PanelBody } from '@wordpress/components'; import { withSelect, withDispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + function TaxonomyPanel( { isEnabled, taxonomy, @@ -44,16 +49,16 @@ export default compose( return { panelName, isEnabled: slug - ? select( 'core/edit-post' ).isEditorPanelEnabled( panelName ) + ? select( editPostStore ).isEditorPanelEnabled( panelName ) : false, isOpened: slug - ? select( 'core/edit-post' ).isEditorPanelOpened( panelName ) + ? select( editPostStore ).isEditorPanelOpened( panelName ) : false, }; } ), withDispatch( ( dispatch, ownProps ) => ( { onTogglePanel: () => { - dispatch( 'core/edit-post' ).toggleEditorPanelOpened( + dispatch( editPostStore ).toggleEditorPanelOpened( ownProps.panelName ); }, diff --git a/packages/edit-post/src/components/sidebar/post-template/index.js b/packages/edit-post/src/components/sidebar/post-template/index.js index 9c3380860aacbf..38168cc6794b79 100644 --- a/packages/edit-post/src/components/sidebar/post-template/index.js +++ b/packages/edit-post/src/components/sidebar/post-template/index.js @@ -18,8 +18,8 @@ function PostTemplate() { const { template, isEditing, isFSETheme } = useSelect( ( select ) => { const { getEditedPostAttribute, - __unstableIsAutodraftPost, getCurrentPostType, + getCurrentPost, } = select( editorStore ); const { __experimentalGetTemplateForLink } = select( coreStore ); const { isEditingTemplate } = select( editPostStore ); @@ -30,7 +30,7 @@ function PostTemplate() { template: isFSEEnabled && link && - ! __unstableIsAutodraftPost() && + getCurrentPost().status !== 'auto-draft' && getCurrentPostType() !== 'wp_template' ? __experimentalGetTemplateForLink( link ) : null, diff --git a/packages/edit-post/src/components/sidebar/settings-header/index.js b/packages/edit-post/src/components/sidebar/settings-header/index.js index 6a144d4daeb2b4..b614ec0ebaf102 100644 --- a/packages/edit-post/src/components/sidebar/settings-header/index.js +++ b/packages/edit-post/src/components/sidebar/settings-header/index.js @@ -5,8 +5,13 @@ import { Button } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import { useDispatch, useSelect } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../../store'; + const SettingsHeader = ( { sidebarName } ) => { - const { openGeneralSidebar } = useDispatch( 'core/edit-post' ); + const { openGeneralSidebar } = useDispatch( editPostStore ); const openDocumentSettings = () => openGeneralSidebar( 'edit-post/document' ); const openBlockSettings = () => openGeneralSidebar( 'edit-post/block' ); diff --git a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js index d488179edc7184..34395f1bb94f05 100644 --- a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js @@ -23,6 +23,7 @@ import PluginDocumentSettingPanel from '../plugin-document-setting-panel'; import PluginSidebarEditPost from '../../sidebar/plugin-sidebar'; import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; +import { store as editPostStore } from '../../../store'; const SIDEBAR_ACTIVE_BY_DEFAULT = Platform.select( { web: true, @@ -39,7 +40,7 @@ const SettingsSidebar = () => { // should contain the sidebar that will be active when the toggle button is pressed. If a block // is selected, that should be edit-post/block otherwise it's edit-post/document. let sidebar = select( 'core/interface' ).getActiveComplementaryArea( - 'core/edit-post' + editPostStore.name ); if ( ! [ 'edit-post/document', 'edit-post/block' ].includes( sidebar ) diff --git a/packages/edit-post/src/components/text-editor/index.js b/packages/edit-post/src/components/text-editor/index.js index 30102330e53776..c056b72a30ea68 100644 --- a/packages/edit-post/src/components/text-editor/index.js +++ b/packages/edit-post/src/components/text-editor/index.js @@ -12,6 +12,11 @@ import { __ } from '@wordpress/i18n'; import { displayShortcut } from '@wordpress/keycodes'; import { compose } from '@wordpress/compose'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + function TextEditor( { onExit, isRichEditingEnabled } ) { return (
@@ -44,7 +49,7 @@ export default compose( withDispatch( ( dispatch ) => { return { onExit() { - dispatch( 'core/edit-post' ).switchEditorMode( 'visual' ); + dispatch( editPostStore ).switchEditorMode( 'visual' ); }, }; } ) diff --git a/packages/edit-post/src/components/visual-editor/block-inspector-button.js b/packages/edit-post/src/components/visual-editor/block-inspector-button.js index 2eb90256b4c17d..e5e6b1e02f90a0 100644 --- a/packages/edit-post/src/components/visual-editor/block-inspector-button.js +++ b/packages/edit-post/src/components/visual-editor/block-inspector-button.js @@ -12,6 +12,11 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { speak } from '@wordpress/a11y'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + export function BlockInspectorButton( { onClick = noop, small = false } ) { const { shortcut, areAdvancedSettingsOpened } = useSelect( ( select ) => ( { @@ -19,13 +24,13 @@ export function BlockInspectorButton( { onClick = noop, small = false } ) { keyboardShortcutsStore ).getShortcutRepresentation( 'core/edit-post/toggle-sidebar' ), areAdvancedSettingsOpened: - select( 'core/edit-post' ).getActiveGeneralSidebarName() === + select( editPostStore ).getActiveGeneralSidebarName() === 'edit-post/block', } ), [] ); const { openGeneralSidebar, closeGeneralSidebar } = useDispatch( - 'core/edit-post' + editPostStore ); const speakMessage = () => { diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 0f6d4b73d94f34..4829c5d483de1c 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -25,6 +25,7 @@ import { useRef } from '@wordpress/element'; */ import BlockInspectorButton from './block-inspector-button'; import { useSelect } from '@wordpress/data'; +import { store as editPostStore } from '../../store'; export default function VisualEditor() { const ref = useRef(); @@ -32,14 +33,14 @@ export default function VisualEditor() { const { isEditingTemplate, __experimentalGetPreviewDeviceType, - } = select( 'core/edit-post' ); + } = select( editPostStore ); return { deviceType: __experimentalGetPreviewDeviceType(), isTemplateMode: isEditingTemplate(), }; }, [] ); const hasMetaBoxes = useSelect( - ( select ) => select( 'core/edit-post' ).hasMetaBoxes(), + ( select ) => select( editPostStore ).hasMetaBoxes(), [] ); const desktopCanvasStyles = { @@ -64,6 +65,7 @@ export default function VisualEditor() {
diff --git a/packages/edit-post/src/components/welcome-guide/index.js b/packages/edit-post/src/components/welcome-guide/index.js index 56c30202af1729..78481c9467f86d 100644 --- a/packages/edit-post/src/components/welcome-guide/index.js +++ b/packages/edit-post/src/components/welcome-guide/index.js @@ -16,15 +16,15 @@ import { DocumentationImage, InserterIconImage, } from './images'; +import { store as editPostStore } from '../../store'; export default function WelcomeGuide() { const isActive = useSelect( - ( select ) => - select( 'core/edit-post' ).isFeatureActive( 'welcomeGuide' ), + ( select ) => select( editPostStore ).isFeatureActive( 'welcomeGuide' ), [] ); - const { toggleFeature } = useDispatch( 'core/edit-post' ); + const { toggleFeature } = useDispatch( editPostStore ); if ( ! isActive ) { return null; diff --git a/packages/edit-post/src/editor.js b/packages/edit-post/src/editor.js index 898adf8652f0a9..5487f88b4fd36f 100644 --- a/packages/edit-post/src/editor.js +++ b/packages/edit-post/src/editor.js @@ -27,6 +27,7 @@ import preventEventDiscovery from './prevent-event-discovery'; import Layout from './components/layout'; import EditorInitialization from './components/editor-initialization'; import EditPostSettings from './components/edit-post-settings'; +import { store as editPostStore } from './store'; function Editor( { postId, @@ -55,13 +56,11 @@ function Editor( { getPreference, __experimentalGetPreviewDeviceType, isEditingTemplate, - } = select( 'core/edit-post' ); + } = select( editPostStore ); const { getEntityRecord, __experimentalGetTemplateForLink } = select( 'core' ); - const { getEditorSettings, __unstableIsAutodraftPost } = select( - 'core/editor' - ); + const { getEditorSettings, getCurrentPost } = select( 'core/editor' ); const { getBlockTypes } = select( blocksStore ); const postObject = getEntityRecord( 'postType', postType, postId ); const isFSETheme = getEditorSettings().isFSETheme; @@ -86,7 +85,7 @@ function Editor( { template: isFSETheme && postObject && - ! __unstableIsAutodraftPost() && + getCurrentPost().status !== 'auto-draft' && postType !== 'wp_template' ? __experimentalGetTemplateForLink( postObject.link ) : null, @@ -95,7 +94,7 @@ function Editor( { } ); const { updatePreferredStyleVariations, setIsInserterOpened } = useDispatch( - 'core/edit-post' + editPostStore ); const editorSettings = useMemo( () => { diff --git a/packages/edit-post/src/editor.native.js b/packages/edit-post/src/editor.native.js index 2e7c227aa321f4..34ea06067cca48 100644 --- a/packages/edit-post/src/editor.native.js +++ b/packages/edit-post/src/editor.native.js @@ -26,6 +26,7 @@ import { Preview } from '@wordpress/block-editor'; * Internal dependencies */ import Layout from './components/layout'; +import { store as editPostStore } from './store'; class Editor extends Component { constructor( props ) { @@ -171,7 +172,7 @@ export default compose( [ getEditorMode, getPreference, __experimentalGetPreviewDeviceType, - } = select( 'core/edit-post' ); + } = select( editPostStore ); const { getBlockTypes } = select( blocksStore ); return { @@ -185,7 +186,7 @@ export default compose( [ }; } ), withDispatch( ( dispatch ) => { - const { switchEditorMode } = dispatch( 'core/edit-post' ); + const { switchEditorMode } = dispatch( editPostStore ); return { switchEditorMode, }; diff --git a/packages/edit-post/src/index.js b/packages/edit-post/src/index.js index 19e4c48a246814..e7759c013ad024 100644 --- a/packages/edit-post/src/index.js +++ b/packages/edit-post/src/index.js @@ -15,7 +15,7 @@ import { render, unmountComponentAtNode } from '@wordpress/element'; */ import './hooks'; import './plugins'; -import './store'; +export { store } from './store'; import Editor from './editor'; /** diff --git a/packages/edit-post/src/index.native.js b/packages/edit-post/src/index.native.js index 70b0924f967fdb..ff3a028bf719c8 100644 --- a/packages/edit-post/src/index.native.js +++ b/packages/edit-post/src/index.native.js @@ -8,7 +8,7 @@ import { render } from '@wordpress/element'; /** * Internal dependencies */ -import './store'; +export { store } from './store'; import Editor from './editor'; let editorInitialized = false; diff --git a/packages/edit-post/src/plugins/keyboard-shortcuts-help-menu-item/index.js b/packages/edit-post/src/plugins/keyboard-shortcuts-help-menu-item/index.js index 73d3b09683f501..69f7b35c3f1167 100644 --- a/packages/edit-post/src/plugins/keyboard-shortcuts-help-menu-item/index.js +++ b/packages/edit-post/src/plugins/keyboard-shortcuts-help-menu-item/index.js @@ -6,6 +6,11 @@ import { withDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { displayShortcut } from '@wordpress/keycodes'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + export function KeyboardShortcutsHelpMenuItem( { openModal } ) { return ( { - const { openModal } = dispatch( 'core/edit-post' ); + const { openModal } = dispatch( editPostStore ); return { openModal, diff --git a/packages/edit-post/src/plugins/manage-blocks-menu-item/index.js b/packages/edit-post/src/plugins/manage-blocks-menu-item/index.js index 4275f0a36988e3..64340588509274 100644 --- a/packages/edit-post/src/plugins/manage-blocks-menu-item/index.js +++ b/packages/edit-post/src/plugins/manage-blocks-menu-item/index.js @@ -5,6 +5,11 @@ import { MenuItem } from '@wordpress/components'; import { withDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + export function ManageBlocksMenuItem( { openModal } ) { return ( { - const { openModal } = dispatch( 'core/edit-post' ); + const { openModal } = dispatch( editPostStore ); return { openModal, diff --git a/packages/edit-post/src/plugins/welcome-guide-menu-item/index.js b/packages/edit-post/src/plugins/welcome-guide-menu-item/index.js index de7d00cab912e4..1969311e6c2461 100644 --- a/packages/edit-post/src/plugins/welcome-guide-menu-item/index.js +++ b/packages/edit-post/src/plugins/welcome-guide-menu-item/index.js @@ -5,8 +5,13 @@ import { useDispatch } from '@wordpress/data'; import { MenuItem } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import { store as editPostStore } from '../../store'; + export default function WelcomeGuideMenuItem() { - const { toggleFeature } = useDispatch( 'core/edit-post' ); + const { toggleFeature } = useDispatch( editPostStore ); return ( toggleFeature( 'welcomeGuide' ) }> diff --git a/packages/edit-post/src/store/actions.js b/packages/edit-post/src/store/actions.js index 95901295d0ca3b..b828ecdc54d6fb 100644 --- a/packages/edit-post/src/store/actions.js +++ b/packages/edit-post/src/store/actions.js @@ -15,7 +15,7 @@ import { speak } from '@wordpress/a11y'; * Internal dependencies */ import { getMetaBoxContainer } from '../utils/meta-boxes'; - +import { store as editPostStore } from '.'; /** * Returns an action object used in signalling that the user opened an editor sidebar. * @@ -27,7 +27,7 @@ export function* openGeneralSidebar( name ) { yield controls.dispatch( 'core/interface', 'enableComplementaryArea', - 'core/edit-post', + editPostStore.name, name ); } @@ -41,7 +41,7 @@ export function* closeGeneralSidebar() { yield controls.dispatch( 'core/interface', 'disableComplementaryArea', - 'core/edit-post' + editPostStore.name ); } @@ -288,7 +288,7 @@ export function* setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) { // // See: https://github.com/WordPress/WordPress/blob/5.1.1/wp-admin/includes/post.php#L2307-L2309 const hasActiveMetaBoxes = yield controls.select( - 'core/edit-post', + editPostStore.name, 'hasMetaBoxes' ); @@ -314,7 +314,7 @@ export function* setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) { wasAutosavingPost = isAutosavingPost; if ( shouldTriggerMetaboxesSave ) { - dispatch( 'core/edit-post' ).requestMetaBoxUpdates(); + dispatch( editPostStore.name ).requestMetaBoxUpdates(); } } ); } @@ -349,7 +349,7 @@ export function* requestMetaBoxUpdates() { document.querySelector( '.metabox-base-form' ) ); const activeMetaBoxLocations = yield controls.select( - 'core/edit-post', + editPostStore.name, 'getActiveMetaBoxLocations' ); const formDataToMerge = [ @@ -382,7 +382,7 @@ export function* requestMetaBoxUpdates() { body: formData, parse: false, } ); - yield controls.dispatch( 'core/edit-post', 'metaBoxUpdatesSuccess' ); + yield controls.dispatch( editPostStore.name, 'metaBoxUpdatesSuccess' ); } /** diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index 61313977e33361..dccde836ecabf6 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { useCallback, useRef } from '@wordpress/element'; +import { useCallback } from '@wordpress/element'; import { useEntityBlockEditor } from '@wordpress/core-data'; import { BlockEditorProvider, @@ -12,7 +12,6 @@ import { WritingFlow, ObserveTyping, BlockList, - __unstableUseBlockSelectionClearer as useBlockSelectionClearer, } from '@wordpress/block-editor'; /** @@ -25,12 +24,12 @@ import { SidebarInspectorFill } from '../sidebar'; export default function BlockEditor( { setIsInserterOpen } ) { const { settings, templateType, page } = useSelect( ( select ) => { - const { getSettings, getTemplateType, getPage } = select( + const { getSettings, getEditedPostType, getPage } = select( 'core/edit-site' ); return { settings: getSettings( setIsInserterOpen ), - templateType: getTemplateType(), + templateType: getEditedPostType(), page: getPage(), }; }, @@ -40,11 +39,8 @@ export default function BlockEditor( { setIsInserterOpen } ) { 'postType', templateType ); - const { setPage } = useDispatch( 'core/edit-site' ); - const ref = useRef(); - - useBlockSelectionClearer( ref ); + const { setPage } = useDispatch( 'core/edit-site' ); return ( -
+
diff --git a/packages/edit-site/src/components/editor/global-styles-provider.js b/packages/edit-site/src/components/editor/global-styles-provider.js index db62624c076775..5d6f33118070fa 100644 --- a/packages/edit-site/src/components/editor/global-styles-provider.js +++ b/packages/edit-site/src/components/editor/global-styles-provider.js @@ -38,8 +38,8 @@ const GlobalStylesContext = createContext( { /* eslint-disable no-unused-vars */ getSetting: ( context, path ) => {}, setSetting: ( context, path, newValue ) => {}, - getStyleProperty: ( context, propertyName, origin ) => {}, - setStyleProperty: ( context, propertyName, newValue ) => {}, + getStyle: ( context, propertyName, origin ) => {}, + setStyle: ( context, propertyName, newValue ) => {}, contexts: {}, /* eslint-enable no-unused-vars */ } ); @@ -164,7 +164,7 @@ export default function GlobalStylesProvider( { children, baseStyles } ) { set( contextSettings, path, newValue ); setContent( JSON.stringify( newContent ) ); }, - getStyleProperty: ( context, propertyName, origin = 'merged' ) => { + getStyle: ( context, propertyName, origin = 'merged' ) => { const styles = 'user' === origin ? userStyles : mergedStyles; const value = get( @@ -173,7 +173,7 @@ export default function GlobalStylesProvider( { children, baseStyles } ) { ); return getValueFromVariable( mergedStyles, context, value ); }, - setStyleProperty: ( context, propertyName, newValue ) => { + setStyle: ( context, propertyName, newValue ) => { const newContent = { ...userStyles }; let contextStyles = newContent?.[ context ]?.styles; if ( ! contextStyles ) { @@ -208,7 +208,6 @@ export default function GlobalStylesProvider( { children, baseStyles } ) { css: getGlobalStyles( contexts, mergedStyles, - STYLE_PROPERTY, 'cssVariables' ), isGlobalStyles: true, @@ -218,7 +217,6 @@ export default function GlobalStylesProvider( { children, baseStyles } ) { css: getGlobalStyles( contexts, mergedStyles, - STYLE_PROPERTY, 'blockStyles' ), isGlobalStyles: true, diff --git a/packages/edit-site/src/components/editor/global-styles-renderer.js b/packages/edit-site/src/components/editor/global-styles-renderer.js index 9fb1fb457d762f..d2f538d9371f10 100644 --- a/packages/edit-site/src/components/editor/global-styles-renderer.js +++ b/packages/edit-site/src/components/editor/global-styles-renderer.js @@ -1,7 +1,12 @@ /** * External dependencies */ -import { get, kebabCase, reduce, startsWith } from 'lodash'; +import { capitalize, get, kebabCase, reduce, startsWith } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __EXPERIMENTAL_STYLE_PROPERTY as STYLE_PROPERTY } from '@wordpress/blocks'; /** * Internal dependencies @@ -96,36 +101,46 @@ function flattenTree( input = {}, prefix, token ) { * * @param {Object} blockSupports What styles the block supports. * @param {Object} blockStyles Block styles. - * @param {Object} metadata Block styles metadata information. * * @return {Array} An array of style declarations. */ -function getBlockStylesDeclarations( - blockSupports, - blockStyles = {}, - metadata -) { +function getBlockStylesDeclarations( blockSupports, blockStyles = {} ) { return reduce( - metadata, - ( declarations, { value }, key ) => { - const cssProperty = key.startsWith( '--' ) ? key : kebabCase( key ); - if ( - blockSupports.includes( key ) && - get( blockStyles, value, false ) - ) { + STYLE_PROPERTY, + ( declarations, { value, properties }, key ) => { + if ( ! blockSupports.includes( key ) ) { + return declarations; + } + + if ( !! properties ) { + properties.forEach( ( prop ) => { + const cssProperty = key.startsWith( '--' ) + ? key + : kebabCase( `${ key }${ capitalize( prop ) }` ); + declarations.push( + `${ cssProperty }: ${ compileStyleValue( + get( blockStyles, [ ...value, prop ] ) + ) }` + ); + } ); + } else if ( get( blockStyles, value, false ) ) { + const cssProperty = key.startsWith( '--' ) + ? key + : kebabCase( key ); declarations.push( `${ cssProperty }: ${ compileStyleValue( get( blockStyles, value ) ) }` ); } + return declarations; }, [] ); } -export default ( blockData, tree, metadata, type = 'all' ) => { +export default ( blockData, tree, type = 'all' ) => { return reduce( blockData, ( styles, { selector }, context ) => { @@ -150,8 +165,7 @@ export default ( blockData, tree, metadata, type = 'all' ) => { if ( type === 'all' || type === 'blockStyles' ) { const blockStyleDeclarations = getBlockStylesDeclarations( blockData[ context ].supports, - tree?.[ context ]?.styles, - metadata + tree?.[ context ]?.styles ); if ( blockStyleDeclarations.length > 0 ) { diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index bcd180fe66735c..964390eee4de5d 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -18,6 +18,7 @@ import { import { EntityProvider } from '@wordpress/core-data'; import { BlockContextProvider, + BlockSelectionClearer, BlockBreadcrumb, __unstableUseEditorStyles as useEditorStyles, __experimentalUseResizeCanvas as useResizeCanvas, @@ -72,23 +73,15 @@ function Editor() { isInserterOpened, __experimentalGetPreviewDeviceType, getSettings, - getTemplateId, - getTemplatePartId, - getTemplateType, + getEditedPostType, + getEditedPostId, getPage, isNavigationOpened, } = select( 'core/edit-site' ); - const _templateId = getTemplateId(); - const _templatePartId = getTemplatePartId(); - const _templateType = getTemplateType(); + const postType = getEditedPostType(); + const postId = getEditedPostId(); // The currently selected entity to display. Typically template or template part. - let _entityId; - if ( _templateType ) { - _entityId = - _templateType === 'wp_template' ? _templateId : _templatePartId; - } - return { isInserterOpen: isInserterOpened(), isFullscreenActive: isFeatureActive( 'fullscreenMode' ), @@ -97,17 +90,16 @@ function Editor() { 'core/interface' ).getActiveComplementaryArea( 'core/edit-site' ), settings: getSettings(), - templateType: _templateType, + templateType: postType, page: getPage(), - template: - _templateType && _entityId - ? select( 'core' ).getEntityRecord( - 'postType', - _templateType, - _entityId - ) - : null, - entityId: _entityId, + template: postId + ? select( 'core' ).getEntityRecord( + 'postType', + postType, + postId + ) + : null, + entityId: postId, isNavigationOpen: isNavigationOpened(), }; }, [] ); @@ -260,7 +252,7 @@ function Editor() { /> } content={ -
@@ -274,7 +266,7 @@ function Editor() { /> ) } -
+ } actions={ <> diff --git a/packages/edit-site/src/components/header/index.js b/packages/edit-site/src/components/header/index.js index 2567a3cfea10f7..487b2ea757af11 100644 --- a/packages/edit-site/src/components/header/index.js +++ b/packages/edit-site/src/components/header/index.js @@ -36,9 +36,8 @@ export default function Header( { openEntitiesSavedStates } ) { const { __experimentalGetPreviewDeviceType, isFeatureActive, - getTemplateId, - getTemplatePartId, - getTemplateType, + getEditedPostType, + getEditedPostId, isInserterOpened, } = select( 'core/edit-site' ); const { getEntityRecord } = select( 'core' ); @@ -46,9 +45,8 @@ export default function Header( { openEntitiesSavedStates } ) { 'core/editor' ); - const postType = getTemplateType(); - const postId = - postType === 'wp_template' ? getTemplateId() : getTemplatePartId(); + const postType = getEditedPostType(); + const postId = getEditedPostId(); const record = getEntityRecord( 'postType', postType, postId ); const _entityTitle = 'wp_template' === postType diff --git a/packages/edit-site/src/components/navigation-sidebar/navigation-panel/templates-navigation.js b/packages/edit-site/src/components/navigation-sidebar/navigation-panel/templates-navigation.js index 55bcbf88439ea0..d20c32286c52a0 100644 --- a/packages/edit-site/src/components/navigation-sidebar/navigation-panel/templates-navigation.js +++ b/packages/edit-site/src/components/navigation-sidebar/navigation-panel/templates-navigation.js @@ -19,34 +19,25 @@ import MainDashboardButton from '../../main-dashboard-button'; import { MENU_ROOT, MENU_TEMPLATE_PARTS, MENU_TEMPLATES } from './constants'; export default function TemplatesNavigation() { - const { templateId, templatePartId, templateType, activeMenu } = useSelect( - ( select ) => { - const { - getTemplateId, - getTemplatePartId, - getTemplateType, - getNavigationPanelActiveMenu, - } = select( 'core/edit-site' ); + const { postId, postType, activeMenu } = useSelect( ( select ) => { + const { + getEditedPostType, + getEditedPostId, + getNavigationPanelActiveMenu, + } = select( 'core/edit-site' ); - return { - templateId: getTemplateId(), - templatePartId: getTemplatePartId(), - templateType: getTemplateType(), - activeMenu: getNavigationPanelActiveMenu(), - }; - }, - [] - ); + return { + postId: getEditedPostId(), + postType: getEditedPostType(), + activeMenu: getNavigationPanelActiveMenu(), + }; + }, [] ); const { setNavigationPanelActiveMenu } = useDispatch( 'core/edit-site' ); return ( diff --git a/packages/edit-site/src/components/sidebar/color-panel.js b/packages/edit-site/src/components/sidebar/color-panel.js index 9960ab1d7b62b2..9cc2067decbbf7 100644 --- a/packages/edit-site/src/components/sidebar/color-panel.js +++ b/packages/edit-site/src/components/sidebar/color-panel.js @@ -21,8 +21,8 @@ export function useHasColorPanel( { supports } ) { export default function ColorPanel( { context: { supports, name }, - getStyleProperty, - setStyleProperty, + getStyle, + setStyle, getSetting, setSetting, } ) { @@ -37,12 +37,11 @@ export default function ColorPanel( { const settings = []; if ( supports.includes( 'color' ) ) { - const color = getStyleProperty( name, 'color' ); - const userColor = getStyleProperty( name, 'color', 'user' ); + const color = getStyle( name, 'color' ); + const userColor = getStyle( name, 'color', 'user' ); settings.push( { colorValue: color, - onColorChange: ( value ) => - setStyleProperty( name, 'color', value ), + onColorChange: ( value ) => setStyle( name, 'color', value ), label: __( 'Text color' ), clearable: color === userColor, } ); @@ -50,16 +49,12 @@ export default function ColorPanel( { let backgroundSettings = {}; if ( supports.includes( 'backgroundColor' ) ) { - const backgroundColor = getStyleProperty( name, 'backgroundColor' ); - const userBackgroundColor = getStyleProperty( - name, - 'backgroundColor', - 'user' - ); + const backgroundColor = getStyle( name, 'backgroundColor' ); + const userBackgroundColor = getStyle( name, 'backgroundColor', 'user' ); backgroundSettings = { colorValue: backgroundColor, onColorChange: ( value ) => - setStyleProperty( name, 'backgroundColor', value ), + setStyle( name, 'backgroundColor', value ), }; if ( backgroundColor ) { backgroundSettings.clearable = @@ -69,12 +64,12 @@ export default function ColorPanel( { let gradientSettings = {}; if ( supports.includes( 'background' ) ) { - const gradient = getStyleProperty( name, 'background' ); - const userGradient = getStyleProperty( name, 'background', 'user' ); + const gradient = getStyle( name, 'background' ); + const userGradient = getStyle( name, 'background', 'user' ); gradientSettings = { gradientValue: gradient, onGradientChange: ( value ) => - setStyleProperty( name, 'background', value ), + setStyle( name, 'background', value ), }; if ( gradient ) { gradientSettings.clearable = gradient === userGradient; @@ -93,12 +88,11 @@ export default function ColorPanel( { } if ( supports.includes( LINK_COLOR ) ) { - const color = getStyleProperty( name, LINK_COLOR ); - const userColor = getStyleProperty( name, LINK_COLOR, 'user' ); + const color = getStyle( name, LINK_COLOR ); + const userColor = getStyle( name, LINK_COLOR, 'user' ); settings.push( { colorValue: color, - onColorChange: ( value ) => - setStyleProperty( name, LINK_COLOR, value ), + onColorChange: ( value ) => setStyle( name, LINK_COLOR, value ), label: __( 'Link color' ), clearable: color === userColor, } ); diff --git a/packages/edit-site/src/components/sidebar/global-styles-sidebar.js b/packages/edit-site/src/components/sidebar/global-styles-sidebar.js index d2308264f2ca90..62592d8c20abbe 100644 --- a/packages/edit-site/src/components/sidebar/global-styles-sidebar.js +++ b/packages/edit-site/src/components/sidebar/global-styles-sidebar.js @@ -25,19 +25,21 @@ import { useHasTypographyPanel, } from './typography-panel'; import { default as ColorPanel, useHasColorPanel } from './color-panel'; +import { default as SpacingPanel, useHasSpacingPanel } from './spacing-panel'; function GlobalStylesPanel( { wrapperPanelTitle, context, - getStyleProperty, - setStyleProperty, + getStyle, + setStyle, getSetting, setSetting, } ) { const hasColorPanel = useHasColorPanel( context ); const hasTypographyPanel = useHasTypographyPanel( context ); + const hasSpacingPanel = useHasSpacingPanel( context ); - if ( ! hasColorPanel && ! hasTypographyPanel ) { + if ( ! hasColorPanel && ! hasTypographyPanel && ! hasSpacingPanel ) { return null; } @@ -46,19 +48,26 @@ function GlobalStylesPanel( { { hasTypographyPanel && ( ) } { hasColorPanel && ( ) } + { hasSpacingPanel && ( + + ) } ); if ( ! wrapperPanelTitle ) { @@ -99,8 +108,8 @@ function getPanelTitle( context ) { function GlobalStylesBlockPanels( { contexts, - getStyleProperty, - setStyleProperty, + getStyle, + setStyle, getSetting, setSetting, } ) { @@ -128,8 +137,8 @@ function GlobalStylesBlockPanels( { key={ 'panel-' + name } wrapperPanelTitle={ wrapperPanelTitle } context={ { ...context, name } } - getStyleProperty={ getStyleProperty } - setStyleProperty={ setStyleProperty } + getStyle={ getStyle } + setStyle={ setStyle } getSetting={ getSetting } setSetting={ setSetting } /> @@ -145,8 +154,8 @@ export default function GlobalStylesSidebar( { } ) { const { contexts, - getStyleProperty, - setStyleProperty, + getStyle, + setStyle, getSetting, setSetting, } = useGlobalStylesContext(); @@ -191,8 +200,8 @@ export default function GlobalStylesSidebar( { return ( @@ -205,8 +214,8 @@ export default function GlobalStylesSidebar( { ...contexts[ GLOBAL_CONTEXT_NAME ], name: GLOBAL_CONTEXT_NAME, } } - getStyleProperty={ getStyleProperty } - setStyleProperty={ setStyleProperty } + getStyle={ getStyle } + setStyle={ setStyle } getSetting={ getSetting } setSetting={ setSetting } /> diff --git a/packages/edit-site/src/components/sidebar/spacing-panel.js b/packages/edit-site/src/components/sidebar/spacing-panel.js new file mode 100644 index 00000000000000..f2609b49c4696f --- /dev/null +++ b/packages/edit-site/src/components/sidebar/spacing-panel.js @@ -0,0 +1,63 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + __experimentalBoxControl as BoxControl, + PanelBody, +} from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { useEditorFeature } from '../editor/utils'; + +export function useHasSpacingPanel( { supports, name } ) { + return ( + useEditorFeature( 'spacing.customPadding', name ) && + supports.includes( 'padding' ) + ); +} + +function filterUnitsWithSettings( settings = [], units = [] ) { + return units.filter( ( unit ) => { + return settings.includes( unit.value ); + } ); +} + +function useCustomUnits( { units, contextName } ) { + const availableUnits = useEditorFeature( 'spacing.units', contextName ); + const usedUnits = filterUnitsWithSettings( + ! availableUnits ? [] : availableUnits, + units + ); + + return usedUnits.length === 0 ? false : usedUnits; +} + +export default function SpacingPanel( { + context: { name }, + getStyle, + setStyle, +} ) { + const units = useCustomUnits( { contextName: name } ); + const paddingValues = getStyle( name, 'padding' ); + const setPaddingValues = ( { top, right, bottom, left } ) => { + setStyle( name, 'padding', { + top: top || paddingValues?.top, + right: right || paddingValues?.right, + bottom: bottom || paddingValues?.bottom, + left: left || paddingValues?.left, + } ); + }; + return ( + + + + ); +} diff --git a/packages/edit-site/src/components/sidebar/typography-panel.js b/packages/edit-site/src/components/sidebar/typography-panel.js index 529115d8b5adf5..558f2bf11414dc 100644 --- a/packages/edit-site/src/components/sidebar/typography-panel.js +++ b/packages/edit-site/src/components/sidebar/typography-panel.js @@ -41,8 +41,8 @@ function useHasAppearenceControl( { supports, name } ) { export default function TypographyPanel( { context: { supports, name }, - getStyleProperty, - setStyleProperty, + getStyle, + setStyle, } ) { const fontSizes = useEditorFeature( 'typography.fontSizes', name ); const disableCustomFontSizes = ! useEditorFeature( @@ -64,17 +64,17 @@ export default function TypographyPanel( { { supports.includes( 'fontFamily' ) && ( - setStyleProperty( name, 'fontFamily', value ) + setStyle( name, 'fontFamily', value ) } /> ) } { supports.includes( 'fontSize' ) && ( - setStyleProperty( name, 'fontSize', value ) + setStyle( name, 'fontSize', value ) } fontSizes={ fontSizes } disableCustomFontSizes={ disableCustomFontSizes } @@ -82,21 +82,21 @@ export default function TypographyPanel( { ) } { hasLineHeightEnabled && ( - setStyleProperty( name, 'lineHeight', value ) + setStyle( name, 'lineHeight', value ) } /> ) } { hasAppearenceControl && ( { - setStyleProperty( name, 'fontStyle', fontStyle ); - setStyleProperty( name, 'fontWeight', fontWeight ); + setStyle( name, 'fontStyle', fontStyle ); + setStyle( name, 'fontWeight', fontWeight ); } } hasFontStyles={ hasFontStyles } hasFontWeights={ hasFontWeights } diff --git a/packages/edit-site/src/components/url-query-controller/index.js b/packages/edit-site/src/components/url-query-controller/index.js index e7685a1f1ab13a..3ff703bf0debd4 100644 --- a/packages/edit-site/src/components/url-query-controller/index.js +++ b/packages/edit-site/src/components/url-query-controller/index.js @@ -47,28 +47,19 @@ export default function URLQueryController() { function useCurrentPageContext() { return useSelect( ( select ) => { - const { - getTemplateId, - getTemplatePartId, - getTemplateType, - getPage, - } = select( 'core/edit-site' ); + const { getEditedPostType, getEditedPostId, getPage } = select( + 'core/edit-site' + ); const page = getPage(); - const templateType = getTemplateType(); - const templateId = getTemplateId(); - const templatePartId = getTemplatePartId(); - - let _postId, _postType; + let _postId = getEditedPostId(), + _postType = getEditedPostType(); + // This doesn't seem right to me, + // we shouldn't be using the "page" and the "template" in the same way. + // This need to be investigated. if ( page?.context?.postId && page?.context?.postType ) { _postId = page.context.postId; _postType = page.context.postType; - } else if ( templateType === 'wp_template' && templateId ) { - _postId = templateId; - _postType = templateType; - } else if ( templateType === 'wp_template_part' && templatePartId ) { - _postId = templatePartId; - _postType = templateType; } if ( _postId && _postType ) { diff --git a/packages/edit-site/src/store/reducer.js b/packages/edit-site/src/store/reducer.js index dcc57c8bc3a9af..0a89862d23ec87 100644 --- a/packages/edit-site/src/store/reducer.js +++ b/packages/edit-site/src/store/reducer.js @@ -69,79 +69,28 @@ export function settings( state = {}, action ) { } /** - * Reducer returning the template ID. + * Reducer keeping track of the currently edited Post Type, + * Post Id and the context provided to fill the content of the block editor. * * @param {Object} state Current state. * @param {Object} action Dispatched action. * * @return {Object} Updated state. */ -export function templateId( state, action ) { +export function editedPost( state = {}, action ) { switch ( action.type ) { case 'SET_TEMPLATE': case 'SET_PAGE': - return action.templateId; - case 'SET_TEMPLATE_PART': - return undefined; - } - - return state; -} - -/** - * Reducer returning the template part ID. - * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. - * - * @return {Object} Updated state. - */ -export function templatePartId( state, action ) { - switch ( action.type ) { - case 'SET_TEMPLATE_PART': - return action.templatePartId; - case 'SET_TEMPLATE': - case 'SET_PAGE': - return undefined; - } - - return state; -} - -/** - * Reducer returning the template type. - * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. - * - * @return {Object} Updated state. - */ -export function templateType( state = 'wp_template', action ) { - switch ( action.type ) { - case 'SET_TEMPLATE': - case 'SET_PAGE': - return 'wp_template'; - case 'SET_TEMPLATE_PART': - return 'wp_template_part'; - } - - return state; -} - -/** - * Reducer returning the page being edited. - * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. - * - * @return {Object} Updated state. - */ -export function page( state, action ) { - switch ( action.type ) { - case 'SET_PAGE': - return action.page; + return { + type: 'wp_template', + id: action.templateId, + page: action.page, + }; case 'SET_TEMPLATE_PART': - return undefined; + return { + type: 'wp_template_part', + id: action.templatePartId, + }; } return state; @@ -231,10 +180,7 @@ export default combineReducers( { preferences, deviceType, settings, - templateId, - templatePartId, - templateType, - page, + editedPost, homeTemplateId, navigationPanel, blockInserterPanel, diff --git a/packages/edit-site/src/store/selectors.js b/packages/edit-site/src/store/selectors.js index 2fc2ba5d43614f..4bcfd07dc2926e 100644 --- a/packages/edit-site/src/store/selectors.js +++ b/packages/edit-site/src/store/selectors.js @@ -96,36 +96,25 @@ export function getHomeTemplateId( state ) { } /** - * Returns the current template ID. + * Returns the current edited post type (wp_template or wp_template_part). * * @param {Object} state Global application state. * * @return {number?} Template ID. */ -export function getTemplateId( state ) { - return state.templateId; +export function getEditedPostType( state ) { + return state.editedPost.type; } /** - * Returns the current template part ID. + * Returns the ID of the currently edited template or template part. * * @param {Object} state Global application state. * - * @return {number?} Template part ID. + * @return {number?} Post ID. */ -export function getTemplatePartId( state ) { - return state.templatePartId; -} - -/** - * Returns the current template type. - * - * @param {Object} state Global application state. - * - * @return {string?} Template type. - */ -export function getTemplateType( state ) { - return state.templateType; +export function getEditedPostId( state ) { + return state.editedPost.id; } /** @@ -136,7 +125,7 @@ export function getTemplateType( state ) { * @return {Object} Page. */ export function getPage( state ) { - return state.page; + return state.editedPost.page; } /** diff --git a/packages/edit-site/src/store/test/reducer.js b/packages/edit-site/src/store/test/reducer.js index ff725b0c2e861d..9f8263786464bd 100644 --- a/packages/edit-site/src/store/test/reducer.js +++ b/packages/edit-site/src/store/test/reducer.js @@ -10,10 +10,7 @@ import { preferences, settings, homeTemplateId, - templateId, - templatePartId, - templateType, - page, + editedPost, navigationPanel, blockInserterPanel, } from '../reducer'; @@ -87,108 +84,51 @@ describe( 'state', () => { } ); } ); - describe( 'templateId()', () => { + describe( 'editedPost()', () => { it( 'should apply default state', () => { - expect( templateId( undefined, {} ) ).toEqual( undefined ); + expect( editedPost( undefined, {} ) ).toEqual( {} ); } ); it( 'should default to returning the same state', () => { const state = {}; - expect( templateId( state, {} ) ).toBe( state ); + expect( editedPost( state, {} ) ).toBe( state ); } ); it( 'should update when a template is set', () => { expect( - templateId( 1, { - type: 'SET_TEMPLATE', - templateId: 2, - } ) - ).toEqual( 2 ); - } ); - - it( 'should update when a page is set', () => { - expect( - templateId( 1, { - type: 'SET_PAGE', - templateId: 2, - } ) - ).toEqual( 2 ); - } ); - } ); - - describe( 'templatePartId()', () => { - it( 'should apply default state', () => { - expect( templatePartId( undefined, {} ) ).toEqual( undefined ); - } ); - - it( 'should default to returning the same state', () => { - const state = {}; - expect( templatePartId( state, {} ) ).toBe( state ); - } ); - - it( 'should update when a template part is set', () => { - expect( - templatePartId( 1, { - type: 'SET_TEMPLATE_PART', - templatePartId: 2, - } ) - ).toEqual( 2 ); - } ); - } ); - - describe( 'templateType()', () => { - it( 'should apply default state', () => { - expect( templateType( undefined, {} ) ).toEqual( 'wp_template' ); - } ); - - it( 'should default to returning the same state', () => { - const state = {}; - expect( templateType( state, {} ) ).toBe( state ); - } ); - - it( 'should update when a template is set', () => { - expect( - templateType( undefined, { - type: 'SET_TEMPLATE', - } ) - ).toEqual( 'wp_template' ); + editedPost( + { id: 1, type: 'wp_template' }, + { + type: 'SET_TEMPLATE', + templateId: 2, + } + ) + ).toEqual( { id: 2, type: 'wp_template' } ); } ); it( 'should update when a page is set', () => { expect( - templateType( undefined, { - type: 'SET_PAGE', - } ) - ).toEqual( 'wp_template' ); + editedPost( + { id: 1, type: 'wp_template' }, + { + type: 'SET_PAGE', + templateId: 2, + page: {}, + } + ) + ).toEqual( { id: 2, type: 'wp_template', page: {} } ); } ); it( 'should update when a template part is set', () => { expect( - templateType( undefined, { - type: 'SET_TEMPLATE_PART', - } ) - ).toEqual( 'wp_template_part' ); - } ); - } ); - - describe( 'page()', () => { - it( 'should apply default state', () => { - expect( page( undefined, {} ) ).toEqual( undefined ); - } ); - - it( 'should default to returning the same state', () => { - const state = {}; - expect( page( state, {} ) ).toBe( state ); - } ); - - it( 'should set the page', () => { - const newPage = {}; - expect( - page( undefined, { - type: 'SET_PAGE', - page: newPage, - } ) - ).toBe( newPage ); + editedPost( + { id: 1, type: 'wp_template' }, + { + type: 'SET_TEMPLATE_PART', + templatePartId: 2, + } + ) + ).toEqual( { id: 2, type: 'wp_template_part' } ); } ); } ); diff --git a/packages/edit-site/src/store/test/selectors.js b/packages/edit-site/src/store/test/selectors.js index 85b4ac71219d86..e24b640f07afb1 100644 --- a/packages/edit-site/src/store/test/selectors.js +++ b/packages/edit-site/src/store/test/selectors.js @@ -6,9 +6,8 @@ import { getCanUserCreateMedia, getSettings, getHomeTemplateId, - getTemplateId, - getTemplatePartId, - getTemplateType, + getEditedPostType, + getEditedPostId, getPage, getNavigationPanelActiveMenu, isNavigationOpened, @@ -119,31 +118,25 @@ describe( 'selectors', () => { } ); } ); - describe( 'getTemplateId', () => { + describe( 'getEditedPostId', () => { it( 'returns the template ID', () => { - const state = { templateId: {} }; - expect( getTemplateId( state ) ).toBe( state.templateId ); + const state = { editedPost: { id: 10 } }; + expect( getEditedPostId( state ) ).toBe( 10 ); } ); } ); - describe( 'getTemplatePartId', () => { - it( 'returns the template part ID', () => { - const state = { templatePartId: {} }; - expect( getTemplatePartId( state ) ).toBe( state.templatePartId ); - } ); - } ); - - describe( 'getTemplateType', () => { + describe( 'getEditedPostType', () => { it( 'returns the template type', () => { - const state = { templateType: {} }; - expect( getTemplateType( state ) ).toBe( state.templateType ); + const state = { editedPost: { type: 'wp_template' } }; + expect( getEditedPostType( state ) ).toBe( 'wp_template' ); } ); } ); describe( 'getPage', () => { it( 'returns the page object', () => { - const state = { page: {} }; - expect( getPage( state ) ).toBe( state.page ); + const page = {}; + const state = { editedPost: { page } }; + expect( getPage( state ) ).toBe( page ); } ); } ); diff --git a/packages/editor/package.json b/packages/editor/package.json index 27ac617fe07615..30137e42835d23 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -59,7 +59,6 @@ "lodash": "^4.17.19", "memize": "^1.1.0", "react-autosize-textarea": "^7.1.0", - "redux-optimist": "^1.0.0", "refx": "^3.0.0", "rememo": "^3.0.0" }, diff --git a/packages/editor/src/components/post-publish-button/index.js b/packages/editor/src/components/post-publish-button/index.js index 46ebe017edbfd7..01d98a50541945 100644 --- a/packages/editor/src/components/post-publish-button/index.js +++ b/packages/editor/src/components/post-publish-button/index.js @@ -94,6 +94,7 @@ export class PostPublishButton extends Component { isPublished, isSaveable, isSaving, + isAutoSaving, isToggle, onSave, onStatusChange, @@ -147,7 +148,7 @@ export class PostPublishButton extends Component { const buttonProps = { 'aria-disabled': isButtonDisabled && ! hasNonPostEntityChanges, className: 'editor-post-publish-button', - isBusy: isSaving && isPublished, + isBusy: ! isAutoSaving && isSaving && isPublished, isPrimary: true, onClick: this.createOnClick( onClickButton ), }; @@ -197,6 +198,7 @@ export default compose( [ withSelect( ( select ) => { const { isSavingPost, + isAutosavingPost, isEditedPostBeingScheduled, getEditedPostVisibility, isCurrentPostPublished, @@ -208,8 +210,10 @@ export default compose( [ getCurrentPostId, hasNonPostEntityChanges, } = select( 'core/editor' ); + const _isAutoSaving = isAutosavingPost(); return { - isSaving: isSavingPost(), + isSaving: isSavingPost() || _isAutoSaving, + isAutoSaving: _isAutoSaving, isBeingScheduled: isEditedPostBeingScheduled(), visibility: getEditedPostVisibility(), isSaveable: isEditedPostSaveable(), diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index 19a4d89d0ee335..6f4b2ed1cd8592 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -15,11 +15,7 @@ import { store as noticesStore } from '@wordpress/notices'; /** * Internal dependencies */ -import { - STORE_NAME, - POST_UPDATE_TRANSACTION_ID, - TRASH_POST_NOTICE_ID, -} from './constants'; +import { STORE_NAME, TRASH_POST_NOTICE_ID } from './constants'; import { getNotificationArgumentsForSaveSuccess, getNotificationArgumentsForSaveFail, @@ -94,7 +90,7 @@ export function* __unstableSetupTemplate( template ) { { blocks, }, - { __unstableShouldCreateUndoLevel: false } + { undoIgnore: true } ); } @@ -178,14 +174,15 @@ export function __experimentalRequestPostUpdateFinish( options = {} ) { * Returns an action object used in signalling that a patch of updates for the * latest version of the post have been received. * - * @param {Object} edits Updated post fields. - * * @return {Object} Action object. + * @deprecated since Gutenberg 9.7.0. */ -export function updatePost( edits ) { +export function updatePost() { + deprecated( "wp.data.dispatch( 'core/editor' ).updatePost", { + alternative: 'User the core entitires store instead', + } ); return { - type: 'UPDATE_POST', - edits, + type: 'DO_NOTHING', }; } @@ -226,21 +223,6 @@ export function* editPost( edits, options ) { ); } -/** - * Returns action object produced by the updatePost creator augmented by - * an optimist option that signals optimistically applying updates. - * - * @param {Object} edits Updated post fields. - * - * @return {Object} Action object. - */ -export function __experimentalOptimisticUpdatePost( edits ) { - return { - ...updatePost( edits ), - optimist: { id: POST_UPDATE_TRANSACTION_ID }, - }; -} - /** * Action generator for saving the current post in the editor. * diff --git a/packages/editor/src/store/constants.js b/packages/editor/src/store/constants.js index 073efe20455410..7882ba53e64db3 100644 --- a/packages/editor/src/store/constants.js +++ b/packages/editor/src/store/constants.js @@ -13,7 +13,6 @@ export const EDIT_MERGE_PROPERTIES = new Set( [ 'meta' ] ); */ export const STORE_NAME = 'core/editor'; -export const POST_UPDATE_TRANSACTION_ID = 'post-update'; export const SAVE_POST_NOTICE_ID = 'SAVE_POST_NOTICE_ID'; export const TRASH_POST_NOTICE_ID = 'TRASH_POST_NOTICE_ID'; export const PERMALINK_POSTNAME_REGEX = /%(?:postname|pagename)%/; diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js index 071b2492945aa3..07b2a74376a252 100644 --- a/packages/editor/src/store/reducer.js +++ b/packages/editor/src/store/reducer.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import optimist from 'redux-optimist'; import { omit, keys, isEqual } from 'lodash'; /** @@ -86,7 +85,6 @@ export function postId( state = null, action ) { switch ( action.type ) { case 'SETUP_EDITOR_STATE': case 'RESET_POST': - case 'UPDATE_POST': return action.post.id; } @@ -97,7 +95,6 @@ export function postType( state = null, action ) { switch ( action.type ) { case 'SETUP_EDITOR_STATE': case 'RESET_POST': - case 'UPDATE_POST': return action.post.type; } @@ -284,17 +281,15 @@ export function editorSettings( state = EDITOR_SETTINGS_DEFAULTS, action ) { return state; } -export default optimist( - combineReducers( { - postId, - postType, - preferences, - saving, - postLock, - template, - postSavingLock, - isReady, - editorSettings, - postAutosavingLock, - } ) -); +export default combineReducers( { + postId, + postType, + preferences, + saving, + postLock, + template, + postSavingLock, + isReady, + editorSettings, + postAutosavingLock, +} ); diff --git a/packages/editor/src/store/reducer.native.js b/packages/editor/src/store/reducer.native.js index 3036cb5704a480..d9b3fbcd67888a 100644 --- a/packages/editor/src/store/reducer.native.js +++ b/packages/editor/src/store/reducer.native.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import optimist from 'redux-optimist'; - /** * WordPress dependencies */ @@ -85,19 +80,17 @@ export function notices( state = [], action ) { return state; } -export default optimist( - combineReducers( { - postId, - postType, - postTitle, - preferences, - saving, - postLock, - postSavingLock, - template, - isReady, - editorSettings, - clipboard, - notices, - } ) -); +export default combineReducers( { + postId, + postType, + postTitle, + preferences, + saving, + postLock, + postSavingLock, + template, + isReady, + editorSettings, + clipboard, + notices, +} ); diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index 5849de6a6521fa..9c5a92d25da234 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -33,7 +33,6 @@ import { Platform } from '@wordpress/element'; import { PREFERENCES_DEFAULTS } from './defaults'; import { EDIT_MERGE_PROPERTIES, - POST_UPDATE_TRANSACTION_ID, PERMALINK_POSTNAME_REGEX, ONE_MINUTE_IN_MS, AUTOSAVE_PROPERTIES, @@ -1001,26 +1000,6 @@ export const getEditedPostContent = createRegistrySelector( } ); -/** - * Returns state object prior to a specified optimist transaction ID, or `null` - * if the transaction corresponding to the given ID cannot be found. - * - * @param {Object} state Current global application state. - * @param {Object} transactionId Optimist transaction ID. - * - * @return {Object} Global application state prior to transaction. - */ -export function getStateBeforeOptimisticTransaction( state, transactionId ) { - const transaction = find( - state.optimist, - ( entry ) => - entry.beforeState && - get( entry.action, [ 'optimist', 'id' ] ) === transactionId - ); - - return transaction ? transaction.beforeState : null; -} - /** * Returns true if the post is being published, or false otherwise. * @@ -1029,28 +1008,10 @@ export function getStateBeforeOptimisticTransaction( state, transactionId ) { * @return {boolean} Whether post is being published. */ export function isPublishingPost( state ) { - if ( ! isSavingPost( state ) ) { - return false; - } - - // Saving is optimistic, so assume that current post would be marked as - // published if publishing - if ( ! isCurrentPostPublished( state ) ) { - return false; - } - - // Use post update transaction ID to retrieve the state prior to the - // optimistic transaction - const stateBeforeRequest = getStateBeforeOptimisticTransaction( - state, - POST_UPDATE_TRANSACTION_ID - ); - - // Consider as publishing when current post prior to request was not - // considered published return ( - !! stateBeforeRequest && - ! isCurrentPostPublished( null, stateBeforeRequest.currentPost ) + isSavingPost( state ) && + ! isCurrentPostPublished( state ) && + getEditedPostAttribute( state, 'status' ) === 'publish' ); } @@ -1142,28 +1103,6 @@ export function getPermalinkParts( state ) { }; } -/** - * Returns true if an optimistic transaction is pending commit, for which the - * before state satisfies the given predicate function. - * - * @param {Object} state Editor state. - * @param {Function} predicate Function given state, returning true if match. - * - * @return {boolean} Whether predicate matches for some history. - */ -export function inSomeHistory( state, predicate ) { - const { optimist } = state; - - // In recursion, optimist state won't exist. Assume exhausted options. - if ( ! optimist ) { - return false; - } - - return optimist.some( - ( { beforeState } ) => beforeState && predicate( beforeState ) - ); -} - /** * Returns whether the post is locked. * @@ -1269,20 +1208,6 @@ export function getEditorBlocks( state ) { return getEditedPostAttribute( state, 'blocks' ) || EMPTY_ARRAY; } -/** - * Checks whether a post is an auto-draft ignoring the optimistic transaction. - * This selector shouldn't be necessary. It's currently used as a workaround - * to avoid template resolution for auto-drafts which has a backend bug. - * - * @param {Object} state State. - * @return {boolean} Whether the post is "auto-draft" on the backend. - */ -export function __unstableIsAutodraftPost( state ) { - const post = getCurrentPost( state ); - const isSaving = isSavingPost( state ); - return isSaving || post.status === 'auto-draft'; -} - /** * A block selection object. * @@ -1339,6 +1264,32 @@ export function getEditorSettings( state ) { * Backward compatibility */ +/** + * Returns state object prior to a specified optimist transaction ID, or `null` + * if the transaction corresponding to the given ID cannot be found. + * + * @deprecated since Gutenberg 9.7.0. + */ +export function getStateBeforeOptimisticTransaction() { + deprecated( "select('core/editor').getStateBeforeOptimisticTransaction", { + hint: 'No state history is kept on this store anymore', + } ); + + return null; +} +/** + * Returns true if an optimistic transaction is pending commit, for which the + * before state satisfies the given predicate function. + * + * @deprecated since Gutenberg 9.7.0. + */ +export function inSomeHistory() { + deprecated( "select('core/editor').inSomeHistory", { + hint: 'No state history is kept on this store anymore', + } ); + return false; +} + function getBlockEditorSelector( name ) { return createRegistrySelector( ( select ) => ( state, ...args ) => { deprecated( "`wp.data.select( 'core/editor' )." + name + '`', { diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js index 82d94c7dd94ff7..822d653676869c 100644 --- a/packages/editor/src/store/test/actions.js +++ b/packages/editor/src/store/test/actions.js @@ -9,11 +9,7 @@ import { store as noticesStore } from '@wordpress/notices'; * Internal dependencies */ import * as actions from '../actions'; -import { - STORE_NAME, - TRASH_POST_NOTICE_ID, - POST_UPDATE_TRANSACTION_ID, -} from '../constants'; +import { STORE_NAME, TRASH_POST_NOTICE_ID } from '../constants'; const postType = { rest_base: 'posts', @@ -459,17 +455,6 @@ describe( 'Editor actions', () => { } ); } ); - describe( 'updatePost', () => { - it( 'should return the UPDATE_POST action', () => { - const edits = {}; - const result = actions.updatePost( edits ); - expect( result ).toEqual( { - type: 'UPDATE_POST', - edits, - } ); - } ); - } ); - describe( 'editPost', () => { it( 'should edit the relevant entity record', () => { const edits = { format: 'sample' }; @@ -498,18 +483,6 @@ describe( 'Editor actions', () => { } ); } ); - describe( 'optimisticUpdatePost', () => { - it( 'should return the UPDATE_POST action with optimist property', () => { - const edits = {}; - const result = actions.__experimentalOptimisticUpdatePost( edits ); - expect( result ).toEqual( { - type: 'UPDATE_POST', - edits, - optimist: { id: POST_UPDATE_TRANSACTION_ID }, - } ); - } ); - } ); - describe( 'redo', () => { it( 'should yield the REDO action', () => { const fulfillment = actions.redo(); diff --git a/packages/editor/src/store/test/selectors.js b/packages/editor/src/store/test/selectors.js index fd4a84ecbdbdc6..e886d019a81f90 100644 --- a/packages/editor/src/store/test/selectors.js +++ b/packages/editor/src/store/test/selectors.js @@ -22,7 +22,6 @@ import { RawHTML } from '@wordpress/element'; */ import * as _selectors from '../selectors'; import { PREFERENCES_DEFAULTS } from '../defaults'; -import { POST_UPDATE_TRANSACTION_ID } from '../constants'; const selectors = { ..._selectors }; const selectorNames = Object.keys( selectors ); @@ -161,8 +160,6 @@ const { didPostSaveRequestFail, getSuggestedPostFormat, getEditedPostContent, - getStateBeforeOptimisticTransaction, - isPublishingPost, isPublishSidebarEnabled, isPermalinkEditable, getPermalink, @@ -415,7 +412,6 @@ describe( 'selectors', () => { describe( 'isEditedPostDirty', () => { it( 'should return false when blocks state not dirty nor edits exist', () => { const state = { - optimist: [], editor: { present: { blocks: { @@ -432,7 +428,6 @@ describe( 'selectors', () => { it( 'should return true when blocks state dirty', () => { const state = { - optimist: [], editor: { present: { blocks: { @@ -449,7 +444,6 @@ describe( 'selectors', () => { it( 'should return true when edits exist', () => { const state = { - optimist: [], editor: { present: { blocks: { @@ -2503,163 +2497,6 @@ describe( 'selectors', () => { } ); } ); - describe( 'getStateBeforeOptimisticTransaction', () => { - it( 'should return null if no transaction can be found', () => { - const beforeState = getStateBeforeOptimisticTransaction( - { - optimist: [], - }, - 'foo' - ); - - expect( beforeState ).toBe( null ); - } ); - - it( 'should return null if a transaction with ID can be found, but lacks before state', () => { - const beforeState = getStateBeforeOptimisticTransaction( - { - optimist: [ - { - action: { - optimist: { - id: 'foo', - }, - }, - }, - ], - }, - 'foo' - ); - - expect( beforeState ).toBe( null ); - } ); - - it( 'should return the before state matching the given transaction id', () => { - const expectedBeforeState = {}; - const beforeState = getStateBeforeOptimisticTransaction( - { - optimist: [ - { - beforeState: expectedBeforeState, - action: { - optimist: { - id: 'foo', - }, - }, - }, - ], - }, - 'foo' - ); - - expect( beforeState ).toBe( expectedBeforeState ); - } ); - } ); - - describe( 'isPublishingPost', () => { - it( 'should return false if the post is not being saved', () => { - const isPublishing = isPublishingPost( { - optimist: [], - saving: { - requesting: false, - }, - currentPost: { - status: 'publish', - }, - } ); - - expect( isPublishing ).toBe( false ); - } ); - - it( 'should return false if the current post is not considered published', () => { - const isPublishing = isPublishingPost( { - optimist: [], - saving: { - requesting: true, - }, - currentPost: { - status: 'draft', - }, - } ); - - expect( isPublishing ).toBe( false ); - } ); - - it( 'should return false if the optimistic transaction cannot be found', () => { - const isPublishing = isPublishingPost( { - optimist: [], - saving: { - requesting: true, - }, - currentPost: { - status: 'publish', - }, - } ); - - expect( isPublishing ).toBe( false ); - } ); - - it( 'should return false if the current post prior to request was already published', () => { - const isPublishing = isPublishingPost( { - optimist: [ - { - beforeState: { - saving: { - requesting: false, - }, - currentPost: { - status: 'publish', - }, - }, - action: { - optimist: { - id: POST_UPDATE_TRANSACTION_ID, - }, - }, - }, - ], - saving: { - requesting: true, - }, - currentPost: { - status: 'publish', - }, - } ); - - expect( isPublishing ).toBe( false ); - } ); - - it( 'should return true if the current post prior to request was not published', () => { - const isPublishing = isPublishingPost( { - optimist: [ - { - beforeState: { - saving: { - requesting: false, - }, - currentPost: { - status: 'draft', - }, - }, - action: { - optimist: { - id: POST_UPDATE_TRANSACTION_ID, - }, - }, - }, - ], - saving: { - requesting: true, - }, - currentPost: { - status: 'publish', - }, - } ); - - expect( isPublishing ).toBe( true ); - } ); - } ); - describe( 'isPermalinkEditable', () => { it( 'should be false if there is no permalink', () => { const state = { diff --git a/packages/format-library/src/link/modal-screens/link-settings-screen.native.js b/packages/format-library/src/link/modal-screens/link-settings-screen.native.js index b69d347e065c1f..b4bba800d69fee 100644 --- a/packages/format-library/src/link/modal-screens/link-settings-screen.native.js +++ b/packages/format-library/src/link/modal-screens/link-settings-screen.native.js @@ -137,6 +137,8 @@ const LinkSettingsScreen = ( { }, [ navigation, route.params?.text, text ] ); return useMemo( () => { + const shouldShowLinkOptions = !! inputValue; + return ( <> - - + { shouldShowLinkOptions && ( + <> + + + + ) } ); }, [ inputValue, text, opensInNewWindow, listProps.safeAreaBottomInset ] ); diff --git a/packages/format-library/src/text-color/index.js b/packages/format-library/src/text-color/index.js index c923c73939dad5..b3083b35b79965 100644 --- a/packages/format-library/src/text-color/index.js +++ b/packages/format-library/src/text-color/index.js @@ -87,7 +87,10 @@ function TextColorEdit( { onClose={ disableIsAddingColor } activeAttributes={ activeAttributes } value={ value } - onChange={ onChange } + onChange={ ( ...args ) => { + onChange( ...args ); + disableIsAddingColor(); + } } contentRef={ contentRef } /> ) } diff --git a/packages/keycodes/CHANGELOG.md b/packages/keycodes/CHANGELOG.md index 11185984d7c207..34a5ee6b0c7bd7 100644 --- a/packages/keycodes/CHANGELOG.md +++ b/packages/keycodes/CHANGELOG.md @@ -2,11 +2,15 @@ ## Unreleased +### Enhancement + +- Include TypeScript type declarations ([#19520](https://github.com/WordPress/gutenberg/pull/19520)) + ## 2.12.0 (2020-04-30) ### Bug Fixes -- `isKeyboardEvent` now tests expected modifiers as an exclusive set, fixing an issue where additional modifiers would wrongly report as satisfying a test for a subset of those modifiers [#20733](https://github.com/WordPress/gutenberg/pull/20733). +- `isKeyboardEvent` now tests expected modifiers as an exclusive set, fixing an issue where additional modifiers would wrongly report as satisfying a test for a subset of those modifiers [#20733](https://github.com/WordPress/gutenberg/pull/20733). ## 2.0.5 (2018-11-21) @@ -18,4 +22,4 @@ ### Breaking Change -- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. +- Change how required built-ins are polyfilled with Babel 7 ([#9171](https://github.com/WordPress/gutenberg/pull/9171)). If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. diff --git a/packages/keycodes/README.md b/packages/keycodes/README.md index bb7036ba95de74..eb82e9e64abe1e 100644 --- a/packages/keycodes/README.md +++ b/packages/keycodes/README.md @@ -61,20 +61,34 @@ Keycode for DELETE key. # **displayShortcut** An object that contains functions to display shortcuts. -E.g. displayShortcut.primary( 'm' ) will return '⌘M' on Mac. + +_Usage_ + +```js +// Assuming macOS: +displayShortcut.primary( 'm' ); +// "⌘M" +``` _Type_ -- `WPKeycodeHandlerByModifier` Keyed map of functions to display shortcuts. +- `WPModifierHandler>` Keyed map of functions to display shortcuts. # **displayShortcutList** -Return an array of the parts of a keyboard shortcut chord for display -E.g displayShortcutList.primary( 'm' ) will return [ '⌘', 'M' ] on Mac. +Return an array of the parts of a keyboard shortcut chord for display. + +_Usage_ + +```js +// Assuming macOS: +displayShortcutList.primary( 'm' ); +// [ "⌘", "M" ] +``` _Type_ -- `WPKeycodeHandlerByModifier` Keyed map of functions to shortcut sequences. +- `WPModifierHandler>>` Keyed map of functions to shortcut sequences. # **DOWN** @@ -96,12 +110,18 @@ Keycode for F10 key. An object that contains functions to check if a keyboard event matches a predefined shortcut combination. -E.g. isKeyboardEvent.primary( event, 'm' ) will return true if the event -signals pressing ⌘M. + +_Usage_ + +```js +// Assuming an event for ⌘M key press: +isKeyboardEvent.primary( event, 'm' ); +// true +``` _Type_ -- `WPKeycodeHandlerByModifier` Keyed map of functions to match events. +- `WPModifierHandler` Keyed map of functions to match events. # **LEFT** @@ -112,26 +132,27 @@ Keycode for LEFT key. Object that contains functions that return the available modifier depending on platform. -- `primary`: takes a isApple function as a parameter. -- `primaryShift`: takes a isApple function as a parameter. -- `primaryAlt`: takes a isApple function as a parameter. -- `secondary`: takes a isApple function as a parameter. -- `access`: takes a isApple function as a parameter. -- `ctrl` -- `alt` -- `ctrlShift` -- `shift` -- `shiftAlt` +_Type_ + +- (unknown type) # **rawShortcut** An object that contains functions to get raw shortcuts. -E.g. rawShortcut.primary( 'm' ) will return 'meta+m' on Mac. -These are intended for user with the KeyboardShortcuts component or TinyMCE. + +These are intended for user with the KeyboardShortcuts. + +_Usage_ + +```js +// Assuming macOS: +rawShortcut.primary( 'm' ) +// "meta+m"" +``` _Type_ -- `WPKeycodeHandlerByModifier` Keyed map of functions to raw shortcuts. +- `WPModifierHandler>` Keyed map of functions to raw shortcuts. # **RIGHT** @@ -143,12 +164,20 @@ Keycode for SHIFT key. # **shortcutAriaLabel** -An object that contains functions to return an aria label for a keyboard shortcut. -E.g. shortcutAriaLabel.primary( '.' ) will return 'Command + Period' on Mac. +An object that contains functions to return an aria label for a keyboard +shortcut. + +_Usage_ + +```js +// Assuming macOS: +shortcutAriaLabel.primary( '.' ); +// "Command + Period" +``` _Type_ -- `WPKeycodeHandlerByModifier` Keyed map of functions to shortcut ARIA labels. +- `WPModifierHandler>` Keyed map of functions to shortcut ARIA labels. # **SPACE** diff --git a/packages/keycodes/package.json b/packages/keycodes/package.json index f6a899955be713..7c661189900960 100644 --- a/packages/keycodes/package.json +++ b/packages/keycodes/package.json @@ -21,6 +21,7 @@ "main": "build/index.js", "module": "build-module/index.js", "react-native": "src/index", + "types": "build-types", "sideEffects": false, "dependencies": { "@babel/runtime": "^7.12.5", diff --git a/packages/keycodes/src/index.js b/packages/keycodes/src/index.js index 0466a6c65cb756..460a09057cc7f8 100644 --- a/packages/keycodes/src/index.js +++ b/packages/keycodes/src/index.js @@ -24,77 +24,103 @@ import { __ } from '@wordpress/i18n'; */ import { isAppleOS } from './platform'; -/** - * @typedef {'primary'|'primaryShift'|'primaryAlt'|'secondary'|'access'|'ctrl'|'alt'|'ctrlShift'|'shift'|'shiftAlt'} WPKeycodeModifier - */ +/** @typedef {typeof ALT | CTRL | COMMAND | SHIFT } WPModifierPart */ + +/** @typedef {'primary' | 'primaryShift' | 'primaryAlt' | 'secondary' | 'access' | 'ctrl' | 'alt' | 'ctrlShift' | 'shift' | 'shiftAlt'} WPKeycodeModifier */ /** * An object of handler functions for each of the possible modifier * combinations. A handler will return a value for a given key. * - * @typedef {Recordany>} WPKeycodeHandlerByModifier + * @template T + * + * @typedef {Record} WPModifierHandler + */ + +/* eslint-disable jsdoc/valid-types */ +/** + * @template T + * + * @typedef {(character: string, isApple?: () => boolean) => T} WPKeyHandler */ +/** @typedef {(event: KeyboardEvent, character: string, isApple?: () => boolean) => boolean} WPEventKeyHandler */ +/* eslint-enable jsdoc/valid-types */ /** * Keycode for BACKSPACE key. */ export const BACKSPACE = 8; + /** * Keycode for TAB key. */ export const TAB = 9; + /** * Keycode for ENTER key. */ export const ENTER = 13; + /** * Keycode for ESCAPE key. */ export const ESCAPE = 27; + /** * Keycode for SPACE key. */ export const SPACE = 32; + /** * Keycode for LEFT key. */ export const LEFT = 37; + /** * Keycode for UP key. */ export const UP = 38; + /** * Keycode for RIGHT key. */ export const RIGHT = 39; + /** * Keycode for DOWN key. */ export const DOWN = 40; + /** * Keycode for DELETE key. */ export const DELETE = 46; + /** * Keycode for F10 key. */ export const F10 = 121; + /** * Keycode for ALT key. */ export const ALT = 'alt'; + /** * Keycode for CTRL key. */ export const CTRL = 'ctrl'; + /** * Keycode for COMMAND/META key. */ export const COMMAND = 'meta'; + /** * Keycode for SHIFT key. */ export const SHIFT = 'shift'; + /** * Keycode for ZERO key. */ @@ -104,16 +130,7 @@ export const ZERO = 48; * Object that contains functions that return the available modifier * depending on platform. * - * - `primary`: takes a isApple function as a parameter. - * - `primaryShift`: takes a isApple function as a parameter. - * - `primaryAlt`: takes a isApple function as a parameter. - * - `secondary`: takes a isApple function as a parameter. - * - `access`: takes a isApple function as a parameter. - * - `ctrl` - * - `alt` - * - `ctrlShift` - * - `shift` - * - `shiftAlt` + * @type {WPModifierHandler< ( isApple: () => boolean ) => WPModifierPart[]>} */ export const modifiers = { primary: ( _isApple ) => ( _isApple() ? [ COMMAND ] : [ CTRL ] ), @@ -133,26 +150,46 @@ export const modifiers = { /** * An object that contains functions to get raw shortcuts. - * E.g. rawShortcut.primary( 'm' ) will return 'meta+m' on Mac. - * These are intended for user with the KeyboardShortcuts component or TinyMCE. * - * @type {WPKeycodeHandlerByModifier} Keyed map of functions to raw shortcuts. + * These are intended for user with the KeyboardShortcuts. + * + * @example + * ```js + * // Assuming macOS: + * rawShortcut.primary( 'm' ) + * // "meta+m"" + * ``` + * + * @type {WPModifierHandler>} Keyed map of functions to raw + * shortcuts. */ export const rawShortcut = mapValues( modifiers, ( modifier ) => { - return ( character, _isApple = isAppleOS ) => { + return /** @type {WPKeyHandler} */ ( + character, + _isApple = isAppleOS + ) => { return [ ...modifier( _isApple ), character.toLowerCase() ].join( '+' ); }; } ); /** - * Return an array of the parts of a keyboard shortcut chord for display - * E.g displayShortcutList.primary( 'm' ) will return [ '⌘', 'M' ] on Mac. + * Return an array of the parts of a keyboard shortcut chord for display. + * + * @example + * ```js + * // Assuming macOS: + * displayShortcutList.primary( 'm' ); + * // [ "⌘", "M" ] + * ``` * - * @type {WPKeycodeHandlerByModifier} Keyed map of functions to shortcut - * sequences. + * @type {WPModifierHandler>} Keyed map of functions to + * shortcut sequences. */ export const displayShortcutList = mapValues( modifiers, ( modifier ) => { - return ( character, _isApple = isAppleOS ) => { + return /** @type {WPKeyHandler} */ ( + character, + _isApple = isAppleOS + ) => { const isApple = _isApple(); const replacementKeyMap = { [ ALT ]: isApple ? '⌥' : 'Alt', @@ -171,7 +208,7 @@ export const displayShortcutList = mapValues( modifiers, ( modifier ) => { return [ ...accumulator, replacementKey, '+' ]; }, - [] + /** @type {string[]} */ ( [] ) ); const capitalizedCharacter = capitalize( character ); @@ -181,28 +218,46 @@ export const displayShortcutList = mapValues( modifiers, ( modifier ) => { /** * An object that contains functions to display shortcuts. - * E.g. displayShortcut.primary( 'm' ) will return '⌘M' on Mac. * - * @type {WPKeycodeHandlerByModifier} Keyed map of functions to display - * shortcuts. + * @example + * ```js + * // Assuming macOS: + * displayShortcut.primary( 'm' ); + * // "⌘M" + * ``` + * + * @type {WPModifierHandler>} Keyed map of functions to + * display shortcuts. */ export const displayShortcut = mapValues( displayShortcutList, ( shortcutList ) => { - return ( character, _isApple = isAppleOS ) => - shortcutList( character, _isApple ).join( '' ); + return /** @type {WPKeyHandler} */ ( + character, + _isApple = isAppleOS + ) => shortcutList( character, _isApple ).join( '' ); } ); /** - * An object that contains functions to return an aria label for a keyboard shortcut. - * E.g. shortcutAriaLabel.primary( '.' ) will return 'Command + Period' on Mac. + * An object that contains functions to return an aria label for a keyboard + * shortcut. + * + * @example + * ```js + * // Assuming macOS: + * shortcutAriaLabel.primary( '.' ); + * // "Command + Period" + * ``` * - * @type {WPKeycodeHandlerByModifier} Keyed map of functions to shortcut ARIA - * labels. + * @type {WPModifierHandler>} Keyed map of functions to + * shortcut ARIA labels. */ export const shortcutAriaLabel = mapValues( modifiers, ( modifier ) => { - return ( character, _isApple = isAppleOS ) => { + return /** @type {WPKeyHandler} */ ( + character, + _isApple = isAppleOS + ) => { const isApple = _isApple(); const replacementKeyMap = { [ SHIFT ]: 'Shift', @@ -229,24 +284,42 @@ export const shortcutAriaLabel = mapValues( modifiers, ( modifier ) => { * * @param {KeyboardEvent} event Keyboard event. * - * @return {Array} Active modifier constants. + * @return {Array} Active modifier constants. */ function getEventModifiers( event ) { - return [ ALT, CTRL, COMMAND, SHIFT ].filter( - ( key ) => event[ `${ key }Key` ] + return /** @type {WPModifierPart[]} */ ( [ + ALT, + CTRL, + COMMAND, + SHIFT, + ] ).filter( + ( key ) => + event[ + /** @type {'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'} */ ( `${ key }Key` ) + ] ); } /** * An object that contains functions to check if a keyboard event matches a * predefined shortcut combination. - * E.g. isKeyboardEvent.primary( event, 'm' ) will return true if the event - * signals pressing ⌘M. * - * @type {WPKeycodeHandlerByModifier} Keyed map of functions to match events. + * @example + * ```js + * // Assuming an event for ⌘M key press: + * isKeyboardEvent.primary( event, 'm' ); + * // true + * ``` + * + * @type {WPModifierHandler} Keyed map of functions + * to match events. */ export const isKeyboardEvent = mapValues( modifiers, ( getModifiers ) => { - return ( event, character, _isApple = isAppleOS ) => { + return /** @type {WPEventKeyHandler} */ ( + event, + character, + _isApple = isAppleOS + ) => { const mods = getModifiers( _isApple ); const eventMods = getEventModifiers( event ); diff --git a/packages/keycodes/src/platform.js b/packages/keycodes/src/platform.js index 19295d47b1f4f8..ae28d611cf425d 100644 --- a/packages/keycodes/src/platform.js +++ b/packages/keycodes/src/platform.js @@ -6,9 +6,9 @@ import { includes } from 'lodash'; /** * Return true if platform is MacOS. * - * @param {Object} _window window object by default; used for DI testing. + * @param {Window} _window window object by default; used for DI testing. * - * @return {boolean} True if MacOS; false otherwise. + * @return {boolean} True if MacOS; false otherwise. */ export function isAppleOS( _window = window ) { const { platform } = _window.navigator; diff --git a/packages/keycodes/src/platform.native.js b/packages/keycodes/src/platform.native.js index bd609d5c16a361..5758d42336ba84 100644 --- a/packages/keycodes/src/platform.native.js +++ b/packages/keycodes/src/platform.native.js @@ -6,7 +6,7 @@ import { Platform } from 'react-native'; /** * Return true if platform is iOS. * - * @return {boolean} True if iOS; false otherwise. + * @return {boolean} True if iOS; false otherwise. */ export function isAppleOS() { return Platform.OS === 'ios'; diff --git a/packages/keycodes/tsconfig.json b/packages/keycodes/tsconfig.json new file mode 100644 index 00000000000000..2a1bbd4d1a0d0a --- /dev/null +++ b/packages/keycodes/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "declarationDir": "build-types" + }, + "references": [ { "path": "../i18n" } ], + "include": [ "src/**/*" ] +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java index f912598e0f498b..6c94893d143df9 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java @@ -166,7 +166,9 @@ void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback void gutenbergDidSendButtonPressedAction(String buttonType); - void onAddMention(Consumer onSuccess); + void onShowUserSuggestions(Consumer onResult); + + void onShowXpostSuggestions(Consumer onResult); void setStarterPageTemplatesTooltipShown(boolean tooltipShown); diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java index 4a6b844b2f5c10..d00dc5a566a74a 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java @@ -323,8 +323,13 @@ private OtherMediaOptionsReceivedCallback getNewOtherMediaReceivedCallback(final } @ReactMethod - public void addMention(Promise promise) { - mGutenbergBridgeJS2Parent.onAddMention(promise::resolve); + public void showUserSuggestions(Promise promise) { + mGutenbergBridgeJS2Parent.onShowUserSuggestions(promise::resolve); + } + + @ReactMethod + public void showXpostSuggestions(Promise promise) { + mGutenbergBridgeJS2Parent.onShowXpostSuggestions(promise::resolve); } @ReactMethod diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/AddMentionUtil.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/AddMentionUtil.java deleted file mode 100644 index 837f10e1562835..00000000000000 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/AddMentionUtil.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.wordpress.mobile.WPAndroidGlue; - -import androidx.core.util.Consumer; - -public interface AddMentionUtil { - void getMention(Consumer onResult); -} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt index f9f65dd9c20838..7049bc099c8221 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/GutenbergProps.kt @@ -5,6 +5,7 @@ import android.os.Bundle data class GutenbergProps @JvmOverloads constructor( val enableMediaFilesCollectionBlocks: Boolean, val enableMentions: Boolean, + val enableXPosts: Boolean, val enableUnsupportedBlockEditor: Boolean, val canEnableUnsupportedBlockEditor: Boolean, val localeSlug: String, @@ -38,6 +39,7 @@ data class GutenbergProps @JvmOverloads constructor( fun getUpdatedCapabilitiesProps() = Bundle().apply { putBoolean(PROP_CAPABILITIES_MENTIONS, enableMentions) + putBoolean(PROP_CAPABILITIES_XPOSTS, enableXPosts) putBoolean(PROP_CAPABILITIES_MEDIAFILES_COLLECTION_BLOCK, enableMediaFilesCollectionBlocks) putBoolean(PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR, enableUnsupportedBlockEditor) putBoolean(PROP_CAPABILITIES_CAN_ENABLE_UNSUPPORTED_BLOCK_EDITOR, canEnableUnsupportedBlockEditor) @@ -68,6 +70,7 @@ data class GutenbergProps @JvmOverloads constructor( const val PROP_CAPABILITIES = "capabilities" const val PROP_CAPABILITIES_MEDIAFILES_COLLECTION_BLOCK = "mediaFilesCollectionBlock" const val PROP_CAPABILITIES_MENTIONS = "mentions" + const val PROP_CAPABILITIES_XPOSTS = "xposts" const val PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR = "unsupportedBlockEditor" const val PROP_CAPABILITIES_CAN_ENABLE_UNSUPPORTED_BLOCK_EDITOR = "canEnableUnsupportedBlockEditor" const val PROP_CAPABILITIES_MODAL_LAYOUT_PICKER = "modalLayoutPicker" diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/ShowSuggestionsUtil.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/ShowSuggestionsUtil.java new file mode 100644 index 00000000000000..cd78ded5b6b242 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/ShowSuggestionsUtil.java @@ -0,0 +1,8 @@ +package org.wordpress.mobile.WPAndroidGlue; + +import androidx.core.util.Consumer; + +public interface ShowSuggestionsUtil { + void showUserSuggestions(Consumer onResult); + void showXpostSuggestions(Consumer onResult); +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java index 9c1de6ab757722..6feeb61581b287 100644 --- a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java @@ -109,7 +109,7 @@ public class WPAndroidGlueCode { private CountDownLatch mGetContentCountDownLatch; private WeakReference mLastFocusedView = null; private RequestExecutor mRequestExecutor; - private AddMentionUtil mAddMentionUtil; + private ShowSuggestionsUtil mShowSuggestionsUtil; private @Nullable Bundle mEditorTheme = null; private static OkHttpHeaderInterceptor sAddCookiesInterceptor = new OkHttpHeaderInterceptor(); @@ -411,8 +411,12 @@ public void gutenbergDidSendButtonPressedAction(String buttonType) { } @Override - public void onAddMention(Consumer onSuccess) { - mAddMentionUtil.getMention(onSuccess); + public void onShowUserSuggestions(Consumer onResult) { + mShowSuggestionsUtil.showUserSuggestions(onResult); + } + + @Override public void onShowXpostSuggestions(Consumer onResult) { + mShowSuggestionsUtil.showXpostSuggestions(onResult); } @Override @@ -531,7 +535,7 @@ public void attachToContainer(ViewGroup viewGroup, OnLogGutenbergUserEventListener onLogGutenbergUserEventListener, OnGutenbergDidRequestUnsupportedBlockFallbackListener onGutenbergDidRequestUnsupportedBlockFallbackListener, OnGutenbergDidSendButtonPressedActionListener onGutenbergDidSendButtonPressedActionListener, - AddMentionUtil addMentionUtil, + ShowSuggestionsUtil showSuggestionsUtil, OnStarterPageTemplatesTooltipShownEventListener onStarterPageTemplatesTooltipListener, OnMediaFilesCollectionBasedBlockEditorListener onMediaFilesCollectionBasedBlockEditorListener, boolean isDarkMode) { @@ -549,7 +553,7 @@ public void attachToContainer(ViewGroup viewGroup, mOnLogGutenbergUserEventListener = onLogGutenbergUserEventListener; mOnGutenbergDidRequestUnsupportedBlockFallbackListener = onGutenbergDidRequestUnsupportedBlockFallbackListener; mOnGutenbergDidSendButtonPressedActionListener = onGutenbergDidSendButtonPressedActionListener; - mAddMentionUtil = addMentionUtil; + mShowSuggestionsUtil = showSuggestionsUtil; mOnStarterPageTemplatesTooltipShownListener = onStarterPageTemplatesTooltipListener; mOnMediaFilesCollectionBasedBlockEditorListener = onMediaFilesCollectionBasedBlockEditorListener; diff --git a/packages/react-native-bridge/index.js b/packages/react-native-bridge/index.js index f7d76c91d53cd5..e5bc1db51a0ab2 100644 --- a/packages/react-native-bridge/index.js +++ b/packages/react-native-bridge/index.js @@ -279,8 +279,12 @@ export function logUserEvent( event, properties ) { return RNReactNativeGutenbergBridge.logUserEvent( event, properties ); } -export function addMention() { - return RNReactNativeGutenbergBridge.addMention(); +export function showUserSuggestions() { + return RNReactNativeGutenbergBridge.showUserSuggestions(); +} + +export function showXpostSuggestions() { + return RNReactNativeGutenbergBridge.showXpostSuggestions(); } export function requestStarterPageTemplatesTooltipShown( callback ) { diff --git a/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift b/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift index 2e624791346908..753515f600a7e3 100644 --- a/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift +++ b/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift @@ -18,6 +18,7 @@ public struct MediaInfo: Encodable { public enum Capabilities: String { case mediaFilesCollectionBlock case mentions + case xposts case unsupportedBlockEditor case canEnableUnsupportedBlockEditor case modalLayoutPicker @@ -225,6 +226,10 @@ public protocol GutenbergBridgeDelegate: class { /// - Parameter callback: Completion handler to be called with an user mention or an error func gutenbergDidRequestMention(callback: @escaping (Swift.Result) -> Void) + /// Tells the delegate that the editor requested a mention + /// - Parameter callback: Completion handler to be called with an xpost or an error + func gutenbergDidRequestXpost(callback: @escaping (Swift.Result) -> Void) + /// Tells the delegate that the editor requested to show the tooltip func gutenbergDidRequestStarterPageTemplatesTooltipShown() -> Bool diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m index aafdce5c869aa0..9443cae473c1f3 100644 --- a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m @@ -20,7 +20,8 @@ @interface RCT_EXTERN_MODULE(RNReactNativeGutenbergBridge, NSObject) RCT_EXTERN_METHOD(requestMediaEditor:(NSString *)mediaUrl callback:(RCTResponseSenderBlock)callback) RCT_EXTERN_METHOD(logUserEvent:(NSString *)event properties:(NSDictionary *)properties) RCT_EXTERN_METHOD(requestUnsupportedBlockFallback:(NSString *)content blockId:(NSString *)blockId blockName:(NSString *)blockName blockTitle:(NSString *)blockTitle) -RCT_EXTERN_METHOD(addMention:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)rejecter) +RCT_EXTERN_METHOD(showUserSuggestions:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)rejecter) +RCT_EXTERN_METHOD(showXpostSuggestions:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)rejecter) RCT_EXTERN_METHOD(requestStarterPageTemplatesTooltipShown:(RCTResponseSenderBlock)callback) RCT_EXTERN_METHOD(setStarterPageTemplatesTooltipShown:(BOOL)tooltipShown) RCT_EXTERN_METHOD(requestMediaFilesEditorLoad:(NSArray *)mediaFiles blockId:(NSString *)blockId) diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift index 3d8168ba17e8d4..927a59eb8e0fbe 100644 --- a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift @@ -267,7 +267,7 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter { } @objc - func addMention(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) { + func showUserSuggestions(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) { self.delegate?.gutenbergDidRequestMention(callback: { (result) in switch result { case .success(let mention): @@ -278,6 +278,18 @@ public class RNReactNativeGutenbergBridge: RCTEventEmitter { }) } + @objc + func showXpostSuggestions(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) { + self.delegate?.gutenbergDidRequestXpost(callback: { (result) in + switch result { + case .success(let mention): + resolver([mention]) + case .failure(let error): + rejecter(error.domain, "\(error.code)", error) + } + }) + } + @objc func requestStarterPageTemplatesTooltipShown(_ callback: @escaping RCTResponseSenderBlock) { callback([self.delegate?.gutenbergDidRequestStarterPageTemplatesTooltipShown() ?? false]) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 5e8ccb56e967dd..095ed5bbc8fd57 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -11,14 +11,23 @@ For each user feature we should also add a importance categorization label to i ## Unreleased -## 1.43.0 (2020-12-17) +* [***] Full-width and wide alignment support for Columns +## 1.43.0 +* [***] New Block: File [#27228] +* [**] Fix issue where a blocks would disappear when deleting all of the text inside without requiring the extra backspace to remove the block. [#27583] + +## 1.42.0 * [***] Adding support for selecting different unit of value in Cover and Columns blocks [#26161] * [**] Button block - Add link picker to the block settings [#26206] * [**] Support to render background/text colors in Group, Paragraph and Quote blocks [#25994] * [*] Fix theme colors syncing with the editor [#26821] * [**] Fix issue where a blocks would disappear when deleting all of the text inside without requiring the extra backspace to remove the block. [#27583] +## 1.44.0 + +* [***] Add support for cross-posting between sites + ## 1.41.0 * [***] Faster editor start and overall operation on Android [#26732] diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js index 2b08b695935b6a..f3cdbac9565cf4 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -245,7 +245,9 @@ class EditorPage { blockAccessibilityLabel ); const size = await this.driver.getWindowSize(); - const height = size.height - 5; + // The virtual home button covers the bottom 34 in portrait and 21 on landscape on iOS. + // We start dragging a bit above it to not trigger home button. + const height = size.height - 50; while ( ! ( await blockButton.isDisplayed() ) ) { await this.driver.execute( 'mobile: dragFromToForDuration', { diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java index 83bbea9e5d5a15..ed3fdb7616676a 100644 --- a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java +++ b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java @@ -29,6 +29,7 @@ protected Bundle getLaunchOptions() { Bundle bundle = new Bundle(); Bundle capabilities = new Bundle(); capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_MENTIONS, true); + capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_XPOSTS, true); capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR, true); bundle.putBundle(GutenbergProps.PROP_CAPABILITIES, capabilities); return bundle; diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java index 628feb8b8b6dbb..afa269ee7ce1c6 100644 --- a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java +++ b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java @@ -189,8 +189,13 @@ public void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockC } @Override - public void onAddMention(Consumer onSuccess) { - onSuccess.accept("matt"); + public void onShowUserSuggestions(Consumer onResult) { + onResult.accept("matt"); + } + + @Override + public void onShowXpostSuggestions(Consumer onResult) { + onResult.accept("ma.tt"); } @Override diff --git a/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift b/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift index 06ba6a6704bb32..b0002e0e7b5917 100644 --- a/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift +++ b/packages/react-native-editor/ios/GutenbergDemo/GutenbergViewController.swift @@ -225,6 +225,10 @@ extension GutenbergViewController: GutenbergBridgeDelegate { callback(.success("matt")) } + func gutenbergDidRequestXpost(callback: @escaping (Result) -> Void) { + callback(.success("ma.tt")) + } + func gutenbergDidRequestStarterPageTemplatesTooltipShown() -> Bool { return false; } @@ -298,6 +302,7 @@ extension GutenbergViewController: GutenbergBridgeDataSource { func gutenbergCapabilities() -> [Capabilities : Bool] { return [ .mentions: true, + .xposts: true, .unsupportedBlockEditor: unsupportedBlockEnabled, .canEnableUnsupportedBlockEditor: unsupportedBlockCanBeActivated, .mediaFilesCollectionBlock: true, diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index 39b82482fe5dc7..5735431de050df 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -21,7 +21,7 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - Gutenberg (1.42.1): + - Gutenberg (1.43.0): - React-Core (= 0.61.5) - React-CoreModules (= 0.61.5) - React-RCTImage (= 0.61.5) @@ -253,7 +253,7 @@ PODS: - React-Core - RNSVG (9.13.6-gb): - React-Core - - RNTAztecView (1.42.1): + - RNTAztecView (1.43.0): - React-Core - WordPress-Aztec-iOS (~> 1.19.3) - WordPress-Aztec-iOS (1.19.3) @@ -402,7 +402,7 @@ SPEC CHECKSUMS: FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 - Gutenberg: d4257899f1def887029385c03eeadb20f8769506 + Gutenberg: 0bf0e3308e75b4c4693447d3ce672410e978616e RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78 @@ -435,7 +435,7 @@ SPEC CHECKSUMS: RNReanimated: f05baf4cd76b6eab2e4d7e2b244424960b968918 RNScreens: 953633729a42e23ad0c93574d676b361e3335e8b RNSVG: 46c4b680fe18237fa01eb7d7b311d77618fde31f - RNTAztecView: 38c4acd97d152a125eba9318125c3a75ea99e1db + RNTAztecView: 2b2423ec5349be4170212c6d81345525b4d9f41c WordPress-Aztec-iOS: b7ac8b30f746992e85d9668453ac87c2cdcecf4f Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 7e59d11c094181..2d3f3819dbac13 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -8,7 +8,10 @@ */ import RCTAztecView from '@wordpress/react-native-aztec'; import { View, Platform } from 'react-native'; -import { addMention } from '@wordpress/react-native-bridge'; +import { + showUserSuggestions, + showXpostSuggestions, +} from '@wordpress/react-native-bridge'; import { get, pickBy, debounce } from 'lodash'; import memize from 'memize'; @@ -17,14 +20,13 @@ import memize from 'memize'; */ import { BlockFormatControls } from '@wordpress/block-editor'; import { Component } from '@wordpress/element'; -import { Toolbar, ToolbarButton } from '@wordpress/components'; import { compose, withPreferredColorScheme } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; import { childrenBlock } from '@wordpress/blocks'; import { decodeEntities } from '@wordpress/html-entities'; import { BACKSPACE, DELETE, ENTER } from '@wordpress/keycodes'; import { isURL } from '@wordpress/url'; -import { Icon, atSymbol } from '@wordpress/icons'; +import { atSymbol, plus } from '@wordpress/icons'; import { __ } from '@wordpress/i18n'; /** @@ -43,6 +45,8 @@ import { removeLineSeparator } from '../remove-line-separator'; import { isCollapsed } from '../is-collapsed'; import { remove } from '../remove'; import styles from './style.scss'; +import ToolbarButtonWithOptions from './toolbar-button-with-options'; +import { store as richTextStore } from '../store'; const unescapeSpaces = ( text ) => { return text.replace( / | /gi, ' ' ); @@ -82,7 +86,6 @@ export class RichText extends Component { this.onKeyDown = this.onKeyDown.bind( this ); this.handleEnter = this.handleEnter.bind( this ); this.handleDelete = this.handleDelete.bind( this ); - this.handleMention = this.handleMention.bind( this ); this.onPaste = this.onPaste.bind( this ); this.onFocus = this.onFocus.bind( this ); this.onBlur = this.onBlur.bind( this ); @@ -100,7 +103,16 @@ export class RichText extends Component { ); this.valueToFormat = this.valueToFormat.bind( this ); this.getHtmlToRender = this.getHtmlToRender.bind( this ); - this.showMention = this.showMention.bind( this ); + this.handleSuggestionFunc = this.handleSuggestionFunc.bind( this ); + this.handleUserSuggestion = this.handleSuggestionFunc( + showUserSuggestions, + '@' + ).bind( this ); + this.handleXpostSuggestion = this.handleSuggestionFunc( + showXpostSuggestions, + '+' + ).bind( this ); + this.suggestionOptions = this.suggestionOptions.bind( this ); this.insertString = this.insertString.bind( this ); this.state = { activeFormats: [], @@ -321,7 +333,7 @@ export class RichText extends Component { this.handleDelete( event ); this.handleEnter( event ); - this.handleMention( event ); + this.handleTriggerKeyCodes( event ); } handleEnter( event ) { @@ -400,33 +412,66 @@ export class RichText extends Component { this.lastAztecEventType = 'input'; } - handleMention( event ) { + handleTriggerKeyCodes( event ) { const { keyCode } = event; + const triggeredOption = this.suggestionOptions().find( ( option ) => { + const triggeredKeyCode = option.triggerChar.charCodeAt( 0 ); + return triggeredKeyCode === keyCode; + } ); - if ( keyCode !== '@'.charCodeAt( 0 ) ) { - return; - } - const record = this.getRecord(); - const text = getTextContent( record ); - // Only start the mention UI if the selection is on the start of text or the character before is a space - if ( - text.length === 0 || - record.start === 0 || - text.charAt( record.start - 1 ) === ' ' - ) { - this.showMention(); - } else { - this.insertString( record, '@' ); + if ( triggeredOption ) { + const record = this.getRecord(); + const text = getTextContent( record ); + // Only respond to the trigger if the selection is on the start of text or line + // or if the character before is a space + const useTrigger = + text.length === 0 || + record.start === 0 || + text.charAt( record.start - 1 ) === '\n' || + text.charAt( record.start - 1 ) === ' '; + + if ( useTrigger && triggeredOption.onClick ) { + triggeredOption.onClick(); + } else { + this.insertString( record, triggeredOption.triggerChar ); + } } } - showMention() { - const record = this.getRecord(); - addMention() - .then( ( mentionUserId ) => { - this.insertString( record, `@${ mentionUserId } ` ); - } ) - .catch( () => {} ); + suggestionOptions() { + const { areMentionsSupported, areXPostsSupported } = this.props; + const allOptions = [ + { + supported: areMentionsSupported, + title: __( 'Insert mention' ), + onClick: this.handleUserSuggestion, + triggerChar: '@', + value: 'mention', + label: __( 'Mention' ), + icon: atSymbol, + }, + { + supported: areXPostsSupported, + title: __( 'Insert crosspost' ), + onClick: this.handleXpostSuggestion, + triggerChar: '+', + value: 'crosspost', + label: __( 'Crosspost' ), + icon: plus, + }, + ]; + return allOptions.filter( ( op ) => op.supported ); + } + + handleSuggestionFunc( suggestionFunction, prefix ) { + return () => { + const record = this.getRecord(); + suggestionFunction() + .then( ( suggestion ) => { + this.insertString( record, `${ prefix }${ suggestion } ` ); + } ) + .catch( () => {} ); + }; } /** @@ -685,7 +730,7 @@ export class RichText extends Component { } componentWillUnmount() { - if ( this._editor.isFocused() && this.props.shouldBlurOnUnmount ) { + if ( this._editor.isFocused() ) { this._editor.blur(); } } @@ -757,7 +802,6 @@ export class RichText extends Component { withoutInteractiveFormatting, accessibilityLabel, disableEditingMenu = false, - isMentionsSupported, } = this.props; const record = this.getRecord(); @@ -873,11 +917,9 @@ export class RichText extends Component { onFocus={ this.onFocus } onBlur={ this.onBlur } onKeyDown={ this.onKeyDown } - triggerKeyCodes={ - disableEditingMenu === false && isMentionsSupported - ? [ '@' ] - : [] - } + triggerKeyCodes={ this.suggestionOptions().map( + ( op ) => op.triggerChar + ) } onPaste={ this.onPaste } activeFormats={ this.getActiveFormatNames( record ) } onContentSizeChange={ this.onContentSizeChange } @@ -918,18 +960,9 @@ export class RichText extends Component { onFocus={ () => {} } /> - { - // eslint-disable-next-line no-undef - isMentionsSupported && ( - - } - onClick={ this.showMention } - /> - - ) - } + ) } @@ -955,9 +988,10 @@ export default compose( [ get( parentBlock, [ 'attributes', 'childrenStyles' ] ) || {}; return { - formatTypes: select( 'core/rich-text' ).getFormatTypes(), - isMentionsSupported: + formatTypes: select( richTextStore ).getFormatTypes(), + areMentionsSupported: getSettings( 'capabilities' ).mentions === true, + areXPostsSupported: getSettings( 'capabilities' ).xposts === true, ...{ parentBlockStyles }, }; } ), diff --git a/packages/rich-text/src/component/toolbar-button-with-options.native.js b/packages/rich-text/src/component/toolbar-button-with-options.native.js new file mode 100644 index 00000000000000..3936bdd98c2872 --- /dev/null +++ b/packages/rich-text/src/component/toolbar-button-with-options.native.js @@ -0,0 +1,61 @@ +/** + * WordPress dependencies + */ +import { Picker, ToolbarGroup, ToolbarButton } from '@wordpress/components'; +import { useRef } from '@wordpress/element'; +import { Icon } from '@wordpress/icons'; + +/** + * Toolbar button component that, upon a long press, opens a Picker + * to allow selecting from among multiple options. + * + * @param {Object} props Component props. + * @param {Object} props.options Options to pick from. + */ +function ToolbarButtonWithOptions( { options } ) { + const picker = useRef(); + + function presentPicker() { + if ( picker.current ) { + picker.current.presentPicker(); + } + } + + function onValueSelected( selectedValue ) { + const selectedOption = options.find( + ( op ) => op.value === selectedValue + ); + if ( selectedOption ) { + selectedOption.onClick(); + } + } + + if ( ! options || options.length === 0 ) { + return null; + } + const firstOption = options[ 0 ]; + const enablePicker = options.length > 1; + + return ( + <> + + } + onClick={ firstOption.onClick } + onLongPress={ enablePicker && presentPicker } + /> + + { enablePicker && ( + + ) } + + ); +} + +export default ToolbarButtonWithOptions; diff --git a/packages/rich-text/src/component/use-format-types.js b/packages/rich-text/src/component/use-format-types.js index 285e5ee540eaf2..c1df61ac093c12 100644 --- a/packages/rich-text/src/component/use-format-types.js +++ b/packages/rich-text/src/component/use-format-types.js @@ -2,9 +2,13 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as richTextStore } from '../store'; function formatTypesSelector( select ) { - return select( 'core/rich-text' ).getFormatTypes(); + return select( richTextStore ).getFormatTypes(); } /** diff --git a/packages/rich-text/src/get-format-type.js b/packages/rich-text/src/get-format-type.js index 7b266f66779a7d..48e41d41b9c795 100644 --- a/packages/rich-text/src/get-format-type.js +++ b/packages/rich-text/src/get-format-type.js @@ -2,6 +2,10 @@ * WordPress dependencies */ import { select } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as richTextStore } from './store'; /** @typedef {import('./register-format-type').RichTextFormatType} RichTextFormatType */ @@ -13,5 +17,5 @@ import { select } from '@wordpress/data'; * @return {RichTextFormatType|undefined} Format type. */ export function getFormatType( name ) { - return select( 'core/rich-text' ).getFormatType( name ); + return select( richTextStore ).getFormatType( name ); } diff --git a/packages/rich-text/src/get-format-types.js b/packages/rich-text/src/get-format-types.js index 8f2d88f0040995..74bec3a355aa62 100644 --- a/packages/rich-text/src/get-format-types.js +++ b/packages/rich-text/src/get-format-types.js @@ -2,6 +2,10 @@ * WordPress dependencies */ import { select } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as richTextStore } from './store'; /** @typedef {import('./register-format-type').RichTextFormatType} RichTextFormatType */ @@ -11,5 +15,5 @@ import { select } from '@wordpress/data'; * @return {Array} Format settings. */ export function getFormatTypes() { - return select( 'core/rich-text' ).getFormatTypes(); + return select( richTextStore ).getFormatTypes(); } diff --git a/packages/rich-text/src/register-format-type.js b/packages/rich-text/src/register-format-type.js index 80e9d1680bc7fc..e3c096804e0ee6 100644 --- a/packages/rich-text/src/register-format-type.js +++ b/packages/rich-text/src/register-format-type.js @@ -2,7 +2,10 @@ * WordPress dependencies */ import { select, dispatch } from '@wordpress/data'; - +/** + * Internal dependencies + */ +import { store as richTextStore } from './store'; /** * @typedef {Object} WPFormat * @@ -44,7 +47,7 @@ export function registerFormatType( name, settings ) { return; } - if ( select( 'core/rich-text' ).getFormatType( settings.name ) ) { + if ( select( richTextStore ).getFormatType( settings.name ) ) { window.console.error( 'Format "' + settings.name + '" is already registered.' ); @@ -76,7 +79,7 @@ export function registerFormatType( name, settings ) { if ( settings.className === null ) { const formatTypeForBareElement = select( - 'core/rich-text' + richTextStore ).getFormatTypeForBareElement( settings.tagName ); if ( formatTypeForBareElement ) { @@ -87,7 +90,7 @@ export function registerFormatType( name, settings ) { } } else { const formatTypeForClassName = select( - 'core/rich-text' + richTextStore ).getFormatTypeForClassName( settings.className ); if ( formatTypeForClassName ) { @@ -119,7 +122,7 @@ export function registerFormatType( name, settings ) { return; } - dispatch( 'core/rich-text' ).addFormatTypes( settings ); + dispatch( richTextStore ).addFormatTypes( settings ); return settings; } diff --git a/packages/rich-text/src/test/register-format-type.js b/packages/rich-text/src/test/register-format-type.js index 9983c48f85f39d..0d044d28facfae 100644 --- a/packages/rich-text/src/test/register-format-type.js +++ b/packages/rich-text/src/test/register-format-type.js @@ -9,6 +9,7 @@ import { select } from '@wordpress/data'; import { registerFormatType } from '../register-format-type'; import { unregisterFormatType } from '../unregister-format-type'; import { getFormatType } from '../get-format-type'; +import { store as richTextStore } from '../store'; describe( 'registerFormatType', () => { beforeAll( () => { @@ -17,7 +18,7 @@ describe( 'registerFormatType', () => { } ); afterEach( () => { - select( 'core/rich-text' ) + select( richTextStore ) .getFormatTypes() .forEach( ( { name } ) => { unregisterFormatType( name ); diff --git a/packages/rich-text/src/unregister-format-type.js b/packages/rich-text/src/unregister-format-type.js index 97ee623c9383ea..519e33362d5b68 100644 --- a/packages/rich-text/src/unregister-format-type.js +++ b/packages/rich-text/src/unregister-format-type.js @@ -3,6 +3,11 @@ */ import { select, dispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store as richTextStore } from './store'; + /** @typedef {import('./register-format-type').RichTextFormatType} RichTextFormatType */ /** @@ -15,14 +20,14 @@ import { select, dispatch } from '@wordpress/data'; * otherwise `undefined`. */ export function unregisterFormatType( name ) { - const oldFormat = select( 'core/rich-text' ).getFormatType( name ); + const oldFormat = select( richTextStore ).getFormatType( name ); if ( ! oldFormat ) { window.console.error( `Format ${ name } is not registered.` ); return; } - dispatch( 'core/rich-text' ).removeFormatTypes( name ); + dispatch( richTextStore ).removeFormatTypes( name ); return oldFormat; } diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index ac9b0bdc414f92..4e80c587709c62 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fix + +- Fix multiple build (`build` command) runtimes conflicting when using globals ([#27985](https://github.com/WordPress/gutenberg/pull/27985)). + ## 12.6.0 (2020-12-17) ### Enhancements diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js index 22a9878ac3e015..190bf16f3c5831 100644 --- a/packages/scripts/config/webpack.config.js +++ b/packages/scripts/config/webpack.config.js @@ -17,7 +17,11 @@ const postcssPlugins = require( '@wordpress/postcss-plugins-preset' ); /** * Internal dependencies */ -const { hasBabelConfig, hasPostCSSConfig } = require( '../utils' ); +const { + getPackageProp, + hasBabelConfig, + hasPostCSSConfig, +} = require( '../utils' ); const FixStyleWebpackPlugin = require( './fix-style-webpack-plugin' ); const isProduction = process.env.NODE_ENV === 'production'; @@ -46,6 +50,32 @@ const cssLoaders = [ }, ]; +/** + * Gets a unique identifier for the webpack build to avoid multiple webpack + * runtimes to conflict when using globals. + * This is polyfill and it is based on the default webpack 5 implementation. + * + * @see https://github.com/webpack/webpack/blob/bbb16e7af2eddba4cd77ca739904c2aa238a2b7b/lib/config/defaults.js#L374-L376 + * + * @return {string} The generated identifier. + */ +const getJsonpFunctionIdentifier = () => { + const jsonpFunction = 'webpackJsonp_'; + const packageName = getPackageProp( 'name' ); + if ( typeof packageName !== 'string' || ! packageName ) { + return jsonpFunction; + } + const IDENTIFIER_NAME_REPLACE_REGEX = /^([^a-zA-Z$_])/; + const IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX = /[^a-zA-Z0-9$]+/g; + + return ( + jsonpFunction + + packageName + .replace( IDENTIFIER_NAME_REPLACE_REGEX, '_$1' ) + .replace( IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX, '_' ) + ); +}; + const config = { mode, entry: { @@ -54,6 +84,10 @@ const config = { output: { filename: '[name].js', path: path.resolve( process.cwd(), 'build' ), + // Prevents conflicts when multiple webpack runtimes (from different apps) + // are used on the same page. + // @see https://github.com/WordPress/gutenberg/issues/23607 + jsonpFunction: getJsonpFunctionIdentifier(), }, resolve: { alias: { diff --git a/packages/scripts/utils/index.js b/packages/scripts/utils/index.js index d4806fbdeaa570..edb728d0521ecb 100644 --- a/packages/scripts/utils/index.js +++ b/packages/scripts/utils/index.js @@ -19,7 +19,7 @@ const { hasPostCSSConfig, } = require( './config' ); const { fromProjectRoot, fromConfigRoot, hasProjectFile } = require( './file' ); -const { hasPackageProp } = require( './package' ); +const { getPackageProp, hasPackageProp } = require( './package' ); module.exports = { fromProjectRoot, @@ -27,16 +27,17 @@ module.exports = { getArgFromCLI, getArgsFromCLI, getFileArgsFromCLI, + getJestOverrideConfigFile, getNodeArgsFromCLI, + getPackageProp, getWebpackArgs, - hasBabelConfig, hasArgInCLI, + hasBabelConfig, hasFileArgInCLI, - getJestOverrideConfigFile, hasJestConfig, hasPackageProp, - hasPrettierConfig, hasPostCSSConfig, + hasPrettierConfig, hasProjectFile, spawnScript, }; diff --git a/packages/scripts/utils/package.js b/packages/scripts/utils/package.js index 4de586f297c185..1ad275e64fb682 100644 --- a/packages/scripts/utils/package.js +++ b/packages/scripts/utils/package.js @@ -15,9 +15,12 @@ const { pkg, path: pkgPath } = readPkgUp( { const getPackagePath = () => pkgPath; +const getPackageProp = ( prop ) => pkg && pkg[ prop ]; + const hasPackageProp = ( prop ) => pkg && pkg.hasOwnProperty( prop ); module.exports = { getPackagePath, + getPackageProp, hasPackageProp, }; diff --git a/packages/stylelint-config/.npmrc b/packages/stylelint-config/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/stylelint-config/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/stylelint-config/CHANGELOG.md b/packages/stylelint-config/CHANGELOG.md new file mode 100644 index 00000000000000..7c2e4e55926745 --- /dev/null +++ b/packages/stylelint-config/CHANGELOG.md @@ -0,0 +1,250 @@ + + +## Unreleased + +### Breaking Change + +- Removed stylelint `^10.1.0`, `^11.0.0`, and `^12.0.0` as peer dependency. + +### Internal + +- Imported from `WordPress-Coding-Standards/stylelint-config-wordpress` repository to `WordPress/gutenberg` ([#22777](https://github.com/WordPress/gutenberg/pull/22777)) + +## 17.0.0 (2020-05-31) + +- Updated: `stylelint-scss` to `3.17.2`. +- Updated: `stylelint` to `13.0.0`. + +## 16.0.0 (2019-12-31) + +- Fixed: `selector-class-pattern` rule regex to account for numerals, case detection, and ensure kebab-case over snake_case. +- Fixed: `selector-id-pattern` rule regex to account for numerals, case detection, and ensure kebab-case over snake_case. +- Updated: `stylelint-config-recommended-scss` to `4.1.0`. +- Updated: `stylelint-find-rules` to `2.2.0`. +- Updated: `stylelint-scss` to `3.13.0`. +- Updated: `stylelint` to `11.0.0`. + +## 15.0.0 (2019-10-05) + +- Added: NodeJS 12.x.x support. +- Updated: `stylelint` to `11.0.0`. +- Removed: `stylelint < 10.1.0` compatibility. +- Updated: `stylelint-config-recommended` to `3.0.0`. +- Updated: `stylelint-config-recommended-scss` to `4.0.0`. +- Updated: Bump minimum Node.js required version to `10.0.0`. + +## 14.0.0 (2019-04-18) + +- Updated: `stylelint` to `10.0.0`. +- Updated: `stylelint-scss` to `3.6.0`. +- Updated: `stylelint-config-recommended` to `2.2.0`. + +## 13.1.0 (2018-08-19) + +- Added: Added SCSS _shared config_ `extends` tests. +- Changed: `stylelint-config-wordpress/scss` now extends [`stylelint-config-recommended-scss`](https://github.com/kristerkari/stylelint-config-recommended-scss) (the net result of this change results in no rule changes for this SCSS config). +- Updated: `stylelint-scss` to `3.3.0`. +- Updated: `stylelint` to `9.5.0`. + +## 13.0.0 (2018-03-19) + +- Added: stylelint `9.1.3` support. +- Changed: Updated `stylelint` peer dependency version to `^9.1.3`. +- Changed: Improved `no-duplicate-selectors` tests. +- Removed: Jest snapshots. +- Removed: `stylelint < 9.1.3` compatibility. +- Updated: `selector-pseudo-element-colon-notation` to use `double` +- Updated: `stylelint-config-recommended` to `2.1.0`. +- Updated: `stylelint-scss` to `2.1.0`. +- Updated: Bump minimum Node.js required version to `8.9.3`. + +## 12.0.0 (2017-07-18) + +- Changed: `stylelint-config-wordpress` now extends [`stylelint-config-recommended`](https://github.com/stylelint/stylelint-config-recommended), which turns on the `at-rule-no-unknown`, `block-no-empty`, `comment-no-empty`, `declaration-block-no-ignored-properties`, `declaration-block-no-redundant-longhand-properties`, `font-family-no-duplicate-names`, `media-feature-name-no-unknown`, `no-empty-source` rule. These rules are part of stylelint's [possible errors](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/rules.md#possible-errors) rules. +- Removed: `stylelint-scss < 1.5.1` compatibility. +- Removed: Removed style guide docs. +- Removed: `at-rule-no-unknown` custom `ignoreAtRules` options in `stylelint-config-wordpress/scss` shared config. +- Added: `scss/at-rule-no-unknown` rule in `stylelint-config-wordpress/scss` shared config. +- Added: NodeJS 8.x.x support. +- Added: npm 5.x.x support. +- Added: Jest snapshots to help detect and prevent regressions. + +## 11.0.0 (2017-05-16) + +- Added: `declaration-property-unit-whitelist` rule to allow `px` and exclude `%` and `em` units in `line-height` values. +- Changed: Relocated repo to https://github.com/WordPress-Coding-Standards. +- Fixed: Include CSS config `at-rule-empty-line-before` rules in SCSS config. + +## 10.0.2 (2017-04-29) + +- Added: Added `import` to `ignoreAtRules` option in `at-rule-empty-line-before` rule for SCSS config. + +## 10.0.1 (2017-04-21) + +- Removed: `rule-non-nested-empty-line-before` rule from SCSS config. This rule is deprecated in stylelint v8, the new `rule-empty-line-before` rule already exists in the primary config. + +## 10.0.0 (2017-04-21) + +- Added: `scss/selector-no-redundant-nesting-selector` rule in `stylelint-config-wordpress/scss` shared config. +- Added: `selector-no-empty` rule. +- Added: NodeJS 7.x.x support +- Fixed: Added `stylelint-scss` plugin @if/@else placement rules. +- Fixed: Ignore `relative` keyword names in `font-weight-notation` rule. +- Fixed: Ignore proprietary `DXImageTransform.Microsoft` MS filters +- Fixed: Removed `@debug` from `ignoreAtRules` array of `at-rule-no-unknown` rule in `stylelint-config-wordpress/scss` chared config. +- Deprecated `blockless-group` option for `at-rule-empty-line-before` rule. Use the new `blockless-after-blockless` option instead. +- Deprecated `media-feature-no-missing-punctuation` rule. +- Deprecated `rule-nested-empty-line-before` and `rule-non-nested-empty-line-before` rules. Use the new `rule-empty-line-before` rule instead. +- Deprecated `selector-no-empty` rule. +- Refactor: Switch from AVA to Jest for tests. +- Refactor: Switch from eslint-plugin-ava to eslint-plugin-jest. +- Removed: `stylelint < 7.10.1` compatibility. +- Removed: `stylelint-scss < 1.4.4` compatibility. +- Removed: NodeJS 4.x support, `stylelint` and `stylelint-config-wordpress` now require NodeJS > 6.9.1 LTS or greater + +## 9.1.1 (2016-09-30) + +- Fixed: Re-releasing failed npmjs.com 9.1.0 release as 9.1.1. + +## 9.1.0 (2016-09-30) + +- Added: `stylelint-config-wordpress/scss` preset. + +## 9.0.0 (2016-09-10) + +- Removed: `stylelint < 7.2.0` compatibility. +- Removed: NodeJS 0.12.x support, `stylelint` and `stylelint-config-wordpress` now require NodeJS > 4.2.1 LTS or greater +- Added: `at-rule-no-unknown` rule. +- Added: `selector-attribute-quotes` rule. +- Added: `font-weight-notation` rule. +- Added: `max-line-length` rule. +- Added: `property-no-unknown` rule. +- Added: `selector-class-pattern` rule. +- Added: `selector-id-pattern` rule. +- Deprecated `no-missing-eof-newline` rule. Use the new `no-missing-end-of-source-newline` rule instead. +- Fixed `font-family-name-quotes` test warning message in `values.js`. + +## 8.0.0 (2016-06-14) + +- Removed: `stylelint < 6.6.0` compatibility. +- Removed: `number-zero-length-no-unit` rule. +- Added: `length-zero-no-unit` rule. +- Added: `value-keyword-case` rule. + +## 7.1.1 (2016-05-30) + +- Fixed: Re-releasing failed npmjs.com 7.0.0 release as 7.1.1. + +## 7.1.0 (2016-05-30) + +- Fixed: `font-family-name-quotes` rule deprecated option `double-where-recommended` to new `always-where-recommended` option. +- Fixed: `function-url-quotes` rule deprecated option `none` to new `never` option. +- Removed: `stylelint < 6.5.1` compatibility. +- Changed: Improved tests and documentation. +- Added: `comment-empty-line-before` rule. + +## 7.0.0 (2016-05-20) + +- Added: `keyframe-declaration-no-important` rule. +- Added: `selector-pseudo-class-no-unknown` rule. +- Added: `selector-pseudo-element-no-unknown` rule. +- Added: `selector-type-no-unknown` rule. + +## 6.0.0 (2016-05-17) + +- Added: `at-rule-name-space-after` rule. +- Added: `no-extra-semicolons` rule. +- Added: `selector-attribute-operator-space-after` rule. +- Added: `selector-attribute-operator-space-before` rule. +- Added: `selector-max-empty-liness` rule. + +## 5.0.0 (2016-04-24) + +- Added: `at-rule-name-case` rule. +- Added: `declaration-block-no-duplicate-properties` rule. +- Added: `function-max-empty-lines` rule. +- Added: `function-name-case` rule. +- Added: `property-case` rule. +- Added: `selector-attribute-brackets-space-inside` rule. +- Added: `selector-pseudo-class-case` rule. +- Added: `selector-pseudo-class-parentheses-space-inside` rule. +- Added: `selector-pseudo-element-case` rule. +- Added: `shorthand-property-no-redundant-values` rule. +- Added: `unit-case` rule. +- Added: `unit-no-unknown` rule. + +## 4.0.0 (2016-03-25) + +- Removed: `stylelint < 5.2.0` compatibility. +- Added: `at-rule-semicolon-newline-after` rule. +- Added: `selector-type-case` rule. + +## 3.0.1 (2016-03-10) + +- Added: `stylelint` version `^4.5.0` as a peer dependency to `peerDependencies` in `package.json` + +## 3.0.0 (2016-03-08) + +- Removed: `stylelint < 4.5.0` compatibility. +- Deprecated: `rule-no-shorthand-property-overrides` rule. Use the new `declaration-block-no-shorthand-property-overrides` rule instead. +- Deprecated: `rule-trailing-semicolon` rule. Use the new `declaration-block-trailing-semicolon` rule instead. +- Added: `color-named` rule. +- Added: `declaration-block-no-shorthand-property-overrides` rule. +- Added: `declaration-block-trailing-semicolon` rule. +- Added: `string-no-newline` rule. + +## 2.1.0 (2016-03-03) + +- Added: `max-empty-lines` rule, limits the number of adjacent empty lines to 2. +- Changed: `rule-nested-empty-line-before` rule option `ignore: ["after-comment"]`. +- Removed all vendor prefixes, lets autoprefixer handle vendor prefixes: + - Removed: `at-rule-no-vendor-prefix` + - Removed: `media-feature-name-no-vendor-prefix` + - Removed: `property-no-vendor-prefix` + - Removed: `selector-no-vendor-prefix` + - Removed: `value-no-vendor-prefix` + +## 2.0.2 (2016-02-17) + +- Fixed another npmjs.com release issue + +## 2.0.1 (2016-02-17) + +- Fixed npmjs.com release + +## 2.0.0 (2016-02-17) + +- Removed: `media-query-parentheses-space-inside` rule. +- Removed: `stylelint < 4.3.4` compatibility. +- Added: `font-family-name-quotes` rule with double quotes where recommended option. +- Added: `media-feature-no-missing-punctuation` rule. +- Added: `no-invalid-double-slash-comments` rule. + +## 1.1.1 (2016-01-19) + +- Changed: `rule-non-nested-empty-line-before` with option `ignore: ["after-comment"],`. + +## 1.1.0 (2016-01-18) + +- Added: `selector-pseudo-element-colon-notation` with option `single` + +## 1.0.1 (2015-12-11) + +- Changed: config syntax. + +## 1.0.0 (2015-12-11) + +- Removed: `stylelint < 3.0.0` compatibility. +- Changed: renamed the `function-space-after` rule to `function-whitespace-after`. +- Changed: `at-rule-empty-line-before` with option `ignore: ["after-comment"],`. +- Changed: `declaration-colon-space-after` with option `always-single-line`. +- Added: `declaration-colon-newline-after` with option `always-multi-line`. +- Added: `function-linear-gradient-no-nonstandard-direction`. + +## 0.2.0 (2015-09-04) + +- Fixed: No quotes for URLs -> `"function-url-quotes": [ 2, "none" ]`. + +## 0.1.0 (2015-08-01) + +Initial release. diff --git a/packages/stylelint-config/LICENSE b/packages/stylelint-config/LICENSE new file mode 100644 index 00000000000000..8673b137beef47 --- /dev/null +++ b/packages/stylelint-config/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 stylelint + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/packages/stylelint-config/README.md b/packages/stylelint-config/README.md new file mode 100644 index 00000000000000..0989d54a20d08f --- /dev/null +++ b/packages/stylelint-config/README.md @@ -0,0 +1,57 @@ +# stylelint config + +[stylelint](https://stylelint.io/) configuration rules to ensure your CSS is compliant with the [WordPress CSS Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/css/). + +## Installation + +```bash +$ npm install @wordpress/stylelint-config --save-dev +``` + +## Usage + +If you've installed `@wordpress/stylelint-config` locally within your project, just set your `stylelint` config to: + +```json +{ + "extends": "@wordpress/stylelint-config" +} +``` + +If you've globally installed `@wordpress/stylelint-config` using the `-g` flag, then you'll need to use the absolute path to `@wordpress/stylelint-config` in your config: + +```json +{ + "extends": "/absolute/path/to/@wordpress/stylelint-config" +} +``` + +## Presets + +In addition to the default preset, there is also a SCSS preset. This preset extends both `@wordpress/stylelint-config` and [`stylelint-config-recommended-scss`](https://github.com/kristerkari/stylelint-config-recommended-scss). + +### SCSS + +```json +{ + "extends": [ "@wordpress/stylelint-config/scss" ] +} +``` + +## Extending the config + +Simply add a `"rules"` key to your config and add your overrides there. + +For example, to change the `indentation` to four spaces and turn off the `number-leading-zero` rule: + +```json +{ + "extends": "@wordpress/stylelint-config", + "rules": { + "indentation": 4, + "number-leading-zero": null + } +} +``` + +

Code is Poetry.

diff --git a/packages/stylelint-config/index.js b/packages/stylelint-config/index.js new file mode 100644 index 00000000000000..490ab35d5b1312 --- /dev/null +++ b/packages/stylelint-config/index.js @@ -0,0 +1,131 @@ +'use strict'; + +module.exports = { + extends: 'stylelint-config-recommended', + rules: { + 'at-rule-empty-line-before': [ + 'always', + { + except: [ 'blockless-after-blockless' ], + ignore: [ 'after-comment' ], + }, + ], + 'at-rule-name-case': 'lower', + 'at-rule-name-space-after': 'always-single-line', + 'at-rule-no-unknown': true, + 'at-rule-semicolon-newline-after': 'always', + 'block-closing-brace-newline-after': 'always', + 'block-closing-brace-newline-before': 'always', + 'block-opening-brace-newline-after': 'always', + 'block-opening-brace-space-before': 'always', + 'color-hex-case': 'lower', + 'color-hex-length': 'short', + 'color-named': 'never', + 'comment-empty-line-before': [ + 'always', + { + ignore: [ 'stylelint-commands' ], + }, + ], + 'declaration-bang-space-after': 'never', + 'declaration-bang-space-before': 'always', + 'declaration-block-no-duplicate-properties': [ + true, + { + ignore: [ 'consecutive-duplicates' ], + }, + ], + 'declaration-block-semicolon-newline-after': 'always', + 'declaration-block-semicolon-space-before': 'never', + 'declaration-block-trailing-semicolon': 'always', + 'declaration-colon-newline-after': 'always-multi-line', + 'declaration-colon-space-after': 'always-single-line', + 'declaration-colon-space-before': 'never', + 'declaration-property-unit-whitelist': { + 'line-height': [ 'px' ], + }, + 'font-family-name-quotes': 'always-where-recommended', + 'font-weight-notation': [ + 'numeric', + { + ignore: [ 'relative' ], + }, + ], + 'function-comma-space-after': 'always', + 'function-comma-space-before': 'never', + 'function-max-empty-lines': 1, + 'function-name-case': [ + 'lower', + { + ignoreFunctions: [ '/^DXImageTransform.Microsoft.*$/' ], + }, + ], + 'function-parentheses-space-inside': 'never', + 'function-url-quotes': 'never', + 'function-whitespace-after': 'always', + indentation: 'tab', + 'length-zero-no-unit': true, + 'max-empty-lines': 2, + 'max-line-length': [ + 80, + { + ignore: 'non-comments', + ignorePattern: [ + '/(https?://[0-9,a-z]*.*)|(^description\\:.+)|(^tags\\:.+)/i', + ], + }, + ], + 'media-feature-colon-space-after': 'always', + 'media-feature-colon-space-before': 'never', + 'media-feature-range-operator-space-after': 'always', + 'media-feature-range-operator-space-before': 'always', + 'media-query-list-comma-newline-after': 'always-multi-line', + 'media-query-list-comma-space-after': 'always-single-line', + 'media-query-list-comma-space-before': 'never', + 'no-eol-whitespace': true, + 'no-missing-end-of-source-newline': true, + 'number-leading-zero': 'always', + 'number-no-trailing-zeros': true, + 'property-case': 'lower', + 'rule-empty-line-before': [ + 'always', + { + ignore: [ 'after-comment' ], + }, + ], + 'selector-attribute-brackets-space-inside': 'never', + 'selector-attribute-operator-space-after': 'never', + 'selector-attribute-operator-space-before': 'never', + 'selector-attribute-quotes': 'always', + 'selector-class-pattern': [ + '^([a-z][a-z0-9]*)(-[a-z0-9]+)*$', + { + message: + 'Selector should use lowercase and separate words with hyphens (selector-class-pattern)', + }, + ], + 'selector-id-pattern': [ + '^([a-z][a-z0-9]*)(-[a-z0-9]+)*$', + { + message: + 'Selector should use lowercase and separate words with hyphens (selector-id-pattern)', + }, + ], + 'selector-combinator-space-after': 'always', + 'selector-combinator-space-before': 'always', + 'selector-list-comma-newline-after': 'always', + 'selector-list-comma-space-before': 'never', + 'selector-max-empty-lines': 0, + 'selector-pseudo-class-case': 'lower', + 'selector-pseudo-class-parentheses-space-inside': 'never', + 'selector-pseudo-element-case': 'lower', + 'selector-pseudo-element-colon-notation': 'double', + 'selector-type-case': 'lower', + 'string-quotes': 'double', + 'unit-case': 'lower', + 'value-keyword-case': 'lower', + 'value-list-comma-newline-after': 'always-multi-line', + 'value-list-comma-space-after': 'always-single-line', + 'value-list-comma-space-before': 'never', + }, +}; diff --git a/packages/stylelint-config/package.json b/packages/stylelint-config/package.json new file mode 100644 index 00000000000000..8e7a90f8de2c16 --- /dev/null +++ b/packages/stylelint-config/package.json @@ -0,0 +1,52 @@ +{ + "name": "@wordpress/stylelint-config", + "version": "17.0.0", + "description": "stylelint config for WordPress development.", + "author": "The WordPress Contributors", + "license": "MIT", + "keywords": [ + "stylelint", + "stylelint-config", + "stylelint-config-wordpress", + "wordpress" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/stylelint-config/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/stylelint-config" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "index.js", + "scss.js" + ], + "main": "index.js", + "dependencies": { + "stylelint-config-recommended": "^3.0.0", + "stylelint-config-recommended-scss": "^4.2.0", + "stylelint-scss": "^3.17.2" + }, + "peerDependencies": { + "stylelint": "^13.0.0" + }, + "npmpackagejsonlint": { + "extends": "@wordpress/npm-package-json-lint-config", + "rules": { + "valid-values-license": [ + "error", + [ + "MIT" + ] + ] + } + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/stylelint-config/scss.js b/packages/stylelint-config/scss.js new file mode 100644 index 00000000000000..09940642b218b1 --- /dev/null +++ b/packages/stylelint-config/scss.js @@ -0,0 +1,36 @@ +'use strict'; + +module.exports = { + extends: [ './', 'stylelint-config-recommended-scss' ].map( + require.resolve + ), + + plugins: [ 'stylelint-scss' ], + + rules: { + // @wordpress/stylelint-config CSS overrides. + 'at-rule-empty-line-before': [ + 'always', + { + except: [ 'blockless-after-blockless' ], + ignore: [ 'after-comment' ], + ignoreAtRules: [ 'else' ], + }, + ], + + 'block-opening-brace-space-before': 'always', + 'block-closing-brace-newline-after': [ + 'always', + { + ignoreAtRules: [ 'if', 'else' ], + }, + ], + 'at-rule-name-space-after': 'always', + 'scss/at-else-closing-brace-newline-after': 'always-last-in-chain', + 'scss/at-else-closing-brace-space-after': 'always-intermediate', + 'scss/at-else-empty-line-before': 'never', + 'scss/at-if-closing-brace-newline-after': 'always-last-in-chain', + 'scss/at-if-closing-brace-space-after': 'always-intermediate', + 'scss/selector-no-redundant-nesting-selector': true, + }, +}; diff --git a/packages/stylelint-config/test/.stylelintrc.json b/packages/stylelint-config/test/.stylelintrc.json new file mode 100644 index 00000000000000..99a3abd90cbccb --- /dev/null +++ b/packages/stylelint-config/test/.stylelintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "stylelint-config-wordpress/scss", + "ignoreFiles": [ + "*-invalid.scss" + ] +} diff --git a/packages/stylelint-config/test/__snapshots__/commenting.js.snap b/packages/stylelint-config/test/__snapshots__/commenting.js.snap new file mode 100644 index 00000000000000..82a5c3efe8ff03 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/commenting.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid commenting css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 1, + "line": 9, + "rule": "comment-empty-line-before", + "severity": "error", + "text": "Expected empty line before comment (comment-empty-line-before)", + }, + Object { + "column": 1, + "line": 18, + "rule": "comment-empty-line-before", + "severity": "error", + "text": "Expected empty line before comment (comment-empty-line-before)", + }, + Object { + "column": 131, + "line": 24, + "rule": "max-line-length", + "severity": "error", + "text": "Expected line length to be no more than 80 characters (max-line-length)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/functions.js.snap b/packages/stylelint-config/test/__snapshots__/functions.js.snap new file mode 100644 index 00000000000000..0e75e70fcf7b49 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/functions.js.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid functions css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 9, + "line": 4, + "rule": "function-name-case", + "severity": "error", + "text": "Expected \\"Calc\\" to be \\"calc\\" (function-name-case)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/index.js.snap b/packages/stylelint-config/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000000..b0df67be5d2f93 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/index.js.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 7, + "line": 2, + "rule": "number-leading-zero", + "severity": "error", + "text": "Expected a leading zero (number-leading-zero)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/media-queries.js.snap b/packages/stylelint-config/test/__snapshots__/media-queries.js.snap new file mode 100644 index 00000000000000..e5f02f1c72b828 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/media-queries.js.snap @@ -0,0 +1,83 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid media queries css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 1, + "line": 31, + "rule": "at-rule-no-unknown", + "severity": "error", + "text": "Unexpected unknown at-rule \\"@mdia\\" (at-rule-no-unknown)", + }, + Object { + "column": 26, + "line": 1, + "rule": "media-feature-colon-space-after", + "severity": "error", + "text": "Expected single space after \\":\\" (media-feature-colon-space-after)", + }, + Object { + "column": 27, + "line": 6, + "rule": "media-feature-colon-space-after", + "severity": "error", + "text": "Expected single space after \\":\\" (media-feature-colon-space-after)", + }, + Object { + "column": 27, + "line": 6, + "rule": "media-feature-colon-space-before", + "severity": "error", + "text": "Unexpected whitespace before \\":\\" (media-feature-colon-space-before)", + }, + Object { + "column": 17, + "line": 11, + "rule": "media-feature-name-no-unknown", + "severity": "error", + "text": "Unexpected unknown media feature name \\"max-width 699px\\" (media-feature-name-no-unknown)", + }, + Object { + "column": 28, + "line": 16, + "rule": "media-feature-range-operator-space-after", + "severity": "error", + "text": "Expected single space after range operator (media-feature-range-operator-space-after)", + }, + Object { + "column": 29, + "line": 21, + "rule": "media-feature-range-operator-space-after", + "severity": "error", + "text": "Expected single space after range operator (media-feature-range-operator-space-after)", + }, + Object { + "column": 25, + "line": 16, + "rule": "media-feature-range-operator-space-before", + "severity": "error", + "text": "Expected single space before range operator (media-feature-range-operator-space-before)", + }, + Object { + "column": 25, + "line": 26, + "rule": "media-feature-range-operator-space-before", + "severity": "error", + "text": "Expected single space before range operator (media-feature-range-operator-space-before)", + }, + Object { + "column": 27, + "line": 36, + "rule": "media-query-list-comma-space-before", + "severity": "error", + "text": "Unexpected whitespace before \\",\\" (media-query-list-comma-space-before)", + }, + Object { + "column": 27, + "line": 40, + "rule": "media-query-list-comma-space-before", + "severity": "error", + "text": "Unexpected whitespace before \\",\\" (media-query-list-comma-space-before)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/properties.js.snap b/packages/stylelint-config/test/__snapshots__/properties.js.snap new file mode 100644 index 00000000000000..cb4c5a5bf2a9c4 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/properties.js.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid properties css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 13, + "line": 2, + "rule": "color-hex-case", + "severity": "error", + "text": "Expected \\"#FFFFFF\\" to be \\"#ffffff\\" (color-hex-case)", + }, + Object { + "column": 13, + "line": 2, + "rule": "color-hex-length", + "severity": "error", + "text": "Expected \\"#FFFFFF\\" to be \\"#FFF\\" (color-hex-length)", + }, + Object { + "column": 2, + "line": 5, + "rule": "declaration-block-no-shorthand-property-overrides", + "severity": "error", + "text": "Unexpected shorthand \\"margin\\" after \\"margin-left\\" (declaration-block-no-shorthand-property-overrides)", + }, + Object { + "column": 13, + "line": 2, + "rule": "declaration-colon-space-after", + "severity": "error", + "text": "Expected single space after \\":\\" with a single-line declaration (declaration-colon-space-after)", + }, + Object { + "column": 2, + "line": 6, + "rule": "property-no-unknown", + "severity": "error", + "text": "Unexpected unknown property \\"argin\\" (property-no-unknown)", + }, + Object { + "column": 15, + "line": 4, + "rule": "unit-case", + "severity": "error", + "text": "Expected \\"PX\\" to be \\"px\\" (unit-case)", + }, + Object { + "column": 11, + "line": 3, + "rule": "value-keyword-case", + "severity": "error", + "text": "Expected \\"BLOCK\\" to be \\"block\\" (value-keyword-case)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/selectors-scss.js.snap b/packages/stylelint-config/test/__snapshots__/selectors-scss.js.snap new file mode 100644 index 00000000000000..30e2617192d204 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/selectors-scss.js.snap @@ -0,0 +1,48 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid selectors scss snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 2, + "line": 3, + "rule": "scss/selector-no-redundant-nesting-selector", + "severity": "error", + "text": "Unnecessary nesting selector (&) (scss/selector-no-redundant-nesting-selector)", + }, + Object { + "column": 2, + "line": 10, + "rule": "scss/selector-no-redundant-nesting-selector", + "severity": "error", + "text": "Unnecessary nesting selector (&) (scss/selector-no-redundant-nesting-selector)", + }, + Object { + "column": 2, + "line": 17, + "rule": "scss/selector-no-redundant-nesting-selector", + "severity": "error", + "text": "Unnecessary nesting selector (&) (scss/selector-no-redundant-nesting-selector)", + }, + Object { + "column": 2, + "line": 24, + "rule": "scss/selector-no-redundant-nesting-selector", + "severity": "error", + "text": "Unnecessary nesting selector (&) (scss/selector-no-redundant-nesting-selector)", + }, + Object { + "column": 2, + "line": 31, + "rule": "scss/selector-no-redundant-nesting-selector", + "severity": "error", + "text": "Unnecessary nesting selector (&) (scss/selector-no-redundant-nesting-selector)", + }, + Object { + "column": 10, + "line": 31, + "rule": "selector-pseudo-element-colon-notation", + "severity": "error", + "text": "Expected double colon pseudo-element notation (selector-pseudo-element-colon-notation)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/selectors.js.snap b/packages/stylelint-config/test/__snapshots__/selectors.js.snap new file mode 100644 index 00000000000000..6debd6f6f38b0d --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/selectors.js.snap @@ -0,0 +1,62 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid selectors css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 15, + "line": 18, + "rule": "declaration-property-unit-whitelist", + "severity": "error", + "text": "Unexpected unit \\"%\\" for property \\"line-height\\" (declaration-property-unit-whitelist)", + }, + Object { + "column": 1, + "line": 25, + "rule": "selector-class-pattern", + "severity": "error", + "text": "Selector should use lowercase and separate words with hyphens (selector-class-pattern)", + }, + Object { + "column": 1, + "line": 1, + "rule": "selector-id-pattern", + "severity": "error", + "text": "Selector should use lowercase and separate words with hyphens (selector-id-pattern)", + }, + Object { + "column": 1, + "line": 5, + "rule": "selector-id-pattern", + "severity": "error", + "text": "Selector should use lowercase and separate words with hyphens (selector-id-pattern)", + }, + Object { + "column": 4, + "line": 9, + "rule": "selector-id-pattern", + "severity": "error", + "text": "Selector should use lowercase and separate words with hyphens (selector-id-pattern)", + }, + Object { + "column": 1, + "line": 21, + "rule": "selector-id-pattern", + "severity": "error", + "text": "Selector should use lowercase and separate words with hyphens (selector-id-pattern)", + }, + Object { + "column": 10, + "line": 29, + "rule": "selector-pseudo-element-colon-notation", + "severity": "error", + "text": "Expected double colon pseudo-element notation (selector-pseudo-element-colon-notation)", + }, + Object { + "column": 12, + "line": 17, + "rule": "string-quotes", + "severity": "error", + "text": "Expected double quotes (string-quotes)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/structure.js.snap b/packages/stylelint-config/test/__snapshots__/structure.js.snap new file mode 100644 index 00000000000000..45da6df9648187 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/structure.js.snap @@ -0,0 +1,62 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid structure css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 45, + "line": 7, + "rule": "block-closing-brace-newline-before", + "severity": "error", + "text": "Expected newline before \\"}\\" (block-closing-brace-newline-before)", + }, + Object { + "column": 14, + "line": 7, + "rule": "block-opening-brace-newline-after", + "severity": "error", + "text": "Expected newline after \\"{\\" (block-opening-brace-newline-after)", + }, + Object { + "column": 32, + "line": 7, + "rule": "declaration-block-semicolon-newline-after", + "severity": "error", + "text": "Expected newline after \\";\\" (declaration-block-semicolon-newline-after)", + }, + Object { + "column": 12, + "line": 1, + "rule": "selector-list-comma-newline-after", + "severity": "error", + "text": "Expected newline after \\",\\" (selector-list-comma-newline-after)", + }, + Object { + "column": 25, + "line": 1, + "rule": "selector-list-comma-newline-after", + "severity": "error", + "text": "Expected newline after \\",\\" (selector-list-comma-newline-after)", + }, + Object { + "column": 3, + "line": 4, + "rule": "indentation", + "severity": "error", + "text": "Expected indentation of 0 tabs (indentation)", + }, + Object { + "column": 3, + "line": 2, + "rule": "indentation", + "severity": "error", + "text": "Expected indentation of 1 tab (indentation)", + }, + Object { + "column": 3, + "line": 3, + "rule": "indentation", + "severity": "error", + "text": "Expected indentation of 1 tab (indentation)", + }, +] +`; diff --git a/packages/stylelint-config/test/__snapshots__/values.js.snap b/packages/stylelint-config/test/__snapshots__/values.js.snap new file mode 100644 index 00000000000000..20c229db69e230 --- /dev/null +++ b/packages/stylelint-config/test/__snapshots__/values.js.snap @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flags warnings with invalid values css snapshot matches warnings 1`] = ` +Array [ + Object { + "column": 16, + "line": 2, + "rule": "declaration-block-trailing-semicolon", + "severity": "error", + "text": "Expected a trailing semicolon (declaration-block-trailing-semicolon)", + }, + Object { + "column": 13, + "line": 2, + "rule": "declaration-colon-space-after", + "severity": "error", + "text": "Expected single space after \\":\\" with a single-line declaration (declaration-colon-space-after)", + }, + Object { + "column": 15, + "line": 12, + "rule": "declaration-property-unit-whitelist", + "severity": "error", + "text": "Unexpected unit \\"em\\" for property \\"line-height\\" (declaration-property-unit-whitelist)", + }, + Object { + "column": 15, + "line": 10, + "rule": "font-family-name-quotes", + "severity": "error", + "text": "Expected quotes around \\"Times New Roman\\" (font-family-name-quotes)", + }, + Object { + "column": 15, + "line": 11, + "rule": "font-weight-notation", + "severity": "error", + "text": "Expected numeric font-weight notation (font-weight-notation)", + }, + Object { + "column": 11, + "line": 6, + "rule": "length-zero-no-unit", + "severity": "error", + "text": "Unexpected unit (length-zero-no-unit)", + }, + Object { + "column": 15, + "line": 6, + "rule": "length-zero-no-unit", + "severity": "error", + "text": "Unexpected unit (length-zero-no-unit)", + }, + Object { + "column": 24, + "line": 6, + "rule": "length-zero-no-unit", + "severity": "error", + "text": "Unexpected unit (length-zero-no-unit)", + }, + Object { + "column": 1, + "line": 15, + "rule": "no-duplicate-selectors", + "severity": "error", + "text": "Unexpected duplicate selector \\".selector\\", first used at line 1 (no-duplicate-selectors)", + }, +] +`; diff --git a/packages/stylelint-config/test/commenting-invalid.css b/packages/stylelint-config/test/commenting-invalid.css new file mode 100644 index 00000000000000..192f8ceae6036c --- /dev/null +++ b/packages/stylelint-config/test/commenting-invalid.css @@ -0,0 +1,24 @@ +/** +* #.# Section title +* +* Description of section, whether or not it has media queries, etc. +*/ +.selector { + float: left; +} +/** +* #.# Another section title +* +* Description of section, whether or not it has media queries, long comments +* should manually break the line length at 80 characters. +*/ +.another-selector { + float: right; +} +/* This is a comment about this selector */ +.one-more-another-selector { + position: absolute; + top: 0 !important; /* I should explain why this is so !important */ +} + +/* Comments shouldn't have a line length greater than 80 characters, they should manually break the line length at 80 characters */ diff --git a/packages/stylelint-config/test/commenting-valid.css b/packages/stylelint-config/test/commenting-valid.css new file mode 100644 index 00000000000000..e145e49471c7d9 --- /dev/null +++ b/packages/stylelint-config/test/commenting-valid.css @@ -0,0 +1,29 @@ +/** +* #.# Section title +* +* Description of section, whether or not it has media queries, etc. +*/ + +.selector { + float: left; +} + + +/** +* #.# Another section title +* +* Description of section, whether or not it has media queries, long comments +* should manually break the line length at 80 characters. +*/ + +.another-selector { + float: right; +} + +/* This is a comment about this selector */ +.one-more-selector { + position: absolute; + top: 0 !important; /* I should explain why this is so !important */ +} + +/* Long comments should manually break the line length at 80 characters. */ diff --git a/packages/stylelint-config/test/commenting.js b/packages/stylelint-config/test/commenting.js new file mode 100644 index 00000000000000..1a23a47434fc10 --- /dev/null +++ b/packages/stylelint-config/test/commenting.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/commenting-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/commenting-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid commenting css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid commenting css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 3 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/css-invalid.css b/packages/stylelint-config/test/css-invalid.css new file mode 100644 index 00000000000000..9b98086cd5f687 --- /dev/null +++ b/packages/stylelint-config/test/css-invalid.css @@ -0,0 +1,3 @@ +a { + top: .2em; +} diff --git a/packages/stylelint-config/test/css-valid.css b/packages/stylelint-config/test/css-valid.css new file mode 100644 index 00000000000000..363d12aed3ed66 --- /dev/null +++ b/packages/stylelint-config/test/css-valid.css @@ -0,0 +1,3 @@ +a { + top: 0.2em; +} diff --git a/packages/stylelint-config/test/functions-invalid.css b/packages/stylelint-config/test/functions-invalid.css new file mode 100644 index 00000000000000..33a93985335cf0 --- /dev/null +++ b/packages/stylelint-config/test/functions-invalid.css @@ -0,0 +1,5 @@ +/* function-name-case */ + +a { + width: Calc(5% - 10em); +} diff --git a/packages/stylelint-config/test/functions-valid.css b/packages/stylelint-config/test/functions-valid.css new file mode 100644 index 00000000000000..8219b38b2005c8 --- /dev/null +++ b/packages/stylelint-config/test/functions-valid.css @@ -0,0 +1,7 @@ +/* function-name-case */ + +a { + width: calc(5% - 10em); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#1e8cbe", endColorstr="#0074a2", GradientType=0); + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=100); +} diff --git a/packages/stylelint-config/test/functions.js b/packages/stylelint-config/test/functions.js new file mode 100644 index 00000000000000..38b0fbf37a3a87 --- /dev/null +++ b/packages/stylelint-config/test/functions.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/functions-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/functions-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid functions css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid functions css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 1 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/index.js b/packages/stylelint-config/test/index.js new file mode 100644 index 00000000000000..dfc857e8a45041 --- /dev/null +++ b/packages/stylelint-config/test/index.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/css-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/css-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 1 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/media-queries-invalid.css b/packages/stylelint-config/test/media-queries-invalid.css new file mode 100644 index 00000000000000..c89a2776bb807b --- /dev/null +++ b/packages/stylelint-config/test/media-queries-invalid.css @@ -0,0 +1,43 @@ +@media all and (max-width:699px) { + + /* Your selectors */ +} + +@media all and (max-width :699px) { + + /* Your selectors */ +} + +@media all and (max-width 699px) { + + /* Your selectors */ +} + +@media all and (max-width>=699px) { + + /* Your selectors */ +} + +@media all and (max-width >=699px) { + + /* Your selectors */ +} + +@media all and (max-width>= 699px) { + + /* Your selectors */ +} + +@mdia all and (max-width>= 699px) { + + /* Your selectors */ +} + +@media screen and (color) , projection and (color) { + top: 0.2em; +} + +@media screen and (color) , + projection and (color) { + top: 0.2em; +} diff --git a/packages/stylelint-config/test/media-queries-valid.css b/packages/stylelint-config/test/media-queries-valid.css new file mode 100644 index 00000000000000..b373e6d8f15369 --- /dev/null +++ b/packages/stylelint-config/test/media-queries-valid.css @@ -0,0 +1,13 @@ +@media all and (max-width: 699px) and (min-width: 520px) { + + /* Your selectors */ +} + +@media screen and (color), + projection and (color) { + top: 0.2em; +} + +@media screen and (color), projection and (color) { + top: 0.2em; +} diff --git a/packages/stylelint-config/test/media-queries.js b/packages/stylelint-config/test/media-queries.js new file mode 100644 index 00000000000000..a3b59aa0fb5413 --- /dev/null +++ b/packages/stylelint-config/test/media-queries.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/media-queries-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/media-queries-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid media queries css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid media queries css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 11 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/properties-invalid.css b/packages/stylelint-config/test/properties-invalid.css new file mode 100644 index 00000000000000..336b739f753b63 --- /dev/null +++ b/packages/stylelint-config/test/properties-invalid.css @@ -0,0 +1,7 @@ +#selector-1 { + background:#FFFFFF; + display: BLOCK; + margin-left: 20PX; + margin: 0; + argin: 20px; +} diff --git a/packages/stylelint-config/test/properties-valid.css b/packages/stylelint-config/test/properties-valid.css new file mode 100644 index 00000000000000..0fffa37ca44493 --- /dev/null +++ b/packages/stylelint-config/test/properties-valid.css @@ -0,0 +1,6 @@ +#selector-1 { + background: #fff; + display: block; + margin: 0; + margin-left: 20px; +} diff --git a/packages/stylelint-config/test/properties.js b/packages/stylelint-config/test/properties.js new file mode 100644 index 00000000000000..35cedc7697515d --- /dev/null +++ b/packages/stylelint-config/test/properties.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/properties-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/properties-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid properties css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid properties css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 7 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/scss-invalid.scss b/packages/stylelint-config/test/scss-invalid.scss new file mode 100644 index 00000000000000..c73e35ab61a25a --- /dev/null +++ b/packages/stylelint-config/test/scss-invalid.scss @@ -0,0 +1,32 @@ +@unknown { + display: block; +} + +a { + + @debug 1; +} + +@if $foo == block { + display: block; +} + +@else{ + display: inline-block; +} + +b { + + @include foo; + + @include bar; +} + +p { + + /* Test `stylelint-config-recommended` inherited `no-extra-semicolons` rule */ + @include foo;; + + /* Test `stylelint-config-wordpress` inherited `number-leading-zero` rule */ + top: .2em; +} diff --git a/packages/stylelint-config/test/scss-valid.scss b/packages/stylelint-config/test/scss-valid.scss new file mode 100644 index 00000000000000..e424c7cfe37a49 --- /dev/null +++ b/packages/stylelint-config/test/scss-valid.scss @@ -0,0 +1,32 @@ +@import "path/to/foo.scss"; + +@function fooBar { + + @return 1; +} + +@mixin foo { + + @content; +} + +$map: ( + "foo": 1, + "bar": 2, + "baz": 3 +); + +@if $foo == block { + display: block; +} @else { + display: inline-block; +} + +@import "../some/url"; +@import "../another/url"; + +b { + + @include foo; + @include bar; +} diff --git a/packages/stylelint-config/test/scss.js b/packages/stylelint-config/test/scss.js new file mode 100644 index 00000000000000..c64537ee07e6b9 --- /dev/null +++ b/packages/stylelint-config/test/scss.js @@ -0,0 +1,67 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../scss' ), + validScss = fs.readFileSync( + './packages/stylelint-config/test/scss-valid.scss', + 'utf-8' + ), + invalidScss = fs.readFileSync( + './packages/stylelint-config/test/scss-invalid.scss', + 'utf-8' + ); + +describe( 'flags no warnings with valid scss', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validScss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid scss', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidScss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 8 ) + ); + } ); + + // ToDo: Fix snapshot, as results differ between Node.js v10 & v12 + // it( 'snapshot matches warnings', () => { + // return result.then( ( data ) => ( + // expect( data.results[ 0 ].warnings ).toMatchSnapshot() + // ) ); + // } ); +} ); diff --git a/packages/stylelint-config/test/selectors-invalid.css b/packages/stylelint-config/test/selectors-invalid.css new file mode 100644 index 00000000000000..bf0716916420ff --- /dev/null +++ b/packages/stylelint-config/test/selectors-invalid.css @@ -0,0 +1,31 @@ +#commentForm { /* Avoid camelcase. */ + margin: 0; +} + +#comment_form { /* Avoid underscores. */ + margin: 0; +} + +div#comment_form { /* Avoid over-qualification. */ + margin: 0; +} + +#c1-xr { /* What is a c1-xr?! Use a better name. */ + margin: 0; +} + +input[type='text'] { /* Should be [type="text"] */ + line-height: 110% /* Also doubly incorrect */ +} + +#Selector { + color: #000; +} + +.selectorA { + color: #000; +} + +.selector:after { + color: #000; +} diff --git a/packages/stylelint-config/test/selectors-invalid.scss b/packages/stylelint-config/test/selectors-invalid.scss new file mode 100644 index 00000000000000..d1bb44f841dbac --- /dev/null +++ b/packages/stylelint-config/test/selectors-invalid.scss @@ -0,0 +1,34 @@ +.foo { + + & > .bar { + margin: 0; + } +} + +a { + + & a { + margin: 0; + } +} + +div { + + & > a { + margin: 0; + } +} + +p { + + & .class { + margin: 0; + } +} + +span { + + & .class:after { + margin: 0; + } +} diff --git a/packages/stylelint-config/test/selectors-scss.js b/packages/stylelint-config/test/selectors-scss.js new file mode 100644 index 00000000000000..94a85ff86543e0 --- /dev/null +++ b/packages/stylelint-config/test/selectors-scss.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../scss' ), + validScss = fs.readFileSync( + './packages/stylelint-config/test/selectors-valid.scss', + 'utf-8' + ), + invalidScss = fs.readFileSync( + './packages/stylelint-config/test/selectors-invalid.scss', + 'utf-8' + ); + +describe( 'flags no warnings with valid selectors scss', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validScss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid selectors scss', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidScss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 6 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/selectors-valid.css b/packages/stylelint-config/test/selectors-valid.css new file mode 100644 index 00000000000000..19a87ff51f35d8 --- /dev/null +++ b/packages/stylelint-config/test/selectors-valid.css @@ -0,0 +1,19 @@ +#comment-form { + margin: 1em 0; +} + +input[type="text"] { + line-height: 1.1; +} + +.selector::after { + color: #000; +} + +.selector-class { + color: #000; +} + +#selector-id { + color: #000; +} diff --git a/packages/stylelint-config/test/selectors-valid.scss b/packages/stylelint-config/test/selectors-valid.scss new file mode 100644 index 00000000000000..a6d4db9172be4c --- /dev/null +++ b/packages/stylelint-config/test/selectors-valid.scss @@ -0,0 +1,37 @@ +.foo { + + > .bar { + margin: 0; + } +} + +a { + + &.foo { + margin: 0; + } +} + +div { + + .foo > & { + margin: 0; + } +} + +p { + + &, + .foo, + .baz { + margin: 0; + } +} + +span { + + &, + .foo::after { + color: #000; + } +} diff --git a/packages/stylelint-config/test/selectors.js b/packages/stylelint-config/test/selectors.js new file mode 100644 index 00000000000000..337d1d00eed311 --- /dev/null +++ b/packages/stylelint-config/test/selectors.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/selectors-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/selectors-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid selectors css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid selectors css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 8 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/structure-invalid.css b/packages/stylelint-config/test/structure-invalid.css new file mode 100644 index 00000000000000..78820847ae9d89 --- /dev/null +++ b/packages/stylelint-config/test/structure-invalid.css @@ -0,0 +1,7 @@ +#selector-1, #selector-2, #selector-3 { + background: #fff; + color: #000; + } + + +#selector-1 { background: #fff; color: #000; } diff --git a/packages/stylelint-config/test/structure-valid.css b/packages/stylelint-config/test/structure-valid.css new file mode 100644 index 00000000000000..b7b28949f3cd52 --- /dev/null +++ b/packages/stylelint-config/test/structure-valid.css @@ -0,0 +1,29 @@ +#selector-1, +#selector-2, +#selector-3 { + background: #fff; + color: #000; +} + +#selector-4 { + background: #fff; + color: #000; +} + +h1, +.heading-size-1 { + background: #fff; + color: #000; +} + +h2, +.heading-size-2 { + background: #fff; + color: #000; +} + +h3, +.heading-size-3 { + background: #fff; + color: #000; +} diff --git a/packages/stylelint-config/test/structure.js b/packages/stylelint-config/test/structure.js new file mode 100644 index 00000000000000..7ec03a3b667bac --- /dev/null +++ b/packages/stylelint-config/test/structure.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/structure-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/structure-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid structure css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid structure css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 8 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/themes-valid.css b/packages/stylelint-config/test/themes-valid.css new file mode 100644 index 00000000000000..de9a2fb8193a6c --- /dev/null +++ b/packages/stylelint-config/test/themes-valid.css @@ -0,0 +1,16 @@ +/* +Theme Name: Twenty Ten +Theme URI: https://wordpress.org/themes/twentyten/themes/twentyten/themes/twentyten/themes/twentyten/ +Description: The 2010 theme for WordPress is stylish, customizable, simple, and readable -- make it yours with a custom menu, header image, and background. Twenty Ten supports six widgetized areas (two in the sidebar, four in the footer) and featured images (thumbnails for gallery posts and custom header images for posts and pages). It includes stylesheets for print and the admin Visual Editor, special styles for posts in the "Asides" and "Gallery" categories, and has an optional one-column page template that removes the sidebar. +Author: the WordPress team +Author URI: https://wordpress.org/ +Version: 2.3 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Tags: blog, two-columns, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style, custom-menu, flexible-header, featured-images, footer-widgets, featured-image-header +Text Domain: twentyten +*/ + +a { + top: 0.2em; +} diff --git a/packages/stylelint-config/test/themes.js b/packages/stylelint-config/test/themes.js new file mode 100644 index 00000000000000..f0016832b24d7b --- /dev/null +++ b/packages/stylelint-config/test/themes.js @@ -0,0 +1,35 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/themes-valid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); diff --git a/packages/stylelint-config/test/values-invalid.css b/packages/stylelint-config/test/values-invalid.css new file mode 100644 index 00000000000000..d9ce259e58c8c0 --- /dev/null +++ b/packages/stylelint-config/test/values-invalid.css @@ -0,0 +1,17 @@ +.selector { /* Avoid missing space and semicolon */ + background:#fff +} + +.another-selector { /* Avoid adding a unit on a zero value */ + margin: 0px 0px 20px 0px; +} + +.one-more-selector { + font-family: Times New Roman, serif; /* Quote font names when required */ + font-weight: bold; /* Avoid named font weights */ + line-height: 1.4em; +} + +.selector { /* Avoid duplicate selectors */ + background: #fff; +} diff --git a/packages/stylelint-config/test/values-valid.css b/packages/stylelint-config/test/values-valid.css new file mode 100644 index 00000000000000..ca9ccb5f188c29 --- /dev/null +++ b/packages/stylelint-config/test/values-valid.css @@ -0,0 +1,15 @@ +.selector { /* Correct usage of quotes */ + background-image: url(images/bg.png); + font-family: "Helvetica Neue", sans-serif; + font-weight: 700; + line-height: 14px; +} + +.another-selector { /* Correct usage of zero values */ + font-family: Georgia, serif; + font-weight: bolder; /* Ignore relative font weights */ + line-height: 1.4; + text-shadow: + 0 -1px 0 rgba(0, 0, 0, 0.5), + 0 1px 0 #fff; +} diff --git a/packages/stylelint-config/test/values.js b/packages/stylelint-config/test/values.js new file mode 100644 index 00000000000000..97cbc58e02f3b4 --- /dev/null +++ b/packages/stylelint-config/test/values.js @@ -0,0 +1,66 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/values-valid.css', + 'utf-8' + ), + invalidCss = fs.readFileSync( + './packages/stylelint-config/test/values-invalid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid values css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); + +describe( 'flags warnings with invalid values css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: invalidCss, + config, + } ); + } ); + + it( 'did error', () => { + return result.then( ( data ) => expect( data.errored ).toBeTruthy() ); + } ); + + it( 'flags correct number of warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 9 ) + ); + } ); + + it( 'snapshot matches warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toMatchSnapshot() + ); + } ); +} ); diff --git a/packages/stylelint-config/test/vendor-prefixes-valid.css b/packages/stylelint-config/test/vendor-prefixes-valid.css new file mode 100644 index 00000000000000..e46698570d9ffd --- /dev/null +++ b/packages/stylelint-config/test/vendor-prefixes-valid.css @@ -0,0 +1,5 @@ +.sample-output { + -webkit-box-shadow: inset 0 0 1px 1px #eee; + -moz-box-shadow: inset 0 0 1px 1px #eee; + box-shadow: inset 0 0 1px 1px #eee; +} diff --git a/packages/stylelint-config/test/vendor-prefixes.js b/packages/stylelint-config/test/vendor-prefixes.js new file mode 100644 index 00000000000000..e3ec4d2a7e5dfc --- /dev/null +++ b/packages/stylelint-config/test/vendor-prefixes.js @@ -0,0 +1,35 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ), + stylelint = require( 'stylelint' ); + +/** + * Internal dependencies + */ +const config = require( '../' ), + validCss = fs.readFileSync( + './packages/stylelint-config/test/vendor-prefixes-valid.css', + 'utf-8' + ); + +describe( 'flags no warnings with valid vendor prefixes css', () => { + let result; + + beforeEach( () => { + result = stylelint.lint( { + code: validCss, + config, + } ); + } ); + + it( 'did not error', () => { + return result.then( ( data ) => expect( data.errored ).toBeFalsy() ); + } ); + + it( 'flags no warnings', () => { + return result.then( ( data ) => + expect( data.results[ 0 ].warnings ).toHaveLength( 0 ) + ); + } ); +} ); diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md index e31ef4fedde793..7dc8a515a74b0a 100644 --- a/packages/url/CHANGELOG.md +++ b/packages/url/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Feature + +- Add optional argument `maxLength` for truncating URL in `filterURLForDisplay` + ## 2.16.0 (2020-06-15) ### New Feature diff --git a/packages/url/README.md b/packages/url/README.md index c0df7acf89e227..d369f6ed7cd62d 100644 --- a/packages/url/README.md +++ b/packages/url/README.md @@ -96,11 +96,13 @@ _Usage_ ```js const displayUrl = filterURLForDisplay( 'https://www.wordpress.org/gutenberg/' ); // wordpress.org/gutenberg +const imageUrl = filterURLForDisplay( 'https://www.wordpress.org/wp-content/uploads/img.png', 20 ); // …ent/uploads/img.png ``` _Parameters_ - _url_ `string`: Original URL. +- _maxLength_ `(number|null)`: URL length. _Returns_ diff --git a/packages/url/src/filter-url-for-display.js b/packages/url/src/filter-url-for-display.js index 978594aced536c..fd3eccc99cbf74 100644 --- a/packages/url/src/filter-url-for-display.js +++ b/packages/url/src/filter-url-for-display.js @@ -2,22 +2,53 @@ * Returns a URL for display. * * @param {string} url Original URL. + * @param {number|null} maxLength URL length. * * @example * ```js * const displayUrl = filterURLForDisplay( 'https://www.wordpress.org/gutenberg/' ); // wordpress.org/gutenberg + * const imageUrl = filterURLForDisplay( 'https://www.wordpress.org/wp-content/uploads/img.png', 20 ); // …ent/uploads/img.png * ``` * * @return {string} Displayed URL. */ -export function filterURLForDisplay( url ) { +export function filterURLForDisplay( url, maxLength = null ) { // Remove protocol and www prefixes. - const filteredURL = url.replace( /^(?:https?:)\/\/(?:www\.)?/, '' ); + let filteredURL = url.replace( /^(?:https?:)\/\/(?:www\.)?/, '' ); // Ends with / and only has that single slash, strip it. if ( filteredURL.match( /^[^\/]+\/$/ ) ) { - return filteredURL.replace( '/', '' ); + filteredURL = filteredURL.replace( '/', '' ); } - return filteredURL; + const mediaRegexp = /([\w|:])*\.(?:jpg|jpeg|gif|png|svg)/; + + if ( + ! maxLength || + filteredURL.length <= maxLength || + ! filteredURL.match( mediaRegexp ) + ) { + return filteredURL; + } + + // If the file is not greater than max length, return last portion of URL. + filteredURL = filteredURL.split( '?' )[ 0 ]; + const urlPieces = filteredURL.split( '/' ); + const file = urlPieces[ urlPieces.length - 1 ]; + if ( file.length <= maxLength ) { + return '…' + filteredURL.slice( -maxLength ); + } + + // If the file is greater than max length, truncate the file. + const index = file.lastIndexOf( '.' ); + const [ fileName, extension ] = [ + file.slice( 0, index ), + file.slice( index + 1 ), + ]; + const truncatedFile = fileName.slice( -3 ) + '.' + extension; + return ( + file.slice( 0, maxLength - truncatedFile.length - 1 ) + + '…' + + truncatedFile + ); } diff --git a/packages/url/src/remove-query-args.js b/packages/url/src/remove-query-args.js index 8d2ac9757ae305..07fd5467808e00 100644 --- a/packages/url/src/remove-query-args.js +++ b/packages/url/src/remove-query-args.js @@ -26,5 +26,6 @@ export function removeQueryArgs( url, ...args ) { const query = getQueryArgs( url ); const baseURL = url.substr( 0, queryStringIndex ); args.forEach( ( arg ) => delete query[ arg ] ); - return baseURL + '?' + buildQueryString( query ); + const queryString = buildQueryString( query ); + return queryString ? baseURL + '?' + queryString : baseURL; } diff --git a/packages/url/src/test/index.test.js b/packages/url/src/test/index.test.js index 9a2eddc478a551..f4814b0b0bc83b 100644 --- a/packages/url/src/test/index.test.js +++ b/packages/url/src/test/index.test.js @@ -758,6 +758,14 @@ describe( 'removeQueryArgs', () => { ); } ); + it( 'should not leave ? char after removing all query args', () => { + const url = 'https://andalouses.example/beach?foo=bar&bar=baz'; + + expect( removeQueryArgs( url, 'foo', 'bar' ) ).toEqual( + 'https://andalouses.example/beach' + ); + } ); + it( 'should remove array query arg', () => { const url = 'https://andalouses.example/beach?foo[]=bar&foo[]=baz&bar=foobar'; @@ -876,6 +884,54 @@ describe( 'filterURLForDisplay', () => { const url = filterURLForDisplay( 'http://www.wordpress.org/something' ); expect( url ).toBe( 'wordpress.org/something' ); } ); + it( 'should preserve the original url if no argument max length', () => { + const url = filterURLForDisplay( + 'http://www.wordpress.org/wp-content/uploads/myimage.jpg' + ); + expect( url ).toBe( 'wordpress.org/wp-content/uploads/myimage.jpg' ); + } ); + it( 'should preserve the original url if the url is short enough', () => { + const url = filterURLForDisplay( + 'http://www.wordpress.org/ig.jpg', + 20 + ); + expect( url ).toBe( 'wordpress.org/ig.jpg' ); + } ); + it( 'should return ellipsis, upper level pieces url, and filename when the url is long enough but filename is short enough', () => { + const url = filterURLForDisplay( + 'http://www.wordpress.org/wp-content/uploads/myimage.jpg', + 20 + ); + expect( url ).toBe( '…/uploads/myimage.jpg' ); + } ); + it( 'should return filename split by ellipsis plus three characters when filename is long enough', () => { + const url = filterURLForDisplay( + 'http://www.wordpress.org/wp-content/uploads/superlongtitlewithextension.jpeg', + 20 + ); + expect( url ).toBe( 'superlongti…ion.jpeg' ); + } ); + it( 'should remove query arguments', () => { + const url = filterURLForDisplay( + 'http://www.wordpress.org/wp-content/uploads/myimage.jpeg?query_args=a', + 20 + ); + expect( url ).toBe( '…uploads/myimage.jpeg' ); + } ); + it( 'should preserve the original url when it is not a file', () => { + const url = filterURLForDisplay( + 'http://www.wordpress.org/wp-content/url/', + 20 + ); + expect( url ).toBe( 'wordpress.org/wp-content/url/' ); + } ); + it( 'should return file split by ellipsis when the file name has multiple periods', () => { + const url = filterURLForDisplay( + 'http://www.wordpress.org/wp-content/uploads/filename.2020.12.20.png', + 20 + ); + expect( url ).toBe( 'filename.202….20.png' ); + } ); } ); describe( 'cleanForSlug', () => { diff --git a/phpunit/class-register-block-type-from-metadata-test.php b/phpunit/class-register-block-type-from-metadata-test.php deleted file mode 100644 index 6b4a6d8f063c27..00000000000000 --- a/phpunit/class-register-block-type-from-metadata-test.php +++ /dev/null @@ -1,216 +0,0 @@ -assertSame( 'script-handle', $result ); - } - - function test_removes_block_asset_path_prefix() { - $result = remove_block_asset_path_prefix( 'file:./block.js' ); - - $this->assertSame( './block.js', $result ); - } - - function test_generate_block_asset_handle() { - $block_name = 'unit-tests/my-block'; - - $this->assertSame( - 'unit-tests-my-block-editor-script', - generate_block_asset_handle( $block_name, 'editorScript' ) - ); - $this->assertSame( - 'unit-tests-my-block-script', - generate_block_asset_handle( $block_name, 'script' ) - ); - $this->assertSame( - 'unit-tests-my-block-editor-style', - generate_block_asset_handle( $block_name, 'editorStyle' ) - ); - $this->assertSame( - 'unit-tests-my-block-style', - generate_block_asset_handle( $block_name, 'style' ) - ); - } - - function test_field_not_found_register_block_script_handle() { - $result = register_block_script_handle( array(), 'script' ); - - $this->assertFalse( $result ); - } - - function test_empty_value_register_block_script_handle() { - $metadata = array( 'script' => '' ); - $result = register_block_script_handle( $metadata, 'script' ); - - $this->assertFalse( $result ); - } - - /** - * @expectedIncorrectUsage register_block_script_handle - */ - function test_missing_asset_file_register_block_script_handle() { - $metadata = array( - 'file' => __FILE__, - 'name' => 'unit-tests/test-block', - 'script' => 'file:./fixtures/missing-asset.js', - ); - $result = register_block_script_handle( $metadata, 'script' ); - - $this->assertFalse( $result ); - } - - function test_handle_passed_register_block_script_handle() { - $metadata = array( - 'editorScript' => 'test-script-handle', - ); - $result = register_block_script_handle( $metadata, 'editorScript' ); - - $this->assertSame( 'test-script-handle', $result ); - } - - function test_success_register_block_script_handle() { - $metadata = array( - 'file' => __FILE__, - 'name' => 'unit-tests/test-block', - 'script' => 'file:./fixtures/block.js', - ); - $result = register_block_script_handle( $metadata, 'script' ); - - $this->assertSame( 'unit-tests-test-block-script', $result ); - } - - function test_field_not_found_register_block_style_handle() { - $result = register_block_style_handle( array(), 'style' ); - - $this->assertFalse( $result ); - } - - function test_empty_value_found_register_block_style_handle() { - $metadata = array( 'style' => '' ); - $result = register_block_style_handle( $metadata, 'style' ); - - $this->assertFalse( $result ); - } - - function test_handle_passed_register_block_style_handle() { - $metadata = array( - 'style' => 'test-style-handle', - ); - $result = register_block_style_handle( $metadata, 'style' ); - - $this->assertSame( 'test-style-handle', $result ); - } - - function test_success_register_block_style_handle() { - $metadata = array( - 'file' => __FILE__, - 'name' => 'unit-tests/test-block', - 'style' => 'file:./fixtures/block.css', - ); - $result = register_block_style_handle( $metadata, 'style' ); - - $this->assertSame( 'unit-tests-test-block-style', $result ); - } - - /** - * Tests that the function returns false when the `block.json` is not found - * in the WordPress core. - */ - function test_metadata_not_found_in_wordpress_core() { - $result = register_block_type_from_metadata( 'unknown' ); - - $this->assertFalse( $result ); - } - - /** - * Tests that the function returns false when the `block.json` is not found - * in the current directory. - */ - function test_metadata_not_found_in_the_current_directory() { - $result = register_block_type_from_metadata( __DIR__ ); - - $this->assertFalse( $result ); - } - - /** - * Tests that the function returns the registered block when the `block.json` - * is found in the fixtures directory. - */ - function test_block_registers_with_metadata_fixture() { - $result = register_block_type_from_metadata( - __DIR__ . '/fixtures' - ); - - $this->assertInstanceOf( 'WP_Block_Type', $result ); - $this->assertSame( 'my-plugin/notice', $result->name ); - $this->assertSame( 'Notice', $result->title ); - $this->assertSame( 'common', $result->category ); - $this->assertEqualSets( array( 'core/group' ), $result->parent ); - $this->assertSame( 'star', $result->icon ); - $this->assertSame( 'Shows warning, error or success notices…', $result->description ); - $this->assertEqualSets( array( 'alert', 'message' ), $result->keywords ); - $this->assertEquals( - array( - 'message' => array( - 'type' => 'string', - 'source' => 'html', - 'selector' => '.message', - ), - ), - $result->attributes - ); - $this->assertEquals( - array( - 'my-plugin/message' => 'message', - ), - $result->provides_context - ); - $this->assertEqualSets( array( 'groupId' ), $result->uses_context ); - $this->assertEquals( - array( - 'align' => true, - ), - $result->supports - ); - $this->assertEquals( - array( - array( - 'name' => 'default', - 'label' => 'Default', - 'isDefault' => true, - ), - array( - 'name' => 'other', - 'label' => 'Other', - ), - ), - $result->styles - ); - $this->assertEquals( - array( - 'attributes' => array( - 'message' => 'This is a notice!', - ), - ), - $result->example - ); - $this->assertSame( 'my-plugin-notice-editor-script', $result->editor_script ); - $this->assertSame( 'my-plugin-notice-script', $result->script ); - $this->assertSame( 'my-plugin-notice-editor-style', $result->editor_style ); - $this->assertSame( 'my-plugin-notice-style', $result->style ); - } -} diff --git a/phpunit/class-wp-block-list-test.php b/phpunit/class-wp-block-list-test.php deleted file mode 100644 index 5f0d98d5b1afe0..00000000000000 --- a/phpunit/class-wp-block-list-test.php +++ /dev/null @@ -1,100 +0,0 @@ -registry = new WP_Block_Type_Registry(); - $this->registry->register( 'core/example', array() ); - } - - /** - * Tear down each test method. - */ - public function tearDown() { - parent::tearDown(); - - $this->registry = null; - } - - function test_array_access() { - $parsed_blocks = parse_blocks( '' ); - $context = array(); - $blocks = new WP_Block_List( $parsed_blocks, $context, $this->registry ); - - // Test "offsetExists". - $this->assertTrue( isset( $blocks[0] ) ); - - // Test "offsetGet". - $this->assertEquals( 'core/example', $blocks[0]->name ); - - // Test "offsetSet". - $parsed_blocks[0]['blockName'] = 'core/updated'; - $blocks[0] = new WP_Block( $parsed_blocks[0], $context, $this->registry ); - $this->assertEquals( 'core/updated', $blocks[0]->name ); - - // Test "offsetUnset". - unset( $blocks[0] ); - $this->assertFalse( isset( $blocks[0] ) ); - } - - function test_iterable() { - $parsed_blocks = parse_blocks( '' ); - $context = array(); - $blocks = new WP_Block_List( $parsed_blocks, $context, $this->registry ); - $assertions = 0; - - foreach ( $blocks as $block ) { - $this->assertEquals( 'core/example', $block->name ); - $assertions++; - foreach ( $block->inner_blocks as $inner_block ) { - $this->assertEquals( 'core/example', $inner_block->name ); - $assertions++; - } - } - - $blocks->rewind(); - while ( $blocks->valid() ) { - $key = $blocks->key(); - $block = $blocks->current(); - $this->assertEquals( 0, $key ); - $assertions++; - $this->assertEquals( 'core/example', $block->name ); - $assertions++; - $blocks->next(); - } - - $this->assertEquals( 4, $assertions ); - } - - function test_countable() { - $parsed_blocks = parse_blocks( '' ); - $context = array(); - $blocks = new WP_Block_List( $parsed_blocks, $context, $this->registry ); - - $this->assertEquals( 1, count( $blocks ) ); - } - -} diff --git a/phpunit/class-wp-block-test.php b/phpunit/class-wp-block-test.php deleted file mode 100644 index 3c7752118d09af..00000000000000 --- a/phpunit/class-wp-block-test.php +++ /dev/null @@ -1,355 +0,0 @@ -registry = new WP_Block_Type_Registry(); - } - - /** - * Tear down each test method. - */ - public function tearDown() { - parent::tearDown(); - - $this->registry = null; - } - - function filter_render_block( $content, $parsed_block ) { - return 'Original: "' . $content . '", from block "' . $parsed_block['blockName'] . '"'; - } - - function test_constructor_assigns_properties_from_parsed_block() { - $this->registry->register( 'core/example', array() ); - - $parsed_blocks = parse_blocks( 'ab' ); - $parsed_block = $parsed_blocks[0]; - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertSame( $parsed_block, $block->parsed_block ); - $this->assertEquals( $parsed_block['blockName'], $block->name ); - $this->assertEquals( $parsed_block['attrs'], $block->attributes ); - $this->assertEquals( $parsed_block['innerContent'], $block->inner_content ); - $this->assertEquals( $parsed_block['innerHTML'], $block->inner_html ); - } - - function test_constructor_assigns_block_type_from_registry() { - $block_type_settings = array( - 'attributes' => array( - 'defaulted' => array( - 'type' => 'number', - 'default' => 10, - ), - ), - ); - $this->registry->register( 'core/example', $block_type_settings ); - - $parsed_block = array( 'blockName' => 'core/example' ); - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertInstanceOf( WP_Block_Type::class, $block->block_type ); - $this->assertEquals( - $block_type_settings['attributes'], - $block->block_type->attributes - ); - } - - function test_lazily_assigns_attributes_with_defaults() { - $this->registry->register( - 'core/example', - array( - 'attributes' => array( - 'defaulted' => array( - 'type' => 'number', - 'default' => 10, - ), - ), - ) - ); - - $parsed_block = array( - 'blockName' => 'core/example', - 'attrs' => array( - 'explicit' => 20, - ), - ); - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertEquals( - array( - 'defaulted' => 10, - 'explicit' => 20, - ), - $block->attributes - ); - } - - function test_lazily_assigns_attributes_with_only_defaults() { - $this->registry->register( - 'core/example', - array( - 'attributes' => array( - 'defaulted' => array( - 'type' => 'number', - 'default' => 10, - ), - ), - ) - ); - - $parsed_block = array( - 'blockName' => 'core/example', - 'attrs' => array(), - ); - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertEquals( array( 'defaulted' => 10 ), $block->attributes ); - // Intentionally call a second time, to ensure property was assigned. - $this->assertEquals( array( 'defaulted' => 10 ), $block->attributes ); - } - - function test_constructor_assigns_context_from_block_type() { - $this->registry->register( - 'core/example', - array( - 'uses_context' => array( 'requested' ), - ) - ); - - $parsed_block = array( 'blockName' => 'core/example' ); - $context = array( - 'requested' => 'included', - 'unrequested' => 'not included', - ); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertEquals( array( 'requested' => 'included' ), $block->context ); - } - - function test_constructor_maps_inner_blocks() { - $this->registry->register( 'core/example', array() ); - - $parsed_blocks = parse_blocks( 'ab' ); - $parsed_block = $parsed_blocks[0]; - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertCount( 1, $block->inner_blocks ); - $this->assertInstanceOf( WP_Block::class, $block->inner_blocks[0] ); - $this->assertEquals( 'core/example', $block->inner_blocks[0]->name ); - } - - function test_constructor_prepares_context_for_inner_blocks() { - $this->registry->register( - 'core/outer', - array( - 'attributes' => array( - 'recordId' => array( - 'type' => 'number', - ), - ), - 'provides_context' => array( - 'core/recordId' => 'recordId', - ), - ) - ); - $this->registry->register( - 'core/inner', - array( - 'uses_context' => array( 'core/recordId' ), - ) - ); - - $parsed_blocks = parse_blocks( '' ); - $parsed_block = $parsed_blocks[0]; - $context = array( 'unrequested' => 'not included' ); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertCount( 0, $block->context ); - $this->assertEquals( - array( 'core/recordId' => 10 ), - $block->inner_blocks[0]->context - ); - } - - function test_constructor_assigns_merged_context() { - $this->registry->register( - 'core/example', - array( - 'attributes' => array( - 'value' => array( - 'type' => array( 'string', 'null' ), - ), - ), - 'provides_context' => array( - 'core/value' => 'value', - ), - 'uses_context' => array( 'core/value' ), - ) - ); - - $parsed_blocks = parse_blocks( - '' . - '' . - '' . - '' . - '' - ); - $parsed_block = $parsed_blocks[0]; - $context = array( 'core/value' => 'original' ); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertEquals( - array( 'core/value' => 'original' ), - $block->context - ); - $this->assertEquals( - array( 'core/value' => 'merged' ), - $block->inner_blocks[0]->context - ); - $this->assertEquals( - array( 'core/value' => null ), - $block->inner_blocks[0]->inner_blocks[0]->context - ); - } - - function test_render_static_block_type_returns_own_content() { - $this->registry->register( 'core/static', array() ); - $this->registry->register( - 'core/dynamic', - array( - 'render_callback' => function() { - return 'b'; - }, - ) - ); - - $parsed_blocks = parse_blocks( 'ac' ); - $parsed_block = $parsed_blocks[0]; - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertSame( 'abc', $block->render() ); - } - - function test_render_passes_block_for_render_callback() { - $this->registry->register( - 'core/greeting', - array( - 'render_callback' => function( $attributes, $content, $block ) { - return sprintf( 'Hello from %s', $block->name ); - }, - ) - ); - - $parsed_blocks = parse_blocks( '' ); - $parsed_block = $parsed_blocks[0]; - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertSame( 'Hello from core/greeting', $block->render() ); - } - - function test_render_applies_render_block_filter() { - $this->registry->register( 'core/example', array() ); - - add_filter( 'render_block', array( $this, 'filter_render_block' ), 10, 2 ); - - $parsed_blocks = parse_blocks( 'StaticInner' ); - $parsed_block = $parsed_blocks[0]; - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $rendered_content = $block->render(); - - remove_filter( 'render_block', array( $this, 'filter_render_block' ) ); - - $this->assertSame( 'Original: "StaticOriginal: "Inner", from block "core/example"", from block "core/example"', $rendered_content ); - - } - - function test_passes_attributes_to_render_callback() { - $this->registry->register( - 'core/greeting', - array( - 'attributes' => array( - 'toWhom' => array( - 'type' => 'string', - ), - 'punctuation' => array( - 'type' => 'string', - 'default' => '!', - ), - ), - 'render_callback' => function( $block_attributes ) { - return sprintf( - 'Hello %s%s', - $block_attributes['toWhom'], - $block_attributes['punctuation'] - ); - }, - ) - ); - - $parsed_blocks = parse_blocks( '' ); - $parsed_block = $parsed_blocks[0]; - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertSame( 'Hello world!', $block->render() ); - } - - function test_passes_content_to_render_callback() { - $this->registry->register( - 'core/outer', - array( - 'render_callback' => function( $block_attributes, $content ) { - return $content; - }, - ) - ); - $this->registry->register( - 'core/inner', - array( - 'render_callback' => function() { - return 'b'; - }, - ) - ); - - $parsed_blocks = parse_blocks( 'ac' ); - $parsed_block = $parsed_blocks[0]; - $context = array(); - $block = new WP_Block( $parsed_block, $context, $this->registry ); - - $this->assertSame( 'abc', $block->render() ); - } - -} diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 8b5193a7f3a3ee..b2ac5cd3a79daf 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -8,6 +8,39 @@ class WP_Theme_JSON_Test extends WP_UnitTestCase { + function test_user_data_is_escaped() { + $theme_json = new WP_Theme_JSON( + array( + 'global' => array( + 'styles' => array( + 'color' => array( + 'background' => 'green', + 'gradient' => 'linear-gradient(10deg,rgba(6,147,227,1) 0%,rgb(61,132,163) 37%,rgb(155,81,224) 100%)', + 'link' => 'linear-gradient(10deg,rgba(6,147,227,1) 0%,rgb(61,132,163) 37%,rgb(155,81,224) 100%)', + 'text' => 'var:preset|color|dark-gray', + ), + ), + ), + ), + true + ); + $result = $theme_json->get_raw_data(); + + $expected = array( + 'global' => array( + 'styles' => array( + 'color' => array( + 'background' => 'green', + 'gradient' => 'linear-gradient(10deg,rgba(6,147,227,1) 0%,rgb(61,132,163) 37%,rgb(155,81,224) 100%)', + 'text' => 'var:preset|color|dark-gray', + ), + ), + ), + ); + + $this->assertEqualSetsWithIndex( $expected, $result ); + } + function test_contexts_not_valid_are_skipped() { $theme_json = new WP_Theme_JSON( array( @@ -124,7 +157,7 @@ function test_get_stylesheet() { // See schema at WP_Theme_JSON::SCHEMA. $theme_json = new WP_Theme_JSON( array( - 'global' => array( + 'global' => array( 'settings' => array( 'color' => array( 'text' => 'value', @@ -158,20 +191,30 @@ function test_get_stylesheet() { ), 'misc' => 'value', ), + 'core/group' => array( + 'styles' => array( + 'spacing' => array( + 'padding' => array( + 'top' => '12px', + 'bottom' => '24px', + ), + ), + ), + ), ) ); $this->assertEquals( - $theme_json->get_stylesheet(), - ':root{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}:root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}' + ':root{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}:root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}.wp-block-group{padding-top: 12px;padding-bottom: 24px;}', + $theme_json->get_stylesheet() ); $this->assertEquals( - $theme_json->get_stylesheet( 'block_styles' ), - ':root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}' + ':root{--wp--style--color--link: #111;color: var(--wp--preset--color--grey);}.has-grey-color{color: grey;}.has-grey-background-color{background-color: grey;}.wp-block-group{padding-top: 12px;padding-bottom: 24px;}', + $theme_json->get_stylesheet( 'block_styles' ) ); $this->assertEquals( - $theme_json->get_stylesheet( 'css_variables' ), - ':root{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}' + ':root{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}', + $theme_json->get_stylesheet( 'css_variables' ) ); } @@ -298,13 +341,13 @@ public function test_merge_incoming_data() { ), ), 'typography' => array( - 'fontSizes' => array( + 'fontSizes' => array( array( 'slug' => 'fontSize', 'size' => 'fontSize', ), ), - 'fontFamilies' => array( + 'fontFamilies' => array( array( 'slug' => 'fontFamily', 'fontFamily' => 'fontFamily', @@ -335,13 +378,13 @@ public function test_merge_incoming_data() { ), ), 'typography' => array( - 'fontSizes' => array( + 'fontSizes' => array( array( 'slug' => 'fontSize', 'size' => 'fontSize', ), ), - 'fontFamilies' => array( + 'fontFamilies' => array( array( 'slug' => 'fontFamily', 'fontFamily' => 'fontFamily', diff --git a/readme.txt b/readme.txt index 691830be65932a..e551d11d6f1749 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,6 @@ === Gutenberg === Contributors: matveb, joen, karmatosed -Requires at least: 5.4.0 +Requires at least: 5.5.0 Tested up to: 5.5 Requires PHP: 5.6 Stable tag: V.V.V @@ -57,4 +57,4 @@ View release page. +To read the changelog for Gutenberg 9.7.0-rc.1, please navigate to the release page. diff --git a/storybook/.babelrc b/storybook/.babelrc index b2b3e792e2f972..fe77bd84598748 100644 --- a/storybook/.babelrc +++ b/storybook/.babelrc @@ -3,10 +3,5 @@ "plugins": [ "babel-plugin-emotion", "babel-plugin-inline-json-import" - ], - "env": { - "test": { - "plugins": [ "babel-plugin-require-context-hook" ] - } - } + ] } diff --git a/test/unit/config/register-context.js b/test/unit/config/register-context.js deleted file mode 100644 index b73423550f42c6..00000000000000 --- a/test/unit/config/register-context.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * External dependencies - */ -import registerRequireContextHook from 'babel-plugin-require-context-hook/register'; - -registerRequireContextHook(); diff --git a/test/unit/jest.config.js b/test/unit/jest.config.js index fa37927d7c7c48..ee73efecd04029 100644 --- a/test/unit/jest.config.js +++ b/test/unit/jest.config.js @@ -19,7 +19,6 @@ module.exports = { setupFiles: [ '/test/unit/config/global-mocks.js', '/test/unit/config/gutenberg-phase.js', - '/test/unit/config/register-context.js', ], testURL: 'http://localhost', testPathIgnorePatterns: [ diff --git a/tsconfig.json b/tsconfig.json index 003daf1af802cc..9197c90e3f36ca 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,7 @@ { "path": "packages/i18n" }, { "path": "packages/icons" }, { "path": "packages/is-shallow-equal" }, + { "path": "packages/keycodes" }, { "path": "packages/lazy-import" }, { "path": "packages/prettier-config" }, { "path": "packages/primitives" },