diff --git a/.dev-lib b/.dev-lib index 54e968078eb..1199fdca2e1 100644 --- a/.dev-lib +++ b/.dev-lib @@ -3,12 +3,9 @@ DEFAULT_BASE_BRANCH=develop ASSETS_DIR=wp-assets PROJECT_SLUG=amp -SKIP_ECHO_PATHS_SCOPE=1 README_MD_TITLE="AMP Plugin for WordPress" DEV_LIB_SKIP="$DEV_LIB_SKIP,jshint" -if [[ ! -z $TRAVIS ]]; then - CHECK_SCOPE=all -fi +CHECK_SCOPE=all function after_wp_install { if [[ "$WP_VERSION" != "4.9" ]]; then diff --git a/.eslintrc b/.eslintrc index fb606190908..765f3ab5bd4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,11 @@ { "root": true, - "extends": [ "plugin:@wordpress/eslint-plugin/recommended", "plugin:jest/recommended" ], + "extends": [ + "plugin:@wordpress/eslint-plugin/recommended", + "plugin:jest/all", + "plugin:import/recommended", + "plugin:eslint-comments/recommended" + ], "settings": { "react": { "pragma": "wp", @@ -9,11 +14,68 @@ }, "globals": { "browser": true, - "page": true, "wp": true, "Set": true }, "rules": { - "react/prop-types": 2 - } + "block-scoped-var": "error", + "complexity": ["error", { "max": 20 } ], + "consistent-return": "error", + "default-case": "error", + "guard-for-in": "error", + "no-await-in-loop": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-floating-decimal": "error", + "no-implicit-coercion": "error", + "no-implicit-globals": "error", + "no-implied-eval": "error", + "no-loop-func": "error", + "no-new": "error", + "no-new-func": "error", + "no-new-wrappers": "error", + "no-restricted-properties": "error", + "no-return-assign": "error", + "no-return-await": "error", + "no-sequences": "error", + "no-shadow": "error", + "no-template-curly-in-string": "error", + "no-throw-literal": "error", + "no-unmodified-loop-condition": "error", + "no-useless-call": "error", + "no-useless-concat": "error", + "prefer-object-spread": "error", + "prefer-promise-reject-errors": "error", + "prefer-rest-params": "error", + "prefer-spread": "error", + "radix": [ "error", "as-needed" ], + "require-await": "error", + "rest-spread-spacing": [ "error", "never" ], + "jest/lowercase-name": [ + "error", + { + "ignore": [ "describe" ] + } + ], + "jest/no-hooks": "off", + "jest/prefer-expect-assertions": "off", + "jest/prefer-inline-snapshots": "off", + "react/prop-types": "error", + "import/no-unresolved": [ "error", { + "ignore": [ "jquery", "amp-block-editor-data" ] + } ] + }, + "overrides": [ + { + "files": [ "tests/e2e/**/*.js" ], + "env": { + "browser": true + }, + "globals": { + "browser": true, + "page": true, + "wp": true + } + } + ] } diff --git a/.gitignore b/.gitignore index edea2d4486e..7720d65d1b4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,8 @@ node_modules wiki amp.zip -assets/css/*-compiled.css -assets/css/*-compiled-rtl.css -assets/css/*.map +/assets/css/* +!/assets/css/src/ assets/js/*.js assets/js/*.deps.json !assets/js/amp-service-worker-runtime-precaching.js diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000000..1dab4ed4c30 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +save-exact = true diff --git a/.rtlcssrc b/.rtlcssrc new file mode 100644 index 00000000000..dfcfd69bbdb --- /dev/null +++ b/.rtlcssrc @@ -0,0 +1,13 @@ +{ + "options": { + "autoRename": false, + "autoRenameStrict": false, + "blacklist":{}, + "clean": true, + "greedy": false, + "processUrls": false, + "stringMap":[] + }, + "plugins": [ ], + "map": false +} diff --git a/.stylelintignore b/.stylelintignore index 7ba993148f8..cf59a35757b 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,3 +1,6 @@ -assets/css/admin-bar.css -assets/css/*-compiled.css -assets/css/*-compiled-rtl.css +/assets/css/*.css +/assets/css/src/admin-bar.css +/bin +/build +/tests +/vendor diff --git a/.travis.yml b/.travis.yml index ace45891dd1..5e271c2eba1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ notifications: cache: directories: - $HOME/.composer/cache + - $HOME/.jest-cache - $HOME/.npm - $HOME/.nvm/.cache - $HOME/phpunit-bin @@ -29,12 +30,15 @@ branches: - develop - /^\d+\.\d+$/ -env: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true +env: + global: + - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true install: - nvm install - composer install - export DEV_LIB_PATH=vendor/xwp/wp-dev-lib/scripts + - export DIFF_HEAD=HEAD - source "$DEV_LIB_PATH/travis.install.sh" before_script: @@ -42,7 +46,13 @@ before_script: script: - npm run build:js + - npm run build:css - source "$DEV_LIB_PATH/travis.script.sh" + - | + if [[ ! -z "$PHPUNIT_EXTRA_GROUP" ]]; then + echo "Running phpunit group $PHPUNIT_EXTRA_GROUP" + phpunit --group $PHPUNIT_EXTRA_GROUP + fi after_script: - source "$DEV_LIB_PATH/travis.after_script.sh" @@ -64,6 +74,9 @@ jobs: - composer validate --no-check-all - composer normalize --dry-run - npm run lint + - npm run build:js + after_success: + - npx sizereport --config - stage: test name: JavaScript unit tests @@ -71,11 +84,26 @@ jobs: env: WP_VERSION=latest DEV_LIB_SKIP=phpcs,eslint,xmllint,phpsyntax,phpunit script: - source "$DEV_LIB_PATH/travis.script.sh" - - npm run test:js -- --ci + - npm run test:js -- --ci --cacheDirectory="$HOME/.jest-cache" + + - name: E2E tests + php: "7.3" + env: WP_VERSION=latest DEV_LIB_SKIP=phpcs,eslint,xmllint,phpsyntax,phpunit PUPPETEER_SKIP_CHROMIUM_DOWNLOAD= + install: + - nvm install + - composer install + - npm install + script: + - npm run build:js + - npm run build:css + - npm run env:start + - npm run env:reset-site + - npm run test:e2e:ci + - npm run env:stop - - name: PHP unit tests (7.3, WordPress latest) + - name: PHP unit tests w/ external-http (7.3, WordPress latest) php: "7.3" - env: WP_VERSION=latest DEV_LIB_ONLY=phpunit INSTALL_PWA_PLUGIN=1 + env: WP_VERSION=latest DEV_LIB_ONLY=phpunit INSTALL_PWA_PLUGIN=1 PHPUNIT_EXTRA_GROUP=external-http - name: PHP unit tests (7.2, WordPress latest) php: "7.2" @@ -101,9 +129,9 @@ jobs: php: "5.5" env: WP_VERSION=5.0 DEV_LIB_ONLY=phpunit,phpsyntax - - name: PHP unit tests (5.4, WordPress 4.9) + - name: PHP unit tests w/ external-http (5.4, WordPress 4.9) php: "5.4" - env: WP_VERSION=4.9 DEV_LIB_ONLY=phpunit,phpsyntax + env: WP_VERSION=4.9 DEV_LIB_ONLY=phpunit,phpsyntax PHPUNIT_EXTRA_GROUP=external-http - name: PHP unit tests (7.3, WordPress trunk) php: "7.3" @@ -117,6 +145,7 @@ jobs: - echo "Running unit tests with code coverage..." script: - npm run build:js + - npm run build:css - source "$DEV_LIB_PATH/travis.script.sh" - bash <(curl -s https://codecov.io/bash) -cF php -f /tmp/wordpress/src/wp-content/plugins/amp/build/logs/clover.xml - npm run test:js -- --collectCoverage diff --git a/Gruntfile.js b/Gruntfile.js index 02df5e65c0a..73dd280df4f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,4 @@ /* eslint-env node */ -/* eslint-disable camelcase, no-console, no-param-reassign */ module.exports = function( grunt ) { 'use strict'; @@ -88,7 +87,7 @@ module.exports = function( grunt ) { const versionAppend = new Date().toISOString().replace( /\.\d+/, '' ).replace( /-|:/g, '' ) + '-' + commitHash; const paths = lsOutput.trim().split( /\n/ ).filter( function( file ) { - return ! /^(blocks|\.|bin|([^/]+)+\.(md|json|xml)|Gruntfile\.js|postcss\.config\.js|tests|wp-assets|readme\.md|composer\..*|patches|webpack.*|assets\/src|docker-compose\.yml|babel\.config\.js|codecov\.yml)/.test( file ); + return ! /^(blocks|\.|bin|([^/]+)+\.(md|json|xml)|Gruntfile\.js|tests|wp-assets|readme\.md|composer\..*|patches|webpack.*|assets\/images\/stories-editor\/.*\.svg|assets\/src|assets\/css\/src|docker-compose\.yml|.*\.config\.js|codecov\.yml)/.test( file ); } ); paths.push( 'vendor/autoload.php' ); @@ -116,7 +115,7 @@ module.exports = function( grunt ) { matches = content.match( versionRegex ); if ( matches ) { version = matches[ 2 ] + '-' + versionAppend; - console.log( 'Updating version in amp.php to ' + version ); + console.log( 'Updating version in amp.php to ' + version ); // eslint-disable-line no-console content = content.replace( versionRegex, '$1' + version ); content = content.replace( /(define\(\s*'AMP__VERSION',\s*')(.+?)(?=')/, '$1' + version ); } diff --git a/amp.php b/amp.php index 31931c39393..8749631c53b 100644 --- a/amp.php +++ b/amp.php @@ -5,7 +5,7 @@ * Plugin URI: https://amp-wp.org * Author: AMP Project Contributors * Author URI: https://github.com/ampproject/amp-wp/graphs/contributors - * Version: 1.2.0 + * Version: 1.2.1 * Text Domain: amp * Domain Path: /languages/ * License: GPLv2 or later @@ -13,16 +13,20 @@ * @package AMP */ +define( 'AMP__FILE__', __FILE__ ); +define( 'AMP__DIR__', dirname( __FILE__ ) ); +define( 'AMP__VERSION', '1.2.1' ); + /** * Errors encountered while loading the plugin. * * This has to be a global for the same of PHP 5.2. * - * @var \WP_Error $_amp_load_errors + * @var WP_Error $_amp_load_errors */ global $_amp_load_errors; -$_amp_load_errors = new \WP_Error(); +$_amp_load_errors = new WP_Error(); if ( version_compare( phpversion(), '5.4', '<' ) ) { $_amp_load_errors->add( @@ -145,7 +149,7 @@ unset( $_amp_required_extensions, $_amp_missing_extensions, $_amp_required_constructs, $_amp_missing_classes, $_amp_missing_functions, $_amp_required_extension, $_amp_construct_type, $_amp_construct, $_amp_constructs ); -if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) || ! file_exists( __DIR__ . '/vendor/sabberworm/php-css-parser' ) || ! file_exists( __DIR__ . '/assets/js/amp-block-editor.js' ) ) { +if ( ! file_exists( AMP__DIR__ . '/vendor/autoload.php' ) || ! file_exists( AMP__DIR__ . '/vendor/sabberworm/php-css-parser' ) || ! file_exists( AMP__DIR__ . '/assets/js/amp-block-editor.js' ) ) { $_amp_load_errors->add( 'build_required', sprintf( @@ -160,7 +164,7 @@ * Displays an admin notice about why the plugin is unable to load. * * @since 1.1.2 - * @global \WP_Error $_amp_load_errors + * @global WP_Error $_amp_load_errors */ function _amp_show_load_errors_admin_notice() { global $_amp_load_errors; @@ -207,9 +211,6 @@ function _amp_show_load_errors_admin_notice() { return; } -define( 'AMP__FILE__', __FILE__ ); -define( 'AMP__DIR__', dirname( __FILE__ ) ); -define( 'AMP__VERSION', '1.2.0' ); /** * Print admin notice if plugin installed with incorrect slug (which impacts WordPress's auto-update system). @@ -363,9 +364,11 @@ function amp_init() { if ( AMP_Options_Manager::is_stories_experience_enabled() ) { AMP_Story_Post_Type::register(); - add_action( 'wp_loaded', 'amp_story_templates' ); } + // Does its own is_stories_experience_enabled() check. + add_action( 'wp_loaded', 'amp_story_templates' ); + if ( defined( 'WP_CLI' ) && WP_CLI ) { WP_CLI::add_command( 'amp', new AMP_CLI() ); } diff --git a/assets/css/admin-bar.css b/assets/css/src/admin-bar.css similarity index 81% rename from assets/css/admin-bar.css rename to assets/css/src/admin-bar.css index 686efc4d2df..383b7e8c207 100644 --- a/assets/css/admin-bar.css +++ b/assets/css/src/admin-bar.css @@ -1,11 +1,12 @@ /* -This is forked from core's admin-bar.css from WP 4.9.6 -- Rules for IE<9 have been removed. +This is forked from core's admin-bar.css from WP 5.3-alpha at 160fc055da156248277513dd5256fbcc66faa5a7. + +https://github.com/WordPress/wordpress-develop/blob/160fc055da156248277513dd5256fbcc66faa5a7/src/wp-includes/css/admin-bar.css + - References to .hover have been replaced with :focus-within (which is not supported in IE11). -- A universal selector properties have been removed which interferes with AMP shadow elements. +- Universal selector properties have been removed which interferes with AMP shadow elements. */ - #wpadminbar * { height: auto; width: auto; @@ -18,7 +19,7 @@ This is forked from core's admin-bar.css from WP 4.9.6 font-size: 13px; font-weight: 400; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - line-height: 32px; + line-height: 2.46153846; border-radius: 0; box-sizing: content-box; transition: none; @@ -30,7 +31,7 @@ This is forked from core's admin-bar.css from WP 4.9.6 font-family: Tahoma, sans-serif; } -html:lang(he-il) .rtl #wpadminbar * { +html:lang(he-il) .rtl #wpadminbar * { font-family: Arial, sans-serif; } @@ -61,7 +62,6 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar a:hover, #wpadminbar a img, #wpadminbar a img:hover { - outline: none; border: none; text-decoration: none; background: none; @@ -79,7 +79,11 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar textarea, #wpadminbar div { box-shadow: none; - outline: none; +} + +#wpadminbar a:focus { + /* Inherits transparent outline only visible in Windows High Contrast mode */ + outline-offset: -1px; } #wpadminbar { @@ -88,13 +92,13 @@ html:lang(he-il) .rtl #wpadminbar * { font-size: 13px; font-weight: 400; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - line-height: 32px; + line-height: 2.46153846; height: 32px; position: fixed; top: 0; left: 0; width: 100%; - min-width: 600px; /* match the min-width of the body in wp-admin.css */ + min-width: 600px; /* match the min-width of the body in wp-admin/css/common.css */ z-index: 99999; background: #23282d; } @@ -149,13 +153,19 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar .shortlink-input { margin: 0; padding: 0; - box-shadow: 0 3px 5px rgba(0,0,0,0.2); + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); background: #32373c; display: none; position: absolute; float: none; } +#wpadminbar.ie7 .menupop .ab-sub-wrapper, +#wpadminbar.ie7 .shortlink-input { + top: 32px; + left: 0; +} + #wpadminbar .ab-top-menu > .menupop > .ab-sub-wrapper { min-width: 100%; } @@ -186,7 +196,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar .quicklinks .menupop:focus-within ul li .ab-item, #wpadminbar.nojs .quicklinks .menupop:hover ul li .ab-item, #wpadminbar .shortlink-input { - line-height: 26px; + line-height: 2; height: 26px; white-space: nowrap; min-width: 140px; @@ -234,7 +244,8 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar > #wp-toolbar > #wp-admin-bar-root-default .ab-icon, #wpadminbar .ab-icon, -#wpadminbar .ab-item:before { +#wpadminbar .ab-item:before, +.wp-admin-bar-arrow { position: relative; float: left; font: normal 20px/1 dashicons; @@ -250,7 +261,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar .ab-item:before, #wpadminbar #adminbarsearch:before { color: #a0a5aa; - color: rgba(240,245,250,0.6); + color: rgba(240, 245, 250, 0.6); } #wpadminbar .ab-icon:before, @@ -267,7 +278,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar .ab-submenu .ab-item { color: #b4b9be; - color: rgba(240,245,250,0.7); + color: rgba(240, 245, 250, 0.7); } #wpadminbar .quicklinks .menupop ul li a, @@ -275,7 +286,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar .quicklinks .menupop:focus-within ul li a, #wpadminbar.nojs .quicklinks .menupop:hover ul li a { color: #b4b9be; - color: rgba(240,245,250,0.7); + color: rgba(240, 245, 250, 0.7); } #wpadminbar .quicklinks .menupop ul li a:hover, @@ -306,7 +317,12 @@ html:lang(he-il) .rtl #wpadminbar * { color: #b4b9be; } -#wpadminbar .menupop .menupop > .ab-item:before, +#wpadminbar.mobile .quicklinks :focus-within .ab-icon:before, +#wpadminbar.mobile .quicklinks :focus-within .ab-item:before { + color: #00b9eb; +} + +#wpadminbar .menupop .menupop > .ab-item .wp-admin-bar-arrow:before, #wpadminbar .ab-top-secondary .menupop .menupop > .ab-item:before { position: absolute; font: normal 17px/1 dashicons; @@ -320,9 +336,10 @@ html:lang(he-il) .rtl #wpadminbar * { padding-right: 2em; } -#wpadminbar .menupop .menupop > .ab-item:before { +#wpadminbar .menupop .menupop > .ab-item .wp-admin-bar-arrow:before { top: 1px; - right: 4px; + right: 10px; + padding: 4px 0; content: "\f139"; color: inherit; } @@ -332,7 +349,7 @@ html:lang(he-il) .rtl #wpadminbar * { padding-right: 1em; } -#wpadminbar .ab-top-secondary .menupop .menupop > .ab-item:before { +#wpadminbar .ab-top-secondary .menupop .menupop > .ab-item .wp-admin-bar-arrow:before { top: 1px; left: 6px; content: "\f141"; @@ -366,7 +383,7 @@ html:lang(he-il) .rtl #wpadminbar * { border-radius: 10px; } -#wpadminbar .quicklinks a:hover span#ab-updates { +#wpadminbar .quicklinks a:hover span#ab-updates { background: #fff; color: #000; } @@ -380,6 +397,22 @@ html:lang(he-il) .rtl #wpadminbar * { box-shadow: none; } +/** + * Recovery Mode + */ +#wpadminbar #wp-admin-bar-recovery-mode { + color: #fff; + background-color: #ca4a1f; +} + +#wpadminbar .ab-top-menu > #wp-admin-bar-recovery-mode:focus-within >.ab-item, +#wpadminbar.nojq .quicklinks .ab-top-menu > #wp-admin-bar-recovery-mode > .ab-item:focus, +#wpadminbar:not(.mobile) .ab-top-menu > #wp-admin-bar-recovery-mode:hover > .ab-item, +#wpadminbar:not(.mobile) .ab-top-menu > #wp-admin-bar-recovery-mode > .ab-item:focus { + color: #fff; + background-color: #c0461e; +} + /** * My Account */ @@ -404,6 +437,10 @@ html:lang(he-il) .rtl #wpadminbar * { min-width: 270px; } +#wpadminbar.ie8 #wp-admin-bar-my-account.with-avatar .ab-item { + white-space: nowrap; +} + #wpadminbar #wp-admin-bar-user-actions > li { margin-left: 16px; margin-right: 16px; @@ -425,7 +462,6 @@ html:lang(he-il) .rtl #wpadminbar * { } #wp-admin-bar-user-info .avatar { - /* TODO: The amp-img>img does not get loaded since the container is initially hidden, and :hover does not trigger a re-calc. Resizing the window does, however. */ position: absolute; left: -72px; top: 4px; @@ -461,13 +497,18 @@ html:lang(he-il) .rtl #wpadminbar * { padding: 0; border: 1px solid #82878c; background: #eee; - line-height: 24px; + line-height: 1.84615384; vertical-align: middle; margin: -4px 0 0 6px; float: none; display: inline-block; /* Was inline. */ } +#wpadminbar.ie8 #wp-admin-bar-my-account.with-avatar > .ab-empty-item img, +#wpadminbar.ie8 #wp-admin-bar-my-account.with-avatar > a img { + width: 16px; /* Was auto. */ +} + /** * WP Logo */ @@ -579,6 +620,10 @@ html:lang(he-il) .rtl #wpadminbar * { /** * Search */ +#wpadminbar.ie8 #wp-admin-bar-search { + display: block; + min-width: 32px; +} #wpadminbar #wp-admin-bar-search .ab-item { padding: 0; background: transparent; @@ -611,7 +656,7 @@ html:lang(he-il) .rtl #wpadminbar * { z-index: 30; font-size: 13px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - line-height: 24px; + line-height: 1.84615384; text-indent: 0; height: 24px; width: 24px; @@ -619,7 +664,7 @@ html:lang(he-il) .rtl #wpadminbar * { padding: 0 3px 0 24px; margin: 0; color: #ccc; - background-color: rgba( 255, 255, 255, 0 ); + background-color: rgba(255, 255, 255, 0); border: none; outline: none; cursor: pointer; @@ -634,12 +679,30 @@ html:lang(he-il) .rtl #wpadminbar * { z-index: 10; color: #000; width: 200px; - background-color: rgba( 255, 255, 255, 0.9 ); + background-color: rgba(255, 255, 255, 0.9); cursor: text; border: 0; } -/* Removed IE hacks. */ +#wpadminbar.ie7 > #wp-toolbar > #wp-admin-bar-top-secondary > #wp-admin-bar-search #adminbarsearch input.adminbar-input { + margin-top: 3px; + width: 120px; +} + +#wpadminbar.ie8 > #wp-toolbar > #wp-admin-bar-top-secondary > #wp-admin-bar-search #adminbarsearch input.adminbar-input { + /* IE8 z-index bug with transparent / empty elements - fill in with an encoded transparent GIF */ + background: transparent 0 0 repeat scroll url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); +} + +/* IE8 doesn't redraw the pseudo elements unless you make a change to the content */ +#wpadminbar.ie8 #adminbarsearch.adminbar-focused:before { + content: "\f179 "; /* extra space */ +} + +#wpadminbar.ie8 > #wp-toolbar > #wp-admin-bar-top-secondary > #wp-admin-bar-search #adminbarsearch input.adminbar-input:focus { + background: #fff; + z-index: -1; +} #wpadminbar #adminbarsearch .adminbar-button { display: none; @@ -694,34 +757,86 @@ html:lang(he-il) .rtl #wpadminbar * { z-index: 100000; line-height: normal; text-decoration: none; - box-shadow: 0 0 2px 2px rgba(0,0,0,.6); + box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); } /** - * Removed IE 6-targeted rules + * IE 6-targeted rules */ +* html #wpadminbar { + overflow: hidden; + position: absolute; +} + +* html #wpadminbar .quicklinks ul li a { + float: left; +} + +* html #wpadminbar .menupop a span { + background-image: none; +} + +/* No @font-face support */ +.no-font-face #wpadminbar ul.ab-top-menu > li > a.ab-item { + display: block; + width: 45px; + text-align: center; + overflow: hidden; + margin: 0 3px; +} + +.no-font-face #wpadminbar #wp-admin-bar-my-sites > .ab-item, +.no-font-face #wpadminbar #wp-admin-bar-site-name > .ab-item, +.no-font-face #wpadminbar #wp-admin-bar-edit > .ab-item { + text-indent: 0; +} + +.no-font-face #wpadminbar .ab-icon, +.no-font-face #wpadminbar .ab-icon:before, +.no-font-face #wpadminbar a.ab-item:before, +.no-font-face #wpadminbar #wp-admin-bar-wp-logo > .ab-item { + display: none !important; +} + +.no-font-face #wpadminbar ul.ab-top-menu > li > a > span.ab-label { + display: inline; +} + +.no-font-face #wpadminbar #wp-admin-bar-menu-toggle span.ab-icon { + display: inline !important; +} + +.no-font-face #wpadminbar #wp-admin-bar-menu-toggle span.ab-icon:before { + content: "Menu"; + font: 14px/45px sans-serif !important; + display: inline-block !important; + color: #fff; +} -/* Removed No @font-face support */ +.no-font-face #wpadminbar #wp-admin-bar-site-name a.ab-item { + color: #fff; +} +/* End no @font-face */ -@media screen and ( max-width: 782px ) { +@media screen and (max-width: 782px) { /* Toolbar Touchification*/ html #wpadminbar { height: 46px; - min-width: 300px; + min-width: 240px; /* match the min-width of the body in wp-admin/css/common.css */ } #wpadminbar * { font-size: 14px; font-weight: 400; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - line-height: 32px; + line-height: 2.28571428; } #wpadminbar .quicklinks > ul > li > a, #wpadminbar .quicklinks .ab-empty-item { padding: 0; height: 46px; - line-height: 46px; + line-height: 3.28571428; width: auto; } @@ -748,6 +863,14 @@ html:lang(he-il) .rtl #wpadminbar * { text-overflow: clip; } + #wpadminbar .quicklinks .menupop ul li .ab-item, + #wpadminbar .quicklinks .menupop ul li a strong, + #wpadminbar .quicklinks .menupop:focus-within ul li .ab-item, + #wpadminbar.nojs .quicklinks .menupop:hover ul li .ab-item, + #wpadminbar .shortlink-input { + line-height: 1.6; + } + #wpadminbar .ab-label { display: none; } @@ -852,7 +975,7 @@ html:lang(he-il) .rtl #wpadminbar * { /* New Content */ #wpadminbar #wp-admin-bar-new-content .ab-icon:before { top: 0; - line-height: 53px; + line-height: 1.33333333; height: 46px !important; text-align: center; width: 52px; @@ -877,7 +1000,7 @@ html:lang(he-il) .rtl #wpadminbar * { display: block; font-size: 34px; height: 46px; - line-height: 47px; + line-height: 1.38235294; top: 0; } @@ -914,7 +1037,7 @@ html:lang(he-il) .rtl #wpadminbar * { #wpadminbar #wp-admin-bar-user-info .display-name { height: auto; font-size: 16px; - line-height: 24px; + line-height: 1.5; color: #eee; } diff --git a/assets/css/admin-tables.css b/assets/css/src/admin-tables.css similarity index 97% rename from assets/css/admin-tables.css rename to assets/css/src/admin-tables.css index 41309d3b5d2..9f525f210f1 100644 --- a/assets/css/admin-tables.css +++ b/assets/css/src/admin-tables.css @@ -69,3 +69,7 @@ td.column-found_elements_and_attributes div { .wrap .wp-heading-inline + .page-title-action { margin-left: 1rem; } + +.tooltip[hidden] { + visibility: hidden; +} diff --git a/assets/css/amp-block-editor.css b/assets/css/src/amp-block-editor.css similarity index 100% rename from assets/css/amp-block-editor.css rename to assets/css/src/amp-block-editor.css diff --git a/assets/css/amp-customizer.css b/assets/css/src/amp-customizer.css similarity index 100% rename from assets/css/amp-customizer.css rename to assets/css/src/amp-customizer.css diff --git a/assets/css/amp-default.css b/assets/css/src/amp-default.css similarity index 87% rename from assets/css/amp-default.css rename to assets/css/src/amp-default.css index 0da82eb95d5..e8aae6e8712 100644 --- a/assets/css/amp-default.css +++ b/assets/css/src/amp-default.css @@ -3,9 +3,11 @@ * Prevent cases of amp-img converted from img to appear with stretching by using object-fit to scale. * See . * Also use object-fit:contain in worst case scenario when we can't figure out dimensions for an image. + * Additionally, in side of \AMP_Img_Sanitizer::determine_dimensions() it could $amp_img->setAttribute( 'object-fit', 'contain' ) + * so that the following rules wouldn't be needed. */ amp-img.amp-wp-enforced-sizes[layout="intrinsic"] > img, -.amp-wp-unknown-size > img { +amp-anim.amp-wp-enforced-sizes[layout="intrinsic"] > img { object-fit: contain; } diff --git a/assets/css/amp-playlist-shortcode.css b/assets/css/src/amp-playlist-shortcode.css similarity index 100% rename from assets/css/amp-playlist-shortcode.css rename to assets/css/src/amp-playlist-shortcode.css diff --git a/assets/css/amp-post-meta-box.css b/assets/css/src/amp-post-meta-box.css similarity index 75% rename from assets/css/amp-post-meta-box.css rename to assets/css/src/amp-post-meta-box.css index ead68ac1605..89c17fda132 100644 --- a/assets/css/amp-post-meta-box.css +++ b/assets/css/src/amp-post-meta-box.css @@ -65,18 +65,3 @@ line-height: 2.8; } } - -.amp-block-validation-errors { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - font-size: 13px; - line-height: 1.5; -} - -.amp-block-validation-errors .amp-block-validation-errors__summary { - margin: 0.5em 0; - padding: 2px; -} - -.amp-block-validation-errors .amp-block-validation-errors__list { - padding-left: 2.5em; -} diff --git a/assets/css/amp-stories-editor.css b/assets/css/src/amp-stories-editor.css similarity index 83% rename from assets/css/amp-stories-editor.css rename to assets/css/src/amp-stories-editor.css index c55087006a0..6eec46bd341 100644 --- a/assets/css/amp-stories-editor.css +++ b/assets/css/src/amp-stories-editor.css @@ -12,8 +12,8 @@ padding-right: 50px; } -#amp-story-editor, -.amp-story-page-preview .editor-styles-wrapper, +.editor-styles-wrapper .wp-block:not([data-font-family]), +.editor-styles-wrapper #amp-story-editor, .block-editor-block-preview .block-editor-block-preview__content > div { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } @@ -25,11 +25,6 @@ } } -#amp-story-editor, -.amp-story-page-preview .editor-styles-wrapper { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; -} - /* * Remove alpha channel from placeholder background color * @@ -46,6 +41,12 @@ display: none !important; } +/* Removes margin from block wrappers */ +.editor-styles-wrapper #amp-story-editor [data-block] { + margin-top: 0; + margin-bottom: 0; +} + /* Quote block adjustments */ .wp-block-quote__citation { font-size: 16px; @@ -89,7 +90,7 @@ * @see https://github.com/WordPress/gutenberg/issues/7180 */ -.wp-block-image .components-resizable-box__container + .__resizable_base__ { /* stylelint-disable-line selector-class-pattern */ +.wp-block .components-resizable-box__container + .__resizable_base__ { /* stylelint-disable-line selector-class-pattern */ left: 0 !important; } @@ -180,7 +181,7 @@ /** * Hide Block Manager option */ -.edit-post-more-menu__content .components-menu-group:nth-last-of-type(2) div[role="menu"] > .components-button:first-child { +.edit-post-more-menu__content .components-menu-group:nth-last-of-type(2) div[role="group"] > .components-button:first-child { display: none; } @@ -201,7 +202,8 @@ pointer-events: none; } -div[data-amp-image-caption="noCaption"] figure.wp-block-image figcaption { +div[data-amp-caption="noCaption"] figure.wp-block-image figcaption, +div[data-amp-caption="noCaption"] .wp-block-video figcaption { display: none; } @@ -222,3 +224,21 @@ div[data-amp-image-caption="noCaption"] figure.wp-block-image figcaption { height: 100%; width: 100%; } + +/* If the Media Library has 2 notices, like for wrong video file type and size, prevent them from covering the media. */ +.media-frame.has-two-notices .media-frame-content { + bottom: 120px; +} + +/* More space for notices in the sidebar */ + +.components-panel__body .components-notice { + margin-left: 0; + margin-right: 0; +} + +/* Custom video block poster image */ + +.video-block__poster-image.editor-post-featured-image__preview img { + object-fit: cover; +} diff --git a/assets/css/amp-stories-frontend.css b/assets/css/src/amp-stories-frontend.css similarity index 77% rename from assets/css/amp-stories-frontend.css rename to assets/css/src/amp-stories-frontend.css index f19e7103e43..42a2544d603 100644 --- a/assets/css/amp-stories-frontend.css +++ b/assets/css/src/amp-stories-frontend.css @@ -16,6 +16,21 @@ amp-story-grid-layer { align-content: unset; } +.amp-block-story-cta__link { + position: absolute; +} + +.amp-block-story-cta__link amp-img { + max-height: 100%; + + /* Counteract the height increase caused by the inline-block. */ + margin-bottom: -.2em; +} + +.amp-block-story-cta__link amp-img * { + object-fit: contain; +} + .wp-block-pullquote { border-top: 4px solid #555d66; border-bottom: 4px solid #555d66; @@ -116,3 +131,11 @@ amp-story-grid-layer .wp-block-quote { font-size: 14px; text-align: center; } + +.wp-block-amp-amp-story-post-author.amp-text-content, +.wp-block-amp-amp-story-post-title.amp-text-content, +.wp-block-amp-amp-story-post-date.amp-text-content { + + /* --story-page-vw is accessible in the FE, this equals 16px in the editor */ + font-size: calc(4.88 * var(--story-page-vw)); +} diff --git a/assets/css/amp-stories.css b/assets/css/src/amp-stories.css similarity index 72% rename from assets/css/amp-stories.css rename to assets/css/src/amp-stories.css index f79231c3d0b..cc62c398013 100644 --- a/assets/css/amp-stories.css +++ b/assets/css/src/amp-stories.css @@ -25,16 +25,6 @@ amp-story-grid-layer[template="fill"] .wp-block-image { display: block; } -.wp-block-amp-amp-story-cta.aligncenter { - text-align: center; -} - -.wp-block-amp-amp-story-cta.alignright { - - /*rtl:ignore*/ - text-align: right; -} - .amp-block-story-cta__link { border: none; box-shadow: none; @@ -43,6 +33,7 @@ amp-story-grid-layer[template="fill"] .wp-block-image { display: inline-block; font-size: 18px; margin: 0; + max-height: calc(100% - 24px); padding: 12px 24px; text-align: center; text-decoration: none; @@ -89,14 +80,6 @@ table.wp-block-table { background-image: url("../images/quote-white.svg"); } -/** - * See https://github.com/ampproject/amp-wp/issues/2283 - */ -.edit-post-layout[data-block-name="core/video"] .edit-post-settings-sidebar__panel-block .block-editor-block-inspector__card + div > .components-panel__body:first-child .components-toggle-control:nth-child(2), -.edit-post-layout[data-block-name="core/video"] .edit-post-settings-sidebar__panel-block .block-editor-block-inspector__card + div > .components-panel__body:first-child .components-toggle-control:nth-child(6) { - display: none; -} - /* Block Warnings */ .is-selected .block-editor-block-list__block .block-editor-warning { diff --git a/assets/css/amp-story-card.css b/assets/css/src/amp-story-card.css similarity index 100% rename from assets/css/amp-story-card.css rename to assets/css/src/amp-story-card.css diff --git a/assets/css/amp-validation-error-taxonomy.css b/assets/css/src/amp-validation-error-taxonomy.css similarity index 100% rename from assets/css/amp-validation-error-taxonomy.css rename to assets/css/src/amp-validation-error-taxonomy.css diff --git a/assets/css/amp-validation-single-error-url.css b/assets/css/src/amp-validation-single-error-url.css similarity index 100% rename from assets/css/amp-validation-single-error-url.css rename to assets/css/src/amp-validation-single-error-url.css diff --git a/assets/css/amp-validation-tooltips.css b/assets/css/src/amp-validation-tooltips.css similarity index 79% rename from assets/css/amp-validation-tooltips.css rename to assets/css/src/amp-validation-tooltips.css index 9dd843321d4..fef0a17a946 100644 --- a/assets/css/amp-validation-tooltips.css +++ b/assets/css/src/amp-validation-tooltips.css @@ -5,3 +5,7 @@ cursor: pointer; color: #767676; } + +.tooltip[hidden] { + visibility: hidden; +} diff --git a/assets/images/amp-page-fallback-wordpress-publisher-logo.png b/assets/images/amp-page-fallback-wordpress-publisher-logo.png new file mode 100644 index 00000000000..f2a5a23aed4 Binary files /dev/null and b/assets/images/amp-page-fallback-wordpress-publisher-logo.png differ diff --git a/assets/images/add-page-inserter.svg b/assets/images/stories-editor/add-page-inserter.svg similarity index 100% rename from assets/images/add-page-inserter.svg rename to assets/images/stories-editor/add-page-inserter.svg diff --git a/assets/images/add-template.svg b/assets/images/stories-editor/add-template.svg similarity index 100% rename from assets/images/add-template.svg rename to assets/images/stories-editor/add-template.svg diff --git a/assets/images/stories-editor/amp-story-fallback-wordpress-publisher-logo.png b/assets/images/stories-editor/amp-story-fallback-wordpress-publisher-logo.png new file mode 100644 index 00000000000..65ed1497f6a Binary files /dev/null and b/assets/images/stories-editor/amp-story-fallback-wordpress-publisher-logo.png differ diff --git a/assets/images/amp-story-page-icon.svg b/assets/images/stories-editor/amp-story-page-icon.svg similarity index 100% rename from assets/images/amp-story-page-icon.svg rename to assets/images/stories-editor/amp-story-page-icon.svg diff --git a/assets/images/bring-forward.svg b/assets/images/stories-editor/bring-forward.svg similarity index 100% rename from assets/images/bring-forward.svg rename to assets/images/stories-editor/bring-forward.svg diff --git a/assets/images/bring-front.svg b/assets/images/stories-editor/bring-front.svg similarity index 100% rename from assets/images/bring-front.svg rename to assets/images/stories-editor/bring-front.svg diff --git a/assets/images/call-to-action.svg b/assets/images/stories-editor/call-to-action.svg similarity index 100% rename from assets/images/call-to-action.svg rename to assets/images/stories-editor/call-to-action.svg diff --git a/assets/images/font-names/arimo.svg b/assets/images/stories-editor/font-names/arimo.svg similarity index 100% rename from assets/images/font-names/arimo.svg rename to assets/images/stories-editor/font-names/arimo.svg diff --git a/assets/images/font-names/lato.svg b/assets/images/stories-editor/font-names/lato.svg similarity index 100% rename from assets/images/font-names/lato.svg rename to assets/images/stories-editor/font-names/lato.svg diff --git a/assets/images/font-names/lora.svg b/assets/images/stories-editor/font-names/lora.svg similarity index 100% rename from assets/images/font-names/lora.svg rename to assets/images/stories-editor/font-names/lora.svg diff --git a/assets/images/font-names/merriweather.svg b/assets/images/stories-editor/font-names/merriweather.svg similarity index 100% rename from assets/images/font-names/merriweather.svg rename to assets/images/stories-editor/font-names/merriweather.svg diff --git a/assets/images/font-names/montserrat.svg b/assets/images/stories-editor/font-names/montserrat.svg similarity index 100% rename from assets/images/font-names/montserrat.svg rename to assets/images/stories-editor/font-names/montserrat.svg diff --git a/assets/images/font-names/noto-sans.svg b/assets/images/stories-editor/font-names/noto-sans.svg similarity index 100% rename from assets/images/font-names/noto-sans.svg rename to assets/images/stories-editor/font-names/noto-sans.svg diff --git a/assets/images/font-names/open-sans-condensed.svg b/assets/images/stories-editor/font-names/open-sans-condensed.svg similarity index 100% rename from assets/images/font-names/open-sans-condensed.svg rename to assets/images/stories-editor/font-names/open-sans-condensed.svg diff --git a/assets/images/font-names/open-sans.svg b/assets/images/stories-editor/font-names/open-sans.svg similarity index 100% rename from assets/images/font-names/open-sans.svg rename to assets/images/stories-editor/font-names/open-sans.svg diff --git a/assets/images/font-names/oswald.svg b/assets/images/stories-editor/font-names/oswald.svg similarity index 100% rename from assets/images/font-names/oswald.svg rename to assets/images/stories-editor/font-names/oswald.svg diff --git a/assets/images/font-names/playfair-display.svg b/assets/images/stories-editor/font-names/playfair-display.svg similarity index 100% rename from assets/images/font-names/playfair-display.svg rename to assets/images/stories-editor/font-names/playfair-display.svg diff --git a/assets/images/font-names/pt-sans-narrow.svg b/assets/images/stories-editor/font-names/pt-sans-narrow.svg similarity index 100% rename from assets/images/font-names/pt-sans-narrow.svg rename to assets/images/stories-editor/font-names/pt-sans-narrow.svg diff --git a/assets/images/font-names/pt-sans.svg b/assets/images/stories-editor/font-names/pt-sans.svg similarity index 100% rename from assets/images/font-names/pt-sans.svg rename to assets/images/stories-editor/font-names/pt-sans.svg diff --git a/assets/images/font-names/pt-serif.svg b/assets/images/stories-editor/font-names/pt-serif.svg similarity index 100% rename from assets/images/font-names/pt-serif.svg rename to assets/images/stories-editor/font-names/pt-serif.svg diff --git a/assets/images/font-names/raleway.svg b/assets/images/stories-editor/font-names/raleway.svg similarity index 100% rename from assets/images/font-names/raleway.svg rename to assets/images/stories-editor/font-names/raleway.svg diff --git a/assets/images/font-names/roboto-condensed.svg b/assets/images/stories-editor/font-names/roboto-condensed.svg similarity index 100% rename from assets/images/font-names/roboto-condensed.svg rename to assets/images/stories-editor/font-names/roboto-condensed.svg diff --git a/assets/images/font-names/roboto-slab.svg b/assets/images/stories-editor/font-names/roboto-slab.svg similarity index 100% rename from assets/images/font-names/roboto-slab.svg rename to assets/images/stories-editor/font-names/roboto-slab.svg diff --git a/assets/images/font-names/roboto.svg b/assets/images/stories-editor/font-names/roboto.svg similarity index 100% rename from assets/images/font-names/roboto.svg rename to assets/images/stories-editor/font-names/roboto.svg diff --git a/assets/images/font-names/slabo-27.svg b/assets/images/stories-editor/font-names/slabo-27.svg similarity index 100% rename from assets/images/font-names/slabo-27.svg rename to assets/images/stories-editor/font-names/slabo-27.svg diff --git a/assets/images/font-names/source-sans-pro.svg b/assets/images/stories-editor/font-names/source-sans-pro.svg similarity index 100% rename from assets/images/font-names/source-sans-pro.svg rename to assets/images/stories-editor/font-names/source-sans-pro.svg diff --git a/assets/images/font-names/ubuntu.svg b/assets/images/stories-editor/font-names/ubuntu.svg similarity index 100% rename from assets/images/font-names/ubuntu.svg rename to assets/images/stories-editor/font-names/ubuntu.svg diff --git a/assets/images/stories-editor/marker.svg b/assets/images/stories-editor/marker.svg new file mode 100644 index 00000000000..cac327e9767 --- /dev/null +++ b/assets/images/stories-editor/marker.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/reorder.svg b/assets/images/stories-editor/reorder.svg similarity index 100% rename from assets/images/reorder.svg rename to assets/images/stories-editor/reorder.svg diff --git a/assets/images/send-back.svg b/assets/images/stories-editor/send-back.svg similarity index 100% rename from assets/images/send-back.svg rename to assets/images/stories-editor/send-back.svg diff --git a/assets/images/send-backwards.svg b/assets/images/stories-editor/send-backwards.svg similarity index 100% rename from assets/images/send-backwards.svg rename to assets/images/stories-editor/send-backwards.svg diff --git a/assets/images/story-fallback-poster.jpg b/assets/images/stories-editor/story-fallback-poster.jpg similarity index 100% rename from assets/images/story-fallback-poster.jpg rename to assets/images/stories-editor/story-fallback-poster.jpg diff --git a/assets/images/story-templates/cta-bg.jpg b/assets/images/stories-editor/story-templates/cta-bg.jpg similarity index 100% rename from assets/images/story-templates/cta-bg.jpg rename to assets/images/stories-editor/story-templates/cta-bg.jpg diff --git a/assets/images/story-templates/cta-image.jpg b/assets/images/stories-editor/story-templates/cta-image.jpg similarity index 100% rename from assets/images/story-templates/cta-image.jpg rename to assets/images/stories-editor/story-templates/cta-image.jpg diff --git a/assets/images/story-templates/fandom-cta.jpg b/assets/images/stories-editor/story-templates/fandom-cta.jpg similarity index 100% rename from assets/images/story-templates/fandom-cta.jpg rename to assets/images/stories-editor/story-templates/fandom-cta.jpg diff --git a/assets/images/story-templates/fandom-fact.jpg b/assets/images/stories-editor/story-templates/fandom-fact.jpg similarity index 100% rename from assets/images/story-templates/fandom-fact.jpg rename to assets/images/stories-editor/story-templates/fandom-fact.jpg diff --git a/assets/images/story-templates/fandom-title.jpg b/assets/images/stories-editor/story-templates/fandom-title.jpg similarity index 100% rename from assets/images/story-templates/fandom-title.jpg rename to assets/images/stories-editor/story-templates/fandom-title.jpg diff --git a/assets/images/story-templates/got-logo.png b/assets/images/stories-editor/story-templates/got-logo.png similarity index 100% rename from assets/images/story-templates/got-logo.png rename to assets/images/stories-editor/story-templates/got-logo.png diff --git a/assets/images/story-templates/intro-bg.jpg b/assets/images/stories-editor/story-templates/intro-bg.jpg similarity index 100% rename from assets/images/story-templates/intro-bg.jpg rename to assets/images/stories-editor/story-templates/intro-bg.jpg diff --git a/assets/images/story-templates/quote-bg.jpg b/assets/images/stories-editor/story-templates/quote-bg.jpg similarity index 100% rename from assets/images/story-templates/quote-bg.jpg rename to assets/images/stories-editor/story-templates/quote-bg.jpg diff --git a/assets/images/story-templates/quote-image.png b/assets/images/stories-editor/story-templates/quote-image.png similarity index 100% rename from assets/images/story-templates/quote-image.png rename to assets/images/stories-editor/story-templates/quote-image.png diff --git a/assets/images/story-templates/rome.png b/assets/images/stories-editor/story-templates/rome.png similarity index 100% rename from assets/images/story-templates/rome.png rename to assets/images/stories-editor/story-templates/rome.png diff --git a/assets/images/story-templates/title-bg.jpg b/assets/images/stories-editor/story-templates/title-bg.jpg similarity index 100% rename from assets/images/story-templates/title-bg.jpg rename to assets/images/stories-editor/story-templates/title-bg.jpg diff --git a/assets/images/story-templates/travel-tip.jpg b/assets/images/stories-editor/story-templates/travel-tip.jpg similarity index 100% rename from assets/images/story-templates/travel-tip.jpg rename to assets/images/stories-editor/story-templates/travel-tip.jpg diff --git a/assets/src/amp-validation/amp-validation-single-error-url-details.js b/assets/src/amp-validation/amp-validation-single-error-url-details.js index 2917f315866..d6fe77c2c04 100644 --- a/assets/src/amp-validation/amp-validation-single-error-url-details.js +++ b/assets/src/amp-validation/amp-validation-single-error-url-details.js @@ -12,7 +12,7 @@ class RowToggler { this.index = index; // Since we're adding additional rows, we need to override default .striped tables styles. - this.tr.classList.add( this.index % 2 ? 'odd' : 'even' ); // eslint-disable-line no-magic-numbers + this.tr.classList.add( this.index % 2 ? 'odd' : 'even' ); this.toggle = this.toggle.bind( this ); } @@ -43,7 +43,7 @@ class RowToggler { createNewTr() { this.newTr = document.createElement( 'tr' ); this.newTr.classList.add( 'details' ); - this.newTr.classList.add( this.index % 2 ? 'odd' : 'even' ); // eslint-disable-line no-magic-numbers + this.newTr.classList.add( this.index % 2 ? 'odd' : 'even' ); const newCell = document.createElement( 'td' ); newCell.setAttribute( 'colspan', this.getRowColspan() ); diff --git a/assets/src/block-editor/blocks/amp-brid-player/edit.js b/assets/src/block-editor/blocks/amp-brid-player/edit.js index baa879dceea..00f8cfaabd5 100644 --- a/assets/src/block-editor/blocks/amp-brid-player/edit.js +++ b/assets/src/block-editor/blocks/amp-brid-player/edit.js @@ -20,7 +20,7 @@ const BlockEdit = ( props ) => { const { autoPlay, dataPartner, dataPlayer, dataVideo, dataPlaylist, dataOutstream } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, - { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) }, + { value: 'fixed-height', label: __( 'Fixed Height', 'amp' ) }, { value: 'fixed', label: __( 'Fixed', 'amp' ) }, { value: 'fill', label: __( 'Fill', 'amp' ) }, { value: 'flex-item', label: __( 'Flex-item', 'amp' ) }, @@ -36,12 +36,12 @@ const BlockEdit = ( props ) => { ( setAttributes( { dataPartner: value } ) ) } /> ( setAttributes( { dataPlayer: value } ) ) } /> diff --git a/assets/src/block-editor/blocks/amp-ima-video/edit.js b/assets/src/block-editor/blocks/amp-ima-video/edit.js index 084c99d7a9e..cac3211d58d 100644 --- a/assets/src/block-editor/blocks/amp-ima-video/edit.js +++ b/assets/src/block-editor/blocks/amp-ima-video/edit.js @@ -32,17 +32,17 @@ const BlockEdit = ( props ) => { ( setAttributes( { dataTag: value } ) ) } /> ( setAttributes( { dataSrc: value } ) ) } /> ( setAttributes( { dataPoster: value } ) ) } /> diff --git a/assets/src/block-editor/blocks/amp-jwplayer/edit.js b/assets/src/block-editor/blocks/amp-jwplayer/edit.js index 2ba6216c0f3..4ea46e0b4fa 100644 --- a/assets/src/block-editor/blocks/amp-jwplayer/edit.js +++ b/assets/src/block-editor/blocks/amp-jwplayer/edit.js @@ -20,7 +20,7 @@ const BlockEdit = ( props ) => { const { dataPlayerId, dataMediaId, dataPlaylistId } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, - { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) }, + { value: 'fixed-height', label: __( 'Fixed Height', 'amp' ) }, { value: 'fixed', label: __( 'Fixed', 'amp' ) }, { value: 'fill', label: __( 'Fill', 'amp' ) }, { value: 'flex-item', label: __( 'Flex-item', 'amp' ) }, diff --git a/assets/src/block-editor/blocks/amp-latest-stories/edit.js b/assets/src/block-editor/blocks/amp-latest-stories/edit.js index b0e68f77e7e..8a07cb1e36a 100644 --- a/assets/src/block-editor/blocks/amp-latest-stories/edit.js +++ b/assets/src/block-editor/blocks/amp-latest-stories/edit.js @@ -16,9 +16,9 @@ import { PanelBody, Placeholder, QueryControls, - ServerSideRender, Spinner, } from '@wordpress/components'; +import ServerSideRender from '@wordpress/server-side-render'; import { __ } from '@wordpress/i18n'; import { InspectorControls } from '@wordpress/block-editor'; import { withSelect } from '@wordpress/data'; @@ -50,47 +50,45 @@ class LatestStoriesEdit extends Component { const { attributes, setAttributes, latestStories } = this.props; const { order, orderBy, storiesToShow } = attributes; - const inspectorControls = ( - - - setAttributes( { order: value } ) } - onOrderByChange={ ( value ) => setAttributes( { orderBy: value } ) } - onNumberOfItemsChange={ ( value ) => setAttributes( { storiesToShow: value } ) } - /> - - - ); + const isLoading = ! Array.isArray( latestStories ); + const storiesWithFeaturedImages = ( latestStories || [] ).filter( ( { featured_media: image } ) => image > 0 ); + const hasStories = storiesWithFeaturedImages.length > 0; + + const serverSideAttributes = { + ...attributes, + useCarousel: false, + }; - const hasStories = Array.isArray( latestStories ) && latestStories.length; - if ( ! hasStories ) { - return ( - <> - { inspectorControls } + return ( + <> + + + setAttributes( { order: value } ) } + onOrderByChange={ ( value ) => setAttributes( { orderBy: value } ) } + onNumberOfItemsChange={ ( value ) => setAttributes( { storiesToShow: value } ) } + /> + + + { ( isLoading || ! hasStories ) && ( - { ! Array.isArray( latestStories ) ? + { isLoading ? : __( 'No stories found.', 'amp' ) } - - ); - } - - const serverSideAttributes = Object.assign( {}, attributes, { useCarousel: false } ); - - return ( - <> - { inspectorControls } - + ) } + { hasStories && ( + + ) } ); } @@ -103,7 +101,7 @@ LatestStoriesEdit.propTypes = { storiesToShow: PropTypes.number, } ), setAttributes: PropTypes.func.isRequired, - latestStories: PropTypes.array.isRequired, + latestStories: PropTypes.array, }; export default withSelect( ( select, props ) => { @@ -114,6 +112,7 @@ export default withSelect( ( select, props ) => { orderby: orderBy, per_page: storiesToShow, }, ( value ) => ! isUndefined( value ) ); + return { latestStories: getEntityRecords( 'postType', 'amp_story', latestStoriesQuery ), }; diff --git a/assets/src/block-editor/blocks/amp-latest-stories/index.js b/assets/src/block-editor/blocks/amp-latest-stories/index.js index e7af99b221d..48f87e29ebd 100644 --- a/assets/src/block-editor/blocks/amp-latest-stories/index.js +++ b/assets/src/block-editor/blocks/amp-latest-stories/index.js @@ -12,12 +12,12 @@ export const name = 'amp/amp-latest-stories'; export const settings = { title: __( 'Latest Stories', 'amp' ), - description: __( 'See the latest AMP stories', 'amp' ), + description: __( 'Display your most recent stories.', 'amp' ), icon: 'list-view', category: 'widgets', keywords: [ - __( 'Recent stories', 'amp' ), - __( 'AMP stories', 'amp' ), + __( 'recent stories', 'amp' ), + __( 'AMP Stories', 'amp' ), ], supports: { diff --git a/assets/src/block-editor/blocks/amp-o2-player/edit.js b/assets/src/block-editor/blocks/amp-o2-player/edit.js index 11494ae9d3a..9cd723f45b7 100644 --- a/assets/src/block-editor/blocks/amp-o2-player/edit.js +++ b/assets/src/block-editor/blocks/amp-o2-player/edit.js @@ -25,7 +25,7 @@ const BlockEdit = ( props ) => { const { autoPlay, dataPid, dataVid, dataBcid, dataBid } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, - { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) }, + { value: 'fixed-height', label: __( 'Fixed Height', 'amp' ) }, { value: 'fixed', label: __( 'Fixed', 'amp' ) }, { value: 'fill', label: __( 'Fill', 'amp' ) }, { value: 'flex-item', label: __( 'Flex-item', 'amp' ) }, @@ -83,7 +83,7 @@ const BlockEdit = ( props ) => { BlockEdit.propTypes = { attributes: PropTypes.shape( { autoPlay: PropTypes.bool, - dataPidL: PropTypes.string, + dataPid: PropTypes.string, dataVid: PropTypes.string, dataBcid: PropTypes.string, dataBid: PropTypes.string, diff --git a/assets/src/block-editor/blocks/amp-ooyala-player/edit.js b/assets/src/block-editor/blocks/amp-ooyala-player/edit.js index 19013f78c5c..49b2a9fe7b8 100644 --- a/assets/src/block-editor/blocks/amp-ooyala-player/edit.js +++ b/assets/src/block-editor/blocks/amp-ooyala-player/edit.js @@ -37,7 +37,7 @@ const BlockEdit = ( props ) => { return ( <> - + { return ( <> - + ( setAttributes( { dataEmbedId: value } ) ) } /> diff --git a/assets/src/block-editor/blocks/amp-springboard-player/edit.js b/assets/src/block-editor/blocks/amp-springboard-player/edit.js index e25ef9e0e36..9f39ee4af18 100644 --- a/assets/src/block-editor/blocks/amp-springboard-player/edit.js +++ b/assets/src/block-editor/blocks/amp-springboard-player/edit.js @@ -39,12 +39,12 @@ const BlockEdit = ( props ) => { ( setAttributes( { dataSiteId: value } ) ) } /> ( setAttributes( { dataContentId: value } ) ) } /> diff --git a/assets/src/block-editor/blocks/amp-timeago/edit.js b/assets/src/block-editor/blocks/amp-timeago/edit.js index c0ff9fa5582..b9cc207d8c0 100644 --- a/assets/src/block-editor/blocks/amp-timeago/edit.js +++ b/assets/src/block-editor/blocks/amp-timeago/edit.js @@ -39,7 +39,7 @@ const BlockEdit = ( props ) => { const ampLayoutOptions = [ { value: '', label: __( 'Responsive', 'amp' ) }, { value: 'fixed', label: __( 'Fixed', 'amp' ) }, - { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) }, + { value: 'fixed-height', label: __( 'Fixed Height', 'amp' ) }, ]; return ( @@ -49,7 +49,7 @@ const BlockEdit = ( props ) => { ( setAttributes( { dateTime: moment( value, moment.ISO_8601, true ).format() } ) ) } // eslint-disable-line + onChange={ ( value ) => ( setAttributes( { dateTime: moment( value, moment.ISO_8601, true ).format() } ) ) } /> { timeagoProps.layout = ampLayout; } break; + + default: + break; } } return ( diff --git a/assets/src/block-editor/helpers/index.js b/assets/src/block-editor/helpers/index.js index 777cd70d16b..5a62fe867fc 100644 --- a/assets/src/block-editor/helpers/index.js +++ b/assets/src/block-editor/helpers/index.js @@ -48,7 +48,7 @@ const ampLayoutOptions = [ }, { value: 'fixed-height', - label: __( 'Fixed height', 'amp' ), + label: __( 'Fixed Height', 'amp' ), notAvailable: [], }, { @@ -171,7 +171,7 @@ export const addAMPAttributes = ( settings, name ) => { * * @return {Object} Output element. */ -export const filterBlocksSave = ( element, blockType, attributes ) => { +export const filterBlocksSave = ( element, blockType, attributes ) => { // eslint-disable-line complexity let text = attributes.text || '', content = ''; @@ -245,8 +245,10 @@ export const filterBlocksSave = ( element, blockType, attributes ) => { let ampFitTextContent = ''; @@ -451,6 +453,9 @@ export const setImageBlockLayoutAttributes = ( props, layout ) => { setAttributes( { width: DEFAULT_WIDTH } ); } break; + + default: + break; } }; @@ -594,9 +599,9 @@ const setUpTextBlocksInspectorControls = ( props ) => { const label = __( 'Automatically fit text to container', 'amp' ); if ( ampFitText ) { - maxFont = parseInt( maxFont, 10 ); - height = parseInt( height, 10 ); - minFont = parseInt( minFont, 10 ); + maxFont = parseInt( maxFont ); + height = parseInt( height ); + minFont = parseInt( minFont ); } return ( @@ -639,7 +644,7 @@ const setUpTextBlocksInspectorControls = ( props ) => { nextMinFont = MIN_FONT_SIZE; // @todo Supplying fallbackFontSize should be done automatically by the component? } - if ( parseInt( nextMinFont, 10 ) <= maxFont ) { + if ( parseInt( nextMinFont ) <= maxFont ) { setAttributes( { minFont: nextMinFont } ); } } } diff --git a/assets/src/block-editor/helpers/test/getAmpFitTextContent.js b/assets/src/block-editor/helpers/test/getAmpFitTextContent.js new file mode 100644 index 00000000000..d70e903c45b --- /dev/null +++ b/assets/src/block-editor/helpers/test/getAmpFitTextContent.js @@ -0,0 +1,16 @@ +/** + * Internal dependencies + */ +import { getAmpFitTextContent } from '../'; + +describe( 'getAmpFitTextContent', () => { + it( 'should extract the element\'s content', () => { + const result = getAmpFitTextContent( 'Hello World' ); + expect( result ).toBe( 'Hello World' ); + } ); + + it( 'should extract the element\'s content even when there are some attributes', () => { + const result = getAmpFitTextContent( 'Hello World' ); + expect( result ).toBe( 'Hello World' ); + } ); +} ); diff --git a/assets/src/block-editor/index.js b/assets/src/block-editor/index.js index b50f7b51030..4f5c429939d 100644 --- a/assets/src/block-editor/index.js +++ b/assets/src/block-editor/index.js @@ -11,7 +11,7 @@ import { select } from '@wordpress/data'; */ import { withCroppedFeaturedImage, withFeaturedImageNotice } from '../common/components'; import { addAMPAttributes, addAMPExtraProps, filterBlocksEdit, filterBlocksSave } from './helpers'; -import { getMinimumFeaturedImageDimensions } from '../common/helpers'; +import { getMinimumFeaturedImageDimensions, getMinimumPortraitFeaturedImageDimensions } from '../common/helpers'; import './store'; const { @@ -37,7 +37,7 @@ if ( isWebsiteEnabled() ) { addFilter( 'editor.BlockEdit', 'ampEditorBlocks/filterEdit', filterBlocksEdit, 20 ); addFilter( 'blocks.getSaveContent.extraProps', 'ampEditorBlocks/addExtraAttributes', addAMPExtraProps ); addFilter( 'editor.PostFeaturedImage', 'ampEditorBlocks/withFeaturedImageNotice', withFeaturedImageNotice ); - addFilter( 'editor.MediaUpload', 'ampEditorBlocks/addCroppedFeaturedImage', ( InitialMediaUpload ) => withCroppedFeaturedImage( InitialMediaUpload, getMinimumFeaturedImageDimensions() ) ); + addFilter( 'editor.MediaUpload', 'ampEditorBlocks/addCroppedFeaturedImage', ( InitialMediaUpload ) => withCroppedFeaturedImage( InitialMediaUpload, getMinimumFeaturedImageDimensions(), getMinimumPortraitFeaturedImageDimensions() ) ); } /* diff --git a/assets/src/block-editor/plugins/amp-toggle.js b/assets/src/block-editor/plugins/amp-toggle.js index a6330efa8e6..55fca16b765 100644 --- a/assets/src/block-editor/plugins/amp-toggle.js +++ b/assets/src/block-editor/plugins/amp-toggle.js @@ -45,7 +45,7 @@ function AMPToggle( { isEnabled, onChange } ) { ) } { - !! errorMessages.length && + Boolean( errorMessages.length ) && ( { it( 'should return the default AMP status', () => { const state = { defaultStatus: 'enabled' }; - expect( getDefaultStatus( state ) ).toEqual( 'enabled' ); + expect( getDefaultStatus( state ) ).toStrictEqual( 'enabled' ); } ); } ); @@ -55,7 +55,7 @@ describe( 'selectors', () => { it( 'should return the possible AMP statuses', () => { const state = { possibleStatuses: [ 'enabled', 'disabled' ] }; - expect( getPossibleStatuses( state ) ).toEqual( [ 'enabled', 'disabled' ] ); + expect( getPossibleStatuses( state ) ).toStrictEqual( [ 'enabled', 'disabled' ] ); } ); } ); } ); diff --git a/assets/src/block-validation/components/higher-order/with-validation-error-notice/edit.css b/assets/src/block-validation/components/higher-order/with-validation-error-notice/edit.css new file mode 100644 index 00000000000..e913f8b8855 --- /dev/null +++ b/assets/src/block-validation/components/higher-order/with-validation-error-notice/edit.css @@ -0,0 +1,14 @@ +.amp-block-validation-errors { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; + font-size: 13px; + line-height: 1.5; +} + +.amp-block-validation-errors .amp-block-validation-errors__summary { + margin: 0.5em 0; + padding: 2px; +} + +.amp-block-validation-errors .amp-block-validation-errors__list { + padding-left: 2.5em; +} diff --git a/assets/src/block-validation/components/higher-order/with-validation-error-notice.js b/assets/src/block-validation/components/higher-order/with-validation-error-notice/index.js similarity index 85% rename from assets/src/block-validation/components/higher-order/with-validation-error-notice.js rename to assets/src/block-validation/components/higher-order/with-validation-error-notice/index.js index 6f96af80f0a..46fd77c4bc2 100644 --- a/assets/src/block-validation/components/higher-order/with-validation-error-notice.js +++ b/assets/src/block-validation/components/higher-order/with-validation-error-notice/index.js @@ -9,13 +9,16 @@ import { withSelect } from '@wordpress/data'; /** * Internal dependencies */ -import { ValidationErrorMessage } from '../'; +import { ValidationErrorMessage } from '../../'; +import './edit.css'; const applyWithSelect = withSelect( ( select, { clientId } ) => { const { getBlockValidationErrors } = select( 'amp/block-validation' ); + const blockValidationErrors = getBlockValidationErrors( clientId ); + return { - blockValidationErrors: getBlockValidationErrors( clientId ), + blockValidationErrors: blockValidationErrors.length ? blockValidationErrors : undefined, }; } ); @@ -30,15 +33,15 @@ export default createHigherOrderComponent( return applyWithSelect( ( props ) => { const { blockValidationErrors, onReplace } = props; - const errorCount = blockValidationErrors.length; - - if ( errorCount === 0 ) { + if ( ! blockValidationErrors ) { return ; } + const errorCount = blockValidationErrors.length; + const actions = [ { - label: __( 'Remove Block', 'amp' ), + label: __( 'Remove Element', 'amp' ), onClick: () => onReplace( [] ), }, ]; diff --git a/assets/src/block-validation/components/validation-error-message.js b/assets/src/block-validation/components/validation-error-message/index.js similarity index 96% rename from assets/src/block-validation/components/validation-error-message.js rename to assets/src/block-validation/components/validation-error-message/index.js index f4c84be5142..89dc1b37e0c 100644 --- a/assets/src/block-validation/components/validation-error-message.js +++ b/assets/src/block-validation/components/validation-error-message/index.js @@ -20,7 +20,11 @@ import { __, sprintf } from '@wordpress/i18n'; */ const ValidationErrorMessage = ( { message, code, node_name: nodeName, parent_name: parentName } ) => { if ( message ) { - return message; + return ( + <> + { message } + + ); } if ( 'invalid_element' === code && nodeName ) { diff --git a/assets/src/block-validation/components/validation-error-message/test/__snapshots__/index.js.snap b/assets/src/block-validation/components/validation-error-message/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000..c017314c04f --- /dev/null +++ b/assets/src/block-validation/components/validation-error-message/test/__snapshots__/index.js.snap @@ -0,0 +1,48 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ValidationErrorMessage renders an error for a custom error code 1`] = ` +Array [ + "Error code: ", + + some_other_error + , +] +`; + +exports[`ValidationErrorMessage renders an error for an invalid attribute 1`] = ` +Array [ + "Invalid attribute: ", + + bar + , +] +`; + +exports[`ValidationErrorMessage renders an error for an invalid attribute with parent node 1`] = ` +Array [ + "Invalid attribute: ", + + baz[bar] + , +] +`; + +exports[`ValidationErrorMessage renders an error for an invalid element 1`] = ` +Array [ + "Invalid element: ", + + foo + , +] +`; + +exports[`ValidationErrorMessage renders an error for an unknown error code 1`] = ` +Array [ + "Error code: ", + + unknown + , +] +`; + +exports[`ValidationErrorMessage renders an error with a custom message 1`] = `null`; diff --git a/assets/src/block-validation/components/validation-error-message/test/index.js b/assets/src/block-validation/components/validation-error-message/test/index.js new file mode 100644 index 00000000000..9c09c35627d --- /dev/null +++ b/assets/src/block-validation/components/validation-error-message/test/index.js @@ -0,0 +1,41 @@ +/** + * External dependencies + */ +import { render } from 'enzyme'; + +/** + * Internal dependencies + */ +import ValidationErrorMessage from '../'; + +describe( 'ValidationErrorMessage', () => { + it( 'renders an error with a custom message', () => { + const errorMessage = render( ); + expect( errorMessage ).toMatchSnapshot(); + } ); + + it( 'renders an error for an invalid element', () => { + const errorMessage = render( ); + expect( errorMessage ).toMatchSnapshot(); + } ); + + it( 'renders an error for an invalid attribute', () => { + const errorMessage = render( ); + expect( errorMessage ).toMatchSnapshot(); + } ); + + it( 'renders an error for an invalid attribute with parent node', () => { + const errorMessage = render( ); + expect( errorMessage ).toMatchSnapshot(); + } ); + + it( 'renders an error for a custom error code', () => { + const errorMessage = render( ); + expect( errorMessage ).toMatchSnapshot(); + } ); + + it( 'renders an error for an unknown error code', () => { + const errorMessage = render( ); + expect( errorMessage ).toMatchSnapshot(); + } ); +} ); diff --git a/assets/src/block-validation/store/reducer.js b/assets/src/block-validation/store/reducer.js index d158749917e..c1360096b8e 100644 --- a/assets/src/block-validation/store/reducer.js +++ b/assets/src/block-validation/store/reducer.js @@ -32,7 +32,8 @@ export default ( state = undefined, action ) => { ...state, reviewLink: url, }; - } - return state; + default: + return state; + } }; diff --git a/assets/src/block-validation/store/test/actions.js b/assets/src/block-validation/store/test/actions.js index 19f3704e731..11d79a4cda7 100644 --- a/assets/src/block-validation/store/test/actions.js +++ b/assets/src/block-validation/store/test/actions.js @@ -13,9 +13,10 @@ describe( 'actions', () => { const error = { foo: 'bar' }; const result = addValidationError( error ); - expect( result ).toEqual( { + expect( result ).toStrictEqual( { type: 'ADD_VALIDATION_ERROR', error, + clientId: undefined, } ); } ); @@ -24,7 +25,7 @@ describe( 'actions', () => { const error = { foo: 'bar' }; const result = addValidationError( error, clientId ); - expect( result ).toEqual( { + expect( result ).toStrictEqual( { type: 'ADD_VALIDATION_ERROR', error, clientId, @@ -36,7 +37,7 @@ describe( 'actions', () => { it( 'should return the RESET_VALIDATION_ERRORS action', () => { const result = resetValidationErrors(); - expect( result ).toEqual( { + expect( result ).toStrictEqual( { type: 'RESET_VALIDATION_ERRORS', } ); } ); @@ -44,10 +45,12 @@ describe( 'actions', () => { describe( 'updateReviewLink', () => { it( 'should return the UPDATE_REVIEW_LINK action', () => { - const result = updateReviewLink(); + const url = 'https://example.com/'; + const result = updateReviewLink( url ); - expect( result ).toEqual( { + expect( result ).toStrictEqual( { type: 'UPDATE_REVIEW_LINK', + url, } ); } ); } ); diff --git a/assets/src/block-validation/store/test/reducer.js b/assets/src/block-validation/store/test/reducer.js index fd89b3fda7e..c3a2dbda30b 100644 --- a/assets/src/block-validation/store/test/reducer.js +++ b/assets/src/block-validation/store/test/reducer.js @@ -19,7 +19,7 @@ describe( 'reducer', () => { clientId, } ); - expect( state ).toEqual( { + expect( state ).toStrictEqual( { errors: [ { ...error, clientId }, ], @@ -33,7 +33,7 @@ describe( 'reducer', () => { type: 'RESET_VALIDATION_ERRORS', } ); - expect( state ).toEqual( { + expect( state ).toStrictEqual( { errors: [], } ); } ); @@ -44,7 +44,7 @@ describe( 'reducer', () => { url: 'https://example.com', } ); - expect( state ).toEqual( { + expect( state ).toStrictEqual( { reviewLink: 'https://example.com', } ); } ); diff --git a/assets/src/block-validation/store/test/selectors.js b/assets/src/block-validation/store/test/selectors.js index a3d2e4392a5..422eb98752c 100644 --- a/assets/src/block-validation/store/test/selectors.js +++ b/assets/src/block-validation/store/test/selectors.js @@ -17,7 +17,7 @@ describe( 'selectors', () => { errors, }; - expect( getValidationErrors( state ) ).toEqual( errors ); + expect( getValidationErrors( state ) ).toStrictEqual( errors ); } ); } ); @@ -29,7 +29,7 @@ describe( 'selectors', () => { errors, }; - expect( getBlockValidationErrors( state, 'foo' ) ).toEqual( [ { baz: 'boo', clientId: 'foo' } ] ); + expect( getBlockValidationErrors( state, 'foo' ) ).toStrictEqual( [ { baz: 'boo', clientId: 'foo' } ] ); } ); } ); @@ -37,7 +37,7 @@ describe( 'selectors', () => { it( 'should return the validation errors review link', () => { const state = { reviewLink: 'https://example.com' }; - expect( getReviewLink( state ) ).toEqual( 'https://example.com' ); + expect( getReviewLink( state ) ).toStrictEqual( 'https://example.com' ); } ); } ); diff --git a/assets/src/classic-editor/amp-post-meta-box.js b/assets/src/classic-editor/amp-post-meta-box.js index 1dab7f79a42..29ba0b0b0a1 100644 --- a/assets/src/classic-editor/amp-post-meta-box.js +++ b/assets/src/classic-editor/amp-post-meta-box.js @@ -10,7 +10,7 @@ import jQuery from 'jquery'; * * @since 0.6 */ -window.ampPostMetaBox = ( function( $ ) { // eslint-disable-line no-unused-vars +window.ampPostMetaBox = ( function( $ ) { 'use strict'; const component = { diff --git a/assets/src/common/components/featured-image-select-media-frame.js b/assets/src/common/components/featured-image-select-media-frame.js deleted file mode 100644 index 4b9c4626cf0..00000000000 --- a/assets/src/common/components/featured-image-select-media-frame.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * External dependencies - */ -import { template } from 'lodash'; - -/** - * WordPress dependencies - */ -import { __, sprintf } from '@wordpress/i18n'; - -const { wp } = window; - -/** - * FeaturedImageSelectionError - * - * @class - * @augments wp.media.View - * @augments wp.Backbone.View - * @augments Backbone.View - */ -const FeaturedImageSelectionError = wp.media.View.extend( { - className: 'notice notice-warning notice-alt inline', - template: ( () => { - const message = sprintf( - /* translators: 1: image width in pixels. 2: image height in pixels. 3: required minimum width in pixels. 4: required minimum height in pixels. */ - __( 'The selected image is too small (%1$s by %2$s pixels). It should have a size of at least %3$s by %4$s pixels.', 'amp' ), - '{{width}}', - '{{height}}', - '{{minWidth}}', - '{{minHeight}}', - ); - - const errorTemplate = template( - `

${ message }

`, - { - evaluate: /<#([\s\S]+?)#>/g, - interpolate: /\{\{\{([\s\S]+?)\}\}\}/g, - escape: /\{\{([^\}]+?)\}\}(?!\})/g, - } - ); - return ( data ) => { - return errorTemplate( data ); - }; - } )(), -} ); - -/** - * FeaturedImageToolbarSelect - * - * Prevent selection of an image that does not meet the minimum requirements. - * - * @class - * @augments wp.media.view.Toolbar.Select - * @augments wp.media.view.Toolbar - * @augments wp.media.View - * @augments wp.Backbone.View - * @augments Backbone.View - * @inheritDoc - */ -const FeaturedImageToolbarSelect = wp.media.view.Toolbar.Select.extend( { - - /** - * Refresh the view. - */ - refresh() { - wp.media.view.Toolbar.Select.prototype.refresh.call( this ); - - const state = this.controller.state(); - const selection = state.get( 'selection' ); - - const attachment = selection.models[ 0 ]; - const minWidth = state.collection.get( 'library' ).get( 'suggestedWidth' ); - const minHeight = state.collection.get( 'library' ).get( 'suggestedHeight' ); - - if ( ! attachment || ( attachment.get( 'width' ) >= minWidth && attachment.get( 'height' ) >= minHeight ) ) { - this.secondary.unset( 'select-error' ); - } else { - this.secondary.set( - 'select-error', - new FeaturedImageSelectionError( { - minWidth, - minHeight, - width: attachment.get( 'width' ), - height: attachment.get( 'height' ), - } ) - ); - } - }, -} ); - -/** - * FeaturedImageSelectMediaFrame - * - * Select a featured image from the media library. - * - * @class - * @augments wp.media.view.MediaFrame.Select - * @augments wp.media.view.MediaFrame - * @augments wp.media.view.Frame - * @augments wp.media.View - * @augments wp.Backbone.View - * @augments Backbone.View - * @mixes wp.media.controller.StateMachine - * @inheritDoc - */ -const FeaturedImageSelectMediaFrame = wp.media.view.MediaFrame.Select.extend( { - - /** - * Create select toolbar. - * - * The only reason for this method is to override the select toolbar view class. - * - * @param {Object} toolbar - * @param {Object} [options={}] - * @this wp.media.controller.Region - */ - createSelectToolbar( toolbar, options ) { - options = options || this.options.button || {}; - options.controller = this; - - toolbar.view = new FeaturedImageToolbarSelect( options ); - }, -} ); - -export default FeaturedImageSelectMediaFrame; diff --git a/assets/src/common/components/index.js b/assets/src/common/components/index.js index 1fbf0bb1c55..40b90c26c7f 100644 --- a/assets/src/common/components/index.js +++ b/assets/src/common/components/index.js @@ -1,3 +1,4 @@ export { default as PrePublishPanel } from './pre-publish-panel'; export { default as withFeaturedImageNotice } from './higher-order/with-featured-image-notice'; +export { default as withEnforcedFileType } from './with-enforced-file-type'; export { default as withCroppedFeaturedImage } from './with-cropped-featured-image'; diff --git a/assets/src/common/components/select-media-frame.js b/assets/src/common/components/select-media-frame.js new file mode 100644 index 00000000000..186fb56586d --- /dev/null +++ b/assets/src/common/components/select-media-frame.js @@ -0,0 +1,220 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { enforceFileSize, enforceFileType, getNoticeTemplate, mediaLibraryHasTwoNotices } from '../helpers'; + +const { wp } = window; + +const NOTICE_CLASSNAME = 'notice notice-warning notice-alt inline'; + +/** + * FeaturedImageSelectionError + * + * @class + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ +const FeaturedImageSelectionError = wp.media.View.extend( { + className: NOTICE_CLASSNAME, + template: ( () => { + const message = sprintf( + /* translators: 1: image width in pixels. 2: image height in pixels. 3: required minimum width in pixels. 4: required minimum height in pixels. */ + __( 'The selected image is too small (%1$s by %2$s pixels). It should have a size of at least %3$s by %4$s pixels.', 'amp' ), + '{{width}}', + '{{height}}', + '{{minWidth}}', + '{{minHeight}}', + ); + + return getNoticeTemplate( message ); + } )(), +} ); + +/** + * SelectionFileTypeError + * + * Applies if the featured image has the wrong file type, like .mov or .txt. + * Very similar to the FeaturedImageSelectionError class. + * + * @class + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ +export const SelectionFileTypeError = wp.media.View.extend( { + className: 'notice notice-warning notice-alt inline', + template: ( () => { + const message = sprintf( + /* translators: 1: the selected file type. */ + __( 'The selected file mime type, %1$s, is not allowed.', 'amp' ), + '{{mimeType}}', + ); + + return getNoticeTemplate( message ); + } )(), +} ); + +/** + * SelectionFileSizeError + * + * Applies when the video size is more than a certain amount of MB per second. + * Very similar to the FeaturedImageSelectionError class. + * + * @class + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + */ +export const SelectionFileSizeError = wp.media.View.extend( { + className: NOTICE_CLASSNAME, + template: ( () => { + const message = sprintf( + /* translators: 1: the recommended max MB per second for videos. 2: the actual MB per second of the video. */ + __( 'A video size of less than %1$s MB per second is recommended. The selected video is %2$s MB per second.', 'amp' ), + '{{maxVideoMegabytesPerSecond}}', + '{{actualVideoMegabytesPerSecond}}', + ); + + return getNoticeTemplate( message ); + } )(), +} ); + +/** + * FeaturedImageToolbarSelect + * + * Prevent selection of an image that does not meet the minimum requirements. + * Also enforces the file type, ensuring that it was in the allowedTypes prop. + * + * @class + * @augments wp.media.view.Toolbar.Select + * @augments wp.media.view.Toolbar + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + * @inheritDoc + */ +export const FeaturedImageToolbarSelect = wp.media.view.Toolbar.Select.extend( { + /** + * Refresh the view. + */ + refresh() { + wp.media.view.Toolbar.Select.prototype.refresh.call( this ); + + const state = this.controller.state(); + const selection = state.get( 'selection' ); + + const attachment = selection.models[ 0 ]; + const minWidth = state.collection.get( 'library' ).get( 'suggestedWidth' ); + const minHeight = state.collection.get( 'library' ).get( 'suggestedHeight' ); + + if ( + ! attachment || + 'image' !== attachment.get( 'type' ) || + ! attachment.get( 'width' ) || + ( attachment.get( 'width' ) >= minWidth && attachment.get( 'height' ) >= minHeight ) + ) { + this.secondary.unset( 'select-error' ); + } else { + this.secondary.set( + 'select-error', + new FeaturedImageSelectionError( { + minWidth, + minHeight, + width: attachment.get( 'width' ), + height: attachment.get( 'height' ), + } ) + ); + } + + enforceFileType.call( this, attachment, SelectionFileTypeError ); + }, +} ); + +/** + * EnforcedFileToolbarSelect + * + * Prevents selecting an attachment that has the wrong file type, like .mov or .txt. + * + * @class + * @augments wp.media.view.Toolbar.Select + * @augments wp.media.view.Toolbar + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + * @inheritDoc + */ +export const EnforcedFileToolbarSelect = wp.media.view.Toolbar.Select.extend( { + /** + * Refresh the view. + */ + refresh() { + wp.media.view.Toolbar.Select.prototype.refresh.call( this ); + + const state = this.controller.state(); + const selection = state.get( 'selection' ); + const attachment = selection.models[ 0 ]; + + enforceFileType.call( this, attachment, SelectionFileTypeError ); + enforceFileSize.call( this, attachment, SelectionFileSizeError ); + + // If there are two notices, like for wrong size and type, prevent the notices from covering the media. + const mediaFrame = this.$el.parents( '.media-frame' ); + if ( mediaFrame ) { + mediaFrame.toggleClass( 'has-two-notices', mediaLibraryHasTwoNotices.call( this ) ); + } + }, +} ); + +/** + * Gets the select media frame, which displays in the bottom of the Media Library. + * + * @param {Class} ToolbarSelect The select toolbar that display at the bottom of the Media Library. + * @return {Class} ToolbarSelect A wp.media Class that creates a Media Library toolbar. + */ +export const getSelectMediaFrame = ( ToolbarSelect ) => { + /** + * Selects a featured image from the media library. + * + * @class + * @augments wp.media.view.MediaFrame.Select + * @augments wp.media.view.MediaFrame + * @augments wp.media.view.Frame + * @augments wp.media.View + * @augments wp.Backbone.View + * @augments Backbone.View + * @mixes wp.media.controller.StateMachine + * @inheritDoc + */ + return wp.media.view.MediaFrame.Select.extend( { + /** + * Create select toolbar. + * + * The only reason for this method is to override the select toolbar view class. + * + * @param {Object} toolbar + * @param {Object} [options={}] + * @this wp.media.controller.Region + */ + createSelectToolbar( toolbar, options ) { + options = options || this.options.button || {}; + options.controller = this; + options = { + ...options, + allowedTypes: get( this, [ 'options', 'allowedTypes' ], null ), + }; + + toolbar.view = new ToolbarSelect( options ); + }, + } ); +}; diff --git a/assets/src/common/components/with-cropped-featured-image.js b/assets/src/common/components/with-cropped-featured-image.js index caadb72803d..53ff4a6deb0 100644 --- a/assets/src/common/components/with-cropped-featured-image.js +++ b/assets/src/common/components/with-cropped-featured-image.js @@ -12,8 +12,9 @@ import { dispatch } from '@wordpress/data'; /** * Internal dependencies */ -import FeaturedImageSelectMediaFrame from './featured-image-select-media-frame'; +import { FeaturedImageToolbarSelect, getSelectMediaFrame } from './select-media-frame'; import FeaturedImageCropper from './featured-image-cropper'; +import { getAspectRatioType } from '../helpers'; const { wp } = window; @@ -23,13 +24,19 @@ const { wp } = window; * Only applies to the MediaUpload in the Featured Image component, PostFeaturedImage. * Suggests cropping of the featured image if it's not 696 x 928. * Mostly copied from customize-controls.js. + * The optional alternateMinImageDimensions are used for the crop size when they are the same aspect ratio type as the actual image dimensions. + * For example, if the selected image has a portrait aspect ratio, and the alternateMinImageDimensions are also portrait, + * this will use the alternate dimensions as long as the selected image is big enough. + * Otherwise, this will use the minImageDimensions. * - * @param {Function} InitialMediaUpload The MediaUpload component, passed from the filter. - * @param {Object} minImageDimensions Minimum required image dimensions. + * @param {Function} InitialMediaUpload The MediaUpload component, passed from the filter. + * @param {Object} minImageDimensions Minimum required image dimensions. + * @param {Object} alternateMinImageDimensions Alternate required image dimensions, like portrait dimensions (optional). * @return {Function} The wrapped component. */ -export default ( InitialMediaUpload, minImageDimensions ) => { +export default ( InitialMediaUpload, minImageDimensions, alternateMinImageDimensions = {} ) => { const { width: EXPECTED_WIDTH, height: EXPECTED_HEIGHT } = minImageDimensions; + const { width: ALTERNATE_EXPECTED_WIDTH, height: ALTERNATE_EXPECTED_HEIGHT } = alternateMinImageDimensions; /** * Mostly copied from customize-controls.js, with slight changes. @@ -40,14 +47,14 @@ export default ( InitialMediaUpload, minImageDimensions ) => { /** * Constructs the class. */ - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); // @todo This should be a different event. // This class should only be present in the MediaUpload for the Featured Image. - if ( this.props.modalClass && 'editor-post-featured-image__media-modal' === this.props.modalClass ) { - this.init = this.init.bind( this ); - this.init(); + if ( 'editor-post-featured-image__media-modal' === this.props.modalClass ) { + this.initFeaturedImage = this.initFeaturedImage.bind( this ); + this.initFeaturedImage(); } } @@ -61,8 +68,10 @@ export default ( InitialMediaUpload, minImageDimensions ) => { * * @see wp.media.CroppedImageControl.initFrame */ - init() { + initFeaturedImage() { + const FeaturedImageSelectMediaFrame = getSelectMediaFrame( FeaturedImageToolbarSelect ); this.frame = new FeaturedImageSelectMediaFrame( { + allowedTypes: this.props.allowedTypes, button: { text: __( 'Select', 'amp' ), close: false, @@ -92,7 +101,7 @@ export default ( InitialMediaUpload, minImageDimensions ) => { this.frame.on( 'cropped', this.onCropped, this ); this.frame.on( 'skippedcrop', this.onSkippedCrop, this ); this.frame.on( 'close', () => { - this.init(); + this.initFeaturedImage(); }, this ); } @@ -111,8 +120,20 @@ export default ( InitialMediaUpload, minImageDimensions ) => { const realWidth = attachment.get( 'width' ), realHeight = attachment.get( 'height' ); - let xInit = parseInt( EXPECTED_WIDTH, 10 ), - yInit = parseInt( EXPECTED_HEIGHT, 10 ); + /* + * Only use the alternate dimensions if the image is big enough, and if they have the same aspect ratio type. + * For example, if they are portrait dimensions, the real image must also have portrait dimensions. + * This allows having an alternative crop size, for example, a portrait crop in addition to a landscape crop. + */ + const shouldUseAlternateWidthAndHeight = ( + ALTERNATE_EXPECTED_WIDTH && + realWidth >= ALTERNATE_EXPECTED_WIDTH && + realHeight >= ALTERNATE_EXPECTED_HEIGHT && + getAspectRatioType( realWidth, realHeight ) === getAspectRatioType( ALTERNATE_EXPECTED_WIDTH, ALTERNATE_EXPECTED_HEIGHT ) + ); + + let xInit = shouldUseAlternateWidthAndHeight ? parseInt( ALTERNATE_EXPECTED_WIDTH ) : parseInt( EXPECTED_WIDTH ), + yInit = shouldUseAlternateWidthAndHeight ? parseInt( ALTERNATE_EXPECTED_HEIGHT ) : parseInt( EXPECTED_HEIGHT ); const ratio = xInit / yInit, xImg = xInit, @@ -121,10 +142,10 @@ export default ( InitialMediaUpload, minImageDimensions ) => { // Allow cropping to be skipped because the image is at least the required dimensions, so skipping crop will auto crop. controller.set( 'canSkipCrop', true ); - if ( realWidth / realHeight > ratio ) { + if ( realWidth / realHeight > ratio ) { // This is wider than the expected ratio. yInit = realHeight; xInit = yInit * ratio; - } else { + } else { // This is either the expected ratio or taller. xInit = realWidth; yInit = xInit / ratio; } @@ -157,7 +178,10 @@ export default ( InitialMediaUpload, minImageDimensions ) => { */ onSelectImage() { const attachment = this.frame.state().get( 'selection' ).first().toJSON(); - if ( EXPECTED_WIDTH === attachment.width && EXPECTED_HEIGHT === attachment.height ) { + if ( + ( EXPECTED_WIDTH === attachment.width && EXPECTED_HEIGHT === attachment.height ) || + ( ALTERNATE_EXPECTED_WIDTH && ALTERNATE_EXPECTED_WIDTH === attachment.width && ALTERNATE_EXPECTED_HEIGHT === attachment.height ) + ) { this.setImageFromURL( attachment.url, attachment.id, attachment.width, attachment.height ); this.frame.close(); } else { diff --git a/assets/src/common/components/with-enforced-file-type.js b/assets/src/common/components/with-enforced-file-type.js new file mode 100644 index 00000000000..66268582872 --- /dev/null +++ b/assets/src/common/components/with-enforced-file-type.js @@ -0,0 +1,92 @@ +/** + * External dependencies + */ +import { isEqual } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { EnforcedFileToolbarSelect, getSelectMediaFrame } from './select-media-frame'; + +const { wp } = window; + +/** + * Gets a wrapped version of MediaUpload, to enforce that it has the correct file type. + * + * Only intended for the MediaUpload in the Core Video block and the AMP Story 'Background Media' control. + * Though this will also apply to any other MediaUpload with allowedTypes of [ 'video' ]. + * Partly copied from customize-controls.js. + * + * @param {Function} InitialMediaUpload The MediaUpload component, passed from the filter. + * @return {Function} The wrapped component. + */ +export default ( InitialMediaUpload ) => { + /** + * Partly copied from customize-controls.js. + * + * @see wp.media.HeaderControl + */ + return class EnforcedFileTypeMediaUpload extends InitialMediaUpload { + /** + * Constructs the class. + */ + constructor( ...args ) { + super( ...args ); + + // This class should only be present in the MediaUpload for the AMP Story 'Background Media' or when only 'video' types are allowed, like in the Core Video block. + if ( 'story-background-media' === this.props.id || isEqual( [ 'video/mp4' ], this.props.allowedTypes ) ) { + this.initFileTypeMedia = this.initFileTypeMedia.bind( this ); + this.initFileTypeMedia(); + } + } + + /** + * Initialize. + * + * Mainly copied from customize-controls.js. + * Overwrites the Media Library frame, this.frame. + * And checks that the file type is correct. + * + * @see wp.media.CroppedImageControl.initFrame + */ + initFileTypeMedia() { + const SelectMediaFrame = getSelectMediaFrame( EnforcedFileToolbarSelect ); + const previousOnSelect = this.onSelect; + const isVideo = isEqual( [ 'video' ], this.props.allowedTypes ); + const queryType = isVideo ? 'video/mp4' : this.props.allowedTypes; // For the Video block, only display .mp4 files. + this.frame = new SelectMediaFrame( { + allowedTypes: this.props.allowedTypes, + button: { + text: __( 'Select', 'amp' ), + close: false, + }, + states: [ + new wp.media.controller.Library( { + title: __( 'Select or Upload Media', 'amp' ), + library: wp.media.query( { type: queryType } ), + multiple: false, + date: false, + priority: 20, + } ), + ], + } ); + + wp.media.frame = this.frame; + this.frame.on( 'close', () => { + this.initFileTypeMedia(); + }, this ); + + this.frame.on( 'select', () => { + if ( previousOnSelect ) { + previousOnSelect(); + } + this.frame.close(); + }, this ); + } + }; +}; diff --git a/assets/src/common/constants.js b/assets/src/common/constants.js index 9373c45aff0..df372ddddd9 100644 --- a/assets/src/common/constants.js +++ b/assets/src/common/constants.js @@ -1,3 +1,8 @@ // See https://github.com/ampproject/amphtml/blob/e7a1b3ff97645ec0ec482192205134bd0735943c/extensions/amp-fit-text/0.1/amp-fit-text.js#L81-L85 export const MIN_FONT_SIZE = 6; export const MAX_FONT_SIZE = 72; +export const MINIMUM_FEATURED_IMAGE_WIDTH = 1200; +export const MEGABYTE_IN_BYTES = 1000000; +export const VIDEO_ALLOWED_MEGABYTES_PER_SECOND = 1; +export const FILE_TYPE_ERROR_VIEW = 'select-file-type-error'; +export const FILE_SIZE_ERROR_VIEW = 'select-file-size-error'; diff --git a/assets/src/common/helpers/index.js b/assets/src/common/helpers/index.js index 2f1acbca5d1..4c73c2fcc3c 100644 --- a/assets/src/common/helpers/index.js +++ b/assets/src/common/helpers/index.js @@ -1,8 +1,22 @@ +/** + * External dependencies + */ +import { get, has, includes, reduce, template } from 'lodash'; /** * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; import { getColorObjectByAttributeValues, getColorObjectByColorValue } from '@wordpress/block-editor'; +/** + * Internal dependencies + */ +import { + FILE_SIZE_ERROR_VIEW, + FILE_TYPE_ERROR_VIEW, + MEGABYTE_IN_BYTES, + MINIMUM_FEATURED_IMAGE_WIDTH, + VIDEO_ALLOWED_MEGABYTES_PER_SECOND, +} from '../constants'; /** * Determines whether whether the image has the minimum required dimensions. @@ -46,13 +60,26 @@ export const hasMinimumDimensions = ( media, dimensions ) => { * @return {Object} Minimum dimensions including width and height. */ export const getMinimumFeaturedImageDimensions = () => { - const width = 1200; + const width = MINIMUM_FEATURED_IMAGE_WIDTH; const height = width * ( 9 / 16 ); return { width, height }; }; +/** + * Get minimum dimensions for a portrait featured image, but not for an AMP Story. + * + * @return {Object} Minimum dimensions including width and height. + */ +export const getMinimumPortraitFeaturedImageDimensions = () => { + const width = MINIMUM_FEATURED_IMAGE_WIDTH; + + const height = Math.floor( width * ( 16 / 9 ) ); + + return { width, height }; +}; + /** * Validates the an image based on requirements. * @@ -160,3 +187,208 @@ export const getBackgroundColorWithOpacity = ( colors, backgroundColor, customBa return undefined; }; + +/** + * Gets The aspect ratio type, either 'landscape', 'portrait', or 'square'. + * + * @param {number} width The image width. + * @param {number} height The image height. + * @return {string|null} The aspect ratio type: 'landscape', 'portrait', or 'square'. + */ +export const getAspectRatioType = ( width, height ) => { + if ( ! width || ! height ) { + return null; + } + + if ( width > height ) { + return 'landscape'; + } else if ( height > width ) { + return 'portrait'; + } + + return 'square'; +}; + +/** + * Gets the compiled template for a given notice message. + * + * @param {string} message The message to display in the template. + * @return {Function} compiledTemplate A function accepting the data, which creates a compiled template. + */ +export const getNoticeTemplate = ( message ) => { + const errorTemplate = template( + `

${ message }

`, + { + evaluate: /<#([\s\S]+?)#>/g, + interpolate: /\{\{\{([\s\S]+?)\}\}\}/g, + escape: /\{\{([^\}]+?)\}\}(?!\})/g, + } + ); + + return ( data ) => { + return errorTemplate( data ); + }; +}; + +/** + * Gets whether the file type is allowed. + * + * For videos, only 'video/mp4' mime types should be allowed. + * But the allowedTypes property only has 'video', and it can accidentally allow mime types like 'video/quicktime'. + * So this returns false for videos with mime types other than 'video/mp4'. + * + * @param {Object} attachment The file to evaluate. + * @param {Array} allowedTypes The allowed file types. + * @return {boolean} Whether the file type is allowed. + */ +export const isFileTypeAllowed = ( attachment, allowedTypes ) => { + const fileType = attachment.get( 'type' ); + const mimeType = attachment.get( 'mime' ); + + if ( ! includes( allowedTypes, fileType ) && ! includes( allowedTypes, mimeType ) ) { + return false; + } + + if ( 'video' === fileType && 'video/mp4' !== mimeType ) { + return false; + } + + return true; +}; + +/** + * If the attachment has the wrong file type, this displays a notice in the Media Library and disables the 'Select' button. + * + * This is not an arrow function so that it can be called with enforceFileType.call( this, foo, bar ). + * + * @param {Object} attachment The selected attachment. + * @param {Object} SelectionError The error to display. + */ +export const enforceFileType = function( attachment, SelectionError ) { + if ( ! attachment ) { + return; + } + + const allowedTypes = get( this, [ 'options', 'allowedTypes' ], null ); + const selectButton = this.get( 'select' ); + + // If the file type isn't allowed, display a notice and disable the 'Select' button. + if ( allowedTypes && attachment.get( 'type' ) && ! isFileTypeAllowed( attachment, allowedTypes ) ) { + this.secondary.set( + FILE_TYPE_ERROR_VIEW, + new SelectionError( { mimeType: attachment.get( 'mime' ) } ) + ); + if ( selectButton && selectButton.model ) { + selectButton.model.set( 'disabled', true ); // Disable the button to select the file. + } + } else { + this.secondary.unset( FILE_TYPE_ERROR_VIEW ); + if ( selectButton && selectButton.model ) { + selectButton.model.set( 'disabled', false ); // Enable the button to select the file. + } + } +}; + +/** + * If the attachment has the wrong file size, this displays a notice in the Media Library and disables the 'Select' button. + * + * This is not an arrow function so that it can be called with enforceFileSize.call( this, foo, bar ). + * + * @param {Object} attachment The selected attachment. + * @param {Object} SelectionError The error to display. + */ +export const enforceFileSize = function( attachment, SelectionError ) { + if ( ! attachment ) { + return; + } + + const isVideo = 'video' === get( attachment, [ 'media_type' ], null ) || 'video' === get( attachment, [ 'attributes', 'type' ], null ); + + // If the file type is 'video' and its size is over the limit, display a notice in the Media Library. + if ( isVideo && isVideoSizeExcessive( getVideoBytesPerSecond( attachment ) ) ) { + this.secondary.set( + FILE_SIZE_ERROR_VIEW, + new SelectionError( { + actualVideoMegabytesPerSecond: Math.round( getVideoBytesPerSecond( attachment ) / MEGABYTE_IN_BYTES ), + maxVideoMegabytesPerSecond: VIDEO_ALLOWED_MEGABYTES_PER_SECOND, + } ) + ); + } else { + this.secondary.unset( FILE_SIZE_ERROR_VIEW ); + } +}; + +/** + * Gets whether the Media Library has two notices. + * + * It's possible to have a notice that the file type and size are wrong. + * In that case, this will need different styling, so the notices don't overlap the media. + * + * @return {boolean} Whether the Media Library has two notices. + */ +export const mediaLibraryHasTwoNotices = function() { + return Boolean( this.secondary.get( FILE_TYPE_ERROR_VIEW ) ) && Boolean( this.secondary.get( FILE_SIZE_ERROR_VIEW ) ); +}; + +/** + * Gets the number of megabytes per second for the video. + * + * @param {Object} media The media object of the video. + * @return {?number} Number of megabytes per second, or null if media details unavailable. + */ +export const getVideoBytesPerSecond = ( media ) => { + if ( has( media, [ 'media_details', 'filesize' ] ) && has( media, [ 'media_details', 'length' ] ) ) { + return media.media_details.filesize / media.media_details.length; + } else if ( has( media, [ 'attributes', 'filesizeInBytes' ] ) && has( media, [ 'attributes', 'fileLength' ] ) ) { + return media.attributes.filesizeInBytes / getSecondsFromTime( media.attributes.fileLength ); + } + + return null; +}; + +/** + * Gets whether the video file size is over a certain amount of bytes per second. + * + * @param {number} videoSize Video size per second, in bytes. + * @return {boolean} Whether the file size is more than a certain amount of MB per second, or null of the data isn't available. + */ +export const isVideoSizeExcessive = ( videoSize ) => { + return videoSize > VIDEO_ALLOWED_MEGABYTES_PER_SECOND * MEGABYTE_IN_BYTES; +}; + +/** + * Gets the number of seconds in a colon-separated time string, like '01:10'. + * + * @param {string} time A colon-separated time, like '0:12'. + * @return {number} seconds The number of seconds in the time, like 12. + */ +export const getSecondsFromTime = ( time ) => { + const minuteInSeconds = 60; + const splitTime = time.split( ':' ); + + return reduce( + splitTime, + ( totalSeconds, timeSection, index ) => { + const parsedTimeSection = isNaN( parseInt( timeSection ) ) ? 0 : parseInt( timeSection ); + const distanceFromRight = splitTime.length - 1 - index; + const multiple = Math.pow( minuteInSeconds, distanceFromRight ); // This should be 1 for seconds, 60 for minutes, 360 for hours... + return totalSeconds + ( multiple * parsedTimeSection ); + }, + 0 + ); +}; + +/** + * Given a URL, returns file size in bytes. + * + * @param {string} url URL to a file. + * @return {Promise} File size in bytes. + */ +export const getContentLengthFromUrl = async ( url ) => { + const { fetch } = window; + + const response = await fetch( url, { + method: 'head', + } ); + return Number( response.headers.get( 'content-length' ) ); +}; diff --git a/assets/src/common/helpers/test/enforceFileSize.js b/assets/src/common/helpers/test/enforceFileSize.js new file mode 100644 index 00000000000..f3563050e29 --- /dev/null +++ b/assets/src/common/helpers/test/enforceFileSize.js @@ -0,0 +1,79 @@ +/** + * Internal dependencies + */ +import { enforceFileSize } from '../'; +import { Mock, AlternateMock, MockSelectionError } from './fixtures/mockClasses'; +import { FILE_SIZE_ERROR_VIEW } from '../../constants'; + +describe( 'enforceFileSize', () => { + it( 'should have a new error when the video file size is too big', () => { + const mockThis = new Mock(); + const selectButton = { model: new AlternateMock() }; + mockThis.set( { + secondary: new AlternateMock(), + select: selectButton, + } ); + + const attachment = new Mock(); + const filesize = 12000000; + const length = 4; + attachment.set( { + media_details: { filesize, length }, + media_type: 'video', + } ); + + enforceFileSize.call( mockThis, attachment, MockSelectionError ); + const actualSelectionError = mockThis.secondary.get( FILE_SIZE_ERROR_VIEW ); + + expect( actualSelectionError.get( 'maxVideoMegabytesPerSecond' ) ).toBe( 1 ); + expect( actualSelectionError.get( 'actualVideoMegabytesPerSecond' ) ).toBe( 3 ); + + // This shouldn't disable the 'Select' button in the Media Library. + expect( selectButton.model.get( 'disabled' ) ).toBeUndefined( ); + } ); + + it( 'should not have an error when the video file size is under the maximum', () => { + const mockThis = new Mock(); + const selectButton = { model: new AlternateMock() }; + mockThis.set( { + secondary: new AlternateMock(), + select: selectButton, + } ); + + const attachment = new Mock(); + const filesize = 6000000; + const length = 6; + attachment.set( { + media_details: { filesize, length }, + media_type: 'video', + } ); + + enforceFileSize.call( mockThis, attachment, MockSelectionError ); + + expect( mockThis.secondary.get( FILE_SIZE_ERROR_VIEW ) ).toBeUndefined( ); + expect( selectButton.model.get( 'disabled' ) ).toBeUndefined( ); + } ); + + it( 'should not have an error if the file type is not a video', () => { + const mockThis = new Mock(); + const selectButton = { model: new AlternateMock() }; + mockThis.set( { + secondary: new AlternateMock(), + select: selectButton, + } ); + + const attachment = new Mock(); + const filesize = 12000000; + const length = 4; + const nonVideo = 'image'; + attachment.set( { + media_details: { filesize, length }, + media_type: nonVideo, + } ); + + enforceFileSize.call( mockThis, attachment, MockSelectionError ); + + expect( mockThis.secondary.get( FILE_SIZE_ERROR_VIEW ) ).toBeUndefined( ); + expect( selectButton.model.get( 'disabled' ) ).toBeUndefined( ); + } ); +} ); diff --git a/assets/src/common/helpers/test/enforceFileType.js b/assets/src/common/helpers/test/enforceFileType.js new file mode 100644 index 00000000000..ea931f0b5d6 --- /dev/null +++ b/assets/src/common/helpers/test/enforceFileType.js @@ -0,0 +1,84 @@ +/** + * Internal dependencies + */ +import { enforceFileType } from '../'; +import { FILE_TYPE_ERROR_VIEW } from '../../constants'; +import { Mock, AlternateMock, MockSelectionError } from './fixtures/mockClasses'; + +const videoAllowedTypes = [ 'video' ]; +const imageAllowedTypes = [ 'image' ]; + +/** + * Gets an instance of Mock to pass as the this argument to call(). + * + * @param {Array} allowedTypes The allowed file types. + * @return {Mock} An instance of Mock. + */ +const getMockThis = ( allowedTypes ) => { + const mockThis = new Mock(); + mockThis.set( { + secondary: new AlternateMock(), + options: { allowedTypes }, + } ); + + return mockThis; +}; + +describe( 'enforceFileType', () => { + it( 'should have a new error and disable the button when the mimeType is video/quicktime', () => { + const mockThis = getMockThis( videoAllowedTypes ); + const attachment = new Mock(); + const mimeType = 'video/quicktime'; + const selectButton = { model: new AlternateMock() }; + mockThis.set( { select: selectButton } ); + attachment.set( { type: 'video', mime: mimeType } ); + + enforceFileType.call( mockThis, attachment, MockSelectionError ); + const actualSelectionError = mockThis.secondary.get( FILE_TYPE_ERROR_VIEW ); + + expect( actualSelectionError.get( 'mimeType' ) ).toBe( mimeType ); + expect( selectButton.model.get( 'disabled' ) ).toBe( true ); + } ); + + it( 'should have a new error and disable the button when the file type is text', () => { + const mockThis = getMockThis( videoAllowedTypes ); + const attachment = new Mock(); + const mimeType = 'text/plain'; + const selectButton = { model: new AlternateMock() }; + mockThis.set( { select: selectButton } ); + attachment.set( { type: 'text', mime: mimeType } ); + + enforceFileType.call( mockThis, attachment, MockSelectionError ); + const actualSelectionError = mockThis.secondary.get( FILE_TYPE_ERROR_VIEW ); + + expect( actualSelectionError.get( 'mimeType' ) ).toBe( mimeType ); + expect( selectButton.model.get( 'disabled' ) ).toBe( true ); + } ); + + it( 'should not have an error or disable the button when the mimeType is video/mp4', () => { + const mockThis = getMockThis( videoAllowedTypes ); + const attachment = new Mock(); + const correctMimeType = 'video/mp4'; + const selectButton = { model: new AlternateMock() }; + mockThis.set( { select: selectButton } ); + attachment.set( { type: 'video', mime: correctMimeType } ); + + enforceFileType.call( mockThis, attachment, MockSelectionError ); + + expect( mockThis.secondary.get( FILE_TYPE_ERROR_VIEW ) ).toBeUndefined( ); + expect( selectButton.model.get( 'disabled' ) ).toBe( false ); + } ); + + it( 'should not have an error or disable the button when type is an image and that is allowed', () => { + const mockThis = getMockThis( imageAllowedTypes ); + const attachment = new Mock(); + const selectButton = { model: new AlternateMock() }; + mockThis.set( { select: selectButton } ); + attachment.set( { type: 'image' } ); + + enforceFileType.call( mockThis, attachment, MockSelectionError ); + + expect( mockThis.secondary.get( FILE_TYPE_ERROR_VIEW ) ).toBeUndefined( ); + expect( selectButton.model.get( 'disabled' ) ).toBe( false ); + } ); +} ); diff --git a/assets/src/common/helpers/test/fixtures/mockClasses.js b/assets/src/common/helpers/test/fixtures/mockClasses.js new file mode 100644 index 00000000000..5e5c2e25a0a --- /dev/null +++ b/assets/src/common/helpers/test/fixtures/mockClasses.js @@ -0,0 +1,83 @@ +/** + * A testing class that gets and sets values. + * + * @class + */ +export class Mock { + /** + * Gets a given value. + * + * @param {string} key The key of the value to get. + * @return {mixed} value The value corresponding to the key. + */ + get( key ) { + if ( this.hasOwnProperty( key ) ) { + return this[ key ]; + } + + return undefined; + } + + /** + * Sets the values. + * + * @param {Object} values The values to set. + */ + set( values ) { + for ( const property in values ) { + if ( values.hasOwnProperty( property ) ) { + this[ property ] = values[ property ]; + } + } + } +} + +/** + * Mocks the secondary object that stores the file error. + * + * @class + */ +export class AlternateMock extends Mock { + /** + * Sets the error value. + * + * Different from Mock.set, as it accepts 2 arguments. + * + * @param {string} key The name of the error. + * @param {Object} value The file type error object. + */ + set( key, value ) { + this[ key ] = value; + } + + /** + * Unsets the key and value stored at a given key. + * + * @param {string} key The key of the value to unset. + */ + unset( key ) { + delete this[ key ]; + } +} + +/** + * Mocks a selection error. + * + * @class + */ +export class MockSelectionError extends Mock { + /** + * Class constructor. + * + * @param {Object} errorData Error data. + */ + constructor( errorData = {} ) { + super( errorData ); + + for ( const name in errorData ) { + if ( errorData.hasOwnProperty( name ) ) { + this[ name ] = errorData[ name ]; + } + } + } +} diff --git a/assets/src/common/helpers/test/getAspectRatioType.js b/assets/src/common/helpers/test/getAspectRatioType.js new file mode 100644 index 00000000000..673df7a0983 --- /dev/null +++ b/assets/src/common/helpers/test/getAspectRatioType.js @@ -0,0 +1,19 @@ +/** + * Internal dependencies + */ +import { getAspectRatioType } from '../'; + +describe( 'getAspectRatioType', () => { + it( 'should return landscape when the aspect ratio is landscape', () => { + expect( getAspectRatioType( 1400, 1000 ) ).toStrictEqual( 'landscape' ); + } ); + it( 'should return portrait when the aspect ratio is portrait', () => { + expect( getAspectRatioType( 1400, 1800 ) ).toStrictEqual( 'portrait' ); + } ); + it( 'should return square when the aspect ratio is square', () => { + expect( getAspectRatioType( 1200, 1200 ) ).toStrictEqual( 'square' ); + } ); + it( 'should return null when the arguments are null', () => { + expect( getAspectRatioType( null, null ) ).toStrictEqual( null ); + } ); +} ); diff --git a/assets/src/common/helpers/test/getBackgroundColorWithOpacity.js b/assets/src/common/helpers/test/getBackgroundColorWithOpacity.js index a1f81580f82..44bc44344cb 100644 --- a/assets/src/common/helpers/test/getBackgroundColorWithOpacity.js +++ b/assets/src/common/helpers/test/getBackgroundColorWithOpacity.js @@ -66,6 +66,6 @@ describe( 'getBackgroundColorWithOpacity', () => { } ); it( 'should return nothing if no color is passed at all', () => { - expect( getBackgroundColorWithOpacity( [], undefined, undefined ) ).toBe( undefined ); + expect( getBackgroundColorWithOpacity( [], undefined, undefined ) ).toBeUndefined( ); } ); } ); diff --git a/assets/src/common/helpers/test/getMinimumFeaturedImageDimensions.js b/assets/src/common/helpers/test/getMinimumFeaturedImageDimensions.js index 84d3b9501d7..35a9c0c7d38 100644 --- a/assets/src/common/helpers/test/getMinimumFeaturedImageDimensions.js +++ b/assets/src/common/helpers/test/getMinimumFeaturedImageDimensions.js @@ -4,7 +4,7 @@ import { getMinimumFeaturedImageDimensions } from '../'; describe( 'getMinimumFeaturedImageDimensions', () => { - it( 'should return size with correct aspect ration', () => { - expect( getMinimumFeaturedImageDimensions() ).toEqual( { width: 1200, height: 675 } ); + it( 'should return size with correct aspect ratio', () => { + expect( getMinimumFeaturedImageDimensions() ).toStrictEqual( { width: 1200, height: 675 } ); } ); } ); diff --git a/assets/src/common/helpers/test/getMinimumPortraitFeaturedImageDimensions.js b/assets/src/common/helpers/test/getMinimumPortraitFeaturedImageDimensions.js new file mode 100644 index 00000000000..c12eb710a5e --- /dev/null +++ b/assets/src/common/helpers/test/getMinimumPortraitFeaturedImageDimensions.js @@ -0,0 +1,10 @@ +/** + * Internal dependencies + */ +import { getMinimumPortraitFeaturedImageDimensions } from '../'; + +describe( 'getMinimumPortraitFeaturedImageDimensions', () => { + it( 'should return size with correct portrait aspect ratio', () => { + expect( getMinimumPortraitFeaturedImageDimensions() ).toStrictEqual( { width: 1200, height: 2133 } ); + } ); +} ); diff --git a/assets/src/common/helpers/test/getNoticeTemplate.js b/assets/src/common/helpers/test/getNoticeTemplate.js new file mode 100644 index 00000000000..55bf6bb9e07 --- /dev/null +++ b/assets/src/common/helpers/test/getNoticeTemplate.js @@ -0,0 +1,22 @@ +/** + * WordPress dependencies + */ +import { sprintf } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { getNoticeTemplate } from '../'; + +describe( 'getNoticeTemplate', () => { + const message = 'This is an example message'; + const template = getNoticeTemplate( message ); + const type = typeof template; + + it( 'should have the proper type', () => { + expect( type ).toBe( 'function' ); + } ); + it( 'should return the correct message', () => { + expect( template() ).toBe( sprintf( '

%s

', message ) ); + } ); +} ); diff --git a/assets/src/common/helpers/test/getRgbaFromHex.js b/assets/src/common/helpers/test/getRgbaFromHex.js index 7b0da0a195b..05eac8eea4a 100644 --- a/assets/src/common/helpers/test/getRgbaFromHex.js +++ b/assets/src/common/helpers/test/getRgbaFromHex.js @@ -5,24 +5,24 @@ import { getRgbaFromHex } from '../'; describe( 'getRgbaFromHex', () => { it( 'should reject invalid hex values', () => { - expect( getRgbaFromHex( undefined ) ).toEqual( [] ); - expect( getRgbaFromHex( '' ) ).toEqual( [] ); - expect( getRgbaFromHex( null ) ).toEqual( [] ); + expect( getRgbaFromHex( undefined ) ).toStrictEqual( [] ); + expect( getRgbaFromHex( '' ) ).toStrictEqual( [] ); + expect( getRgbaFromHex( null ) ).toStrictEqual( [] ); } ); it( 'should remove leading number sign', () => { - expect( getRgbaFromHex( 'ffffff' ) ).toEqual( [ 255, 255, 255, 1 ] ); - expect( getRgbaFromHex( '#ffffff' ) ).toEqual( [ 255, 255, 255, 1 ] ); + expect( getRgbaFromHex( 'ffffff' ) ).toStrictEqual( [ 255, 255, 255, 1 ] ); + expect( getRgbaFromHex( '#ffffff' ) ).toStrictEqual( [ 255, 255, 255, 1 ] ); } ); it( 'should handle shorthand notation', () => { - expect( getRgbaFromHex( '#f0f' ) ).toEqual( [ 255, 0, 255, 1 ] ); + expect( getRgbaFromHex( '#f0f' ) ).toStrictEqual( [ 255, 0, 255, 1 ] ); } ); it( 'should apply opacity to color', () => { - expect( getRgbaFromHex( '#000000', 0 ) ).toEqual( [ 0, 0, 0, 0 ] ); - expect( getRgbaFromHex( '#000000', 100 ) ).toEqual( [ 0, 0, 0, 1 ] ); - expect( getRgbaFromHex( '#000000', -10 ) ).toEqual( [ 0, 0, 0, 0 ] ); - expect( getRgbaFromHex( '#000000', 10000 ) ).toEqual( [ 0, 0, 0, 1 ] ); + expect( getRgbaFromHex( '#000000', 0 ) ).toStrictEqual( [ 0, 0, 0, 0 ] ); + expect( getRgbaFromHex( '#000000', 100 ) ).toStrictEqual( [ 0, 0, 0, 1 ] ); + expect( getRgbaFromHex( '#000000', -10 ) ).toStrictEqual( [ 0, 0, 0, 0 ] ); + expect( getRgbaFromHex( '#000000', 10000 ) ).toStrictEqual( [ 0, 0, 0, 1 ] ); } ); } ); diff --git a/assets/src/common/helpers/test/getSecondsFromTime.js b/assets/src/common/helpers/test/getSecondsFromTime.js new file mode 100644 index 00000000000..58452f70f1d --- /dev/null +++ b/assets/src/common/helpers/test/getSecondsFromTime.js @@ -0,0 +1,30 @@ +/** + * Internal dependencies + */ +import { getSecondsFromTime } from '../'; + +describe( 'getSecondsFromTime', () => { + it( 'should return the proper seconds if the time only has seconds', () => { + expect( getSecondsFromTime( ':03' ) ).toBe( 3 ); + } ); + + it( 'should return the proper seconds if the time has seconds and 0 for minutes', () => { + expect( getSecondsFromTime( '0:03' ) ).toBe( 3 ); + } ); + + it( 'should return the proper seconds if the time has no minutes but double-digit seconds', () => { + expect( getSecondsFromTime( ':43' ) ).toBe( 43 ); + } ); + + it( 'should return the proper seconds if the time has minutes and seconds', () => { + expect( getSecondsFromTime( '3:43' ) ).toBe( 223 ); + } ); + + it( 'should return the proper seconds if the time has double-digit minutes and seconds', () => { + expect( getSecondsFromTime( '18:43' ) ).toBe( 1123 ); + } ); + + it( 'should return the proper seconds if the time has hours, minutes, and seconds', () => { + expect( getSecondsFromTime( '05:18:43' ) ).toBe( 19123 ); + } ); +} ); diff --git a/assets/src/common/helpers/test/getVideoBytesPerSecond.js b/assets/src/common/helpers/test/getVideoBytesPerSecond.js new file mode 100644 index 00000000000..da7a9c0dbe4 --- /dev/null +++ b/assets/src/common/helpers/test/getVideoBytesPerSecond.js @@ -0,0 +1,37 @@ +/** + * Internal dependencies + */ +import { getVideoBytesPerSecond } from '../'; +import { Mock } from './fixtures/mockClasses'; + +describe( 'getVideoBytesPerSecond', () => { + it( 'should return the proper bytes per second for a simple call', () => { + const attachment = new Mock(); + const filesize = 6000000; + const length = 3; + attachment.set( { media_details: { filesize, length } } ); + expect( getVideoBytesPerSecond( attachment ) ).toBe( 2000000 ); + } ); + + it( 'should return the proper bytes per second for a simple call where the values are stored in the media attributes', () => { + const attachment = new Mock(); + const filesizeInBytes = 63000000; + const fileLength = '1:03'; + attachment.set( { attributes: { filesizeInBytes, fileLength } } ); + expect( getVideoBytesPerSecond( attachment ) ).toBe( 1000000 ); + } ); + + it( 'should return null if the filesize is not defined', () => { + const attachment = new Mock(); + const length = 5; + attachment.set( { media_details: { length } } ); + expect( getVideoBytesPerSecond( attachment ) ).toBeNull( ); + } ); + + it( 'should return null if the length is not defined', () => { + const attachment = new Mock(); + const filesize = 8000000; + attachment.set( { media_details: { filesize } } ); + expect( getVideoBytesPerSecond( attachment ) ).toBeNull( ); + } ); +} ); diff --git a/assets/src/common/helpers/test/isFileTypeAllowed.js b/assets/src/common/helpers/test/isFileTypeAllowed.js new file mode 100644 index 00000000000..af5aa556792 --- /dev/null +++ b/assets/src/common/helpers/test/isFileTypeAllowed.js @@ -0,0 +1,37 @@ +/** + * Internal dependencies + */ +import { isFileTypeAllowed } from '../'; +import { Mock } from './fixtures/mockClasses'; + +describe( 'isFileTypeAllowed', () => { + const attachment = new Mock(); + const videoAllowedTypes = [ 'video' ]; + + it( 'should return false when the file type is text', () => { + attachment.set( { type: 'text' } ); + expect( isFileTypeAllowed( attachment, videoAllowedTypes ) ).toBe( false ); + } ); + + it( 'should return false when the file type is video but the mime type is video/quicktime', () => { + attachment.set( { type: 'video', mime: 'video/quicktime' } ); + expect( isFileTypeAllowed( attachment, videoAllowedTypes ) ).toBe( false ); + } ); + + it( 'should return true when the file type is video and the mime type is correct', () => { + attachment.set( { type: 'video', mime: 'video/mp4' } ); + expect( isFileTypeAllowed( attachment, videoAllowedTypes ) ).toBe( true ); + } ); + + it( 'should return true if the mime type is present in the allowedTypes array', () => { + const videoAllowedTypesWithMp4 = [ 'video/mp4' ]; + attachment.set( { type: 'video', mime: 'video/mp4' } ); + expect( isFileTypeAllowed( attachment, videoAllowedTypesWithMp4 ) ).toBe( true ); + } ); + + it( 'should return true when the file type is image and that is in the allowedTypes', () => { + const imageAllowedTypes = [ 'image' ]; + attachment.set( { type: 'image' } ); + expect( isFileTypeAllowed( attachment, imageAllowedTypes ) ).toBe( true ); + } ); +} ); diff --git a/assets/src/common/helpers/test/isVideoSizeExcessive.js b/assets/src/common/helpers/test/isVideoSizeExcessive.js new file mode 100644 index 00000000000..6be673085c8 --- /dev/null +++ b/assets/src/common/helpers/test/isVideoSizeExcessive.js @@ -0,0 +1,18 @@ +/** + * Internal dependencies + */ +import { isVideoSizeExcessive } from '../'; + +describe( 'isVideoSizeExcessive', () => { + // @todo Use numeric separator once using Node v12.5.0+, see https://v8.dev/features/numeric-separators + it.each( [ + [ 3000000, true ], + [ 1000000.1, true ], + [ 1000000, false ], + [ 500000, false ], + ] )( 'should return excessive video size status', + ( bytesPerSecond, expected ) => { + expect( isVideoSizeExcessive( bytesPerSecond ) ).toBe( expected ); + } + ); +} ); diff --git a/assets/src/common/helpers/test/mediaLibraryHasTwoNotices.js b/assets/src/common/helpers/test/mediaLibraryHasTwoNotices.js new file mode 100644 index 00000000000..6ba1c41da01 --- /dev/null +++ b/assets/src/common/helpers/test/mediaLibraryHasTwoNotices.js @@ -0,0 +1,36 @@ +/** + * Internal dependencies + */ +import { mediaLibraryHasTwoNotices } from '../'; +import { Mock, AlternateMock } from './fixtures/mockClasses'; +import { FILE_TYPE_ERROR_VIEW, FILE_SIZE_ERROR_VIEW } from '../../constants'; + +describe( 'mediaLibraryHasTwoNotices', () => { + it( 'should return false when none of the notices appear', () => { + const mockThis = new Mock(); + mockThis.set( { + secondary: new AlternateMock(), + } ); + + expect( mediaLibraryHasTwoNotices.call( mockThis ) ).toBe( false ); + } ); + + it( 'should return false when only one of the notices appears', () => { + const mockThis = new Mock(); + const secondary = new AlternateMock(); + secondary.set( FILE_TYPE_ERROR_VIEW, { foo: 'baz' } ); + mockThis.set( { secondary } ); + + expect( mediaLibraryHasTwoNotices.call( mockThis ) ).toBe( false ); + } ); + + it( 'should return true when both of the notices appear', () => { + const mockThis = new Mock(); + const secondary = new AlternateMock(); + secondary.set( FILE_TYPE_ERROR_VIEW, { foo: 'baz' } ); + secondary.set( FILE_SIZE_ERROR_VIEW, { bar: 'example' } ); + mockThis.set( { secondary } ); + + expect( mediaLibraryHasTwoNotices.call( mockThis ) ).toBe( true ); + } ); +} ); diff --git a/assets/src/customizer/amp-customize-controls.js b/assets/src/customizer/amp-customize-controls.js index 442bbda69d7..2af885f2abf 100644 --- a/assets/src/customizer/amp-customize-controls.js +++ b/assets/src/customizer/amp-customize-controls.js @@ -2,7 +2,7 @@ /* eslint no-magic-numbers: [ "error", { "ignore": [ 0, 1, 250] } ] */ -window.ampCustomizeControls = ( function( api, $ ) { // eslint-disable-line no-unused-vars +window.ampCustomizeControls = ( function( api, $ ) { 'use strict'; const component = { diff --git a/assets/src/customizer/amp-customize-preview.js b/assets/src/customizer/amp-customize-preview.js index 77985ea91e3..f8a1cea680f 100644 --- a/assets/src/customizer/amp-customize-preview.js +++ b/assets/src/customizer/amp-customize-preview.js @@ -1,4 +1,4 @@ -window.ampCustomizePreview = ( function( api ) { // eslint-disable-line no-unused-vars +window.ampCustomizePreview = ( function( api ) { 'use strict'; const component = {}; diff --git a/assets/src/customizer/amp-customizer-design-preview.js b/assets/src/customizer/amp-customizer-design-preview.js index 317ca6d4c4e..d71a85a287b 100644 --- a/assets/src/customizer/amp-customizer-design-preview.js +++ b/assets/src/customizer/amp-customizer-design-preview.js @@ -1,4 +1,4 @@ -/* global amp_customizer_design, console, jQuery */ +/* global amp_customizer_design, jQuery */ ( function( $ ) { 'use strict'; @@ -24,10 +24,10 @@ // AMP background color scheme. wp.customize( 'amp_customizer[color_scheme]', function( value ) { value.bind( function( to ) { - var colors = amp_customizer_design.color_schemes[ to ]; // eslint-disable-line + var colors = amp_customizer_design.color_schemes[ to ]; // eslint-disable-line no-var if ( ! colors ) { - console.error( 'Selected color scheme "%s" not registered.', to ); // eslint-disable-line + console.error( 'Selected color scheme "%s" not registered.', to ); // eslint-disable-line no-console return; } diff --git a/assets/src/polyfills/wp-dom-ready.js b/assets/src/polyfills/wp-dom-ready.js index 78ccd75d984..39f1032dc1e 100644 --- a/assets/src/polyfills/wp-dom-ready.js +++ b/assets/src/polyfills/wp-dom-ready.js @@ -3,8 +3,6 @@ */ import domReady from '@wordpress/dom-ready'; -if ( ! window.wp ) { - window.wp = {}; -} +window.wp = window.wp || {}; -wp.domReady = domReady; +window.wp.domReady = domReady; diff --git a/assets/src/polyfills/wp-i18n.js b/assets/src/polyfills/wp-i18n.js index 4216b6e0fc0..f429df80766 100644 --- a/assets/src/polyfills/wp-i18n.js +++ b/assets/src/polyfills/wp-i18n.js @@ -3,8 +3,6 @@ */ import * as i18n from '@wordpress/i18n'; -if ( ! window.wp ) { - window.wp = {}; -} +window.wp = window.wp || {}; -wp.i18n = i18n; +window.wp.i18n = i18n; diff --git a/assets/src/polyfills/wp-server-side-render.js b/assets/src/polyfills/wp-server-side-render.js new file mode 100644 index 00000000000..9d99476bf6b --- /dev/null +++ b/assets/src/polyfills/wp-server-side-render.js @@ -0,0 +1,8 @@ +/** + * WordPress dependencies + */ +import * as serverSideRender from '@wordpress/server-side-render'; + +window.wp = window.wp || {}; + +window.wp.serverSideRender = serverSideRender; diff --git a/assets/src/stories-editor/blocks/amp-story-cta/deprecated.js b/assets/src/stories-editor/blocks/amp-story-cta/deprecated.js new file mode 100644 index 00000000000..e04aab371f2 --- /dev/null +++ b/assets/src/stories-editor/blocks/amp-story-cta/deprecated.js @@ -0,0 +1,102 @@ +/** + * External dependencies + */ +import { omit } from 'lodash'; + +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import { getClassNameFromBlockAttributes, getStylesFromBlockAttributes } from '../../helpers'; +import PropTypes from 'prop-types'; + +const blockAttributes = { + url: { + type: 'string', + source: 'attribute', + selector: 'a', + attribute: 'href', + }, + text: { + type: 'string', + source: 'html', + selector: 'a', + }, + customTextColor: { + type: 'string', + default: '#ffffff', + }, + customBackgroundColor: { + type: 'string', + default: '#32373c', + }, +}; + +/** + * Deprecated save function for plugin version 1.2.1 + * + * @param {Object} attributes Attributes. + * @return {*} CTA save. + */ +const CallToActionSaveV121 = ( { attributes } ) => { + const { + anchor, + url, + text, + } = attributes; + + const className = getClassNameFromBlockAttributes( { ...attributes, className: 'amp-block-story-cta__link' } ); + const styles = getStylesFromBlockAttributes( attributes ); + + return ( + + + + ); +}; + +CallToActionSaveV121.propTypes = { + attributes: PropTypes.shape( { + anchor: PropTypes.string, + url: PropTypes.string, + text: PropTypes.string, + } ).isRequired, +}; + +const deprecated = [ + { + attributes: { + align: { + type: 'string', + default: 'center', + }, + ...blockAttributes, + }, + supports: { + align: true, + alignWide: false, + }, + + save: CallToActionSaveV121, + + migrate( attributes ) { + return { + ...omit( attributes, 'align' ), + btnPositionTop: 0, + btnPositionLeft: 30, + }; + }, + }, +]; + +export default deprecated; diff --git a/assets/src/stories-editor/blocks/amp-story-cta/edit.css b/assets/src/stories-editor/blocks/amp-story-cta/edit.css index 4bc7c7a18af..3c29d1f23bd 100644 --- a/assets/src/stories-editor/blocks/amp-story-cta/edit.css +++ b/assets/src/stories-editor/blocks/amp-story-cta/edit.css @@ -5,26 +5,52 @@ height: 20%; } -.editor-block-list__layout div[data-type="amp/amp-story-cta"] .editor-block-mover { - display: none; +.block-editor-block-list__layout div[data-type="amp/amp-story-cta"]:not(#id) { + margin-top: 0; } -.block-editor-block-list__block[data-type="amp/amp-story-cta"][data-align="center"] { - text-align: center; +.editor-block-list__layout div[data-type="amp/amp-story-cta"] img { + + /* Remove the top/bottom padding from the available space. */ + max-height: calc(110px - 24px); } -.block-editor-block-list__block[data-type="amp/amp-story-cta"][data-align="right"] { +.amp-block-story-cta__link img { + object-fit: contain; +} + +.amp-block-story-cta__link .amp-text-placeholder { + opacity: 0.62; +} - /*!rtl:ignore*/ - text-align: right; +div[data-type="amp/amp-story-cta"] .amp-overlay { + height: 100%; + width: 100%; + z-index: 1000; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.editor-block-list__layout div[data-type="amp/amp-story-cta"] .editor-block-mover { + display: none; } .block-editor-block-list__block[data-type="amp/amp-story-cta"] .block-editor-block-list__block-edit { + + /* Let's position the block so that there would be no space between the Page borders and the content */ + --cta-margin: 3px; + height: calc(100% + calc(var(--cta-margin) * 2)); width: 100%; + bottom: var(--cta-margin); } -.block-editor-block-list__block[data-type="amp/amp-story-cta"] .block-editor-block-list__block-edit::before { +.block-editor-block-list__layout .block-editor-block-list__block[data-type="amp/amp-story-cta"] .block-editor-block-list__block-edit::before { + top: 0; left: 0; + bottom: 0; right: 0; } @@ -33,8 +59,13 @@ margin-right: 0; } +.amp-story-cta-button { + position: absolute; +} + .wp-block-amp-amp-story-cta { display: inline-block; + padding: 5px; margin-bottom: 0; position: relative; } @@ -51,6 +82,11 @@ max-width: 100%; } +.wp-block-amp-amp-story-cta .block-editor-rich-text__editable code { + background: inherit; + color: inherit; +} + .wp-block-amp-amp-story-cta .block-editor-rich-text__editable[data-is-placeholder-visible="true"] { height: auto; } @@ -69,7 +105,7 @@ display: inline-block; font-size: 18px; margin: 0; - padding: 12px 24px; + padding: 7px 19px 0; text-align: center; text-decoration: none; white-space: normal; @@ -87,7 +123,11 @@ width: calc(300px + 2px + 2 * 36px); position: absolute; z-index: 10; - margin-top: -1.5em; + margin-top: -0.5em; +} + +.is-dragging-components-draggable .amp-block-story-cta__inline-link { + display: none; } .amp-block-story-cta__inline-link .block-editor-url-input { @@ -110,13 +150,3 @@ .amp-block-story-cta__inline-link .block-editor-url-input input[type="text"]::placeholder { color: #8f98a1; } - -[data-align="center"] .amp-block-story-cta__inline-link { - margin-left: auto; - margin-right: auto; -} - -[data-align="right"] .amp-block-story-cta__inline-link { - margin-left: auto; - margin-right: 0; -} diff --git a/assets/src/stories-editor/blocks/amp-story-cta/edit.js b/assets/src/stories-editor/blocks/amp-story-cta/edit.js index 9e4ecf007b5..cff8e283165 100644 --- a/assets/src/stories-editor/blocks/amp-story-cta/edit.js +++ b/assets/src/stories-editor/blocks/amp-story-cta/edit.js @@ -23,17 +23,26 @@ import { */ import './edit.css'; import { select } from '@wordpress/data'; -import { getUniqueId } from '../../helpers'; +import { getUniqueId, setInputSelectionToEnd } from '../../helpers'; import { getBackgroundColorWithOpacity } from '../../../common/helpers'; +import { DraggableText } from '../../components'; class CallToActionEdit extends Component { constructor( props ) { - super( ...arguments ); + super( props ); if ( ! props.attributes.anchor ) { this.props.setAttributes( { anchor: getUniqueId() } ); } + this.state = { + isEditing: false, + hasOverlay: true, + }; + + this.toggleIsEditing = this.toggleIsEditing.bind( this ); + this.toggleOverlay = this.toggleOverlay.bind( this ); + this.nodeRef = null; this.bindRef = this.bindRef.bind( this ); } @@ -45,15 +54,45 @@ class CallToActionEdit extends Component { this.nodeRef = node; } + toggleIsEditing( enable ) { + if ( enable !== this.state.isEditing ) { + this.setState( { + isEditing: ! this.state.isEditing, + } ); + } + } + + toggleOverlay( add ) { + if ( add !== this.state.hasOverlay ) { + this.setState( { + hasOverlay: ! this.state.hasOverlay, + } ); + } + } + + componentDidUpdate( prevProps, prevState ) { + const { isSelected } = this.props; + // If the block was unselected, make sure that it's not editing anymore. + if ( ! isSelected && prevProps.isSelected ) { + this.toggleIsEditing( false ); + this.toggleOverlay( true ); + } + if ( this.state.isEditing && ! prevState.isEditing ) { + setInputSelectionToEnd( '.is-selected .amp-block-story-cta__link' ); + } + } + render() { const { attributes, backgroundColor, - textColor, - setAttributes, - isSelected, className, + clientId, fontSize, + isSelected, + name, + setAttributes, + textColor, } = this.props; const { @@ -61,47 +100,72 @@ class CallToActionEdit extends Component { url, customBackgroundColor, opacity, + btnPositionTop, + btnPositionLeft, } = attributes; + const { isEditing, hasOverlay } = this.state; + const { colors } = select( 'core/block-editor' ).getSettings(); const appliedBackgroundColor = getBackgroundColorWithOpacity( colors, backgroundColor, customBackgroundColor, opacity ); + const placeholder = __( 'Add text…', 'amp' ); + const textWrapperClass = classnames( + 'amp-block-story-cta__link', { + 'has-background': backgroundColor.color, + 'has-text-color': textColor.color, + [ textColor.class ]: textColor.class, + } + ); + const textStyle = { + color: textColor.color, + fontSize: fontSize.size ? fontSize.size + 'px' : undefined, + }; return ( <> -
- setAttributes( { text: value } ) } - formattingControls={ [ 'bold', 'italic', 'strikethrough' ] } - className={ classnames( - 'amp-block-story-cta__link', { - 'has-background': backgroundColor.color, - [ backgroundColor.class ]: backgroundColor.class, - 'has-text-color': textColor.color, - [ textColor.class ]: textColor.class, - } +
+
+ { isEditing && ( + setAttributes( { text: value } ) } + className={ textWrapperClass } + style={ textStyle } + /> ) } - style={ { - backgroundColor: appliedBackgroundColor, - color: textColor.color, - fontSize: fontSize.size ? fontSize.size + 'px' : undefined, - } } - /> + { ! isEditing && + + } +
+ { isSelected && isEditing && ( +
event.preventDefault() }> + + setAttributes( { url: value } ) } + autoFocus={ false /* eslint-disable-line jsx-a11y/no-autofocus */ } + /> + + + ) }
- { isSelected && ( -
event.preventDefault() }> - - setAttributes( { url: value } ) } - autoFocus={ false /* eslint-disable-line jsx-a11y/no-autofocus */ } - /> - - - ) } ); } @@ -112,10 +176,15 @@ CallToActionEdit.propTypes = { text: PropTypes.string, url: PropTypes.string, anchor: PropTypes.string, + customBackgroundColor: PropTypes.string, + opacity: PropTypes.number, + btnPositionLeft: PropTypes.number, + btnPositionTop: PropTypes.number, } ).isRequired, setAttributes: PropTypes.func.isRequired, isSelected: PropTypes.bool, className: PropTypes.string, + clientId: PropTypes.string, fontSize: PropTypes.shape( { name: PropTypes.string, shortName: PropTypes.string, @@ -128,6 +197,7 @@ CallToActionEdit.propTypes = { slug: PropTypes.string, class: PropTypes.string, } ).isRequired, + name: PropTypes.string.isRequired, textColor: PropTypes.shape( { color: PropTypes.string, name: PropTypes.string, diff --git a/assets/src/stories-editor/blocks/amp-story-cta/index.js b/assets/src/stories-editor/blocks/amp-story-cta/index.js index 0d2cae0ae78..be10840445f 100644 --- a/assets/src/stories-editor/blocks/amp-story-cta/index.js +++ b/assets/src/stories-editor/blocks/amp-story-cta/index.js @@ -2,14 +2,15 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; +import { createBlock, getBlockAttributes } from '@wordpress/blocks'; /** * Internal dependencies */ import edit from './edit'; import save from './save'; -import blockIcon from '../../../../images/call-to-action.svg'; -import { createBlock, getBlockAttributes } from '@wordpress/blocks'; +import deprecated from './deprecated'; +import blockIcon from '../../../../images/stories-editor/call-to-action.svg'; const schema = { url: { @@ -23,10 +24,6 @@ const schema = { source: 'html', selector: 'a', }, - align: { - type: 'string', - default: 'center', - }, // The rest of the color attributes are added by addAMPAttributes() customTextColor: { type: 'string', @@ -36,6 +33,14 @@ const schema = { type: 'string', default: '#32373c', }, + btnPositionTop: { + type: 'number', + default: 0, + }, + btnPositionLeft: { + type: 'number', + default: 30, + }, }; export const name = 'amp/amp-story-cta'; @@ -49,19 +54,19 @@ export const settings = { category: 'layout', - keywords: [ __( 'call to action', 'amp' ), __( 'cta', 'amp' ), __( 'button', 'amp' ) ], + keywords: [ + __( 'cta', 'amp' ), + __( 'button', 'amp' ), + ], attributes: schema, - supports: { - align: true, - alignWide: false, - }, - edit, save, + deprecated, + transforms: { from: [ { diff --git a/assets/src/stories-editor/blocks/amp-story-cta/save.js b/assets/src/stories-editor/blocks/amp-story-cta/save.js index 562459a4c05..13f16f69ffc 100644 --- a/assets/src/stories-editor/blocks/amp-story-cta/save.js +++ b/assets/src/stories-editor/blocks/amp-story-cta/save.js @@ -11,19 +11,25 @@ import { RichText } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { getClassNameFromBlockAttributes, getStylesFromBlockAttributes } from '../../helpers'; +import { getClassNameFromBlockAttributes, getStylesFromBlockAttributes, getUniqueId } from '../../helpers'; -const CallToActionEdit = ( { attributes } ) => { +const CallToActionSave = ( { attributes } ) => { const { - url, + anchor, + btnPositionLeft, + btnPositionTop, text, + url, } = attributes; const className = getClassNameFromBlockAttributes( { ...attributes, className: 'amp-block-story-cta__link' } ); const styles = getStylesFromBlockAttributes( attributes ); + styles.top = btnPositionTop ? `${ btnPositionTop }%` : undefined; + styles.left = btnPositionLeft ? `${ btnPositionLeft }%` : undefined; + return ( - + { ); }; -CallToActionEdit.propTypes = { +CallToActionSave.propTypes = { attributes: PropTypes.shape( { + anchor: PropTypes.string, url: PropTypes.string, text: PropTypes.string, + btnPositionLeft: PropTypes.number, + btnPositionTop: PropTypes.number, backgroundColor: PropTypes.shape( { color: PropTypes.string, name: PropTypes.string, @@ -63,4 +72,4 @@ CallToActionEdit.propTypes = { } ).isRequired, }; -export default CallToActionEdit; +export default CallToActionSave; diff --git a/assets/src/stories-editor/blocks/amp-story-cta/test/index.js b/assets/src/stories-editor/blocks/amp-story-cta/test/index.js deleted file mode 100644 index 2be777940df..00000000000 --- a/assets/src/stories-editor/blocks/amp-story-cta/test/index.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * WordPress dependencies - */ -import { addFilter, removeFilter } from '@wordpress/hooks'; -import '@wordpress/editor'; // So the data store is registered. - -/** - * Internal dependencies - */ -import { name, settings } from '../'; -import { blockEditRender } from '../../../../test/helpers'; -import { addAMPAttributes } from '../../../helpers'; -import { withAmpStorySettings } from '../../../components'; - -describe( 'amp/amp-story-cta', () => { - beforeAll( () => { - addFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes', addAMPAttributes ); - addFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings', withAmpStorySettings ); - } ); - - afterAll( () => { - removeFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes' ); - removeFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings' ); - } ); - - test( 'block is rendered', () => { - const wrapper = blockEditRender( name, settings ); - - expect( wrapper.render().find( '.wp-block-amp-amp-story-cta' ) ).toHaveLength( 1 ); - } ); -} ); diff --git a/assets/src/stories-editor/blocks/amp-story-page/deprecated.js b/assets/src/stories-editor/blocks/amp-story-page/deprecated.js new file mode 100644 index 00000000000..2ff98ebe721 --- /dev/null +++ b/assets/src/stories-editor/blocks/amp-story-page/deprecated.js @@ -0,0 +1,149 @@ +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { InnerBlocks } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import { + addBackgroundColorToOverlay, +} from '../../helpers'; +import { + IMAGE_BACKGROUND_TYPE, + VIDEO_BACKGROUND_TYPE, +} from '../../constants'; + +const blockAttributes = { + anchor: { + source: 'attribute', + selector: 'amp-story-page', + attribute: 'id', + }, + mediaAlt: { + type: 'string', + }, + mediaId: { + type: 'number', + }, + mediaUrl: { + type: 'string', + source: 'attribute', + selector: 'amp-story-grid-layer[template="fill"] > amp-img, amp-story-grid-layer[template="fill"] > amp-video', + attribute: 'src', + }, + mediaType: { + type: 'string', + }, + poster: { + type: 'string', + }, + focalPoint: { + type: 'object', + }, + autoAdvanceAfter: { + type: 'string', + }, + autoAdvanceAfterDuration: { + type: 'number', + }, + autoAdvanceAfterMedia: { + type: 'string', + }, + backgroundColors: { + default: '[]', + }, + overlayOpacity: { + default: 100, + }, +}; + +const SaveV120 = ( { attributes } ) => { + const { + anchor, + focalPoint, + overlayOpacity, + mediaUrl, + mediaType, + poster, + autoAdvanceAfter, + autoAdvanceAfterDuration, + autoAdvanceAfterMedia, + } = attributes; + + const backgroundColors = JSON.parse( attributes.backgroundColors ); + + let advanceAfter; + + if ( [ 'auto', 'time' ].includes( autoAdvanceAfter ) && autoAdvanceAfterDuration ) { + advanceAfter = parseInt( autoAdvanceAfterDuration ) + 's'; + } else if ( 'media' === autoAdvanceAfter ) { + advanceAfter = autoAdvanceAfterMedia; + } + + let overlayStyle = {}; + if ( 0 < backgroundColors.length ) { + overlayStyle = addBackgroundColorToOverlay( overlayStyle, backgroundColors ); + overlayStyle.opacity = overlayOpacity / 100; + } + + const imgStyle = { + objectPosition: IMAGE_BACKGROUND_TYPE === mediaType && focalPoint ? `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%` : 'initial', + }; + + return ( + + { + mediaUrl && ( + + { IMAGE_BACKGROUND_TYPE === mediaType && ( + + ) } + { VIDEO_BACKGROUND_TYPE === mediaType && ( + + ) } + + ) + } + + + + ); +}; + +SaveV120.propTypes = { + attributes: PropTypes.shape( { + anchor: PropTypes.string, + backgroundColors: PropTypes.string, + mediaAlt: PropTypes.string, + mediaId: PropTypes.number, + mediaType: PropTypes.string, + mediaUrl: PropTypes.string, + focalPoint: PropTypes.shape( { + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + } ), + overlayOpacity: PropTypes.number, + poster: PropTypes.string, + autoAdvanceAfter: PropTypes.string, + autoAdvanceAfterDuration: PropTypes.number, + autoAdvanceAfterMedia: PropTypes.string, + } ).isRequired, +}; + +export default [ + { + attributes: { + ...blockAttributes, + deprecated: { + default: '1.2.0', + }, + }, + save: SaveV120, + }, +]; diff --git a/assets/src/stories-editor/blocks/amp-story-page/edit.css b/assets/src/stories-editor/blocks/amp-story-page/edit.css index 7a59b839928..06a99a080a0 100644 --- a/assets/src/stories-editor/blocks/amp-story-page/edit.css +++ b/assets/src/stories-editor/blocks/amp-story-page/edit.css @@ -94,7 +94,7 @@ height: 553px; } -[data-block] { +.editor-styles-wrapper [data-block] { margin-top: 0; margin-bottom: 0; } @@ -107,13 +107,18 @@ z-index: 100; } -.block-editor-block-list__layout .block-editor-block-list__block.amp-page-inactive > .block-editor-block-list__block-edit::before { +.block-editor-block-list__block.amp-page-inactive > .block-editor-block-list__block-edit::before { box-shadow: none; border: 1px solid #e3e5e7; } -.block-editor-block-list__layout .block-editor-block-list__block.amp-page-active > .block-editor-block-list__block-edit::before, -.block-editor-block-list__layout .block-editor-block-list__block.is-selected > .block-editor-block-list__block-edit::before { +/* todo: show border also when is-resizing */ +.block-editor-block-list__block.amp-page-active > .block-editor-block-list__block-edit::before, +.block-editor-block-list__block.amp-page-active.is-selected > .block-editor-block-list__block-edit::before, +.block-editor-block-list__block.amp-page-active.has-child-selected > .block-editor-block-list__block-edit::before, +.block-editor-inner-blocks .wp-block:hover .block-editor-block-list__block-edit::before, +.block-editor-inner-blocks .wp-block.is-rotating .block-editor-block-list__block-edit::before, +.block-editor-inner-blocks .wp-block.is-selected .block-editor-block-list__block-edit::before { box-shadow: none; border: 1px solid rgba(66, 88, 99, .4); } @@ -131,7 +136,7 @@ div[data-type="amp/amp-story-page"] .editor-inner-blocks .editor-block-list__lay } .editor-block-list__layout div[data-type="amp/amp-story-page"][data-amp-selected="parent"] .editor-block-drop-zone { - height: 583px; + height: 603px; --dropzone-padding: 400px; --page-width: 328px; width: calc(var(--dropzone-padding) + var(--page-width)); diff --git a/assets/src/stories-editor/blocks/amp-story-page/edit.js b/assets/src/stories-editor/blocks/amp-story-page/edit.js index 84c07f6479b..6568ca10395 100644 --- a/assets/src/stories-editor/blocks/amp-story-page/edit.js +++ b/assets/src/stories-editor/blocks/amp-story-page/edit.js @@ -8,7 +8,7 @@ import { has } from 'lodash'; /** * WordPress dependencies */ -import { __, sprintf } from '@wordpress/i18n'; +import { __, _x, sprintf } from '@wordpress/i18n'; import { InnerBlocks, PanelColorSettings, @@ -41,21 +41,28 @@ import { getTotalAnimationDuration, addBackgroundColorToOverlay, getCallToActionBlock, - isVideoSizeExcessive, - getVideoBytesPerSecond, getUniqueId, + uploadVideoFrame, + getPosterImageFromFileObj, } from '../../helpers'; +import { + getVideoBytesPerSecond, + isVideoSizeExcessive, +} from '../../../common/helpers'; + import { ALLOWED_CHILD_BLOCKS, - ALLOWED_MEDIA_TYPES, + ALLOWED_BACKGROUND_MEDIA_TYPES, ALLOWED_MOVABLE_BLOCKS, IMAGE_BACKGROUND_TYPE, VIDEO_BACKGROUND_TYPE, POSTER_ALLOWED_MEDIA_TYPES, MAX_IMAGE_SIZE_SLUG, - VIDEO_ALLOWED_MEGABYTES_PER_SECOND, - MEGABYTE_IN_BYTES, } from '../../constants'; +import { + MEGABYTE_IN_BYTES, + VIDEO_ALLOWED_MEGABYTES_PER_SECOND, +} from '../../../common/constants'; import './edit.css'; class PageEdit extends Component { @@ -65,12 +72,16 @@ class PageEdit extends Component { } constructor( props ) { - super( ...arguments ); + super( props ); if ( ! props.attributes.anchor ) { this.props.setAttributes( { anchor: getUniqueId() } ); } + this.state = { + extractingPoster: false, + }; + this.videoPlayer = createRef(); this.onSelectMedia = this.onSelectMedia.bind( this ); } @@ -88,12 +99,15 @@ class PageEdit extends Component { * @param {string} media.image.src Media image URL */ onSelectMedia( media ) { + const { setAttributes } = this.props; + if ( ! media || ! media.url ) { - this.props.setAttributes( + setAttributes( { mediaUrl: undefined, mediaId: undefined, mediaType: undefined, + mediaAlt: undefined, poster: undefined, } ); @@ -121,24 +135,53 @@ class PageEdit extends Component { mediaType = media.type; } - const mediaUrl = has( media, [ 'sizes', MAX_IMAGE_SIZE_SLUG, 'url' ] ) ? media.sizes[ MAX_IMAGE_SIZE_SLUG ].url : media.url; + const mediaAlt = media.alt || media.title; + const mediaUrl = media.url; + const poster = VIDEO_BACKGROUND_TYPE === mediaType && media.image && media.image.src !== media.icon ? media.image.src : undefined; this.props.setAttributes( { mediaUrl, mediaId: media.id, mediaType, - poster: VIDEO_BACKGROUND_TYPE === mediaType && media.image && media.image.src !== media.icon ? media.image.src : undefined, + mediaAlt, + poster, } ); } componentDidUpdate( prevProps ) { - if ( - VIDEO_BACKGROUND_TYPE === this.props.attributes.mediaType && - this.props.attributes.mediaUrl !== prevProps.attributes.mediaUrl && - this.videoPlayer.current - ) { + const { attributes, setAttributes, videoFeaturedImage, media } = this.props; + const { mediaType, mediaUrl, mediaId, poster } = attributes; + + if ( VIDEO_BACKGROUND_TYPE !== mediaType ) { + return; + } + + if ( prevProps.attributes.mediaUrl !== mediaUrl && this.videoPlayer.current ) { this.videoPlayer.current.load(); } + + if ( poster ) { + return; + } + + if ( videoFeaturedImage ) { + setAttributes( { poster: videoFeaturedImage.source_url } ); + } else if ( media && media !== prevProps.media && ! media.featured_media && ! this.state.extractingPoster ) { + /* + * The video has changed, and its media object has been loaded already. + * + * Since it's clear that the video does not have a featured (poster) image, + * one can be generated now. + */ + this.setState( { extractingPoster: true } ); + + uploadVideoFrame( { id: mediaId, src: mediaUrl } ) + .then( ( fileObj ) => { + setAttributes( { poster: getPosterImageFromFileObj( fileObj ) } ); + this.setState( { extractingPoster: false } ); + } ) + .catch( () => this.setState( { extractingPoster: false } ) ); + } } removeBackgroundColor( index ) { @@ -209,14 +252,14 @@ class PageEdit extends Component { } } - render() { + render() { // eslint-disable-line complexity const { attributes, media, setAttributes, totalAnimationDuration, allowedBlocks } = this.props; const { mediaId, mediaType, mediaUrl, - focalPoint = { x: .5, y: .5 }, + focalPoint = { x: 0.5, y: 0.5 }, overlayOpacity, poster, autoAdvanceAfter, @@ -263,7 +306,7 @@ class PageEdit extends Component { overlayStyle.opacity = overlayOpacity / 100; const colorSettings = this.getOverlayColorSettings(); - const isExcessiveVideoSize = VIDEO_BACKGROUND_TYPE === mediaType && isVideoSizeExcessive( media ); + const isExcessiveVideoSize = VIDEO_BACKGROUND_TYPE === mediaType && isVideoSizeExcessive( getVideoBytesPerSecond( media ) ); const videoBytesPerSecond = VIDEO_BACKGROUND_TYPE === mediaType ? getVideoBytesPerSecond( media ) : null; return ( @@ -326,24 +369,23 @@ class PageEdit extends Component { ( ) } + id="story-background-media" /> + { mediaUrl && ( + + ) } - { !! mediaId && - - - - } - { VIDEO_BACKGROUND_TYPE === mediaType && ( + { VIDEO_BACKGROUND_TYPE === mediaType && ( ! this.state.extractingPoster || poster ) && ( ( - ) - } ) } - { mediaUrl && ( - <> - { /* Note: FocalPointPicker is only available in Gutenberg 5.1+ */ } - { IMAGE_BACKGROUND_TYPE === mediaType && FocalPointPicker && ( - setAttributes( { focalPoint: value } ) } - /> - ) } - + { IMAGE_BACKGROUND_TYPE === mediaType && mediaUrl && FocalPointPicker && ( + setAttributes( { focalPoint: value } ) } + /> ) } @@ -439,7 +470,7 @@ class PageEdit extends Component { onChange={ ( value ) => setAttributes( { autoAdvanceAfterDuration: value } ) } min={ Math.max( totalAnimationDuration, 1 ) } initialPosition={ totalAnimationDuration } - help={ totalAnimationDuration > 1 ? __( 'A minimum time is enforced because there are animated blocks on this page', 'amp' ) : undefined } + help={ totalAnimationDuration > 1 ? __( 'A minimum time is enforced because there are animated blocks on this page.', 'amp' ) : undefined } /> ) } @@ -486,18 +517,35 @@ PageEdit.propTypes = { totalAnimationDuration: PropTypes.number.isRequired, getBlockOrder: PropTypes.func.isRequired, moveBlockToPosition: PropTypes.func.isRequired, + videoFeaturedImage: PropTypes.shape( { + source_url: PropTypes.string, + } ), }; export default compose( + withDispatch( () => { + const { moveBlockToPosition } = dispatch( 'core/block-editor' ); + return { + moveBlockToPosition, + }; + } ), withSelect( ( select, { clientId, attributes } ) => { const { getMedia } = select( 'core' ); const { getBlockOrder, getBlockRootClientId } = select( 'core/block-editor' ); + const { getAnimatedBlocks } = select( 'amp/story' ); const isFirstPage = getBlockOrder().indexOf( clientId ) === 0; const isCallToActionAllowed = ! isFirstPage && ! getCallToActionBlock( clientId ); - const { getAnimatedBlocks } = select( 'amp/story' ); - const { mediaId } = attributes; + const { mediaType, mediaId, poster } = attributes; + + const media = mediaId ? getMedia( mediaId ) : undefined; + + let videoFeaturedImage; + + if ( VIDEO_BACKGROUND_TYPE === mediaType && media && media.featured_media && ! poster ) { + videoFeaturedImage = getMedia( media.featured_media ); + } const animatedBlocks = getAnimatedBlocks(); const animatedBlocksPerPage = ( animatedBlocks[ clientId ] || [] ).filter( ( { id } ) => clientId === getBlockRootClientId( id ) ); @@ -505,18 +553,11 @@ export default compose( const totalAnimationDurationInSeconds = Math.ceil( totalAnimationDuration / 1000 ); return { - media: mediaId ? getMedia( mediaId ) : null, + media, + videoFeaturedImage, allowedBlocks: isCallToActionAllowed ? ALLOWED_CHILD_BLOCKS : ALLOWED_MOVABLE_BLOCKS, totalAnimationDuration: totalAnimationDurationInSeconds, getBlockOrder, }; } ), - withDispatch( () => { - const { - moveBlockToPosition, - } = dispatch( 'core/block-editor' ); - return { - moveBlockToPosition, - }; - } ) )( PageEdit ); diff --git a/assets/src/stories-editor/blocks/amp-story-page/index.js b/assets/src/stories-editor/blocks/amp-story-page/index.js index 6538ab20720..5ae149d9cb9 100644 --- a/assets/src/stories-editor/blocks/amp-story-page/index.js +++ b/assets/src/stories-editor/blocks/amp-story-page/index.js @@ -7,9 +7,10 @@ import { createBlock, getBlockAttributes } from '@wordpress/blocks'; /** * Internal dependencies */ +import deprecated from './deprecated'; import edit from './edit'; import save from './save'; -import blockIcon from '../../../../images/amp-story-page-icon.svg'; +import blockIcon from '../../../../images/stories-editor/amp-story-page-icon.svg'; export const name = 'amp/amp-story-page'; @@ -25,12 +26,15 @@ const schema = { mediaUrl: { type: 'string', source: 'attribute', - selector: 'amp-story-grid-layer[template="fill"] > amp-img, amp-story-grid-layer[template="fill"] > amp-video', + selector: 'amp-story-grid-layer[template="fill"] > img, amp-story-grid-layer[template="fill"] > amp-img, amp-story-grid-layer[template="fill"] > amp-video', attribute: 'src', }, mediaType: { type: 'string', }, + mediaAlt: { + type: 'string', + }, poster: { type: 'string', }, @@ -80,6 +84,8 @@ export const settings = { save, + deprecated, + transforms: { from: [ { diff --git a/assets/src/stories-editor/blocks/amp-story-page/save.js b/assets/src/stories-editor/blocks/amp-story-page/save.js index 2a8fa0fd25a..f03f60804e8 100644 --- a/assets/src/stories-editor/blocks/amp-story-page/save.js +++ b/assets/src/stories-editor/blocks/amp-story-page/save.js @@ -19,8 +19,10 @@ const PageSave = ( { attributes } ) => { anchor, focalPoint, overlayOpacity, + mediaId, mediaUrl, mediaType, + mediaAlt, poster, autoAdvanceAfter, autoAdvanceAfterDuration, @@ -43,9 +45,7 @@ const PageSave = ( { attributes } ) => { overlayStyle.opacity = overlayOpacity / 100; } - const imgStyle = { - objectPosition: IMAGE_BACKGROUND_TYPE === mediaType && focalPoint ? `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%` : 'initial', - }; + const objectPosition = IMAGE_BACKGROUND_TYPE === mediaType && focalPoint ? `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%` : 'initial'; return ( @@ -53,10 +53,16 @@ const PageSave = ( { attributes } ) => { mediaUrl && ( { IMAGE_BACKGROUND_TYPE === mediaType && ( - + { ) } { VIDEO_BACKGROUND_TYPE === mediaType && ( - + ) } ) @@ -73,6 +79,7 @@ PageSave.propTypes = { backgroundColors: PropTypes.string, mediaId: PropTypes.number, mediaType: PropTypes.string, + mediaAlt: PropTypes.string, mediaUrl: PropTypes.string, focalPoint: PropTypes.shape( { x: PropTypes.number.isRequired, diff --git a/assets/src/stories-editor/blocks/amp-story-page/test/__snapshots__/index.js.snap b/assets/src/stories-editor/blocks/amp-story-page/test/__snapshots__/index.js.snap deleted file mode 100644 index cb0808a5e9a..00000000000 --- a/assets/src/stories-editor/blocks/amp-story-page/test/__snapshots__/index.js.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`amp/amp-story-page block edit matches snapshot 1`] = ` -
-
-
-
-
-
-
-`; diff --git a/assets/src/stories-editor/blocks/amp-story-page/test/index.js b/assets/src/stories-editor/blocks/amp-story-page/test/index.js deleted file mode 100644 index 57e1209a291..00000000000 --- a/assets/src/stories-editor/blocks/amp-story-page/test/index.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Internal dependencies - */ -import { name, settings } from '../'; -import { blockEditRender } from '../../../../test/helpers'; - -describe( 'amp/amp-story-page', () => { - test( 'block edit matches snapshot', () => { - const wrapper = blockEditRender( name, settings ); - - expect( wrapper.render() ).toMatchSnapshot(); - } ); -} ); diff --git a/assets/src/stories-editor/blocks/amp-story-post-author/edit.css b/assets/src/stories-editor/blocks/amp-story-post-author/edit.css index e84246fa7f1..32a7cc21e09 100644 --- a/assets/src/stories-editor/blocks/amp-story-post-author/edit.css +++ b/assets/src/stories-editor/blocks/amp-story-post-author/edit.css @@ -14,9 +14,10 @@ .wp-block[data-type="amp/amp-story-post-author"] .wp-block-amp-amp-story-post-author:not(.is-amp-fit-text) { display: block; + font-size: 16px; } -.wp-block[data-type="amp/amp-story-post-author"] .wp-block-amp-amp-story-post-author.is-amp-fit-text.is-measuring-fontsize { +.wp-block[data-type="amp/amp-story-post-author"] .wp-block-amp-amp-story-post-author.is-measuring { height: initial !important; width: initial !important; position: absolute !important; diff --git a/assets/src/stories-editor/blocks/amp-story-post-author/test/index.js b/assets/src/stories-editor/blocks/amp-story-post-author/test/index.js deleted file mode 100644 index 61f469eecaa..00000000000 --- a/assets/src/stories-editor/blocks/amp-story-post-author/test/index.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * WordPress dependencies - */ -import { addFilter, removeFilter } from '@wordpress/hooks'; -import '@wordpress/editor'; // So the data store is registered. - -/** - * Internal dependencies - */ -import { name, settings } from '../'; -import { blockEditRender } from '../../../../test/helpers'; -import { addAMPAttributes } from '../../../helpers'; -import { withAmpStorySettings } from '../../../components'; - -describe( 'amp/amp-story-post-author', () => { - beforeAll( () => { - addFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes', addAMPAttributes ); - addFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings', withAmpStorySettings ); - } ); - - afterAll( () => { - removeFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes' ); - removeFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings' ); - } ); - - test( 'block is rendered', () => { - const wrapper = blockEditRender( name, settings ); - - expect( wrapper.render().find( '.wp-block-amp-amp-story-post-author' ) ).toHaveLength( 1 ); - } ); -} ); diff --git a/assets/src/stories-editor/blocks/amp-story-post-date/edit.css b/assets/src/stories-editor/blocks/amp-story-post-date/edit.css index 57c5af21b97..5e36ecf3e43 100644 --- a/assets/src/stories-editor/blocks/amp-story-post-date/edit.css +++ b/assets/src/stories-editor/blocks/amp-story-post-date/edit.css @@ -14,9 +14,10 @@ .wp-block[data-type="amp/amp-story-post-date"] .wp-block-amp-amp-story-post-date:not(.is-amp-fit-text) { display: block; + font-size: 16px; } -.wp-block[data-type="amp/amp-story-post-date"] .wp-block-amp-amp-story-post-date.is-amp-fit-text.is-measuring-fontsize { +.wp-block[data-type="amp/amp-story-post-date"] .wp-block-amp-amp-story-post-date.is-measuring { height: initial !important; width: initial !important; position: absolute !important; diff --git a/assets/src/stories-editor/blocks/amp-story-post-date/index.js b/assets/src/stories-editor/blocks/amp-story-post-date/index.js index f819dcf42a7..cdb46f8fff4 100644 --- a/assets/src/stories-editor/blocks/amp-story-post-date/index.js +++ b/assets/src/stories-editor/blocks/amp-story-post-date/index.js @@ -17,10 +17,7 @@ export const settings = { category: 'common', icon: 'clock', keywords: [ - __( 'post', 'amp' ), __( 'publish date', 'amp' ), - __( 'published date', 'amp' ), - __( 'date', 'amp' ), ], ...getMetaBlockSettings( { tagName: 'div', diff --git a/assets/src/stories-editor/blocks/amp-story-post-date/test/index.js b/assets/src/stories-editor/blocks/amp-story-post-date/test/index.js deleted file mode 100644 index 70fe2e40d9f..00000000000 --- a/assets/src/stories-editor/blocks/amp-story-post-date/test/index.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * WordPress dependencies - */ -import { addFilter, removeFilter } from '@wordpress/hooks'; -import '@wordpress/editor'; // So the data store is registered. - -/** - * Internal dependencies - */ -import { name, settings } from '../'; -import { blockEditRender } from '../../../../test/helpers'; -import { addAMPAttributes } from '../../../helpers'; -import { withAmpStorySettings } from '../../../components'; - -describe( 'amp/amp-story-post-date', () => { - beforeAll( () => { - addFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes', addAMPAttributes ); - addFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings', withAmpStorySettings ); - } ); - - afterAll( () => { - removeFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes' ); - removeFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings' ); - } ); - - test( 'block is rendered', () => { - const wrapper = blockEditRender( name, settings ); - - expect( wrapper.render().find( '.wp-block-amp-amp-story-post-date' ) ).toHaveLength( 1 ); - } ); -} ); diff --git a/assets/src/stories-editor/blocks/amp-story-post-title/edit.css b/assets/src/stories-editor/blocks/amp-story-post-title/edit.css index 5ce1ff7a68b..6d358d1afc6 100644 --- a/assets/src/stories-editor/blocks/amp-story-post-title/edit.css +++ b/assets/src/stories-editor/blocks/amp-story-post-title/edit.css @@ -15,9 +15,10 @@ .wp-block[data-type="amp/amp-story-post-title"] .wp-block-amp-amp-story-post-title:not(.is-amp-fit-text) { display: block; + font-size: 16px; } -.wp-block[data-type="amp/amp-story-post-title"] .wp-block-amp-amp-story-post-title.is-amp-fit-text.is-measuring-fontsize { +.wp-block[data-type="amp/amp-story-post-title"] .wp-block-amp-amp-story-post-title.is-measuring { height: initial !important; width: initial !important; position: absolute !important; diff --git a/assets/src/stories-editor/blocks/amp-story-post-title/test/index.js b/assets/src/stories-editor/blocks/amp-story-post-title/test/index.js deleted file mode 100644 index de72e267857..00000000000 --- a/assets/src/stories-editor/blocks/amp-story-post-title/test/index.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * WordPress dependencies - */ -import { addFilter, removeFilter } from '@wordpress/hooks'; -import '@wordpress/editor'; // So the data store is registered. - -/** - * Internal dependencies - */ -import { name, settings } from '../'; -import { blockEditRender } from '../../../../test/helpers'; -import { addAMPAttributes } from '../../../helpers'; -import { withAmpStorySettings } from '../../../components'; - -describe( 'amp/amp-story-post-title', () => { - beforeAll( () => { - addFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes', addAMPAttributes ); - addFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings', withAmpStorySettings ); - } ); - - afterAll( () => { - removeFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes' ); - removeFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings' ); - } ); - - test( 'block is rendered', () => { - const wrapper = blockEditRender( name, settings ); - - expect( wrapper.render().find( '.wp-block-amp-amp-story-post-title' ) ).toHaveLength( 1 ); - } ); -} ); diff --git a/assets/src/stories-editor/blocks/amp-story-text/deprecated.js b/assets/src/stories-editor/blocks/amp-story-text/deprecated.js new file mode 100644 index 00000000000..0d34ee6e330 --- /dev/null +++ b/assets/src/stories-editor/blocks/amp-story-text/deprecated.js @@ -0,0 +1,96 @@ +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { RichText } from '@wordpress/block-editor'; +import { RawHTML } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { migrateV120 } from '../../deprecations/shared'; +import { getClassNameFromBlockAttributes, getStylesFromBlockAttributes } from '../../helpers'; + +const blockAttributes = { + placeholder: { + type: 'string', + }, + content: { + type: 'string', + source: 'html', + selector: '.amp-text-content', + default: '', + }, + type: { + type: 'string', + default: 'auto', + }, + tagName: { + type: 'string', + default: 'p', + }, + align: { + type: 'string', + }, +}; + +const SaveV120 = ( { attributes } ) => { + const { + content, + ampFitText, + tagName, + } = attributes; + + const className = getClassNameFromBlockAttributes( attributes ); + const styles = getStylesFromBlockAttributes( attributes ); + + if ( ! ampFitText ) { + return ( + + ); + } + + const ContentTag = tagName; + + styles.display = 'flex'; + + // Uses RawHTML to mimic RichText.Content behavior. + return ( + + { content } + + ); +}; + +SaveV120.propTypes = { + attributes: PropTypes.shape( { + content: PropTypes.string, + ampFitText: PropTypes.bool, + tagName: PropTypes.string, + } ).isRequired, +}; + +export default [ + { + attributes: { + ...blockAttributes, + deprecated: { + default: '1.2.0', + }, + }, + save: SaveV120, + migrate: migrateV120, + }, +]; diff --git a/assets/src/stories-editor/blocks/amp-story-text/edit.css b/assets/src/stories-editor/blocks/amp-story-text/edit.css index 1541d9afabe..26fe48dcd24 100644 --- a/assets/src/stories-editor/blocks/amp-story-text/edit.css +++ b/assets/src/stories-editor/blocks/amp-story-text/edit.css @@ -10,40 +10,34 @@ width: 100%; } -.wp-block[data-type="amp/amp-story-text"] .amp-story-resize-container .components-resizable-box__handle-right { - right: -10px; +.is-not-editing .wp-block-amp-amp-story-text.block-editor-rich-text__editable.editor-rich-text__editable { + cursor: grab; } -.wp-block[data-type="amp/amp-story-text"] .amp-story-resize-container .components-resizable-box__handle-right::before { - margin: 0; +.wp-block-amp-story-text-wrapper.is-empty-draggable-text, +.wp-block-amp-story-text-wrapper:not(.with-line-height) { + height: 100%; } -.wp-block[data-type="amp/amp-story-text"] .amp-story-resize-container .components-resizable-box__handle-bottom { - bottom: -8px; - width: 50px; - left: calc(50% - 25px); +.wp-block-amp-story-text-wrapper .amp-overlay { + height: 100%; + width: 100%; + z-index: 1000; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; } -.amp-story-text__resize-container .components-resizable-box__handle-bottom::before { - margin: 0 auto; +.wp-block-amp-story-text-wrapper.is-empty-draggable-text .amp-text-placeholder { + opacity: 0.62; } .editor-styles-wrapper #amp-story-editor .wp-block .wp-block[data-type="amp/amp-story-text"] { width: initial; } -.wp-block[data-type="amp/amp-story-text"] .components-resizable-box__handle, -.wp-block.is-typing[data-type="amp/amp-story-text"] .components-resizable-box__handle { - display: block; - opacity: 0; - transition: opacity .3s; -} - -.wp-block[data-type="amp/amp-story-text"]:hover .components-resizable-box__handle, -.wp-block[data-type="amp/amp-story-text"] .components-resizable-box__handle:hover { - opacity: 100; -} - .wp-block[data-type="amp/amp-story-text"] .block-editor-rich-text__editable, div[data-type="amp/amp-story-page"] .block-editor-inner-blocks .block-editor-block-list__block-edit { display: inline-block; @@ -59,7 +53,7 @@ div[data-type="amp/amp-story-page"] .block-editor-inner-blocks .block-editor-blo line-height: 1.15; } -.wp-block[data-type="amp/amp-story-text"] .wp-block-amp-story-text .is-amp-fit-text.is-measuring-fontsize { +.wp-block[data-type="amp/amp-story-text"] .wp-block-amp-story-text .is-amp-fit-text.is-measuring { height: initial !important; width: initial !important; position: absolute !important; @@ -67,14 +61,6 @@ div[data-type="amp/amp-story-page"] .block-editor-inner-blocks .block-editor-blo .editor-block-list__layout .wp-block[data-type="amp/amp-story-text"] .editor-block-list__block-edit::before { position: absolute; - top: 2px; - left: 2px; - right: 2px; - bottom: 2px; -} - -.wp-block[data-type="amp/amp-story-text"] div[draggable="true"] { - border: 5px solid transparent; } .wp-block[data-type="amp/amp-story-text"] .amp-story-editor__rotate-container, diff --git a/assets/src/stories-editor/blocks/amp-story-text/edit.js b/assets/src/stories-editor/blocks/amp-story-text/edit.js index 8c1e0eedd18..86a39900f21 100644 --- a/assets/src/stories-editor/blocks/amp-story-text/edit.js +++ b/assets/src/stories-editor/blocks/amp-story-text/edit.js @@ -3,6 +3,7 @@ */ import classnames from 'classnames'; import PropTypes from 'prop-types'; +import { isEqual } from 'lodash'; /** * WordPress dependencies @@ -19,38 +20,72 @@ import { select } from '@wordpress/data'; /** * Internal dependencies */ -import { maybeUpdateFontSize } from '../../helpers'; +import { maybeUpdateFontSize, maybeUpdateBlockDimensions, setInputSelectionToEnd } from '../../helpers'; import { getBackgroundColorWithOpacity } from '../../../common/helpers'; import './edit.css'; +import { DraggableText } from '../../components'; class TextBlockEdit extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); + + this.state = { + isEditing: false, + hasOverlay: true, + }; this.onReplace = this.onReplace.bind( this ); + this.toggleIsEditing = this.toggleIsEditing.bind( this ); + this.toggleOverlay = this.toggleOverlay.bind( this ); } componentDidMount() { maybeUpdateFontSize( this.props ); } - componentDidUpdate( prevProps ) { - const { attributes } = this.props; + componentDidUpdate( prevProps, prevState ) { + const { attributes, fontSize, isSelected } = this.props; const { height, width, content, + ampFitText, + ampFontFamily, } = attributes; - if ( - prevProps.attributes.height === height && - prevProps.attributes.width === width && - prevProps.attributes.content === content - ) { - return; + // If the block was unselected, make sure that it's not editing anymore. + if ( ! isSelected && prevProps.isSelected ) { + this.toggleIsEditing( false ); + this.toggleOverlay( true ); } - maybeUpdateFontSize( this.props ); + const checkFontSize = ampFitText && ( + prevProps.attributes.ampFitText !== ampFitText || + prevProps.attributes.ampFontFamily !== ampFontFamily || + prevProps.attributes.width !== width || + prevProps.attributes.height !== height || + prevProps.attributes.content !== content + ); + + if ( checkFontSize ) { + maybeUpdateFontSize( this.props ); + } + + const checkBlockDimensions = ! ampFitText && ( + ! isEqual( prevProps.fontSize, fontSize ) || + prevProps.attributes.ampFitText !== ampFitText || + prevProps.attributes.ampFontFamily !== ampFontFamily || + prevProps.attributes.content !== content + ); + + if ( checkBlockDimensions ) { + maybeUpdateBlockDimensions( this.props ); + } + + // If the state changed to editing, focus on the text. + if ( this.state.isEditing && ! prevState.isEditing ) { + setInputSelectionToEnd( '.is-selected .wp-block-amp-amp-story-text' ); + } } onReplace( blocks ) { @@ -72,15 +107,37 @@ class TextBlockEdit extends Component { ) ) ); } + toggleIsEditing( enable ) { + if ( enable !== this.state.isEditing ) { + this.setState( { + isEditing: ! this.state.isEditing, + } ); + } + } + + toggleOverlay( add ) { + if ( add !== this.state.hasOverlay ) { + this.setState( { + hasOverlay: ! this.state.hasOverlay, + } ); + } + } + render() { + const { isEditing, hasOverlay } = this.state; + const { attributes, setAttributes, className, + clientId, fontSize, + isPartOfMultiSelection, + isSelected, backgroundColor, customBackgroundColor, textColor, + name, } = this.props; const { @@ -90,18 +147,10 @@ class TextBlockEdit extends Component { ampFitText, autoFontSize, height, - tagName, opacity, } = attributes; - let userFontSize = fontSize && fontSize.size ? fontSize.size + 'px' : undefined; - if ( undefined === userFontSize ) { - if ( 'h1' === tagName ) { - userFontSize = 2 + 'rem'; - } else if ( 'h2' === tagName ) { - userFontSize = 1.5 + 'rem'; - } - } + const userFontSize = fontSize && fontSize.size ? fontSize.size + 'px' : undefined; const { colors } = select( 'core/block-editor' ).getSettings(); const appliedBackgroundColor = getBackgroundColorWithOpacity( colors, backgroundColor, customBackgroundColor, opacity ); @@ -128,6 +177,21 @@ class TextBlockEdit extends Component { wrapperClass += ' ' + styleClasses.join( ' ' ); } + const textWrapperClassName = 'wp-block-amp-story-text'; + const textClassNames = { + 'has-text-color': textColor.color, + [ textColor.class ]: textColor.class, + [ fontSize.class ]: ampFitText ? undefined : fontSize.class, + 'is-amp-fit-text': ampFitText, + }; + const textStyle = { + color: textColor.color, + fontSize: ampFitText ? autoFontSize + 'px' : userFontSize, + textAlign: align, + position: ampFitText && content.length ? 'static' : undefined, + }; + + // StoryBlockMover is added here to the Text block since it depends on isEditing state. return ( <> @@ -138,30 +202,41 @@ class TextBlockEdit extends Component {
- setAttributes( { content: nextContent } ) } - // The 2 following lines are necessary for pasting to work. - onReplace={ this.onReplace } - onSplit={ () => {} } - style={ { - color: textColor.color, - fontSize: ampFitText ? autoFontSize + 'px' : userFontSize, - textAlign: align, - position: ampFitText && content.length ? 'static' : undefined, - } } - className={ classnames( className, { - 'has-text-color': textColor.color, - [ textColor.class ]: textColor.class, - [ fontSize.class ]: ampFitText ? undefined : fontSize.class, - 'is-amp-fit-text': ampFitText, - } ) } - placeholder={ placeholder || __( 'Write text…', 'amp' ) } - /> + { isEditing && + setAttributes( { content: nextContent } ) } + // The 2 following lines are necessary for pasting to work. + onReplace={ this.onReplace } + onSplit={ () => {} } + style={ textStyle } + className={ classnames( className, textClassNames ) } + placeholder={ placeholder || __( 'Write text…', 'amp' ) } + /> + } + { ! isEditing && + + }
); @@ -179,8 +254,12 @@ TextBlockEdit.propTypes = { autoFontSize: PropTypes.number, tagName: PropTypes.string, opacity: PropTypes.number, + className: PropTypes.string, + ampFontFamily: PropTypes.string, } ).isRequired, isSelected: PropTypes.bool.isRequired, + clientId: PropTypes.string.isRequired, + isPartOfMultiSelection: PropTypes.bool, onReplace: PropTypes.func.isRequired, name: PropTypes.string.isRequired, setAttributes: PropTypes.func.isRequired, @@ -190,6 +269,7 @@ TextBlockEdit.propTypes = { shortName: PropTypes.string, size: PropTypes.number, slug: PropTypes.string, + class: PropTypes.string, } ).isRequired, backgroundColor: PropTypes.shape( { color: PropTypes.string, diff --git a/assets/src/stories-editor/blocks/amp-story-text/index.js b/assets/src/stories-editor/blocks/amp-story-text/index.js index cba6359031a..05e0bb00641 100644 --- a/assets/src/stories-editor/blocks/amp-story-text/index.js +++ b/assets/src/stories-editor/blocks/amp-story-text/index.js @@ -9,6 +9,7 @@ import { createBlock, getBlockAttributes } from '@wordpress/blocks'; */ import edit from './edit'; import save from './save'; +import deprecated from './deprecated'; export const name = 'amp/amp-story-text'; @@ -44,7 +45,7 @@ const schema = { export const settings = { title: __( 'Text', 'amp' ), - description: __( 'Add free-form text to your story', 'amp' ), + description: __( 'Add free-form text to your story.', 'amp' ), icon: , @@ -64,6 +65,8 @@ export const settings = { save, + deprecated, + transforms: { from: [ { diff --git a/assets/src/stories-editor/blocks/amp-story-text/test/index.js b/assets/src/stories-editor/blocks/amp-story-text/test/index.js deleted file mode 100644 index 4c39440c795..00000000000 --- a/assets/src/stories-editor/blocks/amp-story-text/test/index.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * WordPress dependencies - */ -import { addFilter, removeFilter } from '@wordpress/hooks'; - -/** - * Internal dependencies - */ -import { name, settings } from '../'; -import { blockEditRender } from '../../../../test/helpers'; -import { addAMPAttributes } from '../../../helpers'; -import { withAmpStorySettings } from '../../../components'; - -describe( 'amp/amp-story-text', () => { - beforeAll( () => { - addFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes', addAMPAttributes ); - addFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings', withAmpStorySettings ); - } ); - - afterAll( () => { - removeFilter( 'blocks.registerBlockType', 'ampStoryEditorBlocks/addAttributes' ); - removeFilter( 'editor.BlockEdit', 'ampStoryEditorBlocks/addStorySettings' ); - } ); - - // Because of onSplit warnings. See https://github.com/WordPress/gutenberg/pull/14765 - test.skip( 'block edit matches snapshot', () => { // eslint-disable-line jest/no-disabled-tests - const wrapper = blockEditRender( name, settings ); - - expect( wrapper.render().find( '.wp-block-amp-story-text' ) ).toHaveLength( 1 ); - } ); -} ); diff --git a/assets/src/stories-editor/components/block-mover/block-drag-area.js b/assets/src/stories-editor/components/block-mover/block-drag-area.js index bd604051773..583ebc60e83 100644 --- a/assets/src/stories-editor/components/block-mover/block-drag-area.js +++ b/assets/src/stories-editor/components/block-mover/block-drag-area.js @@ -8,11 +8,12 @@ import PropTypes from 'prop-types'; */ import BlockDraggable from './block-draggable'; -export const BlockDragArea = ( { children, className, onDragStart, onDragEnd, blockElementId, clientId } ) => { +export const BlockDragArea = ( { children, blockName, className, onDragStart, onDragEnd, blockElementId, clientId } ) => { return ( @@ -39,6 +40,7 @@ BlockDragArea.propTypes = { onDragStart: PropTypes.func, onDragEnd: PropTypes.func, blockElementId: PropTypes.string, + blockName: PropTypes.string, clientId: PropTypes.string, children: PropTypes.any.isRequired, }; diff --git a/assets/src/stories-editor/components/block-mover/block-draggable.js b/assets/src/stories-editor/components/block-mover/block-draggable.js index 903f860d829..f1c25b6f863 100644 --- a/assets/src/stories-editor/components/block-mover/block-draggable.js +++ b/assets/src/stories-editor/components/block-mover/block-draggable.js @@ -17,7 +17,7 @@ import { withSelect } from '@wordpress/data'; */ import Draggable from './draggable'; -const BlockDraggable = ( { children, clientId, rootClientId, blockElementId, index, onDragStart, onDragEnd } ) => { +const BlockDraggable = ( { children, clientId, blockName, rootClientId, blockElementId, index, onDragStart, onDragEnd } ) => { const transferData = { type: 'block', srcIndex: index, @@ -27,6 +27,7 @@ const BlockDraggable = ( { children, clientId, rootClientId, blockElementId, ind return ( /Chrome/i.test( window.navigator.userAgent ); const documentHasIframes = ( ) => [ ...document.getElementById( 'editor' ).querySelectorAll( 'iframe' ) ].length > 0; class Draggable extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); this.onDragStart = this.onDragStart.bind( this ); this.onDragOver = this.onDragOver.bind( this ); @@ -78,10 +82,17 @@ class Draggable extends Component { * @param {Object} event The non-custom DragEvent. */ onDragOver( event ) { - this.cloneWrapper.style.top = - `${ parseInt( this.cloneWrapper.style.top, 10 ) + event.clientY - this.cursorTop }px`; + const top = parseInt( this.cloneWrapper.style.top ) + event.clientY - this.cursorTop; + + // Don't allow the CTA button to go over its top limit. + if ( 'amp/amp-story-cta' === this.props.blockName ) { + this.cloneWrapper.style.top = top >= 0 ? `${ top }px` : '0px'; + } else { + this.cloneWrapper.style.top = `${ top }px`; + } + this.cloneWrapper.style.left = - `${ parseInt( this.cloneWrapper.style.left, 10 ) + event.clientX - this.cursorLeft }px`; + `${ parseInt( this.cloneWrapper.style.left ) + event.clientX - this.cursorLeft }px`; // Update cursor coordinates. this.cursorLeft = event.clientX; @@ -104,8 +115,9 @@ class Draggable extends Component { * @param {Object} transferData The data to be set to the event's dataTransfer - to be accessible in any later drop logic. */ onDragStart( event ) { - const { elementId, transferData, onDragStart = noop } = this.props; + const { blockName, elementId, transferData, onDragStart = noop } = this.props; const element = document.getElementById( elementId ); + const isCTABlock = 'amp/amp-story-cta' === blockName; const parentPage = element.closest( 'div[data-type="amp/amp-story-page"]' ); if ( ! element || ! parentPage ) { event.preventDefault(); @@ -136,9 +148,12 @@ class Draggable extends Component { const clone = element.cloneNode( true ); this.cloneWrapper.style.transform = clone.style.transform; + // 20% of the full value in case of CTA block. + const baseHeight = isCTABlock ? STORY_PAGE_INNER_HEIGHT / 5 : STORY_PAGE_INNER_HEIGHT; + // Position clone over the original element. - this.cloneWrapper.style.top = `${ getPixelsFromPercentage( 'y', parseInt( clone.style.top ) ) }px`; - this.cloneWrapper.style.left = `${ getPixelsFromPercentage( 'x', parseInt( clone.style.left ) ) }px`; + this.cloneWrapper.style.top = `${ getPixelsFromPercentage( 'y', parseInt( clone.style.top ), baseHeight ) }px`; + this.cloneWrapper.style.left = `${ getPixelsFromPercentage( 'x', parseInt( clone.style.left ), STORY_PAGE_INNER_WIDTH ) }px`; clone.id = `clone-${ elementId }`; clone.style.top = 0; @@ -204,6 +219,7 @@ class Draggable extends Component { } Draggable.propTypes = { + blockName: PropTypes.string, elementId: PropTypes.string, transferData: PropTypes.object, onDragStart: PropTypes.func, diff --git a/assets/src/stories-editor/components/block-mover/ignore-nested-events.js b/assets/src/stories-editor/components/block-mover/ignore-nested-events.js index 68097fadeed..5fb487c8679 100644 --- a/assets/src/stories-editor/components/block-mover/ignore-nested-events.js +++ b/assets/src/stories-editor/components/block-mover/ignore-nested-events.js @@ -31,8 +31,8 @@ import { Component, forwardRef } from '@wordpress/element'; * @type {Component} */ export class IgnoreNestedEvents extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); this.proxyEvent = this.proxyEvent.bind( this ); @@ -51,7 +51,7 @@ export class IgnoreNestedEvents extends Component { * @return {void} */ proxyEvent( event ) { - const isHandled = !! event.nativeEvent._blockHandled; + const isHandled = Boolean( event.nativeEvent._blockHandled ); // Assign into the native event, since React will reuse their synthetic // event objects and this property assignment could otherwise leak. @@ -83,7 +83,7 @@ export class IgnoreNestedEvents extends Component { // Try to match prop key as event handler const match = key.match( /^on([A-Z][a-zA-Z]+?)(Handled)?$/ ); if ( match ) { - const isHandledProp = !! match[ 2 ]; + const isHandledProp = Boolean( match[ 2 ] ); if ( isHandledProp ) { // Avoid assigning through the invalid prop key. This // assumes mutation of shallow clone by above spread. diff --git a/assets/src/stories-editor/components/block-mover/index.js b/assets/src/stories-editor/components/block-mover/index.js index ed132b5f9cc..73fea5b680b 100644 --- a/assets/src/stories-editor/components/block-mover/index.js +++ b/assets/src/stories-editor/components/block-mover/index.js @@ -19,12 +19,12 @@ import { Component } from '@wordpress/element'; * Internal dependencies */ import { BlockDragArea } from './block-drag-area'; -import IgnoreNestedEvents from './ignore-nested-events'; +import IgnoreNestedEvents from './ignore-nested-events'; // eslint-disable-line import/no-named-as-default import './edit.css'; export class BlockMover extends Component { render() { - const { children, isDraggable, isMovable, onDragStart, clientId, blockElementId } = this.props; + const { children, blockName, isDraggable, isMovable, onDragStart, clientId, blockElementId } = this.props; if ( ! isMovable || ! isDraggable ) { return children; @@ -41,6 +41,7 @@ export class BlockMover extends Component { children={ children } clientId={ clientId } blockElementId={ blockElementId } + blockName={ blockName } onDragStart={ onDragStart } />
@@ -55,6 +56,7 @@ BlockMover.propTypes = { onDragStart: PropTypes.func, clientId: PropTypes.string, blockElementId: PropTypes.string, + blockName: PropTypes.string, children: PropTypes.any.isRequired, }; diff --git a/assets/src/stories-editor/components/block-navigation/edit.css b/assets/src/stories-editor/components/block-navigation/edit.css index 826c5b31cfc..efe5c1db65c 100644 --- a/assets/src/stories-editor/components/block-navigation/edit.css +++ b/assets/src/stories-editor/components/block-navigation/edit.css @@ -4,12 +4,27 @@ left: 45px; top: 75px; width: 300px; + min-width: 115px; z-index: 80; list-style-type: none; padding: 0; margin: 0; } +@media (max-width: 1200px) { + + .is-sidebar-opened #amp-story-block-navigation { + left: 0; + } +} + +@media (min-width: 1001px) and (max-width: 1100px) { + + .is-sidebar-opened .editor-block-list__layout { + margin-right: -100px; + } +} + @media (min-width: 961px) { #amp-story-block-navigation { @@ -17,6 +32,13 @@ } } +@media (min-width: 961px) and (max-width: 1000px) { + + .is-sidebar-opened #amp-story-block-navigation { + display: none; + } +} + #amp-story-block-navigation .editor-inserter { position: absolute; bottom: 100%; @@ -34,6 +56,12 @@ #amp-story-block-navigation .block-editor-block-navigation__list { list-style-type: none; + margin-bottom: 15px; +} + +#amp-story-block-navigation .editor-block-navigation__list__static { + margin: 0; + padding: 0; } #amp-story-block-navigation .components-icon-button .dashicon { @@ -142,6 +170,11 @@ } } +/* Hide default block navigation icon in toolbar */ +.edit-post-header-toolbar .components-icon-button.block-editor-block-navigation { + display: none; +} + @media (min-width: 961px) { .edit-post-header-toolbar #amp-story-shortcuts { @@ -153,10 +186,6 @@ margin-right: 0; } - .components-icon-button.block-editor-block-navigation { - display: none; - } - .block-editor-block-navigation__container { background: #fff; border: 1px solid #eee; @@ -200,18 +229,27 @@ display: none; } -.block-editor-block-navigation__list .block-editor-block-navigation__item .components-drop-zone.is-close-to-bottom { +.block-editor-block-navigation__list li .block-editor-block-navigation__item .components-drop-zone { background: none; - border-bottom: 3px solid #0071a1; } -.block-editor-block-navigation__list li .block-editor-block-navigation__item .components-drop-zone.is-close-to-top { - background: none; - border: none; +.block-editor-block-navigation__list li .block-navigation__placeholder { + transition: height 0.3s ease; + height: 0; } -.block-editor-block-navigation__list li:first-child .block-editor-block-navigation__item .components-drop-zone.is-close-to-top { - background: none; - border-top: 3px solid #0071a1; - border-bottom: none; +/* When dragging near the top of a drop zone, display the placeholder so there is a space between this and the button above. */ +.block-editor-block-navigation__list li .block-editor-block-navigation__item .components-drop-zone.is-close-to-top + .block-navigation__placeholder { + visibility: hidden; + height: 36px; +} + +/* Allow dropping below the last +
+ ); + } + const transferData = { type: 'block', srcIndex: getBlockIndex( clientId ), @@ -112,6 +137,7 @@ class BlockNavigationItem extends Component { className={ this.state.isDragging ? 'is-dragging-block' : undefined } onDrop={ this.onDrop } /> +
+ ) } + /> + + + ) } + { + isExcessiveVideoSize && ( + + { + sprintf( + /* translators: %d: the number of recommended megabytes per second */ + __( 'A video size of less than %d MB per second is recommended.', 'amp' ), + VIDEO_ALLOWED_MEGABYTES_PER_SECOND + ) + } + { ' ' } + { + sprintf( + /* translators: %d: the number of actual megabytes per second */ + __( 'The selected video is %d MB per second.', 'amp' ), + Math.round( videoBytesPerSecond / MEGABYTE_IN_BYTES ) + ) + } + + ) + } +
+
+
+
+ + ); + } +} + +CustomVideoBlockEdit.propTypes = { + attributes: PropTypes.shape( { + caption: PropTypes.string, + controls: PropTypes.bool, + loop: PropTypes.bool, + id: PropTypes.number, + poster: PropTypes.string, + src: PropTypes.string, + width: PropTypes.number, + height: PropTypes.number, + } ), + className: PropTypes.string, + instanceId: PropTypes.number, + isSelected: PropTypes.bool, + mediaUpload: PropTypes.func, + noticeUI: PropTypes.oneOfType( [ PropTypes.func, PropTypes.bool ] ), + noticeOperations: PropTypes.object, + media: PropTypes.object, + setAttributes: PropTypes.func, + videoFeaturedImage: PropTypes.shape( { + source_url: PropTypes.string, + } ), +}; + +export default compose( [ + withSelect( ( select, { attributes } ) => { + const { getMedia } = select( 'core' ); + + let videoFeaturedImage; + + const { id, poster } = attributes; + + const media = id ? getMedia( id ) : undefined; + + if ( media && media.featured_media && ! poster ) { + videoFeaturedImage = getMedia( media.featured_media ); + } + + return { + media, + videoFeaturedImage, + }; + } ), + withNotices, + withInstanceId, +] )( CustomVideoBlockEdit ); diff --git a/assets/src/stories-editor/components/draggable-text.js b/assets/src/stories-editor/components/draggable-text.js new file mode 100644 index 00000000000..f5a7d9968db --- /dev/null +++ b/assets/src/stories-editor/components/draggable-text.js @@ -0,0 +1,127 @@ +/** + * External dependencies + */ +import PropTypes from 'prop-types'; +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { RawHTML } from '@wordpress/element'; +import { ENTER } from '@wordpress/keycodes'; + +/** + * Internal dependencies + */ +import { StoryBlockMover } from './index'; + +/** + * Draggable Text: a non-editable text content which can be dragged. + * Switches to edit mode when clicked twice. + * + * @param {Object} props Component props. + * + * @return {WPElement} Rendered element. + */ +const DraggableText = ( props ) => { + const { + blockClass, + blockElementId, + clientId, + hasOverlay, + isDraggable, + isSelected, + name, + toggleIsEditing, + toggleOverlay, + text, + textStyle, + textWrapperClass, + placeholder, + } = props; + return ( + +
{ + if ( isSelected ) { + toggleIsEditing( true ); + } + } } + onMouseDown={ ( event ) => { + // Prevent text selection on double click. + if ( 1 < event.detail ) { + event.preventDefault(); + } + } } + onKeyDown={ ( event ) => { + event.stopPropagation(); + if ( ENTER === event.keyCode && isSelected ) { + toggleOverlay( false ); + toggleIsEditing( true ); + } + } } + > + { hasOverlay && (
{ + toggleOverlay( false ); + e.stopPropagation(); + } } + onKeyDown={ ( event ) => { + event.stopPropagation(); + if ( ENTER === event.keyCode && isSelected ) { + toggleOverlay( false ); + toggleIsEditing( true ); + } + } } + >
+ ) } +
+ { text && text.length ? + { text } : ( + + { placeholder } + + ) } +
+
+
+ ); +}; + +DraggableText.propTypes = { + clientId: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + blockClass: PropTypes.string, + blockElementId: PropTypes.string.isRequired, + hasOverlay: PropTypes.bool.isRequired, + isDraggable: PropTypes.bool.isRequired, + isSelected: PropTypes.bool.isRequired, + toggleIsEditing: PropTypes.func.isRequired, + toggleOverlay: PropTypes.func.isRequired, + text: PropTypes.string.isRequired, + textStyle: PropTypes.shape( { + color: PropTypes.string, + fontSize: PropTypes.string, + textAlign: PropTypes.string, + position: PropTypes.string, + } ).isRequired, + textWrapperClass: PropTypes.string.isRequired, + placeholder: PropTypes.string.isRequired, +}; + +export default DraggableText; diff --git a/assets/src/stories-editor/components/editor-carousel/index.js b/assets/src/stories-editor/components/editor-carousel/index.js index 8b6fb2ca33b..9fae137ac85 100644 --- a/assets/src/stories-editor/components/editor-carousel/index.js +++ b/assets/src/stories-editor/components/editor-carousel/index.js @@ -25,8 +25,8 @@ const TOTAL_PAGE_MARGIN = 50; const PAGE_BORDER = 1; class EditorCarousel extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); this.translateWrapper.bind( this ); } diff --git a/assets/src/stories-editor/components/editor-carousel/test/__snapshots__/index.js.snap b/assets/src/stories-editor/components/editor-carousel/test/__snapshots__/index.js.snap deleted file mode 100644 index 4b92213fea6..00000000000 --- a/assets/src/stories-editor/components/editor-carousel/test/__snapshots__/index.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EditorCarousel should render block shortcuts 1`] = ` - - - -`; diff --git a/assets/src/stories-editor/components/editor-carousel/test/index.js b/assets/src/stories-editor/components/editor-carousel/test/index.js deleted file mode 100644 index c2056d99a13..00000000000 --- a/assets/src/stories-editor/components/editor-carousel/test/index.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - -/** - * Internal dependencies - */ -import EditorCarousel from '../'; - -describe( 'EditorCarousel', () => { - it( 'should render block shortcuts', () => { - const wrapper = shallow( - - ); - - expect( wrapper ).toMatchSnapshot(); - } ); -} ); diff --git a/assets/src/stories-editor/components/higher-order/with-amp-story-settings.js b/assets/src/stories-editor/components/higher-order/with-amp-story-settings.js index b7fd6aea6ea..f5d51f2a960 100644 --- a/assets/src/stories-editor/components/higher-order/with-amp-story-settings.js +++ b/assets/src/stories-editor/components/higher-order/with-amp-story-settings.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - /** * WordPress dependencies */ @@ -16,7 +11,7 @@ import { } from '@wordpress/block-editor'; import { getBlockType } from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; -import { compose, createHigherOrderComponent, withSafeTimeout } from '@wordpress/compose'; +import { compose, createHigherOrderComponent } from '@wordpress/compose'; import { IconButton, PanelBody, @@ -39,12 +34,14 @@ import { MIN_BLOCK_WIDTH, MIN_BLOCK_HEIGHTS, BLOCKS_WITH_RESIZING, + BLOCK_ROTATION_SNAPS, + BLOCK_ROTATION_SNAP_GAP, } from '../../constants'; import { getBlockOrderDescription, maybeEnqueueFontStyle, getCallToActionBlock } from '../../helpers'; -import bringForwardIcon from '../../../../images/bring-forward.svg'; -import sendBackwardIcon from '../../../../images/send-backwards.svg'; -import bringFrontIcon from '../../../../images/bring-front.svg'; -import sendBackIcon from '../../../../images/send-back.svg'; +import bringForwardIcon from '../../../../images/stories-editor/bring-forward.svg'; +import sendBackwardIcon from '../../../../images/stories-editor/send-backwards.svg'; +import bringFrontIcon from '../../../../images/stories-editor/bring-front.svg'; +import sendBackIcon from '../../../../images/stories-editor/send-back.svg'; const { getComputedStyle, ampStoriesFonts } = window; @@ -63,7 +60,6 @@ const applyFallbackStyles = withFallbackStyles( ( node, ownProps ) => { const applyWithSelect = withSelect( ( select, props ) => { const { getSelectedBlockClientId, getBlockRootClientId, getBlock, getBlockOrder, getBlockIndex } = select( 'core/block-editor' ); const { getAnimatedBlocks, isValidAnimationPredecessor } = select( 'amp/story' ); - const { getMedia } = select( 'core' ); const currentBlock = getSelectedBlockClientId(); const page = getBlockRootClientId( currentBlock ); @@ -75,16 +71,6 @@ const applyWithSelect = withSelect( ( select, props ) => { const blockClientIds = getBlockOrder( parentBlockId ); const blockIndex = getBlockIndex( props.clientId, parentBlockId ); - const isVideoBlock = 'core/video' === props.name; - let videoFeaturedImage; - - // If we have a video set from an attachment but there is no poster, use the featured image of the video if available. - if ( isVideoBlock && props.attributes.id && ! props.attributes.poster ) { - const media = getMedia( props.attributes.id ); - const featuredImage = media && get( media, [ '_links', 'wp:featuredmedia', 0, 'href' ], null ); - videoFeaturedImage = featuredImage && getMedia( Number( featuredImage.split( '/' ).pop() ) ); - } - const reversedIndex = blockClientIds.length - 1 - blockIndex; return { @@ -116,7 +102,6 @@ const applyWithSelect = withSelect( ( select, props ) => { }; } ); }, - videoFeaturedImage, }; } ); @@ -175,17 +160,15 @@ const enhance = compose( applyFallbackStyles, applyWithSelect, applyWithDispatch, - withSafeTimeout, ); export default createHigherOrderComponent( ( BlockEdit ) => { - return enhance( ( props ) => { + return enhance( ( props ) => { // eslint-disable-line complexity const { clientId, name, attributes, - isSelected, isLast, isFirst, currentBlockPosition, @@ -205,14 +188,12 @@ export default createHigherOrderComponent( onAnimationDelayChange, getAnimatedBlocks, animationAfter, - videoFeaturedImage, startBlockActions, stopBlockActions, bringForward, sendBackward, moveFront, moveBack, - setTimeout, } = props; const isChildBlock = ALLOWED_CHILD_BLOCKS.includes( name ); @@ -238,20 +219,12 @@ export default createHigherOrderComponent( width, opacity, type: textBlockTextType, - ampShowImageCaption, ampAnimationType, ampAnimationDuration, ampAnimationDelay, rotationAngle, } = attributes; - // If we have a video set from an attachment but there is no poster, use the featured image of the video if available. - if ( isVideoBlock && videoFeaturedImage ) { - setTimeout( () => { - setAttributes( { poster: videoFeaturedImage.source_url } ); - }, 100 ); - } - const isEmptyImageBlock = isImageBlock && ( ! attributes.url || ! attributes.url.length ); // In case of table, the min height depends on the number of rows, each row takes 45px. let minHeight; @@ -268,12 +241,12 @@ export default createHigherOrderComponent( minHeight = MIN_BLOCK_HEIGHTS[ name ] || MIN_BLOCK_HEIGHTS.default; } + const captionAttribute = isVideoBlock ? 'ampShowCaption' : 'ampShowImageCaption'; return ( <> - { ( ! isMovableBlock || isEmptyImageBlock ) && ( ) } + { ( ! isMovableBlock ) && ( ) } { isMovableBlock && ! isEmptyImageBlock && needsResizing && ( - + { isTextBlock && ( - + ) } + { ! isTextBlock && ( + + + + ) } ) } - { isMovableBlock && ! needsResizing && ( + { isMovableBlock && ( ! needsResizing || isEmptyImageBlock ) && ( setAttributes( { opacity: value } ) } min={ 5 } @@ -541,23 +523,23 @@ export default createHigherOrderComponent(
) } - { isImageBlock && ( + { ( isImageBlock || isVideoBlock ) && ( diff --git a/assets/src/stories-editor/components/higher-order/with-video-poster-image-notice.js b/assets/src/stories-editor/components/higher-order/with-video-poster-image-notice.js deleted file mode 100644 index caa17997be0..00000000000 --- a/assets/src/stories-editor/components/higher-order/with-video-poster-image-notice.js +++ /dev/null @@ -1,56 +0,0 @@ - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { select } from '@wordpress/data'; -import { Notice } from '@wordpress/components'; - -/** - * Internal dependencies - */ -import { createHigherOrderComponent } from '@wordpress/compose'; - -/** - * Higher-order component that is used for adding an error notice for the poster image control for video blocks in AMP stories. - * - * Note that if a user has selected a poster image and then removed it, the poster attribute will remain but be empty. - * Because of this, an AMP validation error will not not always ensue if no poster image is supplied, as the plugin's sanitizer - * will supply an empty poster attribute to try to prevent a validation error from happening. The "amp-story >> amp-video" spec - * has a loose definition for amp-video[poster] in that only specifies that it is mandatory, but it leaves its value as being undefined. - * So this is why an empty poster attribute actually circumvents a validation error from happening. In the future if the value_url type - * is specified, then the sanitizer will not be able to supply an empty value to circumvent the AMP validation error. - * - * @link https://github.com/ampproject/amphtml/blob/b814e5d74cadf554c5caa1233d71e8e840788ff5/extensions/amp-video/validator-amp-video.protoascii#L147-L150 - * - * @return {Function} Higher-order component. - */ -export default createHigherOrderComponent( - ( MediaUpload ) => { - return ( props ) => { - const isAmpStory = 'amp_story' === select( 'core/editor' ).getCurrentPostType(); - const selectedBlock = select( 'core/block-editor' ).getSelectedBlock(); - - // The `! selectedBlock.attributes.src` check ensures that the notice is not added to the block placeholder. - // Otherwise, if a video has been selected, then it is presumed that the MediaUpload here is for the poster image. - // There is apparently no way to know for sure that this is for the poster, other than by checking if - // props.title === "Select Poster Image", but this would be quite brittle. - if ( ! isAmpStory || ! selectedBlock || 'core/video' !== selectedBlock.name || ! selectedBlock.attributes.src || selectedBlock.attributes.poster ) { - return ; - } - - return ( - <> - - { __( 'A poster is required for videos in stories.', 'amp' ) } - - - - ); - }; - }, - 'withVideoPosterImageNotice' -); diff --git a/assets/src/stories-editor/components/index.js b/assets/src/stories-editor/components/index.js index 123356e4b56..dc1bed21354 100644 --- a/assets/src/stories-editor/components/index.js +++ b/assets/src/stories-editor/components/index.js @@ -3,6 +3,7 @@ export { default as AnimationOrderPicker } from './animation-order-picker'; export { default as BlockNavigation } from './block-navigation'; export { default as BlockPreview } from './block-preview'; export { default as BlockPreviewLabel } from './block-preview-label'; +export { default as DraggableText } from './draggable-text'; export { default as EditorCarousel } from './editor-carousel'; export { default as Reorderer } from './reorderer'; export { default as StoryControls } from './story-controls'; @@ -24,10 +25,12 @@ export { default as withHasSelectedInnerBlock } from './higher-order/with-has-se export { default as withPageNumber } from './higher-order/with-page-number'; export { default as withStoryFeaturedImageNotice } from './higher-order/with-story-featured-image-notice'; export { default as withEditFeaturedImage } from './with-edit-featured-image'; +export { default as withCustomVideoBlockEdit } from './with-custom-video-block-edit'; +export { default as CustomVideoBlockEdit } from './custom-video-block-edit'; export { default as withIsReordering } from './higher-order/with-is-reordering'; export { default as withSelectedBlock } from './higher-order/with-selected-block'; export { default as withWrapperProps } from './with-wrapper-props'; export { default as withActivePageState } from './with-active-page-state'; export { default as withStoryBlockDropZone } from './with-story-block-drop-zone'; export { default as withCallToActionValidation } from './higher-order/with-call-to-action-validation'; -export { default as withVideoPosterImageNotice } from './higher-order/with-video-poster-image-notice'; +export { default as withEnforcedVideoUploadType } from './with-enforced-video-upload-type'; diff --git a/assets/src/stories-editor/components/inserter/edit.css b/assets/src/stories-editor/components/inserter/edit.css new file mode 100644 index 00000000000..9882bad618c --- /dev/null +++ b/assets/src/stories-editor/components/inserter/edit.css @@ -0,0 +1,3 @@ +.amp__block-editor-inserter__menu.block-editor-inserter__menu { + flex-direction: column; +} diff --git a/assets/src/stories-editor/components/inserter/index.js b/assets/src/stories-editor/components/inserter/index.js index cc3fb1529c6..9f651f8416f 100644 --- a/assets/src/stories-editor/components/inserter/index.js +++ b/assets/src/stories-editor/components/inserter/index.js @@ -24,12 +24,13 @@ import { withSelect } from '@wordpress/data'; /** * Internal dependencies */ -import InserterMenu from './menu'; +import InserterMenu from './menu'; // eslint-disable-line import/no-named-as-default +import './edit.css'; const defaultRenderToggle = ( { onToggle, disabled, isOpen } ) => ( @@ -128,13 +129,18 @@ Inserter.propTypes = { rootClientId: PropTypes.string, clientId: PropTypes.string, isAppender: PropTypes.bool, + showInserter: PropTypes.bool, }; const applyWithSelect = withSelect( ( select ) => { const { isReordering } = select( 'amp/story' ); + // As used in component + const showInserter = select( 'core/edit-post' ).getEditorMode() === 'visual' && select( 'core/editor' ).getEditorSettings().richEditingEnabled; + return { isReordering: isReordering(), + disabled: ! showInserter, }; } ); diff --git a/assets/src/stories-editor/components/inserter/menu.js b/assets/src/stories-editor/components/inserter/menu.js index 8a561a19182..677b60b8c94 100644 --- a/assets/src/stories-editor/components/inserter/menu.js +++ b/assets/src/stories-editor/components/inserter/menu.js @@ -104,8 +104,8 @@ export const normalizeTerm = ( term ) => { }; export class InserterMenu extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); this.state = { childItems: [], filterValue: '', @@ -171,7 +171,6 @@ export class InserterMenu extends Component { this.props.setTimeout( () => { // We need a generic way to access the panel's container - // eslint-disable-next-line react/no-find-dom-node scrollIntoView( this.panels[ panel ], this.inserterResults.current, { alignWithTop: true, } ); @@ -275,31 +274,31 @@ export class InserterMenu extends Component { /* eslint-disable jsx-a11y/no-autofocus, jsx-a11y/no-static-element-interactions */ return (
- { !! suggestedItems.length && + { Boolean( suggestedItems.length ) && ); - /* eslint-enable jsx-a11y/no-autofocus, jsx-a11y/no-noninteractive-element-interactions */ + /* eslint-enable jsx-a11y/no-autofocus, jsx-a11y/no-static-element-interactions */ } } @@ -429,7 +428,6 @@ export default compose( // This breaks the withDispatch not containing any logic rule. // Since it's a function only called when the event handlers are called, // it's fine to extract it. - // eslint-disable-next-line no-restricted-syntax function getInsertionIndex( name ) { const { getBlockIndex, diff --git a/assets/src/stories-editor/components/inserter/tests/menu.js b/assets/src/stories-editor/components/inserter/test/menu.js similarity index 89% rename from assets/src/stories-editor/components/inserter/tests/menu.js rename to assets/src/stories-editor/components/inserter/test/menu.js index 421b76d6b35..8cc11fda10d 100644 --- a/assets/src/stories-editor/components/inserter/tests/menu.js +++ b/assets/src/stories-editor/components/inserter/test/menu.js @@ -18,6 +18,7 @@ const textItem = { category: 'common', isDisabled: false, utility: 1, + hasChildBlocksWithInserterSupport: false, }; const advancedTextItem = { @@ -28,6 +29,7 @@ const advancedTextItem = { category: 'common', isDisabled: false, utility: 1, + hasChildBlocksWithInserterSupport: false, }; const someOtherItem = { @@ -38,6 +40,7 @@ const someOtherItem = { category: 'common', isDisabled: false, utility: 1, + hasChildBlocksWithInserterSupport: false, }; const moreItem = { @@ -48,6 +51,7 @@ const moreItem = { category: 'layout', isDisabled: true, utility: 0, + hasChildBlocksWithInserterSupport: false, }; const youtubeItem = { @@ -59,6 +63,7 @@ const youtubeItem = { keywords: [ 'google' ], isDisabled: false, utility: 0, + hasChildBlocksWithInserterSupport: false, }; const textEmbedItem = { @@ -69,6 +74,7 @@ const textEmbedItem = { category: 'embed', isDisabled: false, utility: 0, + hasChildBlocksWithInserterSupport: false, }; const reusableItem = { @@ -79,6 +85,7 @@ const reusableItem = { category: 'reusable', isDisabled: false, utility: 0, + hasChildBlocksWithInserterSupport: false, }; const items = [ @@ -92,11 +99,16 @@ const items = [ ]; const DEFAULT_PROPS = { + instanceId: 1, position: 'top center', items, + onSelect: noop, debouncedSpeak: noop, fetchReusableBlocks: noop, setTimeout: noop, + showInsertionPoint: noop, + hideInsertionPoint: noop, + rootChildBlocks: [], }; const getWrapperForProps = ( propOverrides ) => { @@ -127,14 +139,14 @@ const assertNoResultsMessageToBePresent = ( element ) => { const noResultsMessage = element.querySelector( '.block-editor-inserter__no-results' ); - expect( noResultsMessage.textContent ).toEqual( 'No blocks found.' ); + expect( noResultsMessage.textContent ).toStrictEqual( 'No blocks found.' ); }; const assertNoResultsMessageNotToBePresent = ( element ) => { const noResultsMessage = element.querySelector( '.block-editor-inserter__no-results' ); - expect( noResultsMessage ).toBe( null ); + expect( noResultsMessage ).toBeNull( ); }; const assertOpenedPanels = ( element, expectedOpen = 0 ) => { @@ -175,7 +187,7 @@ describe( 'InserterMenu', () => { '.block-editor-block-types-list__item' ); - expect( visibleBlocks ).toBe( null ); + expect( visibleBlocks ).toBeNull( ); assertNoResultsMessageToBePresent( element ); } ); @@ -186,9 +198,9 @@ describe( 'InserterMenu', () => { '.block-editor-block-types-list__item-title' ); expect( visibleBlocks ).toHaveLength( 3 ); - expect( visibleBlocks[ 0 ].textContent ).toEqual( 'Text' ); - expect( visibleBlocks[ 1 ].textContent ).toEqual( 'Advanced Text' ); - expect( visibleBlocks[ 2 ].textContent ).toEqual( 'Some Other Block' ); + expect( visibleBlocks[ 0 ].textContent ).toStrictEqual( 'Text' ); + expect( visibleBlocks[ 1 ].textContent ).toStrictEqual( 'Advanced Text' ); + expect( visibleBlocks[ 2 ].textContent ).toStrictEqual( 'Some Other Block' ); } ); it( 'should limit the number of items shown in the suggested tab', () => { @@ -327,25 +339,25 @@ describe( 'InserterMenu', () => { describe( 'searchItems', () => { it( 'should search items using the title ignoring case', () => { - expect( searchItems( items, 'TEXT' ) ).toEqual( + expect( searchItems( items, 'TEXT' ) ).toStrictEqual( [ textItem, advancedTextItem, textEmbedItem ] ); } ); it( 'should search items using the keywords', () => { - expect( searchItems( items, 'GOOGL' ) ).toEqual( + expect( searchItems( items, 'GOOGL' ) ).toStrictEqual( [ youtubeItem ] ); } ); it( 'should search items using the categories', () => { - expect( searchItems( items, 'LAYOUT' ) ).toEqual( + expect( searchItems( items, 'LAYOUT' ) ).toStrictEqual( [ moreItem ] ); } ); it( 'should ignore a leading slash on a search term', () => { - expect( searchItems( items, '/GOOGL' ) ).toEqual( + expect( searchItems( items, '/GOOGL' ) ).toStrictEqual( [ youtubeItem ] ); } ); @@ -353,19 +365,19 @@ describe( 'searchItems', () => { describe( 'normalizeTerm', () => { it( 'should remove diacritics', () => { - expect( normalizeTerm( 'média' ) ).toEqual( + expect( normalizeTerm( 'média' ) ).toStrictEqual( 'media' ); } ); it( 'should trim whitespace', () => { - expect( normalizeTerm( ' média ' ) ).toEqual( + expect( normalizeTerm( ' média ' ) ).toStrictEqual( 'media' ); } ); it( 'should convert to lowercase', () => { - expect( normalizeTerm( ' Média ' ) ).toEqual( + expect( normalizeTerm( ' Média ' ) ).toStrictEqual( 'media' ); } ); diff --git a/assets/src/stories-editor/components/reorderer/edit.css b/assets/src/stories-editor/components/reorderer/edit.css index a53411a9203..5460ed8df13 100644 --- a/assets/src/stories-editor/components/reorderer/edit.css +++ b/assets/src/stories-editor/components/reorderer/edit.css @@ -44,7 +44,7 @@ --preview-translateX: -40%; --preview-translateY: -70%; position: absolute; - transform: scale(var(--preview-scale)) translateX(var(--preview-translateX)) translateY(var(--preview-translateY)),; + transform: scale(var(--preview-scale)) translateX(var(--preview-translateX)) translateY(var(--preview-translateY)); } .amp-story-reorderer .block-editor-block-list__layout > .block-editor-block-list__block > .block-editor-block-list__block-edit { diff --git a/assets/src/stories-editor/components/reorderer/item.js b/assets/src/stories-editor/components/reorderer/item.js index 064e2865d49..f1d9063bd5c 100644 --- a/assets/src/stories-editor/components/reorderer/item.js +++ b/assets/src/stories-editor/components/reorderer/item.js @@ -50,8 +50,8 @@ const parseDropEvent = ( event ) => { * in order to not re-invent the wheel. */ class ReordererItem extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); this.state = { isDragging: false, @@ -66,6 +66,8 @@ class ReordererItem extends Component { if ( index !== undefined ) { return position.x === 'right' ? index + 1 : index; } + + return undefined; } onDrop( event, position ) { diff --git a/assets/src/stories-editor/components/resizable-box/edit.css b/assets/src/stories-editor/components/resizable-box/edit.css index a82215bff96..8b712b393e4 100644 --- a/assets/src/stories-editor/components/resizable-box/edit.css +++ b/assets/src/stories-editor/components/resizable-box/edit.css @@ -1,23 +1,43 @@ -.amp-story-resize-container .components-resizable-box__handle-right { - right: -14px; - height: 50px; - top: calc(50% - 25px); +.amp-story-resize-container .components-resizable-box__handle { + display: block; + opacity: 0; + transition: opacity .3s; } -.amp-story-resize-container .components-resizable-box__handle-right::before { - margin: 0; +.block-editor-inner-blocks .wp-block.is-typing .amp-story-resize-container .components-resizable-box__handle { + opacity: 0; +} + +.block-editor-inner-blocks .wp-block:hover .amp-story-resize-container .components-resizable-box__handle, +.block-editor-inner-blocks .wp-block.is-selected .amp-story-resize-container .components-resizable-box__handle, +.block-editor-inner-blocks .wp-block .amp-story-resize-container.is-resizing .components-resizable-box__handle { + opacity: 1; +} + +.amp-story-resize-container .components-resizable-box__handle-top { + top: -14px !important; +} + +.amp-story-resize-container .components-resizable-box__handle-right { + right: -14px !important; } .amp-story-resize-container .components-resizable-box__handle-bottom { - bottom: -14px; - width: 50px; - left: calc(50% - 25px); + bottom: -14px !important; +} + +.amp-story-resize-container .components-resizable-box__handle-left { + left: -14px !important; } .amp-story-editor__rotate-container .components-resizable-box__handle { display: none !important; } +.amp-story-resize-container .amp-story-editor__rotate-container { + height: 100%; +} + .wp-block-image .components-resizable-box__container img { height: 100%; object-fit: cover; @@ -30,23 +50,3 @@ .block-editor-block-list__block[data-type="core/image"] img { -webkit-user-drag: none; } - -.amp-story-resize-container .components-resizable-box__handle-bottom::before { - margin: 0 auto; -} - -.amp-story-resize-container .amp-story-editor__rotate-container { - height: 100%; -} - -.wp-block .components-resizable-box__handle, -.wp-block.is-typing .components-resizable-box__handle { - display: block; - opacity: 0; - transition: opacity .3s; -} - -.wp-block.amp-page-active .wp-block:hover .components-resizable-box__handle, -.wp-block.amp-page-active .wp-block .components-resizable-box__handle:hover { - opacity: 1; -} diff --git a/assets/src/stories-editor/components/resizable-box/helpers.js b/assets/src/stories-editor/components/resizable-box/helpers.js new file mode 100644 index 00000000000..779f51af387 --- /dev/null +++ b/assets/src/stories-editor/components/resizable-box/helpers.js @@ -0,0 +1,192 @@ +/** + * Internal dependencies + */ +import { + BLOCKS_WITH_TEXT_SETTINGS, + REVERSE_WIDTH_CALCULATIONS, + REVERSE_HEIGHT_CALCULATIONS, +} from '../../constants'; +import { getPixelsFromPercentage } from '../../helpers'; + +/** + * Get the distance between two points based on pythagorean. + * + * @param {number} deltaX Difference between X coordinates. + * @param {number} deltaY Difference between Y coordinates. + * @return {number} Difference between the two points. + */ +const getDelta = ( deltaX, deltaY ) => Math.sqrt( Math.pow( deltaX, 2 ) + Math.pow( deltaY, 2 ) ); + +/** + * Converts degrees to radian. + * + * @param {number} angle Angle. + * @return {number} Radian. + */ +export const getRadianFromDeg = ( angle ) => angle * Math.PI / 180; + +/** + * Gets width and height delta values based on the original coordinates, rotation angle and mouse event. + * + * @param {Object} event MouseEvent. + * @param {number} angle Rotation angle. + * @param {number} lastSeenX Starting X coordinate. + * @param {number} lastSeenY Starting Y coordinate. + * @param {string} direction Direction of resizing. + * @return {Object} Width and height values. + */ +export const getResizedWidthAndHeight = ( event, angle, lastSeenX, lastSeenY, direction ) => { + const deltaY = event.clientY - lastSeenY; + const deltaX = event.clientX - lastSeenX; + const deltaL = getDelta( deltaX, deltaY ); + + // Get the angle between the two points. + const alpha = Math.atan2( deltaY, deltaX ); + // Get the difference with rotation angle. + const beta = alpha - getRadianFromDeg( angle ); + + const resizedHorizontally = direction.toLowerCase().includes( 'left' ) || direction.toLowerCase().includes( 'right' ); + const resizedVertically = direction.toLowerCase().includes( 'top' ) || direction.toLowerCase().includes( 'bottom' ); + const deltaW = resizedHorizontally ? deltaL * Math.cos( beta ) : 0; + const deltaH = resizedVertically ? deltaL * Math.sin( beta ) : 0; + + // When using left or top handles the size of the block is changing reversely to right and bottom. + return { + deltaW: REVERSE_WIDTH_CALCULATIONS.includes( direction ) ? -deltaW : deltaW, + deltaH: REVERSE_HEIGHT_CALCULATIONS.includes( direction ) ? -deltaH : deltaH, + }; +}; + +/** + * Returns the block's inner text element. + * + * @param {string} blockName Block name. + * @param {HTMLElement} blockElement The block's `.wp-block` element. + * @return {?HTMLElement} Inner element if found, otherwise null. + */ +export const getBlockTextElement = ( blockName, blockElement ) => { + const isBlockWithText = BLOCKS_WITH_TEXT_SETTINGS.includes( blockName ) || 'core/code' === blockName; + + if ( ! isBlockWithText ) { + return null; + } + + switch ( blockName ) { + case 'amp/amp-story-text': + return blockElement.querySelector( '.block-editor-rich-text__editable.editor-rich-text__editable' ); + case 'amp/amp-story-post-title': + return blockElement.querySelector( '.wp-block-amp-amp-story-post-title' ); + case 'amp/amp-story-post-author': + return blockElement.querySelector( '.wp-block-amp-amp-story-post-author' ); + case 'amp/amp-story-post-date': + return blockElement.querySelector( '.wp-block-amp-amp-story-post-date' ); + case 'core/code': + return blockElement.querySelector( '.wp-block-code' ); + default: + return null; + } +}; + +/** + * Get block positioning after resizing, not considering the rotation. + * + * @param {string} direction Resizing direction. + * @param {string} blockElementLeft Original left position before resizing. + * @param {string} blockElementTop Original top position before resizing. + * @param {number} deltaW Width change with resizing. + * @param {number} deltaH Height change with resizing. + * @return {{top: number, left: number}} Top and left positioning after resizing, not considering the rotation. + */ +export const getResizedBlockPosition = ( direction, blockElementLeft, blockElementTop, deltaW, deltaH ) => { + const baseLeftInPixels = getPixelsFromPercentage( 'x', parseFloat( blockElementLeft ) ); + const baseTopInPixels = getPixelsFromPercentage( 'y', parseFloat( blockElementTop ) ); + switch ( direction ) { + case 'topRight': + return { + left: baseLeftInPixels, + top: baseTopInPixels - deltaH, + }; + case 'bottomLeft': + return { + left: baseLeftInPixels - deltaW, + top: baseTopInPixels, + }; + case 'left': + case 'topLeft': + case 'top': + return { + left: baseLeftInPixels - deltaW, + top: baseTopInPixels - deltaH, + }; + default: + return { + left: baseLeftInPixels, + top: baseTopInPixels, + }; + } +}; + +/** + * Get block position after resizing, considering the rotation. + * + * @param {string} direction Resizing direction. + * @param {Object} originalPosition Original block position, considering the rotation. + * @param {Object} diff Block position difference after resizing. + * @return {{top: number, left: number}} Top and left params in pixels. + */ +export const getUpdatedBlockPosition = ( direction, originalPosition, diff ) => { + switch ( direction ) { + case 'topRight': + return { + left: originalPosition.left - diff.left, + top: originalPosition.top - diff.top, + }; + case 'bottomLeft': + return { + left: originalPosition.left + diff.left, + top: originalPosition.top + diff.top, + }; + case 'left': + case 'topLeft': + case 'top': + return { + left: originalPosition.left + diff.left, + top: originalPosition.top - diff.top, + }; + default: + return { + left: originalPosition.left - diff.left, + top: originalPosition.top + diff.top, + }; + } +}; + +/** + * Get block's left and top position based on width, height, and radian. + * + * @param {number} width Width. + * @param {number} height Height. + * @param {number} radian Radian. + * @param {string} direction Resizing direction. + * @return {{top: number, left: number}} Top and left positioning. + */ +export const getBlockPositioning = ( width, height, radian, direction ) => { + // The center point of the block. + const x = -width / 2; + const y = height / 2; + + let rotatedX, rotatedY; + // Get the center point of the rotated block. + if ( 'topRight' === direction || 'bottomLeft' === direction ) { + rotatedX = ( y * -Math.sin( radian ) ) + ( x * Math.cos( radian ) ); + rotatedY = ( y * Math.cos( radian ) ) - ( x * -Math.sin( radian ) ); + } else { + rotatedX = ( y * Math.sin( radian ) ) + ( x * Math.cos( radian ) ); + rotatedY = ( y * Math.cos( radian ) ) - ( x * Math.sin( radian ) ); + } + + return { + left: rotatedX - x, + top: rotatedY - y, + }; +}; diff --git a/assets/src/stories-editor/components/resizable-box/index.js b/assets/src/stories-editor/components/resizable-box/index.js index 815b108f5b2..f9761772443 100644 --- a/assets/src/stories-editor/components/resizable-box/index.js +++ b/assets/src/stories-editor/components/resizable-box/index.js @@ -7,6 +7,7 @@ import PropTypes from 'prop-types'; /** * WordPress dependencies */ +import { Component } from '@wordpress/element'; import { ResizableBox } from '@wordpress/components'; /** @@ -14,14 +15,23 @@ import { ResizableBox } from '@wordpress/components'; */ import './edit.css'; import { - getResizedWidthAndHeight, getPercentageFromPixels, getPixelsFromPercentage, +} from '../../helpers'; +import { getBlockPositioning, + getResizedBlockPosition, + getUpdatedBlockPosition, + getResizedWidthAndHeight, getRadianFromDeg, -} from '../../helpers'; + getBlockTextElement, +} from './helpers'; -import { BLOCKS_WITH_TEXT_SETTINGS, TEXT_BLOCK_BORDER, TEXT_BLOCK_PADDING } from '../../constants'; +import { + TEXT_BLOCK_PADDING, + REVERSE_WIDTH_CALCULATIONS, + REVERSE_HEIGHT_CALCULATIONS, +} from '../../constants'; let lastSeenX = 0, lastSeenY = 0, @@ -30,226 +40,233 @@ let lastSeenX = 0, blockElement = null, blockElementTop, blockElementLeft, + lastDeltaW, + lastDeltaH, imageWrapper, textBlockWrapper, textElement; -const EnhancedResizableBox = ( props ) => { - const { - isSelected, - angle, - blockName, - ampFitText, - minWidth, - minHeight, - onResizeStart, - onResizeStop, - children, - ...otherProps - } = props; - - let { - width, - height, - } = props; - - const isImage = 'core/image' === blockName; - const isBlockWithText = BLOCKS_WITH_TEXT_SETTINGS.includes( blockName ) || 'core/code' === blockName; - const isText = 'amp/amp-story-text' === blockName; - - if ( isText ) { - height += TEXT_BLOCK_PADDING * 2; - width += TEXT_BLOCK_PADDING * 2; +class EnhancedResizableBox extends Component { + constructor( ...args ) { + super( ...args ); + this.state = { + isResizing: false, + }; } - const textBlockBorderInPercentageTop = getPercentageFromPixels( 'y', TEXT_BLOCK_BORDER ); - const textBlockBorderInPercentageLeft = getPercentageFromPixels( 'x', TEXT_BLOCK_BORDER ); - - return ( - { - const { deltaW, deltaH } = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, direction ); - let appliedWidth = width + deltaW; - let appliedHeight = height + deltaH; - - // Ensure the measures not crossing limits. - appliedWidth = appliedWidth < lastWidth ? lastWidth : appliedWidth; - appliedHeight = appliedHeight < lastHeight ? lastHeight : appliedHeight; - - const elementTop = parseFloat( blockElement.style.top ); - const elementLeft = parseFloat( blockElement.style.left ); - - const positionTop = ! isText ? Number( elementTop.toFixed( 2 ) ) : Number( ( elementTop + textBlockBorderInPercentageTop ).toFixed( 2 ) ); - const positionLeft = ! isText ? Number( elementLeft.toFixed( 2 ) ) : Number( ( elementLeft + textBlockBorderInPercentageLeft ).toFixed( 2 ) ); - - onResizeStop( { - width: isText ? parseInt( appliedWidth, 10 ) - ( TEXT_BLOCK_PADDING * 2 ) : parseInt( appliedWidth, 10 ), - height: isText ? parseInt( appliedHeight, 10 ) - ( TEXT_BLOCK_PADDING * 2 ) : parseInt( appliedHeight, 10 ), - positionTop, - positionLeft, - } ); - } } - onResizeStart={ ( event, direction, element ) => { - lastSeenX = event.clientX; - lastSeenY = event.clientY; - lastWidth = width; - lastHeight = height; - blockElement = element.closest( '.wp-block' ); - blockElementTop = blockElement.style.top; - blockElementLeft = blockElement.style.left; - if ( isImage ) { - imageWrapper = blockElement.querySelector( 'figure .components-resizable-box__container' ); - } - if ( isBlockWithText && ! ampFitText ) { - switch ( blockName ) { - case 'amp/amp-story-text': - textElement = blockElement.querySelector( '.block-editor-rich-text__editable.editor-rich-text__editable' ); - break; - case 'amp/amp-story-post-title': - textElement = blockElement.querySelector( '.wp-block-amp-amp-story-post-title' ); - break; - case 'amp/amp-story-post-author': - textElement = blockElement.querySelector( '.wp-block-amp-amp-story-post-author' ); - break; - case 'amp/amp-story-post-date': - textElement = blockElement.querySelector( '.wp-block-amp-amp-story-post-date' ); - break; - case 'core/code': - textElement = blockElement.querySelector( '.wp-block-code' ); + render() { + const { + angle, + blockName, + ampFitText, + minWidth, + minHeight, + onResizeStart, + onResizeStop, + children, + ...otherProps + } = this.props; + + let { + width, + height, + } = this.props; + + const { isResizing } = this.state; + + const isImage = 'core/image' === blockName; + const isText = 'amp/amp-story-text' === blockName; + + return ( + { + const { deltaW, deltaH } = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, direction ); + let appliedWidth = width + deltaW; + let appliedHeight = height + deltaH; + + // Restore the full height for Text block wrapper. + if ( textBlockWrapper ) { + textBlockWrapper.style.height = '100%'; } - } else { - textElement = null; - } - - if ( ampFitText && isText ) { - textBlockWrapper = blockElement.querySelector( '.with-line-height' ); - } else { - textBlockWrapper = null; - } - - onResizeStart(); - } } - onResize={ ( event, direction, element ) => { - const { deltaW, deltaH } = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, direction ); - - // Handle case where media is inserted from URL. - if ( isImage && ! width && ! height ) { - width = blockElement.clientWidth; - height = blockElement.clientHeight; - } - let appliedWidth = minWidth <= width + deltaW ? width + deltaW : minWidth; - let appliedHeight = minHeight <= height + deltaH ? height + deltaH : minHeight; - const isReducing = 0 > deltaW || 0 > deltaH; - - if ( textElement && isReducing ) { - // If we have a rotated block, let's assign the width and height for measuring. - // Without assigning the new measure, the calculation would be incorrect due to angle. - // Text block is handled differently since the text block's content shouldn't have full width while measuring. - if ( angle ) { - if ( ! isText ) { - textElement.style.width = appliedWidth + 'px'; - textElement.style.height = appliedHeight + 'px'; - } else if ( isText && ! ampFitText ) { - textElement.style.width = 'initial'; - } + + // Ensure the measures not crossing limits. + appliedWidth = appliedWidth < lastWidth ? lastWidth : appliedWidth; + appliedHeight = appliedHeight < lastHeight ? lastHeight : appliedHeight; + + const elementTop = parseFloat( blockElement.style.top ); + const elementLeft = parseFloat( blockElement.style.left ); + + const positionTop = Number( elementTop.toFixed( 2 ) ); + const positionLeft = Number( elementLeft.toFixed( 2 ) ); + + this.setState( { isResizing: false } ); + + onResizeStop( { + width: parseInt( appliedWidth ), + height: parseInt( appliedHeight ), + positionTop, + positionLeft, + } ); + } } + onResizeStart={ ( event, direction, element ) => { + lastSeenX = event.clientX; + lastSeenY = event.clientY; + lastWidth = width; + lastHeight = height; + lastDeltaW = null; + lastDeltaH = null; + blockElement = element.closest( '.wp-block' ); + blockElementTop = blockElement.style.top; + blockElementLeft = blockElement.style.left; + if ( isImage ) { + imageWrapper = blockElement.querySelector( 'figure .components-resizable-box__container' ); } + textElement = ! ampFitText ? getBlockTextElement( blockName, blockElement ) : null; - const scrollWidth = isText ? textElement.scrollWidth + ( TEXT_BLOCK_BORDER * 2 ) : textElement.scrollWidth; - const scrollHeight = isText ? textElement.scrollHeight + ( TEXT_BLOCK_BORDER * 2 ) : textElement.scrollHeight; - if ( appliedWidth < scrollWidth || appliedHeight < scrollHeight ) { - appliedWidth = lastWidth; - appliedHeight = lastHeight; + if ( ampFitText && isText ) { + textBlockWrapper = blockElement.querySelector( '.with-line-height' ); + } else { + textBlockWrapper = null; } - // If we have rotated block, let's restore the correct measures. - if ( angle ) { - if ( ! isText ) { - textElement.style.width = 'initial'; - textElement.style.height = '100%'; - } else if ( isText && ! ampFitText ) { - textElement.style.width = '100%'; + + this.setState( { isResizing: true } ); + + onResizeStart(); + } } + onResize={ ( event, direction, element ) => { // eslint-disable-line complexity + const { deltaW, deltaH } = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, direction ); + + // Handle case where media is inserted from URL. + if ( isImage && ! width && ! height ) { + width = blockElement.clientWidth; + height = blockElement.clientHeight; + } + let appliedWidth = minWidth <= width + deltaW ? width + deltaW : minWidth; + let appliedHeight = minHeight <= height + deltaH ? height + deltaH : minHeight; + const isReducing = 0 > deltaW || 0 > deltaH; + + if ( textElement && isReducing ) { + // If we have a rotated block, let's assign the width and height for measuring. + // Without assigning the new measure, the calculation would be incorrect due to angle. + // Text block is handled differently since the text block's content shouldn't have full width while measuring. + if ( angle ) { + if ( ! isText ) { + textElement.style.width = appliedWidth + 'px'; + textElement.style.height = appliedHeight + 'px'; + } else if ( isText && ! ampFitText ) { + textElement.style.width = 'initial'; + } + } + + const scrollWidth = textElement.scrollWidth; + const scrollHeight = textElement.scrollHeight; + if ( appliedWidth <= scrollWidth || appliedHeight <= scrollHeight ) { + appliedWidth = lastWidth; + appliedHeight = lastHeight; + } + // If we have rotated block, let's restore the correct measures. + if ( angle ) { + if ( ! isText ) { + textElement.style.width = 'initial'; + textElement.style.height = '100%'; + } else if ( isText && ! ampFitText ) { + textElement.style.width = '100%'; + } } } - } - if ( angle ) { - const radianAngle = getRadianFromDeg( angle ); + // Is it's not min width / height yet, assign lastDeltaH and lastDeltaW for position calculation. + if ( minHeight < appliedHeight ) { + lastDeltaH = deltaH; + } + if ( minWidth < appliedWidth ) { + lastDeltaW = deltaW; + } - // Compare position between the initial and after resizing. - let initialPosition, resizedPosition; - // If it's a text block, we shouldn't consider the added padding for measuring. - if ( isText ) { - initialPosition = getBlockPositioning( width - ( TEXT_BLOCK_PADDING * 2 ), height - ( TEXT_BLOCK_PADDING * 2 ), radianAngle ); - resizedPosition = getBlockPositioning( appliedWidth - ( TEXT_BLOCK_PADDING * 2 ), appliedHeight - ( TEXT_BLOCK_PADDING * 2 ), radianAngle ); + if ( ! angle ) { + // If the resizing is to left or top then we have to compensate + if ( REVERSE_WIDTH_CALCULATIONS.includes( direction ) ) { + const leftInPx = getPixelsFromPercentage( 'x', parseFloat( blockElementLeft ) ); + blockElement.style.left = getPercentageFromPixels( 'x', leftInPx - lastDeltaW ) + '%'; + } + if ( REVERSE_HEIGHT_CALCULATIONS.includes( direction ) ) { + const topInPx = getPixelsFromPercentage( 'y', parseFloat( blockElementTop ) ); + blockElement.style.top = getPercentageFromPixels( 'y', topInPx - lastDeltaH ) + '%'; + } } else { - initialPosition = getBlockPositioning( width, height, radianAngle ); - resizedPosition = getBlockPositioning( appliedWidth, appliedHeight, radianAngle ); + const radianAngle = getRadianFromDeg( angle ); + + // Compare position between the initial and after resizing. + let initialPosition, resizedPosition; + // If it's a text block, we shouldn't consider the added padding for measuring. + if ( isText ) { + initialPosition = getBlockPositioning( width - ( TEXT_BLOCK_PADDING * 2 ), height - ( TEXT_BLOCK_PADDING * 2 ), radianAngle, direction ); + resizedPosition = getBlockPositioning( appliedWidth - ( TEXT_BLOCK_PADDING * 2 ), appliedHeight - ( TEXT_BLOCK_PADDING * 2 ), radianAngle, direction ); + } else { + initialPosition = getBlockPositioning( width, height, radianAngle, direction ); + resizedPosition = getBlockPositioning( appliedWidth, appliedHeight, radianAngle, direction ); + } + const diff = { + left: resizedPosition.left - initialPosition.left, + top: resizedPosition.top - initialPosition.top, + }; + + const originalPos = getResizedBlockPosition( direction, blockElementLeft, blockElementTop, lastDeltaW, lastDeltaH ); + const updatedPos = getUpdatedBlockPosition( direction, originalPos, diff ); + + blockElement.style.left = getPercentageFromPixels( 'x', updatedPos.left ) + '%'; + blockElement.style.top = getPercentageFromPixels( 'y', updatedPos.top ) + '%'; } - const diff = { - left: resizedPosition.left - initialPosition.left, - top: resizedPosition.top - initialPosition.top, - }; - // Get new position based on the difference. - const originalPos = { - left: getPixelsFromPercentage( 'x', parseFloat( blockElementLeft ) ), - top: getPixelsFromPercentage( 'y', parseFloat( blockElementTop ) ), - }; - - // @todo Figure out why calculating the new top / left position doesn't work in case of small height value. - // @todo Remove this temporary fix. - if ( appliedHeight < 60 ) { - diff.left = diff.left / ( 60 / appliedHeight ); - diff.right = diff.right / ( 60 / appliedHeight ); + + element.style.width = appliedWidth + 'px'; + element.style.height = appliedHeight + 'px'; + + lastWidth = appliedWidth; + lastHeight = appliedHeight; + + if ( textBlockWrapper ) { + if ( ampFitText ) { + textBlockWrapper.style.lineHeight = appliedHeight + 'px'; + } + // Also add the height to the wrapper since the background color is set to the wrapper. + textBlockWrapper.style.height = appliedHeight + 'px'; } - const updatedPos = { - left: originalPos.left - diff.left, - top: originalPos.top + diff.top, - }; - - blockElement.style.left = getPercentageFromPixels( 'x', updatedPos.left ) + '%'; - blockElement.style.top = getPercentageFromPixels( 'y', updatedPos.top ) + '%'; - } - - element.style.width = appliedWidth + 'px'; - element.style.height = appliedHeight + 'px'; - - lastWidth = appliedWidth; - lastHeight = appliedHeight; - - if ( textBlockWrapper && ampFitText ) { - textBlockWrapper.style.lineHeight = isText ? appliedHeight - ( TEXT_BLOCK_PADDING * 2 ) + 'px' : appliedHeight + 'px'; - } - - // If it's image, let's change the width and height of the image, too. - if ( imageWrapper && isImage ) { - imageWrapper.style.width = appliedWidth + 'px'; - imageWrapper.style.height = appliedHeight + 'px'; - } - } } - > - { children } - - ); -}; + // If it's image, let's change the width and height of the image, too. + if ( imageWrapper && isImage ) { + imageWrapper.style.width = appliedWidth + 'px'; + imageWrapper.style.height = appliedHeight + 'px'; + } + } } + > + { children } + + ); + } +} EnhancedResizableBox.propTypes = { - isSelected: PropTypes.bool, ampFitText: PropTypes.bool, angle: PropTypes.number, blockName: PropTypes.string, diff --git a/assets/src/stories-editor/components/resizable-box/test/getBlockPositioning.js b/assets/src/stories-editor/components/resizable-box/test/getBlockPositioning.js new file mode 100644 index 00000000000..3a488ddc8a9 --- /dev/null +++ b/assets/src/stories-editor/components/resizable-box/test/getBlockPositioning.js @@ -0,0 +1,10 @@ +/** + * Internal dependencies + */ +import { getBlockPositioning } from '../helpers'; + +describe( 'getBlockPositioning', () => { + it( 'should return correct coordinates', () => { + expect( getBlockPositioning( 50, 50, 1, 'direction' ) ).toStrictEqual( { top: 9.54433226690091, left: 32.52921697349392 } ); + } ); +} ); diff --git a/assets/src/stories-editor/helpers/test/getResizedWidthAndHeight.js b/assets/src/stories-editor/components/resizable-box/test/getResizedWidthAndHeight.js similarity index 76% rename from assets/src/stories-editor/helpers/test/getResizedWidthAndHeight.js rename to assets/src/stories-editor/components/resizable-box/test/getResizedWidthAndHeight.js index c18da6a826f..945f172c9ac 100644 --- a/assets/src/stories-editor/helpers/test/getResizedWidthAndHeight.js +++ b/assets/src/stories-editor/components/resizable-box/test/getResizedWidthAndHeight.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { getResizedWidthAndHeight } from '../'; +import { getResizedWidthAndHeight } from '../helpers'; describe( 'getResizedWidthAndHeight', () => { const event = { @@ -14,26 +14,26 @@ describe( 'getResizedWidthAndHeight', () => { it( 'should return zero for width delta when resizing from bottom', () => { const delta = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, 'bottom' ); - expect( delta.deltaW ).toEqual( 0 ); + expect( delta.deltaW ).toStrictEqual( 0 ); } ); it( 'should return zero for height delta when resizing from right', () => { const delta = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, 'right' ); - expect( delta.deltaH ).toEqual( 0 ); + expect( delta.deltaH ).toStrictEqual( 0 ); } ); it( 'should return correct width delta when resizing from right', () => { const delta = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, 'right' ); - expect( delta.deltaW ).toEqual( -70.71067811865476 ); + expect( delta.deltaW ).toStrictEqual( -70.71067811865476 ); } ); it( 'should return correct height delta when resizing from bottom', () => { const delta = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, 'bottom' ); - expect( delta.deltaH ).toEqual( -8.659560562354933e-15 ); + expect( delta.deltaH ).toStrictEqual( -8.659560562354933e-15 ); } ); it( 'should return zero values if the direction is not matched', () => { const delta = getResizedWidthAndHeight( event, angle, lastSeenX, lastSeenY, 'some-direction' ); - expect( delta ).toEqual( { deltaH: 0, deltaW: 0 } ); + expect( delta ).toStrictEqual( { deltaH: 0, deltaW: 0 } ); } ); } ); diff --git a/assets/src/stories-editor/components/rotatable-box/edit.css b/assets/src/stories-editor/components/rotatable-box/edit.css index d4ef9087c73..0c6d9b87c22 100644 --- a/assets/src/stories-editor/components/rotatable-box/edit.css +++ b/assets/src/stories-editor/components/rotatable-box/edit.css @@ -10,8 +10,7 @@ .editor-inner-blocks .block-editor-block-list__block.is-rotating .block-editor-block-list__insertion-point, .editor-inner-blocks .block-editor-block-list__block.is-rotating .block-editor-block-list__breadcrumb, -.editor-inner-blocks .block-editor-block-list__block.is-rotating .block-editor-block-contextual-toolbar, -.block-editor-block-list__layout .block-editor-block-list__block.is-rotating > .block-editor-block-list__block-edit::before { +.editor-inner-blocks .block-editor-block-list__block.is-rotating .block-editor-block-contextual-toolbar { display: none !important; } @@ -28,11 +27,10 @@ display: block; content: ""; cursor: inherit; - border-left: 1px solid theme(outlines); - box-shadow: inset -3px 0 0 0 #555d66; - height: 40px; + border-left: 1px solid rgba(66, 88, 99, .4); + height: 24px; width: 0; - margin: 0 auto; + margin: 3px auto 0; } .block-editor-block-list__block .rotatable-box-wrap .rotatable-box-wrap__handle { @@ -57,26 +55,26 @@ content: ""; cursor: inherit; display: block; - height: 16px; - width: 16px; + height: 15px; + width: 15px; margin: 0 auto; } -.wp-block .rotatable-box-wrap, -.wp-block.is-typing .rotatable-box-wrap { +.block-editor-inner-blocks .wp-block .rotatable-box-wrap, +.block-editor-inner-blocks .wp-block.is-typing .rotatable-box-wrap { display: block; opacity: 0; transition: opacity .3s; } -.wp-block.amp-page-active .wp-block:hover .rotatable-box-wrap, -.wp-block.amp-page-active .wp-block .rotatable-box-wrap:hover, -.wp-block.amp-page-active .wp-block.is-rotating .rotatable-box-wrap { - opacity: 1; +.block-editor-inner-blocks .wp-block.is-typing .rotatable-box-wrap, +.block-editor-inner-blocks .wp-block .amp-story-resize-container.is-resizing .rotatable-box-wrap { + opacity: 0; } -.wp-block.amp-page-active .wp-block.is-rotating:hover .components-resizable-box__handle, -.wp-block.amp-page-active .wp-block.is-rotating .components-resizable-box__handle:hover { - opacity: 0; +.block-editor-inner-blocks .wp-block:hover .rotatable-box-wrap, +.block-editor-inner-blocks .wp-block.is-selected .rotatable-box-wrap, +.block-editor-inner-blocks .wp-block.is-rotating .rotatable-box-wrap { + opacity: 1; } diff --git a/assets/src/stories-editor/components/rotatable-box/index.js b/assets/src/stories-editor/components/rotatable-box/index.js index 5a186098e0d..79c02140d21 100644 --- a/assets/src/stories-editor/components/rotatable-box/index.js +++ b/assets/src/stories-editor/components/rotatable-box/index.js @@ -16,6 +16,7 @@ import { __, sprintf } from '@wordpress/i18n'; /** * Internal dependencies */ +import { findClosestSnap } from '../../helpers'; import './edit.css'; class RotatableBox extends Component { @@ -125,7 +126,9 @@ class RotatableBox extends Component { const y = e.clientY - centerY; const rad2deg = ( 180 / Math.PI ); - const angle = Math.ceil( -( rad2deg * Math.atan2( x, y ) ) ); + let angle = Math.ceil( -( rad2deg * Math.atan2( x, y ) ) ); + + angle = findClosestSnap( angle, this.props.snap, this.props.snapGap ); if ( this.state.angle === angle ) { return; @@ -187,6 +190,7 @@ class RotatableBox extends Component { RotatableBox.defaultProps = { angle: 0, initialAngle: 0, + snapGap: 0, }; RotatableBox.propTypes = { @@ -199,6 +203,8 @@ RotatableBox.propTypes = { onRotate: PropTypes.func, onRotateStop: PropTypes.func, children: PropTypes.any.isRequired, + snap: PropTypes.oneOfType( [ PropTypes.arrayOf( PropTypes.number ), PropTypes.func ] ), + snapGap: PropTypes.number, }; export default compose( diff --git a/assets/src/stories-editor/components/shortcuts/index.js b/assets/src/stories-editor/components/shortcuts/index.js index ef213cacfd1..54607366e04 100644 --- a/assets/src/stories-editor/components/shortcuts/index.js +++ b/assets/src/stories-editor/components/shortcuts/index.js @@ -12,7 +12,7 @@ import { withDispatch, withSelect } from '@wordpress/data'; import { IconButton } from '@wordpress/components'; import { compose, ifCondition } from '@wordpress/compose'; -const Shortcuts = ( { insertBlock, canInsertBlockType } ) => { +const Shortcuts = ( { insertBlock, canInsertBlockType, showInserter } ) => { const blocks = [ 'amp/amp-story-text', 'core/image', @@ -34,6 +34,7 @@ const Shortcuts = ( { insertBlock, canInsertBlockType } ) => { onClick={ () => insertBlock( block ) } label={ blockType.title } labelPosition="bottom" + disabled={ ! showInserter } /> ); } ) @@ -43,6 +44,7 @@ const Shortcuts = ( { insertBlock, canInsertBlockType } ) => { Shortcuts.propTypes = { insertBlock: PropTypes.func.isRequired, canInsertBlockType: PropTypes.func.isRequired, + showInserter: PropTypes.bool.isRequired, }; const applyWithSelect = withSelect( ( select ) => { @@ -57,6 +59,8 @@ const applyWithSelect = withSelect( ( select ) => { const blockSettings = getBlockListSettings( getCurrentPage() ); return canInsertBlockType( name, getCurrentPage() ) && blockSettings && blockSettings.allowedBlocks.includes( name ); }, + // As used in component + showInserter: select( 'core/edit-post' ).getEditorMode() === 'visual' && select( 'core/editor' ).getEditorSettings().richEditingEnabled, }; } ); diff --git a/assets/src/stories-editor/components/shortcuts/tests/index.js b/assets/src/stories-editor/components/shortcuts/tests/index.js deleted file mode 100644 index 910022035b8..00000000000 --- a/assets/src/stories-editor/components/shortcuts/tests/index.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - -/** - * Internal dependencies - */ -import Shortcuts from '../'; - -describe( 'Shortcuts', () => { - it( 'should render block shortcuts', () => { - const wrapper = shallow( - - ); - - expect( wrapper ).toMatchSnapshot(); - } ); -} ); diff --git a/assets/src/stories-editor/components/story-block-drop-zone.js b/assets/src/stories-editor/components/story-block-drop-zone.js index 2d2217f0017..43339a50a8a 100644 --- a/assets/src/stories-editor/components/story-block-drop-zone.js +++ b/assets/src/stories-editor/components/story-block-drop-zone.js @@ -21,44 +21,78 @@ import { withDispatch } from '@wordpress/data'; * Internal dependencies */ import { getPercentageFromPixels } from '../helpers'; -import { TEXT_BLOCK_BORDER } from '../constants'; +import { + STORY_PAGE_INNER_HEIGHT, +} from '../constants'; const wrapperElSelector = 'div[data-amp-selected="parent"] .editor-inner-blocks'; class BlockDropZone extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); this.onDrop = this.onDrop.bind( this ); } + /** + * Handles the drop event for blocks within a page. + * Separate handling for CTA block. + * + * @param {Object} event Drop event. + */ onDrop( event ) { - const { updateBlockAttributes, srcBlockName, srcClientId } = this.props; + const { srcBlockName, updateBlockAttributes, srcClientId } = this.props; + const isCTABlock = 'amp/amp-story-cta' === srcBlockName; + + let elementId, + cloneElementId, + wrapperEl; + + // In case of the CTA block we are not moving the block itself but just the `a` within. + if ( isCTABlock ) { + elementId = `amp-story-cta-button-${ srcClientId }`; + cloneElementId = `clone-amp-story-cta-button-${ srcClientId }`; + const btnWrapperSelector = `#block-${ srcClientId } .editor-block-list__block-edit`; + + // Get the editor wrapper element for calculating the width and height. + wrapperEl = document.querySelector( btnWrapperSelector ); + } else { + elementId = `block-${ srcClientId }`; + cloneElementId = `clone-block-${ srcClientId }`; + wrapperEl = document.querySelector( wrapperElSelector ); + } - const elementId = `block-${ srcClientId }`; - const cloneElementId = `clone-block-${ srcClientId }`; const element = document.getElementById( elementId ); const clone = document.getElementById( cloneElementId ); - // Get the editor wrapper element for calculating the width and height. - const wrapperEl = document.querySelector( wrapperElSelector ); if ( ! element || ! clone || ! wrapperEl ) { event.preventDefault(); return; } - // We have to remove the rotation for getting accurate position. - clone.parentNode.style.visibility = 'hidden'; - clone.parentNode.style.transform = 'none'; + // CTA block can't be rotated. + if ( ! isCTABlock ) { + // We have to remove the rotation for getting accurate position. + clone.parentNode.style.visibility = 'hidden'; + clone.parentNode.style.transform = 'none'; + } + const clonePosition = clone.getBoundingClientRect(); const wrapperPosition = wrapperEl.getBoundingClientRect(); // We will set the new position based on where the clone was moved to, with reference being the wrapper element. // Lets take the % based on the wrapper for top and left. - const possibleDelta = 'amp/amp-story-text' === srcBlockName ? TEXT_BLOCK_BORDER : 0; + const leftPosKey = isCTABlock ? 'btnPositionLeft' : 'positionLeft'; + const topPosKey = isCTABlock ? 'btnPositionTop' : 'positionTop'; + + // Let's get the base value to measure the top percentage from. + let baseHeight = STORY_PAGE_INNER_HEIGHT; + if ( isCTABlock ) { + baseHeight = STORY_PAGE_INNER_HEIGHT / 5; + } updateBlockAttributes( srcClientId, { - positionLeft: getPercentageFromPixels( 'x', clonePosition.left - wrapperPosition.left + possibleDelta ), - positionTop: getPercentageFromPixels( 'y', clonePosition.top - wrapperPosition.top + possibleDelta ), + [ leftPosKey ]: getPercentageFromPixels( 'x', clonePosition.left - wrapperPosition.left ), + [ topPosKey ]: getPercentageFromPixels( 'y', clonePosition.top - wrapperPosition.top, baseHeight ), } ); } diff --git a/assets/src/stories-editor/components/story-controls/edit.css b/assets/src/stories-editor/components/story-controls/edit.css index 795e44dcfe5..57b752d9074 100644 --- a/assets/src/stories-editor/components/story-controls/edit.css +++ b/assets/src/stories-editor/components/story-controls/edit.css @@ -1,3 +1,7 @@ +#amp-story-shortcuts { + display: inline-flex; +} + #amp-story-controls { text-align: right; padding-right: 20px; @@ -22,3 +26,7 @@ margin-right: 20px; display: inline-flex; } + +.amp-story-controls-reorder-save { + float: right; +} diff --git a/assets/src/stories-editor/components/story-controls/index.js b/assets/src/stories-editor/components/story-controls/index.js index e892add2c50..f330f73038d 100644 --- a/assets/src/stories-editor/components/story-controls/index.js +++ b/assets/src/stories-editor/components/story-controls/index.js @@ -20,7 +20,7 @@ import { compose } from '@wordpress/compose'; * Internal dependencies */ import { TemplateInserter } from '../'; -import reorderIcon from '../../../../images/reorder.svg'; +import reorderIcon from '../../../../images/stories-editor/reorder.svg'; import './edit.css'; function StoryControls( { isReordering, startReordering, saveOrder, resetOrder } ) { @@ -69,22 +69,24 @@ StoryControls.propTypes = { export default compose( withSelect( ( select ) => { const { isReordering } = select( 'amp/story' ); + const { getBlockOrder } = select( 'core/block-editor' ); return { isReordering: isReordering(), + blockOrder: getBlockOrder(), }; } ), - withDispatch( ( dispatch ) => { + withDispatch( ( dispatch, { blockOrder } ) => { const { clearSelectedBlock } = dispatch( 'core/block-editor' ); const { startReordering, saveOrder, resetOrder } = dispatch( 'amp/story' ); return { startReordering: () => { clearSelectedBlock(); - startReordering(); + startReordering( blockOrder ); }, saveOrder, - resetOrder, + resetOrder: () => resetOrder( blockOrder ), }; } ) )( StoryControls ); diff --git a/assets/src/stories-editor/components/story-controls/tests/index.js b/assets/src/stories-editor/components/story-controls/tests/index.js deleted file mode 100644 index 941a074f57c..00000000000 --- a/assets/src/stories-editor/components/story-controls/tests/index.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - -/** - * Internal dependencies - */ -import StoryControls from '../'; - -describe( 'StoryControls', () => { - it( 'should render story controls', () => { - const wrapper = shallow( - - ); - - expect( wrapper ).toMatchSnapshot(); - } ); -} ); diff --git a/assets/src/stories-editor/components/template-inserter/edit.css b/assets/src/stories-editor/components/template-inserter/edit.css index d8690ed128f..4ac47eeb9de 100644 --- a/assets/src/stories-editor/components/template-inserter/edit.css +++ b/assets/src/stories-editor/components/template-inserter/edit.css @@ -36,6 +36,12 @@ margin-left: -15px; } +.amp-stories__editor-inserter__results .components-spinner { + margin-left: calc(50% - 9px); + margin-right: calc(50% - 9px); + margin-top: 128px; +} + .amp-stories__template-inserter__popover.components-popover:not(.is-without-arrow):not(.is-mobile).is-top::before { border-bottom: 8px solid rgb(226, 228, 231); } @@ -97,10 +103,12 @@ height: 268px; margin: 10px; padding: 0; + overflow: hidden; } .amp-stories__editor-inserter__results .block-editor-block-preview .block-editor-block-preview__content, .amo-stories__editor-inserter__results .components-placeholder { + position: initial; padding: 0; width: 100%; height: 100%; @@ -120,6 +128,10 @@ margin: 0 auto; } +.amp-stories__blank-page-inserter span { + display: none; +} + .amp-stories__editor-inserter__results .block-editor-block-preview { pointer-events: initial; } diff --git a/assets/src/stories-editor/components/template-inserter/index.js b/assets/src/stories-editor/components/template-inserter/index.js index a969d25a5f7..c970e27532c 100644 --- a/assets/src/stories-editor/components/template-inserter/index.js +++ b/assets/src/stories-editor/components/template-inserter/index.js @@ -18,15 +18,15 @@ import { ENTER, SPACE } from '@wordpress/keycodes'; /** * Internal dependencies */ -import { BlockPreview } from '../'; -import pageIcon from '../../../../images/add-page-inserter.svg'; -import addTemplateIcon from '../../../../images/add-template.svg'; +import TemplatePreview from './template-preview'; +import pageIcon from '../../../../images/stories-editor/add-page-inserter.svg'; +import addTemplateIcon from '../../../../images/stories-editor/add-template.svg'; import './edit.css'; import { createSkeletonTemplate, maybeEnqueueFontStyle } from '../../helpers'; class TemplateInserter extends Component { - constructor() { - super( ...arguments ); + constructor( ...args ) { + super( ...args ); this.onToggle = this.onToggle.bind( this ); @@ -119,7 +119,8 @@ class TemplateInserter extends Component { />
{ this.state.storyTemplates.map( ( item ) => ( - - ) ) } diff --git a/assets/src/stories-editor/components/template-inserter/template-preview.js b/assets/src/stories-editor/components/template-inserter/template-preview.js new file mode 100644 index 00000000000..c97314ac930 --- /dev/null +++ b/assets/src/stories-editor/components/template-inserter/template-preview.js @@ -0,0 +1,60 @@ +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { withSafeTimeout } from '@wordpress/compose'; +import { Spinner } from '@wordpress/components'; +import { Component } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { BlockPreview } from '../'; + +class TemplatePreview extends Component { + constructor( ...args ) { + super( ...args ); + + this.state = { + shouldLoad: false, + }; + } + + componentDidMount() { + if ( ! this.state.shouldLoad ) { + // @todo Look into React Concurrent mode to replace this once it gets available. + // Set timeout to cause a small latency between loading the templates, otherwise they all try to load instantly and cause a lag. + this.props.setTimeout( () => { + this.setState( { shouldLoad: true } ); + }, 100 ); + } + } + + render() { + if ( ! this.state.shouldLoad ) { + return ; + } + + const { item } = this.props; + + return ( + + ); + } +} + +TemplatePreview.propTypes = { + item: PropTypes.shape( { + id: PropTypes.number.isRequired, + } ).isRequired, + setTimeout: PropTypes.func.isRequired, +}; + +export default withSafeTimeout( TemplatePreview ); diff --git a/assets/src/stories-editor/components/with-custom-video-block-edit.js b/assets/src/stories-editor/components/with-custom-video-block-edit.js new file mode 100644 index 00000000000..b3192a99fb6 --- /dev/null +++ b/assets/src/stories-editor/components/with-custom-video-block-edit.js @@ -0,0 +1,34 @@ +/** + * External dependencies + */ +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import { CustomVideoBlockEdit } from './'; + +/** + * If this is a Core Video block, this uses an alternate edit component that enables previewing the video. + * + * The Core Video edit component wraps the
'; } ?> - true ) ); ?> + true ] ); ?>
ID, '_amp_queried_object', true ); - if ( isset( $queried_object['id'] ) && isset( $queried_object['type'] ) ) { + if ( isset( $queried_object['id'], $queried_object['type'] ) ) { $after = ' | '; if ( 'post' === $queried_object['type'] && get_post( $queried_object['id'] ) && post_type_exists( get_post( $queried_object['id'] )->post_type ) ) { $post_type_object = get_post_type_object( get_post( $queried_object['id'] )->post_type ); @@ -1854,7 +1847,7 @@ public static function render_single_url_list_table( $post ) { * * @return WP_Term[] */ - $override_terms_in_occurrence_order = function() use ( $post ) { + $override_terms_in_occurrence_order = static function() use ( $post ) { return wp_list_pluck( AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( $post ), 'term' ); }; @@ -1862,10 +1855,10 @@ public static function render_single_url_list_table( $post ) { $wp_list_table = _get_list_table( 'WP_Terms_List_Table' ); get_current_screen()->set_screen_reader_content( - array( + [ 'heading_pagination' => $taxonomy_object->labels->items_list_navigation, 'heading_list' => $taxonomy_object->labels->items_list, - ) + ] ); $wp_list_table->prepare_items(); @@ -1998,9 +1991,9 @@ public static function render_post_filters( $post_type, $which ) { * @return string The URL to recheck the post. */ public static function get_recheck_url( $url_or_post ) { - $args = array( + $args = [ 'action' => self::VALIDATE_ACTION, - ); + ]; if ( is_string( $url_or_post ) ) { $args['url'] = $url_or_post; } elseif ( $url_or_post instanceof WP_Post && self::POST_TYPE_SLUG === $url_or_post->post_type ) { @@ -2022,15 +2015,15 @@ public static function get_recheck_url( $url_or_post ) { public static function filter_dashboard_glance_items( $items ) { $query = new WP_Query( - array( + [ 'post_type' => self::POST_TYPE_SLUG, - AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_STATUS_QUERY_VAR => array( + AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_STATUS_QUERY_VAR => [ AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_REJECTED_STATUS, AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_ACCEPTED_STATUS, - ), + ], 'update_post_meta_cache' => false, 'update_post_term_cache' => false, - ) + ] ); if ( 0 !== $query->found_posts ) { @@ -2039,13 +2032,13 @@ public static function filter_dashboard_glance_items( $items ) { esc_url( admin_url( add_query_arg( - array( + [ 'post_type' => self::POST_TYPE_SLUG, - AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_STATUS_QUERY_VAR => array( + AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_STATUS_QUERY_VAR => [ AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_REJECTED_STATUS, AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_ACCEPTED_STATUS, - ), - ), + ], + ], 'edit.php' ) ) @@ -2099,7 +2092,7 @@ public static function filter_admin_title( $title ) { if ( $page_title ) { /* translators: Admin screen title. %s: Admin screen name */ - return sprintf( __( '%s — WordPress' ), $page_title ); + return sprintf( __( '%s — WordPress', 'default' ), $page_title ); } return $title; @@ -2147,8 +2140,9 @@ public static function get_single_url_page_heading() { * * Manages links for details, recheck, view, forget, and forget permanently. * - * @param array $actions Row action links. - * @param \WP_Post $post Current WP post. + * @param array $actions Row action links. + * @param WP_Post $post Current WP post. + * * @return array Filtered action links. */ public static function filter_post_row_actions( $actions, $post ) { @@ -2234,7 +2228,7 @@ public static function filter_bulk_post_updated_messages( $messages, $bulk_count if ( get_current_screen()->id === sprintf( 'edit-%s', self::POST_TYPE_SLUG ) ) { $messages['post'] = array_merge( $messages['post'], - array( + [ /* translators: %s is the number of posts forgotten */ 'deleted' => _n( '%s validated URL forgotten.', @@ -2256,7 +2250,7 @@ public static function filter_bulk_post_updated_messages( $messages, $bulk_count $bulk_counts['untrashed'], 'amp' ), - ) + ] ); } @@ -2290,7 +2284,7 @@ public static function is_amp_enabled_on_post( $post ) { */ protected static function count_invalid_url_validation_errors( $validation_errors ) { $counts = array_fill_keys( - array( 'new_accepted', 'ack_accepted', 'new_rejected', 'ack_rejected' ), + [ 'new_accepted', 'ack_accepted', 'new_rejected', 'ack_rejected' ], 0 ); foreach ( $validation_errors as $error ) { diff --git a/includes/validation/class-amp-validation-callback-wrapper.php b/includes/validation/class-amp-validation-callback-wrapper.php new file mode 100644 index 00000000000..e18b20f6d71 --- /dev/null +++ b/includes/validation/class-amp-validation-callback-wrapper.php @@ -0,0 +1,152 @@ +callback = $callback; + } + + /** + * Invoke wrapped callback. + * + * @return mixed + */ + public function __invoke() { + global $wp_styles, $wp_scripts; + + $function = $this->callback['function']; + $accepted_args = $this->callback['accepted_args']; + $args = func_get_args(); + + $before_styles_enqueued = []; + if ( isset( $wp_styles, $wp_styles->queue ) ) { + $before_styles_enqueued = $wp_styles->queue; + } + $before_scripts_enqueued = []; + if ( isset( $wp_scripts, $wp_scripts->queue ) ) { + $before_scripts_enqueued = $wp_scripts->queue; + } + + $is_filter = isset( $callback['source']['hook'] ) && ! did_action( $this->callback['source']['hook'] ); + + // Wrap the markup output of (action) hooks in source comments. + AMP_Validation_Manager::$hook_source_stack[] = $this->callback['source']; + $has_buffer_started = false; + if ( ! $is_filter && AMP_Validation_Manager::can_output_buffer() ) { + $has_buffer_started = ob_start( [ 'AMP_Validation_Manager', 'wrap_buffer_with_source_comments' ] ); + } + $result = call_user_func_array( $function, array_slice( $args, 0, (int) $accepted_args ) ); + if ( $has_buffer_started ) { + ob_end_flush(); + } + array_pop( AMP_Validation_Manager::$hook_source_stack ); + + // Keep track of which source enqueued the styles. + if ( isset( $wp_styles, $wp_styles->queue ) ) { + foreach ( array_diff( $wp_styles->queue, $before_styles_enqueued ) as $handle ) { + AMP_Validation_Manager::$enqueued_style_sources[ $handle ][] = array_merge( $this->callback['source'], compact( 'handle' ) ); + } + } + + // Keep track of which source enqueued the scripts, and immediately report validity. + if ( isset( $wp_scripts, $wp_scripts->queue ) ) { + foreach ( array_diff( $wp_scripts->queue, $before_scripts_enqueued ) as $queued_handle ) { + $handles = [ $queued_handle ]; + + // Account for case where registered script is a placeholder for a set of scripts (e.g. jquery). + if ( isset( $wp_scripts->registered[ $queued_handle ] ) && false === $wp_scripts->registered[ $queued_handle ]->src ) { + $handles = array_merge( $handles, $wp_scripts->registered[ $queued_handle ]->deps ); + } + + foreach ( $handles as $handle ) { + AMP_Validation_Manager::$enqueued_script_sources[ $handle ][] = array_merge( $this->callback['source'], compact( 'handle' ) ); + } + } + } + + return $result; + } + + /** + * Offset set. + * + * @param mixed $offset Offset. + * @param mixed $value Value. + */ + public function offsetSet( $offset, $value ) { + if ( ! is_array( $this->callback['function'] ) ) { + return; + } + if ( is_null( $offset ) ) { + $this->callback['function'][] = $value; + } else { + $this->callback['function'][ $offset ] = $value; + } + } + + /** + * Offset exists. + * + * @param mixed $offset Offset. + * @return bool Exists. + */ + public function offsetExists( $offset ) { + if ( ! is_array( $this->callback['function'] ) ) { + return false; + } + return isset( $this->callback['function'][ $offset ] ); + } + + /** + * Offset unset. + * + * @param mixed $offset Offset. + */ + public function offsetUnset( $offset ) { + if ( ! is_array( $this->callback['function'] ) ) { + return; + } + unset( $this->callback['function'][ $offset ] ); + } + + /** + * Offset get. + * + * @param mixed $offset Offset. + * @return mixed|null Value. + */ + public function offsetGet( $offset ) { + if ( is_array( $this->callback['function'] ) && isset( $this->callback['function'][ $offset ] ) ) { + return $this->callback['function'][ $offset ]; + } + return null; + } +} diff --git a/includes/validation/class-amp-validation-error-taxonomy.php b/includes/validation/class-amp-validation-error-taxonomy.php index a705c5321bc..29f6ef744f4 100644 --- a/includes/validation/class-amp-validation-error-taxonomy.php +++ b/includes/validation/class-amp-validation-error-taxonomy.php @@ -233,8 +233,8 @@ public static function register() { register_taxonomy( self::TAXONOMY_SLUG, AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, - array( - 'labels' => array( + [ + 'labels' => [ 'name' => _x( 'AMP Validation Error Index', 'taxonomy general name', 'amp' ), 'singular_name' => _x( 'AMP Validation Error', 'taxonomy singular name', 'amp' ), 'search_items' => __( 'Search AMP Validation Errors', 'amp' ), @@ -253,20 +253,20 @@ public static function register() { 'items_list' => __( 'Validation errors list', 'amp' ), /* translators: Tab heading when selecting from the most used terms */ 'most_used' => __( 'Most Used Validation Errors', 'amp' ), - ), + ], 'public' => false, 'show_ui' => true, // @todo False because we need a custom UI. 'show_tagcloud' => false, 'show_in_quick_edit' => false, 'hierarchical' => false, // Or true? Code could be the parent term? - 'show_in_menu' => ( self::should_show_in_menu() || AMP_Validated_URL_Post_Type::should_show_in_menu() ), + 'show_in_menu' => current_theme_supports( 'amp' ) && current_user_can( 'manage_options' ), 'meta_box_cb' => false, - 'capabilities' => array( + 'capabilities' => [ // Note that delete_terms is needed so the checkbox (cb) table column will work. 'assign_terms' => 'do_not_allow', 'edit_terms' => 'do_not_allow', - ), - ) + ], + ] ); if ( is_admin() ) { @@ -276,19 +276,6 @@ public static function register() { self::accept_validation_errors( AMP_Core_Theme_Sanitizer::get_acceptable_errors( get_template() ) ); } - /** - * Determine whether the admin menu item should be included. - * - * @return bool Whether to show in menu. - */ - public static function should_show_in_menu() { - global $pagenow; - if ( AMP_Options_Manager::is_website_experience_enabled() && current_theme_supports( AMP_Theme_Support::SLUG ) ) { - return true; - } - return ( 'edit-tags.php' === $pagenow && ( isset( $_GET['taxonomy'] ) && self::TAXONOMY_SLUG === $_GET['taxonomy'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - } - /** * Get amp_validation_error taxonomy term by slug or error properties. * @@ -361,12 +348,12 @@ public static function delete_empty_terms() { * } * @return int|int[]|null Returns an integer unless the multiple option is passed. Null if invalid. */ - public static function sanitize_term_status( $status, $options = array() ) { + public static function sanitize_term_status( $status, $options = [] ) { $multiple = ! empty( $options['multiple'] ); // Catch case where an empty string is supplied. Prevent casting to 0. if ( ! is_numeric( $status ) && empty( $status ) ) { - return $multiple ? array() : null; + return $multiple ? [] : null; } if ( is_string( $status ) ) { @@ -376,21 +363,21 @@ public static function sanitize_term_status( $status, $options = array() ) { } $statuses = array_intersect( - array( + [ self::VALIDATION_ERROR_NEW_REJECTED_STATUS, self::VALIDATION_ERROR_NEW_ACCEPTED_STATUS, self::VALIDATION_ERROR_ACK_ACCEPTED_STATUS, self::VALIDATION_ERROR_ACK_REJECTED_STATUS, - ), + ], $statuses ); $statuses = array_values( array_unique( $statuses ) ); if ( ! $multiple ) { return array_shift( $statuses ); - } else { - return $statuses; } + + return $statuses; } /** @@ -418,11 +405,11 @@ public static function prepare_validation_error_taxonomy_term( $error ) { ksort( $error ); $description = wp_json_encode( $error ); $term_slug = md5( $description ); - return array( + return [ 'slug' => $term_slug, 'name' => $term_slug, 'description' => $description, - ); + ]; } /** @@ -457,12 +444,12 @@ public static function is_validation_error_sanitized( $error ) { public static function get_validation_error_sanitization( $error ) { $term_data = self::prepare_validation_error_taxonomy_term( $error ); $term = self::get_term( $term_data['slug'] ); - $statuses = array( + $statuses = [ self::VALIDATION_ERROR_NEW_REJECTED_STATUS, self::VALIDATION_ERROR_NEW_ACCEPTED_STATUS, self::VALIDATION_ERROR_ACK_ACCEPTED_STATUS, self::VALIDATION_ERROR_ACK_REJECTED_STATUS, - ); + ]; if ( ! empty( $term ) && in_array( $term->term_group, $statuses, true ) ) { $term_status = $term->term_group; } else { @@ -520,7 +507,7 @@ public static function accept_validation_errors( $acceptable_errors ) { } add_filter( 'amp_validation_error_sanitized', - function( $sanitized, $error ) use ( $acceptable_errors ) { + static function( $sanitized, $error ) use ( $acceptable_errors ) { if ( true === $acceptable_errors ) { return true; } @@ -576,20 +563,20 @@ public static function is_array_subset( $superset, $subset ) { * } * @return int Term count. */ - public static function get_validation_error_count( $args = array() ) { + public static function get_validation_error_count( $args = [] ) { $args = array_merge( - array( + [ 'group' => null, - ), + ], $args ); $groups = null; if ( isset( $args['group'] ) ) { - $groups = self::sanitize_term_status( $args['group'], array( 'multiple' => true ) ); + $groups = self::sanitize_term_status( $args['group'], [ 'multiple' => true ] ); } - $filter = function( $clauses ) use ( $groups ) { + $filter = static function( $clauses ) use ( $groups ) { $clauses['where'] .= ' AND t.term_group ' . AMP_Validation_Error_Taxonomy::prepare_term_group_in_sql( $groups ); return $clauses; }; @@ -625,9 +612,9 @@ public static function filter_posts_where_for_validation_error_status( $where, W return $where; } - $error_statuses = array(); + $error_statuses = []; if ( false !== $query->get( self::VALIDATION_ERROR_STATUS_QUERY_VAR, false ) ) { - $error_statuses = self::sanitize_term_status( $query->get( self::VALIDATION_ERROR_STATUS_QUERY_VAR ), array( 'multiple' => true ) ); + $error_statuses = self::sanitize_term_status( $query->get( self::VALIDATION_ERROR_STATUS_QUERY_VAR ), [ 'multiple' => true ] ); } $error_type = sanitize_key( $query->get( self::VALIDATION_ERROR_TYPE_QUERY_VAR ) ); @@ -683,10 +670,10 @@ public static function filter_posts_where_for_validation_error_status( $where, W * @return array The AMP validity of the markup. */ public static function summarize_validation_errors( $validation_errors ) { - $results = array(); - $removed_elements = array(); - $removed_attributes = array(); - $invalid_sources = array(); + $results = []; + $removed_elements = []; + $removed_attributes = []; + $invalid_sources = []; foreach ( $validation_errors as $validation_error ) { $code = isset( $validation_error['code'] ) ? $validation_error['code'] : null; @@ -694,12 +681,12 @@ public static function summarize_validation_errors( $validation_errors ) { if ( ! isset( $removed_elements[ $validation_error['node_name'] ] ) ) { $removed_elements[ $validation_error['node_name'] ] = 0; } - $removed_elements[ $validation_error['node_name'] ] += 1; + ++$removed_elements[ $validation_error['node_name'] ]; } elseif ( self::INVALID_ATTRIBUTE_CODE === $code ) { if ( ! isset( $removed_attributes[ $validation_error['node_name'] ] ) ) { $removed_attributes[ $validation_error['node_name'] ] = 0; } - $removed_attributes[ $validation_error['node_name'] ] += 1; + ++$removed_attributes[ $validation_error['node_name'] ]; } if ( ! empty( $validation_error['sources'] ) ) { @@ -723,9 +710,9 @@ public static function summarize_validation_errors( $validation_errors ) { } $results = array_merge( - array( + [ self::SOURCES_INVALID_OUTPUT => $invalid_sources, - ), + ], compact( 'removed_elements', 'removed_attributes' @@ -740,41 +727,41 @@ public static function summarize_validation_errors( $validation_errors ) { * Add admin hooks. */ public static function add_admin_hooks() { - add_filter( 'redirect_term_location', array( __CLASS__, 'add_term_filter_query_var' ), 10, 2 ); - add_action( 'load-edit-tags.php', array( __CLASS__, 'add_group_terms_clauses_filter' ) ); - add_action( 'load-edit-tags.php', array( __CLASS__, 'add_error_type_clauses_filter' ) ); - add_action( 'load-post.php', array( __CLASS__, 'add_error_type_clauses_filter' ) ); - add_action( 'load-edit-tags.php', array( __CLASS__, 'add_order_clauses_from_description_json' ) ); - add_action( 'load-post.php', array( __CLASS__, 'add_order_clauses_from_description_json' ) ); - add_action( sprintf( 'after-%s-table', self::TAXONOMY_SLUG ), array( __CLASS__, 'render_taxonomy_filters' ) ); - add_action( sprintf( 'after-%s-table', self::TAXONOMY_SLUG ), array( __CLASS__, 'render_link_to_invalid_urls_screen' ) ); + add_filter( 'redirect_term_location', [ __CLASS__, 'add_term_filter_query_var' ], 10, 2 ); + add_action( 'load-edit-tags.php', [ __CLASS__, 'add_group_terms_clauses_filter' ] ); + add_action( 'load-edit-tags.php', [ __CLASS__, 'add_error_type_clauses_filter' ] ); + add_action( 'load-post.php', [ __CLASS__, 'add_error_type_clauses_filter' ] ); + add_action( 'load-edit-tags.php', [ __CLASS__, 'add_order_clauses_from_description_json' ] ); + add_action( 'load-post.php', [ __CLASS__, 'add_order_clauses_from_description_json' ] ); + add_action( sprintf( 'after-%s-table', self::TAXONOMY_SLUG ), [ __CLASS__, 'render_taxonomy_filters' ] ); + add_action( sprintf( 'after-%s-table', self::TAXONOMY_SLUG ), [ __CLASS__, 'render_link_to_invalid_urls_screen' ] ); add_action( 'load-edit-tags.php', - function() { - add_filter( 'user_has_cap', array( __CLASS__, 'filter_user_has_cap_for_hiding_term_list_table_checkbox' ), 10, 3 ); + static function() { + add_filter( 'user_has_cap', [ __CLASS__, 'filter_user_has_cap_for_hiding_term_list_table_checkbox' ], 10, 3 ); } ); - add_filter( 'terms_clauses', array( __CLASS__, 'filter_terms_clauses_for_description_search' ), 10, 3 ); - add_action( 'admin_notices', array( __CLASS__, 'add_admin_notices' ) ); - add_filter( 'tag_row_actions', array( __CLASS__, 'filter_tag_row_actions' ), 10, 2 ); + add_filter( 'terms_clauses', [ __CLASS__, 'filter_terms_clauses_for_description_search' ], 10, 3 ); + add_action( 'admin_notices', [ __CLASS__, 'add_admin_notices' ] ); + add_filter( 'tag_row_actions', [ __CLASS__, 'filter_tag_row_actions' ], 10, 2 ); if ( get_taxonomy( self::TAXONOMY_SLUG )->show_in_menu ) { - add_action( 'admin_menu', array( __CLASS__, 'add_admin_menu_validation_error_item' ) ); - } - add_action( 'parse_term_query', array( __CLASS__, 'parse_post_php_term_query' ) ); - add_filter( 'manage_' . self::TAXONOMY_SLUG . '_custom_column', array( __CLASS__, 'filter_manage_custom_columns' ), 10, 3 ); - add_filter( 'manage_' . AMP_Validated_URL_Post_Type::POST_TYPE_SLUG . '_sortable_columns', array( __CLASS__, 'add_single_post_sortable_columns' ) ); - add_filter( 'posts_where', array( __CLASS__, 'filter_posts_where_for_validation_error_status' ), 10, 2 ); - add_filter( 'post_action_' . self::VALIDATION_ERROR_REJECT_ACTION, array( __CLASS__, 'handle_single_url_page_bulk_and_inline_actions' ) ); - add_filter( 'post_action_' . self::VALIDATION_ERROR_ACCEPT_ACTION, array( __CLASS__, 'handle_single_url_page_bulk_and_inline_actions' ) ); - add_filter( 'handle_bulk_actions-edit-' . self::TAXONOMY_SLUG, array( __CLASS__, 'handle_validation_error_update' ), 10, 3 ); - add_action( 'load-edit-tags.php', array( __CLASS__, 'handle_inline_edit_request' ) ); - add_action( 'load-edit-tags.php', array( __CLASS__, 'handle_clear_empty_terms_request' ) ); - add_action( 'load-edit.php', array( __CLASS__, 'handle_inline_edit_request' ) ); + add_action( 'admin_menu', [ __CLASS__, 'add_admin_menu_validation_error_item' ] ); + } + add_action( 'parse_term_query', [ __CLASS__, 'parse_post_php_term_query' ] ); + add_filter( 'manage_' . self::TAXONOMY_SLUG . '_custom_column', [ __CLASS__, 'filter_manage_custom_columns' ], 10, 3 ); + add_filter( 'manage_' . AMP_Validated_URL_Post_Type::POST_TYPE_SLUG . '_sortable_columns', [ __CLASS__, 'add_single_post_sortable_columns' ] ); + add_filter( 'posts_where', [ __CLASS__, 'filter_posts_where_for_validation_error_status' ], 10, 2 ); + add_filter( 'post_action_' . self::VALIDATION_ERROR_REJECT_ACTION, [ __CLASS__, 'handle_single_url_page_bulk_and_inline_actions' ] ); + add_filter( 'post_action_' . self::VALIDATION_ERROR_ACCEPT_ACTION, [ __CLASS__, 'handle_single_url_page_bulk_and_inline_actions' ] ); + add_filter( 'handle_bulk_actions-edit-' . self::TAXONOMY_SLUG, [ __CLASS__, 'handle_validation_error_update' ], 10, 3 ); + add_action( 'load-edit-tags.php', [ __CLASS__, 'handle_inline_edit_request' ] ); + add_action( 'load-edit-tags.php', [ __CLASS__, 'handle_clear_empty_terms_request' ] ); + add_action( 'load-edit.php', [ __CLASS__, 'handle_inline_edit_request' ] ); // Prevent query vars from persisting after redirect. add_filter( 'removable_query_args', - function( $query_vars ) { + static function( $query_vars ) { $query_vars[] = 'amp_actioned'; $query_vars[] = 'amp_actioned_count'; $query_vars[] = 'amp_validation_errors_not_deleted'; @@ -786,7 +773,7 @@ function( $query_vars ) { // Add recognition of amp_validation_error_status and type query vars (which will only apply in admin since post type is not publicly_queryable). add_filter( 'query_vars', - function( $query_vars ) { + static function( $query_vars ) { $query_vars[] = AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_STATUS_QUERY_VAR; $query_vars[] = AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_TYPE_QUERY_VAR; return $query_vars; @@ -796,8 +783,8 @@ function( $query_vars ) { // Default ordering terms by ID descending so that new terms appear at the top. add_filter( 'get_terms_defaults', - function( $args, $taxonomies ) { - if ( array( AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG ) === $taxonomies ) { + static function( $args, $taxonomies ) { + if ( [ AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG ] === $taxonomies ) { $args['orderby'] = 'term_id'; $args['order'] = 'DESC'; } @@ -810,7 +797,7 @@ function( $args, $taxonomies ) { // Add bulk actions. add_filter( 'bulk_actions-edit-' . self::TAXONOMY_SLUG, - function( $bulk_actions ) { + static function( $bulk_actions ) { unset( $bulk_actions['delete'] ); $bulk_actions[ AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACCEPT_ACTION ] = __( 'Accept', 'amp' ); $bulk_actions[ AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_REJECT_ACTION ] = __( 'Reject', 'amp' ); @@ -821,9 +808,9 @@ function( $bulk_actions ) { // Override the columns displayed for the validation error terms. add_filter( 'manage_edit-' . self::TAXONOMY_SLUG . '_columns', - function( $old_columns ) { + static function( $old_columns ) { - return array( + return [ 'cb' => $old_columns['cb'], 'error' => esc_html__( 'Error', 'amp' ), 'status' => sprintf( @@ -851,14 +838,14 @@ function( $old_columns ) { 'error_type' => esc_html__( 'Type', 'amp' ), 'created_date_gmt' => esc_html__( 'Last Seen', 'amp' ), 'posts' => esc_html__( 'Found URLs', 'amp' ), - ); + ]; } ); // Let the created date column sort by term ID. add_filter( 'manage_edit-' . self::TAXONOMY_SLUG . '_sortable_columns', - function( $sortable_columns ) { + static function( $sortable_columns ) { $sortable_columns['created_date_gmt'] = 'term_id'; $sortable_columns['error_type'] = AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_TYPE_QUERY_VAR; $sortable_columns['error'] = AMP_Validation_Error_Taxonomy::VALIDATION_DETAILS_ERROR_CODE_QUERY_VAR; @@ -869,7 +856,7 @@ function( $sortable_columns ) { // Hide empty term addition form. add_action( 'admin_enqueue_scripts', - function() { + static function() { $current_screen = get_current_screen(); if ( ! $current_screen ) { return; @@ -892,19 +879,21 @@ function() { wp_register_style( 'amp-validation-tooltips', amp_get_asset_url( 'css/amp-validation-tooltips.css' ), - array( 'wp-pointer' ), + [ 'wp-pointer' ], AMP__VERSION ); + wp_styles()->add_data( 'amp-validation-tooltips', 'rtl', 'replace' ); + $script_deps_path = AMP__DIR__ . '/assets/js/amp-validation-tooltips.deps.json'; $script_dependencies = file_exists( $script_deps_path ) ? json_decode( file_get_contents( $script_deps_path ), false ) // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents - : array(); + : []; wp_register_script( 'amp-validation-tooltips', amp_get_asset_url( 'js/amp-validation-tooltips.js' ), - array_merge( $script_dependencies, array( 'wp-pointer' ) ), + array_merge( $script_dependencies, [ 'wp-pointer' ] ), AMP__VERSION, true ); @@ -912,14 +901,16 @@ function() { wp_enqueue_style( 'amp-validation-error-taxonomy', amp_get_asset_url( 'css/amp-validation-error-taxonomy.css' ), - array( 'common', 'amp-validation-tooltips' ), + [ 'common', 'amp-validation-tooltips' ], AMP__VERSION ); + wp_styles()->add_data( 'amp-validation-error-taxonomy', 'rtl', 'replace' ); + wp_enqueue_script( 'amp-validation-detail-toggle', amp_get_asset_url( 'js/amp-validation-detail-toggle.js' ), - array( 'wp-dom-ready', 'wp-i18n', 'amp-validation-tooltips' ), + [ 'wp-dom-ready', 'wp-i18n', 'amp-validation-tooltips' ], AMP__VERSION, true ); @@ -929,14 +920,16 @@ function() { wp_enqueue_style( 'amp-validation-single-error-url', amp_get_asset_url( 'css/amp-validation-single-error-url.css' ), - array( 'common' ), + [ 'common' ], AMP__VERSION ); + wp_styles()->add_data( 'amp-validation-single-error-url', 'rtl', 'replace' ); + $script_deps_path = AMP__DIR__ . '/assets/js/amp-validation-single-error-url-details.deps.json'; $script_dependencies = file_exists( $script_deps_path ) ? json_decode( file_get_contents( $script_deps_path ), false ) // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents - : array(); + : []; wp_enqueue_script( 'amp-validation-single-error-url-details', @@ -952,7 +945,7 @@ function() { // Make sure parent menu item is expanded when visiting the taxonomy term page. add_filter( 'parent_file', - function( $parent_file ) { + static function( $parent_file ) { if ( get_current_screen()->taxonomy === AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG ) { $parent_file = AMP_Options_Manager::OPTION_NAME; } @@ -965,7 +958,7 @@ function( $parent_file ) { // Replace the primary column to be error instead of the removed name column.. add_filter( 'list_table_primary_column', - function( $primary_column ) { + static function( $primary_column ) { if ( get_current_screen() && AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG === get_current_screen()->taxonomy ) { $primary_column = 'error'; } @@ -1007,7 +1000,7 @@ public static function add_term_filter_query_var( $url, $tax ) { && in_array( $_POST[ self::VALIDATION_ERROR_TYPE_QUERY_VAR ], // phpcs:ignore WordPress.Security.NonceVerification.Missing - array_merge( self::get_error_types(), array( strval( self::NO_FILTER_VALUE ) ) ), + array_merge( self::get_error_types(), [ (string) self::NO_FILTER_VALUE ] ), true ) ) { @@ -1019,13 +1012,13 @@ public static function add_term_filter_query_var( $url, $tax ) { } // If the error status query var is valid, pass it along in the redirect $url. - $groups = array(); + $groups = []; if ( isset( $_POST[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing - $groups = self::sanitize_term_status( wp_unslash( $_POST[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ] ), array( 'multiple' => true ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + $groups = self::sanitize_term_status( wp_unslash( $_POST[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ] ), [ 'multiple' => true ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing } if ( ! empty( $groups ) ) { $url = add_query_arg( - array( self::VALIDATION_ERROR_STATUS_QUERY_VAR => $groups ), + [ self::VALIDATION_ERROR_STATUS_QUERY_VAR => $groups ], $url ); } else { @@ -1043,13 +1036,13 @@ public static function add_group_terms_clauses_filter() { return; } self::$should_filter_terms_clauses_for_error_validation_status = true; - $groups = self::sanitize_term_status( wp_unslash( $_GET[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ] ), array( 'multiple' => true ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $groups = self::sanitize_term_status( wp_unslash( $_GET[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ] ), [ 'multiple' => true ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( empty( $groups ) ) { return; } add_filter( 'terms_clauses', - function( $clauses, $taxonomies ) use ( $groups ) { + static function( $clauses, $taxonomies ) use ( $groups ) { if ( AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG === $taxonomies[0] && AMP_Validation_Error_Taxonomy::$should_filter_terms_clauses_for_error_validation_status ) { $clauses['where'] .= ' AND t.term_group ' . AMP_Validation_Error_Taxonomy::prepare_term_group_in_sql( $groups ); } @@ -1080,7 +1073,7 @@ public static function add_error_type_clauses_filter() { add_filter( 'terms_clauses', - function( $clauses, $taxonomies ) use ( $type ) { + static function( $clauses, $taxonomies ) use ( $type ) { global $wpdb; if ( AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG === $taxonomies[0] ) { $clauses['where'] .= $wpdb->prepare( ' AND tt.description LIKE %s', '%"type":"' . $wpdb->esc_like( $type ) . '"%' ); @@ -1103,10 +1096,10 @@ public static function add_order_clauses_from_description_json() { return; } - $sortable_column_vars = array( + $sortable_column_vars = [ self::VALIDATION_ERROR_TYPE_QUERY_VAR, self::VALIDATION_DETAILS_ERROR_CODE_QUERY_VAR, - ); + ]; if ( ! isset( $_GET['orderby'] ) || ! in_array( $_GET['orderby'], $sortable_column_vars, true ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return; @@ -1114,7 +1107,7 @@ public static function add_order_clauses_from_description_json() { add_filter( 'terms_clauses', - function( $clauses ) { + static function( $clauses ) { global $wpdb; if ( isset( $_GET['order'] ) && 'desc' === $_GET['order'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended @@ -1167,7 +1160,7 @@ public static function render_taxonomy_filters( $taxonomy_name ) { 'doaction' ) ); + submit_button( __( 'Apply Filter', 'amp' ), '', 'filter_action', false, [ 'id' => 'doaction' ] ); self::render_clear_empty_button(); ?>
@@ -1241,16 +1234,16 @@ public static function render_error_status_filter() { if ( 'edit-tags' === $screen_base ) { $total_term_count = self::get_validation_error_count(); - $ack_rejected_term_count = self::get_validation_error_count( array( 'group' => array( self::VALIDATION_ERROR_ACK_REJECTED_STATUS ) ) ); - $ack_accepted_term_count = self::get_validation_error_count( array( 'group' => array( self::VALIDATION_ERROR_ACK_ACCEPTED_STATUS ) ) ); + $ack_rejected_term_count = self::get_validation_error_count( [ 'group' => [ self::VALIDATION_ERROR_ACK_REJECTED_STATUS ] ] ); + $ack_accepted_term_count = self::get_validation_error_count( [ 'group' => [ self::VALIDATION_ERROR_ACK_ACCEPTED_STATUS ] ] ); $new_term_count = $total_term_count - $ack_rejected_term_count - $ack_accepted_term_count; } elseif ( 'edit' === $screen_base ) { - $args = array( + $args = [ 'post_type' => AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, - ); + ]; $error_type = sanitize_key( $wp_query->get( self::VALIDATION_ERROR_TYPE_QUERY_VAR ) ); if ( $error_type && in_array( $error_type, self::get_error_types(), true ) ) { @@ -1260,12 +1253,12 @@ public static function render_error_status_filter() { $with_new_query = new WP_Query( array_merge( $args, - array( - self::VALIDATION_ERROR_STATUS_QUERY_VAR => array( + [ + self::VALIDATION_ERROR_STATUS_QUERY_VAR => [ self::VALIDATION_ERROR_NEW_ACCEPTED_STATUS, self::VALIDATION_ERROR_NEW_REJECTED_STATUS, - ), - ) + ], + ] ) ); $new_term_count = $with_new_query->found_posts; @@ -1273,7 +1266,7 @@ public static function render_error_status_filter() { $with_rejected_query = new WP_Query( array_merge( $args, - array( self::VALIDATION_ERROR_STATUS_QUERY_VAR => self::VALIDATION_ERROR_ACK_REJECTED_STATUS ) + [ self::VALIDATION_ERROR_STATUS_QUERY_VAR => self::VALIDATION_ERROR_ACK_REJECTED_STATUS ] ) ); $ack_rejected_term_count = $with_rejected_query->found_posts; @@ -1281,7 +1274,7 @@ public static function render_error_status_filter() { $with_accepted_query = new WP_Query( array_merge( $args, - array( self::VALIDATION_ERROR_STATUS_QUERY_VAR => self::VALIDATION_ERROR_ACK_ACCEPTED_STATUS ) + [ self::VALIDATION_ERROR_STATUS_QUERY_VAR => self::VALIDATION_ERROR_ACK_ACCEPTED_STATUS ] ) ); $ack_accepted_term_count = $with_accepted_query->found_posts; @@ -1289,9 +1282,9 @@ public static function render_error_status_filter() { return; } - $selected_groups = array(); + $selected_groups = []; if ( isset( $_GET[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $selected_groups = self::sanitize_term_status( $_GET[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ], array( 'multiple' => true ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $selected_groups = self::sanitize_term_status( $_GET[ self::VALIDATION_ERROR_STATUS_QUERY_VAR ], [ 'multiple' => true ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended } if ( ! empty( $selected_groups ) ) { sort( $selected_groups ); @@ -1401,7 +1394,7 @@ public static function render_error_status_filter() { * @return array Error types. */ public static function get_error_types() { - return array( self::HTML_ELEMENT_ERROR_TYPE, self::HTML_ATTRIBUTE_ERROR_TYPE, self::JS_ERROR_TYPE, self::CSS_ERROR_TYPE ); + return [ self::HTML_ELEMENT_ERROR_TYPE, self::HTML_ATTRIBUTE_ERROR_TYPE, self::JS_ERROR_TYPE, self::CSS_ERROR_TYPE ]; } /** @@ -1481,7 +1474,6 @@ public static function render_clear_empty_button() { * @return array All caps. */ public static function filter_user_has_cap_for_hiding_term_list_table_checkbox( $allcaps, $caps, $args ) { - unset( $caps ); if ( isset( $args[0] ) && 'delete_term' === $args[0] ) { $term = get_term( $args[2] ); $error = json_decode( $term->description, true ); @@ -1523,7 +1515,7 @@ public static function add_admin_notices() { // Show success messages for accepting/rejecting validation errors. if ( ! empty( $_GET['amp_actioned'] ) && ! empty( $_GET['amp_actioned_count'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $actioned = sanitize_key( $_GET['amp_actioned'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $count = intval( $_GET['amp_actioned_count'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $count = (int) $_GET['amp_actioned_count']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $message = null; if ( self::VALIDATION_ERROR_ACCEPT_ACTION === $actioned ) { $message = sprintf( @@ -1609,10 +1601,10 @@ public static function filter_tag_row_actions( $actions, WP_Term $tag ) { '
%s', admin_url( add_query_arg( - array( + [ self::TAXONOMY_SLUG => $term->name, 'post_type' => AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, - ), + ], 'edit.php' ) ), @@ -1627,7 +1619,7 @@ public static function filter_tag_row_actions( $actions, WP_Term $tag ) { $actions[ self::VALIDATION_ERROR_REJECT_ACTION ] = sprintf( '%s', wp_nonce_url( - add_query_arg( array_merge( array( 'action' => self::VALIDATION_ERROR_REJECT_ACTION ), compact( 'term_id' ) ) ), + add_query_arg( array_merge( [ 'action' => self::VALIDATION_ERROR_REJECT_ACTION ], compact( 'term_id' ) ) ), self::VALIDATION_ERROR_REJECT_ACTION ), esc_html__( 'Reject', 'amp' ) @@ -1637,7 +1629,7 @@ public static function filter_tag_row_actions( $actions, WP_Term $tag ) { $actions[ self::VALIDATION_ERROR_ACCEPT_ACTION ] = sprintf( '%s', wp_nonce_url( - add_query_arg( array_merge( array( 'action' => self::VALIDATION_ERROR_ACCEPT_ACTION ), compact( 'term_id' ) ) ), + add_query_arg( array_merge( [ 'action' => self::VALIDATION_ERROR_ACCEPT_ACTION ], compact( 'term_id' ) ) ), self::VALIDATION_ERROR_ACCEPT_ACTION ), esc_html__( 'Accept', 'amp' ) @@ -1653,9 +1645,9 @@ public static function filter_tag_row_actions( $actions, WP_Term $tag ) { public static function add_admin_menu_validation_error_item() { $menu_item_label = esc_html__( 'Error Index', 'amp' ); $new_error_count = self::get_validation_error_count( - array( - 'group' => array( self::VALIDATION_ERROR_NEW_REJECTED_STATUS, self::VALIDATION_ERROR_NEW_ACCEPTED_STATUS ), - ) + [ + 'group' => [ self::VALIDATION_ERROR_NEW_REJECTED_STATUS, self::VALIDATION_ERROR_NEW_ACCEPTED_STATUS ], + ] ); if ( $new_error_count ) { $menu_item_label .= ' ' . esc_html( number_format_i18n( $new_error_count ) ) . ''; @@ -1769,10 +1761,10 @@ public static function filter_manage_custom_columns( $content, $column_name, $te '%s', admin_url( add_query_arg( - array( + [ self::TAXONOMY_SLUG => $term->name, 'post_type' => AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, - ), + ], 'edit.php' ) ), @@ -1882,7 +1874,7 @@ public static function filter_manage_custom_columns( $content, $column_name, $te __( 'F j, Y g:i a', 'amp' ) ) ), - /* translators: %s: human readable timestamp */ + /* translators: %s: the human-readable time difference. */ esc_html( sprintf( __( '%s ago', 'amp' ), human_time_diff( $created_datetime->getTimestamp() ) ) ) ); } @@ -1905,10 +1897,9 @@ public static function filter_manage_custom_columns( $content, $column_name, $te if ( isset( $validation_error['parent_name'] ) ) { $summary = self::get_details_summary_label( $validation_error ); - unset( $validation_error['error_type'] ); - unset( $validation_error['parent_name'] ); + unset( $validation_error['error_type'], $validation_error['parent_name'] ); - $attributes = array(); + $attributes = []; $attributes_heading = ''; if ( ! empty( $validation_error['node_attributes'] ) ) { $attributes_heading = sprintf( '
%s
', esc_html__( 'Element attributes:', 'amp' ) ); @@ -1949,11 +1940,11 @@ public static function filter_manage_custom_columns( $content, $column_name, $te if ( ! isset( $_GET['post'], $_GET['action'] ) || 'edit' !== $_GET['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended break; } - $url_post_id = intval( $_GET['post'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $url_post_id = (int) $_GET['post']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $validation_errors = AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( $url_post_id ); $validation_errors = array_filter( $validation_errors, - function( $error ) use ( $term ) { + static function( $error ) use ( $term ) { return $error['term']->term_id === $term->term_id; } ); @@ -1988,10 +1979,10 @@ function( $error ) use ( $term ) { public static function add_single_post_sortable_columns( $sortable_columns ) { return array_merge( $sortable_columns, - array( + [ 'error' => self::VALIDATION_DETAILS_ERROR_CODE_QUERY_VAR, 'error_type' => self::VALIDATION_ERROR_TYPE_QUERY_VAR, - ) + ] ); } @@ -2005,7 +1996,7 @@ public static function add_single_post_sortable_columns( $sortable_columns ) { public static function render_single_url_error_details( $validation_error, $term ) { // Get the sources, if they exist. if ( isset( $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $validation_errors = AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( intval( $_GET['post'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $validation_errors = AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( (int) $_GET['post'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended foreach ( $validation_errors as $error ) { if ( isset( $error['data']['sources'], $error['term']->term_id ) && $error['term']->term_id === $term->term_id ) { $validation_error['sources'] = $error['data']['sources']; @@ -2065,9 +2056,9 @@ public static function render_single_url_error_details( $validation_error, $term
- $attr ) : ?> + $attr ) : ?> %s', esc_html( $key ) ); + printf( '%s', esc_html( $value_key ) ); if ( ! empty( $attr ) ) : printf( ': %s', esc_html( $attr ) ); endif; @@ -2101,12 +2092,12 @@ public static function get_translated_type_name( $validation_error ) { return null; } - $translated_names = array( + $translated_names = [ self::HTML_ELEMENT_ERROR_TYPE => __( 'HTML Element', 'amp' ), self::HTML_ATTRIBUTE_ERROR_TYPE => __( 'HTML Attribute', 'amp' ), self::JS_ERROR_TYPE => __( 'JavaScript', 'amp' ), self::CSS_ERROR_TYPE => __( 'CSS', 'amp' ), - ); + ]; if ( isset( $translated_names[ $validation_error['type'] ] ) ) { return $translated_names[ $validation_error['type'] ]; @@ -2120,7 +2111,7 @@ public static function get_translated_type_name( $validation_error ) { */ public static function handle_inline_edit_request() { // Check for necessary arguments. - if ( ! isset( $_GET['action'] ) || ! isset( $_GET['_wpnonce'] ) || ! isset( $_GET['term_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( ! isset( $_GET['action'], $_GET['_wpnonce'], $_GET['term_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return; } @@ -2130,7 +2121,7 @@ public static function handle_inline_edit_request() { } // If we have a post_type check that it is the correct one. - if ( isset( $_GET['post_type'] ) && \AMP_Validated_URL_Post_Type::POST_TYPE_SLUG !== $_GET['post_type'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( isset( $_GET['post_type'] ) && AMP_Validated_URL_Post_Type::POST_TYPE_SLUG !== $_GET['post_type'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended return; } $action = sanitize_key( $_GET['action'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended @@ -2141,8 +2132,8 @@ public static function handle_inline_edit_request() { } $referer = wp_get_referer(); - $term_id = intval( $_GET['term_id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $redirect = self::handle_validation_error_update( $referer, $action, array( $term_id ) ); + $term_id = (int) $_GET['term_id']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $redirect = self::handle_validation_error_update( $referer, $action, [ $term_id ] ); if ( $redirect !== $referer ) { wp_safe_redirect( $redirect ); @@ -2167,10 +2158,10 @@ public static function handle_single_url_page_bulk_and_inline_actions( $post_id $action = sanitize_key( $_REQUEST['action'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $term_ids = isset( $_POST['delete_tags'] ) ? array_map( 'sanitize_key', $_POST['delete_tags'] ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing $single_term_id = isset( $_GET['term_id'] ) ? sanitize_key( $_GET['term_id'] ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $redirect_query_args = array( + $redirect_query_args = [ 'action' => 'edit', 'amp_actioned' => $action, - ); + ]; if ( $term_ids ) { // If this is a bulk action. @@ -2178,7 +2169,7 @@ public static function handle_single_url_page_bulk_and_inline_actions( $post_id $redirect_query_args['amp_actioned_count'] = count( $term_ids ); } elseif ( $single_term_id ) { // If this is an inline action, like 'Reject' or 'Accept'. - self::handle_validation_error_update( null, $action, array( $single_term_id ) ); + self::handle_validation_error_update( null, $action, [ $single_term_id ] ); $redirect_query_args['amp_actioned_count'] = 1; } @@ -2221,10 +2212,10 @@ public static function handle_validation_error_update( $redirect_to, $action, $t add_filter( 'pre_term_description', 'wp_filter_kses', $has_pre_term_description_filter ); } $redirect_to = add_query_arg( - array( + [ 'amp_actioned' => $action, 'amp_actioned_count' => count( $term_ids ), - ), + ], $redirect_to ); } @@ -2236,7 +2227,7 @@ public static function handle_validation_error_update( $redirect_to, $action, $t * Handle request to delete empty terms. */ public static function handle_clear_empty_terms_request() { - if ( ! isset( $_POST[ self::VALIDATION_ERROR_CLEAR_EMPTY_ACTION ] ) || ! isset( $_POST[ self::VALIDATION_ERROR_CLEAR_EMPTY_ACTION . '_nonce' ] ) ) { + if ( ! isset( $_POST[ self::VALIDATION_ERROR_CLEAR_EMPTY_ACTION ], $_POST[ self::VALIDATION_ERROR_CLEAR_EMPTY_ACTION . '_nonce' ] ) ) { return; } if ( ! check_ajax_referer( self::VALIDATION_ERROR_CLEAR_EMPTY_ACTION, self::VALIDATION_ERROR_CLEAR_EMPTY_ACTION . '_nonce', false ) ) { @@ -2286,8 +2277,6 @@ public static function get_error_title_from_code( $error_code ) { ); } elseif ( 'disallowed_file_extension' === $error_code ) { $error_title = __( 'Disallowed file extension', 'amp' ); - } elseif ( 'file_path_not_allowed' === $error_code ) { - $error_title = __( 'File path not allowed', 'amp' ); } elseif ( 'removed_unused_css_rules' === $error_code ) { $error_title = __( 'Remove unused CSS rules', 'amp' ); } diff --git a/includes/validation/class-amp-validation-manager.php b/includes/validation/class-amp-validation-manager.php index dbb26d9f181..844b3c97972 100644 --- a/includes/validation/class-amp-validation-manager.php +++ b/includes/validation/class-amp-validation-manager.php @@ -63,21 +63,21 @@ class AMP_Validation_Manager { * @type string $slug Hash of the error. * } */ - public static $validation_results = array(); + public static $validation_results = []; /** * Sources that enqueue each script. * * @var array */ - public static $enqueued_script_sources = array(); + public static $enqueued_script_sources = []; /** * Sources that enqueue each style. * * @var array */ - public static $enqueued_style_sources = array(); + public static $enqueued_style_sources = []; /** * Post IDs for posts that have been updated which need to be re-validated. @@ -86,7 +86,7 @@ class AMP_Validation_Manager { * * @var bool[] */ - public static $posts_pending_frontend_validation = array(); + public static $posts_pending_frontend_validation = []; /** * Current sources gathered for a given hook currently being run. @@ -95,7 +95,7 @@ class AMP_Validation_Manager { * @see AMP_Validation_Manager::decorate_filter_source() * @var array[] */ - protected static $current_hook_source_stack = array(); + protected static $current_hook_source_stack = []; /** * Index for where block appears in a post's content. @@ -112,7 +112,7 @@ class AMP_Validation_Manager { * @since 0.7 * @var array[] */ - public static $hook_source_stack = array(); + public static $hook_source_stack = []; /** * Whether validation error sources should be located. @@ -126,7 +126,7 @@ class AMP_Validation_Manager { * * @var array */ - public static $validation_error_status_overrides = array(); + public static $validation_error_status_overrides = []; /** * Whether the admin bar item was added for AMP. @@ -138,17 +138,35 @@ class AMP_Validation_Manager { /** * Cached template directory to prevent infinite recursion. * + * @see get_template_directory() * @var string */ protected static $template_directory; + /** + * Cached template slug to prevent infinite recursion. + * + * @see get_template() + * @var string + */ + protected static $template_slug; + /** * Cached stylesheet directory to prevent infinite recursion. * + * @see get_stylesheet_directory() * @var string */ protected static $stylesheet_directory; + /** + * Cached stylesheet slug to prevent infinite recursion. + * + * @see get_stylesheet() + * @var string + */ + protected static $stylesheet_slug; + /** * Add the actions. * @@ -159,11 +177,11 @@ class AMP_Validation_Manager { * } * @return void */ - public static function init( $args = array() ) { + public static function init( $args = [] ) { $args = array_merge( - array( + [ 'should_locate_sources' => self::should_validate_response(), - ), + ], $args ); @@ -177,10 +195,10 @@ public static function init( $args = array() ) { return; } - add_action( 'save_post', array( __CLASS__, 'handle_save_post_prompting_validation' ) ); - add_action( 'enqueue_block_editor_assets', array( __CLASS__, 'enqueue_block_validation' ) ); - add_action( 'edit_form_top', array( __CLASS__, 'print_edit_form_validation_status' ), 10, 2 ); - add_action( 'rest_api_init', array( __CLASS__, 'add_rest_api_fields' ) ); + add_action( 'save_post', [ __CLASS__, 'handle_save_post_prompting_validation' ] ); + add_action( 'enqueue_block_editor_assets', [ __CLASS__, 'enqueue_block_validation' ] ); + add_action( 'edit_form_top', [ __CLASS__, 'print_edit_form_validation_status' ], 10, 2 ); + add_action( 'rest_api_init', [ __CLASS__, 'add_rest_api_fields' ] ); // Add actions for checking theme support is present to determine plugin compatibility and show validation links in the admin bar. if ( AMP_Options_Manager::is_website_experience_enabled() && current_theme_supports( AMP_Theme_Support::SLUG ) ) { @@ -188,8 +206,8 @@ public static function init( $args = array() ) { add_action( 'activate_plugin', function() { - if ( ! has_action( 'shutdown', array( __CLASS__, 'validate_after_plugin_activation' ) ) ) { - add_action( 'shutdown', array( __CLASS__, 'validate_after_plugin_activation' ) ); // Shutdown so all plugins will have been activated. + if ( ! has_action( 'shutdown', [ __CLASS__, 'validate_after_plugin_activation' ] ) ) { + add_action( 'shutdown', [ __CLASS__, 'validate_after_plugin_activation' ] ); // Shutdown so all plugins will have been activated. } } ); @@ -203,9 +221,9 @@ function( $query_vars ) { } ); - add_action( 'all_admin_notices', array( __CLASS__, 'print_plugin_notice' ) ); + add_action( 'all_admin_notices', [ __CLASS__, 'print_plugin_notice' ] ); - add_action( 'admin_bar_menu', array( __CLASS__, 'add_admin_bar_menu_items' ), 101 ); + add_action( 'admin_bar_menu', [ __CLASS__, 'add_admin_bar_menu_items' ], 101 ); } if ( self::$should_locate_sources ) { @@ -332,10 +350,10 @@ public static function add_admin_bar_menu_items( $wp_admin_bar ) { $amp_url = remove_query_arg( array_merge( wp_removable_query_args(), - array( + [ self::VALIDATE_QUERY_VAR, 'amp_preserve_source_comments', - ) + ] ), $current_url ); @@ -374,7 +392,7 @@ public static function add_admin_bar_menu_items( $wp_admin_bar ) { } // @todo The amp_validated_url post should probably only be accessible to users who can manage_options, or limit access to a post if the user has the cap to edit the queried object? - $validate_url = AMP_Validated_URL_Post_Type::get_recheck_url( $amp_validated_url_post ? $amp_validated_url_post : $amp_url ); + $validate_url = AMP_Validated_URL_Post_Type::get_recheck_url( $amp_validated_url_post ?: $amp_url ); // Construct the parent admin bar item. if ( is_amp_endpoint() ) { @@ -387,7 +405,7 @@ public static function add_admin_bar_menu_items( $wp_admin_bar ) { $icon = '🔗'; // LINK SYMBOL. $href = $amp_url; } - $parent = array( + $parent = [ 'id' => 'amp', 'title' => sprintf( '%s %s', @@ -395,14 +413,14 @@ public static function add_admin_bar_menu_items( $wp_admin_bar ) { esc_html__( 'AMP', 'amp' ) ), 'href' => esc_url( $href ), - ); + ]; // Construct admin bar item for validation. - $validate_item = array( + $validate_item = [ 'parent' => 'amp', 'id' => 'amp-validity', 'href' => esc_url( $validate_url ), - ); + ]; if ( $error_count <= 0 ) { $validate_item['title'] = esc_html__( 'Re-validate', 'amp' ); } else { @@ -421,12 +439,12 @@ public static function add_admin_bar_menu_items( $wp_admin_bar ) { } // Construct admin bar item to link to AMP version or non-AMP version. - $link_item = array( + $link_item = [ 'parent' => 'amp', 'id' => 'amp-view', 'title' => esc_html( is_amp_endpoint() ? __( 'View non-AMP version', 'amp' ) : __( 'View AMP version', 'amp' ) ), 'href' => esc_url( is_amp_endpoint() ? $non_amp_url : $amp_url ), - ); + ]; // Add admin bar item to switch between AMP and non-AMP if parent node is also an AMP link. $is_single_version_available = ( @@ -500,25 +518,27 @@ public static function add_validation_error_sourcing() { */ foreach ( $_REQUEST[ self::VALIDATION_ERROR_TERM_STATUS_QUERY_VAR ] as $slug => $status ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $slug = sanitize_key( $slug ); - $status = intval( $status ); + $status = (int) $status; self::$validation_error_status_overrides[ $slug ] = $status; ksort( self::$validation_error_status_overrides ); } } - self::$template_directory = get_template_directory(); - self::$stylesheet_directory = get_stylesheet_directory(); + self::$template_directory = wp_normalize_path( get_template_directory() ); + self::$template_slug = get_template(); + self::$stylesheet_directory = wp_normalize_path( get_stylesheet_directory() ); + self::$stylesheet_slug = get_stylesheet(); - add_action( 'wp', array( __CLASS__, 'wrap_widget_callbacks' ) ); + add_action( 'wp', [ __CLASS__, 'wrap_widget_callbacks' ] ); - add_action( 'all', array( __CLASS__, 'wrap_hook_callbacks' ) ); - $wrapped_filters = array( 'the_content', 'the_excerpt' ); + add_action( 'all', [ __CLASS__, 'wrap_hook_callbacks' ] ); + $wrapped_filters = [ 'the_content', 'the_excerpt' ]; foreach ( $wrapped_filters as $wrapped_filter ) { - add_filter( $wrapped_filter, array( __CLASS__, 'decorate_filter_source' ), PHP_INT_MAX ); + add_filter( $wrapped_filter, [ __CLASS__, 'decorate_filter_source' ], PHP_INT_MAX ); } - add_filter( 'do_shortcode_tag', array( __CLASS__, 'decorate_shortcode_source' ), PHP_INT_MAX, 2 ); - add_filter( 'embed_oembed_html', array( __CLASS__, 'decorate_embed_source' ), PHP_INT_MAX, 3 ); + add_filter( 'do_shortcode_tag', [ __CLASS__, 'decorate_shortcode_source' ], PHP_INT_MAX, 2 ); + add_filter( 'embed_oembed_html', [ __CLASS__, 'decorate_embed_source' ], PHP_INT_MAX, 3 ); $do_blocks_priority = has_filter( 'the_content', 'do_blocks' ); $is_gutenberg_active = ( @@ -527,7 +547,7 @@ public static function add_validation_error_sourcing() { class_exists( 'WP_Block_Type_Registry' ) ); if ( $is_gutenberg_active ) { - add_filter( 'the_content', array( __CLASS__, 'add_block_source_comments' ), $do_blocks_priority - 1 ); + add_filter( 'the_content', [ __CLASS__, 'add_block_source_comments' ], $do_blocks_priority - 1 ); } } @@ -568,8 +588,8 @@ public static function handle_save_post_prompting_validation( $post_id ) { self::$posts_pending_frontend_validation[ $post_id ] = true; // The reason for shutdown is to ensure that all postmeta changes have been saved, including whether AMP is enabled. - if ( ! has_action( 'shutdown', array( __CLASS__, 'validate_queued_posts_on_frontend' ) ) ) { - add_action( 'shutdown', array( __CLASS__, 'validate_queued_posts_on_frontend' ) ); + if ( ! has_action( 'shutdown', [ __CLASS__, 'validate_queued_posts_on_frontend' ] ) ) { + add_action( 'shutdown', [ __CLASS__, 'validate_queued_posts_on_frontend' ] ); } } } @@ -589,7 +609,7 @@ function( $post ) { } ); - $validation_posts = array(); + $validation_posts = []; /* * It is unlikely that there will be more than one post in the array. @@ -609,16 +629,16 @@ function( $post ) { if ( is_wp_error( $validity ) ) { $validation_posts[ $post->ID ] = $validity; } else { - $invalid_url_post_id = intval( get_post_meta( $post->ID, '_amp_validated_url_post_id', true ) ); + $invalid_url_post_id = (int) get_post_meta( $post->ID, '_amp_validated_url_post_id', true ); $validation_posts[ $post->ID ] = AMP_Validated_URL_Post_Type::store_validation_errors( wp_list_pluck( $validity['results'], 'error' ), $validity['url'], array_merge( - array( + [ 'invalid_url_post' => $invalid_url_post_id, - ), - wp_array_slice_assoc( $validity, array( 'queried_object' ) ) + ], + wp_array_slice_assoc( $validity, [ 'queried_object' ] ) ) ); @@ -639,16 +659,16 @@ function( $post ) { */ public static function add_rest_api_fields() { if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) { - $object_types = array( AMP_Story_Post_Type::POST_TYPE_SLUG ); // Eventually validation should be done in Reader mode as well, but for now, limit to stories. + $object_types = [ AMP_Story_Post_Type::POST_TYPE_SLUG ]; // Eventually validation should be done in Reader mode as well, but for now, limit to stories. } elseif ( amp_is_canonical() ) { $object_types = get_post_types_by_support( 'editor' ); // @todo Shouldn't this actually only be those with 'amp' support, or if if all_templates_supported? } else { $object_types = array_intersect( get_post_types_by_support( 'amp' ), get_post_types( - array( + [ 'show_in_rest' => true, - ) + ] ) ); } @@ -656,13 +676,13 @@ public static function add_rest_api_fields() { register_rest_field( $object_types, self::VALIDITY_REST_FIELD_NAME, - array( - 'get_callback' => array( __CLASS__, 'get_amp_validity_rest_field' ), - 'schema' => array( + [ + 'get_callback' => [ __CLASS__, 'get_amp_validity_rest_field' ], + 'schema' => [ 'description' => __( 'AMP validity status', 'amp' ), 'type' => 'object', - ), - ) + ], + ] ); } @@ -678,14 +698,13 @@ public static function add_rest_api_fields() { * @return array|null $validation_data Validation data if it's available, or null. */ public static function get_amp_validity_rest_field( $post_data, $field_name, $request ) { - unset( $field_name ); if ( ! current_user_can( 'edit_post', $post_data['id'] ) || ! self::has_cap() || ! self::post_supports_validation( $post_data['id'] ) ) { return null; } $post = get_post( $post_data['id'] ); $validation_status_post = null; - if ( in_array( $request->get_method(), array( 'PUT', 'POST' ), true ) ) { + if ( in_array( $request->get_method(), [ 'PUT', 'POST' ], true ) ) { if ( ! isset( self::$posts_pending_frontend_validation[ $post->ID ] ) ) { self::$posts_pending_frontend_validation[ $post->ID ] = true; } @@ -699,21 +718,21 @@ public static function get_amp_validity_rest_field( $post_data, $field_name, $re $validation_status_post = AMP_Validated_URL_Post_Type::get_invalid_url_post( amp_get_permalink( $post->ID ) ); } - $field = array( - 'results' => array(), + $field = [ + 'results' => [], 'review_link' => null, - ); + ]; if ( $validation_status_post ) { $field['review_link'] = get_edit_post_link( $validation_status_post->ID, 'raw' ); foreach ( AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( $validation_status_post ) as $result ) { - $field['results'][] = array( + $field['results'][] = [ 'sanitized' => AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACK_ACCEPTED_STATUS === $result['status'], 'error' => $result['data'], 'status' => $result['status'], 'term_status' => $result['term_status'], 'forced' => $result['forced'], - ); + ]; } } @@ -739,7 +758,7 @@ public static function has_cap() { * * @return bool Whether the validation error should result in sanitization. */ - public static function add_validation_error( array $error, array $data = array() ) { + public static function add_validation_error( array $error, array $data = [] ) { $node = null; $matches = null; $sources = null; @@ -819,9 +838,9 @@ public static function add_validation_error( array $error, array $data = array() * @return void */ public static function reset_validation_results() { - self::$validation_results = array(); - self::$enqueued_style_sources = array(); - self::$enqueued_script_sources = array(); + self::$validation_results = []; + self::$enqueued_style_sources = []; + self::$enqueued_script_sources = []; } /** @@ -845,7 +864,7 @@ public static function print_edit_form_validation_status( $post ) { } // Show all validation errors which have not been explicitly acknowledged as accepted. - $validation_errors = array(); + $validation_errors = []; $has_rejected_error = false; foreach ( AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( $invalid_url_post ) as $error ) { $needs_moderation = ( @@ -902,25 +921,25 @@ public static function print_edit_form_validation_status( $post ) { echo '

'; $results = AMP_Validation_Error_Taxonomy::summarize_validation_errors( array_unique( $validation_errors, SORT_REGULAR ) ); - $removed_sets = array(); + $removed_sets = []; if ( ! empty( $results[ AMP_Validation_Error_Taxonomy::REMOVED_ELEMENTS ] ) && is_array( $results[ AMP_Validation_Error_Taxonomy::REMOVED_ELEMENTS ] ) ) { - $removed_sets[] = array( + $removed_sets[] = [ 'label' => __( 'Invalid elements:', 'amp' ), 'names' => array_map( 'sanitize_key', $results[ AMP_Validation_Error_Taxonomy::REMOVED_ELEMENTS ] ), - ); + ]; } if ( ! empty( $results[ AMP_Validation_Error_Taxonomy::REMOVED_ATTRIBUTES ] ) && is_array( $results[ AMP_Validation_Error_Taxonomy::REMOVED_ATTRIBUTES ] ) ) { - $removed_sets[] = array( + $removed_sets[] = [ 'label' => __( 'Invalid attributes:', 'amp' ), 'names' => array_map( 'sanitize_key', $results[ AMP_Validation_Error_Taxonomy::REMOVED_ATTRIBUTES ] ), - ); + ]; } // @todo There are other kinds of errors other than REMOVED_ELEMENTS and REMOVED_ATTRIBUTES. foreach ( $removed_sets as $removed_set ) { printf( '

%s ', esc_html( $removed_set['label'] ) ); - $items = array(); + $items = []; foreach ( $removed_set['names'] as $name => $count ) { - if ( 1 === intval( $count ) ) { + if ( 1 === (int) $count ) { $items[] = sprintf( '%s', esc_html( $name ) ); } else { $items[] = sprintf( '%s (%d)', esc_html( $name ), $count ); @@ -982,8 +1001,8 @@ public static function parse_source_comment( DOMComment $comment ) { public static function locate_sources( DOMNode $node ) { $xpath = new DOMXPath( $node->ownerDocument ); $comments = $xpath->query( 'preceding::comment()[ starts-with( ., "amp-source-stack" ) or starts-with( ., "/amp-source-stack" ) ]', $node ); - $sources = array(); - $matches = array(); + $sources = []; + $matches = []; foreach ( $comments as $comment ) { $parsed_comment = self::parse_source_comment( $comment ); @@ -1083,7 +1102,7 @@ public static function locate_sources( DOMNode $node ) { */ public static function remove_source_comments( $dom ) { $xpath = new DOMXPath( $dom ); - $comments = array(); + $comments = []; foreach ( $xpath->query( '//comment()[ starts-with( ., "amp-source-stack" ) or starts-with( ., "/amp-source-stack" ) ]' ) as $comment ) { if ( self::parse_source_comment( $comment ) ) { $comments[] = $comment; @@ -1105,19 +1124,19 @@ public static function add_block_source_comments( $content ) { $start_block_pattern = implode( '', - array( + [ '##s', - ) + ] ); return preg_replace_callback( $start_block_pattern, - array( __CLASS__, 'handle_block_source_comment_replacement' ), + [ __CLASS__, 'handle_block_source_comment_replacement' ], $content ); } @@ -1135,10 +1154,10 @@ protected static function handle_block_source_comment_replacement( $matches ) { $replaced = $matches[0]; // Obtain source information for block. - $source = array( + $source = [ 'block_name' => $matches['name'], 'post_id' => get_the_ID(), - ); + ]; if ( empty( $matches['closing'] ) ) { $source['block_content_index'] = self::$block_content_index; @@ -1216,7 +1235,7 @@ public static function wrap_hook_callbacks( $hook ) { return; } - self::$current_hook_source_stack[ $hook ] = array(); + self::$current_hook_source_stack[ $hook ] = []; foreach ( $wp_filter[ $hook ]->callbacks as $priority => &$callbacks ) { foreach ( $callbacks as &$callback ) { $source = self::get_source( $callback['function'] ); @@ -1296,11 +1315,11 @@ public static function decorate_shortcode_source( $output, $tag ) { $output = implode( '', - array( + [ self::get_source_comment( $source, true ), $output, self::get_source_comment( $source, false ), - ) + ] ); return $output; } @@ -1316,17 +1335,17 @@ public static function decorate_shortcode_source( $output, $tag ) { * @return string Output. */ public static function decorate_embed_source( $output, $url, $attr ) { - $source = array( + $source = [ 'embed' => $url, 'attr' => $attr, - ); + ]; return implode( '', - array( + [ self::get_source_comment( $source, true ), trim( $output ), self::get_source_comment( $source, false ), - ) + ] ); } @@ -1345,10 +1364,10 @@ public static function decorate_filter_source( $value ) { } $post = get_post(); - $source = array( + $source = [ 'hook' => current_filter(), 'filter' => true, - ); + ]; if ( $post ) { $source['post_id'] = $post->ID; $source['post_type'] = $post->post_type; @@ -1360,18 +1379,18 @@ public static function decorate_filter_source( $value ) { } return implode( '', - array( + [ self::get_source_comment( $source, true ), $value, self::get_source_comment( $source, false ), - ) + ] ); } /** * Gets the plugin or theme of the callback, if one exists. * - * @param string|array $callback The callback for which to get the plugin. + * @param string|array|callable $callback The callback for which to get the plugin. * @return array|null { * The source data. * @@ -1434,15 +1453,12 @@ public static function get_source( $callback ) { if ( preg_match( ':' . preg_quote( trailingslashit( wp_normalize_path( WP_PLUGIN_DIR ) ), ':' ) . $slug_pattern . ':s', $file, $matches ) ) { $source['type'] = 'plugin'; $source['name'] = $matches[1]; - } elseif ( preg_match( ':' . preg_quote( trailingslashit( wp_normalize_path( self::$template_directory ) ), ':' ) . ':s', $file ) ) { + } elseif ( preg_match( ':' . preg_quote( trailingslashit( self::$template_directory ), ':' ) . $slug_pattern . ':s', $file ) ) { $source['type'] = 'theme'; - $source['name'] = get_template(); - } elseif ( preg_match( ':' . preg_quote( trailingslashit( wp_normalize_path( self::$stylesheet_directory ) ), ':' ) . ':s', $file ) ) { + $source['name'] = self::$template_slug; + } elseif ( preg_match( ':' . preg_quote( trailingslashit( self::$stylesheet_directory ), ':' ) . $slug_pattern . ':s', $file ) ) { $source['type'] = 'theme'; - $source['name'] = get_stylesheet(); - } elseif ( preg_match( ':' . preg_quote( trailingslashit( wp_normalize_path( get_theme_root() ) ), ':' ) . $slug_pattern . ':s', $file, $matches ) ) { - $source['type'] = 'theme'; - $source['name'] = $matches[1]; + $source['name'] = self::$stylesheet_slug; } elseif ( preg_match( ':' . preg_quote( trailingslashit( wp_normalize_path( WPMU_PLUGIN_DIR ) ), ':' ) . $slug_pattern . ':s', $file, $matches ) ) { $source['type'] = 'mu-plugin'; $source['name'] = $matches[1]; @@ -1481,7 +1497,7 @@ public static function can_output_buffer() { } // Check if any functions in call stack are output buffering display handlers. - $called_functions = array(); + $called_functions = []; if ( defined( 'DEBUG_BACKTRACE_IGNORE_ARGS' ) ) { $arg = DEBUG_BACKTRACE_IGNORE_ARGS; // phpcs:ignore PHPCompatibility.Constants.NewConstants.debug_backtrace_ignore_argsFound } else { @@ -1514,64 +1530,10 @@ public static function can_output_buffer() { * @type int $accepted_args * @type array $source * } - * @return closure $wrapped_callback The callback, wrapped in comments. + * @return AMP_Validation_Callback_Wrapper $wrapped_callback The callback, wrapped in comments. */ public static function wrapped_callback( $callback ) { - return function() use ( $callback ) { - global $wp_styles, $wp_scripts; - - $function = $callback['function']; - $accepted_args = $callback['accepted_args']; - $args = func_get_args(); - - $before_styles_enqueued = array(); - if ( isset( $wp_styles ) && isset( $wp_styles->queue ) ) { - $before_styles_enqueued = $wp_styles->queue; - } - $before_scripts_enqueued = array(); - if ( isset( $wp_scripts ) && isset( $wp_scripts->queue ) ) { - $before_scripts_enqueued = $wp_scripts->queue; - } - - $is_filter = isset( $callback['source']['hook'] ) && ! did_action( $callback['source']['hook'] ); - - // Wrap the markup output of (action) hooks in source comments. - AMP_Validation_Manager::$hook_source_stack[] = $callback['source']; - $has_buffer_started = false; - if ( ! $is_filter && AMP_Validation_Manager::can_output_buffer() ) { - $has_buffer_started = ob_start( array( __CLASS__, 'wrap_buffer_with_source_comments' ) ); - } - $result = call_user_func_array( $function, array_slice( $args, 0, intval( $accepted_args ) ) ); - if ( $has_buffer_started ) { - ob_end_flush(); - } - array_pop( AMP_Validation_Manager::$hook_source_stack ); - - // Keep track of which source enqueued the styles. - if ( isset( $wp_styles ) && isset( $wp_styles->queue ) ) { - foreach ( array_diff( $wp_styles->queue, $before_styles_enqueued ) as $handle ) { - AMP_Validation_Manager::$enqueued_style_sources[ $handle ][] = array_merge( $callback['source'], compact( 'handle' ) ); - } - } - - // Keep track of which source enqueued the scripts, and immediately report validity. - if ( isset( $wp_scripts ) && isset( $wp_scripts->queue ) ) { - foreach ( array_diff( $wp_scripts->queue, $before_scripts_enqueued ) as $queued_handle ) { - $handles = array( $queued_handle ); - - // Account for case where registered script is a placeholder for a set of scripts (e.g. jquery). - if ( isset( $wp_scripts->registered[ $queued_handle ] ) && false === $wp_scripts->registered[ $queued_handle ]->src ) { - $handles = array_merge( $handles, $wp_scripts->registered[ $queued_handle ]->deps ); - } - - foreach ( $handles as $handle ) { - AMP_Validation_Manager::$enqueued_script_sources[ $handle ][] = array_merge( $callback['source'], compact( 'handle' ) ); - } - } - } - - return $result; - }; + return new AMP_Validation_Callback_Wrapper( $callback ); } /** @@ -1597,11 +1559,11 @@ public static function wrap_buffer_with_source_comments( $output ) { if ( ! empty( $output ) && preg_match( '/<.+?>/s', $output ) ) { $output = implode( '', - array( + [ self::get_source_comment( $source, true ), $output, self::get_source_comment( $source, false ), - ) + ] ); } return $output; @@ -1615,7 +1577,7 @@ public static function wrap_buffer_with_source_comments( $output ) { * @return string Nonce. */ public static function get_amp_validate_nonce() { - return substr( wp_hash( self::VALIDATE_QUERY_VAR . (string) wp_nonce_tick(), 'nonce' ), -12, 10 ); + return substr( wp_hash( self::VALIDATE_QUERY_VAR . wp_nonce_tick(), 'nonce' ), -12, 10 ); } /** @@ -1647,12 +1609,12 @@ public static function should_validate_response() { * @type bool $append_validation_status_comment Whether the validation errors should be appended as an HTML comment. Defaults to true. * } */ - public static function finalize_validation( DOMDocument $dom, $args = array() ) { + public static function finalize_validation( DOMDocument $dom, $args = [] ) { $args = array_merge( - array( + [ 'remove_source_comments' => true, 'append_validation_status_comment' => true, - ), + ], $args ); @@ -1705,11 +1667,11 @@ public static function finalize_validation( DOMDocument $dom, $args = array() ) } if ( $args['append_validation_status_comment'] ) { - $data = array( + $data = [ 'results' => self::$validation_results, - ); + ]; if ( get_queried_object() ) { - $data['queried_object'] = array(); + $data['queried_object'] = []; if ( get_queried_object_id() ) { $data['queried_object']['id'] = get_queried_object_id(); } @@ -1746,7 +1708,7 @@ public static function filter_sanitizer_args( $sanitizers ) { if ( isset( $sanitizers['AMP_Style_Sanitizer'] ) ) { $sanitizers['AMP_Style_Sanitizer']['should_locate_sources'] = self::$should_locate_sources; - $css_validation_errors = array(); + $css_validation_errors = []; foreach ( self::$validation_error_status_overrides as $slug => $status ) { $term = AMP_Validation_Error_Taxonomy::get_term( $slug ); if ( ! $term ) { @@ -1792,7 +1754,7 @@ public static function validate_after_plugin_activation() { AMP_Validated_URL_Post_Type::store_validation_errors( $validation_errors, $validity['url'], - wp_array_slice_assoc( $validity, array( 'queried_object_id', 'queried_object_type' ) ) + wp_array_slice_assoc( $validity, [ 'queried_object_id', 'queried_object_type' ] ) ); set_transient( self::PLUGIN_ACTIVATION_VALIDATION_ERRORS_TRANSIENT_KEY, $validation_errors, 60 ); } else { @@ -1819,10 +1781,10 @@ public static function validate_after_plugin_activation() { */ public static function validate_url( $url ) { - $added_query_vars = array( + $added_query_vars = [ self::VALIDATE_QUERY_VAR => self::get_amp_validate_nonce(), self::CACHE_BUST_QUERY_VAR => wp_rand(), - ); + ]; $validation_url = add_query_arg( $added_query_vars, $url ); $r = null; @@ -1832,15 +1794,15 @@ public static function validate_url( $url ) { for ( $redirect_count = 0; $redirect_count < $allowed_redirects; $redirect_count++ ) { $r = wp_remote_get( $validation_url, - array( + [ 'cookies' => wp_unslash( $_COOKIE ), // Pass along cookies so private pages and drafts can be accessed. 'timeout' => 15, // Increase from default of 5 to give extra time for the plugin to identify the sources for any given validation errors; also, response caching is disabled when validating. 'sslverify' => false, 'redirection' => 0, // Because we're in a loop for redirection. - 'headers' => array( + 'headers' => [ 'Cache-Control' => 'no-cache', - ), - ) + ], + ] ); // If the response is not a redirect, then break since $r is all we need. @@ -1887,7 +1849,7 @@ public static function validate_url( $url ) { ); $response = wp_remote_retrieve_body( $r ); - if ( strlen( trim( $response ) ) === 0 ) { + if ( trim( $response ) === '' ) { $error_code = 'white_screen_of_death'; return new WP_Error( $error_code, self::get_validate_url_error_message( $error_code ) ); } @@ -1938,7 +1900,7 @@ public static function get_validate_url_error_message( $error_code ) { default: /* translators: %s is error code */ return sprintf( __( 'URL validation failed. Error code: %s.', 'amp' ), $error_code ); // Note that $error_code has been sanitized with sanitize_key(); will be escaped below as well. - }; + } } /** @@ -1957,7 +1919,7 @@ public static function print_plugin_notice() { $errors = AMP_Validation_Error_Taxonomy::summarize_validation_errors( $validation_errors ); $invalid_plugins = isset( $errors[ AMP_Validation_Error_Taxonomy::SOURCES_INVALID_OUTPUT ]['plugin'] ) ? array_unique( $errors[ AMP_Validation_Error_Taxonomy::SOURCES_INVALID_OUTPUT ]['plugin'] ) : null; if ( isset( $invalid_plugins ) ) { - $reported_plugins = array(); + $reported_plugins = []; foreach ( $invalid_plugins as $plugin ) { $reported_plugins[] = sprintf( '%s', esc_html( $plugin ) ); } @@ -2015,7 +1977,7 @@ public static function enqueue_block_validation() { $script_deps_path = AMP__DIR__ . '/assets/js/' . $slug . '.deps.json'; $script_dependencies = file_exists( $script_deps_path ) ? json_decode( file_get_contents( $script_deps_path ), false ) // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents - : array(); + : []; wp_enqueue_script( $slug, @@ -2025,14 +1987,23 @@ public static function enqueue_block_validation() { true ); + wp_enqueue_style( + $slug, + amp_get_asset_url( "css/{$slug}-compiled.css" ), + false, + AMP__VERSION + ); + + wp_styles()->add_data( $slug, 'rtl', 'replace' ); + $status_and_errors = AMP_Post_Meta_Box::get_status_and_errors( get_post() ); $enabled_status = $status_and_errors['status']; - $data = array( + $data = [ 'isSanitizationAutoAccepted' => self::is_sanitization_auto_accepted() || AMP_Story_Post_Type::POST_TYPE_SLUG === get_post_type(), - 'possibleStatuses' => array( AMP_Post_Meta_Box::ENABLED_STATUS, AMP_Post_Meta_Box::DISABLED_STATUS ), + 'possibleStatuses' => [ AMP_Post_Meta_Box::ENABLED_STATUS, AMP_Post_Meta_Box::DISABLED_STATUS ], 'defaultStatus' => $enabled_status, - ); + ]; wp_localize_script( $slug, diff --git a/includes/widgets/class-amp-widget-archives.php b/includes/widgets/class-amp-widget-archives.php index 108898d0544..84cefb3ff3b 100644 --- a/includes/widgets/class-amp-widget-archives.php +++ b/includes/widgets/class-amp-widget-archives.php @@ -58,11 +58,11 @@ public function widget( $args, $instance ) { /** This filter is documented in wp-includes/widgets/class-wp-widget-archives.php */ $dropdown_args = apply_filters( 'widget_archives_dropdown_args', - array( + [ 'type' => 'monthly', 'format' => 'option', 'show_post_count' => $c, - ) + ] ); switch ( $dropdown_args['type'] ) { @@ -95,10 +95,10 @@ public function widget( $args, $instance ) { wp_get_archives( apply_filters( 'widget_archives_args', - array( + [ 'type' => 'monthly', 'show_post_count' => $c, - ) + ] ) ); ?> diff --git a/includes/widgets/class-amp-widget-categories.php b/includes/widgets/class-amp-widget-categories.php index 158fc2293a7..0fb88546d7c 100644 --- a/includes/widgets/class-amp-widget-categories.php +++ b/includes/widgets/class-amp-widget-categories.php @@ -46,15 +46,15 @@ public function widget( $args, $instance ) { if ( $title ) { echo wp_kses_post( $args['before_title'] . $title . $args['after_title'] ); } - $cat_args = array( + $cat_args = [ 'orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h, - ); + ]; if ( $d ) : $form_id = sprintf( 'widget-categories-dropdown-%d', $this->number ); printf( '

', esc_url( home_url() ), esc_attr( $form_id ) ); - $dropdown_id = ( $first_dropdown ) ? 'cat' : "{$this->id_base}-dropdown-{$this->number}"; + $dropdown_id = $first_dropdown ? 'cat' : "{$this->id_base}-dropdown-{$this->number}"; $first_dropdown = false; echo ''; $cat_args['show_option_none'] = __( 'Select Category', 'default' ); @@ -64,7 +64,7 @@ public function widget( $args, $instance ) { array_merge( /** This filter is documented in wp-includes/widgets/class-wp-widget-categories.php */ apply_filters( 'widget_categories_dropdown_args', $cat_args, $instance ), - array( 'echo' => false ) + [ 'echo' => false ] ) ); $dropdown = preg_replace( diff --git a/package-lock.json b/package-lock.json index d12c848e648..03e0c58db1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,9 +4,9 @@ "lockfileVersion": 1, "dependencies": { "@babel/cli": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.4.4.tgz", - "integrity": "sha512-XGr5YjQSjgTa6OzQZY57FAJsdeVSAKR/u/KA5exWIz66IKtv/zXtHy+fIZcMry/EgYegwuHE7vzGnrFhjdIAsQ==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.5.5.tgz", + "integrity": "sha512-UHI+7pHv/tk9g6WXQKYz+kmXTI77YtuY3vqC59KIqcoWEjsJJSG6rAxKaLsgj3LDyadsPrCB929gVOKM6Hui0w==", "dev": true, "requires": { "chokidar": "^2.0.4", @@ -14,7 +14,7 @@ "convert-source-map": "^1.1.0", "fs-readdir-recursive": "^1.1.0", "glob": "^7.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "mkdirp": "^0.5.1", "output-file-sync": "^2.0.0", "slash": "^2.0.0", @@ -31,48 +31,81 @@ } }, "@babel/core": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", - "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", - "@babel/helpers": "^7.4.4", - "@babel/parser": "^7.4.5", + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.5", - "@babel/types": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", + "dev": true, + "requires": { + "@babel/types": "^7.5.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, "@babel/parser": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", "dev": true }, "@babel/traverse": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", - "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.5", - "@babel/types": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" } }, "debug": { @@ -85,20 +118,20 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.0.tgz", + "integrity": "sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA==", "dev": true, "requires": { - "@babel/types": "^7.4.4", + "@babel/types": "^7.5.0", "jsesc": "^2.5.1", "lodash": "^4.17.11", "source-map": "^0.5.0", @@ -146,14 +179,27 @@ } }, "@babel/helper-define-map": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", - "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", + "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", "dev": true, "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-explode-assignable-expression": { @@ -196,12 +242,25 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", - "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", + "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.5.5" + }, + "dependencies": { + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-module-imports": { @@ -214,17 +273,30 @@ } }, "@babel/helper-module-transforms": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", - "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", + "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-simple-access": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", "@babel/template": "^7.4.4", - "@babel/types": "^7.4.4", - "lodash": "^4.17.11" + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-optimise-call-expression": { @@ -243,12 +315,12 @@ "dev": true }, "@babel/helper-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", - "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", "dev": true, "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/helper-remap-async-to-generator": { @@ -265,15 +337,88 @@ } }, "@babel/helper-replace-supers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", - "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", + "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", + "dev": true, + "requires": { + "@babel/types": "^7.5.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/parser": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", + "dev": true + }, + "@babel/traverse": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } } }, "@babel/helper-simple-access": { @@ -308,20 +453,93 @@ } }, "@babel/helpers": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", - "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", + "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", "dev": true, "requires": { "@babel/template": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", + "dev": true, + "requires": { + "@babel/types": "^7.5.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/parser": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", + "dev": true + }, + "@babel/traverse": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "dev": true, "requires": { "chalk": "^2.0.0", @@ -330,9 +548,9 @@ } }, "@babel/parser": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", - "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.0.tgz", + "integrity": "sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -346,6 +564,16 @@ "@babel/plugin-syntax-async-generators": "^7.2.0" } }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", + "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0" + } + }, "@babel/plugin-proposal-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", @@ -357,9 +585,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", - "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", + "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -396,6 +624,15 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-syntax-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", @@ -442,9 +679,9 @@ } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", - "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", + "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -462,27 +699,27 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", - "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", + "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.11" + "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", - "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", + "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.4.4", + "@babel/helper-define-map": "^7.5.5", "@babel/helper-function-name": "^7.1.0", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4", "globals": "^11.1.0" } @@ -497,9 +734,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", - "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", + "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -517,9 +754,9 @@ } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", - "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", + "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -573,34 +810,37 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", - "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", + "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", - "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", + "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.4.4", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0" + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", - "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", + "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-umd": { @@ -614,12 +854,12 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.4.tgz", - "integrity": "sha512-Ki+Y9nXBlKfhD+LXaRS7v95TtTGYRAf9Y1rTDiE75zf8YQz4GDaWRXosMfJBXxnk88mGFjWdCRIeqDbon7spYA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", + "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", "dev": true, "requires": { - "regexp-tree": "^0.1.0" + "regexp-tree": "^0.1.6" } }, "@babel/plugin-transform-new-target": { @@ -632,13 +872,13 @@ } }, "@babel/plugin-transform-object-super": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", - "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", + "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.1.0" + "@babel/helper-replace-supers": "^7.5.5" } }, "@babel/plugin-transform-parameters": { @@ -673,12 +913,12 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.4.tgz", - "integrity": "sha512-Zz3w+pX1SI0KMIiqshFZkwnVGUhDZzpX2vtPzfJBKQQq8WsP/Xy9DNdELWivxcKOCX/Pywge4SiEaPaLtoDT4g==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", + "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", "dev": true, "requires": { - "regenerator-transform": "^0.13.4" + "regenerator-transform": "^0.14.0" } }, "@babel/plugin-transform-reserved-words": { @@ -691,9 +931,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.4.tgz", - "integrity": "sha512-aMVojEjPszvau3NRg+TIH14ynZLvPewH4xhlCW1w6A3rkxTS1m4uwzRclYR9oS+rl/dr+kT+pzbfHuAWP/lc7Q==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz", + "integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -761,46 +1001,48 @@ } }, "@babel/preset-env": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.4.tgz", - "integrity": "sha512-FU1H+ACWqZZqfw1x2G1tgtSSYSfxJLkpaUQL37CenULFARDo+h4xJoVHzRoHbK+85ViLciuI7ME4WTIhFRBBlw==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", + "integrity": "sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-dynamic-import": "^7.5.0", "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.4.4", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-syntax-json-strings": "^7.2.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.4.4", + "@babel/plugin-transform-async-to-generator": "^7.5.0", "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.4.4", - "@babel/plugin-transform-classes": "^7.4.4", + "@babel/plugin-transform-block-scoping": "^7.5.5", + "@babel/plugin-transform-classes": "^7.5.5", "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.4.4", + "@babel/plugin-transform-destructuring": "^7.5.0", "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-duplicate-keys": "^7.5.0", "@babel/plugin-transform-exponentiation-operator": "^7.2.0", "@babel/plugin-transform-for-of": "^7.4.4", "@babel/plugin-transform-function-name": "^7.4.4", "@babel/plugin-transform-literals": "^7.2.0", "@babel/plugin-transform-member-expression-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.4.4", - "@babel/plugin-transform-modules-systemjs": "^7.4.4", + "@babel/plugin-transform-modules-amd": "^7.5.0", + "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "@babel/plugin-transform-modules-systemjs": "^7.5.0", "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.4", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", "@babel/plugin-transform-new-target": "^7.4.4", - "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-object-super": "^7.5.5", "@babel/plugin-transform-parameters": "^7.4.4", "@babel/plugin-transform-property-literals": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.4.4", + "@babel/plugin-transform-regenerator": "^7.4.5", "@babel/plugin-transform-reserved-words": "^7.2.0", "@babel/plugin-transform-shorthand-properties": "^7.2.0", "@babel/plugin-transform-spread": "^7.2.0", @@ -808,18 +1050,31 @@ "@babel/plugin-transform-template-literals": "^7.4.4", "@babel/plugin-transform-typeof-symbol": "^7.2.0", "@babel/plugin-transform-unicode-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "browserslist": "^4.5.2", - "core-js-compat": "^3.0.0", + "@babel/types": "^7.5.5", + "browserslist": "^4.6.0", + "core-js-compat": "^3.1.1", "invariant": "^2.2.2", "js-levenshtein": "^1.1.3", "semver": "^5.5.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/runtime": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.4.tgz", - "integrity": "sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.0.tgz", + "integrity": "sha512-2xsuyZ0R0RBFwjgae5NpXk8FcfH4qovj5cEM5VEeB7KXnKqzaisIu2HSV/mCEISolJJuR4wkViUGYujA8MH9tw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -837,17 +1092,17 @@ } }, "@babel/traverse": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", - "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.0.tgz", + "integrity": "sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", + "@babel/generator": "^7.5.0", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4", + "@babel/parser": "^7.5.0", + "@babel/types": "^7.5.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.11" @@ -863,17 +1118,17 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.0.tgz", + "integrity": "sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -905,6 +1160,53 @@ "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==", "dev": true }, + "@hapi/address": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz", + "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw==", + "dev": true + }, + "@hapi/hoek": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-6.2.4.tgz", + "integrity": "sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A==", + "dev": true + }, + "@hapi/joi": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.0.tgz", + "integrity": "sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ==", + "dev": true, + "requires": { + "@hapi/address": "2.x.x", + "@hapi/hoek": "6.x.x", + "@hapi/marker": "1.x.x", + "@hapi/topo": "3.x.x" + } + }, + "@hapi/marker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@hapi/marker/-/marker-1.0.0.tgz", + "integrity": "sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA==", + "dev": true + }, + "@hapi/topo": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.2.tgz", + "integrity": "sha512-r+aumOqJ5QbD6aLPJWqVjMAPsx5pZKz+F5yPqXZ/WWG9JTtHbQqlzrJoknJ0iJxLj9vlXtmpSdjlkszseeG8OA==", + "dev": true, + "requires": { + "@hapi/hoek": "8.x.x" + }, + "dependencies": { + "@hapi/hoek": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.1.0.tgz", + "integrity": "sha512-b1J4jxYnW+n6lC91V6Pqg9imP9BZq0HNCeM+3sbXg05rQsE9cGYrKFpZjyztVesGmNRE6R+QaEoWGATeIiUVjA==", + "dev": true + } + } + }, "@jest/console": { "version": "24.7.1", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", @@ -1192,9 +1494,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz", - "integrity": "sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz", + "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -1242,6 +1544,12 @@ "@types/istanbul-lib-report": "*" } }, + "@types/json-schema": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", + "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -1249,9 +1557,9 @@ "dev": true }, "@types/node": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", - "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", + "version": "12.0.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.12.tgz", + "integrity": "sha512-Uy0PN4R5vgBUXFoJrKryf5aTk3kJ8Rv3PdlHjl6UaX+Cqp1QE0yPQ68MPXGrZOfG7gZVNDIJZYyot0B9ubXUrQ==", "dev": true }, "@types/q": { @@ -1299,6 +1607,53 @@ "integrity": "sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==", "dev": true }, + "@types/yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw==", + "dev": true + }, + "@typescript-eslint/experimental-utils": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz", + "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "1.13.0", + "eslint-scope": "^4.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz", + "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -1478,9 +1833,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -1565,46 +1920,48 @@ "@xtuc/long": "4.2.2" } }, - "@wordpress/a11y": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.3.0.tgz", - "integrity": "sha512-+V/LBz9lQx+jjKk3Do4rSx8vkBS2J8FQTLD8DgPKH/sXo6C6/tTFpNENPKo/O9ZB/NktrIJffQJd4rTbUJesvg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.4", - "@wordpress/dom-ready": "^2.3.0" - } - }, "@wordpress/api-fetch": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.2.0.tgz", - "integrity": "sha512-JWnV8HPQLmEDK8H1T1ucYqmYgdSFy5FRC7Gk/+r02W+irF1igiXz1YVPDdBgDuLrs3fvs7SmEHHp9PON/ONG+g==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.4.0.tgz", + "integrity": "sha512-aNLVIXlnn7RIEzbDcVFhyQfV60O0ggLQOCkHhMCW1Ya86Jlohp658TXe8wIjFhC2ugY239WeZIl1tgoRjqIr0A==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/i18n": "^3.4.0", - "@wordpress/url": "^2.6.0" + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0" + }, + "dependencies": { + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + } } }, "@wordpress/autop": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-2.3.0.tgz", - "integrity": "sha512-j6vm65yragfH7iDLwEdhSP++69ntOabkyPiuYURMILRmPmystZ29R8T7tHrt7SgnE/YOwRqFH45DRq74u9ciDg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-2.4.0.tgz", + "integrity": "sha512-QapmHuXN3daJpfBDVmKLAVIy97xmqoeBbAKT4sfhZGwR3NIv9fmiKrM8XKWSDAGAqNF1lYN2KkrFieXM7lDU4Q==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/babel-plugin-import-jsx-pragma": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-2.2.0.tgz", - "integrity": "sha512-H31qqjbXrQebue4ho8bu/vCPkVCENalxQMMAQOGulmQxOQ6IF+9uwglCR6ZiAWhZmPo6LFq0NQ+IPLSUX8IS8Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-2.3.0.tgz", + "integrity": "sha512-b45c4x1+OvQm1f6egrBruO8eVF4bRVRZ8ojM1ttDcMi+K/qXfun3J6O8xXpSnA5eeNCZaJL3DhIk/aoNBbpwzw==", "dev": true }, "@wordpress/babel-preset-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-4.2.0.tgz", - "integrity": "sha512-a0+PzFKRgmZLILdkCwTqoEJY3getFRqiT1mtd1hQvszrX01RbKmeOmPHx6OZPE0HhbYWS4HK/RCGXgBfPy7ROw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-4.4.0.tgz", + "integrity": "sha512-cFdzlVSYe7M4lKojBxG/TaoRAL6r/UZhvFN7R7e49qlrNlB20YTGSkpKffO1h158mlPuunFIIt+425w/xQE8/g==", "dev": true, "requires": { "@babel/core": "^7.4.4", @@ -1614,220 +1971,1168 @@ "@babel/plugin-transform-runtime": "^7.4.4", "@babel/preset-env": "^7.4.4", "@babel/runtime": "^7.4.4", - "@wordpress/babel-plugin-import-jsx-pragma": "^2.2.0", - "@wordpress/browserslist-config": "^2.4.0" + "@wordpress/babel-plugin-import-jsx-pragma": "^2.3.0", + "@wordpress/browserslist-config": "^2.6.0", + "core-js": "^3.1.4" + }, + "dependencies": { + "@wordpress/browserslist-config": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.6.0.tgz", + "integrity": "sha512-vRgzGoxhcNVChBP30XZlyK4w6r/9ZpO+Fi1dzmButp31lUEb1pT5WBxTIQl3HE0JZ9YTEJ00WWGO5sjGi5MHZA==", + "dev": true + } } }, "@wordpress/blob": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-2.4.0.tgz", - "integrity": "sha512-VUHUTABAR7xgZtP1qRYDNTZqeRlrpSqjAAczk80YkpKQOq2LD+HhxBpktBQ06YchV+OTwXh0l853IRDOUsGwWw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-2.5.0.tgz", + "integrity": "sha512-Eze4O8XivI8Xw4ol3l2TIPUk+K/FVT3GDOuYnwykNXKf19AwOrc51rfX7bqKqonsoGpEQ3TZTIsMfj6+l4k95g==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/block-editor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-2.1.0.tgz", - "integrity": "sha512-XcBXDLcJkEIfUhXv3HNf1M9K/uhFaxvStQ54roVGPuB7cRIZQ8DIm62jkkuBRuo7iGgb1jqvffdFPqtFvstF4g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-3.0.0.tgz", + "integrity": "sha512-ooEBV8kf1mnShUNLYSAZNiAZNFDoy9Eg9wihtfSDzc89431iFeClIw49dYEy3GFn84MNOHiCqXWHD7Ew2RR8iQ==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/a11y": "^2.3.0", - "@wordpress/blob": "^2.4.0", - "@wordpress/blocks": "^6.3.0", - "@wordpress/components": "^7.4.0", - "@wordpress/compose": "^3.3.0", - "@wordpress/data": "^4.5.0", - "@wordpress/dom": "^2.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/hooks": "^2.3.0", - "@wordpress/html-entities": "^2.3.0", - "@wordpress/i18n": "^3.4.0", - "@wordpress/is-shallow-equal": "^1.3.0", - "@wordpress/keycodes": "^2.3.0", - "@wordpress/rich-text": "^3.3.0", - "@wordpress/token-list": "^1.3.0", - "@wordpress/url": "^2.6.0", - "@wordpress/viewport": "^2.4.0", - "@wordpress/wordcount": "^2.3.0", + "@wordpress/a11y": "^2.5.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/token-list": "^1.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", + "@wordpress/wordcount": "^2.5.0", "classnames": "^2.2.5", "dom-scroll-into-view": "^1.2.1", "lodash": "^4.17.10", + "react-spring": "^8.0.19", "redux-multi": "^0.1.12", "refx": "^3.0.0", "rememo": "^3.0.0", "tinycolor2": "^1.4.1" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + }, + "@wordpress/components": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-8.1.0.tgz", + "integrity": "sha512-V35ZyDIVadVQQhKB6IyGULdMfi+44KLL6K0FL2gVihLxHq1P0g3sC6kE26DmYNcYXYfhyGMZT440nkUi1jEo3A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/url": "^2.7.0", + "classnames": "^2.2.5", + "clipboard": "^2.0.1", + "diff": "^3.5.0", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "moment": "^2.22.1", + "mousetrap": "^1.6.2", + "re-resizable": "^5.0.1", + "react-click-outside": "^3.0.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^3.3.2" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/rich-text": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "rememo": "^3.0.0" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + }, + "@wordpress/wordcount": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.5.0.tgz", + "integrity": "sha512-Du/O50ZBpl5Pq/MevUZHQg0FBpT6v/SRhSV8lF5ByjZfXelUcQGN+gQ6RmNdasQ33KVPmspdCQHnQ+sThm4/iA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "re-resizable": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-5.0.1.tgz", + "integrity": "sha512-Iy8v5li7bhNBDxCN1DbA4l6G2Hk8NCZtcExoI1D+5pfvKyQcH8LH2P5h3DGoEfHhs0uyyRC1Qx8bHBomfrmxgA==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" + } + } } }, "@wordpress/block-library": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-2.5.0.tgz", - "integrity": "sha512-eU65Kiuc5oxlHSJj2jx1I82qFxaf55MCza4QCdKOaEhN/Cke7DDjB5tQIQ0fxfQLsK5YBTU32U6f6pF6kXCQMw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-2.7.0.tgz", + "integrity": "sha512-roArvZV4IN7URvI+dHUsNyLWy7WUSmuwndGxVqev15hdv7aOGct4DINv+S6l4LM/PgYsbSOHgDujT4vie9zfmA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/autop": "^2.3.0", - "@wordpress/blob": "^2.4.0", - "@wordpress/block-editor": "^2.1.0", - "@wordpress/blocks": "^6.3.0", - "@wordpress/components": "^7.4.0", - "@wordpress/compose": "^3.3.0", - "@wordpress/core-data": "^2.3.0", - "@wordpress/data": "^4.5.0", - "@wordpress/deprecated": "^2.3.0", - "@wordpress/editor": "^9.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/html-entities": "^2.3.0", - "@wordpress/i18n": "^3.4.0", - "@wordpress/keycodes": "^2.3.0", - "@wordpress/viewport": "^2.4.0", + "@wordpress/autop": "^2.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/block-editor": "^3.0.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/core-data": "^2.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/editor": "^9.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/server-side-render": "^1.1.0", + "@wordpress/viewport": "^2.6.0", "classnames": "^2.2.5", "fast-average-color": "4.3.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "memize": "^1.0.5", "url": "^0.11.0" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + }, + "@wordpress/api-fetch": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.4.0.tgz", + "integrity": "sha512-aNLVIXlnn7RIEzbDcVFhyQfV60O0ggLQOCkHhMCW1Ya86Jlohp658TXe8wIjFhC2ugY239WeZIl1tgoRjqIr0A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0" + } + }, + "@wordpress/block-editor": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-3.0.0.tgz", + "integrity": "sha512-ooEBV8kf1mnShUNLYSAZNiAZNFDoy9Eg9wihtfSDzc89431iFeClIw49dYEy3GFn84MNOHiCqXWHD7Ew2RR8iQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/token-list": "^1.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", + "@wordpress/wordcount": "^2.5.0", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.10", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "refx": "^3.0.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1" + } + }, + "@wordpress/components": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-8.1.0.tgz", + "integrity": "sha512-V35ZyDIVadVQQhKB6IyGULdMfi+44KLL6K0FL2gVihLxHq1P0g3sC6kE26DmYNcYXYfhyGMZT440nkUi1jEo3A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/url": "^2.7.0", + "classnames": "^2.2.5", + "clipboard": "^2.0.1", + "diff": "^3.5.0", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "moment": "^2.22.1", + "mousetrap": "^1.6.2", + "re-resizable": "^5.0.1", + "react-click-outside": "^3.0.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^3.3.2" + } + }, + "@wordpress/core-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-2.5.0.tgz", + "integrity": "sha512-v29VwTOvMvpiebkMDu6r57LHPvIL9mcWKxyrxQUTglXd8Nv9irAoyRxAFRS64DGu8ZbksC5Bl4piiuya2UwUDQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/url": "^2.7.0", + "equivalent-key-map": "^0.2.2", + "lodash": "^4.17.14", + "rememo": "^3.0.0" + } + }, + "@wordpress/data-controls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/data-controls/-/data-controls-1.1.0.tgz", + "integrity": "sha512-uJSrOKdBBYJjLwES4AsfPRyh/GWVFZhf0e/znkx+4yB2T9M1UW156vMq7wuX7xkPiEwdu1j9hZItii9aVrnCmQ==", + "dev": true, + "requires": { + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/data": "^4.7.0" + } + }, + "@wordpress/deprecated": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.5.0.tgz", + "integrity": "sha512-bryhXZZ9dZ8DlMQ2liDAV3CQV7wEiftJ9UAOB7X32X4MPZoPqvk3IGiKgHFs3/pEr4Ums0CCckgUlnY7AI+hxQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/hooks": "^2.5.0" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/editor": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.5.0.tgz", + "integrity": "sha512-9TrRwfmPaqUOyLcTYnl/qqOkYesfFGN2OSLEqbLJIyA961xkRLDz5975MAvGZakHDWwkSv3bxS2ogSoJcr8FOg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/block-editor": "^3.0.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/core-data": "^2.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/data-controls": "^1.1.0", + "@wordpress/date": "^3.4.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/media-utils": "^1.0.0", + "@wordpress/notices": "^1.6.0", + "@wordpress/nux": "^3.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", + "@wordpress/wordcount": "^2.5.0", + "classnames": "^2.2.5", + "inherits": "^2.0.3", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "react-autosize-textarea": "^3.0.2", + "redux-optimist": "^1.0.0", + "refx": "^3.0.0", + "rememo": "^3.0.0", + "traverse": "^0.6.6" + } + }, + "@wordpress/element": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.6.0.tgz", + "integrity": "sha512-t7BgD+gRvC0gOubElsiXhp0H5Dq1yAu2/J8aeok4Fcg1anUXcmjo9M7uL/C17e1AbDVIFQvCyhgOg9ltc/rgEA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/escape-html": "^1.5.0", + "lodash": "^4.17.14", + "react": "^16.8.4", + "react-dom": "^16.8.4" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/html-entities": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.5.0.tgz", + "integrity": "sha512-7TKaJKkOX2Tas0OyXNPz1kA2my1Z804weBf2RsPLiNXm593JDsf6Em8z1TA4mXtn7FO2ZAKTj/3yRemKK4PhnA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/keycodes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.5.0.tgz", + "integrity": "sha512-4SMN3pmJnNBexpd3/6JB6gJw+wcahBaVZaeMcHyF+Uw7bKcG6hDkzEAN6dWFJuifpdxmvilDE4H5JS/Ex9C6sA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/media-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-1.0.0.tgz", + "integrity": "sha512-HjleyNFc+toqeznm8KnR/JhAfDki08FhxZj3/3uksxA4HSJ3Qq6cNc46GlxCCNy7cGhSAsmYrATEsbq3s4IhAA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/notices": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-1.6.0.tgz", + "integrity": "sha512-CXJUHye/qGJo3MF3YC/AwKrFz8X5zEuaD6I1pOoOVVxpLZNMDgA2QqEbxb7X66bedBrh9akFYoNdGwS11KSsKg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/data": "^4.7.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/nux": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/nux/-/nux-3.5.0.tgz", + "integrity": "sha512-PJJweT8/cNQvaFlrf8+jgntHouSu3Gf/OH8ZlICuF73W5Om9M+1Or4eaCS5wGjV1G014dxQBR/S2ydEio37NOw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14", + "rememo": "^3.0.0" + } + }, + "@wordpress/rich-text": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "rememo": "^3.0.0" + } + }, + "@wordpress/server-side-render": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.1.0.tgz", + "integrity": "sha512-bSRHXfJozVzZSbkDSmhfBO/EuwebSLNvuBi/S0XrPA7lIJgqysZVPjSd7Z21qMnlKasF1N21lL7Dn1z2W/sMVQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/components": "^8.1.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/token-list": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-1.5.0.tgz", + "integrity": "sha512-JamANQZLdv2WgmPd0ZumjzmzPoPjbZTWef2W2kuvNHvoLNO9yVulR754qdR/wGPBYEf5sDC3E2D3Vb/zgVEw7A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + }, + "@wordpress/viewport": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.6.0.tgz", + "integrity": "sha512-mnUu/SbwrW949AgOODDFLcbLUM/Qhlbi0qZ4JN5c/nOEukru5NRuktvyPPzcd9wWAeNVlqTSpq6E8ES+65ureg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/wordcount": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.5.0.tgz", + "integrity": "sha512-Du/O50ZBpl5Pq/MevUZHQg0FBpT6v/SRhSV8lF5ByjZfXelUcQGN+gQ6RmNdasQ33KVPmspdCQHnQ+sThm4/iA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "re-resizable": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-5.0.1.tgz", + "integrity": "sha512-Iy8v5li7bhNBDxCN1DbA4l6G2Hk8NCZtcExoI1D+5pfvKyQcH8LH2P5h3DGoEfHhs0uyyRC1Qx8bHBomfrmxgA==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" + } + } } }, "@wordpress/block-serialization-default-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-3.2.0.tgz", - "integrity": "sha512-2e079+2TIAD+H+HX3LZB8SZqzfVD4VcqYnH1/pTdppPcgtcI+4o1Fyrwqm/23JPOhDN/++QCHjrDTBySWvVX9w==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-3.3.0.tgz", + "integrity": "sha512-fTUS/LEvvwyMcy1VvPl4I8c49GrmtFz5/5h9peaRJdk+jCFD0OsXhpXN1bdHC+0CAoJRz5j8Nf0k8FdFqj6uMg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/block-serialization-spec-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-spec-parser/-/block-serialization-spec-parser-3.1.0.tgz", - "integrity": "sha512-OSMLDj+FvHWSJYXkNSXLeovaiuNKrkXjVKLKWW9MQjI4sxaVFypEG9WeTpYmjDMXmTj+om9WL/1Uj0aUv1i5TA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-spec-parser/-/block-serialization-spec-parser-3.2.0.tgz", + "integrity": "sha512-Qce6P7hBI4PBb1nqzJHcyQ4IMa5i0weBDmfGrDNE1EHoJJZ4zfBnzkUqVVnYNDH5al896y6OzLcQoEKk6SDW9Q==", "dev": true, "requires": { "pegjs": "^0.10.0" } }, "@wordpress/blocks": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-6.3.0.tgz", - "integrity": "sha512-eoMwdIbeAgqu8A/zy80m4jkgFJ4ceuk88lzZSb1+FLZiX+IA+UWUEY91OFuvUiWVzv/UthoJnZdN6ngA6V474A==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-6.5.0.tgz", + "integrity": "sha512-0luBvWl8IvQwBkbKLuKg6enBvumxwVexR7gIQ6M9CaptUuVNmTheJIdg1EUUft/srRGyEwsQICDk/D9Pmx6nNw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/autop": "^2.3.0", - "@wordpress/blob": "^2.4.0", - "@wordpress/block-serialization-default-parser": "^3.2.0", - "@wordpress/block-serialization-spec-parser": "^3.1.0", - "@wordpress/data": "^4.5.0", - "@wordpress/dom": "^2.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/hooks": "^2.3.0", - "@wordpress/html-entities": "^2.3.0", - "@wordpress/i18n": "^3.4.0", - "@wordpress/is-shallow-equal": "^1.3.0", - "@wordpress/shortcode": "^2.3.0", + "@wordpress/autop": "^2.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/block-serialization-default-parser": "^3.3.0", + "@wordpress/block-serialization-spec-parser": "^3.2.0", + "@wordpress/data": "^4.7.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/shortcode": "^2.4.0", "hpq": "^1.3.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "rememo": "^3.0.0", "showdown": "^1.8.6", "simple-html-tokenizer": "^0.5.7", "tinycolor2": "^1.4.1", "uuid": "^3.3.2" + }, + "dependencies": { + "@wordpress/autop": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-2.4.0.tgz", + "integrity": "sha512-QapmHuXN3daJpfBDVmKLAVIy97xmqoeBbAKT4sfhZGwR3NIv9fmiKrM8XKWSDAGAqNF1lYN2KkrFieXM7lDU4Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/blob": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-2.5.0.tgz", + "integrity": "sha512-Eze4O8XivI8Xw4ol3l2TIPUk+K/FVT3GDOuYnwykNXKf19AwOrc51rfX7bqKqonsoGpEQ3TZTIsMfj6+l4k95g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/compose": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.5.0.tgz", + "integrity": "sha512-X9Qe7gq5+SNvT5yZXSEEgEz5UwUwYh52SBe8WlW59/t182NBBUy9FICEnmx7DRjMugZcSRDwFX39L6tuwo7cnA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/element": "^2.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/data": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.7.0.tgz", + "integrity": "sha512-6ytvrcvg6otalvFNA26gnHv0GQkQT0h9/a780IKl0wyUqAYdKbn1J52CcJWopyfZ53HDq816NCZng1a4tWxHjQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/priority-queue": "^1.3.0", + "@wordpress/redux-routine": "^3.5.0", + "equivalent-key-map": "^0.2.2", + "is-promise": "^2.1.0", + "lodash": "^4.17.14", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2" + } + }, + "@wordpress/deprecated": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.5.0.tgz", + "integrity": "sha512-bryhXZZ9dZ8DlMQ2liDAV3CQV7wEiftJ9UAOB7X32X4MPZoPqvk3IGiKgHFs3/pEr4Ums0CCckgUlnY7AI+hxQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/hooks": "^2.5.0" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/element": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.6.0.tgz", + "integrity": "sha512-t7BgD+gRvC0gOubElsiXhp0H5Dq1yAu2/J8aeok4Fcg1anUXcmjo9M7uL/C17e1AbDVIFQvCyhgOg9ltc/rgEA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/escape-html": "^1.5.0", + "lodash": "^4.17.14", + "react": "^16.8.4", + "react-dom": "^16.8.4" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/html-entities": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.5.0.tgz", + "integrity": "sha512-7TKaJKkOX2Tas0OyXNPz1kA2my1Z804weBf2RsPLiNXm593JDsf6Em8z1TA4mXtn7FO2ZAKTj/3yRemKK4PhnA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/priority-queue": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-1.3.0.tgz", + "integrity": "sha512-HlhHZUCnKW56b2KFg2cZcn6fnGdi6mrmfOn2lE3cBOibjQLYfOY3pe3TCd+AxS4GdfkgXFA7BHfAinaWCBpAyg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/redux-routine": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-3.5.0.tgz", + "integrity": "sha512-fssGjVcXlNFbAIjv6VhCWZYgsv51sugxxCgxAqgSIexsDVnOphDODo5V5bhcgwiZeL3/n5rzqvFQ7Dv4agvc/A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "is-promise": "^2.1.0", + "rungen": "^0.3.2" + } + } } }, "@wordpress/browserslist-config": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.4.0.tgz", - "integrity": "sha512-d2OmEK/qsZQxTQ449M0eatFYlW/en/ISQtakSDkaY0YB2FKZN2cM5rgOcV1aHQdkrAW00nVorMo4BPH7TpgH6g==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.6.0.tgz", + "integrity": "sha512-vRgzGoxhcNVChBP30XZlyK4w6r/9ZpO+Fi1dzmButp31lUEb1pT5WBxTIQl3HE0JZ9YTEJ00WWGO5sjGi5MHZA==", "dev": true }, "@wordpress/components": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-7.4.0.tgz", - "integrity": "sha512-riVey0Z5835YdPZLWFSAs/4Hzo0nr7WA/393mRXwGuUtkqdk7ia++5emKfhyaCLYbinVBd6366xFFfiFxxcsCA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-8.1.0.tgz", + "integrity": "sha512-V35ZyDIVadVQQhKB6IyGULdMfi+44KLL6K0FL2gVihLxHq1P0g3sC6kE26DmYNcYXYfhyGMZT440nkUi1jEo3A==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/a11y": "^2.3.0", - "@wordpress/api-fetch": "^3.2.0", - "@wordpress/compose": "^3.3.0", - "@wordpress/dom": "^2.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/hooks": "^2.3.0", - "@wordpress/i18n": "^3.4.0", - "@wordpress/is-shallow-equal": "^1.3.0", - "@wordpress/keycodes": "^2.3.0", - "@wordpress/rich-text": "^3.3.0", - "@wordpress/url": "^2.6.0", + "@wordpress/a11y": "^2.5.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/url": "^2.7.0", "classnames": "^2.2.5", "clipboard": "^2.0.1", "diff": "^3.5.0", "dom-scroll-into-view": "^1.2.1", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "memize": "^1.0.5", "moment": "^2.22.1", "mousetrap": "^1.6.2", - "re-resizable": "^4.7.1", + "re-resizable": "^5.0.1", "react-click-outside": "^3.0.0", "react-dates": "^17.1.1", + "react-spring": "^8.0.20", "rememo": "^3.0.0", "tinycolor2": "^1.4.1", "uuid": "^3.3.2" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/rich-text": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "rememo": "^3.0.0" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + } } }, "@wordpress/compose": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.3.0.tgz", - "integrity": "sha512-535cdgFiOKNfdNriyvA6CoFNYJWsL7V5EX1ZB9hqe9BR2m5a2EM+nlr64L3LI/gE9X3+KnZUjX4FRqSHJWxfew==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.5.0.tgz", + "integrity": "sha512-X9Qe7gq5+SNvT5yZXSEEgEz5UwUwYh52SBe8WlW59/t182NBBUy9FICEnmx7DRjMugZcSRDwFX39L6tuwo7cnA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/element": "^2.4.0", - "@wordpress/is-shallow-equal": "^1.3.0", - "lodash": "^4.17.11" + "@wordpress/element": "^2.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "lodash": "^4.17.14" + }, + "dependencies": { + "@wordpress/element": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.6.0.tgz", + "integrity": "sha512-t7BgD+gRvC0gOubElsiXhp0H5Dq1yAu2/J8aeok4Fcg1anUXcmjo9M7uL/C17e1AbDVIFQvCyhgOg9ltc/rgEA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/escape-html": "^1.5.0", + "lodash": "^4.17.14", + "react": "^16.8.4", + "react-dom": "^16.8.4" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + } } }, "@wordpress/core-data": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-2.3.0.tgz", - "integrity": "sha512-Bg3J4EqAfsIfQXhO0CZ5XCl9OSiIF0XtCWKcl7Ne56e1aeV9rilAoOZKcBeBTiiRt4PSyD9UQdnxYlPcZAfx3Q==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-2.5.0.tgz", + "integrity": "sha512-v29VwTOvMvpiebkMDu6r57LHPvIL9mcWKxyrxQUTglXd8Nv9irAoyRxAFRS64DGu8ZbksC5Bl4piiuya2UwUDQ==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/api-fetch": "^3.2.0", - "@wordpress/data": "^4.5.0", - "@wordpress/deprecated": "^2.3.0", - "@wordpress/url": "^2.6.0", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/url": "^2.7.0", "equivalent-key-map": "^0.2.2", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "rememo": "^3.0.0" + }, + "dependencies": { + "@wordpress/api-fetch": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.4.0.tgz", + "integrity": "sha512-aNLVIXlnn7RIEzbDcVFhyQfV60O0ggLQOCkHhMCW1Ya86Jlohp658TXe8wIjFhC2ugY239WeZIl1tgoRjqIr0A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + } } }, "@wordpress/data": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.5.0.tgz", - "integrity": "sha512-ATfN1P4LPKqeA0jkJlZd81y9vdZH3PVL+mYNKTsK3/+RPOpZDtfRn1UwSxTYR4LsAbhZVykbLl1WiWd+7eIAVg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.7.0.tgz", + "integrity": "sha512-6ytvrcvg6otalvFNA26gnHv0GQkQT0h9/a780IKl0wyUqAYdKbn1J52CcJWopyfZ53HDq816NCZng1a4tWxHjQ==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/compose": "^3.3.0", - "@wordpress/deprecated": "^2.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/is-shallow-equal": "^1.3.0", - "@wordpress/priority-queue": "^1.2.0", - "@wordpress/redux-routine": "^3.3.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/priority-queue": "^1.3.0", + "@wordpress/redux-routine": "^3.5.0", "equivalent-key-map": "^0.2.2", "is-promise": "^2.1.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "redux": "^4.0.0", "turbo-combine-reducers": "^1.0.2" + }, + "dependencies": { + "@wordpress/compose": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.5.0.tgz", + "integrity": "sha512-X9Qe7gq5+SNvT5yZXSEEgEz5UwUwYh52SBe8WlW59/t182NBBUy9FICEnmx7DRjMugZcSRDwFX39L6tuwo7cnA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/element": "^2.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/deprecated": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.5.0.tgz", + "integrity": "sha512-bryhXZZ9dZ8DlMQ2liDAV3CQV7wEiftJ9UAOB7X32X4MPZoPqvk3IGiKgHFs3/pEr4Ums0CCckgUlnY7AI+hxQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/hooks": "^2.5.0" + } + }, + "@wordpress/element": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.6.0.tgz", + "integrity": "sha512-t7BgD+gRvC0gOubElsiXhp0H5Dq1yAu2/J8aeok4Fcg1anUXcmjo9M7uL/C17e1AbDVIFQvCyhgOg9ltc/rgEA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/escape-html": "^1.5.0", + "lodash": "^4.17.14", + "react": "^16.8.4", + "react-dom": "^16.8.4" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + } + } + }, + "@wordpress/data-controls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/data-controls/-/data-controls-1.1.0.tgz", + "integrity": "sha512-uJSrOKdBBYJjLwES4AsfPRyh/GWVFZhf0e/znkx+4yB2T9M1UW156vMq7wuX7xkPiEwdu1j9hZItii9aVrnCmQ==", + "dev": true, + "requires": { + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/data": "^4.7.0" + }, + "dependencies": { + "@wordpress/api-fetch": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.4.0.tgz", + "integrity": "sha512-aNLVIXlnn7RIEzbDcVFhyQfV60O0ggLQOCkHhMCW1Ya86Jlohp658TXe8wIjFhC2ugY239WeZIl1tgoRjqIr0A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + } } }, "@wordpress/date": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.3.0.tgz", - "integrity": "sha512-xv7vXXPWyFzUUl/MPZnsbEwrNlDBM6TZCeH/66u7x9TcylVujpaI/ePhowXcnNUvYDHxAkGoBtmKQyfjFRf0rg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.4.0.tgz", + "integrity": "sha512-3rhgSs3KGdGy3m8LIuWe65bkU9zEnbZ2jT0GBtLXqP1yP4STkAcDuedOApbMONgMP7R8bo9KYrQQcOi6eZi5NA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", @@ -1836,9 +3141,9 @@ } }, "@wordpress/dependency-extraction-webpack-plugin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-1.0.1.tgz", - "integrity": "sha512-Ov4IljSGSPDjQPKV79tXKk7Ljndo+f84aImKIH8mzTMRbZS+7wPzz6jHAa/FpGmf7R99QqaN4CNRpvBihu3o9Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-1.1.0.tgz", + "integrity": "sha512-tCyxy7hLzDdCHQ1xGPiMlE7fBp/pCuEum89gqzoiz2HQJld6F7BTNMo3XfTzxFO0SHh/C64yOZgBB8FvH+warQ==", "dev": true, "requires": { "webpack": "^4.8.3", @@ -1846,142 +3151,834 @@ } }, "@wordpress/deprecated": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.3.0.tgz", - "integrity": "sha512-8ZbWPwZo/X6Hen6S1HpDPVneWMnRFesRQmSonbJklAcoz0BrJG/gUGUgfwFNGhe659z9ZbP5xAXEpinG0vsHWA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.5.0.tgz", + "integrity": "sha512-bryhXZZ9dZ8DlMQ2liDAV3CQV7wEiftJ9UAOB7X32X4MPZoPqvk3IGiKgHFs3/pEr4Ums0CCckgUlnY7AI+hxQ==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/hooks": "^2.3.0" + "@wordpress/hooks": "^2.5.0" + }, + "dependencies": { + "@wordpress/hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + } } }, "@wordpress/dom": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.3.0.tgz", - "integrity": "sha512-cy/AD7gcbQmYJd8hSsuOVhdvkdFARsP1UBirZ1nwQZtQyjwAqWQzMdLUml5PzeczhEZQlo9vzJGo8fGwQvpxEw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "@wordpress/dom-ready": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-2.3.0.tgz", - "integrity": "sha512-Wu+UOL+U3PlvdrWDLS2WHys/utzchtkBVJvSPFj8G+5wdGIayEiaj7nmGV02+Vidow6v+4Rc1+UOVuQcoH6vzA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-2.5.0.tgz", + "integrity": "sha512-1CXRTZcQ0yn9Aj5x3e0xwYJeRv81NyuwoQUD2ZvDXRXCvaNq33fm79MDvpW5E2uYoo0t9jPHTCwadVXt7bzhwQ==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/e2e-test-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils/-/e2e-test-utils-2.0.0.tgz", - "integrity": "sha512-DkNM48PZx62jE3Hx+N3qIZxdsAo/LGSL07H6OKvwBx8BTsdgTIZSiqlBM+16tjY4wpMshYVW0ZxGeGZ1XCDGpQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils/-/e2e-test-utils-2.2.0.tgz", + "integrity": "sha512-7MKwyxJKzjz3vB6DgUK8dVkWAYfjicnb9a7T5x1vme1Oub4ZU3cxEawdMdWCe0nSjXQYgatfD1Eff32whWB+Gw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/keycodes": "^2.3.0", - "@wordpress/url": "^2.6.0", - "lodash": "^4.17.11", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/url": "^2.7.0", + "lodash": "^4.17.14", "node-fetch": "^1.7.3" + }, + "dependencies": { + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/keycodes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.5.0.tgz", + "integrity": "sha512-4SMN3pmJnNBexpd3/6JB6gJw+wcahBaVZaeMcHyF+Uw7bKcG6hDkzEAN6dWFJuifpdxmvilDE4H5JS/Ex9C6sA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + } } }, "@wordpress/edit-post": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-3.4.0.tgz", - "integrity": "sha512-mwdZg/6VISBJw5CYTztzp91xG08gI3lFzWRzTwX4LISb6koDrk4e4P1Ta1edC6wfIYLWfwhJU3HDabXY8Z0VhA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-3.6.0.tgz", + "integrity": "sha512-/sFQ8+Z76VlrZ+/PNT7QJKBL4S3JfBALf2L1tRRBfUrwIAXCjgavaTfYSNcyqv1kdshw03QyzaBMIOCfFKqDuA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/a11y": "^2.3.0", - "@wordpress/api-fetch": "^3.2.0", - "@wordpress/block-editor": "^2.1.0", - "@wordpress/block-library": "^2.5.0", - "@wordpress/blocks": "^6.3.0", - "@wordpress/components": "^7.4.0", - "@wordpress/compose": "^3.3.0", - "@wordpress/core-data": "^2.3.0", - "@wordpress/data": "^4.5.0", - "@wordpress/editor": "^9.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/format-library": "^1.5.0", - "@wordpress/hooks": "^2.3.0", - "@wordpress/i18n": "^3.4.0", - "@wordpress/keycodes": "^2.3.0", - "@wordpress/nux": "^3.3.0", - "@wordpress/plugins": "^2.3.0", - "@wordpress/url": "^2.6.0", - "@wordpress/viewport": "^2.4.0", + "@wordpress/a11y": "^2.5.0", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/block-editor": "^3.0.0", + "@wordpress/block-library": "^2.7.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/core-data": "^2.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/editor": "^9.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/nux": "^3.5.0", + "@wordpress/plugins": "^2.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", "classnames": "^2.2.5", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "refx": "^3.0.0" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + }, + "@wordpress/api-fetch": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.4.0.tgz", + "integrity": "sha512-aNLVIXlnn7RIEzbDcVFhyQfV60O0ggLQOCkHhMCW1Ya86Jlohp658TXe8wIjFhC2ugY239WeZIl1tgoRjqIr0A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0" + } + }, + "@wordpress/block-editor": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-3.0.0.tgz", + "integrity": "sha512-ooEBV8kf1mnShUNLYSAZNiAZNFDoy9Eg9wihtfSDzc89431iFeClIw49dYEy3GFn84MNOHiCqXWHD7Ew2RR8iQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/token-list": "^1.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", + "@wordpress/wordcount": "^2.5.0", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.10", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "refx": "^3.0.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1" + } + }, + "@wordpress/components": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-8.1.0.tgz", + "integrity": "sha512-V35ZyDIVadVQQhKB6IyGULdMfi+44KLL6K0FL2gVihLxHq1P0g3sC6kE26DmYNcYXYfhyGMZT440nkUi1jEo3A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/url": "^2.7.0", + "classnames": "^2.2.5", + "clipboard": "^2.0.1", + "diff": "^3.5.0", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "moment": "^2.22.1", + "mousetrap": "^1.6.2", + "re-resizable": "^5.0.1", + "react-click-outside": "^3.0.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^3.3.2" + } + }, + "@wordpress/core-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-2.5.0.tgz", + "integrity": "sha512-v29VwTOvMvpiebkMDu6r57LHPvIL9mcWKxyrxQUTglXd8Nv9irAoyRxAFRS64DGu8ZbksC5Bl4piiuya2UwUDQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/url": "^2.7.0", + "equivalent-key-map": "^0.2.2", + "lodash": "^4.17.14", + "rememo": "^3.0.0" + } + }, + "@wordpress/data-controls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/data-controls/-/data-controls-1.1.0.tgz", + "integrity": "sha512-uJSrOKdBBYJjLwES4AsfPRyh/GWVFZhf0e/znkx+4yB2T9M1UW156vMq7wuX7xkPiEwdu1j9hZItii9aVrnCmQ==", + "dev": true, + "requires": { + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/data": "^4.7.0" + } + }, + "@wordpress/deprecated": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.5.0.tgz", + "integrity": "sha512-bryhXZZ9dZ8DlMQ2liDAV3CQV7wEiftJ9UAOB7X32X4MPZoPqvk3IGiKgHFs3/pEr4Ums0CCckgUlnY7AI+hxQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/hooks": "^2.5.0" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/editor": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.5.0.tgz", + "integrity": "sha512-9TrRwfmPaqUOyLcTYnl/qqOkYesfFGN2OSLEqbLJIyA961xkRLDz5975MAvGZakHDWwkSv3bxS2ogSoJcr8FOg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/block-editor": "^3.0.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/core-data": "^2.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/data-controls": "^1.1.0", + "@wordpress/date": "^3.4.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/media-utils": "^1.0.0", + "@wordpress/notices": "^1.6.0", + "@wordpress/nux": "^3.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", + "@wordpress/wordcount": "^2.5.0", + "classnames": "^2.2.5", + "inherits": "^2.0.3", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "react-autosize-textarea": "^3.0.2", + "redux-optimist": "^1.0.0", + "refx": "^3.0.0", + "rememo": "^3.0.0", + "traverse": "^0.6.6" + } + }, + "@wordpress/element": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.6.0.tgz", + "integrity": "sha512-t7BgD+gRvC0gOubElsiXhp0H5Dq1yAu2/J8aeok4Fcg1anUXcmjo9M7uL/C17e1AbDVIFQvCyhgOg9ltc/rgEA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/escape-html": "^1.5.0", + "lodash": "^4.17.14", + "react": "^16.8.4", + "react-dom": "^16.8.4" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/html-entities": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.5.0.tgz", + "integrity": "sha512-7TKaJKkOX2Tas0OyXNPz1kA2my1Z804weBf2RsPLiNXm593JDsf6Em8z1TA4mXtn7FO2ZAKTj/3yRemKK4PhnA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/keycodes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.5.0.tgz", + "integrity": "sha512-4SMN3pmJnNBexpd3/6JB6gJw+wcahBaVZaeMcHyF+Uw7bKcG6hDkzEAN6dWFJuifpdxmvilDE4H5JS/Ex9C6sA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/media-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-1.0.0.tgz", + "integrity": "sha512-HjleyNFc+toqeznm8KnR/JhAfDki08FhxZj3/3uksxA4HSJ3Qq6cNc46GlxCCNy7cGhSAsmYrATEsbq3s4IhAA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/notices": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-1.6.0.tgz", + "integrity": "sha512-CXJUHye/qGJo3MF3YC/AwKrFz8X5zEuaD6I1pOoOVVxpLZNMDgA2QqEbxb7X66bedBrh9akFYoNdGwS11KSsKg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/data": "^4.7.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/nux": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/nux/-/nux-3.5.0.tgz", + "integrity": "sha512-PJJweT8/cNQvaFlrf8+jgntHouSu3Gf/OH8ZlICuF73W5Om9M+1Or4eaCS5wGjV1G014dxQBR/S2ydEio37NOw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14", + "rememo": "^3.0.0" + } + }, + "@wordpress/plugins": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-2.5.0.tgz", + "integrity": "sha512-RnILA/bl7w3joov61/sliyODN1MFJIGYgfwv20hkmjirmM/q531T4Mzp7FOPiEBn6mqt+gGo4CuGAe8o+oP/Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/rich-text": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "rememo": "^3.0.0" + } + }, + "@wordpress/token-list": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-1.5.0.tgz", + "integrity": "sha512-JamANQZLdv2WgmPd0ZumjzmzPoPjbZTWef2W2kuvNHvoLNO9yVulR754qdR/wGPBYEf5sDC3E2D3Vb/zgVEw7A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + }, + "@wordpress/viewport": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.6.0.tgz", + "integrity": "sha512-mnUu/SbwrW949AgOODDFLcbLUM/Qhlbi0qZ4JN5c/nOEukru5NRuktvyPPzcd9wWAeNVlqTSpq6E8ES+65ureg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/wordcount": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.5.0.tgz", + "integrity": "sha512-Du/O50ZBpl5Pq/MevUZHQg0FBpT6v/SRhSV8lF5ByjZfXelUcQGN+gQ6RmNdasQ33KVPmspdCQHnQ+sThm4/iA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "re-resizable": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-5.0.1.tgz", + "integrity": "sha512-Iy8v5li7bhNBDxCN1DbA4l6G2Hk8NCZtcExoI1D+5pfvKyQcH8LH2P5h3DGoEfHhs0uyyRC1Qx8bHBomfrmxgA==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" + } + } } }, "@wordpress/editor": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.3.0.tgz", - "integrity": "sha512-rBnLCcbxoM+PLQn8evfMuo/K4gppXv5LSkv2bUSv9SWVcEUAX4CLHTTWqG6V1T2G80AZzmijcpJrK8cDIqfcrA==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.5.0.tgz", + "integrity": "sha512-9TrRwfmPaqUOyLcTYnl/qqOkYesfFGN2OSLEqbLJIyA961xkRLDz5975MAvGZakHDWwkSv3bxS2ogSoJcr8FOg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/api-fetch": "^3.2.0", - "@wordpress/blob": "^2.4.0", - "@wordpress/block-editor": "^2.1.0", - "@wordpress/blocks": "^6.3.0", - "@wordpress/components": "^7.4.0", - "@wordpress/compose": "^3.3.0", - "@wordpress/core-data": "^2.3.0", - "@wordpress/data": "^4.5.0", - "@wordpress/date": "^3.3.0", - "@wordpress/deprecated": "^2.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/hooks": "^2.3.0", - "@wordpress/html-entities": "^2.3.0", - "@wordpress/i18n": "^3.4.0", - "@wordpress/keycodes": "^2.3.0", - "@wordpress/notices": "^1.4.0", - "@wordpress/nux": "^3.3.0", - "@wordpress/url": "^2.6.0", - "@wordpress/viewport": "^2.4.0", - "@wordpress/wordcount": "^2.3.0", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/block-editor": "^3.0.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/core-data": "^2.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/data-controls": "^1.1.0", + "@wordpress/date": "^3.4.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/media-utils": "^1.0.0", + "@wordpress/notices": "^1.6.0", + "@wordpress/nux": "^3.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", + "@wordpress/wordcount": "^2.5.0", "classnames": "^2.2.5", "inherits": "^2.0.3", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "memize": "^1.0.5", "react-autosize-textarea": "^3.0.2", "redux-optimist": "^1.0.0", "refx": "^3.0.0", "rememo": "^3.0.0", "traverse": "^0.6.6" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + }, + "@wordpress/api-fetch": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.4.0.tgz", + "integrity": "sha512-aNLVIXlnn7RIEzbDcVFhyQfV60O0ggLQOCkHhMCW1Ya86Jlohp658TXe8wIjFhC2ugY239WeZIl1tgoRjqIr0A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0" + } + }, + "@wordpress/block-editor": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-3.0.0.tgz", + "integrity": "sha512-ooEBV8kf1mnShUNLYSAZNiAZNFDoy9Eg9wihtfSDzc89431iFeClIw49dYEy3GFn84MNOHiCqXWHD7Ew2RR8iQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/blocks": "^6.5.0", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/html-entities": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/token-list": "^1.5.0", + "@wordpress/url": "^2.7.0", + "@wordpress/viewport": "^2.6.0", + "@wordpress/wordcount": "^2.5.0", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.10", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "refx": "^3.0.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1" + } + }, + "@wordpress/components": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-8.1.0.tgz", + "integrity": "sha512-V35ZyDIVadVQQhKB6IyGULdMfi+44KLL6K0FL2gVihLxHq1P0g3sC6kE26DmYNcYXYfhyGMZT440nkUi1jEo3A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/url": "^2.7.0", + "classnames": "^2.2.5", + "clipboard": "^2.0.1", + "diff": "^3.5.0", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "moment": "^2.22.1", + "mousetrap": "^1.6.2", + "re-resizable": "^5.0.1", + "react-click-outside": "^3.0.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^3.3.2" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/html-entities": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.5.0.tgz", + "integrity": "sha512-7TKaJKkOX2Tas0OyXNPz1kA2my1Z804weBf2RsPLiNXm593JDsf6Em8z1TA4mXtn7FO2ZAKTj/3yRemKK4PhnA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/keycodes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.5.0.tgz", + "integrity": "sha512-4SMN3pmJnNBexpd3/6JB6gJw+wcahBaVZaeMcHyF+Uw7bKcG6hDkzEAN6dWFJuifpdxmvilDE4H5JS/Ex9C6sA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/rich-text": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "rememo": "^3.0.0" + } + }, + "@wordpress/token-list": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-1.5.0.tgz", + "integrity": "sha512-JamANQZLdv2WgmPd0ZumjzmzPoPjbZTWef2W2kuvNHvoLNO9yVulR754qdR/wGPBYEf5sDC3E2D3Vb/zgVEw7A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + }, + "@wordpress/viewport": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.6.0.tgz", + "integrity": "sha512-mnUu/SbwrW949AgOODDFLcbLUM/Qhlbi0qZ4JN5c/nOEukru5NRuktvyPPzcd9wWAeNVlqTSpq6E8ES+65ureg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/wordcount": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.5.0.tgz", + "integrity": "sha512-Du/O50ZBpl5Pq/MevUZHQg0FBpT6v/SRhSV8lF5ByjZfXelUcQGN+gQ6RmNdasQ33KVPmspdCQHnQ+sThm4/iA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "re-resizable": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-5.0.1.tgz", + "integrity": "sha512-Iy8v5li7bhNBDxCN1DbA4l6G2Hk8NCZtcExoI1D+5pfvKyQcH8LH2P5h3DGoEfHhs0uyyRC1Qx8bHBomfrmxgA==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" + } + } } }, "@wordpress/element": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.4.0.tgz", - "integrity": "sha512-6DRJ35MY+DJIlPKz8MEEr6V40w1zAcA4r7Ge0HYx9xJRxaFHwtYURqZbJmO0TidfFhv6fZg5/qVtf8LrnFnDLA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.6.0.tgz", + "integrity": "sha512-t7BgD+gRvC0gOubElsiXhp0H5Dq1yAu2/J8aeok4Fcg1anUXcmjo9M7uL/C17e1AbDVIFQvCyhgOg9ltc/rgEA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/escape-html": "^1.3.0", - "lodash": "^4.17.11", + "@wordpress/escape-html": "^1.5.0", + "lodash": "^4.17.14", "react": "^16.8.4", "react-dom": "^16.8.4" + }, + "dependencies": { + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + } } }, "@wordpress/escape-html": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.3.0.tgz", - "integrity": "sha512-4iYVMAwREg9/jXJE80wJAreamwljLmLlA5stXMQ6UIoaW5tPPdyjyjjhCgw7jhEzJAKc+re3UXKf6Up4RXwQ8A==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/eslint-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-2.2.0.tgz", - "integrity": "sha512-0NhyA+sMaLOzdNNhzTIXamllTqcBC6VRQlkkeroJUs8XkTzbCb+xCKuYWQARamjIGBmIo5ljXyKevYYj+VQqyA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-2.4.0.tgz", + "integrity": "sha512-FOsNM6cCKZKug/sXKAum1lceGiULm4sKZlBCHUHRNiGSbOlWs+kjoATQOuid9nGYVK/uzvQOCN1xwZJbQ9XjDw==", "dev": true, "requires": { "babel-eslint": "^10.0.1", @@ -1991,82 +3988,65 @@ "requireindex": "^1.2.0" } }, - "@wordpress/format-library": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/format-library/-/format-library-1.5.0.tgz", - "integrity": "sha512-7d5haQBdlER1sR337pPsQVQte4wFa9tf1lH2lkH0wxdXNuiGUPm5Dfrrf6qBhx+gKvT98hINbjBVhDCLovo6NA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.4", - "@wordpress/block-editor": "^2.1.0", - "@wordpress/components": "^7.4.0", - "@wordpress/editor": "^9.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/i18n": "^3.4.0", - "@wordpress/keycodes": "^2.3.0", - "@wordpress/rich-text": "^3.3.0", - "@wordpress/url": "^2.6.0" - } - }, "@wordpress/hooks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.3.0.tgz", - "integrity": "sha512-N7ijZUcBbcTO6AsITS66On3X14fkT3+e3rNbx/w4AANnUDmP4Nqkl+OiMWqM3gjr936hReAqIqprKKTQ98DBYQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/html-entities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.3.0.tgz", - "integrity": "sha512-pVK1IMOvErrhWXJcsrT970H/tV9GZX4KdGjTYTNVDYFxayCXPYq6HLcWWFn2r+QqNkhCpR+fuH6oee6BZx0JEg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.5.0.tgz", + "integrity": "sha512-7TKaJKkOX2Tas0OyXNPz1kA2my1Z804weBf2RsPLiNXm593JDsf6Em8z1TA4mXtn7FO2ZAKTj/3yRemKK4PhnA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/i18n": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.4.0.tgz", - "integrity": "sha512-58rgcUA9PGQsTzvp6jJxQ+uzTKk7wzzfLmA/jz7MKglrWi1AANaae5NExe+63/AC9/e2srV7baKNUWmak/UGAQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", "gettext-parser": "^1.3.1", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "memize": "^1.0.5", "sprintf-js": "^1.1.1", - "tannin": "^1.0.1" + "tannin": "^1.1.0" } }, "@wordpress/is-shallow-equal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.3.0.tgz", - "integrity": "sha512-NVMeS7mP/7VCZQmq0L88BrPJ5OlzcImhyGp+zk4nCeD3LhO2VNGyAmnFQtbR500C0xjBugF7wTscoTJM6Z7ZCg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/jest-console": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.1.0.tgz", - "integrity": "sha512-6ofKMrGnmDFUnc9zdxN8AfuD3IDrf4THnvJ2QEvz71FVZZbFRLlFZOGs4O/IFmPPOMa/0/lGvTEJr9THZ44wBw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.2.0.tgz", + "integrity": "sha512-WZl2eJH9g+OSTrFPpAKSCT7Pl7rvwatPnBm1Z4kpPZdOQDbF3w2a6yzfpjtBBD2BVEqHsaLAxn0jC6xHkqbAxw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", "jest-matcher-utils": "^24.7.0", - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "@wordpress/jest-preset-default": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-4.1.0.tgz", - "integrity": "sha512-eGV1UwfKiHNpqw78YbxXIpe0ia99Rd9Hn5IqnSJJGtQ6ObhenJC4iVKEtAPvvranHajkZGxMGvhvvH0B9KYm0Q==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-4.3.0.tgz", + "integrity": "sha512-b8rucE3e7+VkD/gX9pB6c9ZysjUAOfNG2Lcp8OLtfzWvlzMkuJtl7+9P/D6GAWk2GEK54GdM018vl3IM5HkaHg==", "dev": true, "requires": { - "@wordpress/jest-console": "^3.1.0", + "@wordpress/jest-console": "^3.2.0", "babel-jest": "^24.7.1", "enzyme": "^3.9.0", "enzyme-adapter-react-16": "^1.10.0", @@ -2074,67 +4054,285 @@ } }, "@wordpress/keycodes": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.3.0.tgz", - "integrity": "sha512-iutKSqHcvhxEvkV/QjgOXlWi/FLaOTtRumQtGxXd7eb8fDqs+8LmhExNn4dw6QJ+vvY+sjUnJh8121eTzCmPjw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.5.0.tgz", + "integrity": "sha512-4SMN3pmJnNBexpd3/6JB6gJw+wcahBaVZaeMcHyF+Uw7bKcG6hDkzEAN6dWFJuifpdxmvilDE4H5JS/Ex9C6sA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/i18n": "^3.4.0", - "lodash": "^4.17.11" + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/media-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-1.0.0.tgz", + "integrity": "sha512-HjleyNFc+toqeznm8KnR/JhAfDki08FhxZj3/3uksxA4HSJ3Qq6cNc46GlxCCNy7cGhSAsmYrATEsbq3s4IhAA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/blob": "^2.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + }, + "dependencies": { + "@wordpress/api-fetch": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.4.0.tgz", + "integrity": "sha512-aNLVIXlnn7RIEzbDcVFhyQfV60O0ggLQOCkHhMCW1Ya86Jlohp658TXe8wIjFhC2ugY239WeZIl1tgoRjqIr0A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + } } }, "@wordpress/notices": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-1.4.0.tgz", - "integrity": "sha512-v88VsEPtcktZriCKr6YW90xYxFgELF6mDMGrXgRviZwRm8Yfubto1Q0DnWFgYV1U8GXgZio95+A1HjZ+/TG32g==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-1.6.0.tgz", + "integrity": "sha512-CXJUHye/qGJo3MF3YC/AwKrFz8X5zEuaD6I1pOoOVVxpLZNMDgA2QqEbxb7X66bedBrh9akFYoNdGwS11KSsKg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/a11y": "^2.3.0", - "@wordpress/data": "^4.5.0", - "lodash": "^4.17.11" + "@wordpress/a11y": "^2.5.0", + "@wordpress/data": "^4.7.0", + "lodash": "^4.17.14" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + } } }, "@wordpress/npm-package-json-lint-config": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-1.3.0.tgz", - "integrity": "sha512-3BlWs7FJms0AOu8vsm2VEmNcIM+tlSgich0AaDPPn/nY0j2knJNNGupDUA9/vmYssvufI/uCTJRq84FHQCOmGA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-2.1.0.tgz", + "integrity": "sha512-NSwcK7GtlmW5O5ZMG7elRKBa9sPws17Sadjlztig6ShOuhlLFeHYk99tUenpmJ/PYOZex4fSJ5e9mqjPyKunjw==", "dev": true }, "@wordpress/nux": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/nux/-/nux-3.3.0.tgz", - "integrity": "sha512-zvFt54+cZ1xq+RqpXyJ5OLAkR7948NjpmF6heT5XTnm27FnagRqF5JMOliOM2ALUGIvTubmnMjaY0CGNGTjUbA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/nux/-/nux-3.5.0.tgz", + "integrity": "sha512-PJJweT8/cNQvaFlrf8+jgntHouSu3Gf/OH8ZlICuF73W5Om9M+1Or4eaCS5wGjV1G014dxQBR/S2ydEio37NOw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/components": "^7.4.0", - "@wordpress/compose": "^3.3.0", - "@wordpress/data": "^4.5.0", - "@wordpress/element": "^2.4.0", - "@wordpress/i18n": "^3.4.0", - "lodash": "^4.17.11", + "@wordpress/components": "^8.1.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14", "rememo": "^3.0.0" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + }, + "@wordpress/components": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-8.1.0.tgz", + "integrity": "sha512-V35ZyDIVadVQQhKB6IyGULdMfi+44KLL6K0FL2gVihLxHq1P0g3sC6kE26DmYNcYXYfhyGMZT440nkUi1jEo3A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/url": "^2.7.0", + "classnames": "^2.2.5", + "clipboard": "^2.0.1", + "diff": "^3.5.0", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "moment": "^2.22.1", + "mousetrap": "^1.6.2", + "re-resizable": "^5.0.1", + "react-click-outside": "^3.0.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^3.3.2" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.5.0.tgz", + "integrity": "sha512-+nsYv5AdX7Oj9gVHvtDIQSE9gntrJwA5FpXSEVlZ2u2E5lhjGQS+a+IrRhxZL/7f2eKby5zvQV6vYCrqMtKxYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/i18n": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.6.0.tgz", + "integrity": "sha512-/fkc5OoUCrIyHAaBEKIsXKl+UWj2kKjquhMSSHu3eVqLv/WKrKAzypPPAZC9UXfdSVBY8MrORYLh7vUy9Ic3Vw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "sprintf-js": "^1.1.1", + "tannin": "^1.1.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/keycodes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.5.0.tgz", + "integrity": "sha512-4SMN3pmJnNBexpd3/6JB6gJw+wcahBaVZaeMcHyF+Uw7bKcG6hDkzEAN6dWFJuifpdxmvilDE4H5JS/Ex9C6sA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/i18n": "^3.6.0", + "lodash": "^4.17.14" + } + }, + "@wordpress/rich-text": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "rememo": "^3.0.0" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "re-resizable": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-5.0.1.tgz", + "integrity": "sha512-Iy8v5li7bhNBDxCN1DbA4l6G2Hk8NCZtcExoI1D+5pfvKyQcH8LH2P5h3DGoEfHhs0uyyRC1Qx8bHBomfrmxgA==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" + } + } } }, "@wordpress/plugins": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-2.3.0.tgz", - "integrity": "sha512-37teeXdcPQt2yEwV+i3pTI2ePm4b0earVJoojuaKGxwy3ya6EOyx6sNvbxkJbnx6+5bmIHWxzZw2SPoNfXbfaA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-2.5.0.tgz", + "integrity": "sha512-RnILA/bl7w3joov61/sliyODN1MFJIGYgfwv20hkmjirmM/q531T4Mzp7FOPiEBn6mqt+gGo4CuGAe8o+oP/Vw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/compose": "^3.3.0", - "@wordpress/element": "^2.4.0", - "@wordpress/hooks": "^2.3.0", - "lodash": "^4.17.11" + "@wordpress/compose": "^3.5.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "lodash": "^4.17.14" } }, "@wordpress/postcss-themes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@wordpress/postcss-themes/-/postcss-themes-2.1.0.tgz", - "integrity": "sha512-hdwGorQF6Od++fmEtNoMQ9kjG0KcdBCFryjnpP2esU1wSyJdOzGA27AB1vkQVW8q3XTmTyN8f6CS75ZjJr9sFQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/postcss-themes/-/postcss-themes-2.2.0.tgz", + "integrity": "sha512-KLbd1i3vpF7B8ZTfw13GPlEvvQqL1aJWdnXt8WJtrwg1DplyL9+8Ar6VtPlq9fZsXUl+Os4YxeSN6pbswOeNeQ==", "dev": true, "requires": { "autoprefixer": "^9.4.5", @@ -2143,18 +4341,18 @@ } }, "@wordpress/priority-queue": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-1.2.0.tgz", - "integrity": "sha512-po70nJhWK3oBhc9D/rBv2RFsX9do7fIABdUSVNAFQ+vRnatxlZTxJ6z8A2rtY71tiV244qgy3In6H7n1i6QO7A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-1.3.0.tgz", + "integrity": "sha512-HlhHZUCnKW56b2KFg2cZcn6fnGdi6mrmfOn2lE3cBOibjQLYfOY3pe3TCd+AxS4GdfkgXFA7BHfAinaWCBpAyg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4" } }, "@wordpress/redux-routine": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-3.3.0.tgz", - "integrity": "sha512-/6QUXBqVAgI9ew9Oec6c6/6MA9MTqMV89Tn6B6ZIDUuXavINSaeBDMMX8a/FBPvzbODOVfwTyhlOCz3lNiG22g==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-3.5.0.tgz", + "integrity": "sha512-fssGjVcXlNFbAIjv6VhCWZYgsv51sugxxCgxAqgSIexsDVnOphDODo5V5bhcgwiZeL3/n5rzqvFQ7Dv4agvc/A==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", @@ -2163,31 +4361,39 @@ } }, "@wordpress/rich-text": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.3.0.tgz", - "integrity": "sha512-vEBBgTHUTKVoYhNuXP1rF7GKOgZY6S4U7G8+sBBltJKPOO4OSfUynDCrJfvPKuXdXkGjeuxEZjGYs6Cu03ZCzg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/compose": "^3.3.0", - "@wordpress/data": "^4.5.0", - "@wordpress/escape-html": "^1.3.0", - "@wordpress/hooks": "^2.3.0", - "lodash": "^4.17.11", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", "rememo": "^3.0.0" } }, "@wordpress/scripts": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-3.2.1.tgz", - "integrity": "sha512-GrOTew6JcRKTTfy/512Wc/dX2xcTQccw04OPJHjfMmp1zU1V/Y1SODSdD5KacygYnBza1NKher6QBP6wKyBF8w==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-3.4.0.tgz", + "integrity": "sha512-PPOXYLLnqdxc/w0BU7YpJoa2G14WbukeWZGavjiYl98l5x4QO6Ddpo31D8Ev+kBMkmIWeyO7Pmgj0flrg8Vd/w==", "dev": true, "requires": { - "@wordpress/babel-preset-default": "^4.2.0", - "@wordpress/dependency-extraction-webpack-plugin": "^1.0.1", - "@wordpress/eslint-plugin": "^2.2.0", - "@wordpress/jest-preset-default": "^4.1.0", - "@wordpress/npm-package-json-lint-config": "^1.3.0", + "@wordpress/babel-preset-default": "^4.4.0", + "@wordpress/dependency-extraction-webpack-plugin": "^1.1.0", + "@wordpress/eslint-plugin": "^2.4.0", + "@wordpress/jest-preset-default": "^4.3.0", + "@wordpress/npm-package-json-lint-config": "^2.1.0", + "babel-jest": "^24.7.1", "babel-loader": "^8.0.5", "chalk": "^2.4.1", "check-node-version": "^3.1.1", @@ -2195,6 +4401,7 @@ "eslint": "^5.16.0", "jest": "^24.7.1", "jest-puppeteer": "^4.0.0", + "minimist": "^1.2.0", "npm-package-json-lint": "^3.6.0", "puppeteer": "1.6.1", "read-pkg-up": "^1.0.1", @@ -2204,7 +4411,7 @@ "stylelint-config-wordpress": "^13.1.0", "thread-loader": "^2.1.2", "webpack": "4.8.3", - "webpack-bundle-analyzer": "^3.0.3", + "webpack-bundle-analyzer": "^3.3.2", "webpack-cli": "^3.1.2", "webpack-livereload-plugin": "^2.2.0" }, @@ -2219,6 +4426,17 @@ "@webassemblyjs/wast-parser": "1.4.3", "debug": "^3.1.0", "webassemblyjs": "1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@webassemblyjs/floating-point-hex-parser": { @@ -2234,6 +4452,17 @@ "dev": true, "requires": { "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@webassemblyjs/helper-code-frame": { @@ -2268,6 +4497,17 @@ "@webassemblyjs/helper-wasm-bytecode": "1.4.3", "@webassemblyjs/wasm-gen": "1.4.3", "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@webassemblyjs/leb128": { @@ -2294,6 +4534,17 @@ "@webassemblyjs/wasm-parser": "1.4.3", "@webassemblyjs/wast-printer": "1.4.3", "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@webassemblyjs/wasm-gen": { @@ -2318,6 +4569,17 @@ "@webassemblyjs/wasm-gen": "1.4.3", "@webassemblyjs/wasm-parser": "1.4.3", "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "@webassemblyjs/wasm-parser": { @@ -2364,34 +4626,109 @@ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", "dev": true }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "chrome-trace-event": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", + "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", "dev": true, "requires": { - "acorn": "^5.0.0" + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } } }, - "chrome-trace-event": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", - "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { - "ms": "^2.1.1" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "schema-utils": { @@ -2432,35 +4769,184 @@ "uglifyjs-webpack-plugin": "^1.2.4", "watchpack": "^1.5.0", "webpack-sources": "^1.0.1" + }, + "dependencies": { + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + } + } + }, + "@wordpress/server-side-render": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.1.0.tgz", + "integrity": "sha512-bSRHXfJozVzZSbkDSmhfBO/EuwebSLNvuBi/S0XrPA7lIJgqysZVPjSd7Z21qMnlKasF1N21lL7Dn1z2W/sMVQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/api-fetch": "^3.4.0", + "@wordpress/components": "^8.1.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/url": "^2.7.0", + "lodash": "^4.17.14" + }, + "dependencies": { + "@wordpress/a11y": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.5.0.tgz", + "integrity": "sha512-KY+Z0NFQUH6cNbFnP9P58fTCLS93zBz+SIEDA633yG46u1NHOBfWDS4lIrx52fihFdaakSTS0f2OH6yeRb41HQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/dom-ready": "^2.5.0" + } + }, + "@wordpress/components": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-8.1.0.tgz", + "integrity": "sha512-V35ZyDIVadVQQhKB6IyGULdMfi+44KLL6K0FL2gVihLxHq1P0g3sC6kE26DmYNcYXYfhyGMZT440nkUi1jEo3A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/a11y": "^2.5.0", + "@wordpress/compose": "^3.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/i18n": "^3.6.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "@wordpress/rich-text": "^3.5.0", + "@wordpress/url": "^2.7.0", + "classnames": "^2.2.5", + "clipboard": "^2.0.1", + "diff": "^3.5.0", + "dom-scroll-into-view": "^1.2.1", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "moment": "^2.22.1", + "mousetrap": "^1.6.2", + "re-resizable": "^5.0.1", + "react-click-outside": "^3.0.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^3.3.2" + } + }, + "@wordpress/dom": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.4.0.tgz", + "integrity": "sha512-8hcHi5iHgi1Z/1G6ti04bgsiYBDNlR05X7MiosjwP8U/iTmcRwKrmtA1X6qzsMlOgvJ3MetoLqGZb3lCjLtXmw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "lodash": "^4.17.14" + } + }, + "@wordpress/escape-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.5.0.tgz", + "integrity": "sha512-9jGwPbpdJ309EP4Acf6/zwHWeuYi0Bi5RAZx9q+BIYC7bjxLs3oFDS5QkEAi2mzrVAhIz+BbEWBGRg70U1RLlA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/is-shallow-equal": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-1.5.0.tgz", + "integrity": "sha512-6GjIDZlwcgLmnt1uexUgnIj3zbzCPCtqe5vTqmsQeexC4zCIzgFJgzilOuuW/4kdwF/XB3jex91L9EImc5HTcw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4" + } + }, + "@wordpress/rich-text": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.5.0.tgz", + "integrity": "sha512-2Pi56SGcao0M0OjZtpwdIyYIXganIDg054InPpdE7zeJRUxf8gKvTGSXA2bYLdDJC0RgCLTtWp+45ItV6byZDg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/deprecated": "^2.5.0", + "@wordpress/dom": "^2.4.0", + "@wordpress/element": "^2.6.0", + "@wordpress/escape-html": "^1.5.0", + "@wordpress/hooks": "^2.5.0", + "@wordpress/is-shallow-equal": "^1.5.0", + "@wordpress/keycodes": "^2.5.0", + "classnames": "^2.2.5", + "lodash": "^4.17.14", + "memize": "^1.0.5", + "rememo": "^3.0.0" + } + }, + "@wordpress/url": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.4", + "qs": "^6.5.2" + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "re-resizable": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-5.0.1.tgz", + "integrity": "sha512-Iy8v5li7bhNBDxCN1DbA4l6G2Hk8NCZtcExoI1D+5pfvKyQcH8LH2P5h3DGoEfHhs0uyyRC1Qx8bHBomfrmxgA==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" } } } }, "@wordpress/shortcode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-2.3.0.tgz", - "integrity": "sha512-JVsykCMc1pvEnqM9Q+xOj1qTUCCtY0c5yOtXWMAEpyeDni99p/eROH2AIUW6hKzqSWTlAJSBLIoDR9Ih4YbcxQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-2.4.0.tgz", + "integrity": "sha512-v9x7KPD39dxmnz9rn9LatrfP3SjWYBPnNVrEmLACXTGOe4XCmx1jfKdE4NlplJ5POq5tvCxcqG07bsKYfj4Dyw==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "memize": "^1.0.5" } }, "@wordpress/token-list": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-1.3.0.tgz", - "integrity": "sha512-/fN9cOuQbyQE4ULvIFFwGMZ5gO70EbEZQKCRQInGMAIlMXdEYU2qG5+yByEC2u/HR0SXQ6mJquckyx6SDlk6ow==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-1.5.0.tgz", + "integrity": "sha512-JamANQZLdv2WgmPd0ZumjzmzPoPjbZTWef2W2kuvNHvoLNO9yVulR754qdR/wGPBYEf5sDC3E2D3Vb/zgVEw7A==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "@wordpress/url": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.6.0.tgz", - "integrity": "sha512-QlC/T6VsIMhArKdYvO1sVEUZYuky+5UojHU1vfZgLNZtt2Tj1dOgP4teMaDhMZtc6FqDkHNiA8r03CvXtbNDQA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.7.0.tgz", + "integrity": "sha512-W1KEyllal8YWbLMyqfbPw7pQzVsJh73RQyqElrPwZ84TPeH/1JilKVMgKb2RXgJw8q8I+gZIXi6GmVY0+WNAxg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", @@ -2468,26 +4954,26 @@ } }, "@wordpress/viewport": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.4.0.tgz", - "integrity": "sha512-PTWvCJrpAy2Avs3GhkwRvj+aebv83rAb4gsnZOl0VU0YMdLOOgwc/l+p6ieFVUNuncfES6lLT6pP3UNgOJzpRQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.6.0.tgz", + "integrity": "sha512-mnUu/SbwrW949AgOODDFLcbLUM/Qhlbi0qZ4JN5c/nOEukru5NRuktvyPPzcd9wWAeNVlqTSpq6E8ES+65ureg==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "@wordpress/compose": "^3.3.0", - "@wordpress/data": "^4.5.0", - "@wordpress/element": "^2.4.0", - "lodash": "^4.17.11" + "@wordpress/compose": "^3.5.0", + "@wordpress/data": "^4.7.0", + "@wordpress/element": "^2.6.0", + "lodash": "^4.17.14" } }, "@wordpress/wordcount": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.3.0.tgz", - "integrity": "sha512-ztXw7/4a51OJ/nZUCJDagvpKOf7BnLxVzfNfDaRXv6rvCI/bEVXWRMfQqjXWkbPxUSSVYcxyTUdru3B6YGxyHA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.5.0.tgz", + "integrity": "sha512-Du/O50ZBpl5Pq/MevUZHQg0FBpT6v/SRhSV8lF5ByjZfXelUcQGN+gQ6RmNdasQ33KVPmspdCQHnQ+sThm4/iA==", "dev": true, "requires": { "@babel/runtime": "^7.4.4", - "lodash": "^4.17.11" + "lodash": "^4.17.14" } }, "@xtuc/ieee754": { @@ -2525,21 +5011,32 @@ } }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz", + "integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==", "dev": true }, "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + } + } }, "acorn-globals": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", - "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.3.tgz", + "integrity": "sha512-vkR40VwS2SYO98AIeFvzWWh+xyc2qi9s7OoXSFEGIP/rOJKzjnhykaZJNnHdoq4BL2gGxI5EZOU16z896EYnOQ==", "dev": true, "requires": { "acorn": "^6.0.1", @@ -2553,15 +5050,15 @@ "dev": true }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -2776,13 +5273,13 @@ "dev": true }, "array.prototype.find": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", - "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.0.tgz", + "integrity": "sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.13.0" } }, "array.prototype.flat": { @@ -2895,9 +5392,9 @@ "dev": true }, "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, "asynckit": { @@ -2913,84 +5410,288 @@ "dev": true }, "autoprefixer": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.0.tgz", - "integrity": "sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz", + "integrity": "sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==", "dev": true, "requires": { - "browserslist": "^4.6.1", - "caniuse-lite": "^1.0.30000971", + "browserslist": "^4.6.3", + "caniuse-lite": "^1.0.30000980", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.16", - "postcss-value-parser": "^3.3.1" + "postcss": "^7.0.17", + "postcss-value-parser": "^4.0.0" }, "dependencies": { "caniuse-lite": { - "version": "1.0.30000971", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000971.tgz", - "integrity": "sha512-TQFYFhRS0O5rdsmSbF1Wn+16latXYsQJat66f7S7lizXW1PVpWJeZw9wqqVLIjuxDRz7s7xRUj13QCfd8hKn6g==", + "version": "1.0.30000980", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000980.tgz", + "integrity": "sha512-as0PRtWHaX3gl2gpC7qA7bX88lr+qLacMMXm1QKLLQtBCwT/Ljbgrv5EXKMNBoeEX6yFZ4vIsBb4Nh+PEwW2Rw==", "dev": true + }, + "postcss-value-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz", + "integrity": "sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==", + "dev": true + } + } + }, + "autosize": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.2.tgz", + "integrity": "sha512-jnSyH2d+qdfPGpWlcuhGiHmqBJ6g3X+8T+iRwFrHPLVcdoGJE/x6Qicm6aDHfTsbgZKxyV8UU/YB2p4cjKDRRA==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "babel-eslint": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.2.tgz", + "integrity": "sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "^1.0.0" + } + }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + }, + "dependencies": { + "@jest/console": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", + "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "dev": true, + "requires": { + "@jest/source-map": "^24.9.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/fake-timers": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", + "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/source-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@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==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.9.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "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", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@types/yargs": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.2.tgz", + "integrity": "sha512-lwwgizwk/bIIU+3ELORkyuOgDjCh7zuWDFqRtPPhhVgq9N1F7CvLNKg1TX4f2duwtKQ0p044Au9r1PLIXHrIzQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "jest-haste-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", + "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.9.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", + "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0" + } + }, + "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==", + "dev": true + }, + "jest-serializer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "dev": true + }, + "jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "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 + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, - "autosize": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.2.tgz", - "integrity": "sha512-jnSyH2d+qdfPGpWlcuhGiHmqBJ6g3X+8T+iRwFrHPLVcdoGJE/x6Qicm6aDHfTsbgZKxyV8UU/YB2p4cjKDRRA==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7" - } - }, - "babel-eslint": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz", - "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "^1.0.0" - } - }, - "babel-jest": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.8.0.tgz", - "integrity": "sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw==", - "dev": true, - "requires": { - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.6.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" - } - }, "babel-loader": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", @@ -3003,6 +5704,15 @@ "pify": "^4.0.1" } }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, "babel-plugin-inline-react-svg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-inline-react-svg/-/babel-plugin-inline-react-svg-1.1.0.tgz", @@ -3073,9 +5783,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz", - "integrity": "sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", "dev": true, "requires": { "@types/babel__traverse": "^7.0.6" @@ -3088,13 +5798,13 @@ "dev": true }, "babel-preset-jest": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz", - "integrity": "sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", "dev": true, "requires": { "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.6.0" + "babel-plugin-jest-hoist": "^24.9.0" } }, "babel-runtime": { @@ -3108,9 +5818,9 @@ }, "dependencies": { "core-js": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.7.tgz", - "integrity": "sha512-ydmsQxDVH7lDpYoirXft8S83ddKKfdsrsmWhtyj7xafXVLbLhKOyfD7kAi2ueFfeP7m9rNavjW59O3hLLzzC5A==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", "dev": true }, "regenerator-runtime": { @@ -3204,15 +5914,15 @@ } }, "bfj": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.1.tgz", - "integrity": "sha512-+GUNvzHR4nRyGybQc2WpNJL4MJazMuvf92ueIyA0bIkPRwhhQu3IfZQ2PSoVPpCBJfmoSdOxu5rnotfFLlvYRQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", "dev": true, "requires": { - "bluebird": "^3.5.1", - "check-types": "^7.3.0", - "hoopy": "^0.1.2", - "tryer": "^1.0.0" + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" } }, "big.js": { @@ -3228,9 +5938,9 @@ "dev": true }, "bluebird": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", - "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", "dev": true }, "bn.js": { @@ -3445,28 +6155,28 @@ } }, "browserslist": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.2.tgz", - "integrity": "sha512-2neU/V0giQy9h3XMPwLhEY3+Ao0uHSwHvU8Q1Ea6AgLVL1sXbX3dzPrJ8NWe5Hi4PoTkCYXOtVR9rfRLI0J/8Q==", + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000974", - "electron-to-chromium": "^1.3.150", - "node-releases": "^1.1.23" + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" }, "dependencies": { "caniuse-lite": { - "version": "1.0.30000974", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz", - "integrity": "sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww==", + "version": "1.0.30000984", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000984.tgz", + "integrity": "sha512-n5tKOjMaZ1fksIpQbjERuqCyfgec/m9pferkFQbLmWtqLUdmt12hNhjSwsmPdqeiG2NkITOQhr1VYIwWSAceiA==", "dev": true } } }, "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", + "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", "dev": true, "requires": { "node-int64": "^0.4.0" @@ -3508,22 +6218,23 @@ "dev": true }, "cacache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", + "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", "dev": true, "requires": { - "bluebird": "^3.5.3", + "bluebird": "^3.5.5", "chownr": "^1.1.1", "figgy-pudding": "^3.5.1", - "glob": "^7.1.3", + "glob": "^7.1.4", "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", + "rimraf": "^2.6.3", "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" @@ -3637,9 +6348,9 @@ } }, "caniuse-lite": { - "version": "1.0.30000969", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000969.tgz", - "integrity": "sha512-Kus0yxkoAJgVc0bax7S4gLSlFifCa7MnSZL9p9VuS/HIKEL4seaqh28KIQAAO50cD/rJ5CiJkJFapkdDAlhFxQ==", + "version": "1.0.30000979", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000979.tgz", + "integrity": "sha512-gcu45yfq3B7Y+WB05fOMfr0EiSlq+1u+m6rPHyJli/Wy3PVQNGaU7VA4bZE5qw+AU2UVOBR/N5g1bzADUqdvFw==", "dev": true }, "capture-exit": { @@ -3728,9 +6439,9 @@ } }, "check-types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz", - "integrity": "sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", "dev": true }, "cheerio": { @@ -3768,9 +6479,9 @@ } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "chrome-trace-event": { @@ -4089,6 +6800,12 @@ "typedarray": "^0.0.6" } }, + "consola": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.10.0.tgz", + "integrity": "sha512-CofUpEOdOu5skHYgI/JEYa4qY9Z07ldLFWeQaOHed+mbSxolLQRz7UbF9gdxZCeR3aUOXJDIQo285+WIN0zEig==", + "dev": true + }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", @@ -4110,6 +6827,12 @@ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -4173,34 +6896,34 @@ "dev": true }, "core-js": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.3.tgz", - "integrity": "sha512-PWZ+ZfuaKf178BIAg+CRsljwjIMRV8MY00CbZczkR6Zk5LfkSkjGoaab3+bqRQWVITNZxQB7TFYz+CFcyuamvA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz", + "integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==", "dev": true }, "core-js-compat": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.1.tgz", - "integrity": "sha512-RH3kv8NFovFRMdeTEUgu8nMquEWKEVttOY3JFi8mN75sg72zygPqWbpWNTUw4JYEU43562tlzhdWsWqXmdFAnQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.4.tgz", + "integrity": "sha512-Z5zbO9f1d0YrJdoaQhphVAnKPimX92D6z8lCGphH89MNRxlL1prI9ExJPqVwP0/kgkQCv8c4GJGT8X16yUncOg==", "dev": true, "requires": { - "browserslist": "^4.6.0", - "core-js-pure": "3.1.1", - "semver": "^6.0.0" + "browserslist": "^4.6.2", + "core-js-pure": "3.1.4", + "semver": "^6.1.1" }, "dependencies": { "semver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", - "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "core-js-pure": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.1.tgz", - "integrity": "sha512-jH3ZJ0CJ0wwDvWY0olbOComLo6tbWg4kE2x0j4+wlqYnofwF9mYm98YvADuENUzGw69IddmWFCF1FQ2S0jP96A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.4.tgz", + "integrity": "sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA==", "dev": true }, "core-util-is": { @@ -4368,9 +7091,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -4421,9 +7144,9 @@ } }, "css-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.0.0.tgz", - "integrity": "sha512-WR6KZuCkFbnMhRrGPlkwAA7SSCtwqPwpyXJAPhotYkYsc0mKU9n/fu5wufy4jl2WhBw9Ia8gUQMIp/1w98DuPw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.2.0.tgz", + "integrity": "sha512-QTF3Ud5H7DaZotgdcJjGMvyDj5F3Pn1j/sC6VBEOVp94cbwqyIBdcs/quzj4MC1BKQSrTpQznegH/5giYbhnCQ==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -4437,7 +7160,7 @@ "postcss-modules-scope": "^2.1.0", "postcss-modules-values": "^3.0.0", "postcss-value-parser": "^4.0.0", - "schema-utils": "^1.0.0" + "schema-utils": "^2.0.0" }, "dependencies": { "camelcase": { @@ -4447,10 +7170,20 @@ "dev": true }, "postcss-value-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz", - "integrity": "sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.1.tgz", + "integrity": "sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A==", "dev": true + }, + "schema-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.0.1.tgz", + "integrity": "sha512-HJFKJ4JixDpRur06QHwi8uu2kZbng318ahWEKgBjc0ZklcE4FDvmm2wghb448q0IRaABxIESt8vqPFvwgMB80A==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } } } }, @@ -4609,15 +7342,15 @@ } }, "cssom": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", - "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, "cssstyle": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", - "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", "dev": true, "requires": { "cssom": "0.3.x" @@ -5001,9 +7734,9 @@ } }, "dom-scroll-into-view": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", - "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz", + "integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==" }, "dom-serializer": { "version": "0.1.1", @@ -5099,21 +7832,21 @@ "dev": true }, "ejs": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", - "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz", + "integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q==", "dev": true }, "electron-to-chromium": { - "version": "1.3.150", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.150.tgz", - "integrity": "sha512-5wuYlaXhXbBvavSTij5ZyidICB6sAK/1BwgZZoPCgsniid1oDgzVvDOV/Dw6J25lKV9QZ9ZdQCp8MEfF0/OIKA==", + "version": "1.3.191", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.191.tgz", + "integrity": "sha512-jasjtY5RUy/TOyiUYM2fb4BDaPZfm6CXRFeJDMfFsXYADGxUN49RBqtgB7EL2RmJXeIRUk9lM1U6A5yk2YJMPQ==", "dev": true }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -5208,9 +7941,9 @@ } }, "enzyme-adapter-react-16": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.13.1.tgz", - "integrity": "sha512-DCKbkiVlfLTbn4SXO8mXDQx1SmmwON5oKXn2QfQSMCt8eTYGwUXy/OBGSuss6KKwY5w5QfK1sQFxhgFOkMCjrw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.14.0.tgz", + "integrity": "sha512-7PcOF7pb4hJUvjY7oAuPGpq3BmlCig3kxXGi2kFx0YzJHppqX1K8IIV9skT1IirxXlu8W7bneKi+oQ10QRnhcA==", "dev": true, "requires": { "enzyme-adapter-utils": "^1.12.0", @@ -5220,7 +7953,7 @@ "prop-types": "^15.7.2", "react-is": "^16.8.6", "react-test-renderer": "^16.0.0-0", - "semver": "^5.6.0" + "semver": "^5.7.0" } }, "enzyme-adapter-utils": { @@ -5238,12 +7971,12 @@ } }, "enzyme-to-json": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.3.5.tgz", - "integrity": "sha512-DmH1wJ68HyPqKSYXdQqB33ZotwfUhwQZW3IGXaNXgR69Iodaoj8TF/D9RjLdz4pEhGq2Tx2zwNUIjBuqoZeTgA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.4.0.tgz", + "integrity": "sha512-gbu8P8PMAtb+qtKuGVRdZIYxWHC03q1dGS3EKRmUzmTDIracu3o6cQ0d4xI2YWojbelbxjYOsmqM5EgAL0WgIA==", "dev": true, "requires": { - "lodash": "^4.17.4" + "lodash": "^4.17.12" } }, "equivalent-key-map": { @@ -5306,9 +8039,9 @@ } }, "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", "dev": true }, "es6-promisify": { @@ -5361,49 +8094,56 @@ } }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", + "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", + "ajv": "^6.10.0", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", + "eslint-scope": "^5.0.0", "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", + "espree": "^6.0.0", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", + "glob-parent": "^5.0.0", "globals": "^11.7.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", "progress": "^2.0.0", "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", "table": "^5.2.3", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -5415,6 +8155,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "debug": { @@ -5436,35 +8184,217 @@ } }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, + "espree": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", + "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", + "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-eslint-comments": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.2.tgz", + "integrity": "sha512-QexaqrNeteFfRTad96W+Vi4Zj1KFbkHHNMMaHZEYcovKav6gdomyGzaxSDSL3GoIyUOo078wRAdYlu1caiauIQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "ignore": "^5.0.5" + }, + "dependencies": { + "ignore": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } } } }, "eslint-plugin-jest": { - "version": "22.6.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.6.4.tgz", - "integrity": "sha512-36OqnZR/uMCDxXGmTsqU4RwllR0IiB/XF8GW3ODmhsjiITKuI0GpgultWFt193ipN3HARkaIcKowpE6HBvRHNg==", - "dev": true + "version": "22.15.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.15.2.tgz", + "integrity": "sha512-p4NME9TgXIt+KgpxcXyNBvO30ZKxwFAO1dJZBc2OGfDnXVEtPwEyNs95GSr6RIE3xLHdjd8ngDdE2icRRXrbxg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^1.13.0" + } }, "eslint-plugin-jsx-a11y": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz", - "integrity": "sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", "dev": true, "requires": { + "@babel/runtime": "^7.4.5", "aria-query": "^3.0.0", "array-includes": "^3.0.3", "ast-types-flow": "^0.0.7", @@ -5472,28 +8402,30 @@ "damerau-levenshtein": "^1.0.4", "emoji-regex": "^7.0.2", "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1" + "jsx-ast-utils": "^2.2.1" } }, "eslint-plugin-react": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz", - "integrity": "sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", + "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", "dev": true, "requires": { "array-includes": "^3.0.3", "doctrine": "^2.1.0", "has": "^1.0.3", "jsx-ast-utils": "^2.1.0", + "object.entries": "^1.1.0", "object.fromentries": "^2.0.0", + "object.values": "^1.1.0", "prop-types": "^15.7.2", "resolve": "^1.10.1" } }, "eslint-plugin-react-hooks": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.0.tgz", - "integrity": "sha512-lHBVRIaz5ibnIgNG07JNiAuBUeKhEf8l4etNx5vfAEwqQ5tcuK3jV9yjmopPgQDagQb7HwIuQVsE3IVcGrRnag==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.1.tgz", + "integrity": "sha512-wHhmGJyVuijnYIJXZJHDUF2WM+rJYTjulUTqF9k61d3BTk8etydz+M4dXUVH7M76ZRS85rqBTCx0Es/lLsrjnA==", "dev": true }, "eslint-scope": { @@ -5688,15 +8620,15 @@ } }, "expect-puppeteer": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/expect-puppeteer/-/expect-puppeteer-4.1.1.tgz", - "integrity": "sha512-xNpu6uYJL9Qrrp4Z31MOpDWK68zAi+2qg5aMQlyOTVZNy7cAgBZiPvKCN0C1JmP3jgPZfcxhetVjZLaw/KcJOQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/expect-puppeteer/-/expect-puppeteer-4.3.0.tgz", + "integrity": "sha512-p8N/KSVPG9PAOJlftK5f1n3JrULJ6Qq1EQ8r/n9xzkX2NmXbK8PcnJnkSAEzEHrMycELKGnlJV7M5nkgm+wEWA==", "dev": true }, "express": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.0.tgz", - "integrity": "sha512-1Z7/t3Z5ZnBG252gKUPyItc4xdeaA0X934ca2ewckAsVsw9EG71i++ZHZPYnus8g/s5Bty8IMpSVEuRkmwwPRQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "requires": { "accepts": "~1.3.7", @@ -5890,6 +8822,12 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-memoize": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.1.tgz", + "integrity": "sha512-xdmw296PCL01tMOXx9mdJSmWY29jQgxyuZdq0rEHMu+Tpe1eOEtCycoG6chzlcrWsNgpZP7oL8RiQr7+G6Bl6g==", + "dev": true + }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -6051,9 +8989,9 @@ } }, "find-process": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.1.tgz", - "integrity": "sha512-RkYWDeukxEoDKUyocqMGKAYuwhSwq77zL99gCqhX9czWon3otdlzihJ0MSZ6YWNKHyvS/MN2YR4+RGYOuIEANg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.2.tgz", + "integrity": "sha512-O83EVJr4dWvHJ7QpUzANNAMeQVKukRzRqRx4AIzdLYRrQorRdbqDwLPigkd9PYPhJRhmNPAoVjOm9bcwSmcZaw==", "dev": true, "requires": { "chalk": "^2.0.1", @@ -6095,13 +9033,13 @@ } }, "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", "dev": true, "requires": { "detect-file": "^1.0.0", - "is-glob": "^3.1.0", + "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" }, @@ -6139,15 +9077,6 @@ "which": "^1.2.14" } }, - "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" - } - }, "resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", @@ -6172,9 +9101,9 @@ } }, "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, "flatten": { @@ -7050,9 +9979,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", "dev": true }, "growly": { @@ -7447,12 +10376,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hoek": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", - "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", - "dev": true - }, "hoist-non-react-statics": { "version": "2.5.5", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", @@ -7549,9 +10472,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", - "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -7572,12 +10495,20 @@ "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } } }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", "dev": true }, "http-signature": { @@ -7598,12 +10529,12 @@ "dev": true }, "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", + "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", "dev": true, "requires": { - "agent-base": "^4.1.0", + "agent-base": "^4.3.0", "debug": "^3.1.0" }, "dependencies": { @@ -7617,9 +10548,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -7670,9 +10601,9 @@ } }, "import-fresh": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", - "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -7730,10 +10661,10 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", "dev": true }, "inflight": { @@ -7747,9 +10678,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "ini": { @@ -7759,9 +10690,9 @@ "dev": true }, "inquirer": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", - "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz", + "integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", @@ -8211,23 +11142,6 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isemail": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", - "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", - "dev": true, - "requires": { - "punycode": "2.x.x" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } - } - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -8278,9 +11192,9 @@ }, "dependencies": { "semver": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", - "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz", + "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", "dev": true } } @@ -8330,9 +11244,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "source-map": { @@ -8620,18 +11534,18 @@ } }, "jest-dev-server": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jest-dev-server/-/jest-dev-server-4.1.1.tgz", - "integrity": "sha512-VB/myFWW1q271FUWWbuTy/tWFTw1bQ8Gs5U/5I0h6p8vNJSs+nBivOJQNiOrc745ijh1ND0WMs1rDSmCCnh5Cg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jest-dev-server/-/jest-dev-server-4.3.0.tgz", + "integrity": "sha512-bC9flKY2G1honQ/UI0gEhb0wFnDhpFr7xidC8Nk+evi7TgnNtfsGIzzF2dcIhF1G9BGF0n/M7CJrMAzwQhyTPA==", "dev": true, "requires": { "chalk": "^2.4.2", "cwd": "^0.10.0", - "find-process": "^1.4.1", - "prompts": "^2.0.4", + "find-process": "^1.4.2", + "prompts": "^2.1.0", "spawnd": "^4.0.0", "tree-kill": "^1.2.1", - "wait-on": "^3.2.0" + "wait-on": "^3.3.0" } }, "jest-diff": { @@ -8696,14 +11610,14 @@ } }, "jest-environment-puppeteer": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jest-environment-puppeteer/-/jest-environment-puppeteer-4.1.1.tgz", - "integrity": "sha512-H+Wqxq4w9mFb0sBRGcbFIU02T+0YZbf/HKfQhwHvbam4UQqq7/n3kRkF0iYYlf76Jmys/H8rThtdh+HHxFgA5Q==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-puppeteer/-/jest-environment-puppeteer-4.3.0.tgz", + "integrity": "sha512-ZighMsU39bnacn2ylyHb88CB+ldgCfXGD3lS78k4PEo8A8xyt6+2mxmSR62FH3Y7K+W2gPDu5+QM3/LZuq42fQ==", "dev": true, "requires": { "chalk": "^2.4.2", "cwd": "^0.10.0", - "jest-dev-server": "^4.1.1", + "jest-dev-server": "^4.3.0", "merge-deep": "^3.0.2" } }, @@ -8714,9 +11628,9 @@ "dev": true }, "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "version": "24.8.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.1.tgz", + "integrity": "sha512-SwaxMGVdAZk3ernAx2Uv2sorA7jm3Kx+lR0grp6rMmnY06Kn/urtKx1LPN2mGTea4fCT38impYT28FfcLUhX0g==", "dev": true, "requires": { "@jest/types": "^24.8.0", @@ -8810,13 +11724,13 @@ "dev": true }, "jest-puppeteer": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jest-puppeteer/-/jest-puppeteer-4.1.1.tgz", - "integrity": "sha512-nMZ8oUrmzp67UfPKXKmoEU1wLsZfPAhlOlLYHZSCb78eIkHmeP8tqSibhAMxH8BIQUHTsnAfel5z5AsGv2SzGQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jest-puppeteer/-/jest-puppeteer-4.3.0.tgz", + "integrity": "sha512-WXhaWlbQl01xadZyNmdZntrtIr8uWUmgjPogDih7dOnr3G/xRr3A034SCqdjwV6fE0tqz7c5hwO8oBTyGZPRgA==", "dev": true, "requires": { - "expect-puppeteer": "^4.1.1", - "jest-environment-puppeteer": "^4.1.1" + "expect-puppeteer": "^4.3.0", + "jest-environment-puppeteer": "^4.3.0" } }, "jest-regex-util": { @@ -9180,17 +12094,6 @@ } } }, - "joi": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", - "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", - "dev": true, - "requires": { - "hoek": "5.x.x", - "isemail": "3.x.x", - "topo": "3.x.x" - } - }, "js-levenshtein": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", @@ -9338,12 +12241,13 @@ } }, "jsx-ast-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz", - "integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", + "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", "dev": true, "requires": { - "array-includes": "^3.0.3" + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" } }, "kind-of": { @@ -9497,9 +12401,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash._reinterpolate": { @@ -9563,6 +12467,12 @@ "lodash._reinterpolate": "~3.0.0" } }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -9709,9 +12619,9 @@ } }, "mdast-util-compact": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.2.tgz", - "integrity": "sha512-d2WS98JSDVbpSsBfVvD9TaDMlqPRz7ohM/11G0rp5jOBb5q96RJ6YLszQ/09AAixyzh23FeIpCGqfaamEADtWg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.3.tgz", + "integrity": "sha512-nRiU5GpNy62rZppDKbLwhhtw5DXoFMqw9UNZFmlPsNaQCZ//WLjGKUwWMdJrUH+Se7UvtO2gXtAMe0g/N+eI5w==", "dev": true, "requires": { "unist-util-visit": "^1.1.0" @@ -9741,8 +12651,7 @@ "memize": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/memize/-/memize-1.0.5.tgz", - "integrity": "sha512-Dm8Jhb5kiC4+ynYsVR4QDXKt+o2dfqGuY4hE2x+XlXZkdndlT80bJxfcMv5QGp/FCy6MhG7f5ElpmKPFKOSEpg==", - "dev": true + "integrity": "sha512-Dm8Jhb5kiC4+ynYsVR4QDXKt+o2dfqGuY4hE2x+XlXZkdndlT80bJxfcMv5QGp/FCy6MhG7f5ElpmKPFKOSEpg==" }, "memory-fs": { "version": "0.4.1", @@ -9836,9 +12745,9 @@ } }, "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.4.tgz", + "integrity": "sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==", "dev": true }, "methods": { @@ -9879,9 +12788,9 @@ } }, "mime": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", - "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true }, "mime-db": { @@ -9906,9 +12815,9 @@ "dev": true }, "mini-css-extract-plugin": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.7.0.tgz", - "integrity": "sha512-RQIw6+7utTYn8DBGsf/LpRgZCJMpZt+kuawJ/fju0KiOL6nAaTBNmCJwS7HtwSCXfS47gCkmtBFS7HdsquhdxQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz", + "integrity": "sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw==", "dev": true, "requires": { "loader-utils": "^1.1.0", @@ -9987,9 +12896,9 @@ } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -10041,9 +12950,9 @@ "dev": true }, "moment-timezone": { - "version": "0.5.25", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz", - "integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==", + "version": "0.5.26", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz", + "integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==", "dev": true, "requires": { "moment": ">= 2.9.0" @@ -10167,9 +13076,9 @@ "dev": true }, "node-libs-browser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", - "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "dev": true, "requires": { "assert": "^1.1.1", @@ -10182,7 +13091,7 @@ "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", + "path-browserify": "0.0.1", "process": "^0.11.10", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", @@ -10194,7 +13103,7 @@ "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.11.0", - "vm-browserify": "0.0.4" + "vm-browserify": "^1.0.1" } }, "node-modules-regexp": { @@ -10204,9 +13113,9 @@ "dev": true }, "node-notifier": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", - "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.1.tgz", + "integrity": "sha512-p52B+onAEHKW1OF9MGO/S7k/ahGEHfhP5/tvwYzog/5XLYOd8ZuD6vdNZdUuWMONRnKPneXV43v3s6Snx1wsCQ==", "dev": true, "requires": { "growly": "^1.3.0", @@ -10217,9 +13126,9 @@ } }, "node-releases": { - "version": "1.1.23", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.23.tgz", - "integrity": "sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w==", + "version": "1.1.25", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.25.tgz", + "integrity": "sha512-fI5BXuk83lKEoZDdH3gRhtsNgh05/wZacuXkgbiYkceE7+QIMXOg98n9ZV7mz27B+kFHnqHcUpscZZlGRSmTpQ==", "dev": true, "requires": { "semver": "^5.3.0" @@ -10271,30 +13180,30 @@ "dev": true }, "npm-package-json-lint": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-3.6.0.tgz", - "integrity": "sha512-N1y3r0l0oN7mYnMfRzZvYF8+NvjIx+zkskRn3J7ofipJKGH4RDDKdEGP/mV1Crf5W8uUo3201VhJe04Q+v9erw==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-3.7.0.tgz", + "integrity": "sha512-eWi1pZ/ZhPHAOMLC1+njBJj81yCu2Ek4VxhwpPHABvSVHS0dkaL6aKhSj/TX8Rtm/0rIg3edgMLt3kSRtWkFaA==", "dev": true, "requires": { - "ajv": "^6.9.2", + "ajv": "^6.10.0", "chalk": "^2.4.2", - "glob": "^7.1.3", - "ignore": "^5.0.5", - "is-path-inside": "^2.0.0", + "glob": "^7.1.4", + "ignore": "^5.1.2", + "is-path-inside": "^2.1.0", "is-plain-obj": "^1.1.0", "is-resolvable": "^1.1.0", "log-symbols": "^2.2.0", "meow": "^5.0.0", - "plur": "^3.0.1", + "plur": "^3.1.1", "semver": "^5.6.0", "strip-json-comments": "^2.0.1", "validator": "^10.11.0" }, "dependencies": { "ignore": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.1.tgz", - "integrity": "sha512-DWjnQIFLenVrwyRCKZT+7a7/U4Cqgar4WG8V++K3hw+lrW1hc/SIwdiGmtxKCVACmHULTuGeBbHJmbwW7/sAvA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", "dev": true } } @@ -10571,12 +13480,12 @@ } }, "optimize-css-assets-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-Rqm6sSjWtx9FchdP0uzTQDc7GXDKnwVEGoSxjezPkzMewx7gEWE9IMUYKmigTRC4U3RaNSwYVnUDLuIdtTpm0A==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", "dev": true, "requires": { - "cssnano": "^4.1.0", + "cssnano": "^4.1.10", "last-call-webpack-plugin": "^3.0.0" } }, @@ -10783,9 +13692,9 @@ "dev": true }, "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, "path-dirname": { @@ -10984,9 +13893,9 @@ "dev": true }, "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", + "integrity": "sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA==", "dev": true, "requires": { "async": "^1.5.2", @@ -11193,9 +14102,9 @@ }, "dependencies": { "color": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.1.tgz", - "integrity": "sha512-PvUltIXRjehRKPSy89VnDWFKY58xyhTLyxIg21vwQBI6qLwZNPmC8k3C1uytIgFKEpOIzN4y32iPm8231zFHIg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", "dev": true, "requires": { "color-convert": "^1.9.1", @@ -11234,12 +14143,12 @@ } }, "postcss-custom-properties": { - "version": "8.0.10", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.10.tgz", - "integrity": "sha512-GDL0dyd7++goDR4SSasYdRNNvp4Gqy1XMzcCnTijiph7VB27XXpJ8bW/AI0i2VSBZ55TpdGhMr37kMSpRfYD0Q==", + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", + "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", "dev": true, "requires": { - "postcss": "^7.0.14", + "postcss": "^7.0.17", "postcss-values-parser": "^2.0.1" } }, @@ -11435,12 +14344,12 @@ } }, "postcss-jsx": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.0.tgz", - "integrity": "sha512-/lWOSXSX5jlITCKFkuYU2WLFdrncZmjSVyNpHAunEgirZXLwI8RjU556e3Uz4mv0WVHnJA9d3JWb36lK9Yx99g==", + "version": "0.36.3", + "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.3.tgz", + "integrity": "sha512-yV8Ndo6KzU8eho5mCn7LoLUGPkXrRXRjhMpX4AaYJ9wLJPv099xbtpbRQ8FrPnzVxb/cuMebbPR7LweSt+hTfA==", "dev": true, "requires": { - "@babel/core": ">=7.1.0" + "@babel/core": ">=7.2.2" } }, "postcss-lab-function": { @@ -11464,27 +14373,13 @@ } }, "postcss-load-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", - "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", "dev": true, "requires": { - "cosmiconfig": "^4.0.0", + "cosmiconfig": "^5.0.0", "import-cwd": "^2.0.0" - }, - "dependencies": { - "cosmiconfig": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", - "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0", - "require-from-string": "^2.0.1" - } - } } }, "postcss-loader": { @@ -11646,9 +14541,9 @@ } }, "postcss-value-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz", - "integrity": "sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.1.tgz", + "integrity": "sha512-3Jk+/CVH0HBfgSSFWALKm9Hyzf4kumPjZfUxkRYZNcqFztELb2APKxv0nlX8HCdc1/ymePmT/nFf1ST6fjWH2A==", "dev": true } } @@ -11863,27 +14758,27 @@ } }, "postcss-preset-env": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.6.0.tgz", - "integrity": "sha512-I3zAiycfqXpPIFD6HXhLfWXIewAWO8emOKz+QSsxaUZb9Dp8HbF5kUf+4Wy/AxR33o+LRoO8blEWCHth0ZsCLA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", + "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", "dev": true, "requires": { - "autoprefixer": "^9.4.9", - "browserslist": "^4.4.2", - "caniuse-lite": "^1.0.30000939", + "autoprefixer": "^9.6.1", + "browserslist": "^4.6.4", + "caniuse-lite": "^1.0.30000981", "css-blank-pseudo": "^0.1.4", "css-has-pseudo": "^0.10.0", "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.3.0", - "postcss": "^7.0.14", + "cssdb": "^4.4.0", + "postcss": "^7.0.17", "postcss-attribute-case-insensitive": "^4.0.1", "postcss-color-functional-notation": "^2.0.1", "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.2", + "postcss-color-hex-alpha": "^5.0.3", "postcss-color-mod-function": "^3.0.3", "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.7", - "postcss-custom-properties": "^8.0.9", + "postcss-custom-media": "^7.0.8", + "postcss-custom-properties": "^8.0.11", "postcss-custom-selectors": "^5.1.2", "postcss-dir-pseudo-class": "^5.0.0", "postcss-double-position-gradients": "^1.0.0", @@ -11905,6 +14800,14 @@ "postcss-replace-overflow-wrap": "^3.0.0", "postcss-selector-matches": "^4.0.0", "postcss-selector-not": "^4.0.0" + }, + "dependencies": { + "caniuse-lite": { + "version": "1.0.30000981", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000981.tgz", + "integrity": "sha512-JTByHj4DQgL2crHNMK6PibqAMrqqb/Vvh0JrsTJVSWG4VSUrT16EklkuRZofurlMjgA9e+zlCM4Y39F3kootMQ==", + "dev": true + } } }, "postcss-pseudo-class-any-link": { @@ -12182,10 +15085,10 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "prettier": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", - "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", + "pretty-bytes": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", + "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==", "dev": true }, "pretty-format": { @@ -12208,6 +15111,12 @@ } } }, + "pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "dev": true + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -12221,9 +15130,9 @@ "dev": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "progress": { @@ -12248,13 +15157,13 @@ "dev": true }, "prompts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz", - "integrity": "sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz", + "integrity": "sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw==", "dev": true, "requires": { - "kleur": "^3.0.2", - "sisteransi": "^1.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.3" } }, "prop-types": { @@ -12307,9 +15216,9 @@ "dev": true }, "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", + "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==", "dev": true }, "public-encrypt": { @@ -12391,9 +15300,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -12501,10 +15410,13 @@ } }, "re-resizable": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-4.11.0.tgz", - "integrity": "sha512-dye+7rERqNf/6mDT1iwps+4Gf42420xuZgygF33uX178DxffqcyeuHbBuJ382FIcB5iP6mMZOhfW7kI0uXwb/Q==", - "dev": true + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-5.0.1.tgz", + "integrity": "sha512-Iy8v5li7bhNBDxCN1DbA4l6G2Hk8NCZtcExoI1D+5pfvKyQcH8LH2P5h3DGoEfHhs0uyyRC1Qx8bHBomfrmxgA==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" + } }, "react": { "version": "16.8.6", @@ -12617,6 +15529,16 @@ "prop-types": "^15.5.8" } }, + "react-spring": { + "version": "8.0.27", + "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.27.tgz", + "integrity": "sha512-nDpWBe3ZVezukNRandTeLSPcwwTMjNVu1IDq9qA/AMiUqHuRN4BeSWvKr3eIxxg1vtiYiOLy4FqdfCP5IoP77g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "prop-types": "^15.5.8" + } + }, "react-test-renderer": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.6.tgz", @@ -12646,15 +15568,26 @@ } }, "react-with-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/react-with-styles/-/react-with-styles-3.2.1.tgz", - "integrity": "sha512-L+x/EDgrKkqV6pTfDtLMShf7Xs+bVQ+HAT5rByX88QYX+ft9t5Gn4PWMmg36Ur21IVEBMGjjQQIJGJpBrzbsyg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/react-with-styles/-/react-with-styles-3.2.3.tgz", + "integrity": "sha512-MTI1UOvMHABRLj5M4WpODfwnveHaip6X7QUMI2x6zovinJiBXxzhA9AJP7MZNaKqg1JRFtHPXZdroUC8KcXwlQ==", "dev": true, "requires": { - "deepmerge": "^1.5.2", - "hoist-non-react-statics": "^2.5.0", - "prop-types": "^15.6.1", + "hoist-non-react-statics": "^3.2.1", + "object.assign": "^4.1.0", + "prop-types": "^15.6.2", "react-with-direction": "^1.3.0" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "dev": true, + "requires": { + "react-is": "^16.7.0" + } + } } }, "react-with-styles-interface-css": { @@ -12831,9 +15764,9 @@ } }, "redux": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.1.tgz", - "integrity": "sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.4.tgz", + "integrity": "sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==", "dev": true, "requires": { "loose-envify": "^1.4.0", @@ -12886,9 +15819,9 @@ "dev": true }, "regenerator-transform": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.4.tgz", - "integrity": "sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", "dev": true, "requires": { "private": "^0.1.6" @@ -12905,9 +15838,9 @@ } }, "regexp-tree": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", - "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.11.tgz", + "integrity": "sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg==", "dev": true }, "regexpp": { @@ -13126,12 +16059,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", @@ -13145,9 +16072,9 @@ "dev": true }, "resolve": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -13265,9 +16192,9 @@ } }, "rsvp": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.4.tgz", - "integrity": "sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==", + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, "rtlcss": { @@ -13303,9 +16230,9 @@ } }, "rtlcss-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/rtlcss-webpack-plugin/-/rtlcss-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-/00Jq2colhg2O5vkdviu+F66DVD/nV9Ll8hbG7YIhjWxfdEMqYT+MGDYhBIWHkhFlPivNGB/1c9mI7tocnYWBw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/rtlcss-webpack-plugin/-/rtlcss-webpack-plugin-4.0.3.tgz", + "integrity": "sha512-p1J6R2wkOhLd/foQwlALDj0dz1zEWRa9/YzB3xf/m4qlT/ghud5pn6ZxEQi5znNOcEDbwIk+UlFpnFl8l1bPEA==", "dev": true, "requires": { "babel-runtime": "~6.25.0", @@ -13545,9 +16472,9 @@ "dev": true }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -13675,9 +16602,9 @@ "dev": true }, "simple-html-tokenizer": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.7.tgz", - "integrity": "sha512-APW9iYbkJ5cijjX4Ljhf3VG8SwYPUJT5gZrwci/wieMabQxWFiV5VwsrP5c6GMRvXKEQMGkAB1d9dvW66dTqpg==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.8.tgz", + "integrity": "sha512-0Sq4FvLlQEQODVA6PH2MIrc7tzYO0KT2HzzwvaVLYClWgIsuvaNUOrhrAvTi1pZHrcq7GDB4WiI3ukjqBMxcGQ==", "dev": true }, "simple-swizzle": { @@ -13698,9 +16625,9 @@ } }, "sisteransi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", - "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.3.tgz", + "integrity": "sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg==", "dev": true }, "slash": { @@ -14031,6 +16958,23 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, + "std-env": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.2.1.tgz", + "integrity": "sha512-IjYQUinA3lg5re/YMlwlfhqNRTzMZMqE+pezevdcTaHceqx8ngEi1alX9nNCk9Sc81fy1fLDeQoaCzeiW1yBOQ==", + "dev": true, + "requires": { + "ci-info": "^1.6.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + } + } + }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -14301,15 +17245,15 @@ } }, "ignore": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.1.tgz", - "integrity": "sha512-DWjnQIFLenVrwyRCKZT+7a7/U4Cqgar4WG8V++K3hw+lrW1hc/SIwdiGmtxKCVACmHULTuGeBbHJmbwW7/sAvA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", "dev": true }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "string-width": { @@ -14361,16 +17305,16 @@ } }, "stylelint-scss": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.6.1.tgz", - "integrity": "sha512-6bB2EHUZsE/bDVKUdzBXqOcfgXmg3zq9Lglgbu16EqMa4PM8Y48XKcB8coOj8CKr07GtlqtOdCNA2E5njoI9Kw==", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.9.3.tgz", + "integrity": "sha512-pLLpwSpUwiqpAga/C22ZuN/d5ql2zVWGzG8MO+P3DQYcDNue3eZGvda/bJdkx4mDcVy06jlDt+BgSvMYUrwleQ==", "dev": true, "requires": { "lodash": "^4.17.11", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^3.3.1" + "postcss-value-parser": "^4.0.0" }, "dependencies": { "postcss-selector-parser": { @@ -14383,6 +17327,12 @@ "indexes-of": "^1.0.1", "uniq": "^1.0.1" } + }, + "postcss-value-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz", + "integrity": "sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==", + "dev": true } } }, @@ -14493,15 +17443,15 @@ "dev": true }, "symbol-tree": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, "table": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/table/-/table-5.3.3.tgz", - "integrity": "sha512-3wUNCgdWX6PNpOe3amTTPWPuF6VGvgzjKCaO1snFj0z7Y3mUPWf5+zDtxUVGispJkDECPmR29wbzh6bVMOHbcw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz", + "integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==", "dev": true, "requires": { "ajv": "^6.9.1", @@ -14554,14 +17504,14 @@ "dev": true }, "terser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.0.0.tgz", - "integrity": "sha512-dOapGTU0hETFl1tCo4t56FN+2jffoKyER9qBGoUFyZ6y7WLoKT0bF+lAYi6B6YsILcGF3q1C2FBh8QcKSCgkgA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz", + "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==", "dev": true, "requires": { - "commander": "^2.19.0", + "commander": "^2.20.0", "source-map": "~0.6.1", - "source-map-support": "~0.5.10" + "source-map-support": "~0.5.12" }, "dependencies": { "source-map": { @@ -14573,20 +17523,19 @@ } }, "terser-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", + "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", "dev": true, "requires": { - "cacache": "^11.3.2", - "find-cache-dir": "^2.0.0", + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", - "loader-utils": "^1.2.3", "schema-utils": "^1.0.0", "serialize-javascript": "^1.7.0", "source-map": "^0.6.1", - "terser": "^4.0.0", - "webpack-sources": "^1.3.0", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", "worker-farm": "^1.7.0" }, "dependencies": { @@ -14595,6 +17544,16 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "webpack-sources": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.0.tgz", + "integrity": "sha512-1e4Cxgqfl8vnDhXMMpegX7JWWP7HwV8Kp8/Oefs6EG52bRtOR9vuOXM1Gl1vy6NwHfUxHeuR6ElD4HamuRPO0A==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } } } }, @@ -14755,9 +17714,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -14843,23 +17802,6 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, - "topo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", - "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", - "dev": true, - "requires": { - "hoek": "6.x.x" - }, - "dependencies": { - "hoek": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", - "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", - "dev": true - } - } - }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -14901,6 +17843,42 @@ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", "dev": true }, + "travis-size-report": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/travis-size-report/-/travis-size-report-1.1.0.tgz", + "integrity": "sha512-mAMeCPZ1TvUEXDvweVCAG/ek6KgPeVsmQYXtv6I85UoIUIFAI/mCXnN7vyvTSCjIa8B0+cYn5slvqNn9Jo0U0g==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "escape-string-regexp": "^2.0.0", + "glob": "^7.1.3", + "gzip-size": "^5.1.0", + "minimist": "^1.2.0", + "node-fetch": "^2.3.0", + "pretty-bytes": "^5.1.0", + "typescript": "^3.4.4" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "dev": true + } + } + }, "tree-kill": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", @@ -14944,9 +17922,9 @@ "dev": true }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, "tty-browserify": { @@ -14985,6 +17963,12 @@ "prelude-ls": "~1.1.2" } }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -15001,16 +17985,22 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typescript": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", + "dev": true + }, "ua-parser-js": { - "version": "0.7.19", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", - "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==", + "version": "0.7.20", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", + "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==", "dev": true }, "uglify-js": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.15.tgz", - "integrity": "sha512-fe7aYFotptIddkwcm6YuA0HmknBZ52ZzOsUxZEdhhkSsz7RfjHDX2QDxwKTiv4JQ5t5NhfmpgAK+J7LiDhKSqg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "dev": true, "optional": true, "requires": { @@ -15241,38 +18231,15 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "uniq": { @@ -15297,27 +18264,27 @@ } }, "unique-slug": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", - "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "dev": true, "requires": { "imurmurhash": "^0.1.4" } }, "unist-util-find-all-after": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.3.tgz", - "integrity": "sha512-FNPM5Q1AViItYvkLngkalxZ879j842VxGzlfI0gLlgDQz/Teh9CUzqpc7kgFOWO3RK5qU/wqG0UnJ6XWiHSWiA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.4.tgz", + "integrity": "sha512-CaxvMjTd+yF93BKLJvZnEfqdM7fgEACsIpQqz8vIj9CJnUb9VpyymFS3tg6TCtgrF7vfCJBF5jbT2Ox9CBRYRQ==", "dev": true, "requires": { - "unist-util-is": "^2.0.0" + "unist-util-is": "^3.0.0" } }, "unist-util-is": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", - "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", + "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==", "dev": true }, "unist-util-remove-position": { @@ -15345,12 +18312,12 @@ } }, "unist-util-visit-parents": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.0.tgz", - "integrity": "sha512-j0XZY3063E6v7qhx4+Q2Z0r8SMrLX7Mr6DabiCy67zMEcFQYtpNOplLlEK1KKEBEs9S+xB5U+yloQxbSwF9P/g==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", "dev": true, "requires": { - "unist-util-is": "^2.1.2" + "unist-util-is": "^3.0.0" } }, "unpipe": { @@ -15457,6 +18424,14 @@ "dev": true, "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } } }, "util-deprecate": { @@ -15482,9 +18457,9 @@ "dev": true }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, "v8-compile-cache": { @@ -15553,9 +18528,9 @@ } }, "vfile-location": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.4.tgz", - "integrity": "sha512-KRL5uXQPoUKu+NGvQVL4XLORw45W62v4U4gxJ3vRlDfI9QsT4ZN1PNXn/zQpKUulqGDpYuT0XDfp5q9O87/y/w==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz", + "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==", "dev": true }, "vfile-message": { @@ -15568,13 +18543,10 @@ } }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true }, "w3c-hr-time": { "version": "1.0.1", @@ -15586,22 +18558,22 @@ } }, "wait-on": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", - "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.3.0.tgz", + "integrity": "sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ==", "dev": true, "requires": { - "core-js": "^2.5.7", - "joi": "^13.0.0", + "@hapi/joi": "^15.0.3", + "core-js": "^2.6.5", "minimist": "^1.2.0", "request": "^2.88.0", "rx": "^4.1.0" }, "dependencies": { "core-js": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.8.tgz", - "integrity": "sha512-RWlREFU74TEkdXzyl1bka66O3kYp8jeTXrvJZDzVVMH8AiHUSOFpL1yfhQJ+wHocAm1m+4971W1PPzfLuCv1vg==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", "dev": true }, "minimist": { @@ -15794,9 +18766,9 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -15808,37 +18780,60 @@ "dev": true }, "webpack": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.33.0.tgz", - "integrity": "sha512-ggWMb0B2QUuYso6FPZKUohOgfm+Z0sVFs8WwWuSH1IAvkWs428VDNmOlAxvHGTB9Dm/qOB/qtE5cRx5y01clxw==", + "version": "4.39.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz", + "integrity": "sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", "@webassemblyjs/helper-module-context": "1.8.5", "@webassemblyjs/wasm-edit": "1.8.5", "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.0.5", - "acorn-dynamic-import": "^4.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "chrome-trace-event": "^1.0.0", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.0", + "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "micromatch": "^3.1.8", - "mkdirp": "~0.5.0", - "neo-async": "^2.5.0", - "node-libs-browser": "^2.0.0", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", - "tapable": "^1.1.0", - "terser-webpack-plugin": "^1.1.0", - "watchpack": "^1.5.0", - "webpack-sources": "^1.3.0" + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" }, "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, "eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", @@ -15848,13 +18843,29 @@ "esrecurse": "^4.1.0", "estraverse": "^4.1.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 + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } } } }, "webpack-bundle-analyzer": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.3.2.tgz", - "integrity": "sha512-7qvJLPKB4rRWZGjVp5U1KEjwutbDHSKboAl0IfafnrdXMrgC0tOtZbQD6Rw0u4cmpgRN4O02Fc0t8eAT+FgGzA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.4.1.tgz", + "integrity": "sha512-Bs8D/1zF+17lhqj2OYmzi7HEVYqEVxu7lCO9Ff8BwajenOU0vAwEoV8e4ICCPNZAcqR1PCR/7o2SkW+cnCmF0A==", "dev": true, "requires": { "acorn": "^6.0.7", @@ -15866,7 +18877,7 @@ "express": "^4.16.3", "filesize": "^3.6.1", "gzip-size": "^5.0.0", - "lodash": "^4.17.10", + "lodash": "^4.17.15", "mkdirp": "^0.5.1", "opener": "^1.5.1", "ws": "^6.0.0" @@ -15884,31 +18895,47 @@ } }, "webpack-cli": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.4.tgz", - "integrity": "sha512-ubJGQEKMtBSpT+LiL5hXvn2GIOWiRWItR1DGUqJRhwRBeGhpRXjvF5f0erqdRJLErkfqS5/Ldkkedh4AL5Q1ZQ==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "enhanced-resolve": "^4.1.0", - "findup-sync": "^2.0.0", - "global-modules": "^1.0.0", - "import-local": "^2.0.0", - "interpret": "^1.1.0", - "loader-utils": "^1.1.0", - "prettier": "^1.17.0", - "supports-color": "^5.5.0", - "v8-compile-cache": "^2.0.2", - "yargs": "^12.0.5" + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.7.tgz", + "integrity": "sha512-OhTUCttAsr+IZSMVwGROGRHvT+QAs8H6/mHIl4SvhAwYywjiylYjpwybGx7WQ9Hkb45FhjtsymkwiRRbGJ1SZQ==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" }, "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -15937,15 +18964,6 @@ "strip-eof": "^1.0.0" } }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -15955,6 +18973,12 @@ "locate-path": "^3.0.0" } }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -15965,27 +18989,23 @@ } }, "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" + "global-prefix": "^3.0.0" } }, "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" } }, "invert-kv": { @@ -16065,40 +19085,81 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -16135,13 +19196,123 @@ } } }, + "webpackbar": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-4.0.0.tgz", + "integrity": "sha512-k1qRoSL/3BVuINzngj09nIwreD8wxV4grcuhHTD8VJgUbGcy8lQSPqv+bM00B7F+PffwIsQ8ISd4mIwRbr23eQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "consola": "^2.10.0", + "figures": "^3.0.0", + "pretty-time": "^1.1.0", + "std-env": "^2.2.1", + "text-table": "^0.2.0", + "wrap-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "dev": true, + "requires": { + "type-fest": "^0.5.2" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.0.0.tgz", + "integrity": "sha512-8zjUtFJ3db/QoPXuuEMloS2AUf79/yeyttJ7Abr3hteopJu9HK8vsgGviGUMq+zyA6cZZO6gAyZoMTF6TgaEjA==", + "dev": true, + "requires": { + "color-convert": "^2.0.0" + } + }, + "color-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.0.tgz", + "integrity": "sha512-hzTicsCJIHdxih9+2aLR1tNGZX5qSJGRHDPVwSY26tVrEf55XNajLOBWz2UuWSIergszA09/bqnOiHyqx9fxQg==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "figures": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", + "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.0.0.tgz", + "integrity": "sha512-8YwLklVkHe4QNpGFrK6Mxm+BaMY7da6C9GlDED3xs3XwThyJHSbVwg9qC4s1N8tBFcnM1S0s8I390RC6SgGe+g==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^5.0.0" + } + } + } + }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "dev": true, "requires": { - "http-parser-js": ">=0.4.0", + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, diff --git a/package.json b/package.json index 16d07524bd8..be394b9b104 100644 --- a/package.json +++ b/package.json @@ -20,79 +20,91 @@ }, "dependencies": { "classnames": "2.2.6", - "dom-scroll-into-view": "1.2.1", + "dom-scroll-into-view": "2.0.1", + "memize": "1.0.5", "prop-types": "15.7.2" }, "devDependencies": { - "@babel/cli": "7.4.4", - "@babel/core": "7.4.5", - "@babel/plugin-proposal-object-rest-spread": "7.4.4", + "@babel/cli": "7.5.5", + "@babel/core": "7.5.5", + "@babel/plugin-proposal-object-rest-spread": "7.5.5", "@babel/plugin-transform-react-jsx": "7.3.0", - "@wordpress/babel-preset-default": "4.2.0", - "@wordpress/block-editor": "2.1.0", - "@wordpress/blocks": "6.3.0", - "@wordpress/browserslist-config": "2.4.0", - "@wordpress/components": "7.4.0", - "@wordpress/compose": "3.3.0", - "@wordpress/data": "4.5.0", - "@wordpress/date": "3.3.0", - "@wordpress/dom-ready": "2.3.0", - "@wordpress/e2e-test-utils": "2.0.0", - "@wordpress/edit-post": "3.4.0", - "@wordpress/editor": "9.3.0", - "@wordpress/element": "2.4.0", - "@wordpress/eslint-plugin": "2.2.0", - "@wordpress/hooks": "2.3.0", - "@wordpress/i18n": "3.4.0", - "@wordpress/keycodes": "2.3.0", - "@wordpress/plugins": "2.3.0", - "@wordpress/postcss-themes": "2.1.0", - "@wordpress/scripts": "3.2.1", - "@wordpress/url": "2.6.0", - "@wordpress/wordcount": "2.3.0", - "autoprefixer": "9.6.0", - "babel-eslint": "10.0.1", - "babel-jest": "24.8.0", + "@wordpress/babel-preset-default": "4.4.0", + "@wordpress/blob": "2.5.0", + "@wordpress/block-editor": "3.0.0", + "@wordpress/blocks": "6.5.0", + "@wordpress/browserslist-config": "2.6.0", + "@wordpress/components": "8.1.0", + "@wordpress/compose": "3.5.0", + "@wordpress/data": "4.7.0", + "@wordpress/date": "3.4.0", + "@wordpress/dom-ready": "2.5.0", + "@wordpress/e2e-test-utils": "2.2.0", + "@wordpress/edit-post": "3.6.0", + "@wordpress/editor": "9.5.0", + "@wordpress/element": "2.6.0", + "@wordpress/eslint-plugin": "2.4.0", + "@wordpress/hooks": "2.5.0", + "@wordpress/i18n": "3.6.0", + "@wordpress/keycodes": "2.5.0", + "@wordpress/plugins": "2.5.0", + "@wordpress/postcss-themes": "2.2.0", + "@wordpress/rich-text": "3.5.0", + "@wordpress/scripts": "3.4.0", + "@wordpress/server-side-render": "1.1.0", + "@wordpress/url": "2.7.0", + "@wordpress/wordcount": "2.5.0", + "autoprefixer": "9.6.1", + "babel-eslint": "10.0.2", + "babel-jest": "24.9.0", "babel-loader": "8.0.6", "babel-plugin-inline-react-svg": "1.1.0", "babel-plugin-transform-react-remove-prop-types": "0.4.24", - "browserslist": "4.6.2", - "core-js": "3.1.3", + "browserslist": "4.6.6", + "core-js": "3.2.1", "cross-env": "5.2.0", - "css-loader": "3.0.0", + "css-loader": "3.2.0", "cssnano": "4.1.10", "enzyme": "3.10.0", - "eslint": "5.16.0", - "eslint-plugin-jest": "22.6.4", - "eslint-plugin-react": "7.13.0", + "eslint": "6.1.0", + "eslint-plugin-eslint-comments": "3.1.2", + "eslint-plugin-import": "2.18.2", + "eslint-plugin-jest": "22.15.2", + "eslint-plugin-react": "7.14.3", "grunt": "1.0.4", "grunt-contrib-clean": "2.0.0", "grunt-contrib-copy": "1.0.0", "grunt-shell": "3.0.1", "grunt-wp-deploy": "2.0.0", - "lodash": "4.17.11", - "mini-css-extract-plugin": "0.7.0", + "lodash": "4.17.15", + "mini-css-extract-plugin": "0.8.0", "moment": "2.24.0", "npm-run-all": "4.1.5", "null-loader": "3.0.0", - "optimize-css-assets-webpack-plugin": "5.0.1", + "optimize-css-assets-webpack-plugin": "5.0.3", "postcss": "7.0.17", "postcss-color-function": "4.1.0", "postcss-import": "12.0.1", "postcss-loader": "3.0.0", "postcss-nested": "4.1.2", - "postcss-preset-env": "6.6.0", - "rtlcss-webpack-plugin": "4.0.0", + "postcss-preset-env": "6.7.0", + "rtlcss": "2.4.0", + "rtlcss-webpack-plugin": "4.0.3", "source-map-loader": "0.2.4", "svg-inline-loader": "0.8.0", - "terser-webpack-plugin": "1.3.0", - "uuid": "3.3.2", - "webpack": "4.33.0", - "webpack-cli": "3.3.4" + "terser-webpack-plugin": "1.4.1", + "travis-size-report": "1.1.0", + "uuid": "3.3.3", + "webpack": "4.39.2", + "webpack-cli": "3.3.7", + "webpackbar": "4.0.0" }, "scripts": { "build": "npm-run-all build:*", "build:prepare": "grunt clean", + "build:css": "npm-run-all build:css:*", + "build:css:copy": "cp -R assets/css/src/* assets/css", + "build:css:rtlcss": "rtlcss -d assets/css/src assets/css -e '-rtl.css'", "build:js": "wp-scripts build", "build:run": "grunt build", "build:zip": "grunt create-build-zip", @@ -100,23 +112,29 @@ "check-licenses": "wp-scripts check-licenses --production", "deploy": "grunt deploy", "dev": "wp-scripts start", + "env:start": "./bin/local-env/start.sh", + "env:stop": "./bin/local-env/stop.sh", + "env:reset-site": "./bin/local-env/install-wordpress.sh --reset-site", "lint": "npm-run-all --parallel lint:*", - "lint:css": "wp-scripts lint-style 'assets/**/*.css'", + "lint:css": "wp-scripts lint-style", "lint:css:fix": "npm run lint:css -- --fix", - "lint:js": "wp-scripts lint-js .", + "lint:js": "wp-scripts lint-js", "lint:js:fix": "npm run lint:js -- --fix", "lint:php": "vendor/bin/phpcs", "lint:php:fix": "./bin/phpcbf.sh", - "lint:pkg-json": "wp-scripts lint-pkg-json . --ignorePath .gitignore", + "lint:pkg-json": "wp-scripts lint-pkg-json --ignorePath .gitignore", "start": "wp-scripts start", "test": "npm-run-all --parallel test:*", - "pretest:e2e": "cross-env SCRIPT_DEBUG=false ./bin/reset-e2e-tests.sh", - "test:e2e": "wp-scripts test-e2e --config=tests/e2e/jest.config.js", + "test:e2e": "WP_BASE_URL=http://localhost:8890 wp-scripts test-e2e --config=tests/e2e/jest.config.js", + "test:e2e:help": "npm run test:e2e -- --help", "test:e2e:watch": "npm run test:e2e -- --watch", - "test:js": "wp-scripts test-unit-js --config=tests/unit/jest.config.js", + "test:e2e:interactive": "npm run test:e2e -- --puppeteer-interactive", + "test:e2e:ci": "npm run test:e2e -- --runInBand", + "test:js": "wp-scripts test-unit-js --config=tests/js/jest.config.js", "test:js:help": "wp-scripts test-unit-js --help", "test:js:watch": "npm run test:js -- --watch", - "test:php": "phpunit" + "test:php": "phpunit", + "test:php:help": "npm run test:php -- --help" }, "npmPackageJsonLintConfig": { "extends": "@wordpress/npm-package-json-lint-config", diff --git a/phpcs.xml b/phpcs.xml index 92b1da3090c..8f12fa14a2b 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -9,7 +9,10 @@ - + + + + @@ -79,6 +82,10 @@ bin/* + + amp.php + + . diff --git a/phpunit.xml b/phpunit.xml index 64c2a940a8c..fcc95e834c2 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -10,17 +10,23 @@ - + + ./tests/ + + + external-http + + ./ - dev-lib svn node_modules + bin tests vendor build diff --git a/readme.md b/readme.md index 5a91119665d..19ad9d8b2f3 100644 --- a/readme.md +++ b/readme.md @@ -4,11 +4,11 @@ ![Banner](wp-assets/banner-1544x500.png) Enable AMP on your WordPress site, the WordPress way. -**Contributors:** [google](https://profiles.wordpress.org/google), [xwp](https://profiles.wordpress.org/xwp), [automattic](https://profiles.wordpress.org/automattic), [westonruter](https://profiles.wordpress.org/westonruter), [swissspidy](https://profiles.wordpress.org/swissspidy), [stubgo](https://profiles.wordpress.org/stubgo), [ryankienstra](https://profiles.wordpress.org/ryankienstra), [albertomedina](https://profiles.wordpress.org/albertomedina), [tweetythierry](https://profiles.wordpress.org/tweetythierry) +**Contributors:** [google](https://profiles.wordpress.org/google), [xwp](https://profiles.wordpress.org/xwp), [automattic](https://profiles.wordpress.org/automattic), [westonruter](https://profiles.wordpress.org/westonruter), [swissspidy](https://profiles.wordpress.org/swissspidy), [miinasikk](https://profiles.wordpress.org/miinasikk), [ryankienstra](https://profiles.wordpress.org/ryankienstra), [albertomedina](https://profiles.wordpress.org/albertomedina), [tweetythierry](https://profiles.wordpress.org/tweetythierry) **Tags:** [amp](https://wordpress.org/plugins/tags/amp), [framework](https://wordpress.org/plugins/tags/framework), [components](https://wordpress.org/plugins/tags/components), [performance](https://wordpress.org/plugins/tags/performance), [mobile](https://wordpress.org/plugins/tags/mobile), [stories](https://wordpress.org/plugins/tags/stories) **Requires at least:** 4.9 **Tested up to:** 5.2 -**Stable tag:** 1.2.0 +**Stable tag:** 1.2.1 **License:** [GPLv2 or later](http://www.gnu.org/licenses/gpl-2.0.html) **Requires PHP:** 5.4 diff --git a/readme.txt b/readme.txt index 1363b8a503b..76132ab8f44 100644 --- a/readme.txt +++ b/readme.txt @@ -1,9 +1,9 @@ === AMP === -Contributors: google, xwp, automattic, westonruter, swissspidy, stubgo, ryankienstra, albertomedina, tweetythierry +Contributors: google, xwp, automattic, westonruter, swissspidy, miinasikk, ryankienstra, albertomedina, tweetythierry Tags: amp, framework, components, performance, mobile, stories Requires at least: 4.9 Tested up to: 5.2 -Stable tag: 1.2.0 +Stable tag: 1.2.1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Requires PHP: 5.4 diff --git a/sizereport.config.js b/sizereport.config.js new file mode 100644 index 00000000000..a9131eed03b --- /dev/null +++ b/sizereport.config.js @@ -0,0 +1,6 @@ +module.exports = { + repo: 'ampproject/amp-wp', + path: 'assets/js/**/*', + branch: 'develop', + findRenamed: '[name]-[extname]', +}; diff --git a/templates/header-bar.php b/templates/header-bar.php index 30935d1d59d..58db6e509d6 100644 --- a/templates/header-bar.php +++ b/templates/header-bar.php @@ -2,9 +2,22 @@ /** * Header bar template part. * + * 🚫🚫🚫 + * DO NOT EDIT THIS FILE WHILE INSIDE THE PLUGIN! Changes You make will be lost when a new version + * of the AMP plugin is released. You need to copy this file out of the plugin and put it into your + * custom theme, for example. To learn about how to customize these Reader-mode AMP templates, please + * see: https://amp-wp.org/documentation/how-the-plugin-works/classic-templates/ + * 🚫🚫🚫 + * * @package AMP */ +/** + * Context. + * + * @var AMP_Post_Template $this + */ + ?>
diff --git a/templates/header.php b/templates/header.php index 17e6de102a2..657ca0327fb 100644 --- a/templates/header.php +++ b/templates/header.php @@ -2,6 +2,13 @@ /** * Header template part. * + * 🚫🚫🚫 + * DO NOT EDIT THIS FILE WHILE INSIDE THE PLUGIN! Changes You make will be lost when a new version + * of the AMP plugin is released. You need to copy this file out of the plugin and put it into your + * custom theme, for example. To learn about how to customize these Reader-mode AMP templates, please + * see: https://amp-wp.org/documentation/how-the-plugin-works/classic-templates/ + * 🚫🚫🚫 + * * @package AMP */ @@ -11,4 +18,4 @@ * @var AMP_Post_Template $this */ -$this->load_parts( array( 'header-bar' ) ); +$this->load_parts( [ 'header-bar' ] ); diff --git a/templates/html-start.php b/templates/html-start.php index ca54160585a..ee28cd8f4cc 100644 --- a/templates/html-start.php +++ b/templates/html-start.php @@ -25,9 +25,10 @@ + diff --git a/templates/meta-author.php b/templates/meta-author.php index 238ea77a925..6d601e637ff 100644 --- a/templates/meta-author.php +++ b/templates/meta-author.php @@ -12,12 +12,18 @@ * @package AMP */ +/** + * Context. + * + * @var AMP_Post_Template $this + */ + $post_author = $this->get( 'post_author' ); ?> diff --git a/templates/meta-comments-link.php b/templates/meta-comments-link.php index 4e037c9b35c..b2179445ab6 100644 --- a/templates/meta-comments-link.php +++ b/templates/meta-comments-link.php @@ -12,6 +12,12 @@ * @package AMP */ +/** + * Context. + * + * @var AMP_Post_Template $this + */ + $comments_link_url = $this->get( 'comments_link_url' ); ?> diff --git a/templates/meta-taxonomy.php b/templates/meta-taxonomy.php index 977bcf5b833..db421649524 100644 --- a/templates/meta-taxonomy.php +++ b/templates/meta-taxonomy.php @@ -12,6 +12,12 @@ * @package AMP */ +/** + * Context. + * + * @var AMP_Post_Template $this + */ + $categories = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'amp' ), '', $this->ID ); ?> diff --git a/templates/meta-time.php b/templates/meta-time.php index 9d0058552ea..f78fc5a25b0 100644 --- a/templates/meta-time.php +++ b/templates/meta-time.php @@ -12,6 +12,12 @@ * @package AMP */ +/** + * Context. + * + * @var AMP_Post_Template $this + */ + ?>