summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/extensions')
-rw-r--r--plugins/jetpack/extensions/README.md225
-rw-r--r--plugins/jetpack/extensions/blocks/business-hours/business-hours.php15
-rw-r--r--plugins/jetpack/extensions/blocks/business-hours/components/day-edit.js200
-rw-r--r--plugins/jetpack/extensions/blocks/business-hours/components/day-preview.js53
-rw-r--r--plugins/jetpack/extensions/blocks/business-hours/edit.js104
-rw-r--r--plugins/jetpack/extensions/blocks/business-hours/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/business-hours/editor.scss128
-rw-r--r--plugins/jetpack/extensions/blocks/business-hours/index.js101
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/components/jetpack-contact-form.js266
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-checkbox.js62
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-label.js35
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-multiple.js122
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-textarea.js59
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field.js62
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/components/jetpack-option.js80
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/editor.scss696
-rw-r--r--plugins/jetpack/extensions/blocks/contact-form/index.js462
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/address/edit.js125
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/address/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/address/index.js71
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/address/save.js85
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/edit.js51
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/editor.scss18
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/email/edit.js15
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/email/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/email/index.js42
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/email/save.js36
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/index.js57
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/phone/edit.js19
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/phone/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/phone/index.js42
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/phone/save.js47
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/style.scss3
-rw-r--r--plugins/jetpack/extensions/blocks/contact-info/view.js5
-rw-r--r--plugins/jetpack/extensions/blocks/gif/edit.js217
-rw-r--r--plugins/jetpack/extensions/blocks/gif/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/gif/editor.scss86
-rw-r--r--plugins/jetpack/extensions/blocks/gif/gif.php32
-rw-r--r--plugins/jetpack/extensions/blocks/gif/index.js61
-rw-r--r--plugins/jetpack/extensions/blocks/gif/style.scss40
-rw-r--r--plugins/jetpack/extensions/blocks/gif/view.js4
-rw-r--r--plugins/jetpack/extensions/blocks/likes/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/likes/index.js8
-rw-r--r--plugins/jetpack/extensions/blocks/likes/likes-checkbox.js45
-rw-r--r--plugins/jetpack/extensions/blocks/mailchimp/edit.js235
-rw-r--r--plugins/jetpack/extensions/blocks/mailchimp/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/mailchimp/editor.scss29
-rw-r--r--plugins/jetpack/extensions/blocks/mailchimp/index.js72
-rw-r--r--plugins/jetpack/extensions/blocks/mailchimp/mailchimp.php107
-rw-r--r--plugins/jetpack/extensions/blocks/mailchimp/view.js91
-rw-r--r--plugins/jetpack/extensions/blocks/mailchimp/view.scss34
-rw-r--r--plugins/jetpack/extensions/blocks/map/add-point/index.js42
-rw-r--r--plugins/jetpack/extensions/blocks/map/add-point/oval.svg19
-rw-r--r--plugins/jetpack/extensions/blocks/map/add-point/style.scss46
-rw-r--r--plugins/jetpack/extensions/blocks/map/component.js332
-rw-r--r--plugins/jetpack/extensions/blocks/map/edit.js283
-rw-r--r--plugins/jetpack/extensions/blocks/map/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/map/editor.scss28
-rw-r--r--plugins/jetpack/extensions/blocks/map/index.js28
-rw-r--r--plugins/jetpack/extensions/blocks/map/info-window/index.js52
-rw-r--r--plugins/jetpack/extensions/blocks/map/location-search/index.js108
-rw-r--r--plugins/jetpack/extensions/blocks/map/locations/index.js81
-rw-r--r--plugins/jetpack/extensions/blocks/map/locations/style.scss27
-rw-r--r--plugins/jetpack/extensions/blocks/map/lookup/index.js230
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-marker/index.js65
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-marker/style.scss6
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-theme-picker/index.js50
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpgbin85291 -> 0 bytes
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_default.jpgbin113462 -> 0 bytes
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpgbin160272 -> 0 bytes
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpgbin108702 -> 0 bytes
-rw-r--r--plugins/jetpack/extensions/blocks/map/map-theme-picker/style.scss36
-rw-r--r--plugins/jetpack/extensions/blocks/map/map.php92
-rw-r--r--plugins/jetpack/extensions/blocks/map/mapbox-map-formatter/index.js22
-rw-r--r--plugins/jetpack/extensions/blocks/map/save.js38
-rw-r--r--plugins/jetpack/extensions/blocks/map/settings.js104
-rw-r--r--plugins/jetpack/extensions/blocks/map/style.scss22
-rw-r--r--plugins/jetpack/extensions/blocks/map/view.js33
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/edit.js127
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/editor.scss144
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/index.js70
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/markdown.php12
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/renderer.js28
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/save.js8
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/test/__snapshots__/markdown-renderer.js.snap63
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/test/fixtures/source.js63
-rw-r--r--plugins/jetpack/extensions/blocks/markdown/test/markdown-renderer.js17
-rw-r--r--plugins/jetpack/extensions/blocks/membership-button/edit.jsx392
-rw-r--r--plugins/jetpack/extensions/blocks/membership-button/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/membership-button/editor.scss38
-rw-r--r--plugins/jetpack/extensions/blocks/membership-button/index.js69
-rw-r--r--plugins/jetpack/extensions/blocks/membership-button/view.js79
-rw-r--r--plugins/jetpack/extensions/blocks/membership-button/view.scss49
-rw-r--r--plugins/jetpack/extensions/blocks/pinterest/pinterest.php26
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/connection-verify.js112
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/connection.js100
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/editor.scss100
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/form-unwrapped.js118
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/form.js72
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/index.js50
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/panel.js51
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/service-icon.js64
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/settings-button.js73
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/store/actions.js41
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/store/controls.js19
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/store/effects.js32
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/store/index.js24
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/store/middlewares.js40
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/store/reducer.js18
-rw-r--r--plugins/jetpack/extensions/blocks/publicize/store/selectors.js24
-rw-r--r--plugins/jetpack/extensions/blocks/rating-star/rating-meta.php108
-rw-r--r--plugins/jetpack/extensions/blocks/rating-star/rating-star.php66
-rw-r--r--plugins/jetpack/extensions/blocks/recurring-payments/recurring-payments.php (renamed from plugins/jetpack/extensions/blocks/membership-button/membership-button.php)8
-rw-r--r--plugins/jetpack/extensions/blocks/related-posts/edit.js252
-rw-r--r--plugins/jetpack/extensions/blocks/related-posts/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/related-posts/index.js75
-rw-r--r--plugins/jetpack/extensions/blocks/related-posts/style.scss85
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/components/edit.js114
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/components/save.js12
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/constants.js5
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/editor.scss55
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/index.js46
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/repeat-visitor.php4
-rw-r--r--plugins/jetpack/extensions/blocks/repeat-visitor/view.js35
-rw-r--r--plugins/jetpack/extensions/blocks/seo/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/seo/editor.scss15
-rw-r--r--plugins/jetpack/extensions/blocks/seo/index.js39
-rw-r--r--plugins/jetpack/extensions/blocks/seo/panel.js54
-rw-r--r--plugins/jetpack/extensions/blocks/sharing/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/sharing/index.js8
-rw-r--r--plugins/jetpack/extensions/blocks/sharing/sharing-checkbox.js45
-rw-r--r--plugins/jetpack/extensions/blocks/shortlinks/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/shortlinks/index.js45
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/constants.js39
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/edit.js579
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/editor.scss63
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/featured-media.js69
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/help-message.js25
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/help-message.scss23
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/index.js131
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/paypal-button-2x.pngbin8186 -> 0 bytes
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/paypal-button.pngbin7496 -> 0 bytes
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.js68
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.scss93
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/save.js9
-rw-r--r--plugins/jetpack/extensions/blocks/simple-payments/utils.js29
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/create-swiper.js48
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/edit.js249
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/editor.scss44
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/index.js93
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/save.js15
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/slideshow.js232
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/slideshow.php161
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/style.scss165
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/swiper-callbacks.js95
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/transforms.js78
-rw-r--r--plugins/jetpack/extensions/blocks/slideshow/view.js70
-rw-r--r--plugins/jetpack/extensions/blocks/subscriptions/edit.js81
-rw-r--r--plugins/jetpack/extensions/blocks/subscriptions/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/subscriptions/index.js85
-rw-r--r--plugins/jetpack/extensions/blocks/subscriptions/save.js17
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/constants.js28
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/css-gram.scss86
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/constants.js27
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/image.js51
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/index.js81
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/column.js3
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/gallery.js7
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/index.js144
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js104
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/ratios.js280
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/resize.js107
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/row.js8
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/square.js33
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/save.js31
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/edit.js289
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/editor.scss148
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/filter-toolbar.js136
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js147
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/save.js46
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/index.js212
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/column.js3
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/gallery.js7
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/index.js160
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/index.js104
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/ratios.js280
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/resize.js107
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/index.js.snap98
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/ratios.js.snap30
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/fixtures/ratios.js16
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/index.js21
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/ratios.js11
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/row.js8
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/square.js33
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/layout/test/fixtures/image-sets.js103
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/save.js30
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php15
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/variables.scss2
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/view.js64
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/view.scss115
-rw-r--r--plugins/jetpack/extensions/blocks/videopress/edit.js185
-rw-r--r--plugins/jetpack/extensions/blocks/videopress/editor.js119
-rw-r--r--plugins/jetpack/extensions/blocks/videopress/index.js9
-rw-r--r--plugins/jetpack/extensions/blocks/videopress/loading.js13
-rw-r--r--plugins/jetpack/extensions/blocks/videopress/save.js37
-rw-r--r--plugins/jetpack/extensions/blocks/wordads/constants.js61
-rw-r--r--plugins/jetpack/extensions/blocks/wordads/edit.js56
-rw-r--r--plugins/jetpack/extensions/blocks/wordads/editor.js7
-rw-r--r--plugins/jetpack/extensions/blocks/wordads/editor.scss52
-rw-r--r--plugins/jetpack/extensions/blocks/wordads/format-picker.js59
-rw-r--r--plugins/jetpack/extensions/blocks/wordads/index.js66
-rw-r--r--plugins/jetpack/extensions/blocks/wordads/wordads.php7
-rw-r--r--plugins/jetpack/extensions/editor.js5
-rw-r--r--plugins/jetpack/extensions/index.json24
-rw-r--r--plugins/jetpack/extensions/shared/styles/gutenberg-colors.scss93
-rw-r--r--plugins/jetpack/extensions/shared/styles/gutenberg-variables.scss22
-rw-r--r--plugins/jetpack/extensions/shared/styles/jetpack-variables.scss1
-rw-r--r--plugins/jetpack/extensions/view.js4
226 files changed, 579 insertions, 15416 deletions
diff --git a/plugins/jetpack/extensions/README.md b/plugins/jetpack/extensions/README.md
deleted file mode 100644
index 147e57b6..00000000
--- a/plugins/jetpack/extensions/README.md
+++ /dev/null
@@ -1,225 +0,0 @@
-# Jetpack Block Editor Extensions
-
-This directory contains the source code for extensions in the block editor,
-also known as Gutenberg, [that was introduced in WordPress 5.0](https://wordpress.org/news/2018/12/bebo/).
-
-## Extension Type
-
-We define different types of block editor extensions:
-
-- Blocks are available in the editor itself.
-- Plugins are available in the Jetpack sidebar that appears on the right side of the block editor.
-
-## Extension Structure
-
-Extensions in the `extensions/blocks` folder loosely follow this structure:
-
-```
-.
-└── block-or-plugin-name/
- ├── block-or-plugin-name.php ← PHP file where the block and its assets are registered.
- ├── editor.js ← script loaded only in the editor
- ├── editor.scss ← styles loaded only in the editor
- ├── view.js ← script loaded in the editor and theme
- └── view.scss ← styles loaded in the editor and theme
-```
-
-If your block depends on another block, place them all in extensions folder:
-
-```
-.
-├── block-name/
-└── sub-blockname/
-```
-
-## Developing block editor extensions in Jetpack
-
-### High-level overview of the development flow
-
-1. Use the [Jetpack Docker environment](https://github.com/Automattic/jetpack/tree/master/docker#readme).
-1. Start a new branch.
-1. Add your new extension's source files to the extensions/blocks directory.
-And add your extensions' slug to the beta array in `extensions/index.json`. You can use Jetpack-CLI command to scaffold the block (see below).
-By keeping your extension in the beta array, it's safe to do small PRs and merge frequently.
-1. Or modify existing extensions in the same folder.
-1. Run `yarn build-extensions [--watch]` to compile your changes.
-1. Now test your changes in your Docker environment's wp-admin.
-1. Open a PR, and a WordPress.com diff will be automatically generated with your changes.
-1. Test the WordPress.com diff
-1. Once the code works well in both environments and has been approved by a Jetpack crew member, you can merge your branch!
-1. When your block is ready to be shipped, move your extensions' slug from beta to production array in `extensions/index.json`
-
-### Beta Extensions
-
-Generally, all new extensions should start out as a beta.
-
-- Before you develop, remember to add your extension's slug to the beta array in `extensions/index.json`.
-- In the `wp-config.php` for your Docker environment (`docker/wordpress/wp-config.php`) or in your custom mu-plugins file (`docker/mu-plugins/yourfile.php`), enable beta extensions with the following snippet: `define( 'JETPACK_BETA_BLOCKS', true );`
-- In the WordPress.com environment, a12s will be able to see beta extensions with no further configuration
-- Once you've successfully beta tested your new extension, you can open new PR to make your extension live!
-- Simply move the extension's slug out of the beta array and into the production array in `extensions/index.json`.
-
-### Testing
-
-Run `yarn test-extensions [--watch]` to run tests written in [Jest](https://jestjs.io/en/).
-
-Note that adding [Jest snapshot tests](https://jestjs.io/docs/en/snapshot-testing) for block's `save` methods is problematic because many core packages relying on `window` that is not present when testing with Jest. See [prior exploration](https://github.com/Automattic/wp-calypso/pull/30727).
-
-## Scaffolding blocks with WP-CLI
-
-We have a command in WP-CLI that allows to scaffold Jetpack blocks. Its syntax is as follows:
-
-`wp jetpack scaffold <type> <title> [--slug] [--description] [--keywords]`
-
-**Currently the only `type` is `block`.**
-
-### Options
-
-- **title**: Block name, also used to create the slug. This parameter is required. If it's something like _Logo gallery_, the slug will be `logo-gallery`. It's also used to generate the class name when an external edit component is requested. Following this example, it would be `LogoGalleryEdit`.
-- **--slug**: Specific slug to identify the block that overrides the one generated base don the title.
-- **--description**: Allows to provide a text description of the block.
-- **--keywords**: Provide up to three keywords separated by a comma so users when they search for a block in the editor.
-
-### Files
-
-All files will be created in a directory under `extensions/blocks/` named after the block title or a specific given slug. For a hypothetical **Jukebox** block, it will create the following files
-
-- `extensions/blocks/jukebox/`
-- `extensions/blocks/jukebox/jukebox.php`
-- `extensions/blocks/jukebox/index.js`
-- `extensions/blocks/jukebox/editor.js`
-- `extensions/blocks/jukebox/editor.scss`
-- `extensions/blocks/jukebox/edit.js`
-
-Additionally, the slug of the new block will be added to the `beta` array in the file `extensions/index.json`.
-Since it's added to the beta array, you need to load the beta blocks as explained above to be able to test this block.
-
-### Examples
-
-`wp jetpack scaffold block "Cool Block"`
-
-`wp jetpack scaffold block "Amazing Rock" --slug="good-music" --description="Rock the best music on your site"`
-
-`wp jetpack scaffold block "Jukebox" --keywords="music, audio, media"`
-
-### Can I use Jurassic Ninja to test blocks?
-
-Yes! Just like any other changes in Jetpack, also blocks work in Jurassic Ninja.
-
-Simply add branch name to the URL: jurassic.ninja/create/?jetpack-beta&branch=master or use other ninjastic features.
-
-### How do I merge extensions to Jetpack
-
-- Jetpack is released once a month, so be sure your team is aware of [upcoming code freezes](https://github.com/Automattic/Jetpack/milestones).
-- Make sure you and your team have tested your PR in both the Jetpack environment, and the WordPress.com environment.
-- Additionally, your PR will require approval from a Jetpack crew member.
-- Once merged, your extension will appear in the next release.
-
-### How do I merge extensions to WordPress.com?
-
-- Merge to Jetpack master first.
-- Now, merge the auto-generated diff on WordPress.com.
-- There's no need to wait on release schedules, in fact it is best if you merge your WordPress.com diff immediately after you've merged to Jetpack master.
-
-### What if I need to manually create a WordPress.com diff?
-
-You can build extensions from the Jetpack folder to your local sandbox folder and sync the whole sandbox like you always do:
-
-```bash
-yarn clean-extensions
-yarn build-extensions \
- --output-path /PATH_TO_YOUR_SANDBOX/wp-content/mu-plugins/jetpack/_inc/blocks/ \
- --watch
-```
-
-Alternatively, if you don’t need to touch PHP files, you can build extensions in the Jetpack folder without --output-path and use rsync to push files directly to your sandbox:
-
-```bash
-rsync -az --delete _inc/blocks/ \
- YOUR_WPCOM_SANDBOX:/BLOCKS_PATH_IN_YOUR_SANDBOX/
-```
-
-To test extensions for a Simple site in Calypso, sandbox the simple site URL (`example.wordpress.com`). Calypso loads Gutenberg from simple sites’ wp-admin in an iframe.
-
-## Good to know when developing Gutenberg extensions
-
-## The Build
-
-- Compiled extensions are output to `_inc/blocks`
-- You can view the various build commands in `package.json`
-- You can see the build configuration in `webpack.config.extensions.js`
-
-If you need to modify the build process, bear in mind that config files are also
-synced to WordPress.com via Fusion. Consult with a Jetpack crew member to ensure
-you test the new build in both environments.
-
-## Debugging
-
-Setting these might be useful for debugging with block editor:
-
-```php
-define( 'SCRIPT_DEBUG', true );
-define( 'GUTENBERG_DEVELOPMENT_MODE', true );
-```
-
-You could modify `SCRIPT_DEBUG` from `docker/wordpress/wp-config.php` in your Docker environment and add `GUTENBERG_DEVELOPMENT_MODE` there as well, or in your custom mu-plugins file (`docker/mu-plugins/yourfile.php`).
-
-[G Debugger](https://wordpress.org/plugins/g-debugger/) plugin might come handy, too.
-
-### Don't worry about dependencies
-
-The build takes care of core dependencies for both editor and view scripts. React, Lodash and `@wordpress/*` [dependencies](https://github.com/WordPress/gutenberg/blob/master/docs/contributors/scripts.md) are externalized and automatically enqueued in PHP for your extension.
-
-Extensions _always_ get [Gutenberg's polyfill scripts](https://github.com/WordPress/gutenberg/blob/master/docs/contributors/scripts.md#polyfill-scripts) enqueued so you can safely use methods not supported by older browsers such as IE11.
-
-### Jetpack plugin sidebar
-
-Jetpack adds its own [plugin sidebar](https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/plugin-sidebar-0/plugin-sidebar-1-up-and-running/) to the block editor. You can find it by choosing "Jetpack" from block the editor's ellipsis menu or by pressing the Jetpack icon in the "pinned plugins" toolbar.
-
-The sidebar itself is always registered in the editor and populated using the [Slot Fill](https://github.com/WordPress/gutenberg/tree/master/packages/components/src/slot-fill#readme) mechanism.
-
-Use the `JetpackPluginSidebar` component to render from anywhere in your plugin's code:
-
-```jsx
-import JetpackPluginSidebar from '../../shared/jetpack-plugin-sidebar';
-
-<JetpackPluginSidebar>
- <PanelBody title={ __( 'My sidebar section', 'jetpack' ) }>
- <p>Jetpack is Bestpack!</p>
- </PanelBody>
-</JetpackPluginSidebar>
-```
-
-The sidebar won't show up at all if nothing is being rendered in the sidebar's "slot".
-
-Remember to be mindful of what post types you want to enable your sidebar section for: e.g. posts, pages, custom post types, and re-usable block post type (`/wp-admin/edit.php?post_type=wp_block`).
-
-See [Publicize](blocks/publicize/index.js) and [Shortlinks](blocks/shortlinks/index.js) for examples how to limit functionality only to some specific post types or posts. The [Likes](blocks/likes/likes-checkbox.js) & [Sharing](blocks/sharing/sharing-checkbox.js) extensions are a great example of how to [output](shared/jetpack-likes-and-sharing-panel.js) content from several extensions to one sidebar section using "slots".
-
-### i18n
-
-As of 04/2019, `wp.i18n` [doesn't support React elements in strings](https://github.com/WordPress/gutenberg/issues/9846). You will have to structure your copy so that links and other HTML can be translated separately.
-
-Not possible:
-
-```js
-__( 'Still confused? Check out <a>documentation</a> for more!' )
-```
-
-Possible:
-
-```jsx
-{ __( 'Still confused?' ) } <a>{ __( 'Check out documentation for more!' ) }</a>
-```
-
-### Colors
-
-To stay consistent with Gutenberg, your extensions should follow [Gutenberg styles and visuals](https://wordpress.org/gutenberg/handbook/designers-developers/designers/block-design/).
-
-Use Gutenberg color variables where possible by importing them in your stylesheet from `extensions/shared/styles/gutenberg-colors.scss`.
-
-The build pipeline also supports [Muriel colors](https://github.com/Automattic/color-studio) via SASS variables (`$muriel-pink-300`) and CSS custom properties (`var( --muriel-pink-300 )`) without specifically importing them first. Prefer CSS custom properties if possible.
-
-### Icons
-
-Please use outline versions of [Material icons](https://material.io/tools/icons/?style=outline) to stay in line with Muriel guidelines. Don't rely on icons used in WordPress core to avoid visual mixing up with core blocks.
diff --git a/plugins/jetpack/extensions/blocks/business-hours/business-hours.php b/plugins/jetpack/extensions/blocks/business-hours/business-hours.php
index e8a5e261..d3afa01d 100644
--- a/plugins/jetpack/extensions/blocks/business-hours/business-hours.php
+++ b/plugins/jetpack/extensions/blocks/business-hours/business-hours.php
@@ -105,36 +105,39 @@ function jetpack_business_hours_render( $attributes ) {
}
foreach ( $attributes['days'] as $day ) {
- $content .= '<dt class="' . esc_attr( $day['name'] ) . '">' .
+ $content .= '<div class="jetpack-business-hours__item"><dt class="' . esc_attr( $day['name'] ) . '">' .
ucfirst( $wp_locale->get_weekday( array_search( $day['name'], $days, true ) ) ) .
'</dt>';
$content .= '<dd class="' . esc_attr( $day['name'] ) . '">';
$days_hours = '';
- foreach ( $day['hours'] as $hour ) {
+ foreach ( $day['hours'] as $key => $hour ) {
$opening = strtotime( $hour['opening'] );
$closing = strtotime( $hour['closing'] );
if ( ! $opening || ! $closing ) {
continue;
}
$days_hours .= sprintf(
- /* Translators: Business opening hours info. */
- _x( 'From %1$s to %2$s', 'from business opening hour to closing hour', 'jetpack' ),
+ '%1$s - %2$s',
date( $time_format, $opening ),
date( $time_format, $closing )
);
- $days_hours .= '<br />';
+ if ( $key + 1 < count( $day['hours'] ) ) {
+ $days_hours .= ', ';
+ }
}
if ( empty( $days_hours ) ) {
$days_hours = esc_html__( 'Closed', 'jetpack' );
}
$content .= $days_hours;
- $content .= '</dd>';
+ $content .= '</dd></div>';
}
$content .= '</dl>';
+ Jetpack_Gutenberg::load_assets_as_required( 'business-hours' );
+
/**
* Allows folks to filter the HTML content for the Business Hours block
*
diff --git a/plugins/jetpack/extensions/blocks/business-hours/components/day-edit.js b/plugins/jetpack/extensions/blocks/business-hours/components/day-edit.js
deleted file mode 100644
index bab6958a..00000000
--- a/plugins/jetpack/extensions/blocks/business-hours/components/day-edit.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * External dependencies
- */
-import classNames from 'classnames';
-import { __ } from '@wordpress/i18n';
-import { Component, Fragment } from '@wordpress/element';
-import { IconButton, TextControl, ToggleControl } from '@wordpress/components';
-import { isEmpty } from 'lodash';
-
-const defaultOpen = '09:00';
-const defaultClose = '17:00';
-
-class DayEdit extends Component {
- renderInterval = ( interval, intervalIndex ) => {
- const { day } = this.props;
- const { opening, closing } = interval;
- return (
- <Fragment key={ intervalIndex }>
- <div className="business-hours__row">
- <div className={ classNames( day.name, 'business-hours__day' ) }>
- { intervalIndex === 0 && this.renderDayToggle() }
- </div>
- <div className={ classNames( day.name, 'business-hours__hours' ) }>
- <TextControl
- type="time"
- label={ __( 'Opening', 'jetpack' ) }
- value={ opening }
- className="business-hours__open"
- placeholder={ defaultOpen }
- onChange={ value => {
- this.setHour( value, 'opening', intervalIndex );
- } }
- />
- <TextControl
- type="time"
- label={ __( 'Closing', 'jetpack' ) }
- value={ closing }
- className="business-hours__close"
- placeholder={ defaultClose }
- onChange={ value => {
- this.setHour( value, 'closing', intervalIndex );
- } }
- />
- </div>
- <div className="business-hours__remove">
- { day.hours.length > 1 && (
- <IconButton
- isSmall
- isLink
- icon="trash"
- onClick={ () => {
- this.removeInterval( intervalIndex );
- } }
- />
- ) }
- </div>
- </div>
- { intervalIndex === day.hours.length - 1 && (
- <div className="business-hours__row business-hours-row__add">
- <div className={ classNames( day.name, 'business-hours__day' ) }>&nbsp;</div>
- <div className={ classNames( day.name, 'business-hours__hours' ) }>
- <IconButton
- isLink
- label={ __( 'Add Hours', 'jetpack' ) }
- onClick={ this.addInterval }
- >
- { __( 'Add Hours', 'jetpack' ) }
- </IconButton>
- </div>
- <div className="business-hours__remove">&nbsp;</div>
- </div>
- ) }
- </Fragment>
- );
- };
-
- setHour = ( hourValue, hourType, hourIndex ) => {
- const { day, attributes, setAttributes } = this.props;
- const { days } = attributes;
- setAttributes( {
- days: days.map( value => {
- if ( value.name === day.name ) {
- return {
- ...value,
- hours: value.hours.map( ( hour, index ) => {
- if ( index === hourIndex ) {
- return {
- ...hour,
- [ hourType ]: hourValue,
- };
- }
- return hour;
- } ),
- };
- }
- return value;
- } ),
- } );
- };
-
- toggleClosed = nextValue => {
- const { day, attributes, setAttributes } = this.props;
- const { days } = attributes;
-
- setAttributes( {
- days: days.map( value => {
- if ( value.name === day.name ) {
- const hours = nextValue
- ? [
- {
- opening: defaultOpen,
- closing: defaultClose,
- },
- ]
- : [];
- return {
- ...value,
- hours,
- };
- }
- return value;
- } ),
- } );
- };
-
- addInterval = () => {
- const { day, attributes, setAttributes } = this.props;
- const { days } = attributes;
- day.hours.push( { opening: '', closing: '' } );
- setAttributes( {
- days: days.map( value => {
- if ( value.name === day.name ) {
- return {
- ...value,
- hours: day.hours,
- };
- }
- return value;
- } ),
- } );
- };
-
- removeInterval = hourIndex => {
- const { day, attributes, setAttributes } = this.props;
- const { days } = attributes;
-
- setAttributes( {
- days: days.map( value => {
- if ( day.name === value.name ) {
- return {
- ...value,
- hours: value.hours.filter( ( hour, index ) => {
- return hourIndex !== index;
- } ),
- };
- }
- return value;
- } ),
- } );
- };
-
- isClosed() {
- const { day } = this.props;
- return isEmpty( day.hours );
- }
-
- renderDayToggle() {
- const { day, localization } = this.props;
- return (
- <Fragment>
- <span className="business-hours__day-name">{ localization.days[ day.name ] }</span>
- <ToggleControl
- label={ this.isClosed() ? __( 'Closed', 'jetpack' ) : __( 'Open', 'jetpack' ) }
- checked={ ! this.isClosed() }
- onChange={ this.toggleClosed }
- />
- </Fragment>
- );
- }
-
- renderClosed() {
- const { day } = this.props;
- return (
- <div className="business-hours__row business-hours-row__closed">
- <div className={ classNames( day.name, 'business-hours__day' ) }>
- { this.renderDayToggle() }
- </div>
- <div className={ classNames( day.name, 'closed', 'business-hours__hours' ) }>&nbsp;</div>
- <div className="business-hours__remove">&nbsp;</div>
- </div>
- );
- }
-
- render() {
- const { day } = this.props;
- return this.isClosed() ? this.renderClosed() : day.hours.map( this.renderInterval );
- }
-}
-
-export default DayEdit;
diff --git a/plugins/jetpack/extensions/blocks/business-hours/components/day-preview.js b/plugins/jetpack/extensions/blocks/business-hours/components/day-preview.js
deleted file mode 100644
index be0dd24b..00000000
--- a/plugins/jetpack/extensions/blocks/business-hours/components/day-preview.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * External dependencies
- */
-import { _x, sprintf } from '@wordpress/i18n';
-import { Component, Fragment } from '@wordpress/element';
-import { date } from '@wordpress/date';
-import { isEmpty } from 'lodash';
-
-class DayPreview extends Component {
- formatTime( time ) {
- const { timeFormat } = this.props;
- const [ hours, minutes ] = time.split( ':' );
- const _date = new Date();
- if ( ! hours || ! minutes ) {
- return false;
- }
- _date.setHours( hours );
- _date.setMinutes( minutes );
- return date( timeFormat, _date );
- }
-
- renderInterval = ( interval, key ) => {
- return (
- <dd key={ key }>
- { sprintf(
- _x( 'From %s to %s', 'from business opening hour to closing hour', 'jetpack' ),
- this.formatTime( interval.opening ),
- this.formatTime( interval.closing )
- ) }
- </dd>
- );
- };
-
- render() {
- const { day, localization } = this.props;
- const hours = day.hours.filter(
- // remove any malformed or empty intervals
- interval => this.formatTime( interval.opening ) && this.formatTime( interval.closing )
- );
- return (
- <Fragment>
- <dt className={ day.name }>{ localization.days[ day.name ] }</dt>
- { isEmpty( hours ) ? (
- <dd>{ _x( 'Closed', 'business is closed on a full day', 'jetpack' ) }</dd>
- ) : (
- hours.map( this.renderInterval )
- ) }
- </Fragment>
- );
- }
-}
-
-export default DayPreview;
diff --git a/plugins/jetpack/extensions/blocks/business-hours/edit.js b/plugins/jetpack/extensions/blocks/business-hours/edit.js
deleted file mode 100644
index 7649fd45..00000000
--- a/plugins/jetpack/extensions/blocks/business-hours/edit.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-import classNames from 'classnames';
-import { __ } from '@wordpress/i18n';
-import { __experimentalGetSettings } from '@wordpress/date';
-import { BlockIcon } from '@wordpress/editor';
-import { Component } from '@wordpress/element';
-import { Placeholder } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import DayEdit from './components/day-edit';
-import DayPreview from './components/day-preview';
-import { icon } from '.';
-
-const defaultLocalization = {
- days: {
- Sun: __( 'Sunday', 'jetpack' ),
- Mon: __( 'Monday', 'jetpack' ),
- Tue: __( 'Tuesday', 'jetpack' ),
- Wed: __( 'Wednesday', 'jetpack' ),
- Thu: __( 'Thursday', 'jetpack' ),
- Fri: __( 'Friday', 'jetpack' ),
- Sat: __( 'Saturday', 'jetpack' ),
- },
- startOfWeek: 0,
-};
-
-class BusinessHours extends Component {
- state = {
- localization: defaultLocalization,
- hasFetched: false,
- };
-
- componentDidMount() {
- this.apiFetch();
- }
-
- apiFetch() {
- this.setState( { data: defaultLocalization }, () => {
- apiFetch( { path: '/wpcom/v2/business-hours/localized-week' } ).then(
- data => {
- this.setState( { localization: data, hasFetched: true } );
- },
- () => {
- this.setState( { localization: defaultLocalization, hasFetched: true } );
- }
- );
- } );
- }
-
- render() {
- const { attributes, className, isSelected } = this.props;
- const { days } = attributes;
- const { localization, hasFetched } = this.state;
- const { startOfWeek } = localization;
- const localizedWeek = days.concat( days.slice( 0, startOfWeek ) ).slice( startOfWeek );
-
- if ( ! hasFetched ) {
- return (
- <Placeholder
- icon={ <BlockIcon icon={ icon } /> }
- label={ __( 'Loading business hours', 'jetpack' ) }
- />
- );
- }
-
- if ( ! isSelected ) {
- const settings = __experimentalGetSettings();
- const {
- formats: { time },
- } = settings;
- return (
- <dl className={ classNames( className, 'jetpack-business-hours' ) }>
- { localizedWeek.map( ( day, key ) => {
- return (
- <DayPreview
- key={ key }
- day={ day }
- localization={ localization }
- timeFormat={ time }
- />
- );
- } ) }
- </dl>
- );
- }
-
- return (
- <div className={ classNames( className, 'is-edit' ) }>
- { localizedWeek.map( ( day, key ) => {
- return (
- <DayEdit key={ key } day={ day } localization={ localization } { ...this.props } />
- );
- } ) }
- </div>
- );
- }
-}
-
-export default BusinessHours;
diff --git a/plugins/jetpack/extensions/blocks/business-hours/editor.js b/plugins/jetpack/extensions/blocks/business-hours/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/business-hours/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/business-hours/editor.scss b/plugins/jetpack/extensions/blocks/business-hours/editor.scss
deleted file mode 100644
index 18073276..00000000
--- a/plugins/jetpack/extensions/blocks/business-hours/editor.scss
+++ /dev/null
@@ -1,128 +0,0 @@
-@import '../../shared/styles/gutenberg-variables.scss';
-
-.wp-block-jetpack-business-hours {
- overflow: hidden;
-
- .business-hours__row {
- display: flex;
-
- &.business-hours-row__add,
- &.business-hours-row__closed {
- margin-bottom: 20px;
- }
-
- .business-hours__day {
- width: 44%;
- display: flex;
- align-items: baseline;
-
- .business-hours__day-name {
- width: 60%;
- font-weight: bold;
- overflow-x: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .components-form-toggle {
- margin-right: 4px;
- }
- }
-
- .business-hours__hours {
- width: 44%;
- margin: 0;
- display: flex;
- align-items: center;
- flex-wrap: wrap;
-
- .components-base-control {
- display: inline-block;
- margin-bottom: 0;
- width: 48%;
-
- &.business-hours__open {
- margin-right: 4%;
- }
-
- .components-base-control__label {
- margin-bottom: 0;
- }
- }
- }
- }
-
- .business-hours__remove {
- align-self: flex-end;
- margin-bottom: 8px;
- text-align: center;
- width: 10%;
- }
-
- .business-hours-row__add button:hover {
- box-shadow: none !important;
- }
-
- .business-hours__remove button {
- display: block;
- margin: 0 auto;
- }
-
- .business-hours-row__add .components-button.is-default:hover,
- .business-hours__remove .components-button.is-default:hover,
- .business-hours-row__add .components-button.is-default:focus,
- .business-hours__remove .components-button.is-default:focus,
- .business-hours-row__add .components-button.is-default:active,
- .business-hours__remove .components-button.is-default:active {
- background: none;
- box-shadow: none;
- }
-}
-
-/**
- * We consider the editor area to be small when the business hours block is:
- * - within a column block
- * - in a screen < xlarge size with the sidebar open
- * - in a screen < small size
- * In these cases we'll apply small screen styles.
- */
-@mixin editor-area-is-small {
- @media ( max-width: $break-xlarge ) {
- .is-sidebar-opened {
- @content;
- }
- }
- @media ( max-width: $break-small ) {
- @content;
- }
-
- .wp-block-columns {
- @content;
- }
-}
-
-@include editor-area-is-small() {
- .wp-block-jetpack-business-hours {
- .business-hours__row {
- flex-wrap: wrap;
-
- &.business-hours-row__add {
- .business-hours__day,
- .business-hours__remove {
- display: none;
- }
- }
-
- .business-hours__day {
- width: 100%;
- }
-
- .business-hours__hours {
- width: 78%;
- }
- .business-hours__remove {
- width: 18%;
- }
- }
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/business-hours/index.js b/plugins/jetpack/extensions/blocks/business-hours/index.js
deleted file mode 100644
index ee307afc..00000000
--- a/plugins/jetpack/extensions/blocks/business-hours/index.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import './editor.scss';
-import BusinessHours from './edit';
-import renderMaterialIcon from '../../shared/render-material-icon';
-
-/**
- * Block Registrations:
- */
-
-export const name = 'business-hours';
-
-export const icon = renderMaterialIcon(
- <Path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z" />
-);
-
-export const settings = {
- title: __( 'Business Hours', 'jetpack' ),
- description: __( 'Display opening hours for your business.', 'jetpack' ),
- icon,
- category: 'jetpack',
- supports: {
- html: true,
- },
- keywords: [
- _x( 'opening hours', 'block search term', 'jetpack' ),
- _x( 'closing time', 'block search term', 'jetpack' ),
- _x( 'schedule', 'block search term', 'jetpack' ),
- ],
- attributes: {
- days: {
- type: 'array',
- default: [
- {
- name: 'Sun',
- hours: [], // Closed by default
- },
- {
- name: 'Mon',
- hours: [
- {
- opening: '09:00',
- closing: '17:00',
- },
- ],
- },
- {
- name: 'Tue',
- hours: [
- {
- opening: '09:00',
- closing: '17:00',
- },
- ],
- },
- {
- name: 'Wed',
- hours: [
- {
- opening: '09:00',
- closing: '17:00',
- },
- ],
- },
- {
- name: 'Thu',
- hours: [
- {
- opening: '09:00',
- closing: '17:00',
- },
- ],
- },
- {
- name: 'Fri',
- hours: [
- {
- opening: '09:00',
- closing: '17:00',
- },
- ],
- },
- {
- name: 'Sat',
- hours: [], // Closed by default
- },
- ],
- },
- },
-
- edit: props => <BusinessHours { ...props } />,
-
- save: () => null,
-};
diff --git a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-contact-form.js b/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-contact-form.js
deleted file mode 100644
index 952a3934..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-contact-form.js
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import emailValidator from 'email-validator';
-import { __, sprintf } from '@wordpress/i18n';
-import { Button, PanelBody, Path, Placeholder, TextControl } from '@wordpress/components';
-import { Component, Fragment } from '@wordpress/element';
-import { compose, withInstanceId } from '@wordpress/compose';
-import { InnerBlocks, InspectorControls } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import HelpMessage from '../../../shared/help-message';
-import renderMaterialIcon from '../../../shared/render-material-icon';
-import SubmitButton from '../../../shared/submit-button';
-
-const ALLOWED_BLOCKS = [
- 'jetpack/markdown',
- 'core/paragraph',
- 'core/image',
- 'core/heading',
- 'core/gallery',
- 'core/list',
- 'core/quote',
- 'core/shortcode',
- 'core/audio',
- 'core/code',
- 'core/cover',
- 'core/file',
- 'core/html',
- 'core/separator',
- 'core/spacer',
- 'core/subhead',
- 'core/table',
- 'core/verse',
- 'core/video',
-];
-
-class JetpackContactForm extends Component {
- constructor( ...args ) {
- super( ...args );
- this.onChangeSubject = this.onChangeSubject.bind( this );
- this.onBlurTo = this.onBlurTo.bind( this );
- this.onChangeTo = this.onChangeTo.bind( this );
- this.onChangeSubmit = this.onChangeSubmit.bind( this );
- this.onFormSettingsSet = this.onFormSettingsSet.bind( this );
- this.getToValidationError = this.getToValidationError.bind( this );
- this.renderToAndSubjectFields = this.renderToAndSubjectFields.bind( this );
- this.preventEnterSubmittion = this.preventEnterSubmittion.bind( this );
- this.hasEmailError = this.hasEmailError.bind( this );
-
- const to = args[ 0 ].attributes.to ? args[ 0 ].attributes.to : '';
- const error = to
- .split( ',' )
- .map( this.getToValidationError )
- .filter( Boolean );
-
- this.state = {
- toError: error && error.length ? error : null,
- };
- }
-
- getIntroMessage() {
- return __(
- 'You’ll receive an email notification each time someone fills out the form. Where should it go, and what should the subject line be?',
- 'jetpack'
- );
- }
-
- getEmailHelpMessage() {
- return __( 'You can enter multiple email addresses separated by commas.', 'jetpack' );
- }
-
- onChangeSubject( subject ) {
- this.props.setAttributes( { subject } );
- }
-
- getToValidationError( email ) {
- email = email.trim();
- if ( email.length === 0 ) {
- return false; // ignore the empty emails
- }
- if ( ! emailValidator.validate( email ) ) {
- return { email };
- }
- return false;
- }
-
- onBlurTo( event ) {
- const error = event.target.value
- .split( ',' )
- .map( this.getToValidationError )
- .filter( Boolean );
- if ( error && error.length ) {
- this.setState( { toError: error } );
- return;
- }
- }
-
- onChangeTo( to ) {
- const emails = to.trim();
- if ( emails.length === 0 ) {
- this.setState( { toError: null } );
- this.props.setAttributes( { to } );
- return;
- }
-
- this.setState( { toError: null } );
- this.props.setAttributes( { to } );
- }
-
- onChangeSubmit( submitButtonText ) {
- this.props.setAttributes( { submitButtonText } );
- }
-
- onFormSettingsSet( event ) {
- event.preventDefault();
- if ( this.state.toError ) {
- // don't submit the form if there are errors.
- return;
- }
- this.props.setAttributes( { hasFormSettingsSet: 'yes' } );
- }
-
- getfieldEmailError( errors ) {
- if ( errors ) {
- if ( errors.length === 1 ) {
- if ( errors[ 0 ] && errors[ 0 ].email ) {
- return sprintf( __( '%s is not a valid email address.', 'jetpack' ), errors[ 0 ].email );
- }
- return errors[ 0 ];
- }
-
- if ( errors.length === 2 ) {
- return sprintf(
- __( '%s and %s are not a valid email address.', 'jetpack' ),
- errors[ 0 ].email,
- errors[ 1 ].email
- );
- }
- const inValidEmails = errors.map( error => error.email );
- return sprintf(
- __( '%s are not a valid email address.', 'jetpack' ),
- inValidEmails.join( ', ' )
- );
- }
- return null;
- }
-
- preventEnterSubmittion( event ) {
- if ( event.key === 'Enter' ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
-
- renderToAndSubjectFields() {
- const fieldEmailError = this.state.toError;
- const { instanceId, attributes } = this.props;
- const { subject, to } = attributes;
- return (
- <Fragment>
- <TextControl
- aria-describedby={ `contact-form-${ instanceId }-email-${
- this.hasEmailError() ? 'error' : 'help'
- }` }
- label={ __( 'Email address', 'jetpack' ) }
- placeholder={ __( 'name@example.com', 'jetpack' ) }
- onKeyDown={ this.preventEnterSubmittion }
- value={ to }
- onBlur={ this.onBlurTo }
- onChange={ this.onChangeTo }
- />
- <HelpMessage isError id={ `contact-form-${ instanceId }-email-error` }>
- { this.getfieldEmailError( fieldEmailError ) }
- </HelpMessage>
- <HelpMessage id={ `contact-form-${ instanceId }-email-help` }>
- { this.getEmailHelpMessage() }
- </HelpMessage>
-
- <TextControl
- label={ __( 'Email subject line', 'jetpack' ) }
- value={ subject }
- placeholder={ __( "Let's work together", 'jetpack' ) }
- onChange={ this.onChangeSubject }
- />
- </Fragment>
- );
- }
-
- hasEmailError() {
- const fieldEmailError = this.state.toError;
- return fieldEmailError && fieldEmailError.length > 0;
- }
-
- render() {
- const { className, attributes } = this.props;
- const { hasFormSettingsSet } = attributes;
- const formClassnames = classnames( className, 'jetpack-contact-form', {
- 'has-intro': ! hasFormSettingsSet,
- } );
-
- return (
- <Fragment>
- <InspectorControls>
- <PanelBody title={ __( 'Email feedback settings', 'jetpack' ) }>
- { this.renderToAndSubjectFields() }
- </PanelBody>
- </InspectorControls>
- <div className={ formClassnames }>
- { ! hasFormSettingsSet && (
- <Placeholder
- label={ __( 'Form', 'jetpack' ) }
- icon={ renderMaterialIcon(
- <Path d="M13 7.5h5v2h-5zm0 7h5v2h-5zM19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zM11 6H6v5h5V6zm-1 4H7V7h3v3zm1 3H6v5h5v-5zm-1 4H7v-3h3v3z" />
- ) }
- >
- <form onSubmit={ this.onFormSettingsSet }>
- <p className="jetpack-contact-form__intro-message">{ this.getIntroMessage() }</p>
- { this.renderToAndSubjectFields() }
- <p className="jetpack-contact-form__intro-message">
- { __(
- '(If you leave these blank, notifications will go to the author with the post or page title as the subject line.)',
- 'jetpack'
- ) }
- </p>
- <div className="jetpack-contact-form__create">
- <Button isPrimary type="submit" disabled={ this.hasEmailError() }>
- { __( 'Add form', 'jetpack' ) }
- </Button>
- </div>
- </form>
- </Placeholder>
- ) }
- { hasFormSettingsSet && (
- <InnerBlocks
- allowedBlocks={ ALLOWED_BLOCKS }
- templateLock={ false }
- template={ [
- [
- 'jetpack/field-name',
- {
- required: true,
- },
- ],
- [
- 'jetpack/field-email',
- {
- required: true,
- },
- ],
- [ 'jetpack/field-url', {} ],
- [ 'jetpack/field-textarea', {} ],
- ] }
- />
- ) }
- { hasFormSettingsSet && <SubmitButton { ...this.props } /> }
- </div>
- </Fragment>
- );
- }
-}
-
-export default compose( [ withInstanceId ] )( JetpackContactForm );
diff --git a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-checkbox.js b/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-checkbox.js
deleted file mode 100644
index 05e49dc4..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-checkbox.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { BaseControl, PanelBody, TextControl, ToggleControl } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-import { InspectorControls } from '@wordpress/editor';
-import { withInstanceId } from '@wordpress/compose';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-
-const JetpackFieldCheckbox = ( {
- instanceId,
- required,
- label,
- setAttributes,
- isSelected,
- defaultValue,
- id,
-} ) => {
- return (
- <BaseControl
- id={ `jetpack-field-checkbox-${ instanceId }` }
- className="jetpack-field jetpack-field-checkbox"
- label={
- <Fragment>
- <input
- className="jetpack-field-checkbox__checkbox"
- type="checkbox"
- disabled
- checked={ defaultValue }
- />
- <JetpackFieldLabel
- required={ required }
- label={ label }
- setAttributes={ setAttributes }
- isSelected={ isSelected }
- />
- <InspectorControls>
- <PanelBody title={ __( 'Field Settings', 'jetpack' ) }>
- <ToggleControl
- label={ __( 'Default Checked State', 'jetpack' ) }
- checked={ defaultValue }
- onChange={ value => setAttributes( { defaultValue: value } ) }
- />
- <TextControl
- label={ __( 'ID', 'jetpack' ) }
- value={ id }
- onChange={ value => setAttributes( { id: value } ) }
- />
- </PanelBody>
- </InspectorControls>
- </Fragment>
- }
- />
- );
-};
-
-export default withInstanceId( JetpackFieldCheckbox );
diff --git a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-label.js b/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-label.js
deleted file mode 100644
index 0ee3d7ba..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-label.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { PlainText } from '@wordpress/editor';
-import { ToggleControl } from '@wordpress/components';
-
-const JetpackFieldLabel = ( { setAttributes, label, resetFocus, isSelected, required } ) => {
- return (
- <div className="jetpack-field-label">
- <PlainText
- value={ label }
- className="jetpack-field-label__input"
- onChange={ value => {
- resetFocus && resetFocus();
- setAttributes( { label: value } );
- } }
- placeholder={ __( 'Write label…', 'jetpack' ) }
- />
- { isSelected && (
- <ToggleControl
- label={ __( 'Required', 'jetpack' ) }
- className="jetpack-field-label__required"
- checked={ required }
- onChange={ value => setAttributes( { required: value } ) }
- />
- ) }
- { ! isSelected && required && (
- <span className="required">{ __( '(required)', 'jetpack' ) }</span>
- ) }
- </div>
- );
-};
-
-export default JetpackFieldLabel;
diff --git a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-multiple.js b/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-multiple.js
deleted file mode 100644
index 292bdeaf..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-multiple.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { BaseControl, IconButton, PanelBody, TextControl } from '@wordpress/components';
-import { Component, Fragment } from '@wordpress/element';
-import { InspectorControls } from '@wordpress/editor';
-import { withInstanceId } from '@wordpress/compose';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-import JetpackOption from './jetpack-option';
-
-class JetpackFieldMultiple extends Component {
- constructor( ...args ) {
- super( ...args );
- this.onChangeOption = this.onChangeOption.bind( this );
- this.addNewOption = this.addNewOption.bind( this );
- this.state = { inFocus: null };
- }
-
- onChangeOption( key = null, option = null ) {
- const newOptions = this.props.options.slice( 0 );
- if ( null === option ) {
- // Remove a key
- newOptions.splice( key, 1 );
- if ( key > 0 ) {
- this.setState( { inFocus: key - 1 } );
- }
- } else {
- // update a key
- newOptions.splice( key, 1, option );
- this.setState( { inFocus: key } ); // set the focus.
- }
- this.props.setAttributes( { options: newOptions } );
- }
-
- addNewOption( key = null ) {
- const newOptions = this.props.options.slice( 0 );
- let inFocus = 0;
- if ( 'object' === typeof key ) {
- newOptions.push( '' );
- inFocus = newOptions.length - 1;
- } else {
- newOptions.splice( key + 1, 0, '' );
- inFocus = key + 1;
- }
-
- this.setState( { inFocus: inFocus } );
- this.props.setAttributes( { options: newOptions } );
- }
-
- render() {
- const { type, instanceId, required, label, setAttributes, isSelected, id } = this.props;
- let { options } = this.props;
- let { inFocus } = this.state;
- if ( ! options.length ) {
- options = [ '' ];
- inFocus = 0;
- }
-
- return (
- <Fragment>
- <BaseControl
- id={ `jetpack-field-multiple-${ instanceId }` }
- className="jetpack-field jetpack-field-multiple"
- label={
- <JetpackFieldLabel
- required={ required }
- label={ label }
- setAttributes={ setAttributes }
- isSelected={ isSelected }
- resetFocus={ () => this.setState( { inFocus: null } ) }
- />
- }
- >
- <ol
- className="jetpack-field-multiple__list"
- id={ `jetpack-field-multiple-${ instanceId }` }
- >
- { options.map( ( option, index ) => (
- <JetpackOption
- type={ type }
- key={ index }
- option={ option }
- index={ index }
- onChangeOption={ this.onChangeOption }
- onAddOption={ this.addNewOption }
- isInFocus={ index === inFocus && isSelected }
- isSelected={ isSelected }
- />
- ) ) }
- </ol>
- { isSelected && (
- <IconButton
- className="jetpack-field-multiple__add-option"
- icon="insert"
- label={ __( 'Insert option', 'jetpack' ) }
- onClick={ this.addNewOption }
- >
- { __( 'Add option', 'jetpack' ) }
- </IconButton>
- ) }
- </BaseControl>
-
- <InspectorControls>
- <PanelBody title={ __( 'Field Settings', 'jetpack' ) }>
- <TextControl
- label={ __( 'ID', 'jetpack' ) }
- value={ id }
- onChange={ value => setAttributes( { id: value } ) }
- />
- </PanelBody>
- </InspectorControls>
- </Fragment>
- );
- }
-}
-
-export default withInstanceId( JetpackFieldMultiple );
diff --git a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-textarea.js b/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-textarea.js
deleted file mode 100644
index e2025941..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field-textarea.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Fragment } from '@wordpress/element';
-import { InspectorControls } from '@wordpress/editor';
-import { PanelBody, TextareaControl, TextControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-
-function JetpackFieldTextarea( {
- required,
- label,
- setAttributes,
- isSelected,
- defaultValue,
- placeholder,
- id,
-} ) {
- return (
- <Fragment>
- <div className="jetpack-field">
- <TextareaControl
- label={
- <JetpackFieldLabel
- required={ required }
- label={ label }
- setAttributes={ setAttributes }
- isSelected={ isSelected }
- />
- }
- placeholder={ placeholder }
- value={ placeholder }
- onChange={ value => setAttributes( { placeholder: value } ) }
- title={ __( 'Set the placeholder text', 'jetpack' ) }
- />
- </div>
- <InspectorControls>
- <PanelBody title={ __( 'Field Settings', 'jetpack' ) }>
- <TextControl
- label={ __( 'Default Value', 'jetpack' ) }
- value={ defaultValue }
- onChange={ value => setAttributes( { defaultValue: value } ) }
- />
- <TextControl
- label={ __( 'ID', 'jetpack' ) }
- value={ id }
- onChange={ value => setAttributes( { id: value } ) }
- />
- </PanelBody>
- </InspectorControls>
- </Fragment>
- );
-}
-
-export default JetpackFieldTextarea;
diff --git a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field.js b/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field.js
deleted file mode 100644
index 6a8269ff..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-field.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * External dependencies
- */
-import classNames from 'classnames';
-import { __ } from '@wordpress/i18n';
-import { Fragment } from '@wordpress/element';
-import { InspectorControls } from '@wordpress/editor';
-import { PanelBody, TextControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-
-function JetpackField( {
- isSelected,
- type,
- required,
- label,
- setAttributes,
- defaultValue,
- placeholder,
- id,
-} ) {
- return (
- <Fragment>
- <div className={ classNames( 'jetpack-field', { 'is-selected': isSelected } ) }>
- <TextControl
- type={ type }
- label={
- <JetpackFieldLabel
- required={ required }
- label={ label }
- setAttributes={ setAttributes }
- isSelected={ isSelected }
- />
- }
- placeholder={ placeholder }
- value={ placeholder }
- onChange={ value => setAttributes( { placeholder: value } ) }
- title={ __( 'Set the placeholder text', 'jetpack' ) }
- />
- </div>
- <InspectorControls>
- <PanelBody title={ __( 'Field Settings', 'jetpack' ) }>
- <TextControl
- label={ __( 'Default Value', 'jetpack' ) }
- value={ defaultValue }
- onChange={ value => setAttributes( { defaultValue: value } ) }
- />
- <TextControl
- label={ __( 'ID', 'jetpack' ) }
- value={ id }
- onChange={ value => setAttributes( { id: value } ) }
- />
- </PanelBody>
- </InspectorControls>
- </Fragment>
- );
-}
-
-export default JetpackField;
diff --git a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-option.js b/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-option.js
deleted file mode 100644
index 8cd2792d..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/components/jetpack-option.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { IconButton } from '@wordpress/components';
-import { Component, createRef } from '@wordpress/element';
-
-class JetpackOption extends Component {
- constructor( ...args ) {
- super( ...args );
- this.onChangeOption = this.onChangeOption.bind( this );
- this.onKeyPress = this.onKeyPress.bind( this );
- this.onDeleteOption = this.onDeleteOption.bind( this );
- this.textInput = createRef();
- }
-
- componentDidMount() {
- if ( this.props.isInFocus ) {
- this.textInput.current.focus();
- }
- }
-
- componentDidUpdate() {
- if ( this.props.isInFocus ) {
- this.textInput.current.focus();
- }
- }
-
- onChangeOption( event ) {
- this.props.onChangeOption( this.props.index, event.target.value );
- }
-
- onKeyPress( event ) {
- if ( event.key === 'Enter' ) {
- this.props.onAddOption( this.props.index );
- event.preventDefault();
- return;
- }
-
- if ( event.key === 'Backspace' && event.target.value === '' ) {
- this.props.onChangeOption( this.props.index );
- event.preventDefault();
- return;
- }
- }
-
- onDeleteOption() {
- this.props.onChangeOption( this.props.index );
- }
-
- render() {
- const { isSelected, option, type } = this.props;
- return (
- <li className="jetpack-option">
- { type && type !== 'select' && (
- <input className="jetpack-option__type" type={ type } disabled />
- ) }
- <input
- type="text"
- className="jetpack-option__input"
- value={ option }
- placeholder={ __( 'Write option…', 'jetpack' ) }
- onChange={ this.onChangeOption }
- onKeyDown={ this.onKeyPress }
- ref={ this.textInput }
- />
- { isSelected && (
- <IconButton
- className="jetpack-option__remove"
- icon="trash"
- label={ __( 'Remove option', 'jetpack' ) }
- onClick={ this.onDeleteOption }
- />
- ) }
- </li>
- );
- }
-}
-
-export default JetpackOption;
diff --git a/plugins/jetpack/extensions/blocks/contact-form/editor.js b/plugins/jetpack/extensions/blocks/contact-form/editor.js
deleted file mode 100644
index 9ffc068d..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { childBlocks, name, settings } from '.';
-
-registerJetpackBlock( name, settings, childBlocks );
diff --git a/plugins/jetpack/extensions/blocks/contact-form/editor.scss b/plugins/jetpack/extensions/blocks/contact-form/editor.scss
deleted file mode 100644
index 13053f07..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/editor.scss
+++ /dev/null
@@ -1,696 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-@import '../../shared/styles/gutenberg-variables.scss';
-
-.jetpack-contact-form .components-placeholder {
- padding: 24px;
-
- input[type='text'] {
- width: 100%;
- outline-width: 0;
- outline-style: none;
- line-height: 16px;
- }
-
- .components-placeholder__label svg {
- margin-right: 1ch;
- }
-
- .help-message,
- .components-placeholder__fieldset {
- text-align: left;
- }
-
- .help-message {
- width: 100%;
- margin: -18px 0 28px;
- }
-
- .components-base-control {
- margin-bottom: 16px;
- width: 100%;
- }
-}
-
-.jetpack-contact-form__intro-message {
- margin: 0 0 16px;
-}
-
-.jetpack-contact-form__create {
- width: 100%;
-}
-
-.jetpack-field-label {
- display: flex;
- flex-direction: row;
-
- .components-base-control {
- margin-top:-1px;
- margin-bottom: -3px;
-
- &.jetpack-field-label__required {
- .components-form-toggle {
- margin: 2px 8px 0 0;
- }
-
- .components-toggle-control__label {
- word-break: normal;
- }
- }
- }
-
- .required {
- color: var( --color-error );
- word-break: normal;
- }
-
- .components-toggle-control .components-base-control__field {
- margin-bottom: 0;
- }
-}
-
-.jetpack-field-label__input {
- flex-grow: 1;
- min-height: unset;
- padding: 0;
-}
-
-// Duplicated to elevate specificity in order to overwrite core styles
-.jetpack-field-label__input.jetpack-field-label__input.jetpack-field-label__input {
- border-color: $white;
- border-radius: 0;
- font-weight: 600;
- margin: 0;
- margin-bottom: 2px;
- padding: 0;
- width: auto;
-
- &:focus {
- border-color: $white;
- box-shadow: none;
- }
-}
-
-input.components-text-control__input {
- line-height: 16px;
-}
-
-.jetpack-field {
- // done to increase elevate specificity in order to overwrite calypso styles
- .components-text-control__input.components-text-control__input {
- width: 100%;
- }
- .components-text-control__input,
- .components-textarea-control__input {
- color: #72777c;
- padding: 10px 8px;
- }
-}
-
-.jetpack-field-checkbox__checkbox.jetpack-field-checkbox__checkbox.jetpack-field-checkbox__checkbox {
- float: left;
-}
-
-// Duplicated to elevate specificity in order to overwrite core styles
-.jetpack-field-multiple__list.jetpack-field-multiple__list {
- list-style-type: none;
- margin: 0;
-
- &:empty {
- display: none;
- }
-
- // TODO: make this a class, @enej
- [data-type='jetpack/field-select'] & {
- border: 1px solid $dark-gray-150;
- border-radius: 4px;
- padding: 4px;
- }
-}
-
-.jetpack-option {
- display: flex;
- align-items: center;
- margin: 0;
-}
-
-.jetpack-option__type.jetpack-option__type {
- margin-top: 0;
-}
-
-// Duplicated to elevate specificity in order to overwrite core styles
-.jetpack-option__input.jetpack-option__input.jetpack-option__input {
- border-color: $white;
- border-radius: 0;
- flex-grow: 1;
-
- &:hover {
- border-color: #357cb5;
- }
-
- &:focus {
- border-color: #e3e5e8;
- box-shadow: none;
- }
-}
-// Duplicated to elevate specificity in order to overwrite calypso styles
-.jetpack-option__remove.jetpack-option__remove {
- padding: 6px;
- vertical-align: bottom;
-}
-
-.jetpack-field-multiple__add-option {
- margin-left: -6px;
- padding: 4px;
- padding-right: 8px;
-
- svg {
- margin-right: 12px;
- }
-}
-
-.jetpack-field-checkbox .components-base-control__label {
- display: flex;
- align-items: center;
-
- .jetpack-field-label {
- flex-grow:1;
- }
-
- .jetpack-field-label__input {
- font-size: 13px;
- font-weight: 400;
- padding-left: 10px;
- }
-}
-
-/* ==========================================================================
-** Shortcode Classic Block Styles
-** ======================================================================= */
-
-@media ( min-width: 481px ) {
- .jetpack-contact-form-shortcode-preview {
- padding: 24px;
- }
-}
-
-.jetpack-contact-form-shortcode-preview {
- font-family: $default-font;
- font-size: 16px;
- line-height: 1.4em;
- display: block;
- position: relative;
- margin: 0 auto;
- padding: 16px;
- box-sizing: border-box;
- background: $white;
- box-shadow: 0 0 0 1px rgba( 200, 215, 225, 0.5 ), 0 1px 2px #e9eff3;
-
- &::after {
- content: '.';
- display: block;
- height: 0;
- clear: both;
- visibility: hidden;
- }
-
- > div {
- margin-top: 24px;
- }
-
- > div:first-child {
- margin-top: 0;
- }
- /* ==========================================================================
- ** Labels
- ** ======================================================================= */
-
- label {
- display: block;
- font-size: 14px;
- font-weight: 600;
- margin-bottom: 5px;
- }
-
-
- /* ==========================================================================
- ** Text Inputs
- ** ======================================================================= */
-
- input[type='text'],
- input[type='tel'],
- input[type='email'],
- input[type='url'] {
- border-radius: 0;
- appearance: none;
- box-sizing: border-box;
- margin: 0;
- padding: 7px 14px;
- width: 100%;
- color: #2e4453;
- font-size: 16px;
- line-height: 1.5;
- border: 1px solid #c8d7e1;
- background-color: $white;
- transition: all 0.15s ease-in-out;
- box-shadow: none;
- }
-
- input[type='text']::placeholder,
- input[type='tel']::placeholder,
- input[type='email']::placeholder,
- input[type='url']::placeholder {
- color: #87a6bc;
- }
-
- input[type='text']:hover,
- input[type='tel']:hover,
- input[type='email']:hover,
- input[type='url']:hover {
- border-color: #a8bece;
- }
-
- input[type='text']:focus,
- input[type='tel']:focus,
- input[type='email']:focus,
- input[type='url']:focus {
- border-color: #0087be;
- outline: none;
- box-shadow: 0 0 0 2px #78dcfa;
- }
-
- input[type='text']:focus::-ms-clear,
- input[type='tel']:focus::-ms-clear,
- input[type='email']:focus::-ms-clear,
- input[type='url']:focus::-ms-clear {
- display: none;
- }
-
- input[type='text']:disabled,
- input[type='tel']:disabled,
- input[type='email']:disabled,
- input[type='url']:disabled {
- background: #f3f6f8;
- border-color: #e9eff3;
- color: #a8bece;
- -webkit-text-fill-color: #a8bece;
- }
-
- input[type='text']:disabled:hover,
- input[type='tel']:disabled:hover,
- input[type='email']:disabled:hover,
- input[type='url']:disabled:hover {
- cursor: default;
- }
-
- input[type='text']:disabled::placeholder,
- input[type='tel']:disabled::placeholder,
- input[type='email']:disabled::placeholder,
- input[type='url']:disabled::placeholder {
- color: #a8bece;
- }
-
-
- /* ==========================================================================
- ** Textareas
- ** ======================================================================= */
-
- textarea {
- border-radius: 0;
- appearance: none;
- box-sizing: border-box;
- margin: 0;
- padding: 7px 14px;
- height: 92px;
- width: 100%;
- color: #2e4453;
- font-size: 16px;
- line-height: 1.5;
- border: 1px solid #c8d7e1;
- background-color: $white;
- transition: all 0.15s ease-in-out;
- box-shadow: none;
- }
-
- textarea::placeholder {
- color: #87a6bc;
- }
-
- textarea:hover {
- border-color: #a8bece;
- }
-
- textarea:focus {
- border-color: #0087be;
- outline: none;
- box-shadow: 0 0 0 2px #78dcfa;
- }
-
- textarea:focus::-ms-clear {
- display: none;
- }
-
- textarea:disabled {
- background: #f3f6f8;
- border-color: #e9eff3;
- color: #a8bece;
- -webkit-text-fill-color: #a8bece;
- }
-
- textarea:disabled:hover {
- cursor: default;
- }
-
- textarea:disabled::placeholder {
- color: #a8bece;
- }
-
-
- /* ==========================================================================
- ** Checkboxes
- ** ======================================================================= */
-
- input[type='checkbox'] {
- -webkit-appearance: none;
- display: inline-block;
- box-sizing: border-box;
- margin: 2px 0 0;
- padding: 7px 14px;
- width: 16px;
- height: 16px;
- float: left;
- outline: 0;
- padding: 0;
- box-shadow: none;
- background-color: $white;
- border: 1px solid #c8d7e1;
- color: #2e4453;
- font-size: 16px;
- line-height: 0;
- text-align: center;
- vertical-align: middle;
- appearance: none;
- transition: all 0.15s ease-in-out;
- clear: none;
- cursor: pointer;
- }
-
- input[type='checkbox']:checked::before {
- content: '\f147';
- font-family: Dashicons;
- margin: -3px 0 0 -4px;
- float: left;
- display: inline-block;
- vertical-align: middle;
- width: 16px;
- font-size: 20px;
- line-height: 1;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- speak: none;
- color: #00aadc;
- }
-
- input[type='checkbox']:disabled:checked::before {
- color: #a8bece;
- }
-
- input[type='checkbox']:hover {
- border-color: #a8bece;
- }
-
- input[type='checkbox']:focus {
- border-color: #0087be;
- outline: none;
- box-shadow: 0 0 0 2px #78dcfa;
- }
-
- input[type='checkbox']:disabled {
- background: #f3f6f8;
- border-color: #e9eff3;
- color: #a8bece;
- opacity: 1;
- }
-
- input[type='checkbox']:disabled:hover {
- cursor: default;
- }
-
- input[type='checkbox'] + span {
- display: block;
- font-weight: normal;
- margin-left: 24px;
- }
-
-
- /* ==========================================================================
- ** Radio buttons
- ** ======================================================================== */
-
- input[type=radio] {
- color: #2e4453;
- font-size: 16px;
- border: 1px solid #c8d7e1;
- background-color: $white;
- transition: all 0.15s ease-in-out;
- box-sizing: border-box;
- -webkit-appearance: none;
- clear: none;
- cursor: pointer;
- display: inline-block;
- line-height: 0;
- height: 16px;
- margin: 2px 4px 0 0;
- float: left;
- outline: 0;
- padding: 0;
- text-align: center;
- vertical-align: middle;
- width: 16px;
- min-width: 16px;
- appearance: none;
- border-radius: 50%;
- line-height: 10px;
- }
-
- input[type='radio']:hover {
- border-color: #a8bece;
- }
-
- input[type='radio']:focus {
- border-color: #0087be;
- outline: none;
- box-shadow: 0 0 0 2px #78dcfa;
- }
-
- input[type='radio']:focus::-ms-clear {
- display: none;
- }
-
- input[type='radio']:checked::before {
- float: left;
- display: inline-block;
- content: '\2022';
- margin: 3px;
- width: 8px;
- height: 8px;
- text-indent: -9999px;
- background: #00aadc;
- vertical-align: middle;
- border-radius: 50%;
- animation: grow 0.2s ease-in-out;
- }
-
- input[type='radio']:disabled {
- background: #f3f6f8;
- border-color: #e9eff3;
- color: #a8bece;
- opacity: 1;
- -webkit-text-fill-color: #a8bece;
- }
-
- input[type='radio']:disabled:hover {
- cursor: default;
- }
-
- input[type='radio']:disabled::placeholder {
- color: #a8bece;
- }
-
- input[type='radio']:disabled:checked::before {
- background: #e9eff3;
- }
-
- input[type='radio'] + span {
- display: block;
- font-weight: normal;
- margin-left: 24px;
- }
-
- @keyframes grow {
- 0% {
- transform: scale( 0.3 );
- }
-
- 60% {
- transform: scale( 1.15 );
- }
-
- 100% {
- transform: scale( 1 );
- }
- }
-
- @keyframes grow {
- 0% {
- transform: scale( 0.3 );
- }
-
- 60% {
- transform: scale( 1.15 );
- }
-
- 100% {
- transform: scale( 1 );
- }
- }
-
-
- /* ==========================================================================
- ** Selects
- ** ======================================================================== */
-
- select {
- background: $white url( data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjQzhEN0UxIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg== ) no-repeat right 10px center;
- border-color: #c8d7e1;
- border-style: solid;
- border-radius: 4px;
- border-width: 1px 1px 2px;
- color: #2e4453;
- cursor: pointer;
- display: inline-block;
- margin: 0;
- outline: 0;
- overflow: hidden;
- font-size: 14px;
- line-height: 21px;
- font-weight: 600;
- text-overflow: ellipsis;
- text-decoration: none;
- vertical-align: top;
- white-space: nowrap;
- box-sizing: border-box;
- padding: 2px 32px 2px 14px; // Aligns the text to the 8px baseline grid and adds padding on right to allow for the arrow.
- appearance: none;
- font-family: sans-serif;
- }
-
- select:hover {
- background-image: url( data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjYThiZWNlIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg== );
- }
-
- select:focus {
- background-image: url( data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiA8dGl0bGU+YXJyb3ctZG93bjwvdGl0bGU+IDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiA8ZGVmcz48L2RlZnM+IDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPiA8ZyBpZD0iYXJyb3ctZG93biIgc2tldGNoOnR5cGU9Ik1TQXJ0Ym9hcmRHcm91cCIgZmlsbD0iIzJlNDQ1MyI+IDxwYXRoIGQ9Ik0xNS41LDYgTDE3LDcuNSBMMTAuMjUsMTQuMjUgTDMuNSw3LjUgTDUsNiBMMTAuMjUsMTEuMjUgTDE1LjUsNiBaIiBpZD0iRG93bi1BcnJvdyIgc2tldGNoOnR5cGU9Ik1TU2hhcGVHcm91cCI+PC9wYXRoPiA8L2c+IDwvZz48L3N2Zz4= );
- border-color: #00aadc;
- box-shadow: 0 0 0 2px #78dcfa;
- outline: 0;
- -moz-outline:none;
- -moz-user-focus:ignore;
- }
-
- select:disabled,
- select:hover:disabled {
- background: url( data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjZTllZmYzIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg== ) no-repeat right 10px center;;
- }
-
- select.is-compact {
- min-width: 0;
- padding: 0 20px 2px 6px;
- margin: 0 4px;
- background-position: right 5px center;
- background-size: 12px 12px;
- }
-
- /* Make it display:block when it follows a label */
- label select,
- label + select {
- display: block;
- min-width: 200px;
- }
-
- label select.is-compact,
- label + select.is-compact {
- display: inline-block;
- min-width: 0;
- }
-
- /* IE: Remove the default arrow */
- select::-ms-expand {
- display: none;
- }
-
- /* IE: Remove default background and color styles on focus */
- select::-ms-value {
- background: none;
- color: #2e4453;
- }
-
- /* Firefox: Remove the focus outline, see http://stackoverflow.com/questions/3773430/remove-outline-from-select-box-in-ff/18853002#18853002 */
- select:-moz-focusring {
- color: transparent;
- text-shadow: 0 0 0 #2e4453;
- }
-
-
- /* ==========================================================================
- ** Buttons
- ** ======================================================================== */
-
- input[type='submit'] {
- padding: 0;
- font-size: 14px;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- vertical-align: baseline;
- background: $white;
- border-color: #c8d7e1;
- border-style: solid;
- border-width: 1px 1px 2px;
- color: #2e4453;
- cursor: pointer;
- display: inline-block;
- margin: 24px 0 0;
- outline: 0;
- overflow: hidden;
- font-weight: 500;
- text-overflow: ellipsis;
- text-decoration: none;
- vertical-align: top;
- box-sizing: border-box;
- font-size: 14px;
- line-height: 21px;
- border-radius: 4px;
- padding: 7px 14px 9px;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- }
-
- input[type='submit']:hover {
- border-color: #a8bece;
- color: #2e4453;
- }
-
- input[type='submit']:active {
- border-width: 2px 1px 1px;
- }
-
- input[type='submit']:visited {
- color: #2e4453;
- }
-
- input[type='submit']:focus {
- border-color: #00aadc;
- box-shadow: 0 0 0 2px #78dcfa;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/contact-form/index.js b/plugins/jetpack/extensions/blocks/contact-form/index.js
deleted file mode 100644
index e2a90c89..00000000
--- a/plugins/jetpack/extensions/blocks/contact-form/index.js
+++ /dev/null
@@ -1,462 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { getBlockType, createBlock } from '@wordpress/blocks';
-import { Path, Circle } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-import { InnerBlocks } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import './editor.scss';
-import JetpackContactForm from './components/jetpack-contact-form';
-import JetpackField from './components/jetpack-field';
-import JetpackFieldTextarea from './components/jetpack-field-textarea';
-import JetpackFieldCheckbox from './components/jetpack-field-checkbox';
-import JetpackFieldMultiple from './components/jetpack-field-multiple';
-import renderMaterialIcon from '../../shared/render-material-icon';
-
-export const name = 'contact-form';
-
-export const settings = {
- title: __( 'Form', 'jetpack' ),
- description: __( 'A simple way to get feedback from folks visiting your site.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M13 7.5h5v2h-5zm0 7h5v2h-5zM19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zM11 6H6v5h5V6zm-1 4H7V7h3v3zm1 3H6v5h5v-5zm-1 4H7v-3h3v3z" />
- ),
- keywords: [
- _x( 'email', 'block search term', 'jetpack' ),
- _x( 'feedback', 'block search term', 'jetpack' ),
- _x( 'contact', 'block search term', 'jetpack' ),
- ],
- category: 'jetpack',
- supports: {
- reusable: false,
- html: false,
- },
- attributes: {
- subject: {
- type: 'string',
- default: '',
- },
- to: {
- type: 'string',
- default: '',
- },
- submitButtonText: {
- type: 'string',
- default: __( 'Submit', 'jetpack' ),
- },
- customBackgroundButtonColor: { type: 'string' },
- customTextButtonColor: { type: 'string' },
- submitButtonClasses: { type: 'string' },
- hasFormSettingsSet: {
- type: 'string',
- default: null,
- },
-
- // Deprecated
- has_form_settings_set: {
- type: 'string',
- default: null,
- },
- submit_button_text: {
- type: 'string',
- default: __( 'Submit', 'jetpack' ),
- },
- },
-
- edit: JetpackContactForm,
- save: InnerBlocks.Content,
- deprecated: [
- {
- attributes: {
- subject: {
- type: 'string',
- default: '',
- },
- to: {
- type: 'string',
- default: '',
- },
- submit_button_text: {
- type: 'string',
- default: __( 'Submit', 'jetpack' ),
- },
- has_form_settings_set: {
- type: 'string',
- default: null,
- },
- },
- migrate: attr => {
- return {
- submitButtonText: attr.submit_button_text,
- hasFormSettingsSet: attr.has_form_settings_set,
- to: attr.to,
- subject: attr.subject,
- };
- },
-
- isEligible: attr => {
- // when the deprecated, snake_case values are default, no need to migrate
- if ( ! attr.has_form_settings_set && attr.submit_button_text === 'Submit' ) {
- return false;
- }
- return true;
- },
-
- save: InnerBlocks.Content,
- },
- ],
-};
-
-const FieldDefaults = {
- category: 'jetpack',
- parent: [ 'jetpack/contact-form' ],
- supports: {
- reusable: false,
- html: false,
- },
- attributes: {
- label: {
- type: 'string',
- default: null,
- },
- required: {
- type: 'boolean',
- default: false,
- },
- options: {
- type: 'array',
- default: [],
- },
- defaultValue: {
- type: 'string',
- default: '',
- },
- placeholder: {
- type: 'string',
- default: '',
- },
- id: {
- type: 'string',
- default: '',
- },
- },
- transforms: {
- to: [
- {
- type: 'block',
- blocks: [ 'jetpack/field-text' ],
- isMatch: ( { options } ) => ! options.length,
- transform: attributes => createBlock( 'jetpack/field-text', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-name' ],
- isMatch: ( { options } ) => ! options.length,
- transform: attributes => createBlock( 'jetpack/field-name', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-email' ],
- isMatch: ( { options } ) => ! options.length,
- transform: attributes => createBlock( 'jetpack/field-email', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-url' ],
- isMatch: ( { options } ) => ! options.length,
- transform: attributes => createBlock( 'jetpack/field-url', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-date' ],
- isMatch: ( { options } ) => ! options.length,
- transform: attributes => createBlock( 'jetpack/field-date', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-telephone' ],
- isMatch: ( { options } ) => ! options.length,
- transform: attributes => createBlock( 'jetpack/field-telephone', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-textarea' ],
- isMatch: ( { options } ) => ! options.length,
- transform: attributes => createBlock( 'jetpack/field-textarea', attributes ),
- },
- /* // not yet ready for prime time.
- {
- type: 'block',
- blocks: [ 'jetpack/field-checkbox' ],
- isMatch: ( { options } ) => 1 === options.length,
- transform: ( attributes )=>createBlock( 'jetpack/field-checkbox', attributes )
- },
- */
- {
- type: 'block',
- blocks: [ 'jetpack/field-checkbox-multiple' ],
- isMatch: ( { options } ) => 1 <= options.length,
- transform: attributes => createBlock( 'jetpack/field-checkbox-multiple', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-radio' ],
- isMatch: ( { options } ) => 1 <= options.length,
- transform: attributes => createBlock( 'jetpack/field-radio', attributes ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/field-select' ],
- isMatch: ( { options } ) => 1 <= options.length,
- transform: attributes => createBlock( 'jetpack/field-select', attributes ),
- },
- ],
- },
- save: () => null,
-};
-
-const getFieldLabel = ( { attributes, name: blockName } ) => {
- return null === attributes.label ? getBlockType( blockName ).title : attributes.label;
-};
-
-const editField = type => props => (
- <JetpackField
- type={ type }
- label={ getFieldLabel( props ) }
- required={ props.attributes.required }
- setAttributes={ props.setAttributes }
- isSelected={ props.isSelected }
- defaultValue={ props.attributes.defaultValue }
- placeholder={ props.attributes.placeholder }
- id={ props.attributes.id }
- />
-);
-
-const editMultiField = type => props => (
- <JetpackFieldMultiple
- label={ getFieldLabel( props ) }
- required={ props.attributes.required }
- options={ props.attributes.options }
- setAttributes={ props.setAttributes }
- type={ type }
- isSelected={ props.isSelected }
- id={ props.attributes.id }
- />
-);
-
-export const childBlocks = [
- {
- name: 'field-text',
- settings: {
- ...FieldDefaults,
- title: __( 'Text', 'jetpack' ),
- description: __( 'When you need just a small amount of text, add a text input.', 'jetpack' ),
- icon: renderMaterialIcon( <Path d="M4 9h16v2H4V9zm0 4h10v2H4v-2z" /> ),
- edit: editField( 'text' ),
- },
- },
- {
- name: 'field-name',
- settings: {
- ...FieldDefaults,
- title: __( 'Name', 'jetpack' ),
- description: __(
- 'Introductions are important. Add an input for folks to add their name.',
- 'jetpack'
- ),
- icon: renderMaterialIcon(
- <Path d="M12 6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0 10c2.7 0 5.8 1.29 6 2H6c.23-.72 3.31-2 6-2m0-12C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 10c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" />
- ),
- edit: editField( 'text' ),
- },
- },
- {
- name: 'field-email',
- settings: {
- ...FieldDefaults,
- title: __( 'Email', 'jetpack' ),
- keywords: [ __( 'e-mail', 'jetpack' ), __( 'mail', 'jetpack' ), 'email' ],
- description: __( 'Want to reply to folks? Add an email address input.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z" />
- ),
- edit: editField( 'email' ),
- },
- },
-
- {
- name: 'field-url',
- settings: {
- ...FieldDefaults,
- title: __( 'Website', 'jetpack' ),
- keywords: [ 'url', __( 'internet page', 'jetpack' ), 'link' ],
- description: __( 'Add an address input for a website.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M20 18c1.1 0 1.99-.9 1.99-2L22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z" />
- ),
- edit: editField( 'url' ),
- },
- },
-
- {
- name: 'field-date',
- settings: {
- ...FieldDefaults,
- title: __( 'Date Picker', 'jetpack' ),
- keywords: [
- __( 'Calendar', 'jetpack' ),
- __( 'day month year', 'block search term', 'jetpack' ),
- ],
- description: __( 'The best way to set a date. Add a date picker.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V9h14v10zm0-12H5V5h14v2zM7 11h5v5H7z" />
- ),
- edit: editField( 'text' ),
- },
- },
- {
- name: 'field-telephone',
- settings: {
- ...FieldDefaults,
- title: __( 'Telephone', 'jetpack' ),
- keywords: [
- __( 'Phone', 'jetpack' ),
- __( 'Cellular phone', 'jetpack' ),
- __( 'Mobile', 'jetpack' ),
- ],
- description: __( 'Add a phone number input.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M6.54 5c.06.89.21 1.76.45 2.59l-1.2 1.2c-.41-1.2-.67-2.47-.76-3.79h1.51m9.86 12.02c.85.24 1.72.39 2.6.45v1.49c-1.32-.09-2.59-.35-3.8-.75l1.2-1.19M7.5 3H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.49c0-.55-.45-1-1-1-1.24 0-2.45-.2-3.57-.57-.1-.04-.21-.05-.31-.05-.26 0-.51.1-.71.29l-2.2 2.2c-2.83-1.45-5.15-3.76-6.59-6.59l2.2-2.2c.28-.28.36-.67.25-1.02C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1z" />
- ),
- edit: editField( 'tel' ),
- },
- },
- {
- name: 'field-textarea',
- settings: {
- ...FieldDefaults,
- title: __( 'Message', 'jetpack' ),
- keywords: [ __( 'Textarea', 'jetpack' ), 'textarea', __( 'Multiline text', 'jetpack' ) ],
- description: __(
- 'Let folks speak their mind. This text box is great for longer responses.',
- 'jetpack'
- ),
- icon: renderMaterialIcon( <Path d="M21 11.01L3 11v2h18zM3 16h12v2H3zM21 6H3v2.01L21 8z" /> ),
- edit: props => (
- <JetpackFieldTextarea
- label={ getFieldLabel( props ) }
- required={ props.attributes.required }
- setAttributes={ props.setAttributes }
- isSelected={ props.isSelected }
- defaultValue={ props.attributes.defaultValue }
- placeholder={ props.attributes.placeholder }
- id={ props.attributes.id }
- />
- ),
- },
- },
- {
- name: 'field-checkbox',
- settings: {
- ...FieldDefaults,
- title: __( 'Checkbox', 'jetpack' ),
- keywords: [ __( 'Confirm', 'jetpack' ), __( 'Accept', 'jetpack' ) ],
- description: __( 'Add a single checkbox.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zM17.99 9l-1.41-1.42-6.59 6.59-2.58-2.57-1.42 1.41 4 3.99z" />
- ),
- edit: props => (
- <JetpackFieldCheckbox
- label={ props.attributes.label } // label intentinally left blank
- required={ props.attributes.required }
- setAttributes={ props.setAttributes }
- isSelected={ props.isSelected }
- defaultValue={ props.attributes.defaultValue }
- id={ props.attributes.id }
- />
- ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: '',
- },
- },
- },
- },
- {
- name: 'field-checkbox-multiple',
- settings: {
- ...FieldDefaults,
- title: __( 'Checkbox Group', 'jetpack' ),
- keywords: [ __( 'Choose Multiple', 'jetpack' ), __( 'Option', 'jetpack' ) ],
- description: __( 'People love options. Add several checkbox items.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z" />
- ),
- edit: editMultiField( 'checkbox' ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: 'Choose several',
- },
- },
- },
- },
- {
- name: 'field-radio',
- settings: {
- ...FieldDefaults,
- title: __( 'Radio', 'jetpack' ),
- keywords: [ __( 'Choose', 'jetpack' ), __( 'Select', 'jetpack' ), __( 'Option', 'jetpack' ) ],
- description: __(
- 'Inspired by radios, only one radio item can be selected at a time. Add several radio button items.',
- 'jetpack'
- ),
- icon: renderMaterialIcon(
- <Fragment>
- <Path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" />
- <Circle cx="12" cy="12" r="5" />
- </Fragment>
- ),
- edit: editMultiField( 'radio' ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: 'Choose one',
- },
- },
- },
- },
- {
- name: 'field-select',
- settings: {
- ...FieldDefaults,
- title: __( 'Select', 'jetpack' ),
- keywords: [
- __( 'Choose', 'jetpack' ),
- __( 'Dropdown', 'jetpack' ),
- __( 'Option', 'jetpack' ),
- ],
- description: __( 'Compact, but powerful. Add a select box with several items.', 'jetpack' ),
- icon: renderMaterialIcon(
- <Path d="M3 17h18v2H3zm16-5v1H5v-1h14m2-2H3v5h18v-5zM3 6h18v2H3z" />
- ),
- edit: editMultiField( 'select' ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: 'Select one',
- },
- },
- },
- },
-];
diff --git a/plugins/jetpack/extensions/blocks/contact-info/address/edit.js b/plugins/jetpack/extensions/blocks/contact-info/address/edit.js
deleted file mode 100644
index 4618f686..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/address/edit.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import { __ } from '@wordpress/i18n';
-import { Component, Fragment } from '@wordpress/element';
-import { PlainText } from '@wordpress/editor';
-import { ToggleControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import save from './save';
-
-class AddressEdit extends Component {
- constructor( ...args ) {
- super( ...args );
-
- this.preventEnterKey = this.preventEnterKey.bind( this );
- }
-
- preventEnterKey( event ) {
- if ( event.key === 'Enter' ) {
- event.preventDefault();
- return;
- }
- }
-
- render() {
- const {
- attributes: {
- address,
- addressLine2,
- addressLine3,
- city,
- region,
- postal,
- country,
- linkToGoogleMaps,
- },
- isSelected,
- setAttributes,
- } = this.props;
-
- const hasContent = [ address, addressLine2, addressLine3, city, region, postal, country ].some(
- value => value !== ''
- );
- const classNames = classnames( {
- 'jetpack-address-block': true,
- 'is-selected': isSelected,
- } );
-
- const externalLink = (
- <ToggleControl
- label={ __( 'Link address to Google Maps', 'jetpack' ) }
- checked={ linkToGoogleMaps }
- onChange={ newlinkToGoogleMaps =>
- setAttributes( { linkToGoogleMaps: newlinkToGoogleMaps } )
- }
- />
- );
-
- return (
- <div className={ classNames }>
- { ! isSelected && hasContent && save( this.props ) }
- { ( isSelected || ! hasContent ) && (
- <Fragment>
- <PlainText
- value={ address }
- placeholder={ __( 'Street Address', 'jetpack' ) }
- aria-label={ __( 'Street Address', 'jetpack' ) }
- onChange={ newAddress => setAttributes( { address: newAddress } ) }
- onKeyDown={ this.preventEnterKey }
- />
- <PlainText
- value={ addressLine2 }
- placeholder={ __( 'Address Line 2', 'jetpack' ) }
- aria-label={ __( 'Address Line 2', 'jetpack' ) }
- onChange={ newAddressLine2 => setAttributes( { addressLine2: newAddressLine2 } ) }
- onKeyDown={ this.preventEnterKey }
- />
- <PlainText
- value={ addressLine3 }
- placeholder={ __( 'Address Line 3', 'jetpack' ) }
- aria-label={ __( 'Address Line 3', 'jetpack' ) }
- onChange={ newAddressLine3 => setAttributes( { addressLine3: newAddressLine3 } ) }
- onKeyDown={ this.preventEnterKey }
- />
- <PlainText
- value={ city }
- placeholder={ __( 'City', 'jetpack' ) }
- aria-label={ __( 'City', 'jetpack' ) }
- onChange={ newCity => setAttributes( { city: newCity } ) }
- onKeyDown={ this.preventEnterKey }
- />
- <PlainText
- value={ region }
- placeholder={ __( 'State/Province/Region', 'jetpack' ) }
- aria-label={ __( 'State/Province/Region', 'jetpack' ) }
- onChange={ newRegion => setAttributes( { region: newRegion } ) }
- onKeyDown={ this.preventEnterKey }
- />
- <PlainText
- value={ postal }
- placeholder={ __( 'Postal/Zip Code', 'jetpack' ) }
- aria-label={ __( 'Postal/Zip Code', 'jetpack' ) }
- onChange={ newPostal => setAttributes( { postal: newPostal } ) }
- onKeyDown={ this.preventEnterKey }
- />
- <PlainText
- value={ country }
- placeholder={ __( 'Country', 'jetpack' ) }
- aria-label={ __( 'Country', 'jetpack' ) }
- onChange={ newCountry => setAttributes( { country: newCountry } ) }
- onKeyDown={ this.preventEnterKey }
- />
- { externalLink }
- </Fragment>
- ) }
- </div>
- );
- }
-}
-
-export default AddressEdit;
diff --git a/plugins/jetpack/extensions/blocks/contact-info/address/editor.js b/plugins/jetpack/extensions/blocks/contact-info/address/editor.js
deleted file mode 100644
index 403fddb8..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/address/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/contact-info/address/index.js b/plugins/jetpack/extensions/blocks/contact-info/address/index.js
deleted file mode 100644
index f94259f4..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/address/index.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Fragment } from '@wordpress/element';
-import { Path, Circle } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import renderMaterialIcon from '../../../shared/render-material-icon';
-
-const attributes = {
- address: {
- type: 'string',
- default: '',
- },
- addressLine2: {
- type: 'string',
- default: '',
- },
- addressLine3: {
- type: 'string',
- default: '',
- },
- city: {
- type: 'string',
- default: '',
- },
- region: {
- type: 'string',
- default: '',
- },
- postal: {
- type: 'string',
- default: '',
- },
- country: {
- type: 'string',
- default: '',
- },
- linkToGoogleMaps: {
- type: 'boolean',
- default: false,
- },
-};
-
-export const name = 'address';
-
-export const settings = {
- title: __( 'Address', 'jetpack' ),
- description: __( 'Lets you add a physical address with Schema markup.', 'jetpack' ),
- keywords: [
- _x( 'location', 'block search term', 'jetpack' ),
- _x( 'direction', 'block search term', 'jetpack' ),
- _x( 'place', 'block search term', 'jetpack' ),
- ],
- icon: renderMaterialIcon(
- <Fragment>
- <Path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zM7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 2.88-2.88 7.19-5 9.88C9.92 16.21 7 11.85 7 9z" />
- <Circle cx="12" cy="9" r="2.5" />
- </Fragment>
- ),
- category: 'jetpack',
- attributes,
- parent: [ 'jetpack/contact-info' ],
- edit,
- save,
-};
diff --git a/plugins/jetpack/extensions/blocks/contact-info/address/save.js b/plugins/jetpack/extensions/blocks/contact-info/address/save.js
deleted file mode 100644
index fd1ba8bb..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/address/save.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Fragment } from '@wordpress/element';
-
-const hasAddress = ( { address, addressLine2, addressLine3, city, region, postal, country } ) => {
- return [ address, addressLine2, addressLine3, city, region, postal, country ].some(
- value => value !== ''
- );
-};
-
-const Address = ( {
- attributes: { address, addressLine2, addressLine3, city, region, postal, country },
-} ) => (
- <Fragment>
- { address && (
- <div className="jetpack-address__address jetpack-address__address1">{ address }</div>
- ) }
- { addressLine2 && (
- <div className="jetpack-address__address jetpack-address__address2">{ addressLine2 }</div>
- ) }
- { addressLine3 && (
- <div className="jetpack-address__address jetpack-address__address3">{ addressLine3 }</div>
- ) }
- { city && ! ( region || postal ) && <div className="jetpack-address__city">{ city }</div> }
- { city && ( region || postal ) && (
- <div>
- { [
- <span className="jetpack-address__city">{ city }</span>,
- ', ',
- <span className="jetpack-address__region">{ region }</span>,
- ' ',
- <span className="jetpack-address__postal">{ postal }</span>,
- ] }
- </div>
- ) }
- { ! city && ( region || postal ) && (
- <div>
- { [
- <span className="jetpack-address__region">{ region }</span>,
- ' ',
- <span className="jetpack-address__postal">{ postal }</span>,
- ] }
- </div>
- ) }
- { country && <div className="jetpack-address__country">{ country }</div> }
- </Fragment>
-);
-
-export const googleMapsUrl = ( {
- attributes: { address, addressLine2, addressLine3, city, region, postal, country },
-} ) => {
- const addressUrl = address ? `${ address },` : '';
- const addressLine2Url = addressLine2 ? `${ addressLine2 },` : '';
- const addressLine3Url = addressLine3 ? `${ addressLine3 },` : '';
- const cityUrl = city ? `+${ city },` : '';
- let regionUrl = region ? `+${ region },` : '';
- regionUrl = postal ? `${ regionUrl }+${ postal }` : regionUrl;
- const countryUrl = country ? `+${ country }` : '';
-
- return `https://www.google.com/maps/search/${ addressUrl }${ addressLine2Url }${ addressLine3Url }${ cityUrl }${ regionUrl }${ countryUrl }`.replace(
- ' ',
- '+'
- );
-};
-
-const save = props =>
- hasAddress( props.attributes ) && (
- <div className={ props.className }>
- { props.attributes.linkToGoogleMaps && (
- <a
- href={ googleMapsUrl( props ) }
- target="_blank"
- rel="noopener noreferrer"
- title={ __( 'Open address in Google Maps', 'jetpack' ) }
- >
- <Address { ...props } />
- </a>
- ) }
- { ! props.attributes.linkToGoogleMaps && <Address { ...props } /> }
- </div>
- );
-
-export default save;
diff --git a/plugins/jetpack/extensions/blocks/contact-info/edit.js b/plugins/jetpack/extensions/blocks/contact-info/edit.js
deleted file mode 100644
index b3ba63a6..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/edit.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * External dependencies
- */
-import { InnerBlocks } from '@wordpress/editor';
-import classnames from 'classnames';
-
-/**
- * Internal dependencies
- */
-const ALLOWED_BLOCKS = [
- 'jetpack/markdown',
- 'jetpack/address',
- 'jetpack/email',
- 'jetpack/phone',
- 'jetpack/map',
- 'jetpack/business-hours',
- 'core/paragraph',
- 'core/image',
- 'core/heading',
- 'core/gallery',
- 'core/list',
- 'core/quote',
- 'core/shortcode',
- 'core/audio',
- 'core/code',
- 'core/cover',
- 'core/html',
- 'core/separator',
- 'core/spacer',
- 'core/subhead',
- 'core/video',
-];
-
-const TEMPLATE = [ [ 'jetpack/email' ], [ 'jetpack/phone' ], [ 'jetpack/address' ] ];
-
-const ContactInfoEdit = props => {
- const { isSelected } = props;
-
- return (
- <div
- className={ classnames( {
- 'jetpack-contact-info-block': true,
- 'is-selected': isSelected,
- } ) }
- >
- <InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } templateLock={ false } template={ TEMPLATE } />
- </div>
- );
-};
-
-export default ContactInfoEdit;
diff --git a/plugins/jetpack/extensions/blocks/contact-info/editor.js b/plugins/jetpack/extensions/blocks/contact-info/editor.js
deleted file mode 100644
index 9ffc068d..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { childBlocks, name, settings } from '.';
-
-registerJetpackBlock( name, settings, childBlocks );
diff --git a/plugins/jetpack/extensions/blocks/contact-info/editor.scss b/plugins/jetpack/extensions/blocks/contact-info/editor.scss
deleted file mode 100644
index c07d148d..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/editor.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-.jetpack-contact-info-block {
- /* css class added to increase specificity */
- .editor-plain-text.editor-plain-text:focus {
- box-shadow: none;
- }
-
- .editor-plain-text {
- flex-grow: 1;
- min-height: unset;
- padding: 0;
- box-shadow: none;
- font-family: inherit;
- font-size: inherit;
- color: inherit;
- line-height: inherit;
- border: none;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/contact-info/email/edit.js b/plugins/jetpack/extensions/blocks/contact-info/email/edit.js
deleted file mode 100644
index 5fd0ccac..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/email/edit.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Internal dependencies
- */
-import save from './save';
-import simpleInput from '../../../shared/simple-input';
-import { __ } from '@wordpress/i18n';
-
-const EmailEdit = props => {
- const { setAttributes } = props;
- return simpleInput( 'email', props, __( 'Email', 'jetpack' ), save, nextValue =>
- setAttributes( { email: nextValue } )
- );
-};
-
-export default EmailEdit;
diff --git a/plugins/jetpack/extensions/blocks/contact-info/email/editor.js b/plugins/jetpack/extensions/blocks/contact-info/email/editor.js
deleted file mode 100644
index 403fddb8..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/email/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/contact-info/email/index.js b/plugins/jetpack/extensions/blocks/contact-info/email/index.js
deleted file mode 100644
index db086dd0..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/email/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import renderMaterialIcon from '../../../shared/render-material-icon';
-import save from './save';
-
-const attributes = {
- email: {
- type: 'string',
- default: '',
- },
-};
-
-export const name = 'email';
-
-export const settings = {
- title: __( 'Email Address', 'jetpack' ),
- description: __(
- 'Lets you add an email address with an automatically generated click-to-email link.',
- 'jetpack'
- ),
- keywords: [
- 'e-mail', // not translatable on purpose
- 'email', // not translatable on purpose
- _x( 'message', 'block search term', 'jetpack' ),
- ],
- icon: renderMaterialIcon(
- <Path d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z" />
- ),
- category: 'jetpack',
- attributes,
- edit,
- save,
- parent: [ 'jetpack/contact-info' ],
-};
diff --git a/plugins/jetpack/extensions/blocks/contact-info/email/save.js b/plugins/jetpack/extensions/blocks/contact-info/email/save.js
deleted file mode 100644
index e0eb0204..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/email/save.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * External dependencies
- */
-import emailValidator from 'email-validator';
-import { Fragment } from '@wordpress/element';
-
-const renderEmail = inputText => {
- const explodedInput = inputText.split( /(\s+)/ ).map( ( email, i ) => {
- // Remove and punctuation from the end of the email address.
- const emailToValidate = email.replace( /([.,/#!$%^&*;:{}=\-_`~()\][])+$/g, '' );
- if ( email.indexOf( '@' ) && emailValidator.validate( emailToValidate ) ) {
- return email === emailToValidate ? (
- // Email.
- <a href={ `mailto:${ email }` } key={ i }>
- { email }
- </a>
- ) : (
- // Email with punctionation.
- <Fragment key={ i }>
- <a href={ `mailto:${ email }` } key={ i }>
- { emailToValidate }
- </a>
- <Fragment>{ email.slice( -( email.length - emailToValidate.length ) ) }</Fragment>
- </Fragment>
- );
- }
- // Just a plain string.
- return <Fragment key={ i }>{ email }</Fragment>;
- } );
- return explodedInput;
-};
-
-const save = ( { attributes: { email }, className } ) =>
- email && <div className={ className }>{ renderEmail( email ) }</div>;
-
-export default save;
diff --git a/plugins/jetpack/extensions/blocks/contact-info/index.js b/plugins/jetpack/extensions/blocks/contact-info/index.js
deleted file mode 100644
index bc748acc..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/index.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { InnerBlocks } from '@wordpress/editor';
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import renderMaterialIcon from '../../shared/render-material-icon';
-import './editor.scss';
-import './style.scss';
-import { name as addressName, settings as addressSettings } from './address/';
-import { name as emailName, settings as emailSettings } from './email/';
-import { name as phoneName, settings as phoneSettings } from './phone/';
-
-const attributes = {};
-
-const save = ( { className } ) => (
- <div className={ className }>
- <InnerBlocks.Content />
- </div>
-);
-
-export const name = 'contact-info';
-
-export const settings = {
- title: __( 'Contact Info', 'jetpack' ),
- description: __(
- 'Lets you add an email address, phone number, and physical address with improved markup for better SEO results.',
- 'jetpack'
- ),
- keywords: [
- _x( 'email', 'block search term', 'jetpack' ),
- _x( 'phone', 'block search term', 'jetpack' ),
- _x( 'address', 'block search term', 'jetpack' ),
- ],
- icon: renderMaterialIcon(
- <Path d="M19 5v14H5V5h14m0-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 9c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3zm0-4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm6 10H6v-1.53c0-2.5 3.97-3.58 6-3.58s6 1.08 6 3.58V18zm-9.69-2h7.38c-.69-.56-2.38-1.12-3.69-1.12s-3.01.56-3.69 1.12z" />
- ),
- category: 'jetpack',
- supports: {
- align: [ 'wide', 'full' ],
- html: false,
- },
- attributes,
- edit,
- save,
-};
-
-export const childBlocks = [
- { name: addressName, settings: addressSettings },
- { name: emailName, settings: emailSettings },
- { name: phoneName, settings: phoneSettings },
-];
diff --git a/plugins/jetpack/extensions/blocks/contact-info/phone/edit.js b/plugins/jetpack/extensions/blocks/contact-info/phone/edit.js
deleted file mode 100644
index 0a55333e..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/phone/edit.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-
-/**
- * Internal dependencies
- */
-import save from './save';
-import simpleInput from '../../../shared/simple-input';
-
-const PhoneEdit = props => {
- const { setAttributes } = props;
- return simpleInput( 'phone', props, __( 'Phone number', 'jetpack' ), save, nextValue =>
- setAttributes( { phone: nextValue } )
- );
-};
-
-export default PhoneEdit;
diff --git a/plugins/jetpack/extensions/blocks/contact-info/phone/editor.js b/plugins/jetpack/extensions/blocks/contact-info/phone/editor.js
deleted file mode 100644
index 403fddb8..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/phone/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/contact-info/phone/index.js b/plugins/jetpack/extensions/blocks/contact-info/phone/index.js
deleted file mode 100644
index 17c51924..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/phone/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import renderMaterialIcon from '../../../shared/render-material-icon';
-import save from './save';
-
-const attributes = {
- phone: {
- type: 'string',
- default: '',
- },
-};
-
-export const name = 'phone';
-
-export const settings = {
- title: __( 'Phone Number', 'jetpack' ),
- description: __(
- 'Lets you add a phone number with an automatically generated click-to-call link.',
- 'jetpack'
- ),
- keywords: [
- _x( 'mobile', 'block search term', 'jetpack' ),
- _x( 'telephone', 'block search term', 'jetpack' ),
- _x( 'cell', 'block search term', 'jetpack' ),
- ],
- icon: renderMaterialIcon(
- <Path d="M6.54 5c.06.89.21 1.76.45 2.59l-1.2 1.2c-.41-1.2-.67-2.47-.76-3.79h1.51m9.86 12.02c.85.24 1.72.39 2.6.45v1.49c-1.32-.09-2.59-.35-3.8-.75l1.2-1.19M7.5 3H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.49c0-.55-.45-1-1-1-1.24 0-2.45-.2-3.57-.57-.1-.04-.21-.05-.31-.05-.26 0-.51.1-.71.29l-2.2 2.2c-2.83-1.45-5.15-3.76-6.59-6.59l2.2-2.2c.28-.28.36-.67.25-1.02C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1z" />
- ),
- category: 'jetpack',
- attributes,
- parent: [ 'jetpack/contact-info' ],
- edit,
- save,
-};
diff --git a/plugins/jetpack/extensions/blocks/contact-info/phone/save.js b/plugins/jetpack/extensions/blocks/contact-info/phone/save.js
deleted file mode 100644
index 50f67914..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/phone/save.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Internal dependencies
- */
-
-export function renderPhone( inputText ) {
- const arrayOfNumbers = inputText.match( /\d+\.\d+|\d+\b|\d+(?=\w)/g );
- if ( ! arrayOfNumbers ) {
- // No numbers found
- return inputText;
- }
- const indexOfFirstNumber = inputText.indexOf( arrayOfNumbers[ 0 ] );
-
- // Assume that eveything after the first number should be part of the phone number.
- // care about the first prefix character.
- let phoneNumber = indexOfFirstNumber ? inputText.substring( indexOfFirstNumber - 1 ) : inputText;
- let prefix = indexOfFirstNumber ? inputText.substring( 0, indexOfFirstNumber ) : '';
-
- let justNumber = phoneNumber.replace( /\D/g, '' );
- // Phone numbers starting with + should be part of the number.
- if ( /[0-9/+/(]/.test( phoneNumber[ 0 ] ) ) {
- // Remove the special character from the prefix so they don't appear twice.
- prefix = prefix.slice( 0, -1 );
- // Phone numbers starting with + shoud be part of the number.
- if ( phoneNumber[ 0 ] === '+' ) {
- justNumber = '+' + justNumber;
- }
- } else {
- // Remove the first character.
- phoneNumber = phoneNumber.substring( 1 );
- }
- const prefixSpan = prefix.trim() ? (
- <span key="phonePrefix" className="phone-prefix">
- { prefix }
- </span>
- ) : null;
- return [
- prefixSpan,
- <a key="phoneNumber" href={ `tel:${ justNumber }` }>
- { phoneNumber }
- </a>,
- ];
-}
-
-const save = ( { attributes: { phone }, className } ) =>
- phone && <div className={ className }>{ renderPhone( phone ) }</div>;
-
-export default save;
diff --git a/plugins/jetpack/extensions/blocks/contact-info/style.scss b/plugins/jetpack/extensions/blocks/contact-info/style.scss
deleted file mode 100644
index 8f81ca89..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/style.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.wp-block-jetpack-contact-info {
- margin-bottom: 1.5em;
-}
diff --git a/plugins/jetpack/extensions/blocks/contact-info/view.js b/plugins/jetpack/extensions/blocks/contact-info/view.js
deleted file mode 100644
index fd92905c..00000000
--- a/plugins/jetpack/extensions/blocks/contact-info/view.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Internal dependencies
- */
-
-import './style.scss';
diff --git a/plugins/jetpack/extensions/blocks/gif/edit.js b/plugins/jetpack/extensions/blocks/gif/edit.js
deleted file mode 100644
index d16fa4db..00000000
--- a/plugins/jetpack/extensions/blocks/gif/edit.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * External dependencies
- */
-import classNames from 'classnames';
-import { __ } from '@wordpress/i18n';
-import { Component, createRef } from '@wordpress/element';
-import { Button, PanelBody, Path, Placeholder, SVG, TextControl } from '@wordpress/components';
-import { InspectorControls, RichText } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import { icon, title } from './';
-
-const GIPHY_API_KEY = 't1PkR1Vq0mzHueIFBvZSZErgFs9NBmYW';
-const INPUT_PROMPT = __( 'Search for a term or paste a Giphy URL', 'jetpack' );
-
-class GifEdit extends Component {
- textControlRef = createRef();
-
- state = {
- captionFocus: false,
- results: null,
- };
-
- onFormSubmit = event => {
- event.preventDefault();
- this.onSubmit();
- };
-
- onSubmit = () => {
- const { attributes } = this.props;
- const { searchText } = attributes;
- this.parseSearch( searchText );
- };
-
- parseSearch = searchText => {
- let giphyID = null;
- // If search is hardcoded Giphy URL following this pattern: https://giphy.com/embed/4ZFekt94LMhNK
- if ( searchText.indexOf( '//giphy.com/gifs' ) !== -1 ) {
- giphyID = this.splitAndLast( this.splitAndLast( searchText, '/' ), '-' );
- }
- // If search is hardcoded Giphy URL following this patterh: http://i.giphy.com/4ZFekt94LMhNK.gif
- if ( searchText.indexOf( '//i.giphy.com' ) !== -1 ) {
- giphyID = this.splitAndLast( searchText, '/' ).replace( '.gif', '' );
- }
- // https://media.giphy.com/media/gt0hYzKlMpfOg/giphy.gif
- const match = searchText.match(
- /http[s]?:\/\/media.giphy.com\/media\/([A-Za-z0-9\-.]+)\/giphy.gif/
- );
- if ( match ) {
- giphyID = match[ 1 ];
- }
- if ( giphyID ) {
- return this.fetch( this.urlForId( giphyID ) );
- }
-
- return this.fetch( this.urlForSearch( searchText ) );
- };
-
- urlForSearch = searchText => {
- return `https://api.giphy.com/v1/gifs/search?q=${ encodeURIComponent(
- searchText
- ) }&api_key=${ encodeURIComponent( GIPHY_API_KEY ) }&limit=10`;
- };
-
- urlForId = giphyId => {
- return `https://api.giphy.com/v1/gifs/${ encodeURIComponent(
- giphyId
- ) }?api_key=${ encodeURIComponent( GIPHY_API_KEY ) }`;
- };
-
- splitAndLast = ( array, delimiter ) => {
- const split = array.split( delimiter );
- return split[ split.length - 1 ];
- };
-
- fetch = url => {
- const xhr = new XMLHttpRequest();
- xhr.open( 'GET', url );
- xhr.onload = () => {
- if ( xhr.status === 200 ) {
- const res = JSON.parse( xhr.responseText );
- // If there is only one result, Giphy's API does not return an array.
- // The following statement normalizes the data into an array with one member in this case.
- const results = typeof res.data.images !== 'undefined' ? [ res.data ] : res.data;
- const giphyData = results[ 0 ];
- // No results
- if ( ! giphyData.images ) {
- return;
- }
- this.setState( { results }, () => {
- this.selectGiphy( giphyData );
- } );
- } else {
- // Error handling TK
- }
- };
- xhr.send();
- };
-
- selectGiphy = giphy => {
- const { setAttributes } = this.props;
- const calculatedPaddingTop = Math.floor(
- ( giphy.images.original.height / giphy.images.original.width ) * 100
- );
- const paddingTop = `${ calculatedPaddingTop }%`;
- const giphyUrl = giphy.embed_url;
- setAttributes( { giphyUrl, paddingTop } );
- };
-
- setFocus = () => {
- this.textControlRef.current.querySelector( 'input' ).focus();
- this.setState( { captionFocus: false } );
- };
-
- hasSearchText = () => {
- const { attributes } = this.props;
- const { searchText } = attributes;
- return searchText && searchText.length > 0;
- };
-
- thumbnailClicked = thumbnail => {
- this.selectGiphy( thumbnail );
- };
-
- render() {
- const { attributes, className, isSelected, setAttributes } = this.props;
- const { align, caption, giphyUrl, searchText, paddingTop } = attributes;
- const { captionFocus, results } = this.state;
- const style = { paddingTop };
- const classes = classNames( className, `align${ align }` );
- const inputFields = (
- <form
- className="wp-block-jetpack-gif_input-container"
- onSubmit={ this.onFormSubmit }
- ref={ this.textControlRef }
- >
- <TextControl
- className="wp-block-jetpack-gif_input"
- label={ INPUT_PROMPT }
- placeholder={ INPUT_PROMPT }
- onChange={ value => setAttributes( { searchText: value } ) }
- value={ searchText }
- />
- <Button isLarge onClick={ this.onSubmit }>
- { __( 'Search', 'jetpack' ) }
- </Button>
- </form>
- );
- return (
- <div className={ classes }>
- <InspectorControls>
- <PanelBody className="components-panel__body-gif-branding">
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 202 22">
- <Path d="M4.6 5.9H0v10h1.6v-3.1h3c4.8 0 4.8-6.9 0-6.9zm0 5.4h-3v-4h3c2.6.1 2.6 4 0 4zM51.2 12.3c2-.3 2.7-1.7 2.7-3.1 0-1.7-1.2-3.3-3.5-3.3h-4.6v10h1.6v-3.4h2.1l3 3.4h1.9l-.2-.3-3-3.3zM47.4 11V7.4h3c1.3 0 1.9.9 1.9 1.8s-.6 1.8-1.9 1.8h-3zM30.6 13.6L28 5.9h-1.1l-2.5 7.7-2.6-7.7H20l3.7 10H25l1.4-3.5L27.5 9l1.1 3.4 1.3 3.5h1.4l3.5-10h-1.7z" />
- <Path d="M14.4 5.7c-3 0-5.1 2.2-5.1 5.2 0 2.6 1.6 5.1 5.1 5.1 3.5 0 5.1-2.5 5.1-5.2-.1-2.6-1.7-5.1-5.1-5.1zm-.1 8.9c-2.5 0-3.5-1.9-3.5-3.7 0-2.2 1.2-3.8 3.5-3.8 2.4 0 3.5 2 3.5 3.8.1 2-1 3.7-3.5 3.7zM57.7 11.6h5.5v-1.5h-5.5V7.4h5.7V5.9h-7.3v10h7.3v-1.6h-5.7zM38 14.3v-2.7h5.5v-1.5H38V7.4h5.7V5.9h-7.3v10h7.3v-1.6zM93 10.3l-2.7-4.4h-1.9V6l3.8 5.8v4.1h1.6v-4.1l4-5.8v-.1h-2zM69.3 5.9h-3.8v10h3.8c3.5 0 5.1-2.5 5-5.1-.1-2.5-1.6-4.9-5-4.9zm0 8.4h-2.2V7.4h2.2c2.3 0 3.4 1.7 3.4 3.4s-1 3.5-3.4 3.5zM86.3 10.7c.9-.4 1.4-1.1 1.4-2 0-2-1.5-2.8-3.4-2.8h-4.6v10h4.6c2 0 3.7-.7 3.7-2.8 0-.8-.5-2-1.7-2.4zm-5-3.4h3c1.2 0 1.8.7 1.8 1.4 0 .8-.6 1.3-1.8 1.3h-3V7.3zm3 7.1h-3v-2.9h3c.9 0 2.1.5 2.1 1.6 0 1-1.2 1.3-2.1 1.3zM113.9 13.3h5.3V16c-1.2.9-2.9 1.1-4 1.1-4.2 0-5.6-3.3-5.6-6 0-4.1 2.2-6.1 5.6-6.1 1.4 0 3.2.4 4.8 1.8l3.4-3.4C120.7.6 118.1 0 115.2 0c-7.8 0-11.4 5.6-11.4 11s3.1 10.9 11.4 10.9c4 0 7.6-1.4 8.9-4.1V8.6h-10.2v4.7zM171.9 8.5h-7.4V.6h-5.9v20.8h5.9v-7.8h7.4v7.8h5.9V.6h-5.9zM195.1.6l-4.5 7.1-4.3-7.1h-6.6v.2l7.9 12.3v8.3h5.9v-8.3L201.8.9V.6zM127.4.6h5.9v20.8h-5.9zM147.6.6h-10.1v20.8h5.9v-5.6h4.2c5.6-.1 8.3-3.4 8.3-7.6.1-4.1-2.7-7.6-8.3-7.6zm0 10.2h-4.2V5.6h4.2c1.6 0 2.5 1.2 2.5 2.6 0 1.4-.9 2.6-2.5 2.6z" />
- </SVG>
- </PanelBody>
- </InspectorControls>
- { ! giphyUrl ? (
- <Placeholder className="wp-block-jetpack-gif_placeholder" icon={ icon } label={ title }>
- { inputFields }
- </Placeholder>
- ) : (
- <figure>
- { isSelected && inputFields }
- { isSelected && results && results.length > 1 && (
- <div className="wp-block-jetpack-gif_thumbnails-container">
- { results.map( thumbnail => {
- const thumbnailStyle = {
- backgroundImage: `url(${ thumbnail.images.downsized_still.url })`,
- };
- return (
- <button
- className="wp-block-jetpack-gif_thumbnail-container"
- key={ thumbnail.id }
- onClick={ () => {
- this.thumbnailClicked( thumbnail );
- } }
- style={ thumbnailStyle }
- />
- );
- } ) }
- </div>
- ) }
- <div className="wp-block-jetpack-gif-wrapper" style={ style }>
- <div
- className="wp-block-jetpack-gif_cover"
- onClick={ this.setFocus }
- onKeyDown={ this.setFocus }
- role="button"
- tabIndex="0"
- />
- <iframe src={ giphyUrl } title={ searchText } />
- </div>
- { ( ! RichText.isEmpty( caption ) || isSelected ) && !! giphyUrl && (
- <RichText
- className="wp-block-jetpack-gif-caption gallery-caption"
- inlineToolbar
- isSelected={ captionFocus }
- unstableOnFocus={ () => {
- this.setState( { captionFocus: true } );
- } }
- onChange={ value => setAttributes( { caption: value } ) }
- placeholder={ __( 'Write caption…', 'jetpack' ) }
- tagName="figcaption"
- value={ caption }
- />
- ) }
- </figure>
- ) }
- </div>
- );
- }
-}
-export default GifEdit;
diff --git a/plugins/jetpack/extensions/blocks/gif/editor.js b/plugins/jetpack/extensions/blocks/gif/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/gif/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/gif/editor.scss b/plugins/jetpack/extensions/blocks/gif/editor.scss
deleted file mode 100644
index 2f1bd55c..00000000
--- a/plugins/jetpack/extensions/blocks/gif/editor.scss
+++ /dev/null
@@ -1,86 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.wp-block-jetpack-gif {
- figure {
- transition: padding-top 125ms ease-in-out;
- }
- .components-base-control__field {
- text-align: center;
- }
- .wp-block-jetpack-gif_cover {
- background: none;
- border: none;
- height: 100%;
- left: 0;
- margin: 0;
- padding: 0;
- position: absolute;
- top: 0;
- width: 100%;
- z-index: 1;
- &:focus {
- outline: none;
- }
- }
- .wp-block-jetpack-gif_input-container {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- justify-content: center;
- margin: 0 auto;
- max-width: 400px;
- width: 100%;
- z-index: 1;
- .components-base-control__label {
- height: 0;
- margin: 0;
- text-indent: -9999px;
- }
- }
- .wp-block-jetpack-gif_input {
- flex-grow: 1;
- margin-right: 0.5em;
- }
- .wp-block-jetpack-gif_thumbnails-container {
- display: flex;
- margin: -2px 0 2px 0;
- margin-left: calc( -4px / 2 );
- overflow-x: auto;
- width: calc( 100% + 4px );
- &::-webkit-scrollbar {
- display: none;
- }
- }
- .wp-block-jetpack-gif_thumbnail-container {
- align-items: center;
- background-size: cover;
- background-repeat: no-repeat;
- background-position: 50% 50%;
- border: none;
- border-radius: 3px;
- cursor: pointer;
- display: flex;
- justify-content: center;
- margin: 2px;
- padding: 0;
- padding-bottom: calc( 100% / 10 - 4px );
- width: calc( 100% / 10 - 4px );
- &:hover {
- box-shadow: 0 0 0 1px $dark-gray-500;
- }
- &:focus {
- box-shadow: 0 0 0 2px $blue-medium-500;
- outline: 0;
- }
- }
-}
-.components-panel__body-gif-branding {
- svg {
- display: block;
- margin: 0 auto;
- max-width: 200px;
- }
- svg path {
- fill: $dark-gray-150;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/gif/gif.php b/plugins/jetpack/extensions/blocks/gif/gif.php
index cb35f3da..1ababeeb 100644
--- a/plugins/jetpack/extensions/blocks/gif/gif.php
+++ b/plugins/jetpack/extensions/blocks/gif/gif.php
@@ -32,29 +32,27 @@ function jetpack_gif_block_render( $attr ) {
return null;
}
- /* TODO: replace with centralized block_class function */
- $align = isset( $attr['align'] ) ? $attr['align'] : 'center';
- $type = 'gif';
- $classes = array(
- 'wp-block-jetpack-' . $type,
- 'align' . $align,
- );
- if ( isset( $attr['className'] ) ) {
- array_push( $classes, $attr['className'] );
- }
- $classes = implode( $classes, ' ' );
+ $classes = Jetpack_Gutenberg::block_classes( 'gif', $attr );
+
+ $placeholder = sprintf( '<a href="%s">%s</a>', esc_url( $giphy_url ), esc_attr( $search_text ) );
ob_start();
?>
<div class="<?php echo esc_attr( $classes ); ?>">
<figure>
- <div class="wp-block-jetpack-gif-wrapper" style="<?php echo esc_attr( $style ); ?>">
- <iframe src="<?php echo esc_url( $giphy_url ); ?>"
- title="<?php echo esc_attr( $search_text ); ?>"></iframe>
- </div>
+ <?php if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) : ?>
+ <amp-iframe src="<?php echo esc_url( $giphy_url ); ?>" width="100" height="<?php echo absint( $padding_top ); ?>" sandbox="allow-scripts allow-same-origin" layout="responsive">
+ <div placeholder>
+ <?php echo wp_kses_post( $placeholder ); ?>
+ </div>
+ </amp-iframe>
+ <?php else : ?>
+ <div class="wp-block-jetpack-gif-wrapper" style="<?php echo esc_attr( $style ); ?>">
+ <iframe src="<?php echo esc_url( $giphy_url ); ?>" title="<?php echo esc_attr( $search_text ); ?>"></iframe>
+ </div>
+ <?php endif; ?>
<?php if ( $caption ) : ?>
- <figcaption
- class="wp-block-jetpack-gif-caption gallery-caption"><?php echo wp_kses_post( $caption ); ?></figcaption>
+ <figcaption class="wp-block-jetpack-gif-caption gallery-caption"><?php echo wp_kses_post( $caption ); ?></figcaption>
<?php endif; ?>
</figure>
</div>
diff --git a/plugins/jetpack/extensions/blocks/gif/index.js b/plugins/jetpack/extensions/blocks/gif/index.js
deleted file mode 100644
index 54ed026c..00000000
--- a/plugins/jetpack/extensions/blocks/gif/index.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-
-// Ordering is important! Editor overrides style!
-import './style.scss';
-import './editor.scss';
-
-export const name = 'gif';
-export const title = __( 'GIF', 'jetpack' );
-
-export const icon = (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M18 13v7H4V6h5.02c.05-.71.22-1.38.48-2H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-5l-2-2zm-1.5 5h-11l2.75-3.53 1.96 2.36 2.75-3.54L16.5 18zm2.8-9.11c.44-.7.7-1.51.7-2.39C20 4.01 17.99 2 15.5 2S11 4.01 11 6.5s2.01 4.5 4.49 4.5c.88 0 1.7-.26 2.39-.7L21 13.42 22.42 12 19.3 8.89zM15.5 9C14.12 9 13 7.88 13 6.5S14.12 4 15.5 4 18 5.12 18 6.5 16.88 9 15.5 9z" />
- </SVG>
-);
-
-export const settings = {
- title,
- icon,
- category: 'jetpack',
- keywords: [
- _x( 'animated', 'block search term', 'jetpack' ),
- _x( 'giphy', 'block search term', 'jetpack' ),
- _x( 'image', 'block search term', 'jetpack' ),
- ],
- description: __( 'Search for and insert an animated image.', 'jetpack' ),
- attributes: {
- align: {
- type: 'string',
- default: 'center',
- },
- caption: {
- type: 'string',
- },
- giphyUrl: {
- type: 'string',
- },
- searchText: {
- type: 'string',
- },
- paddingTop: {
- type: 'string',
- default: '56.2%',
- },
- },
- supports: {
- html: false,
- align: true,
- },
- edit,
- save: () => null,
-};
diff --git a/plugins/jetpack/extensions/blocks/gif/style.scss b/plugins/jetpack/extensions/blocks/gif/style.scss
deleted file mode 100644
index 5dc188fa..00000000
--- a/plugins/jetpack/extensions/blocks/gif/style.scss
+++ /dev/null
@@ -1,40 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.wp-block-jetpack-gif {
- clear: both;
- margin: 0 0 20px;
- figure {
- margin: 0;
- position: relative;
- width: 100%;
- }
- iframe {
- border: 0;
- left: 0;
- height: 100%;
- position: absolute;
- top: 0;
- width: 100%;
- }
- &.aligncenter {
- text-align: center;
- }
- &.alignright,
- &.alignleft {
- min-width: 300px;
- }
- // Mirroring Gutenberg caption-style mixin: https://github.com/WordPress/gutenberg/blob/master/assets/stylesheets/_mixins.scss#L312-L318
- .wp-block-jetpack-gif-caption {
- margin-top: 0.5em;
- margin-bottom: 1em;
- color: $dark-gray-500;
- text-align: center;
- }
- .wp-block-jetpack-gif-wrapper {
- height: 0;
- margin: 0;
- padding: calc( 56.2% + 12px ) 0 0 0;
- position: relative;
- width: 100%;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/gif/view.js b/plugins/jetpack/extensions/blocks/gif/view.js
deleted file mode 100644
index 6a6dda31..00000000
--- a/plugins/jetpack/extensions/blocks/gif/view.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Internal dependencies
- */
-import './style.scss';
diff --git a/plugins/jetpack/extensions/blocks/likes/editor.js b/plugins/jetpack/extensions/blocks/likes/editor.js
deleted file mode 100644
index 9adee220..00000000
--- a/plugins/jetpack/extensions/blocks/likes/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../shared/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/likes/index.js b/plugins/jetpack/extensions/blocks/likes/index.js
deleted file mode 100644
index 693fbdca..00000000
--- a/plugins/jetpack/extensions/blocks/likes/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Internal dependencies
- */
-import LikesCheckbox from './likes-checkbox';
-
-export const name = 'likes';
-
-export const settings = { render: LikesCheckbox };
diff --git a/plugins/jetpack/extensions/blocks/likes/likes-checkbox.js b/plugins/jetpack/extensions/blocks/likes/likes-checkbox.js
deleted file mode 100644
index f8bf0736..00000000
--- a/plugins/jetpack/extensions/blocks/likes/likes-checkbox.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { CheckboxControl } from '@wordpress/components';
-import { compose } from '@wordpress/compose';
-import { PostTypeSupportCheck } from '@wordpress/editor';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import JetpackLikesAndSharingPanel from '../../shared/jetpack-likes-and-sharing-panel';
-
-const LikesCheckbox = ( { areLikesEnabled, editPost } ) => (
- <PostTypeSupportCheck supportKeys="jetpack-post-likes">
- <JetpackLikesAndSharingPanel>
- <CheckboxControl
- label={ __( 'Show likes.', 'jetpack' ) }
- checked={ areLikesEnabled }
- onChange={ value => {
- editPost( { jetpack_likes_enabled: value } );
- } }
- />
- </JetpackLikesAndSharingPanel>
- </PostTypeSupportCheck>
-);
-
-// Fetch the post meta.
-const applyWithSelect = withSelect( select => {
- const { getEditedPostAttribute } = select( 'core/editor' );
- const areLikesEnabled = getEditedPostAttribute( 'jetpack_likes_enabled' );
-
- return { areLikesEnabled };
-} );
-
-// Provide method to update post meta.
-const applyWithDispatch = withDispatch( dispatch => {
- const { editPost } = dispatch( 'core/editor' );
-
- return { editPost };
-} );
-
-// Combine the higher-order components.
-export default compose( [ applyWithSelect, applyWithDispatch ] )( LikesCheckbox );
diff --git a/plugins/jetpack/extensions/blocks/mailchimp/edit.js b/plugins/jetpack/extensions/blocks/mailchimp/edit.js
deleted file mode 100644
index 88f2a84f..00000000
--- a/plugins/jetpack/extensions/blocks/mailchimp/edit.js
+++ /dev/null
@@ -1,235 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-import classnames from 'classnames';
-import SubmitButton from '../../shared/submit-button';
-import { __ } from '@wordpress/i18n';
-import {
- Button,
- ExternalLink,
- PanelBody,
- Placeholder,
- Spinner,
- TextControl,
- withNotices,
-} from '@wordpress/components';
-import { InspectorControls, RichText } from '@wordpress/editor';
-import { Fragment, Component } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import { icon } from '.';
-
-const API_STATE_LOADING = 0;
-const API_STATE_CONNECTED = 1;
-const API_STATE_NOTCONNECTED = 2;
-
-const NOTIFICATION_PROCESSING = 'processing';
-const NOTIFICATION_SUCCESS = 'success';
-const NOTIFICATION_ERROR = 'error';
-
-class MailchimpSubscribeEdit extends Component {
- constructor() {
- super( ...arguments );
- this.state = {
- audition: null,
- connected: API_STATE_LOADING,
- connectURL: null,
- };
- this.timeout = null;
- }
-
- componentDidMount = () => {
- this.apiCall();
- };
-
- onError = message => {
- const { noticeOperations } = this.props;
- noticeOperations.removeAllNotices();
- noticeOperations.createErrorNotice( message );
- };
-
- apiCall = () => {
- const path = '/wpcom/v2/mailchimp';
- const method = 'GET';
- const fetch = { path, method };
- apiFetch( fetch ).then(
- result => {
- const connectURL = result.connect_url;
- const connected =
- result.code === 'connected' ? API_STATE_CONNECTED : API_STATE_NOTCONNECTED;
- this.setState( { connected, connectURL } );
- },
- result => {
- const connectURL = null;
- const connected = API_STATE_NOTCONNECTED;
- this.setState( { connected, connectURL } );
- this.onError( result.message );
- }
- );
- };
-
- auditionNotification = notification => {
- this.setState( { audition: notification } );
- if ( this.timeout ) {
- clearTimeout( this.timeout );
- }
- this.timeout = setTimeout( this.clearAudition, 3000 );
- };
-
- clearAudition = () => {
- this.setState( { audition: null } );
- };
-
- updateProcessingText = processingLabel => {
- const { setAttributes } = this.props;
- setAttributes( { processingLabel } );
- this.auditionNotification( NOTIFICATION_PROCESSING );
- };
-
- updateSuccessText = successLabel => {
- const { setAttributes } = this.props;
- setAttributes( { successLabel } );
- this.auditionNotification( NOTIFICATION_SUCCESS );
- };
-
- updateErrorText = errorLabel => {
- const { setAttributes } = this.props;
- setAttributes( { errorLabel } );
- this.auditionNotification( NOTIFICATION_ERROR );
- };
-
- updateEmailPlaceholder = emailPlaceholder => {
- const { setAttributes } = this.props;
- setAttributes( { emailPlaceholder } );
- this.clearAudition();
- };
-
- labelForAuditionType = audition => {
- const { attributes } = this.props;
- const { processingLabel, successLabel, errorLabel } = attributes;
- if ( audition === NOTIFICATION_PROCESSING ) {
- return processingLabel;
- } else if ( audition === NOTIFICATION_SUCCESS ) {
- return successLabel;
- } else if ( audition === NOTIFICATION_ERROR ) {
- return errorLabel;
- }
- return null;
- };
-
- roleForAuditionType = audition => {
- if ( audition === NOTIFICATION_ERROR ) {
- return 'alert';
- }
- return 'status';
- };
-
- render = () => {
- const { attributes, className, notices, noticeUI, setAttributes } = this.props;
- const { audition, connected, connectURL } = this.state;
- const { emailPlaceholder, consentText, processingLabel, successLabel, errorLabel } = attributes;
- const classPrefix = 'wp-block-jetpack-mailchimp_';
- const waiting = (
- <Placeholder icon={ icon } notices={ notices }>
- <Spinner />
- </Placeholder>
- );
- const placeholder = (
- <Placeholder icon={ icon } label={ __( 'Mailchimp', 'jetpack' ) } notices={ notices }>
- <div className="components-placeholder__instructions">
- { __(
- 'You need to connect your Mailchimp account and choose a list in order to start collecting Email subscribers.',
- 'jetpack'
- ) }
- <br />
- <br />
- <Button isDefault isLarge href={ connectURL } target="_blank">
- { __( 'Set up Mailchimp form', 'jetpack' ) }
- </Button>
- <br />
- <br />
- <Button isLink onClick={ this.apiCall }>
- { __( 'Re-check Connection', 'jetpack' ) }
- </Button>
- </div>
- </Placeholder>
- );
- const inspectorControls = (
- <InspectorControls>
- <PanelBody title={ __( 'Text Elements', 'jetpack' ) }>
- <TextControl
- label={ __( 'Email Placeholder', 'jetpack' ) }
- value={ emailPlaceholder }
- onChange={ this.updateEmailPlaceholder }
- />
- </PanelBody>
- <PanelBody title={ __( 'Notifications', 'jetpack' ) }>
- <TextControl
- label={ __( 'Processing text', 'jetpack' ) }
- value={ processingLabel }
- onChange={ this.updateProcessingText }
- />
- <TextControl
- label={ __( 'Success text', 'jetpack' ) }
- value={ successLabel }
- onChange={ this.updateSuccessText }
- />
- <TextControl
- label={ __( 'Error text', 'jetpack' ) }
- value={ errorLabel }
- onChange={ this.updateErrorText }
- />
- </PanelBody>
- <PanelBody title={ __( 'Mailchimp Connection', 'jetpack' ) }>
- <ExternalLink href={ connectURL }>{ __( 'Manage Connection', 'jetpack' ) }</ExternalLink>
- </PanelBody>
- </InspectorControls>
- );
- const blockClasses = classnames( className, {
- [ `${ classPrefix }notication-audition` ]: audition,
- } );
- const blockContent = (
- <div className={ blockClasses }>
- <TextControl
- aria-label={ emailPlaceholder }
- className="wp-block-jetpack-mailchimp_text-input"
- disabled
- onChange={ () => false }
- placeholder={ emailPlaceholder }
- title={ __( 'You can edit the email placeholder in the sidebar.', 'jetpack' ) }
- type="email"
- />
- <SubmitButton { ...this.props } />
- <RichText
- tagName="p"
- placeholder={ __( 'Write consent text', 'jetpack' ) }
- value={ consentText }
- onChange={ value => setAttributes( { consentText: value } ) }
- inlineToolbar
- />
- { audition && (
- <div
- className={ `${ classPrefix }notification ${ classPrefix }${ audition }` }
- role={ this.roleForAuditionType( audition ) }
- >
- { this.labelForAuditionType( audition ) }
- </div>
- ) }
- </div>
- );
- return (
- <Fragment>
- { noticeUI }
- { connected === API_STATE_LOADING && waiting }
- { connected === API_STATE_NOTCONNECTED && placeholder }
- { connected === API_STATE_CONNECTED && inspectorControls }
- { connected === API_STATE_CONNECTED && blockContent }
- </Fragment>
- );
- };
-}
-
-export default withNotices( MailchimpSubscribeEdit );
diff --git a/plugins/jetpack/extensions/blocks/mailchimp/editor.js b/plugins/jetpack/extensions/blocks/mailchimp/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/mailchimp/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/mailchimp/editor.scss b/plugins/jetpack/extensions/blocks/mailchimp/editor.scss
deleted file mode 100644
index 84de7548..00000000
--- a/plugins/jetpack/extensions/blocks/mailchimp/editor.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-@import './view.scss';
-
-.wp-block-jetpack-mailchimp {
-
- .wp-block-jetpack-mailchimp_notification {
- display: block;
- }
-
- .editor-rich-text__inline-toolbar {
- pointer-events: none;
- .components-toolbar {
- pointer-events: all;
- }
- }
-
- // Hide everything else except notification when modifying notification labels
- &.wp-block-jetpack-mailchimp_notication-audition > *:not( .wp-block-jetpack-mailchimp_notification ) {
- display: none;
- }
-
- .wp-block-jetpack-mailchimp_text-input, .jetpack-submit-button {
- margin-bottom: 1.5rem;
- }
-
- .wp-block-button .wp-block-button__link {
- margin-top: 0;
- }
-
-}
diff --git a/plugins/jetpack/extensions/blocks/mailchimp/index.js b/plugins/jetpack/extensions/blocks/mailchimp/index.js
deleted file mode 100644
index 32412656..00000000
--- a/plugins/jetpack/extensions/blocks/mailchimp/index.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import './editor.scss';
-
-export const name = 'mailchimp';
-
-export const icon = (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z" />
- </SVG>
-);
-
-export const settings = {
- title: __( 'Mailchimp', 'jetpack' ),
- icon,
- description: __( 'A form enabling readers to join a Mailchimp list.', 'jetpack' ),
- category: 'jetpack',
- keywords: [
- _x( 'email', 'block search term', 'jetpack' ),
- _x( 'subscription', 'block search term', 'jetpack' ),
- _x( 'newsletter', 'block search term', 'jetpack' ),
- ],
- attributes: {
- emailPlaceholder: {
- type: 'string',
- default: __( 'Enter your email', 'jetpack' ),
- },
- submitButtonText: {
- type: 'string',
- default: __( 'Join my email list', 'jetpack' ),
- },
- customBackgroundButtonColor: {
- type: 'string',
- },
- customTextButtonColor: {
- type: 'string',
- },
- consentText: {
- type: 'string',
- default: __(
- 'By clicking submit, you agree to share your email address with the site owner and Mailchimp to receive marketing, updates, and other emails from the site owner. Use the unsubscribe link in those emails to opt out at any time.',
- 'jetpack'
- ),
- },
- processingLabel: {
- type: 'string',
- default: __( 'Processing…', 'jetpack' ),
- },
- successLabel: {
- type: 'string',
- default: __( "Success! You're on the list.", 'jetpack' ),
- },
- errorLabel: {
- type: 'string',
- default: __(
- "Whoops! There was an error and we couldn't process your subscription. Please reload the page and try again.",
- 'jetpack'
- ),
- },
- },
- edit,
- save: () => null,
-};
diff --git a/plugins/jetpack/extensions/blocks/mailchimp/mailchimp.php b/plugins/jetpack/extensions/blocks/mailchimp/mailchimp.php
index 7be7823a..80641a1c 100644
--- a/plugins/jetpack/extensions/blocks/mailchimp/mailchimp.php
+++ b/plugins/jetpack/extensions/blocks/mailchimp/mailchimp.php
@@ -28,6 +28,7 @@ function jetpack_mailchimp_block_load_assets( $attr ) {
if ( ! jetpack_mailchimp_verify_connection() ) {
return null;
}
+
$values = array();
$blog_id = ( defined( 'IS_WPCOM' ) && IS_WPCOM )
? get_current_blog_id()
@@ -40,6 +41,9 @@ function jetpack_mailchimp_block_load_assets( $attr ) {
'processingLabel' => esc_html__( 'Processing…', 'jetpack' ),
'successLabel' => esc_html__( 'Success! You\'re on the list.', 'jetpack' ),
'errorLabel' => esc_html__( 'Whoops! There was an error and we couldn\'t process your subscription. Please reload the page and try again.', 'jetpack' ),
+ 'interests' => array(),
+ 'signupFieldTag' => '',
+ 'signupFieldValue' => '',
);
foreach ( $defaults as $id => $default ) {
$values[ $id ] = isset( $attr[ $id ] ) ? $attr[ $id ] : $default;
@@ -47,17 +51,7 @@ function jetpack_mailchimp_block_load_assets( $attr ) {
$values['submitButtonText'] = empty( $values['submitButtonText'] ) ? $defaults['submitButtonText'] : $values['submitButtonText'];
- /* TODO: replace with centralized block_class function */
- $align = isset( $attr['align'] ) ? $attr['align'] : 'center';
- $type = 'mailchimp';
- $classes = array(
- 'wp-block-jetpack-' . $type,
- 'align' . $align,
- );
- if ( isset( $attr['className'] ) ) {
- array_push( $classes, $attr['className'] );
- }
- $classes = implode( $classes, ' ' );
+ $classes = Jetpack_Gutenberg::block_classes( 'mailchimp', $attr );
$button_styles = array();
if ( ! empty( $attr['customBackgroundButtonColor'] ) ) {
@@ -78,13 +72,27 @@ function jetpack_mailchimp_block_load_assets( $attr ) {
)
);
}
- $button_styles = implode( $button_styles, ';' );
+ $button_styles = implode( ';', $button_styles );
+ $amp_form_action = sprintf( 'https://public-api.wordpress.com/rest/v1.1/sites/%s/email_follow/amp/subscribe/', $blog_id );
+ $is_amp_request = class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request();
ob_start();
?>
+
<div class="<?php echo esc_attr( $classes ); ?>" data-blog-id="<?php echo esc_attr( $blog_id ); ?>">
<div class="components-placeholder">
- <form aria-describedby="wp-block-jetpack-mailchimp_consent-text">
+ <form
+ aria-describedby="wp-block-jetpack-mailchimp_consent-text"
+ <?php if ( $is_amp_request ) : ?>
+ action-xhr="<?php echo esc_url( $amp_form_action ); ?>"
+ method="post"
+ id="mailchimp_form"
+ target="_top"
+ <?php if ( $is_amp_request ) : ?>
+ on="submit-success:AMP.setState( { mailing_list_status: 'subscribed', mailing_list_email: event.response.email } )"
+ <?php endif; ?>
+ <?php endif; ?>
+ >
<p>
<input
aria-label="<?php echo esc_attr( $values['emailPlaceholder'] ); ?>"
@@ -92,26 +100,79 @@ function jetpack_mailchimp_block_load_assets( $attr ) {
required
title="<?php echo esc_attr( $values['emailPlaceholder'] ); ?>"
type="email"
+ name="email"
/>
</p>
+ <?php foreach ( is_array( $values['interests'] ) ? $values['interests'] : array() as $interest ) : ?>
+ <input
+ name="interests[<?php echo esc_attr( $interest ); ?>]"
+ type="hidden"
+ class="mc-submit-param"
+ value="1"
+ />
+ <?php endforeach; ?>
+ <?php
+ if (
+ ! empty( $values['signupFieldTag'] )
+ && ! empty( $values['signupFieldValue'] )
+ ) :
+ ?>
+ <input
+ name="merge_fields[<?php echo esc_attr( $values['signupFieldTag'] ); ?>]"
+ type="hidden"
+ class="mc-submit-param"
+ value="<?php echo esc_attr( $values['signupFieldValue'] ); ?>"
+ />
+ <?php endif; ?>
<p>
<button type="submit" class="components-button is-button is-primary" style="<?php echo esc_attr( $button_styles ); ?>">
<?php echo wp_kses_post( $values['submitButtonText'] ); ?>
</button>
</p>
- <p id="wp-block-jetpack-mailchimp_consent-text" name="wp-block-jetpack-mailchimp_consent-text">
+ <p id="wp-block-jetpack-mailchimp_consent-text">
<?php echo wp_kses_post( $values['consentText'] ); ?>
</p>
+
+ <?php if ( $is_amp_request ) : ?>
+
+ <div submit-success>
+ <template type="amp-mustache">
+ <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_success wp-block-jetpack-mailchimp__is-amp">
+ <?php echo esc_html( $values['successLabel'] ); ?>
+ </div>
+ </template>
+ </div>
+ <div submit-error>
+ <template type="amp-mustache">
+ <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_error wp-block-jetpack-mailchimp__is-amp">
+ <?php echo esc_html( $values['errorLabel'] ); ?>
+ </div>
+ </template>
+ </div>
+ <div submitting>
+ <template type="amp-mustache">
+ <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_processing wp-block-jetpack-mailchimp__is-amp" role="status">
+ <?php echo esc_html( $values['processingLabel'] ); ?>
+ </div>
+ </template>
+ </div>
+
+ <?php endif; ?>
+
</form>
- <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_processing" role="status">
- <?php echo esc_html( $values['processingLabel'] ); ?>
- </div>
- <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_success" role="status">
- <?php echo esc_html( $values['successLabel'] ); ?>
- </div>
- <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_error" role="alert">
- <?php echo esc_html( $values['errorLabel'] ); ?>
- </div>
+ <?php if ( ! $is_amp_request ) : ?>
+
+ <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_processing" role="status">
+ <?php echo esc_html( $values['processingLabel'] ); ?>
+ </div>
+ <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_success" role="status">
+ <?php echo esc_html( $values['successLabel'] ); ?>
+ </div>
+ <div class="wp-block-jetpack-mailchimp_notification wp-block-jetpack-mailchimp_error" role="alert">
+ <?php echo esc_html( $values['errorLabel'] ); ?>
+ </div>
+
+ <?php endif; ?>
</div>
</div>
<?php
diff --git a/plugins/jetpack/extensions/blocks/mailchimp/view.js b/plugins/jetpack/extensions/blocks/mailchimp/view.js
deleted file mode 100644
index a2ec7680..00000000
--- a/plugins/jetpack/extensions/blocks/mailchimp/view.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Internal dependencies
- */
-import emailValidator from 'email-validator';
-
-/**
- * Internal dependencies
- */
-import './view.scss';
-
-const blockClassName = 'wp-block-jetpack-mailchimp';
-
-function fetchSubscription( blogId, email ) {
- const url =
- 'https://public-api.wordpress.com/rest/v1.1/sites/' +
- encodeURIComponent( blogId ) +
- '/email_follow/subscribe?email=' +
- encodeURIComponent( email );
- return new Promise( function( resolve, reject ) {
- const xhr = new XMLHttpRequest();
- xhr.open( 'GET', url );
- xhr.onload = function() {
- if ( xhr.status === 200 ) {
- const res = JSON.parse( xhr.responseText );
- resolve( res );
- } else {
- const res = JSON.parse( xhr.responseText );
- reject( res );
- }
- };
- xhr.send();
- } );
-}
-
-function activateSubscription( block, blogId ) {
- const form = block.querySelector( 'form' );
- const errorClass = 'error';
- const processingEl = block.querySelector( '.' + blockClassName + '_processing' );
- const errorEl = block.querySelector( '.' + blockClassName + '_error' );
- const successEl = block.querySelector( '.' + blockClassName + '_success' );
- form.addEventListener( 'submit', e => {
- e.preventDefault();
- const emailField = form.querySelector( 'input' );
- emailField.classList.remove( errorClass );
- const email = emailField.value;
- if ( ! emailValidator.validate( email ) ) {
- emailField.classList.add( errorClass );
- return;
- }
- block.classList.add( 'is-processing' );
- processingEl.classList.add( 'is-visible' );
- fetchSubscription( blogId, email ).then(
- response => {
- processingEl.classList.remove( 'is-visible' );
- if ( response.error && response.error !== 'member_exists' ) {
- errorEl.classList.add( 'is-visible' );
- } else {
- successEl.classList.add( 'is-visible' );
- }
- },
- () => {
- processingEl.classList.remove( 'is-visible' );
- errorEl.classList.add( 'is-visible' );
- }
- );
- } );
-}
-
-const initializeMailchimpBlocks = () => {
- const mailchimpBlocks = Array.from( document.querySelectorAll( '.' + blockClassName ) );
- mailchimpBlocks.forEach( block => {
- const blog_id = block.getAttribute( 'data-blog-id' );
- try {
- activateSubscription( block, blog_id );
- } catch ( err ) {
- if ( 'production' !== process.env.NODE_ENV ) {
- // eslint-disable-next-line no-console
- console.error( err );
- }
- }
- } );
-};
-
-if ( typeof window !== 'undefined' && typeof document !== 'undefined' ) {
- // `DOMContentLoaded` may fire before the script has a chance to run
- if ( document.readyState === 'loading' ) {
- document.addEventListener( 'DOMContentLoaded', initializeMailchimpBlocks );
- } else {
- initializeMailchimpBlocks();
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/mailchimp/view.scss b/plugins/jetpack/extensions/blocks/mailchimp/view.scss
deleted file mode 100644
index c01cec98..00000000
--- a/plugins/jetpack/extensions/blocks/mailchimp/view.scss
+++ /dev/null
@@ -1,34 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.wp-block-jetpack-mailchimp {
-
- &.is-processing {
- form {
- display: none;
- }
- }
-
- .wp-block-jetpack-mailchimp_notification {
- display: none;
- margin-bottom: 1.5em;
- padding: 0.75em;
- &.is-visible {
- display: block;
- }
-
- &.wp-block-jetpack-mailchimp_error {
- background-color: var( --muriel-hot-red-500 );
- color: var( --muriel-white );
- }
-
- &.wp-block-jetpack-mailchimp_processing {
- background-color: rgba( 0, 0, 0, 0.025 ); // This would be "dark-opacity-light-50" which doesn't exist in Gutenberg
- }
-
- &.wp-block-jetpack-mailchimp_success {
- background-color: var( --muriel-hot-green-500 );
- color: var( --muriel-white );
- }
- }
-
-}
diff --git a/plugins/jetpack/extensions/blocks/map/add-point/index.js b/plugins/jetpack/extensions/blocks/map/add-point/index.js
deleted file mode 100644
index a4c6e2e1..00000000
--- a/plugins/jetpack/extensions/blocks/map/add-point/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { Button, Dashicon, Popover } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import './style.scss';
-import LocationSearch from '../location-search';
-
-export class AddPoint extends Component {
- render() {
- const { onClose, onAddPoint, onError, apiKey } = this.props;
- return (
- <Button className="component__add-point">
- { __( 'Add marker', 'jetpack' ) }
- <Popover className="component__add-point__popover">
- <Button className="component__add-point__close" onClick={ onClose }>
- <Dashicon icon="no" />
- </Button>
- <LocationSearch
- onAddPoint={ onAddPoint }
- label={ __( 'Add a location', 'jetpack' ) }
- apiKey={ apiKey }
- onError={ onError }
- />
- </Popover>
- </Button>
- );
- }
-}
-
-AddPoint.defaultProps = {
- onAddPoint: () => {},
- onClose: () => {},
- onError: () => {},
-};
-
-export default AddPoint;
diff --git a/plugins/jetpack/extensions/blocks/map/add-point/oval.svg b/plugins/jetpack/extensions/blocks/map/add-point/oval.svg
deleted file mode 100644
index cb149ec4..00000000
--- a/plugins/jetpack/extensions/blocks/map/add-point/oval.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="32px" height="38px" viewBox="0 0 32 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <!-- Generator: Sketch 52.1 (67048) - http://www.bohemiancoding.com/sketch -->
- <title>Oval Copy</title>
- <desc>Created with Sketch.</desc>
- <defs>
- <path d="M119,136 C119,136 135,124.692424 135,114 C135,103.307576 127.836556,98 119,98 C110.163444,98 103,103.307576 103,114 C103,124.692424 119,136 119,136 Z" id="path-1"></path>
- <mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="32" height="38" fill="white">
- <use xlink:href="#path-1"></use>
- </mask>
- </defs>
- <g id="Map-Block" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-dasharray="4">
- <g id="Revised-01-Placeholder-Copy" transform="translate(-496.000000, -376.000000)" stroke="#444444" stroke-width="4">
- <g id="Group" transform="translate(393.000000, 278.000000)">
- <use id="Oval-Copy" mask="url(#mask-2)" xlink:href="#path-1"></use>
- </g>
- </g>
- </g>
-</svg> \ No newline at end of file
diff --git a/plugins/jetpack/extensions/blocks/map/add-point/style.scss b/plugins/jetpack/extensions/blocks/map/add-point/style.scss
deleted file mode 100644
index dba3c0c0..00000000
--- a/plugins/jetpack/extensions/blocks/map/add-point/style.scss
+++ /dev/null
@@ -1,46 +0,0 @@
-@import '../../../shared/styles/gutenberg-colors.scss';
-
-.component__add-point {
- position: absolute;
- left: 50%;
- top: 50%;
- width: 32px;
- height: 38px;
- margin-top: -19px;
- margin-left: -16px;
- background-image: url( ./oval.svg );
- background-repeat: no-repeat;
- text-indent: -9999px;
- box-shadow: none;
- background-color: transparent;
- &.components-button:not( :disabled ):not( [aria-disabled='true'] ):focus {
- background-color: transparent;
- box-shadow: none;
- }
- &:focus,
- &:active {
- background-color: transparent;
- }
-}
-.component__add-point__popover {
- .components-button:not( :disabled ):not( [aria-disabled='true'] ):focus {
- background-color: transparent;
- box-shadow: none;
- }
- .components-popover__content {
- padding: 0.1rem;
- }
- .components-location-search {
- margin: 0.5rem;
- }
-}
-.component__add-point__close {
- margin: 0;
- padding: 0;
- border: none;
- box-shadow: none;
- float: right;
- path {
- color: $dark-gray-150;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/map/component.js b/plugins/jetpack/extensions/blocks/map/component.js
deleted file mode 100644
index c4ea55ae..00000000
--- a/plugins/jetpack/extensions/blocks/map/component.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { assign, debounce, get } from 'lodash';
-import { Button, Dashicon, TextareaControl, TextControl } from '@wordpress/components';
-import { Children, Component, createRef, Fragment } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import MapMarker from './map-marker/';
-import InfoWindow from './info-window/';
-import { mapboxMapFormatter } from './mapbox-map-formatter/';
-
-export class Map extends Component {
- // Lifecycle
- constructor() {
- super( ...arguments );
-
- this.state = {
- map: null,
- fit_to_bounds: false,
- loaded: false,
- mapboxgl: null,
- };
-
- // Refs
- this.mapRef = createRef();
-
- // Debouncers
- this.debouncedSizeMap = debounce( this.sizeMap, 250 );
- }
- render() {
- const { points, admin, children, markerColor } = this.props;
- const { map, activeMarker, mapboxgl } = this.state;
- const { onMarkerClick, deleteActiveMarker, updateActiveMarker } = this;
- const currentPoint = get( activeMarker, 'props.point' ) || {};
- const { title, caption } = currentPoint;
- const addPoint = Children.map( children, child => {
- const tagName = get( child, 'props.tagName' );
- if ( 'AddPoint' === tagName ) {
- return child;
- }
- } );
- const mapMarkers =
- map &&
- mapboxgl &&
- points.map( ( point, index ) => {
- return (
- <MapMarker
- key={ index }
- point={ point }
- index={ index }
- map={ map }
- mapboxgl={ mapboxgl }
- markerColor={ markerColor }
- onClick={ onMarkerClick }
- />
- );
- } );
- const infoWindow = mapboxgl && (
- <InfoWindow
- activeMarker={ activeMarker }
- map={ map }
- mapboxgl={ mapboxgl }
- unsetActiveMarker={ () => this.setState( { activeMarker: null } ) }
- >
- { activeMarker && admin && (
- <Fragment>
- <TextControl
- label={ __( 'Marker Title', 'jetpack' ) }
- value={ title }
- onChange={ value => updateActiveMarker( { title: value } ) }
- />
- <TextareaControl
- className="wp-block-jetpack-map__marker-caption"
- label={ __( 'Marker Caption', 'jetpack' ) }
- value={ caption }
- rows="2"
- tag="textarea"
- onChange={ value => updateActiveMarker( { caption: value } ) }
- />
- <Button onClick={ deleteActiveMarker } className="wp-block-jetpack-map__delete-btn">
- <Dashicon icon="trash" size="15" /> { __( 'Delete Marker', 'jetpack' ) }
- </Button>
- </Fragment>
- ) }
-
- { activeMarker && ! admin && (
- <Fragment>
- <h3>{ title }</h3>
- <p>{ caption }</p>
- </Fragment>
- ) }
- </InfoWindow>
- );
- return (
- <Fragment>
- <div className="wp-block-jetpack-map__gm-container" ref={ this.mapRef }>
- { mapMarkers }
- </div>
- { infoWindow }
- { addPoint }
- </Fragment>
- );
- }
- componentDidMount() {
- const { apiKey } = this.props;
- if ( apiKey ) {
- this.loadMapLibraries();
- }
- }
- componentWillUnmount() {
- this.debouncedSizeMap.cancel();
- }
- componentDidUpdate( prevProps ) {
- const { apiKey, children, points, mapStyle, mapDetails } = this.props;
- const { map } = this.state;
- if ( apiKey && apiKey.length > 0 && apiKey !== prevProps.apiKey ) {
- this.loadMapLibraries();
- }
- // If the user has just clicked to show the Add Point component, hide info window.
- // AddPoint is the only possible child.
- if ( children !== prevProps.children && children !== false ) {
- this.clearCurrentMarker();
- }
- if ( points !== prevProps.points ) {
- this.setBoundsByMarkers();
- }
- if ( points.length !== prevProps.points.length ) {
- this.clearCurrentMarker();
- }
- if ( mapStyle !== prevProps.mapStyle || mapDetails !== prevProps.mapDetails ) {
- map.setStyle( this.getMapStyle() );
- }
- }
- /* Event handling */
- onMarkerClick = marker => {
- const { onMarkerClick } = this.props;
- this.setState( { activeMarker: marker } );
- onMarkerClick();
- };
- onMapClick = () => {
- this.setState( { activeMarker: null } );
- };
- clearCurrentMarker = () => {
- this.setState( { activeMarker: null } );
- };
- updateActiveMarker = updates => {
- const { points } = this.props;
- const { activeMarker } = this.state;
- const { index } = activeMarker.props;
- const newPoints = points.slice( 0 );
-
- assign( newPoints[ index ], updates );
- this.props.onSetPoints( newPoints );
- };
- deleteActiveMarker = () => {
- const { points } = this.props;
- const { activeMarker } = this.state;
- const { index } = activeMarker.props;
- const newPoints = points.slice( 0 );
-
- newPoints.splice( index, 1 );
- this.props.onSetPoints( newPoints );
- this.setState( { activeMarker: null } );
- };
- // Various map functions
- sizeMap = () => {
- const { map } = this.state;
- const mapEl = this.mapRef.current;
- const blockWidth = mapEl.offsetWidth;
- const maxHeight = window.innerHeight * 0.8;
- const blockHeight = Math.min( blockWidth * ( 3 / 4 ), maxHeight );
- mapEl.style.height = blockHeight + 'px';
- map.resize();
- this.setBoundsByMarkers();
- };
- setBoundsByMarkers = () => {
- const { zoom, points, onSetZoom } = this.props;
- const { map, activeMarker, mapboxgl, zoomControl, boundsSetProgrammatically } = this.state;
- if ( ! map ) {
- return;
- }
- // If there are no points at all, there is no data to set bounds to. Abort the function.
- if ( ! points.length ) {
- return;
- }
- // If there is an open info window, resizing will probably move the info window which complicates interaction.
- if ( activeMarker ) {
- return;
- }
- const bounds = new mapboxgl.LngLatBounds();
- points.forEach( point => {
- bounds.extend( [ point.coordinates.longitude, point.coordinates.latitude ] );
- } );
-
- // If there are multiple points, zoom is determined by the area they cover, and zoom control is removed.
- if ( points.length > 1 ) {
- map.fitBounds( bounds, {
- padding: {
- top: 40,
- bottom: 40,
- left: 20,
- right: 20,
- },
- } );
- this.setState( { boundsSetProgrammatically: true } );
- map.removeControl( zoomControl );
- return;
- }
- // If there is only one point, center map around it.
- map.setCenter( bounds.getCenter() );
-
- // If the number of markers has just changed from > 1 to 1, set an arbitrary tight zoom, which feels like the original default.
- if ( boundsSetProgrammatically ) {
- const newZoom = 12;
- map.setZoom( newZoom );
- onSetZoom( newZoom );
- } else {
- // If there are one (or zero) points, and this is not a recent change, respect user's chosen zoom.
- map.setZoom( parseInt( zoom, 10 ) );
- }
- map.addControl( zoomControl );
- this.setState( { boundsSetProgrammatically: false } );
- };
- getMapStyle() {
- const { mapStyle, mapDetails } = this.props;
- return mapboxMapFormatter( mapStyle, mapDetails );
- }
- getMapType() {
- const { mapStyle } = this.props;
- switch ( mapStyle ) {
- case 'satellite':
- return 'HYBRID';
- case 'terrain':
- return 'TERRAIN';
- case 'black_and_white':
- default:
- return 'ROADMAP';
- }
- }
- // Script loading, browser geolocation
- scriptsLoaded = () => {
- const { mapCenter, points } = this.props;
- this.setState( { loaded: true } );
-
- // If the map has any points, skip geolocation and use what we have.
- if ( points.length > 0 ) {
- this.initMap( mapCenter );
- return;
- }
- this.initMap( mapCenter );
- };
- loadMapLibraries() {
- const { apiKey } = this.props;
- Promise.all( [
- import( /* webpackChunkName: "map/mapbox-gl" */ 'mapbox-gl' ),
- import( /* webpackChunkName: "map/mapbox-gl" */ 'mapbox-gl/dist/mapbox-gl.css' ),
- ] ).then( ( [ { default: mapboxgl } ] ) => {
- mapboxgl.accessToken = apiKey;
- this.setState( { mapboxgl: mapboxgl }, this.scriptsLoaded );
- } );
- }
- initMap( mapCenter ) {
- const { mapboxgl } = this.state;
- const { zoom, onMapLoaded, onError, admin } = this.props;
- let map = null;
- try {
- map = new mapboxgl.Map( {
- container: this.mapRef.current,
- style: this.getMapStyle(),
- center: this.googlePoint2Mapbox( mapCenter ),
- zoom: parseInt( zoom, 10 ),
- pitchWithRotate: false,
- attributionControl: false,
- dragRotate: false,
- } );
- } catch ( e ) {
- onError( 'mapbox_error', e.message );
- return;
- }
- map.on( 'error', e => {
- onError( 'mapbox_error', e.error.message );
- } );
- const zoomControl = new mapboxgl.NavigationControl( {
- showCompass: false,
- showZoom: true,
- } );
- map.on( 'zoomend', () => {
- this.props.onSetZoom( map.getZoom() );
- } );
-
- /* Listen for clicks on the Map background, which hides the current popup. */
- map.getCanvas().addEventListener( 'click', this.onMapClick );
- this.setState( { map, zoomControl }, () => {
- this.debouncedSizeMap();
- map.addControl( zoomControl );
- if ( ! admin ) {
- map.addControl( new mapboxgl.FullscreenControl() );
- }
- this.mapRef.current.addEventListener( 'alignmentChanged', this.debouncedSizeMap );
- map.resize();
- onMapLoaded();
- this.setState( { loaded: true } );
- window.addEventListener( 'resize', this.debouncedSizeMap );
- } );
- }
- googlePoint2Mapbox( google_point ) {
- const mapCenter = [
- google_point.longitude ? google_point.longitude : 0,
- google_point.latitude ? google_point.latitude : 0,
- ];
- return mapCenter;
- }
-}
-
-Map.defaultProps = {
- points: [],
- mapStyle: 'default',
- zoom: 13,
- onSetZoom: () => {},
- onMapLoaded: () => {},
- onMarkerClick: () => {},
- onError: () => {},
- markerColor: 'red',
- apiKey: null,
- mapCenter: {},
-};
-
-export default Map;
diff --git a/plugins/jetpack/extensions/blocks/map/edit.js b/plugins/jetpack/extensions/blocks/map/edit.js
deleted file mode 100644
index 87889f63..00000000
--- a/plugins/jetpack/extensions/blocks/map/edit.js
+++ /dev/null
@@ -1,283 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-import { __ } from '@wordpress/i18n';
-import { Component, createRef, Fragment } from '@wordpress/element';
-import {
- Button,
- ButtonGroup,
- ExternalLink,
- IconButton,
- PanelBody,
- Placeholder,
- Spinner,
- TextControl,
- ToggleControl,
- Toolbar,
- withNotices,
-} from '@wordpress/components';
-import {
- BlockAlignmentToolbar,
- BlockControls,
- InspectorControls,
- PanelColorSettings,
-} from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import AddPoint from './add-point';
-import Locations from './locations';
-import Map from './component.js';
-import MapThemePicker from './map-theme-picker';
-import { settings } from './settings.js';
-
-const API_STATE_LOADING = 0;
-const API_STATE_FAILURE = 1;
-const API_STATE_SUCCESS = 2;
-
-class MapEdit extends Component {
- constructor() {
- super( ...arguments );
- this.state = {
- addPointVisibility: false,
- apiState: API_STATE_LOADING,
- };
- this.mapRef = createRef();
- }
- addPoint = point => {
- const { attributes, setAttributes } = this.props;
- const { points } = attributes;
- const newPoints = points.slice( 0 );
- let duplicateFound = false;
- points.map( existingPoint => {
- if ( existingPoint.id === point.id ) {
- duplicateFound = true;
- }
- } );
- if ( duplicateFound ) {
- return;
- }
- newPoints.push( point );
- setAttributes( { points: newPoints } );
- this.setState( { addPointVisibility: false } );
- };
- updateAlignment = value => {
- this.props.setAttributes( { align: value } );
- // Allow one cycle for alignment change to take effect
- setTimeout( this.mapRef.current.sizeMap, 0 );
- };
- updateAPIKeyControl = value => {
- this.setState( {
- apiKeyControl: value,
- } );
- };
- updateAPIKey = () => {
- const { noticeOperations } = this.props;
- const { apiKeyControl } = this.state;
- noticeOperations.removeAllNotices();
- apiKeyControl && this.apiCall( apiKeyControl, 'POST' );
- };
- removeAPIKey = () => {
- this.apiCall( null, 'DELETE' );
- };
- apiCall( serviceApiKey = null, method = 'GET' ) {
- const { noticeOperations } = this.props;
- const { apiKey } = this.state;
- const path = '/wpcom/v2/service-api-keys/mapbox';
- const fetch = serviceApiKey
- ? { path, method, data: { service_api_key: serviceApiKey } }
- : { path, method };
- this.setState( { apiRequestOutstanding: true }, () => {
- apiFetch( fetch ).then(
- result => {
- noticeOperations.removeAllNotices();
- this.setState( {
- apiState: result.service_api_key ? API_STATE_SUCCESS : API_STATE_FAILURE,
- apiKey: result.service_api_key,
- apiKeyControl: result.service_api_key,
- apiRequestOutstanding: false,
- } );
- },
- result => {
- this.onError( null, result.message );
- this.setState( {
- apiRequestOutstanding: false,
- apiKeyControl: apiKey,
- } );
- }
- );
- } );
- }
- componentDidMount() {
- this.apiCall();
- }
- onError = ( code, message ) => {
- const { noticeOperations } = this.props;
- noticeOperations.removeAllNotices();
- noticeOperations.createErrorNotice( message );
- };
- render() {
- const { className, setAttributes, attributes, noticeUI, notices } = this.props;
- const { mapStyle, mapDetails, points, zoom, mapCenter, markerColor, align } = attributes;
- const {
- addPointVisibility,
- apiKey,
- apiKeyControl,
- apiState,
- apiRequestOutstanding,
- } = this.state;
- const inspectorControls = (
- <Fragment>
- <BlockControls>
- <BlockAlignmentToolbar
- value={ align }
- onChange={ this.updateAlignment }
- controls={ [ 'center', 'wide', 'full' ] }
- />
- <Toolbar>
- <IconButton
- icon={ settings.markerIcon }
- label="Add a marker"
- onClick={ () => this.setState( { addPointVisibility: true } ) }
- />
- </Toolbar>
- </BlockControls>
- <InspectorControls>
- <PanelBody title={ __( 'Map Theme', 'jetpack' ) }>
- <MapThemePicker
- value={ mapStyle }
- onChange={ value => setAttributes( { mapStyle: value } ) }
- options={ settings.mapStyleOptions }
- />
- <ToggleControl
- label={ __( 'Show street names', 'jetpack' ) }
- checked={ mapDetails }
- onChange={ value => setAttributes( { mapDetails: value } ) }
- />
- </PanelBody>
- <PanelColorSettings
- title={ __( 'Colors', 'jetpack' ) }
- initialOpen={ true }
- colorSettings={ [
- {
- value: markerColor,
- onChange: value => setAttributes( { markerColor: value } ),
- label: 'Marker Color',
- },
- ] }
- />
- { points.length ? (
- <PanelBody title={ __( 'Markers', 'jetpack' ) } initialOpen={ false }>
- <Locations
- points={ points }
- onChange={ value => {
- setAttributes( { points: value } );
- } }
- />
- </PanelBody>
- ) : null }
- <PanelBody title={ __( 'Mapbox Access Token', 'jetpack' ) } initialOpen={ false }>
- <TextControl
- label={ __( 'Mapbox Access Token', 'jetpack' ) }
- value={ apiKeyControl }
- onChange={ value => this.setState( { apiKeyControl: value } ) }
- />
- <ButtonGroup>
- <Button type="button" onClick={ this.updateAPIKey } isDefault>
- { __( 'Update Token', 'jetpack' ) }
- </Button>
- <Button type="button" onClick={ this.removeAPIKey } isDefault>
- { __( 'Remove Token', 'jetpack' ) }
- </Button>
- </ButtonGroup>
- </PanelBody>
- </InspectorControls>
- </Fragment>
- );
- const placholderAPIStateLoading = (
- <Placeholder icon={ settings.icon }>
- <Spinner />
- </Placeholder>
- );
- const placeholderAPIStateFailure = (
- <Placeholder icon={ settings.icon } label={ __( 'Map', 'jetpack' ) } notices={ notices }>
- <Fragment>
- <div className="components-placeholder__instructions">
- { __( 'To use the map block, you need an Access Token.', 'jetpack' ) }
- <br />
- <ExternalLink href="https://www.mapbox.com">
- { __( 'Create an account or log in to Mapbox.', 'jetpack' ) }
- </ExternalLink>
- <br />
- { __(
- 'Locate and copy the default access token. Then, paste it into the field below.',
- 'jetpack'
- ) }
- </div>
- <TextControl
- className="wp-block-jetpack-map-components-text-control-api-key"
- disabled={ apiRequestOutstanding }
- placeholder={ __( 'Paste Token Here', 'jetpack' ) }
- value={ apiKeyControl }
- onChange={ this.updateAPIKeyControl }
- />
- <Button
- className="wp-block-jetpack-map-components-text-control-api-key-submit"
- isLarge
- disabled={ apiRequestOutstanding || ! apiKeyControl || apiKeyControl.length < 1 }
- onClick={ this.updateAPIKey }
- >
- { __( 'Set Token', 'jetpack' ) }
- </Button>
- </Fragment>
- </Placeholder>
- );
- const placeholderAPIStateSuccess = (
- <Fragment>
- { inspectorControls }
- <div className={ className }>
- <Map
- ref={ this.mapRef }
- mapStyle={ mapStyle }
- mapDetails={ mapDetails }
- points={ points }
- zoom={ zoom }
- mapCenter={ mapCenter }
- markerColor={ markerColor }
- onSetZoom={ value => {
- setAttributes( { zoom: value } );
- } }
- admin={ true }
- apiKey={ apiKey }
- onSetPoints={ value => setAttributes( { points: value } ) }
- onMapLoaded={ () => this.setState( { addPointVisibility: true } ) }
- onMarkerClick={ () => this.setState( { addPointVisibility: false } ) }
- onError={ this.onError }
- >
- { addPointVisibility && (
- <AddPoint
- onAddPoint={ this.addPoint }
- onClose={ () => this.setState( { addPointVisibility: false } ) }
- apiKey={ apiKey }
- onError={ this.onError }
- tagName="AddPoint"
- />
- ) }
- </Map>
- </div>
- </Fragment>
- );
- return (
- <Fragment>
- { noticeUI }
- { apiState === API_STATE_LOADING && placholderAPIStateLoading }
- { apiState === API_STATE_FAILURE && placeholderAPIStateFailure }
- { apiState === API_STATE_SUCCESS && placeholderAPIStateSuccess }
- </Fragment>
- );
- }
-}
-
-export default withNotices( MapEdit );
diff --git a/plugins/jetpack/extensions/blocks/map/editor.js b/plugins/jetpack/extensions/blocks/map/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/map/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/map/editor.scss b/plugins/jetpack/extensions/blocks/map/editor.scss
deleted file mode 100644
index ab66d12b..00000000
--- a/plugins/jetpack/extensions/blocks/map/editor.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-
-.wp-block-jetpack-map__delete-btn {
- padding: 0;
- svg {
- margin-right: 0.4em;
- }
-}
-.wp-block-jetpack-map-components-text-control-api-key {
- margin-right: 4px;
- &.components-base-control .components-base-control__field {
- margin-bottom: 0;
- }
-}
-.wp-block-jetpack-map-components-text-control-api-key-submit.is-large {
- height: 31px;
-}
-.wp-block-jetpack-map-components-text-control-api-key-submit:disabled {
- opacity: 1;
-}
-.wp-block[data-type='jetpack/map'] {
- .components-placeholder__label {
- svg {
- fill: currentColor;
- margin-right: 6px;
- margin-right: 1ch;
- }
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/map/index.js b/plugins/jetpack/extensions/blocks/map/index.js
deleted file mode 100644
index 2e66caae..00000000
--- a/plugins/jetpack/extensions/blocks/map/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Internal dependencies
- */
-import { settings as mapSettings } from './settings.js';
-import edit from './edit';
-import save from './save';
-import './style.scss';
-import './editor.scss';
-
-export const { name } = mapSettings;
-
-export const settings = {
- title: mapSettings.title,
- icon: mapSettings.icon,
- category: mapSettings.category,
- keywords: mapSettings.keywords,
- description: mapSettings.description,
- attributes: mapSettings.attributes,
- supports: mapSettings.supports,
- getEditWrapperProps( attributes ) {
- const { align } = attributes;
- if ( -1 !== mapSettings.validAlignments.indexOf( align ) ) {
- return { 'data-align': align };
- }
- },
- edit,
- save,
-};
diff --git a/plugins/jetpack/extensions/blocks/map/info-window/index.js b/plugins/jetpack/extensions/blocks/map/info-window/index.js
deleted file mode 100644
index f469efad..00000000
--- a/plugins/jetpack/extensions/blocks/map/info-window/index.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * External dependencies
- */
-
-import { Component, createPortal } from '@wordpress/element';
-
-export class InfoWindow extends Component {
- componentDidMount() {
- const { mapboxgl } = this.props;
- this.el = document.createElement( 'DIV' );
- this.infowindow = new mapboxgl.Popup( {
- closeButton: true,
- closeOnClick: false,
- offset: {
- left: [ 0, 0 ],
- top: [ 0, 5 ],
- right: [ 0, 0 ],
- bottom: [ 0, -40 ],
- },
- } );
- this.infowindow.setDOMContent( this.el );
- this.infowindow.on( 'close', this.closeClick );
- }
- componentDidUpdate( prevProps ) {
- if ( this.props.activeMarker !== prevProps.activeMarker ) {
- this.props.activeMarker ? this.openWindow() : this.closeWindow();
- }
- }
- render() {
- // Use React portal to render components directly into the Mapbox info window.
- return this.el ? createPortal( this.props.children, this.el ) : null;
- }
- closeClick = () => {
- this.props.unsetActiveMarker();
- };
- openWindow() {
- const { map, activeMarker } = this.props;
- this.infowindow.setLngLat( activeMarker.getPoint() ).addTo( map );
- }
- closeWindow() {
- this.infowindow.remove();
- }
-}
-
-InfoWindow.defaultProps = {
- unsetActiveMarker: () => {},
- activeMarker: null,
- map: null,
- mapboxgl: null,
-};
-
-export default InfoWindow;
diff --git a/plugins/jetpack/extensions/blocks/map/location-search/index.js b/plugins/jetpack/extensions/blocks/map/location-search/index.js
deleted file mode 100644
index aad845ca..00000000
--- a/plugins/jetpack/extensions/blocks/map/location-search/index.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Component, createRef } from '@wordpress/element';
-import { BaseControl, TextControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import Lookup from '../lookup';
-
-const placeholderText = __( 'Add a marker…', 'jetpack' );
-
-export class LocationSearch extends Component {
- constructor() {
- super( ...arguments );
-
- this.textRef = createRef();
- this.containerRef = createRef();
- this.state = {
- isEmpty: true,
- };
- this.autocompleter = {
- name: 'placeSearch',
- options: this.search,
- isDebounced: true,
- getOptionLabel: option => <span>{ option.place_name }</span>,
- getOptionKeywords: option => [ option.place_name ],
- getOptionCompletion: this.getOptionCompletion,
- };
- }
- componentDidMount() {
- setTimeout( () => {
- this.containerRef.current.querySelector( 'input' ).focus();
- }, 50 );
- }
- getOptionCompletion = option => {
- const { value } = option;
- const point = {
- placeTitle: value.text,
- title: value.text,
- caption: value.place_name,
- id: value.id,
- coordinates: {
- longitude: value.geometry.coordinates[ 0 ],
- latitude: value.geometry.coordinates[ 1 ],
- },
- };
- this.props.onAddPoint( point );
- return value.text;
- };
-
- search = value => {
- const { apiKey, onError } = this.props;
- const url =
- 'https://api.mapbox.com/geocoding/v5/mapbox.places/' +
- encodeURI( value ) +
- '.json?access_token=' +
- apiKey;
- return new Promise( function( resolve, reject ) {
- const xhr = new XMLHttpRequest();
- xhr.open( 'GET', url );
- xhr.onload = function() {
- if ( xhr.status === 200 ) {
- const res = JSON.parse( xhr.responseText );
- resolve( res.features );
- } else {
- const res = JSON.parse( xhr.responseText );
- onError( res.statusText, res.responseJSON.message );
- reject( new Error( 'Mapbox Places Error' ) );
- }
- };
- xhr.send();
- } );
- };
- onReset = () => {
- this.textRef.current.value = null;
- };
- render() {
- const { label } = this.props;
- return (
- <div ref={ this.containerRef }>
- <BaseControl label={ label } className="components-location-search">
- <Lookup completer={ this.autocompleter } onReset={ this.onReset }>
- { ( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) => (
- <TextControl
- placeholder={ placeholderText }
- ref={ this.textRef }
- onChange={ onChange }
- aria-expanded={ isExpanded }
- aria-owns={ listBoxId }
- aria-activedescendant={ activeId }
- onKeyDown={ onKeyDown }
- />
- ) }
- </Lookup>
- </BaseControl>
- </div>
- );
- }
-}
-
-LocationSearch.defaultProps = {
- onError: () => {},
-};
-
-export default LocationSearch;
diff --git a/plugins/jetpack/extensions/blocks/map/locations/index.js b/plugins/jetpack/extensions/blocks/map/locations/index.js
deleted file mode 100644
index 80385891..00000000
--- a/plugins/jetpack/extensions/blocks/map/locations/index.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * External dependencies
- */
-import {
- Button,
- Dashicon,
- Panel,
- PanelBody,
- TextareaControl,
- TextControl,
-} from '@wordpress/components';
-import { Component } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import './style.scss';
-
-export class Locations extends Component {
- constructor() {
- super( ...arguments );
- this.state = {
- selectedCell: null,
- };
- }
-
- onDeletePoint = e => {
- const index = parseInt( e.target.getAttribute( 'data-id' ) );
- const { points, onChange } = this.props;
-
- const newPoints = points.slice( 0 );
- newPoints.splice( index, 1 );
- onChange( newPoints );
- };
-
- setMarkerField( field, value, index ) {
- const { points, onChange } = this.props;
-
- const newPoints = points.slice( 0 );
- newPoints[ index ][ field ] = value;
- onChange( newPoints );
- }
-
- render() {
- const { points } = this.props;
- const rows = points.map( ( point, index ) => (
- <PanelBody title={ point.placeTitle } key={ point.id } initialOpen={ false }>
- <TextControl
- label="Marker Title"
- value={ point.title }
- onChange={ title => this.setMarkerField( 'title', title, index ) }
- />
- <TextareaControl
- label="Marker Caption"
- value={ point.caption }
- rows="3"
- onChange={ caption => this.setMarkerField( 'caption', caption, index ) }
- />
- <Button
- data-id={ index }
- onClick={ this.onDeletePoint }
- className="component__locations__delete-btn"
- >
- <Dashicon icon="trash" size="15" /> Delete Marker
- </Button>
- </PanelBody>
- ) );
- return (
- <div className="component__locations">
- <Panel className="component__locations__panel">{ rows }</Panel>
- </div>
- );
- }
-}
-
-Locations.defaultProps = {
- points: Object.freeze( [] ),
- onChange: () => {},
-};
-
-export default Locations;
diff --git a/plugins/jetpack/extensions/blocks/map/locations/style.scss b/plugins/jetpack/extensions/blocks/map/locations/style.scss
deleted file mode 100644
index 73f5e8b5..00000000
--- a/plugins/jetpack/extensions/blocks/map/locations/style.scss
+++ /dev/null
@@ -1,27 +0,0 @@
-
-.component__locations__panel {
- .edit-post-settings-sidebar__panel-block & {
- margin-bottom: 1em;
- &:empty {
- display: none;
- }
- .components-panel__body:first-child {
- border-top: none;
- }
- .components-panel__body,
- .components-panel__body:first-child,
- .components-panel__body:last-child {
- max-width: 100%;
- margin: 0;
- }
- .components-panel__body button {
- padding-right: 40px;
- }
- }
-}
-.component__locations__delete-btn {
- padding: 0;
- svg {
- margin-right: 0.4em;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/map/lookup/index.js b/plugins/jetpack/extensions/blocks/map/lookup/index.js
deleted file mode 100644
index c9d41969..00000000
--- a/plugins/jetpack/extensions/blocks/map/lookup/index.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import { __, _n, sprintf } from '@wordpress/i18n';
-import { Button, Popover, withFocusOutside, withSpokenMessages } from '@wordpress/components';
-import { Component } from '@wordpress/element';
-import { debounce, map } from 'lodash';
-import { ENTER, ESCAPE, UP, DOWN, LEFT, RIGHT } from '@wordpress/keycodes';
-import { withInstanceId, compose } from '@wordpress/compose';
-
-function filterOptions( options = [], maxResults = 10 ) {
- const filtered = [];
- for ( let i = 0; i < options.length; i++ ) {
- const option = options[ i ];
-
- // Merge label into keywords
- let { keywords = [] } = option;
- if ( 'string' === typeof option.label ) {
- keywords = [ ...keywords, option.label ];
- }
-
- filtered.push( option );
-
- // Abort early if max reached
- if ( filtered.length === maxResults ) {
- break;
- }
- }
-
- return filtered;
-}
-
-export class Lookup extends Component {
- static getInitialState() {
- return {
- selectedIndex: 0,
- query: undefined,
- filteredOptions: [],
- isOpen: false,
- };
- }
-
- constructor() {
- super( ...arguments );
- this.debouncedLoadOptions = debounce( this.loadOptions, 250 );
- this.state = this.constructor.getInitialState();
- }
-
- componentWillUnmount() {
- this.debouncedLoadOptions.cancel();
- }
-
- select = option => {
- const { completer } = this.props;
- const getOptionCompletion = completer.getOptionCompletion || {};
- getOptionCompletion( option );
- this.reset();
- };
-
- reset = () => {
- this.setState( this.constructor.getInitialState() );
- };
-
- handleFocusOutside() {
- this.reset();
- }
-
- loadOptions( completer, query ) {
- const { options } = completer;
- const promise = ( this.activePromise = Promise.resolve(
- typeof options === 'function' ? options( query ) : options
- ).then( optionsData => {
- if ( promise !== this.activePromise ) {
- // Another promise has become active since this one was asked to resolve, so do nothing,
- // or else we might end triggering a race condition updating the state.
- return;
- }
- const keyedOptions = optionsData.map( ( optionData, optionIndex ) => ( {
- key: `${ optionIndex }`,
- value: optionData,
- label: completer.getOptionLabel( optionData ),
- keywords: completer.getOptionKeywords ? completer.getOptionKeywords( optionData ) : [],
- } ) );
-
- const filteredOptions = filterOptions( keyedOptions );
- const selectedIndex =
- filteredOptions.length === this.state.filteredOptions.length ? this.state.selectedIndex : 0;
- this.setState( {
- [ 'options' ]: keyedOptions,
- filteredOptions,
- selectedIndex,
- isOpen: filteredOptions.length > 0,
- } );
- this.announce( filteredOptions );
- } ) );
- }
-
- onChange = query => {
- const { completer } = this.props;
- const { options } = this.state;
-
- if ( ! query ) {
- this.reset();
- return;
- }
-
- if ( completer ) {
- if ( completer.isDebounced ) {
- this.debouncedLoadOptions( completer, query );
- } else {
- this.loadOptions( completer, query );
- }
- }
-
- const filteredOptions = completer ? filterOptions( options ) : [];
- if ( completer ) {
- this.setState( { selectedIndex: 0, filteredOptions, query } );
- }
- };
-
- onKeyDown = event => {
- const { isOpen, selectedIndex, filteredOptions } = this.state;
- if ( ! isOpen ) {
- return;
- }
- let nextSelectedIndex;
- switch ( event.keyCode ) {
- case UP:
- nextSelectedIndex = ( selectedIndex === 0 ? filteredOptions.length : selectedIndex ) - 1;
- this.setState( { selectedIndex: nextSelectedIndex } );
- break;
-
- case DOWN:
- nextSelectedIndex = ( selectedIndex + 1 ) % filteredOptions.length;
- this.setState( { selectedIndex: nextSelectedIndex } );
- break;
-
- case ENTER:
- this.select( filteredOptions[ selectedIndex ] );
- break;
-
- case LEFT:
- case RIGHT:
- case ESCAPE:
- this.reset();
- return;
-
- default:
- return;
- }
-
- // Any handled keycode should prevent original behavior. This relies on
- // the early return in the default case.
- event.preventDefault();
- event.stopPropagation();
- };
- announce( filteredOptions ) {
- const { debouncedSpeak } = this.props;
- if ( ! debouncedSpeak ) {
- return;
- }
- if ( filteredOptions.length ) {
- debouncedSpeak(
- sprintf(
- _n(
- '%d result found, use up and down arrow keys to navigate.',
- '%d results found, use up and down arrow keys to navigate.',
- filteredOptions.length,
- 'jetpack',
- 'jetpack'
- ),
- filteredOptions.length
- ),
- 'assertive'
- );
- } else {
- debouncedSpeak( __( 'No results.', 'jetpack' ), 'assertive' );
- }
- }
- render() {
- const { onChange, onKeyDown } = this;
- const { children, instanceId, completer } = this.props;
- const { selectedIndex, filteredOptions } = this.state;
- const { key: selectedKey = '' } = filteredOptions[ selectedIndex ] || {};
- const { className } = completer;
- const isExpanded = filteredOptions.length > 0;
- const listBoxId = isExpanded ? `components-autocomplete-listbox-${ instanceId }` : null;
- const activeId = isExpanded
- ? `components-autocomplete-item-${ instanceId }-${ selectedKey }`
- : null;
- return (
- <div className="components-autocomplete">
- { children( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) }
- { isExpanded && (
- <Popover
- focusOnMount={ false }
- onClose={ this.reset }
- position="top center"
- className="components-autocomplete__popover"
- noArrow
- >
- <div id={ listBoxId } role="listbox" className="components-autocomplete__results">
- { map( filteredOptions, ( option, index ) => (
- <Button
- key={ option.key }
- id={ `components-autocomplete-item-${ instanceId }-${ option.key }` }
- role="option"
- aria-selected={ index === selectedIndex }
- disabled={ option.isDisabled }
- className={ classnames( 'components-autocomplete__result', className, {
- 'is-selected': index === selectedIndex,
- } ) }
- onClick={ () => this.select( option ) }
- >
- { option.label }
- </Button>
- ) ) }
- </div>
- </Popover>
- ) }
- </div>
- );
- }
-}
-export default compose( [
- withSpokenMessages,
- withInstanceId,
- withFocusOutside, // this MUST be the innermost HOC as it calls handleFocusOutside
-] )( Lookup );
diff --git a/plugins/jetpack/extensions/blocks/map/map-marker/index.js b/plugins/jetpack/extensions/blocks/map/map-marker/index.js
deleted file mode 100644
index e8db9934..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-marker/index.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import './style.scss';
-
-export class MapMarker extends Component {
- componentDidMount() {
- this.renderMarker();
- }
- componentWillUnmount() {
- if ( this.marker ) {
- this.marker.remove();
- }
- }
- componentDidUpdate() {
- this.renderMarker();
- }
- handleClick = () => {
- const { onClick } = this.props;
- onClick( this );
- };
- getPoint = () => {
- const { point } = this.props;
- return [ point.coordinates.longitude, point.coordinates.latitude ];
- };
- renderMarker() {
- const { map, point, mapboxgl, markerColor } = this.props;
- const { handleClick } = this;
- const mapboxPoint = [ point.coordinates.longitude, point.coordinates.latitude ];
- const el = this.marker ? this.marker.getElement() : document.createElement( 'div' );
- if ( this.marker ) {
- this.marker.setLngLat( mapboxPoint );
- } else {
- el.className = 'wp-block-jetpack-map-marker';
- this.marker = new mapboxgl.Marker( el )
- .setLngLat( mapboxPoint )
- .setOffset( [ 0, -19 ] )
- .addTo( map );
-
- this.marker.getElement().addEventListener( 'click', handleClick );
- }
- el.innerHTML =
- '<?xml version="1.0" encoding="UTF-8"?><svg version="1.1" viewBox="0 0 32 38" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g fill-rule="evenodd"><path id="d" d="m16 38s16-11.308 16-22-7.1634-16-16-16-16 5.3076-16 16 16 22 16 22z" fill="' +
- markerColor +
- '" mask="url(#c)"/></g></svg>';
- }
- render() {
- return null;
- }
-}
-
-MapMarker.defaultProps = {
- point: {},
- map: null,
- markerColor: '#000000',
- mapboxgl: null,
- onClick: () => {},
-};
-
-export default MapMarker;
diff --git a/plugins/jetpack/extensions/blocks/map/map-marker/style.scss b/plugins/jetpack/extensions/blocks/map/map-marker/style.scss
deleted file mode 100644
index 6c5a2a65..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-marker/style.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-
-.wp-block-jetpack-map-marker {
- width: 32px;
- height: 38px;
- opacity: 0.9;
-}
diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/index.js b/plugins/jetpack/extensions/blocks/map/map-theme-picker/index.js
deleted file mode 100644
index e226534a..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/index.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-import { Button, ButtonGroup } from '@wordpress/components';
-import classnames from 'classnames';
-
-/**
- * Internal dependencies
- */
-import './style.scss';
-
-export class MapThemePicker extends Component {
- render() {
- const { options, value, onChange, label } = this.props;
- const buttons = options.map( ( option, index ) => {
- const classes = classnames(
- 'component__map-theme-picker__button',
- 'is-theme-' + option.value,
- option.value === value ? 'is-selected' : ''
- );
- return (
- <Button
- className={ classes }
- title={ option.label }
- key={ index }
- onClick={ () => onChange( option.value ) }
- >
- { option.label }
- </Button>
- );
- } );
- return (
- <div className="component__map-theme-picker components-base-control">
- { /* eslint-disable-next-line jsx-a11y/label-has-for */ }
- <label className="components-base-control__label">{ label }</label>
- <ButtonGroup>{ buttons }</ButtonGroup>
- </div>
- );
- }
-}
-
-MapThemePicker.defaultProps = {
- label: '',
- options: [],
- value: null,
- onChange: () => {},
-};
-
-export default MapThemePicker;
diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg
deleted file mode 100644
index 34cc1412..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg
+++ /dev/null
Binary files differ
diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_default.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_default.jpg
deleted file mode 100644
index 35505eb1..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_default.jpg
+++ /dev/null
Binary files differ
diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg
deleted file mode 100644
index ef6ae417..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg
+++ /dev/null
Binary files differ
diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg
deleted file mode 100644
index eee1a2da..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg
+++ /dev/null
Binary files differ
diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/style.scss b/plugins/jetpack/extensions/blocks/map/map-theme-picker/style.scss
deleted file mode 100644
index eb444c1c..00000000
--- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/style.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-@import '../../../shared/styles/gutenberg-colors.scss';
-
-.component__map-theme-picker__button {
- .edit-post-settings-sidebar__panel-block & {
- border: 1px solid $light-gray-500;
- border-radius: 100%;
- width: 56px;
- height: 56px;
- margin: 2px;
- text-indent: -9999px;
- background-color: $light-gray-500;
- background-position: center center;
- background-repeat: no-repeat;
- background-size: contain;
- transform: scale( 1 );
- transition: transform 0.2s ease;
- &:hover {
- transform: scale( 1.1 );
- }
- &.is-selected {
- border-color: $black;
- }
- &.is-theme-default {
- background-image: url( './map-theme_default.jpg' );
- }
- &.is-theme-black_and_white {
- background-image: url( './map-theme_black_and_white.jpg' );
- }
- &.is-theme-satellite {
- background-image: url( './map-theme_satellite.jpg' );
- }
- &.is-theme-terrain {
- background-image: url( './map-theme_terrain.jpg' );
- }
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/map/map.php b/plugins/jetpack/extensions/blocks/map/map.php
index 8b8532c0..d0c82a0d 100644
--- a/plugins/jetpack/extensions/blocks/map/map.php
+++ b/plugins/jetpack/extensions/blocks/map/map.php
@@ -25,7 +25,99 @@ jetpack_register_block(
function jetpack_map_block_load_assets( $attr, $content ) {
$api_key = Jetpack_Options::get_option( 'mapbox_api_key' );
+ if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
+ static $map_block_counter = array();
+
+ $id = get_the_ID();
+ if ( ! isset( $map_block_counter[ $id ] ) ) {
+ $map_block_counter[ $id ] = 0;
+ }
+ $map_block_counter[ $id ]++;
+
+ $iframe_url = add_query_arg(
+ array(
+ 'map-block-counter' => absint( $map_block_counter[ $id ] ),
+ 'map-block-post-id' => $id,
+ ),
+ get_permalink()
+ );
+
+ $placeholder = preg_replace( '/(?<=<div\s)/', 'placeholder ', $content );
+
+ return sprintf(
+ '<amp-iframe src="%s" width="%d" height="%d" layout="responsive" allowfullscreen sandbox="allow-scripts">%s</amp-iframe>',
+ esc_url( $iframe_url ),
+ 4,
+ 3,
+ $placeholder
+ );
+ }
+
Jetpack_Gutenberg::load_assets_as_required( 'map' );
return preg_replace( '/<div /', '<div data-api-key="' . esc_attr( $api_key ) . '" ', $content, 1 );
}
+
+/**
+ * Render a page containing only a single Map block.
+ */
+function jetpack_map_block_render_single_block_page() {
+ // phpcs:ignore WordPress.Security.NonceVerification
+ $map_block_counter = isset( $_GET, $_GET['map-block-counter'] ) ? absint( $_GET['map-block-counter'] ) : null;
+ // phpcs:ignore WordPress.Security.NonceVerification
+ $map_block_post_id = isset( $_GET, $_GET['map-block-post-id'] ) ? absint( $_GET['map-block-post-id'] ) : null;
+
+ if ( ! $map_block_counter || ! $map_block_post_id ) {
+ return;
+ }
+
+ /* Create an array of all root-level DIVs that are Map Blocks */
+ $post = get_post( $map_block_post_id );
+
+ if ( ! class_exists( 'DOMDocument' ) ) {
+ return;
+ }
+
+ $post_html = new DOMDocument();
+ /** This filter is already documented in core/wp-includes/post-template.php */
+ $content = apply_filters( 'the_content', $post->post_content );
+
+ /* Suppress warnings */
+ libxml_use_internal_errors( true );
+ @$post_html->loadHTML( $content ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
+ libxml_use_internal_errors( false );
+
+ $xpath = new DOMXPath( $post_html );
+ $container = $xpath->query( '//div[ contains( @class, "wp-block-jetpack-map" ) ]' )->item( $map_block_counter - 1 );
+
+ /* Check that we have a block matching the counter position */
+ if ( ! $container ) {
+ return;
+ }
+
+ /* Compile scripts and styles */
+ ob_start();
+
+ add_filter( 'jetpack_is_amp_request', '__return_false' );
+
+ Jetpack_Gutenberg::load_assets_as_required( 'map' );
+ wp_scripts()->do_items();
+ wp_styles()->do_items();
+
+ add_filter( 'jetpack_is_amp_request', '__return_true' );
+
+ $head_content = ob_get_clean();
+
+ /* Put together a new complete document containing only the requested block markup and the scripts/styles needed to render it */
+ $block_markup = $post_html->saveHTML( $container );
+ $api_key = Jetpack_Options::get_option( 'mapbox_api_key' );
+ $page_html = sprintf(
+ '<!DOCTYPE html><head><style>html, body { margin: 0; padding: 0; }</style>%s</head><body>%s</body>',
+ $head_content,
+ preg_replace( '/(?<=<div\s)/', 'data-api-key="' . esc_attr( $api_key ) . '" ', $block_markup, 1 )
+ );
+ echo $page_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ exit;
+}
+
+add_action( 'wp', 'jetpack_map_block_render_single_block_page' );
diff --git a/plugins/jetpack/extensions/blocks/map/mapbox-map-formatter/index.js b/plugins/jetpack/extensions/blocks/map/mapbox-map-formatter/index.js
deleted file mode 100644
index 6ec21ad8..00000000
--- a/plugins/jetpack/extensions/blocks/map/mapbox-map-formatter/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export function mapboxMapFormatter( mapStyle, mapDetails ) {
- const style_urls = {
- default: {
- details: 'mapbox://styles/automattic/cjolkhmez0qdd2ro82dwog1in',
- no_details: 'mapbox://styles/automattic/cjolkci3905d82soef4zlmkdo',
- },
- black_and_white: {
- details: 'mapbox://styles/automattic/cjolkixvv0ty42spgt2k4j434',
- no_details: 'mapbox://styles/automattic/cjolkgc540tvj2spgzzoq37k4',
- },
- satellite: {
- details: 'mapbox://styles/mapbox/satellite-streets-v10',
- no_details: 'mapbox://styles/mapbox/satellite-v9',
- },
- terrain: {
- details: 'mapbox://styles/automattic/cjolkf8p405fh2soet2rdt96b',
- no_details: 'mapbox://styles/automattic/cjolke6fz12ys2rpbpvgl12ha',
- },
- };
- const style_url = style_urls[ mapStyle ][ mapDetails ? 'details' : 'no_details' ];
- return style_url;
-}
diff --git a/plugins/jetpack/extensions/blocks/map/save.js b/plugins/jetpack/extensions/blocks/map/save.js
deleted file mode 100644
index ffa82641..00000000
--- a/plugins/jetpack/extensions/blocks/map/save.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * External dependencies
- */
-
-import { Component } from '@wordpress/element';
-
-class MapSave extends Component {
- render() {
- const { attributes } = this.props;
- const { align, mapStyle, mapDetails, points, zoom, mapCenter, markerColor } = attributes;
- const pointsList = points.map( ( point, index ) => {
- const { longitude, latitude } = point.coordinates;
- const url = 'https://www.google.com/maps/search/?api=1&query=' + latitude + ',' + longitude;
- return (
- <li key={ index }>
- <a href={ url }>{ point.title }</a>
- </li>
- );
- } );
- const alignClassName = align ? `align${ align }` : null;
- // All camelCase attribute names converted to snake_case data attributes
- return (
- <div
- className={ alignClassName }
- data-map-style={ mapStyle }
- data-map-details={ mapDetails }
- data-points={ JSON.stringify( points ) }
- data-zoom={ zoom }
- data-map-center={ JSON.stringify( mapCenter ) }
- data-marker-color={ markerColor }
- >
- { points.length > 0 && <ul>{ pointsList }</ul> }
- </div>
- );
- }
-}
-
-export default MapSave;
diff --git a/plugins/jetpack/extensions/blocks/map/settings.js b/plugins/jetpack/extensions/blocks/map/settings.js
deleted file mode 100644
index e8bc87d2..00000000
--- a/plugins/jetpack/extensions/blocks/map/settings.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Disable forbidden <svg> etc. so that frontend component does not depend on @wordpress/component
-/* eslint-disable react/forbid-elements */
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-
-export const settings = {
- name: 'map',
- prefix: 'jetpack',
- title: __( 'Map', 'jetpack' ),
- icon: (
- /* Do not use SVG components from @wordpress/component to avoid frontend bloat */
- <svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- role="img"
- aria-hidden="true"
- focusable="false"
- >
- <path fill="none" d="M0 0h24v24H0V0z" />
- <path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z" />
- </svg>
- ),
- category: 'jetpack',
- keywords: [
- _x( 'map', 'block search term', 'jetpack' ),
- _x( 'location', 'block search term', 'jetpack' ),
- _x( 'navigation', 'block search term', 'jetpack' ),
- ],
- description: __( 'Add an interactive map showing one or more locations.', 'jetpack' ),
- attributes: {
- align: {
- type: 'string',
- },
- points: {
- type: 'array',
- default: [],
- },
- mapStyle: {
- type: 'string',
- default: 'default',
- },
- mapDetails: {
- type: 'boolean',
- default: true,
- },
- zoom: {
- type: 'integer',
- default: 13,
- },
- mapCenter: {
- type: 'object',
- default: {
- longitude: -122.41941550000001,
- latitude: 37.7749295,
- },
- },
- markerColor: {
- type: 'string',
- default: 'red',
- },
- },
- supports: {
- html: false,
- },
- mapStyleOptions: [
- {
- value: 'default',
- label: __( 'Basic', 'jetpack' ),
- },
- {
- value: 'black_and_white',
- label: __( 'Black and white', 'jetpack' ),
- },
- {
- value: 'satellite',
- label: __( 'Satellite', 'jetpack' ),
- },
- {
- value: 'terrain',
- label: __( 'Terrain', 'jetpack' ),
- },
- ],
- validAlignments: [ 'center', 'wide', 'full' ],
- markerIcon: (
- /* Do not use SVG components from @wordpress/component to avoid frontend bloat */
- <svg width="14" height="20" viewBox="0 0 14 20" xmlns="http://www.w3.org/2000/svg">
- <g id="Page-1" fill="none" fillRule="evenodd">
- <g id="outline-add_location-24px" transform="translate(-5 -2)">
- <polygon id="Shape" points="0 0 24 0 24 24 0 24" />
- <path
- d="M12,2 C8.14,2 5,5.14 5,9 C5,14.25 12,22 12,22 C12,22 19,14.25 19,9 C19,5.14 15.86,2 12,2 Z M7,9 C7,6.24 9.24,4 12,4 C14.76,4 17,6.24 17,9 C17,11.88 14.12,16.19 12,18.88 C9.92,16.21 7,11.85 7,9 Z M13,6 L11,6 L11,8 L9,8 L9,10 L11,10 L11,12 L13,12 L13,10 L15,10 L15,8 L13,8 L13,6 Z"
- id="Shape"
- fill="#000"
- fillRule="nonzero"
- />
- </g>
- </g>
- </svg>
- ),
-};
diff --git a/plugins/jetpack/extensions/blocks/map/style.scss b/plugins/jetpack/extensions/blocks/map/style.scss
deleted file mode 100644
index a3a25f29..00000000
--- a/plugins/jetpack/extensions/blocks/map/style.scss
+++ /dev/null
@@ -1,22 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.wp-block-jetpack-map {
- .wp-block-jetpack-map__gm-container {
- width: 100%;
- overflow: hidden;
- background: $light-gray-500;
- min-height: 400px;
- text-align: left;
- }
- .mapboxgl-popup {
- h3 {
- font-size: 1.3125em;
- font-weight: 400;
- margin-bottom: 0.5rem;
- }
- p {
- margin-bottom: 0;
- }
- max-width: 300px;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/map/view.js b/plugins/jetpack/extensions/blocks/map/view.js
deleted file mode 100644
index fc825d67..00000000
--- a/plugins/jetpack/extensions/blocks/map/view.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Internal dependencies
- */
-import './style.scss';
-import component from './component.js';
-import { settings } from './settings.js';
-import FrontendManagement from '../../shared/frontend-management.js';
-
-typeof window !== 'undefined' &&
- window.addEventListener( 'load', function() {
- const frontendManagement = new FrontendManagement();
- // Add apiKey to attibutes so FrontendManagement knows about it.
- // It is dynamically being added on the php side.
- // So that it can be updated accross all the map blocks at the same time.
- const apiKey = {
- type: 'string',
- default: '',
- };
- frontendManagement.blockIterator( document, [
- {
- component: component,
- options: {
- settings: {
- ...settings,
- attributes: {
- ...settings.attributes,
- apiKey,
- },
- },
- },
- },
- ] );
- } );
diff --git a/plugins/jetpack/extensions/blocks/markdown/edit.js b/plugins/jetpack/extensions/blocks/markdown/edit.js
deleted file mode 100644
index 13dff7f4..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/edit.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { BlockControls, PlainText } from '@wordpress/editor';
-import { Component } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import MarkdownRenderer from './renderer';
-
-/**
- * Module variables
- */
-const PANEL_EDITOR = 'editor';
-const PANEL_PREVIEW = 'preview';
-
-class MarkdownEdit extends Component {
- input = null;
-
- state = {
- activePanel: PANEL_EDITOR,
- };
-
- bindInput = ref => void ( this.input = ref );
-
- componentDidUpdate( prevProps ) {
- if (
- prevProps.isSelected &&
- ! this.props.isSelected &&
- this.state.activePanel === PANEL_PREVIEW
- ) {
- this.toggleMode( PANEL_EDITOR )();
- }
- if (
- ! prevProps.isSelected &&
- this.props.isSelected &&
- this.state.activePanel === PANEL_EDITOR &&
- this.input
- ) {
- this.input.focus();
- }
- }
-
- isEmpty() {
- const source = this.props.attributes.source;
- return ! source || source.trim() === '';
- }
-
- updateSource = source => this.props.setAttributes( { source } );
-
- handleKeyDown = e => {
- const { attributes, removeBlock } = this.props;
- const { source } = attributes;
-
- // Remove the block if source is empty and we're pressing the Backspace key
- if ( e.keyCode === 8 && source === '' ) {
- removeBlock();
- e.preventDefault();
- }
- };
-
- toggleMode = mode => () => this.setState( { activePanel: mode } );
-
- renderToolbarButton( mode, label ) {
- const { activePanel } = this.state;
-
- return (
- <button
- className={ `components-tab-button ${ activePanel === mode ? 'is-active' : '' }` }
- onClick={ this.toggleMode( mode ) }
- >
- <span>{ label }</span>
- </button>
- );
- }
-
- render() {
- const { attributes, className, isSelected } = this.props;
- const { source } = attributes;
- const { activePanel } = this.state;
-
- if ( ! isSelected && this.isEmpty() ) {
- return (
- <p className={ `${ className }__placeholder` }>
- { __( 'Write your _Markdown_ **here**…', 'jetpack' ) }
- </p>
- );
- }
-
- return (
- <div className={ className }>
- <BlockControls>
- <div className="components-toolbar">
- { this.renderToolbarButton( PANEL_EDITOR, __( 'Markdown', 'jetpack' ) ) }
- { this.renderToolbarButton( PANEL_PREVIEW, __( 'Preview', 'jetpack' ) ) }
- </div>
- </BlockControls>
-
- { activePanel === PANEL_PREVIEW || ! isSelected ? (
- <MarkdownRenderer className={ `${ className }__preview` } source={ source } />
- ) : (
- <PlainText
- className={ `${ className }__editor` }
- onChange={ this.updateSource }
- onKeyDown={ this.handleKeyDown }
- aria-label={ __( 'Markdown', 'jetpack' ) }
- innerRef={ this.bindInput }
- value={ source }
- />
- ) }
- </div>
- );
- }
-}
-
-export default compose( [
- withSelect( select => ( {
- currentBlockId: select( 'core/editor' ).getSelectedBlockClientId(),
- } ) ),
- withDispatch( ( dispatch, { currentBlockId } ) => ( {
- removeBlock: () => dispatch( 'core/editor' ).removeBlocks( currentBlockId ),
- } ) ),
-] )( MarkdownEdit );
diff --git a/plugins/jetpack/extensions/blocks/markdown/editor.js b/plugins/jetpack/extensions/blocks/markdown/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/markdown/editor.scss b/plugins/jetpack/extensions/blocks/markdown/editor.scss
deleted file mode 100644
index 0cb11581..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/editor.scss
+++ /dev/null
@@ -1,144 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-@import '../../shared/styles/gutenberg-variables.scss';
-
-.wp-block-jetpack-markdown__placeholder {
- opacity: 0.62; // See https://github.com/WordPress/gutenberg/blob/db7decd27f7c476684bc8edde381ffab4c916cb2/packages/block-editor/src/components/rich-text/style.scss#L72
- pointer-events: none;
-}
-
-// @TODO: Remove all these specific styles when related Gutenberg core styles become more generic
-.editor-block-list__block {
- .wp-block-jetpack-markdown__preview {
- min-height: 1.8em;
- line-height: 1.8;
-
- & > * {
- margin-top: 32px;
- margin-bottom: 32px;
- }
-
- // See https://github.com/WordPress/gutenberg/blob/db7decd27f7c476684bc8edde381ffab4c916cb2/packages/block-library/src/heading/editor.scss#L12-L35
- h1,
- h2,
- h3 {
- line-height: 1.4;
- }
-
- h1 {
- font-size: 2.44em;
- }
-
- h2 {
- font-size: 1.95em;
- }
-
- h3 {
- font-size: 1.56em;
- }
-
- h4 {
- font-size: 1.25em;
- line-height: 1.5;
- }
-
- h5 {
- font-size: 1em;
- }
-
- h6 {
- font-size: 0.8em;
- }
-
- hr {
- border: none;
- border-bottom: 2px solid $dark-gray-100;
- margin: 2em auto;
- max-width: 100px;
- }
-
- p {
- line-height: 1.8;
- }
-
- blockquote {
- border-left: 4px solid $black;
- margin-left: 0;
- margin-right: 0;
- padding-left: 1em;
-
- p {
- line-height: 1.5;
- margin: 1em 0;
- }
- }
-
- ul,
- ol {
- margin-left: 1.3em;
- padding-left: 1.3em;
- }
-
- li {
- p {
- margin: 0;
- }
- }
-
- // See https://github.com/WordPress/gutenberg/blob/db7decd27f7c476684bc8edde381ffab4c916cb2/packages/block-editor/src/components/rich-text/style.scss#L28-L39
- code,
- pre {
- color: $dark-gray-800;
- font-family: $editor-html-font;
- }
-
- code {
- background: $light-gray-200;
- border-radius: 2px;
- font-size: inherit; // This is necessary to override upstream CSS.
- padding: 2px;
- }
-
- pre {
- border-radius: 4px;
- border: 1px solid $light-gray-500;
- font-size: $text-editor-font-size;
- padding: 0.8em 1em;
-
- code {
- background: transparent;
- padding: 0;
- }
- }
-
- table {
- overflow-x: auto;
- border-collapse: collapse;
- width: 100%;
- }
-
- thead,
- tbody,
- tfoot {
- width: 100%;
- min-width: 240px;
- }
-
- td,
- th {
- padding: 0.5em;
- border: 1px solid currentColor;
- }
- }
-}
-
-.wp-block-jetpack-markdown {
- .wp-block-jetpack-markdown__editor {
- font-family: $editor-html-font;
- font-size: $text-editor-font-size;
-
- &:focus {
- border-color: transparent;
- box-shadow: 0 0 0 transparent;
- }
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/markdown/index.js b/plugins/jetpack/extensions/blocks/markdown/index.js
deleted file mode 100644
index ff5d3dc8..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/index.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { ExternalLink, Path, Rect, SVG } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import './editor.scss';
-import edit from './edit';
-import save from './save';
-
-export const name = 'markdown';
-
-export const settings = {
- title: __( 'Markdown', 'jetpack' ),
-
- description: (
- <Fragment>
- <p>
- { __(
- 'Use regular characters and punctuation to style text, links, and lists.',
- 'jetpack'
- ) }
- </p>
- <ExternalLink href="https://en.support.wordpress.com/markdown-quick-reference/">
- { __( 'Support reference', 'jetpack' ) }
- </ExternalLink>
- </Fragment>
- ),
-
- icon: (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 208 128">
- <Rect
- width="198"
- height="118"
- x="5"
- y="5"
- ry="10"
- stroke="currentColor"
- strokeWidth="10"
- fill="none"
- />
- <Path d="M30 98v-68h20l20 25 20-25h20v68h-20v-39l-20 25-20-25v39zM155 98l-30-33h20v-35h20v35h20z" />
- </SVG>
- ),
-
- category: 'jetpack',
-
- keywords: [
- _x( 'formatting', 'block search term', 'jetpack' ),
- _x( 'syntax', 'block search term', 'jetpack' ),
- _x( 'markup', 'block search term', 'jetpack' ),
- ],
-
- attributes: {
- //The Markdown source is saved in the block content comments delimiter
- source: { type: 'string' },
- },
-
- supports: {
- html: false,
- },
-
- edit,
-
- save,
-};
diff --git a/plugins/jetpack/extensions/blocks/markdown/markdown.php b/plugins/jetpack/extensions/blocks/markdown/markdown.php
index 7490b9d2..27978dcb 100644
--- a/plugins/jetpack/extensions/blocks/markdown/markdown.php
+++ b/plugins/jetpack/extensions/blocks/markdown/markdown.php
@@ -7,14 +7,4 @@
* @package Jetpack
*/
-/**
- * The block depends on the Markdown module to be active for now.
- * Related discussion: https://github.com/Automattic/jetpack/issues/10294
- */
-if (
- ( defined( 'IS_WPCOM' ) && IS_WPCOM )
- || ( method_exists( 'Jetpack', 'is_module_active' ) && Jetpack::is_module_active( 'markdown' ) )
-) {
- jetpack_register_block( 'jetpack/markdown' );
-}
-
+jetpack_register_block( 'jetpack/markdown' );
diff --git a/plugins/jetpack/extensions/blocks/markdown/renderer.js b/plugins/jetpack/extensions/blocks/markdown/renderer.js
deleted file mode 100644
index ae87568a..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/renderer.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import MarkdownIt from 'markdown-it';
-import { RawHTML } from '@wordpress/element';
-
-/**
- * Module variables
- */
-const markdownConverter = new MarkdownIt();
-const handleLinkClick = event => {
- if ( event.target.nodeName === 'A' ) {
- const hasConfirmed = window.confirm(
- __( 'Are you sure you wish to leave this page?', 'jetpack' )
- );
-
- if ( ! hasConfirmed ) {
- event.preventDefault();
- }
- }
-};
-
-export default ( { className, source = '' } ) => (
- <RawHTML className={ className } onClick={ handleLinkClick }>
- { source.length ? markdownConverter.render( source ) : '' }
- </RawHTML>
-);
diff --git a/plugins/jetpack/extensions/blocks/markdown/save.js b/plugins/jetpack/extensions/blocks/markdown/save.js
deleted file mode 100644
index 06d08138..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/save.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Internal dependencies
- */
-import MarkdownRenderer from './renderer';
-
-export default ( { attributes, className } ) => (
- <MarkdownRenderer className={ className } source={ attributes.source } />
-);
diff --git a/plugins/jetpack/extensions/blocks/markdown/test/__snapshots__/markdown-renderer.js.snap b/plugins/jetpack/extensions/blocks/markdown/test/__snapshots__/markdown-renderer.js.snap
deleted file mode 100644
index ebc9bfc2..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/test/__snapshots__/markdown-renderer.js.snap
+++ /dev/null
@@ -1,63 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`MarkdownRenderer renders markdown to HTML as expected 1`] = `
-<RawHTML
- className="markdown"
- onClick={[Function]}
->
- &lt;h1&gt;Heading&lt;/h1&gt;
-&lt;h2&gt;2nd Heading&lt;/h2&gt;
-&lt;ul&gt;
-&lt;li&gt;List 1&lt;/li&gt;
-&lt;li&gt;List 1&lt;/li&gt;
-&lt;/ul&gt;
-&lt;ul&gt;
-&lt;li&gt;List 2&lt;/li&gt;
-&lt;li&gt;List 2&lt;/li&gt;
-&lt;/ul&gt;
-&lt;ul&gt;
-&lt;li&gt;List 3&lt;/li&gt;
-&lt;li&gt;List 3&lt;/li&gt;
-&lt;/ul&gt;
-&lt;ol&gt;
-&lt;li&gt;Red&lt;/li&gt;
-&lt;li&gt;Green&lt;/li&gt;
-&lt;li&gt;Blue&lt;/li&gt;
-&lt;/ol&gt;
-&lt;ul&gt;
-&lt;li&gt;
-&lt;p&gt;A list item.&lt;/p&gt;
-&lt;p&gt;With multiple paragraphs.&lt;/p&gt;
-&lt;/li&gt;
-&lt;li&gt;
-&lt;p&gt;Another item in the list.&lt;/p&gt;
-&lt;/li&gt;
-&lt;/ul&gt;
-&lt;p&gt;&lt;em&gt;em&lt;/em&gt;
-&lt;em&gt;em&lt;/em&gt;
-&lt;strong&gt;strong&lt;/strong&gt;
-&lt;strong&gt;strong&lt;/strong&gt;
-&lt;em&gt;&lt;strong&gt;em strong&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
-&lt;p&gt;*Literal asterisks*&lt;/p&gt;
-&lt;p&gt;Link to &lt;a href="https://wordpress.com"&gt;WordPress&lt;/a&gt; and &lt;a href="https://jetpack.com/"&gt;https://jetpack.com/&lt;/a&gt;&lt;/p&gt;
-&lt;p&gt;email me: &lt;a href="mailto:address@example.com"&gt;address@example.com&lt;/a&gt;&lt;/p&gt;
-&lt;p&gt;Inline &lt;code&gt;code&lt;/code&gt; here.&lt;/p&gt;
-&lt;pre&gt;&lt;code&gt;Block of code with backticks.
-&lt;/code&gt;&lt;/pre&gt;
-&lt;pre&gt;&lt;code&gt;Block of code prefixed by four spaces
-&lt;/code&gt;&lt;/pre&gt;
-&lt;blockquote&gt;
-&lt;p&gt;a blockquote.&lt;/p&gt;
-&lt;p&gt;2nd paragraph in the blockquote.&lt;/p&gt;
-&lt;h2&gt;H2 in a blockquote&lt;/h2&gt;
-&lt;/blockquote&gt;
-&lt;p&gt;A bunch of horizontal rules:&lt;/p&gt;
-&lt;hr&gt;
-&lt;hr&gt;
-&lt;hr&gt;
-&lt;hr&gt;
-&lt;hr&gt;
-&lt;p&gt;👋&lt;/p&gt;
-
-</RawHTML>
-`;
diff --git a/plugins/jetpack/extensions/blocks/markdown/test/fixtures/source.js b/plugins/jetpack/extensions/blocks/markdown/test/fixtures/source.js
deleted file mode 100644
index 0c24e6ba..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/test/fixtures/source.js
+++ /dev/null
@@ -1,63 +0,0 @@
-export const source = `
-# Heading
-
-## 2nd Heading
-
-- List 1
-- List 1
-
-* List 2
-* List 2
-
-+ List 3
-+ List 3
-
-1. Red
-2. Green
-3. Blue
-
-* A list item.
-
- With multiple paragraphs.
-
-* Another item in the list.
-
-_em_
-*em*
-**strong**
-__strong__
-***em strong***
-
-\\\*Literal asterisks\\\*
-
-Link to [WordPress](https://wordpress.com) and <https://jetpack.com/>
-
-email me: <address@example.com>
-
-Inline \`code\` here.
-
-\`\`\`
-Block of code with backticks.
-\`\`\`
-
- Block of code prefixed by four spaces
-
-> a blockquote.
->
-> 2nd paragraph in the blockquote.
->
-> ## H2 in a blockquote
-
-A bunch of horizontal rules:
-
-* * *
-
-***
-
-*****
-
-- - -
-
----------------------------------------
-
-👋`;
diff --git a/plugins/jetpack/extensions/blocks/markdown/test/markdown-renderer.js b/plugins/jetpack/extensions/blocks/markdown/test/markdown-renderer.js
deleted file mode 100644
index f8890eb3..00000000
--- a/plugins/jetpack/extensions/blocks/markdown/test/markdown-renderer.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * External dependencies
- */
-import { shallow } from 'enzyme';
-import React from 'react';
-
-/**
- * Internal dependencies
- */
-import { source } from './fixtures/source'
-import MarkdownRenderer from '../renderer';
-
-describe( 'MarkdownRenderer', () => {
- test( 'renders markdown to HTML as expected', () => {
- expect( shallow( <MarkdownRenderer className='markdown' source={ source } /> ) ).toMatchSnapshot();
- } );
-} );
diff --git a/plugins/jetpack/extensions/blocks/membership-button/edit.jsx b/plugins/jetpack/extensions/blocks/membership-button/edit.jsx
deleted file mode 100644
index 4843f802..00000000
--- a/plugins/jetpack/extensions/blocks/membership-button/edit.jsx
+++ /dev/null
@@ -1,392 +0,0 @@
-/**
- * External dependencies
- */
-
-import classnames from 'classnames';
-import SubmitButton from '../../shared/submit-button';
-import apiFetch from '@wordpress/api-fetch';
-import { __ } from '@wordpress/i18n';
-import { trimEnd } from 'lodash';
-import formatCurrency, { getCurrencyDefaults } from '@automattic/format-currency';
-
-import {
- Button,
- ExternalLink,
- PanelBody,
- Placeholder,
- Spinner,
- TextControl,
- withNotices,
- SelectControl,
-} from '@wordpress/components';
-import { InspectorControls, BlockIcon } from '@wordpress/editor';
-import { Fragment, Component } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import { icon, SUPPORTED_CURRENCY_LIST } from '.';
-
-const API_STATE_LOADING = 0;
-const API_STATE_CONNECTED = 1;
-const API_STATE_NOTCONNECTED = 2;
-
-const PRODUCT_NOT_ADDING = 0;
-const PRODUCT_FORM = 1;
-const PRODUCT_FORM_SUBMITTED = 2;
-
-class MembershipsButtonEdit extends Component {
- constructor() {
- super( ...arguments );
- this.state = {
- connected: API_STATE_LOADING,
- connectURL: null,
- addingMembershipAmount: PRODUCT_NOT_ADDING,
- products: [],
- editedProductCurrency: 'USD',
- editedProductPrice: 5,
- editedProductPriceValid: true,
- editedProductTitle: '',
- editedProductTitleValid: true,
- editedProductRenewInterval: '1 month',
- };
- this.timeout = null;
- }
-
- componentDidMount = () => {
- this.apiCall();
- };
-
- onError = message => {
- const { noticeOperations } = this.props;
- noticeOperations.removeAllNotices();
- noticeOperations.createErrorNotice( message );
- };
-
- apiCall = () => {
- const path = '/wpcom/v2/memberships/status';
- const method = 'GET';
- const fetch = { path, method };
- apiFetch( fetch ).then(
- result => {
- const connectURL = result.connect_url;
- const products = result.products;
- const connected = result.connected_account_id
- ? API_STATE_CONNECTED
- : API_STATE_NOTCONNECTED;
- this.setState( { connected, connectURL, products } );
- },
- result => {
- const connectURL = null;
- const connected = API_STATE_NOTCONNECTED;
- this.setState( { connected, connectURL } );
- this.onError( result.message );
- }
- );
- };
- getCurrencyList = SUPPORTED_CURRENCY_LIST.map( value => {
- const { symbol } = getCurrencyDefaults( value );
- // if symbol is equal to the code (e.g., 'CHF' === 'CHF'), don't duplicate it.
- // trim the dot at the end, e.g., 'kr.' becomes 'kr'
- const label = symbol === value ? value : `${ value } ${ trimEnd( symbol, '.' ) }`;
- return { value, label };
- } );
-
- handleCurrencyChange = editedProductCurrency => this.setState( { editedProductCurrency } );
- handleRenewIntervalChange = editedProductRenewInterval =>
- this.setState( { editedProductRenewInterval } );
-
- handlePriceChange = price => {
- price = parseFloat( price );
- this.setState( {
- editedProductPrice: price,
- editedProductPriceValid: ! isNaN( price ) && price >= 5,
- } );
- };
-
- handleTitleChange = editedProductTitle =>
- this.setState( {
- editedProductTitle,
- editedProductTitleValid: editedProductTitle.length > 0,
- } );
- // eslint-disable-next-line
- saveProduct = () => {
- if ( ! this.state.editedProductTitle || this.state.editedProductTitle.length === 0 ) {
- this.setState( { editedProductTitleValid: false } );
- return;
- }
- if (
- ! this.state.editedProductPrice ||
- isNaN( this.state.editedProductPrice ) ||
- this.state.editedProductPrice < 5
- ) {
- this.setState( { editedProductPriceValid: false } );
- return;
- }
- this.setState( { addingMembershipAmount: PRODUCT_FORM_SUBMITTED } );
- const path = '/wpcom/v2/memberships/product';
- const method = 'POST';
- const data = {
- currency: this.state.editedProductCurrency,
- price: this.state.editedProductPrice,
- title: this.state.editedProductTitle,
- interval: this.state.editedProductRenewInterval,
- };
- const fetch = { path, method, data };
- apiFetch( fetch ).then(
- result => {
- this.setState( {
- addingMembershipAmount: PRODUCT_NOT_ADDING,
- products: this.state.products.concat( [
- {
- id: result.id,
- title: result.title,
- interval: result.interval,
- price: result.price,
- },
- ] ),
- } );
- },
- result => {
- this.setState( { addingMembershipAmount: PRODUCT_FORM } );
- this.onError( result.message );
- }
- );
- };
-
- renderAddMembershipAmount = () => {
- if ( this.state.addingMembershipAmount === PRODUCT_NOT_ADDING ) {
- return (
- <Button
- isDefault
- isLarge
- onClick={ () => this.setState( { addingMembershipAmount: PRODUCT_FORM } ) }
- >
- { __( 'Add Memberships Amounts', 'jetpack' ) }
- </Button>
- );
- }
- if ( this.state.addingMembershipAmount === PRODUCT_FORM_SUBMITTED ) {
- return;
- }
-
- return (
- <div>
- <div className="membership-button__price-container">
- <SelectControl
- className="membership-button__field membership-button__field-currency"
- label={ __( 'Currency', 'jetpack' ) }
- onChange={ this.handleCurrencyChange }
- options={ this.getCurrencyList }
- value={ this.state.editedProductCurrency }
- />
- <TextControl
- label={ __( 'Price', 'jetpack' ) }
- className={ classnames( {
- 'membership-membership-button__field': true,
- 'membership-button__field-price': true,
- 'membership-button__field-error': ! this.state.editedProductPriceValid,
- } ) }
- onChange={ this.handlePriceChange }
- placeholder={ formatCurrency( 0, this.state.editedProductCurrency ) }
- required
- step="1"
- type="number"
- value={ this.state.editedProductPrice || '' }
- />
- </div>
- <TextControl
- className={ classnames( {
- 'membership-button__field': true,
- 'membership-button__field-error': ! this.state.editedProductTitleValid,
- } ) }
- label={ __( 'Describe your subscription in a few words', 'jetpack' ) }
- onChange={ this.handleTitleChange }
- placeholder={ __( 'Subscription description', 'jetpack' ) }
- value={ this.state.editedProductTitle }
- />
- <SelectControl
- label={ __( 'Renew interval', 'jetpack' ) }
- onChange={ this.handleRenewIntervalChange }
- options={ [
- {
- label: __( 'Monthly', 'jetpack' ),
- value: '1 month',
- },
- {
- label: __( 'Yearly', 'jetpack' ),
- value: '1 year',
- },
- ] }
- value={ this.state.editedProductRenewInterval }
- />
- <div>
- <Button
- isDefault
- isLarge
- className="membership-button__field-button"
- onClick={ this.saveProduct }
- >
- { __( 'Add Amount', 'jetpack' ) }
- </Button>
- <Button
- isLarge
- className="membership-button__field-button"
- onClick={ () => this.setState( { addingMembershipAmount: PRODUCT_NOT_ADDING } ) }
- >
- { __( 'Cancel', 'jetpack' ) }
- </Button>
- </div>
- </div>
- );
- };
- getFormattedPriceByProductId = id => {
- const product = this.state.products
- .filter( prod => parseInt( prod.id ) === parseInt( id ) )
- .pop();
- return formatCurrency( parseFloat( product.price ), product.currency );
- };
-
- setMembershipAmount = id =>
- this.props.setAttributes( {
- planId: id,
- submitButtonText: this.getFormattedPriceByProductId( id ) + __( ' Contribution', 'jetpack' ),
- } );
-
- renderMembershipAmounts = () => (
- <div>
- { this.state.products.map( product => (
- <Button
- className="membership-button__field-button"
- isLarge
- key={ product.id }
- onClick={ () => this.setMembershipAmount( product.id ) }
- >
- { formatCurrency( parseFloat( product.price ), product.currency ) }
- </Button>
- ) ) }
- </div>
- );
-
- renderDisclaimer = () => {
- return (
- <div className="membership-button__disclaimer">
- <ExternalLink href="https://en.support.wordpress.com/memberships/#related-fees">
- { __( 'Read more about memberships and related fees.', 'jetpack' ) }
- </ExternalLink>
- </div>
- );
- };
-
- render = () => {
- const { className, notices } = this.props;
- const { connected, connectURL, products } = this.state;
-
- const inspectorControls = (
- <InspectorControls>
- <PanelBody title={ __( 'Product', 'jetpack' ) }>
- <SelectControl
- label="Membership plan"
- value={ this.props.attributes.planId }
- onChange={ this.setMembershipAmount }
- options={ this.state.products.map( product => ( {
- label: formatCurrency( parseFloat( product.price ), product.currency ),
- value: product.id,
- key: product.id,
- } ) ) }
- />
- </PanelBody>
- </InspectorControls>
- );
- const blockClasses = classnames( className, [
- 'components-button',
- 'is-primary',
- 'is-button',
- ] );
- const blockContent = (
- <SubmitButton
- className={ blockClasses }
- submitButtonText={ this.props.attributes.submitButtonText }
- attributes={ this.props.attributes }
- setAttributes={ this.props.setAttributes }
- />
- );
- return (
- <Fragment>
- { this.props.noticeUI }
- { ( connected === API_STATE_LOADING ||
- this.state.addingMembershipAmount === PRODUCT_FORM_SUBMITTED ) &&
- ! this.props.attributes.planId && (
- <Placeholder icon={ <BlockIcon icon={ icon } /> } notices={ notices }>
- <Spinner />
- </Placeholder>
- ) }
- { ! this.props.attributes.planId && connected === API_STATE_NOTCONNECTED && (
- <Placeholder
- icon={ <BlockIcon icon={ icon } /> }
- label={ __( 'Memberships', 'jetpack' ) }
- notices={ notices }
- >
- <div className="components-placeholder__instructions wp-block-jetpack-membership-button">
- { __(
- 'In order to start selling Membership plans, you have to connect to Stripe:',
- 'jetpack'
- ) }
- <br />
- <br />
- <Button isDefault isLarge href={ connectURL } target="_blank">
- { __( 'Connect to Stripe or set up an account', 'jetpack' ) }
- </Button>
- <br />
- <br />
- <Button isLink onClick={ this.apiCall }>
- { __( 'Re-check Connection', 'jetpack' ) }
- </Button>
- { this.renderDisclaimer() }
- </div>
- </Placeholder>
- ) }
- { ! this.props.attributes.planId &&
- connected === API_STATE_CONNECTED &&
- products.length === 0 && (
- <Placeholder
- icon={ <BlockIcon icon={ icon } /> }
- label={ __( 'Memberships', 'jetpack' ) }
- notices={ notices }
- >
- <div className="components-placeholder__instructions wp-block-jetpack-membership-button">
- { __( 'Add your first Membership amount:', 'jetpack' ) }
- <br />
- <br />
- { this.renderAddMembershipAmount() }
- { this.renderDisclaimer() }
- </div>
- </Placeholder>
- ) }
- { ! this.props.attributes.planId &&
- this.state.addingMembershipAmount !== PRODUCT_FORM_SUBMITTED &&
- connected === API_STATE_CONNECTED &&
- products.length > 0 && (
- <Placeholder
- icon={ <BlockIcon icon={ icon } /> }
- label={ __( 'Memberships', 'jetpack' ) }
- notices={ notices }
- >
- <div className="components-placeholder__instructions wp-block-jetpack-membership-button">
- { __( 'Select payment amount:', 'jetpack' ) }
- { this.renderMembershipAmounts() }
- { __( 'Or add another membership amount:', 'jetpack' ) }
- <br />
- { this.renderAddMembershipAmount() }
- { this.renderDisclaimer() }
- </div>
- </Placeholder>
- ) }
- { this.state.products && inspectorControls }
- { this.props.attributes.planId && blockContent }
- </Fragment>
- );
- };
-}
-
-export default withNotices( MembershipsButtonEdit );
diff --git a/plugins/jetpack/extensions/blocks/membership-button/editor.js b/plugins/jetpack/extensions/blocks/membership-button/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/membership-button/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/membership-button/editor.scss b/plugins/jetpack/extensions/blocks/membership-button/editor.scss
deleted file mode 100644
index be104f57..00000000
--- a/plugins/jetpack/extensions/blocks/membership-button/editor.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-@import './view.scss';
-
-.wp-block-jetpack-membership-button {
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell,
- Helvetica Neue, sans-serif;
-
- .membership-button__price-container {
- display: flex;
- flex-wrap: wrap;
- }
- .membership-button__field-price {
- margin-left: 10px;
- }
- .wp-block-jetpack-membership-button_notification {
- display: block;
- }
-
- .editor-rich-text__inline-toolbar {
- pointer-events: none;
- .components-toolbar {
- pointer-events: all;
- }
- }
-
- .membership-button__field-button {
- margin: 4px;
- }
-
- .membership-button__field-error .components-text-control__input {
- border: 1px solid;
- border-color: var( --color-error );
- }
-
- .membership-button__disclaimer {
- margin-top: 20px;
- font-style: italic;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/membership-button/index.js b/plugins/jetpack/extensions/blocks/membership-button/index.js
deleted file mode 100644
index 69578a79..00000000
--- a/plugins/jetpack/extensions/blocks/membership-button/index.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, Rect, SVG, G } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import edit from './edit';
-import './editor.scss';
-
-export const name = 'membership-button';
-
-export const icon = (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
- <Rect x="0" fill="none" width="24" height="24" />
- <G>
- <Path d="M20 4H4c-1.105 0-2 .895-2 2v12c0 1.105.895 2 2 2h16c1.105 0 2-.895 2-2V6c0-1.105-.895-2-2-2zm0 2v2H4V6h16zM4 18v-6h16v6H4zm2-4h7v2H6v-2zm9 0h3v2h-3v-2z" />
- </G>
- </SVG>
-);
-
-export const settings = {
- title: __( 'Membership Button', 'jetpack' ),
- icon,
- description: __( 'Button allowing you to sell subscription products.', 'jetpack' ),
- category: 'jetpack',
- keywords: [
- _x( 'sell', 'block search term', 'jetpack' ),
- _x( 'subscription', 'block search term', 'jetpack' ),
- 'stripe',
- ],
- attributes: {
- planId: {
- type: 'integer',
- },
- submitButtonText: {
- type: 'string',
- },
- customBackgroundButtonColor: {
- type: 'string',
- },
- customTextButtonColor: {
- type: 'string',
- },
- },
- edit,
- save: () => null,
-};
-
-// These are Stripe Settlement currencies https://stripe.com/docs/currencies since memberships supports only Stripe ATM.
-export const SUPPORTED_CURRENCY_LIST = [
- 'USD',
- 'AUD',
- 'BRL',
- 'CAD',
- 'CHF',
- 'DKK',
- 'EUR',
- 'GBP',
- 'HKD',
- 'JPY',
- 'MXN',
- 'NOK',
- 'NZD',
- 'SEK',
- 'SGD',
-];
diff --git a/plugins/jetpack/extensions/blocks/membership-button/view.js b/plugins/jetpack/extensions/blocks/membership-button/view.js
deleted file mode 100644
index 6e10a1d3..00000000
--- a/plugins/jetpack/extensions/blocks/membership-button/view.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* global tb_show, tb_remove */
-
-/**
- * Internal dependencies
- */
-import './view.scss';
-const name = 'membership-button';
-const blockClassName = 'wp-block-jetpack-' + name;
-
-/**
- * Since "close" button is inside our checkout iframe, in order to close it, it has to pass a message to higher scope to close the modal.
- *
- * @param {event} eventFromIframe - message event that gets emmited in the checkout iframe.
- * @listens message
- */
-function handleIframeResult( eventFromIframe ) {
- if ( eventFromIframe.origin === 'https://subscribe.wordpress.com' && eventFromIframe.data ) {
- const data = JSON.parse( eventFromIframe.data );
- if ( data && data.action === 'close' ) {
- window.removeEventListener( 'message', handleIframeResult );
- tb_remove();
- }
- }
-}
-
-function activateSubscription( block, blogId, planId, poweredText, lang ) {
- block.addEventListener( 'click', () => {
- tb_show(
- null,
- 'https://subscribe.wordpress.com/memberships/?blog=' +
- blogId +
- '&plan=' +
- planId +
- '&lang=' +
- lang +
- 'TB_iframe=true&height=600&width=400',
- null
- );
- window.addEventListener( 'message', handleIframeResult, false );
- const tbWindow = document.querySelector( '#TB_window' );
- tbWindow.classList.add( 'jetpack-memberships-modal' );
- const footer = document.createElement( 'DIV' );
- footer.classList.add( 'TB_footer' );
- footer.innerHTML = poweredText;
- tbWindow.appendChild( footer );
- } );
-}
-
-const initializeMembershipButtonBlocks = () => {
- const membershipButtonBlocks = Array.prototype.slice.call(
- document.querySelectorAll( '.' + blockClassName )
- );
- membershipButtonBlocks.forEach( block => {
- const blogId = block.getAttribute( 'data-blog-id' );
- const planId = block.getAttribute( 'data-plan-id' );
- const lang = block.getAttribute( 'data-lang' );
- const poweredText = block
- .getAttribute( 'data-powered-text' )
- .replace(
- 'WordPress.com',
- '<a href="https://wordpress.com" target="_blank" rel="noreferrer noopener">WordPress.com</a>'
- );
- try {
- activateSubscription( block, blogId, planId, poweredText, lang );
- } catch ( err ) {
- // eslint-disable-next-line no-console
- console.error( 'Problem activating Membership Button ' + planId, err );
- }
- } );
-};
-
-if ( typeof window !== 'undefined' && typeof document !== 'undefined' ) {
- // `DOMContentLoaded` may fire before the script has a chance to run
- if ( document.readyState === 'loading' ) {
- document.addEventListener( 'DOMContentLoaded', initializeMembershipButtonBlocks );
- } else {
- initializeMembershipButtonBlocks();
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/membership-button/view.scss b/plugins/jetpack/extensions/blocks/membership-button/view.scss
deleted file mode 100644
index cc0eb71c..00000000
--- a/plugins/jetpack/extensions/blocks/membership-button/view.scss
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Additional styling to thickbox that displays modal */
-/* stylelint-disable selector-max-id */
-
-.jetpack-memberships-modal #TB_title {
- border-radius: 4px 4px 0 0;
-}
-#TB_window.jetpack-memberships-modal {
- border-radius: 4px;
- background-color: $muriel-gray-0;
- background-image: url( 'https://s0.wp.com/i/loading/loading-64.gif' );
- background-repeat: no-repeat;
- background-position: center;
- bottom: 10%;
- margin-top: 0 !important;
- top: 10%;
-}
-
-.jetpack-memberships-modal #TB_iframeContent {
- height: calc( 100% - 50px ) !important;
-}
-@media only screen and ( max-width: 480px ) {
- #TB_window.jetpack-memberships-modal {
- bottom: 0;
- left: 0;
- margin-left: 0 !important;
- right: 0;
- top: 0;
- width: 100% !important;
- }
- .jetpack-memberships-modal #TB_iframeContent {
- width: 100% !important;
- }
-}
-
-.jetpack-memberships-modal #TB_iframeContent {
- height: calc( 100% - 80px ) !important;
-}
-.jetpack-memberships-modal .TB_footer {
- border-top: 1px solid $muriel-gray-50;
- color: $muriel-blue-200;
- font-size: 13px;
- padding: 4px 0;
- text-align: center;
-}
-.jetpack-memberships-modal .TB_footer a,
-.jetpack-memberships-modal .TB_footer a:hover,
-.jetpack-memberships-modal .TB_footer a:visited {
- color: $muriel-hot-blue-500;
-}
diff --git a/plugins/jetpack/extensions/blocks/pinterest/pinterest.php b/plugins/jetpack/extensions/blocks/pinterest/pinterest.php
new file mode 100644
index 00000000..a3b6e616
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/pinterest/pinterest.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Pinterest Block.
+ *
+ * @since 8.0.0
+ *
+ * @package Jetpack
+ */
+
+jetpack_register_block(
+ 'jetpack/pinterest',
+ array( 'render_callback' => 'jetpack_pinterest_block_load_assets' )
+);
+
+/**
+ * Pinterest block registration/dependency declaration.
+ *
+ * @param array $attr Array containing the Pinterest block attributes.
+ * @param string $content String containing the Pinterest block content.
+ *
+ * @return string
+ */
+function jetpack_pinterest_block_load_assets( $attr, $content ) {
+ wp_enqueue_script( 'pinterest-pinit', 'https://assets.pinterest.com/js/pinit.js', array(), JETPACK__VERSION, true );
+ return $content;
+}
diff --git a/plugins/jetpack/extensions/blocks/publicize/connection-verify.js b/plugins/jetpack/extensions/blocks/publicize/connection-verify.js
deleted file mode 100644
index 030ebb11..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/connection-verify.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * Publicize connections verification component.
- *
- * Component to create Ajax request to check
- * all connections. If any connection tests failed,
- * a refresh link may be provided to the user. If
- * no connection tests fail, this component will
- * not render anything.
- */
-
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Button, Notice } from '@wordpress/components';
-import { Component, Fragment } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-class PublicizeConnectionVerify extends Component {
- componentDidMount() {
- this.props.refreshConnections();
- }
-
- /**
- * Opens up popup so user can refresh connection
- *
- * Displays pop up with to specified URL where user
- * can refresh a specific connection.
- *
- * @param {object} event Event instance for onClick.
- */
- refreshConnectionClick = event => {
- const { href, title } = event.target;
- event.preventDefault();
- // open a popup window
- // when it is closed, kick off the tests again
- const popupWin = window.open( href, title, '' );
- const popupTimer = window.setInterval( () => {
- if ( false !== popupWin.closed ) {
- window.clearInterval( popupTimer );
- this.props.refreshConnections();
- }
- }, 500 );
- };
-
- renderRefreshableConnections() {
- const { failedConnections } = this.props;
- const refreshableConnections = failedConnections.filter( connection => connection.can_refresh );
-
- if ( refreshableConnections.length ) {
- return (
- <Notice className="jetpack-publicize-notice" isDismissible={ false } status="error">
- <p>
- { __(
- 'Before you hit Publish, please refresh the following connection(s) to make sure we can Publicize your post:',
- 'jetpack'
- ) }
- </p>
- { refreshableConnections.map( connection => (
- <Button
- href={ connection.refresh_url }
- isSmall
- key={ connection.id }
- onClick={ this.refreshConnectionClick }
- title={ connection.refresh_text }
- >
- { connection.refresh_text }
- </Button>
- ) ) }
- </Notice>
- );
- }
-
- return null;
- }
-
- renderNonRefreshableConnections() {
- const { failedConnections } = this.props;
- const nonRefreshableConnections = failedConnections.filter(
- connection => ! connection.can_refresh
- );
-
- if ( nonRefreshableConnections.length ) {
- return nonRefreshableConnections.map( connection => (
- <Notice className="jetpack-publicize-notice" isDismissible={ false } status="error">
- <p>{ connection.test_message }</p>
- </Notice>
- ) );
- }
-
- return null;
- }
-
- render() {
- return (
- <Fragment>
- { this.renderRefreshableConnections() }
- { this.renderNonRefreshableConnections() }
- </Fragment>
- );
- }
-}
-
-export default compose( [
- withSelect( select => ( {
- failedConnections: select( 'jetpack/publicize' ).getFailedConnections(),
- } ) ),
- withDispatch( dispatch => ( {
- refreshConnections: dispatch( 'jetpack/publicize' ).refreshConnectionTestResults,
- } ) ),
-] )( PublicizeConnectionVerify );
diff --git a/plugins/jetpack/extensions/blocks/publicize/connection.js b/plugins/jetpack/extensions/blocks/publicize/connection.js
deleted file mode 100644
index 071a275d..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/connection.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Publicize connection form component.
- *
- * Component to display connection label and a
- * checkbox to enable/disable the connection for sharing.
- */
-
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { Disabled, FormToggle, Notice, ExternalLink } from '@wordpress/components';
-import { withSelect } from '@wordpress/data';
-import { includes } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import PublicizeServiceIcon from './service-icon';
-import getSiteFragment from '../../shared/get-site-fragment';
-
-class PublicizeConnection extends Component {
- /**
- * Displays a message when a connection requires reauthentication. We used this when migrating LinkedIn API usage from v1 to v2,
- * since the prevous OAuth1 tokens were incompatible with OAuth2.
- *
- * @returns {object|?null} Notice about reauthentication
- */
- maybeDisplayLinkedInNotice = () =>
- this.connectionNeedsReauth() && (
- <Notice className="jetpack-publicize-notice" isDismissible={ false } status="error">
- <p>
- { __(
- 'Your LinkedIn connection needs to be reauthenticated ' +
- 'to continue working – head to Sharing to take care of it.',
- 'jetpack'
- ) }
- </p>
- <ExternalLink href={ `https://wordpress.com/marketing/connections/${ getSiteFragment() }` }>
- { __( 'Go to Sharing settings', 'jetpack' ) }
- </ExternalLink>
- </Notice>
- );
-
- /**
- * Check whether the connection needs to be reauthenticated.
- *
- * @returns {boolean} True if connection must be reauthenticated.
- */
- connectionNeedsReauth = () => includes( this.props.mustReauthConnections, this.props.name );
-
- onConnectionChange = () => {
- const { id } = this.props;
- this.props.toggleConnection( id );
- };
-
- connectionIsFailing() {
- const { failedConnections, name } = this.props;
- return failedConnections.some( connection => connection.service_name === name );
- }
-
- render() {
- const { disabled, enabled, id, label, name } = this.props;
- const fieldId = 'connection-' + name + '-' + id;
- // Genericon names are dash separated
- const serviceName = name.replace( '_', '-' );
-
- let toggle = (
- <FormToggle
- id={ fieldId }
- className="jetpack-publicize-connection-toggle"
- checked={ enabled }
- onChange={ this.onConnectionChange }
- />
- );
-
- if ( disabled || this.connectionIsFailing() || this.connectionNeedsReauth() ) {
- toggle = <Disabled>{ toggle }</Disabled>;
- }
-
- return (
- <li>
- { this.maybeDisplayLinkedInNotice() }
- <div className="publicize-jetpack-connection-container">
- <label htmlFor={ fieldId } className="jetpack-publicize-connection-label">
- <PublicizeServiceIcon serviceName={ serviceName } />
- <span className="jetpack-publicize-connection-label-copy">{ label }</span>
- </label>
- { toggle }
- </div>
- </li>
- );
- }
-}
-
-export default withSelect( select => ( {
- failedConnections: select( 'jetpack/publicize' ).getFailedConnections(),
- mustReauthConnections: select( 'jetpack/publicize' ).getMustReauthConnections(),
-} ) )( PublicizeConnection );
diff --git a/plugins/jetpack/extensions/blocks/publicize/editor.js b/plugins/jetpack/extensions/blocks/publicize/editor.js
deleted file mode 100644
index 9adee220..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../shared/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/publicize/editor.scss b/plugins/jetpack/extensions/blocks/publicize/editor.scss
deleted file mode 100644
index 0704a5fa..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/editor.scss
+++ /dev/null
@@ -1,100 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.jetpack-publicize-message-box {
- background-color: $light-gray-300;
- border-radius: 4px;
-}
-
-.jetpack-publicize-message-box textarea {
- width: 100%;
-}
-
-.jetpack-publicize-character-count {
- padding-bottom: 5px;
- padding-left: 5px;
-}
-
-.jetpack-publicize__connections-list {
- list-style-type: none;
- margin: 13px 0;
-}
-
-.publicize-jetpack-connection-container {
- display: flex;
-}
-
-.jetpack-publicize-gutenberg-social-icon {
- fill: $dark-gray-500;
- margin-right: 5px;
-
- &.is-facebook {
- fill: var( --color-facebook );
- }
- &.is-twitter {
- fill: var( --color-twitter );
- }
- &.is-linkedin {
- fill: var( --color-linkedin );
- }
- &.is-tumblr {
- fill: var( --color-tumblr );
- }
-}
-
-.jetpack-publicize-connection-label {
- flex: 1;
- margin-right: 5px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-
- .jetpack-publicize-gutenberg-social-icon,
- .jetpack-publicize-connection-label-copy {
- display: inline-block;
- vertical-align: middle;
- }
-}
-
-.jetpack-publicize-connection-toggle {
- margin-top: 3px;
-}
-
-.jetpack-publicize-notice {
- &.components-notice {
- margin-left: 0;
- margin-right: 0;
- margin-bottom: 13px;
- }
-
- .components-button + .components-button {
- margin-top: 5px;
- }
-}
-
-.jetpack-publicize-message-note {
- display: inline-block;
- margin-bottom: 4px;
- margin-top: 13px;
-}
-
-.jetpack-publicize-add-connection-wrapper {
- margin: 15px 0;
-}
-
-.jetpack-publicize-add-connection-container {
- display: flex;
-
- a {
- cursor: pointer;
- }
-
- span {
- vertical-align: middle;
- }
-}
-
-.jetpack-publicize__connections-list {
- .components-notice {
- margin: 5px 0 10px;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/publicize/form-unwrapped.js b/plugins/jetpack/extensions/blocks/publicize/form-unwrapped.js
deleted file mode 100644
index 04efc7eb..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/form-unwrapped.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * Publicize sharing form component.
- *
- * Displays text area and connection list to allow user
- * to select connections to share to and write a custom
- * sharing message.
- */
-
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import { __, _n, sprintf } from '@wordpress/i18n';
-import { Component, Fragment } from '@wordpress/element';
-import { uniqueId } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import PublicizeConnection from './connection';
-import PublicizeSettingsButton from './settings-button';
-
-export const MAXIMUM_MESSAGE_LENGTH = 256;
-
-class PublicizeFormUnwrapped extends Component {
- state = {
- hasEditedShareMessage: false,
- };
-
- fieldId = uniqueId( 'jetpack-publicize-message-field-' );
-
- /**
- * Check to see if form should be disabled.
- *
- * Checks full connection list to determine if all are disabled.
- * If they all are, it returns true to disable whole form.
- *
- * @return {boolean} True if whole form should be disabled.
- */
- isDisabled() {
- return this.props.connections.every( connection => ! connection.toggleable );
- }
-
- getShareMessage() {
- const { shareMessage, defaultShareMessage } = this.props;
- return ! this.state.hasEditedShareMessage && shareMessage === ''
- ? defaultShareMessage
- : shareMessage;
- }
-
- onMessageChange = event => {
- const { messageChange } = this.props;
- this.setState( { hasEditedShareMessage: true } );
- messageChange( event );
- };
-
- render() {
- const { connections, toggleConnection, refreshCallback } = this.props;
- const shareMessage = this.getShareMessage();
- const charactersRemaining = MAXIMUM_MESSAGE_LENGTH - shareMessage.length;
- const characterCountClass = classnames( 'jetpack-publicize-character-count', {
- 'wpas-twitter-length-limit': charactersRemaining <= 0,
- } );
-
- return (
- <div id="publicize-form">
- <ul className="jetpack-publicize__connections-list">
- { connections.map( ( { display_name, enabled, id, service_name, toggleable } ) => (
- <PublicizeConnection
- disabled={ ! toggleable }
- enabled={ enabled }
- key={ id }
- id={ id }
- label={ display_name }
- name={ service_name }
- toggleConnection={ toggleConnection }
- />
- ) ) }
- </ul>
- <PublicizeSettingsButton refreshCallback={ refreshCallback } />
- { connections.some( connection => connection.enabled ) && (
- <Fragment>
- <label className="jetpack-publicize-message-note" htmlFor={ this.fieldId }>
- { __( 'Customize your message', 'jetpack' ) }
- </label>
- <div className="jetpack-publicize-message-box">
- <textarea
- id={ this.fieldId }
- value={ shareMessage }
- onChange={ this.onMessageChange }
- disabled={ this.isDisabled() }
- maxLength={ MAXIMUM_MESSAGE_LENGTH }
- placeholder={ __(
- "Write a message for your audience here. If you leave this blank, we'll use the post title as the message.",
- 'jetpack'
- ) }
- rows={ 4 }
- />
- <div className={ characterCountClass }>
- { sprintf(
- _n(
- '%d character remaining',
- '%d characters remaining',
- charactersRemaining,
- 'jetpack'
- ),
- charactersRemaining
- ) }
- </div>
- </div>
- </Fragment>
- ) }
- </div>
- );
- }
-}
-
-export default PublicizeFormUnwrapped;
diff --git a/plugins/jetpack/extensions/blocks/publicize/form.js b/plugins/jetpack/extensions/blocks/publicize/form.js
deleted file mode 100644
index cb76b54f..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/form.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Higher Order Publicize sharing form composition.
- *
- * Uses Gutenberg data API to dispatch publicize form data to
- * editor post data in format to match 'publicize' field schema.
- */
-
-/**
- * External dependencies
- */
-import { get } from 'lodash';
-import { compose } from '@wordpress/compose';
-import { withSelect, withDispatch } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import PublicizeFormUnwrapped, { MAXIMUM_MESSAGE_LENGTH } from './form-unwrapped';
-
-const PublicizeForm = compose( [
- withSelect( select => {
- const meta = select( 'core/editor' ).getEditedPostAttribute( 'meta' );
- const postTitle = select( 'core/editor' ).getEditedPostAttribute( 'title' );
- const message = get( meta, [ 'jetpack_publicize_message' ], '' );
-
- return {
- connections: select( 'core/editor' ).getEditedPostAttribute(
- 'jetpack_publicize_connections'
- ),
- defaultShareMessage: postTitle.substr( 0, MAXIMUM_MESSAGE_LENGTH ),
- shareMessage: message.substr( 0, MAXIMUM_MESSAGE_LENGTH ),
- };
- } ),
- withDispatch( ( dispatch, { connections } ) => ( {
- /**
- * Toggle connection enable/disable state based on checkbox.
- *
- * Saves enable/disable value to connections property in editor
- * in field 'jetpack_publicize_connections'.
- *
- * @param {number} id ID of the connection being enabled/disabled
- */
- toggleConnection( id ) {
- const newConnections = connections.map( connection => ( {
- ...connection,
- enabled: connection.id === id ? ! connection.enabled : connection.enabled,
- } ) );
-
- dispatch( 'core/editor' ).editPost( {
- jetpack_publicize_connections: newConnections,
- } );
- },
-
- /**
- * Handler for when sharing message is edited.
- *
- * Saves edited message to state and to the editor
- * in field 'jetpack_publicize_message'.
- *
- * @param {object} event Change event data from textarea element.
- */
- messageChange( event ) {
- dispatch( 'core/editor' ).editPost( {
- meta: {
- jetpack_publicize_message: event.target.value,
- },
- } );
- },
- } ) ),
-] )( PublicizeFormUnwrapped );
-
-export default PublicizeForm;
diff --git a/plugins/jetpack/extensions/blocks/publicize/index.js b/plugins/jetpack/extensions/blocks/publicize/index.js
deleted file mode 100644
index 9d553873..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/index.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Top-level Publicize plugin for Gutenberg editor.
- *
- * Hooks into Gutenberg's PluginPrePublishPanel
- * to display Jetpack's Publicize UI in the pre-publish flow.
- *
- * It also hooks into our dedicated Jetpack plugin sidebar and
- * displays the Publicize UI there.
- */
-
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { PanelBody } from '@wordpress/components';
-import { PluginPrePublishPanel } from '@wordpress/edit-post';
-import { PostTypeSupportCheck } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import './editor.scss';
-import './store';
-import JetpackPluginSidebar from '../../shared/jetpack-plugin-sidebar';
-import PublicizePanel from './panel';
-
-export const name = 'publicize';
-
-export const settings = {
- render: () => (
- <PostTypeSupportCheck supportKeys="publicize">
- <JetpackPluginSidebar>
- <PanelBody title={ __( 'Share this post', 'jetpack' ) }>
- <PublicizePanel />
- </PanelBody>
- </JetpackPluginSidebar>
- <PluginPrePublishPanel
- initialOpen
- id="publicize-title"
- title={
- <span id="publicize-defaults" key="publicize-title-span">
- { __( 'Share this post', 'jetpack' ) }
- </span>
- }
- >
- <PublicizePanel />
- </PluginPrePublishPanel>
- </PostTypeSupportCheck>
- ),
-};
diff --git a/plugins/jetpack/extensions/blocks/publicize/panel.js b/plugins/jetpack/extensions/blocks/publicize/panel.js
deleted file mode 100644
index 81735c48..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/panel.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Publicize sharing panel component.
- *
- * Displays Publicize notifications if no
- * services are connected or displays form if
- * services are connected.
- */
-
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { compose } from '@wordpress/compose';
-import { Fragment } from '@wordpress/element';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import PublicizeConnectionVerify from './connection-verify';
-import PublicizeForm from './form';
-import PublicizeSettingsButton from './settings-button';
-
-const PublicizePanel = ( { connections, refreshConnections } ) => (
- <Fragment>
- { connections && connections.some( connection => connection.enabled ) && (
- <PublicizeConnectionVerify />
- ) }
- <div>
- { __( "Connect and select the accounts where you'd like to share your post.", 'jetpack' ) }
- </div>
- { connections && connections.length > 0 && (
- <PublicizeForm refreshCallback={ refreshConnections } />
- ) }
- { connections && 0 === connections.length && (
- <PublicizeSettingsButton
- className="jetpack-publicize-add-connection-wrapper"
- refreshCallback={ refreshConnections }
- />
- ) }
- </Fragment>
-);
-
-export default compose( [
- withSelect( select => ( {
- connections: select( 'core/editor' ).getEditedPostAttribute( 'jetpack_publicize_connections' ),
- } ) ),
- withDispatch( dispatch => ( {
- refreshConnections: dispatch( 'core/editor' ).refreshPost,
- } ) ),
-] )( PublicizePanel );
diff --git a/plugins/jetpack/extensions/blocks/publicize/service-icon.js b/plugins/jetpack/extensions/blocks/publicize/service-icon.js
deleted file mode 100644
index dc5dc392..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/service-icon.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * External dependencies
- */
-import { G, Icon, Path, Rect, SVG } from '@wordpress/components';
-
-/**
- * Module variables
- */
-// @TODO: Import those from https://github.com/Automattic/social-logos when that's possible.
-// Currently we can't directly import icons from there, because all icons are bundled in a single file.
-// This means that to import an icon from there, we'll need to add the entire bundle with all icons to our build.
-// In the future we'd want to export each icon in that repo separately, and then import them separately here.
-const FacebookIcon = (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
- <Rect x="0" fill="none" width="24" height="24" />
- <G>
- <Path d="M20.007 3H3.993C3.445 3 3 3.445 3 3.993v16.013c0 .55.445.994.993.994h8.62v-6.97H10.27V11.31h2.346V9.31c0-2.325 1.42-3.59 3.494-3.59.993 0 1.847.073 2.096.106v2.43h-1.438c-1.128 0-1.346.537-1.346 1.324v1.734h2.69l-.35 2.717h-2.34V21h4.587c.548 0 .993-.445.993-.993V3.993c0-.548-.445-.993-.993-.993z" />
- </G>
- </SVG>
-);
-const TwitterIcon = (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
- <Rect x="0" fill="none" width="24" height="24" />
- <G>
- <Path d="M22.23 5.924c-.736.326-1.527.547-2.357.646.847-.508 1.498-1.312 1.804-2.27-.793.47-1.67.812-2.606.996C18.325 4.498 17.258 4 16.078 4c-2.266 0-4.103 1.837-4.103 4.103 0 .322.036.635.106.935-3.41-.17-6.433-1.804-8.457-4.287-.353.607-.556 1.312-.556 2.064 0 1.424.724 2.68 1.825 3.415-.673-.022-1.305-.207-1.86-.514v.052c0 1.988 1.415 3.647 3.293 4.023-.344.095-.707.145-1.08.145-.265 0-.522-.026-.773-.074.522 1.63 2.038 2.817 3.833 2.85-1.404 1.1-3.174 1.757-5.096 1.757-.332 0-.66-.02-.98-.057 1.816 1.164 3.973 1.843 6.29 1.843 7.547 0 11.675-6.252 11.675-11.675 0-.178-.004-.355-.012-.53.802-.578 1.497-1.3 2.047-2.124z" />
- </G>
- </SVG>
-);
-const LinkedinIcon = (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
- <Rect x="0" fill="none" width="24" height="24" />
- <G>
- <Path d="M19.7 3H4.3C3.582 3 3 3.582 3 4.3v15.4c0 .718.582 1.3 1.3 1.3h15.4c.718 0 1.3-.582 1.3-1.3V4.3c0-.718-.582-1.3-1.3-1.3zM8.34 18.338H5.666v-8.59H8.34v8.59zM7.003 8.574c-.857 0-1.55-.694-1.55-1.548 0-.855.692-1.548 1.55-1.548.854 0 1.547.694 1.547 1.548 0 .855-.692 1.548-1.546 1.548zm11.335 9.764h-2.67V14.16c0-.995-.017-2.277-1.387-2.277-1.39 0-1.6 1.086-1.6 2.206v4.248h-2.668v-8.59h2.56v1.174h.036c.357-.675 1.228-1.387 2.527-1.387 2.703 0 3.203 1.78 3.203 4.092v4.71z" />
- </G>
- </SVG>
-);
-const TumblrIcon = (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
- <Rect x="0" fill="none" width="24" height="24" />
- <G>
- <Path d="M19 3H5c-1.105 0-2 .895-2 2v14c0 1.105.895 2 2 2h14c1.105 0 2-.895 2-2V5c0-1.105-.895-2-2-2zm-5.57 14.265c-2.445.042-3.37-1.742-3.37-2.998V10.6H8.922V9.15c1.703-.615 2.113-2.15 2.21-3.026.006-.06.053-.084.08-.084h1.645V8.9h2.246v1.7H12.85v3.495c.008.476.182 1.13 1.08 1.107.3-.008.698-.094.907-.194l.54 1.6c-.205.297-1.12.642-1.946.657z" />
- </G>
- </SVG>
-);
-
-export default ( { serviceName } ) => {
- const defaultProps = {
- className: `jetpack-publicize-gutenberg-social-icon is-${ serviceName }`,
- size: 24,
- };
-
- switch ( serviceName ) {
- case 'facebook':
- return <Icon icon={ FacebookIcon } { ...defaultProps } />;
- case 'twitter':
- return <Icon icon={ TwitterIcon } { ...defaultProps } />;
- case 'linkedin':
- return <Icon icon={ LinkedinIcon } { ...defaultProps } />;
- case 'tumblr':
- return <Icon icon={ TumblrIcon } { ...defaultProps } />;
- }
-
- return null;
-};
diff --git a/plugins/jetpack/extensions/blocks/publicize/settings-button.js b/plugins/jetpack/extensions/blocks/publicize/settings-button.js
deleted file mode 100644
index 8e22ee82..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/settings-button.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Publicize settings button component.
- *
- * Component which allows user to click to open settings
- * in a new window/tab. If window/tab is closed, then
- * connections will be automatically refreshed.
- */
-
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import classnames from 'classnames';
-import { Component } from '@wordpress/element';
-import { ExternalLink } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import getSiteFragment from '../../shared/get-site-fragment';
-
-class PublicizeSettingsButton extends Component {
- getButtonLink() {
- const siteFragment = getSiteFragment();
-
- // If running in WP.com wp-admin or in Calypso, we redirect to Calypso sharing settings.
- if ( siteFragment ) {
- return `https://wordpress.com/marketing/connections/${ siteFragment }`;
- }
-
- // If running in WordPress.org wp-admin we redirect to Sharing settings in wp-admin.
- return 'options-general.php?page=sharing&publicize_popup=true';
- }
-
- /**
- * Opens up popup so user can view/modify connections
- *
- * @param {object} event Event instance for onClick.
- */
- settingsClick = event => {
- const href = this.getButtonLink();
- const { refreshCallback } = this.props;
- event.preventDefault();
- /**
- * Open a popup window, and
- * when it is closed, refresh connections
- */
- const popupWin = window.open( href, '', '' );
- const popupTimer = window.setInterval( () => {
- if ( false !== popupWin.closed ) {
- window.clearInterval( popupTimer );
- refreshCallback();
- }
- }, 500 );
- };
-
- render() {
- const className = classnames(
- 'jetpack-publicize-add-connection-container',
- this.props.className
- );
-
- return (
- <div className={ className }>
- <ExternalLink onClick={ this.settingsClick }>
- { __( 'Connect an account', 'jetpack' ) }
- </ExternalLink>
- </div>
- );
- }
-}
-
-export default PublicizeSettingsButton;
diff --git a/plugins/jetpack/extensions/blocks/publicize/store/actions.js b/plugins/jetpack/extensions/blocks/publicize/store/actions.js
deleted file mode 100644
index e5b71694..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/store/actions.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Returns an action object used in signalling that
- * we're setting the Publicize connection test results.
- *
- * @param {Array} results Connection test results.
- *
- * @return {Object} Action object.
- */
-export function setConnectionTestResults( results ) {
- return {
- type: 'SET_CONNECTION_TEST_RESULTS',
- results,
- };
-}
-
-/**
- * Returns an action object used in signalling that
- * we're refreshing the Publicize connection test results.
- *
- * @return {Object} Action object.
- */
-export function refreshConnectionTestResults() {
- return {
- type: 'REFRESH_CONNECTION_TEST_RESULTS',
- };
-}
-
-/**
- * Returns an action object used in signalling that
- * we're initiating a fetch request to the REST API.
- *
- * @param {String} path API endpoint path.
- *
- * @return {Object} Action object.
- */
-export function fetchFromAPI( path ) {
- return {
- type: 'FETCH_FROM_API',
- path,
- };
-}
diff --git a/plugins/jetpack/extensions/blocks/publicize/store/controls.js b/plugins/jetpack/extensions/blocks/publicize/store/controls.js
deleted file mode 100644
index afe6eccd..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/store/controls.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-
-/**
- * Trigger an API Fetch request.
- *
- * @param {Object} action Action Object.
- *
- * @return {Promise} Fetch request promise.
- */
-const fetchFromApi = ( { path } ) => {
- return apiFetch( { path } );
-};
-
-export default {
- FETCH_FROM_API: fetchFromApi,
-};
diff --git a/plugins/jetpack/extensions/blocks/publicize/store/effects.js b/plugins/jetpack/extensions/blocks/publicize/store/effects.js
deleted file mode 100644
index 594c8b72..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/store/effects.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-
-/**
- * Internal dependencies
- */
-import { setConnectionTestResults } from './actions';
-
-/**
- * Effect handler which will refresh the connection test results.
- *
- * @param {Object} action Action which had initiated the effect handler.
- * @param {Object} store Store instance.
- *
- * @return {Object} Refresh connection test results action.
- */
-export async function refreshConnectionTestResults( action, store ) {
- const { dispatch } = store;
-
- try {
- const results = await apiFetch( { path: '/wpcom/v2/publicize/connection-test-results' } );
- return dispatch( setConnectionTestResults( results ) );
- } catch ( error ) {
- // Refreshing connections failed
- }
-}
-
-export default {
- REFRESH_CONNECTION_TEST_RESULTS: refreshConnectionTestResults,
-};
diff --git a/plugins/jetpack/extensions/blocks/publicize/store/index.js b/plugins/jetpack/extensions/blocks/publicize/store/index.js
deleted file mode 100644
index 337167bc..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/store/index.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * External dependencies
- */
-import { registerStore } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import * as actions from './actions';
-import * as selectors from './selectors';
-import applyMiddlewares from './middlewares';
-import controls from './controls';
-import reducer from './reducer';
-
-const store = registerStore( 'jetpack/publicize', {
- actions,
- controls,
- reducer,
- selectors,
-} );
-
-applyMiddlewares( store );
-
-export default store;
diff --git a/plugins/jetpack/extensions/blocks/publicize/store/middlewares.js b/plugins/jetpack/extensions/blocks/publicize/store/middlewares.js
deleted file mode 100644
index 1403b808..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/store/middlewares.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * External dependencies
- */
-import refx from 'refx';
-import { flowRight } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import effects from './effects';
-
-/**
- * Applies the custom middlewares used specifically in the Publicize extension.
- *
- * @param {Object} store Store Object.
- *
- * @return {Object} Update Store Object.
- */
-export default function applyMiddlewares( store ) {
- const middlewares = [ refx( effects ) ];
-
- let enhancedDispatch = () => {
- throw new Error(
- 'Dispatching while constructing your middleware is not allowed. ' +
- 'Other middleware would not be applied to this dispatch.'
- );
- };
- let chain = [];
-
- const middlewareAPI = {
- getState: store.getState,
- dispatch: ( ...args ) => enhancedDispatch( ...args ),
- };
- chain = middlewares.map( middleware => middleware( middlewareAPI ) );
- enhancedDispatch = flowRight( ...chain )( store.dispatch );
-
- store.dispatch = enhancedDispatch;
-
- return store;
-}
diff --git a/plugins/jetpack/extensions/blocks/publicize/store/reducer.js b/plugins/jetpack/extensions/blocks/publicize/store/reducer.js
deleted file mode 100644
index 80af0701..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/store/reducer.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Reducer managing Publicize connection test results.
- *
- * @param {Object} state Current state.
- * @param {Object} action Dispatched action.
- *
- * @return {Object} Updated state.
- */
-export default function( state = [], action ) {
- switch ( action.type ) {
- case 'SET_CONNECTION_TEST_RESULTS':
- return action.results;
- case 'REFRESH_CONNECTION_TEST_RESULTS':
- return [];
- }
-
- return state;
-}
diff --git a/plugins/jetpack/extensions/blocks/publicize/store/selectors.js b/plugins/jetpack/extensions/blocks/publicize/store/selectors.js
deleted file mode 100644
index db86a4fe..00000000
--- a/plugins/jetpack/extensions/blocks/publicize/store/selectors.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Returns the failed Publicize connections.
- *
- * @param {Object} state State object.
- *
- * @return {Array} List of connections.
- */
-export function getFailedConnections( state ) {
- return state.filter( connection => false === connection.test_success );
-}
-
-/**
- * Returns a list of Publicize connection service names that require reauthentication from users.
- * iFor example, when LinkedIn switched its API from v1 to v2.
- *
- * @param {Object} state State object.
- *
- * @return {Array} List of service names that need reauthentication.
- */
-export function getMustReauthConnections( state ) {
- return state
- .filter( connection => 'must_reauth' === connection.test_success )
- .map( connection => connection.service_name );
-}
diff --git a/plugins/jetpack/extensions/blocks/rating-star/rating-meta.php b/plugins/jetpack/extensions/blocks/rating-star/rating-meta.php
new file mode 100644
index 00000000..dfbf3003
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/rating-star/rating-meta.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Utilities for the rating block.
+ *
+ * @since 8.0.0
+ *
+ * @package Jetpack
+ */
+
+if ( ! function_exists( 'jetpack_rating_meta_get_symbol_low_fidelity' ) ) {
+ /**
+ * Returns the low fidelity symbol for the block.
+ *
+ * @return string
+ */
+ function jetpack_rating_meta_get_symbol_low_fidelity() {
+ return '⭐';
+ }
+}
+
+if ( ! function_exists( 'jetpack_rating_star_get_symbol_high_fidelity' ) ) {
+ /**
+ * Return the high fidelity symbol for the block.
+ *
+ * @param string $classname_whole Name of the whole symbol class.
+ * @param string $classname_half Name of the half symbol class.
+ * @param string $color Color of the block.
+ *
+ * @return string
+ */
+ function jetpack_rating_star_get_symbol_high_fidelity( $classname_whole, $classname_half, $color ) {
+ return <<<ELO
+<span>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path class="{$classname_whole}" fill="{$color}" stroke="{$color}" d="M12,17.3l6.2,3.7l-1.6-7L22,9.2l-7.2-0.6L12,2L9.2,8.6L2,9.2L7.5,14l-1.6,7L12,17.3z" />
+</svg>
+</span>
+<span>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+ <path class="{$classname_half}" fill="{$color}" stroke="{$color}" d="M12,17.3l6.2,3.7l-1.6-7L22,9.2l-7.2-0.6L12,2L9.2,8.6L2,9.2L7.5,14l-1.6,7L12,17.3z" />
+</svg>
+</span>
+ELO;
+ }
+}
+
+if ( ! function_exists( 'jetpack_rating_meta_get_symbol_high_fidelity' ) ) {
+ /**
+ * Returns the high fidelity symbol for the block.
+ *
+ * @param array $attributes Array containing the block attributes.
+ * @param integer $pos Value to render whole and half symbols.
+ * @return string
+ */
+ function jetpack_rating_meta_get_symbol_high_fidelity( $attributes, $pos ) {
+ $classname_whole = ( $attributes['rating'] >= ( $pos - 0.5 ) ) ? '' : 'is-rating-unfilled';
+ $classname_half = ( $attributes['rating'] >= $pos ) ? '' : 'is-rating-unfilled';
+ $color = empty( $attributes['color'] ) ? 'currentColor' : esc_attr( $attributes['color'] );
+
+ return jetpack_rating_star_get_symbol_high_fidelity( $classname_whole, $classname_half, $color );
+ }
+}
+
+if ( ! function_exists( 'jetpack_rating_meta_get_symbols' ) ) {
+ /**
+ * Returns the symbol for the block.
+ *
+ * @param array $attributes Array containing the block attributes.
+ *
+ * @return string
+ */
+ function jetpack_rating_meta_get_symbols( $attributes ) {
+ // Output SVGs for high fidelity contexts, then color them according to rating.
+ // These are hidden by default, then unhid when CSS loads.
+ $symbols_hifi = array();
+ for ( $pos = 1; $pos <= $attributes['maxRating']; $pos++ ) {
+ $symbols_hifi[] = '<span style="display: none;">' . jetpack_rating_meta_get_symbol_high_fidelity( $attributes, $pos ) . '</span>';
+ }
+
+ // Output fallback symbols for low fidelity contexts, like AMP,
+ // where CSS is not loaded so the high-fidelity symbols won't be rendered.
+ $symbols_lofi = '';
+ for ( $i = 0; $i < $attributes['rating']; $i++ ) {
+ $symbols_lofi .= jetpack_rating_meta_get_symbol_low_fidelity();
+ }
+
+ return '<p>' . $symbols_lofi . '</p>' . implode( $symbols_hifi );
+ }
+}
+
+if ( ! function_exists( 'jetpack_rating_meta_render_block' ) ) {
+ /**
+ * Dynamic rendering of the block.
+ *
+ * @param array $attributes Array containing the block attributes.
+ *
+ * @return string
+ */
+ function jetpack_rating_meta_render_block( $attributes ) {
+ $classname = empty( $attributes['className'] ) ? '' : ' ' . $attributes['className'];
+ return sprintf(
+ '<div class="%1$s" style="text-align:%3$s">%2$s</div>',
+ esc_attr( 'wp-block-jetpack-rating-' . $attributes['ratingStyle'] . $classname ),
+ jetpack_rating_meta_get_symbols( $attributes ),
+ ( isset( $attributes['align'] ) ) ? esc_attr( $attributes['align'] ) : ''
+ );
+ }
+}
diff --git a/plugins/jetpack/extensions/blocks/rating-star/rating-star.php b/plugins/jetpack/extensions/blocks/rating-star/rating-star.php
new file mode 100644
index 00000000..8b351e9b
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/rating-star/rating-star.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Star Rating Block.
+ *
+ * @since 8.0.0
+ *
+ * @package Jetpack
+ */
+
+// Load generic function definitions.
+require_once __DIR__ . '/rating-meta.php';
+
+/**
+ * Dynamic rendering of the block.
+ *
+ * @param array $attributes Array containing the block attributes.
+ *
+ * @return string
+ */
+function jetpack_rating_star_render_block( $attributes ) {
+ // Tell Jetpack to load the assets registered via jetpack_register_block.
+ Jetpack_Gutenberg::load_assets_as_required( 'rating-star' );
+
+ return jetpack_rating_meta_render_block( $attributes );
+}
+
+/**
+ * The following filter is added only to support the old 0.6.2 version of the AMP plugin.
+ * This entire section can be removed once we're on version a newer version.
+ * Confirmed that version 1.4.1 (or presumably newer) does not need this filter.
+ */
+function jetpack_rating_star_amp_add_inline_css() {
+ echo '.wp-block-jetpack-rating-star span { display: none; }';
+}
+add_action( 'amp_post_template_css', 'jetpack_rating_star_amp_add_inline_css', 11 );
+
+jetpack_register_block(
+ 'jetpack/rating-star',
+ array(
+ 'render_callback' => 'jetpack_rating_star_render_block',
+ 'attributes' => array(
+ 'rating' => array(
+ 'type' => 'number',
+ 'default' => 1,
+ ),
+ 'maxRating' => array(
+ 'type' => 'number',
+ 'default' => 5,
+ ),
+ 'color' => array(
+ 'type' => 'string',
+ ),
+ 'ratingStyle' => array(
+ 'type' => 'string',
+ 'default' => 'star',
+ ),
+ 'className' => array(
+ 'type' => 'string',
+ ),
+ 'align' => array(
+ 'type' => 'string',
+ 'default' => 'left',
+ ),
+ ),
+ )
+);
diff --git a/plugins/jetpack/extensions/blocks/membership-button/membership-button.php b/plugins/jetpack/extensions/blocks/recurring-payments/recurring-payments.php
index d8488cf2..d5d461e9 100644
--- a/plugins/jetpack/extensions/blocks/membership-button/membership-button.php
+++ b/plugins/jetpack/extensions/blocks/recurring-payments/recurring-payments.php
@@ -9,11 +9,5 @@
if ( ( defined( 'IS_WPCOM' ) && IS_WPCOM ) || Jetpack::is_active() ) {
require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php';
-
- jetpack_register_block(
- 'jetpack/membership-button',
- array(
- 'render_callback' => array( Jetpack_Memberships::get_instance(), 'render_button' ),
- )
- );
+ Jetpack_Memberships::get_instance()->register_gutenberg_block();
}
diff --git a/plugins/jetpack/extensions/blocks/related-posts/edit.js b/plugins/jetpack/extensions/blocks/related-posts/edit.js
deleted file mode 100644
index 7de102f4..00000000
--- a/plugins/jetpack/extensions/blocks/related-posts/edit.js
+++ /dev/null
@@ -1,252 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { BlockControls, InspectorControls } from '@wordpress/editor';
-import { PanelBody, RangeControl, ToggleControl, Toolbar, Path, SVG } from '@wordpress/components';
-import { Component, Fragment } from '@wordpress/element';
-import { get } from 'lodash';
-import { withSelect } from '@wordpress/data';
-import { compose, withInstanceId } from '@wordpress/compose';
-
-export const MAX_POSTS_TO_SHOW = 6;
-
-function PlaceholderPostEdit( props ) {
- return (
- <div
- className="jp-related-posts-i2__post"
- id={ props.id }
- aria-labelledby={ props.id + '-heading' }
- >
- <strong id={ props.id + '-heading' } className="jp-related-posts-i2__post-link">
- { __(
- "Preview unavailable: you haven't published enough posts with similar content.",
- 'jetpack'
- ) }
- </strong>
- { props.displayThumbnails && (
- <figure
- className="jp-related-posts-i2__post-image-placeholder"
- aria-label={ __( 'Placeholder image', 'jetpack' ) }
- >
- <SVG
- className="jp-related-posts-i2__post-image-placeholder-square"
- xmlns="http://www.w3.org/2000/svg"
- width="100%"
- height="100%"
- viewBox="0 0 350 200"
- >
- <title>{ __( 'Grey square', 'jetpack' ) }</title>
- <Path d="M0 0h350v200H0z" fill="#8B8B96" fill-opacity=".1" />
- </SVG>
- <SVG
- className="jp-related-posts-i2__post-image-placeholder-icon"
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- >
- <title>{ __( 'Icon for image', 'jetpack' ) }</title>
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86l-3 3.87L9 13.14 6 17h12l-3.86-5.14z" />
- </SVG>
- </figure>
- ) }
-
- { props.displayDate && (
- <div className="jp-related-posts-i2__post-date has-small-font-size">
- { __( 'August 3, 2018', 'jetpack' ) }
- </div>
- ) }
- { props.displayContext && (
- <div className="jp-related-posts-i2__post-context has-small-font-size">
- { __( 'In “Uncategorized”', 'jetpack' ) }
- </div>
- ) }
- </div>
- );
-}
-
-function RelatedPostsEditItem( props ) {
- return (
- <div
- className="jp-related-posts-i2__post"
- id={ props.id }
- aria-labelledby={ props.id + '-heading' }
- >
- <a
- className="jp-related-posts-i2__post-link"
- id={ props.id + '-heading' }
- href={ props.post.url }
- rel="nofollow noopener noreferrer"
- target="_blank"
- >
- { props.post.title }
- </a>
- { props.displayThumbnails && props.post.img && props.post.img.src && (
- <a className="jp-related-posts-i2__post-img-link" href={ props.post.url }>
- <img
- className="jp-related-posts-i2__post-img"
- src={ props.post.img.src }
- alt={ props.post.title }
- rel="nofollow noopener noreferrer"
- target="_blank"
- />
- </a>
- ) }
- { props.displayDate && (
- <div className="jp-related-posts-i2__post-date has-small-font-size">
- { props.post.date }
- </div>
- ) }
- { props.displayContext && (
- <div className="jp-related-posts-i2__post-context has-small-font-size">
- { props.post.context }
- </div>
- ) }
- </div>
- );
-}
-
-function RelatedPostsPreviewRows( props ) {
- const className = 'jp-related-posts-i2__row';
-
- let topRowEnd = 0;
- const displayLowerRow = props.posts.length > 3;
-
- switch ( props.posts.length ) {
- case 2:
- case 4:
- case 5:
- topRowEnd = 2;
- break;
- default:
- topRowEnd = 3;
- break;
- }
-
- return (
- <div>
- <div className={ className } data-post-count={ props.posts.slice( 0, topRowEnd ).length }>
- { props.posts.slice( 0, topRowEnd ) }
- </div>
- { displayLowerRow && (
- <div className={ className } data-post-count={ props.posts.slice( topRowEnd ).length }>
- { props.posts.slice( topRowEnd ) }
- </div>
- ) }
- </div>
- );
-}
-
-class RelatedPostsEdit extends Component {
- render() {
- const { attributes, className, posts, setAttributes, instanceId } = this.props;
- const { displayContext, displayDate, displayThumbnails, postLayout, postsToShow } = attributes;
-
- const layoutControls = [
- {
- icon: 'grid-view',
- title: __( 'Grid View', 'jetpack' ),
- onClick: () => setAttributes( { postLayout: 'grid' } ),
- isActive: postLayout === 'grid',
- },
- {
- icon: 'list-view',
- title: __( 'List View', 'jetpack' ),
- onClick: () => setAttributes( { postLayout: 'list' } ),
- isActive: postLayout === 'list',
- },
- ];
-
- // To prevent the block from crashing, we need to limit ourselves to the
- // posts returned by the backend - so if we want 6 posts, but only 3 are
- // returned, we need to limit ourselves to those 3 and fill in the rest
- // with placeholders.
- //
- // Also, if the site does not have sufficient posts to display related ones
- // (minimum 10 posts), we also use this code block to fill in the
- // placeholders.
- const previewClassName = 'jp-relatedposts-i2';
- const displayPosts = [];
- for ( let i = 0; i < postsToShow; i++ ) {
- if ( posts[ i ] ) {
- displayPosts.push(
- <RelatedPostsEditItem
- id={ `related-posts-${ instanceId }-post-${ i }` }
- key={ previewClassName + '-' + i }
- post={ posts[ i ] }
- displayThumbnails={ displayThumbnails }
- displayDate={ displayDate }
- displayContext={ displayContext }
- />
- );
- } else {
- displayPosts.push(
- <PlaceholderPostEdit
- id={ `related-posts-${ instanceId }-post-${ i }` }
- key={ 'related-post-placeholder-' + i }
- displayThumbnails={ displayThumbnails }
- displayDate={ displayDate }
- displayContext={ displayContext }
- />
- );
- }
- }
-
- return (
- <Fragment>
- <InspectorControls>
- <PanelBody title={ __( 'Related Posts Settings', 'jetpack' ) }>
- <ToggleControl
- label={ __( 'Display thumbnails', 'jetpack' ) }
- checked={ displayThumbnails }
- onChange={ value => setAttributes( { displayThumbnails: value } ) }
- />
- <ToggleControl
- label={ __( 'Display date', 'jetpack' ) }
- checked={ displayDate }
- onChange={ value => setAttributes( { displayDate: value } ) }
- />
- <ToggleControl
- label={ __( 'Display context (category or tag)', 'jetpack' ) }
- checked={ displayContext }
- onChange={ value => setAttributes( { displayContext: value } ) }
- />
- <RangeControl
- label={ __( 'Number of posts', 'jetpack' ) }
- value={ postsToShow }
- onChange={ value =>
- setAttributes( { postsToShow: Math.min( value, MAX_POSTS_TO_SHOW ) } )
- }
- min={ 1 }
- max={ MAX_POSTS_TO_SHOW }
- />
- </PanelBody>
- </InspectorControls>
-
- <BlockControls>
- <Toolbar controls={ layoutControls } />
- </BlockControls>
-
- <div className={ className } id={ `related-posts-${ instanceId }` }>
- <div className={ previewClassName } data-layout={ postLayout }>
- <RelatedPostsPreviewRows posts={ displayPosts } />
- </div>
- </div>
- </Fragment>
- );
- }
-}
-
-export default compose(
- withInstanceId,
- withSelect( select => {
- const { getCurrentPost } = select( 'core/editor' );
- const posts = get( getCurrentPost(), 'jetpack-related-posts', [] );
-
- return {
- posts,
- };
- } )
-)( RelatedPostsEdit );
diff --git a/plugins/jetpack/extensions/blocks/related-posts/editor.js b/plugins/jetpack/extensions/blocks/related-posts/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/related-posts/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/related-posts/index.js b/plugins/jetpack/extensions/blocks/related-posts/index.js
deleted file mode 100644
index c9f01c58..00000000
--- a/plugins/jetpack/extensions/blocks/related-posts/index.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { G, Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import './style.scss';
-
-export const name = 'related-posts';
-
-export const settings = {
- title: __( 'Related Posts', 'jetpack' ),
-
- icon: (
- <SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
- <G stroke="currentColor" strokeWidth="2" strokeLinecap="square">
- <Path d="M4,4 L4,19 M4,4 L19,4 M4,9 L19,9 M4,14 L19,14 M4,19 L19,19 M9,4 L9,19 M19,4 L19,19" />
- </G>
- </SVG>
- ),
-
- category: 'jetpack',
-
- keywords: [
- _x( 'Similar content', 'block search term', 'jetpack' ),
- _x( 'Linked', 'block search term', 'jetpack' ),
- _x( 'Connected', 'block search term', 'jetpack' ),
- ],
-
- attributes: {
- postLayout: {
- type: 'string',
- default: 'grid',
- },
- displayDate: {
- type: 'boolean',
- default: true,
- },
- displayThumbnails: {
- type: 'boolean',
- default: false,
- },
- displayContext: {
- type: 'boolean',
- default: false,
- },
- postsToShow: {
- type: 'number',
- default: 3,
- },
- },
-
- supports: {
- html: false,
- multiple: false,
- reusable: false,
- },
-
- transforms: {
- from: [
- {
- type: 'shortcode',
- tag: 'jetpack-related-posts',
- },
- ],
- },
-
- edit,
-
- save: () => null,
-};
diff --git a/plugins/jetpack/extensions/blocks/related-posts/style.scss b/plugins/jetpack/extensions/blocks/related-posts/style.scss
deleted file mode 100644
index bc753513..00000000
--- a/plugins/jetpack/extensions/blocks/related-posts/style.scss
+++ /dev/null
@@ -1,85 +0,0 @@
-.jp-related-posts-i2 {
- &__row {
- display: flex;
- margin-top: 1.5rem;
-
- &:first-child {
- margin-top: 0;
- }
-
- &[data-post-count='3'] .jp-related-posts-i2__post {
- max-width: calc( 33% - 20px );
- }
-
- &[data-post-count='2'] .jp-related-posts-i2__post,
- &[data-post-count='1'] .jp-related-posts-i2__post {
- max-width: calc( 50% - 20px );
- }
- }
-
- &__post {
- flex-grow: 1;
- flex-basis: 0;
- margin: 0 10px;
- display: flex;
- flex-direction: column;
- }
-
- &__post-heading, &__post-img-link, &__post-date, &__post-context {
- flex-direction: row;
- }
-
- &__post-img-link, &__post-image-placeholder {
- order: -1;
- }
-
- &__post-heading {
- margin: 0.5rem 0;
- font-size: 1rem;
- line-height: 1.2em;
- }
-
- &__post-link {
- display: block;
- width: 100%;
- line-height: 1.2em;
- margin: 0.2em 0;
- }
-
- &__post-img {
- width: 100%;
- }
-
- &__post-image-placeholder {
- display: block;
- position: relative;
- margin: 0 auto;
- max-width: 350px;
- &-icon {
- position: absolute;
- top: calc( 50% - 12px );
- left: calc( 50% - 12px );
- }
- }
-}
-
-/* List view */
-
-.jp-relatedposts-i2[data-layout='list'] {
- .jp-related-posts-i2__row {
- margin-top: 0;
- display: block;
- }
- .jp-related-posts-i2__post {
- max-width: none;
- margin: 0;
- margin-top: 1rem;
- }
- .jp-related-posts-i2__post-image-placeholder {
- max-width: 350px;
- margin: 0;
- }
- .jp-related-posts-i2__post-img-link {
- margin-top: 1rem;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/components/edit.js b/plugins/jetpack/extensions/blocks/repeat-visitor/components/edit.js
deleted file mode 100644
index ff954162..00000000
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/components/edit.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _n, sprintf } from '@wordpress/i18n';
-import { Notice, TextControl, RadioControl, Placeholder } from '@wordpress/components';
-import { Component } from '@wordpress/element';
-import { InnerBlocks } from '@wordpress/editor';
-import { withSelect } from '@wordpress/data';
-import classNames from 'classnames';
-
-/**
- * Internal dependencies
- */
-import { CRITERIA_AFTER, CRITERIA_BEFORE } from '../constants';
-import { icon } from '../index';
-
-const RADIO_OPTIONS = [
- {
- value: CRITERIA_AFTER,
- label: __( 'Show after threshold', 'jetpack' ),
- },
- {
- value: CRITERIA_BEFORE,
- label: __( 'Show before threshold', 'jetpack' ),
- },
-];
-
-class RepeatVisitorEdit extends Component {
- state = {
- isThresholdValid: true,
- };
-
- setCriteria = criteria => this.props.setAttributes( { criteria } );
- setThreshold = threshold => {
- if ( /^\d+$/.test( threshold ) && +threshold > 0 ) {
- this.props.setAttributes( { threshold: +threshold } );
- this.setState( { isThresholdValid: true } );
- return;
- }
- this.setState( { isThresholdValid: false } );
- };
-
- getNoticeLabel() {
- if ( this.props.attributes.criteria === CRITERIA_AFTER ) {
- return sprintf(
- _n(
- 'This block will only appear to people who have visited this page more than once.',
- 'This block will only appear to people who have visited this page more than %d times.',
- +this.props.attributes.threshold,
- 'jetpack'
- ),
- this.props.attributes.threshold
- );
- }
-
- return sprintf(
- _n(
- 'This block will only appear to people who are visiting this page for the first time.',
- 'This block will only appear to people who have visited this page at most %d times.',
- +this.props.attributes.threshold,
- 'jetpack'
- ),
- this.props.attributes.threshold
- );
- }
-
- render() {
- return (
- <div
- className={ classNames( this.props.className, {
- 'wp-block-jetpack-repeat-visitor--is-unselected': ! this.props.isSelected,
- } ) }
- >
- <Placeholder
- icon={ icon }
- label={ __( 'Repeat Visitor', 'jetpack' ) }
- className="wp-block-jetpack-repeat-visitor-placeholder"
- >
- <TextControl
- className="wp-block-jetpack-repeat-visitor-threshold"
- defaultValue={ this.props.attributes.threshold }
- help={
- this.state.isThresholdValid ? '' : __( 'Please enter a valid number.', 'jetpack' )
- }
- label={ __( 'Visit count threshold', 'jetpack' ) }
- min="1"
- onChange={ this.setThreshold }
- pattern="[0-9]"
- type="number"
- />
-
- <RadioControl
- label={ __( 'Visibility', 'jetpack' ) }
- selected={ this.props.attributes.criteria }
- options={ RADIO_OPTIONS }
- onChange={ this.setCriteria }
- />
- </Placeholder>
-
- <Notice status="info" isDismissible={ false }>
- { this.getNoticeLabel() }
- </Notice>
- <InnerBlocks />
- </div>
- );
- }
-}
-
-export default withSelect( ( select, ownProps ) => {
- const { isBlockSelected, hasSelectedInnerBlock } = select( 'core/editor' );
- return {
- isSelected: isBlockSelected( ownProps.clientId ) || hasSelectedInnerBlock( ownProps.clientId ),
- };
-} )( RepeatVisitorEdit );
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/components/save.js b/plugins/jetpack/extensions/blocks/repeat-visitor/components/save.js
deleted file mode 100644
index 7484c06d..00000000
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/components/save.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * External dependencies
- */
-import { InnerBlocks } from '@wordpress/editor';
-
-export default ( { className } ) => {
- return (
- <div className={ className }>
- <InnerBlocks.Content />
- </div>
- );
-};
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/constants.js b/plugins/jetpack/extensions/blocks/repeat-visitor/constants.js
deleted file mode 100644
index 09f459d2..00000000
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/constants.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export const CRITERIA_AFTER = 'after-visits';
-export const CRITERIA_BEFORE = 'before-visits';
-export const DEFAULT_THRESHOLD = 3;
-export const COOKIE_NAME = 'jp-visit-counter';
-export const MAX_COOKIE_AGE = 6 * 30 * 24 * 60 * 60; // 6 months
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/editor.js b/plugins/jetpack/extensions/blocks/repeat-visitor/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/editor.scss b/plugins/jetpack/extensions/blocks/repeat-visitor/editor.scss
deleted file mode 100644
index 6a4dd9a5..00000000
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/editor.scss
+++ /dev/null
@@ -1,55 +0,0 @@
-.wp-block-jetpack-repeat-visitor {
- .components-notice {
- margin: 1em 0 0;
- }
- .components-radio-control__option {
- text-align: left;
- }
- .components-notice__content {
- margin: 0.5em 0;
- font-size: 0.8em;
-
- .components-base-control {
- display: inline-block;
- max-width: 8em;
- vertical-align: middle;
-
- .components-base-control__field {
- margin-bottom: 0;
- }
- }
- }
-}
-
-.wp-block-jetpack-repeat-visitor-placeholder {
- min-height: inherit;
-
- .components-placeholder__label svg {
- margin-right: 0.5ch;
- }
-
- .components-placeholder__fieldset {
- flex-wrap: nowrap;
- .components-base-control {
- flex-basis: 100%;
- }
- }
-
- .components-base-control__help {
- color: var( --muriel-hot-red-500 );
- font-size: 13px;
- }
-}
-
-.wp-block-jetpack-repeat-visitor--is-unselected .wp-block-jetpack-repeat-visitor-placeholder {
- display: none;
-}
-
-.wp-block-jetpack-repeat-visitor-threshold {
- margin-right: 20px;
-
- .components-text-control__input {
- width: 5em;
- text-align: center;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/index.js b/plugins/jetpack/extensions/blocks/repeat-visitor/index.js
deleted file mode 100644
index 067c1177..00000000
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import renderMaterialIcon from '../../shared/render-material-icon';
-import edit from './components/edit';
-import save from './components/save';
-import { CRITERIA_AFTER, DEFAULT_THRESHOLD } from './constants';
-import './editor.scss';
-
-export const name = 'repeat-visitor';
-export const icon = renderMaterialIcon(
- <Path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z" />
-);
-export const settings = {
- attributes: {
- criteria: {
- type: 'string',
- default: CRITERIA_AFTER,
- },
- threshold: {
- type: 'number',
- default: DEFAULT_THRESHOLD,
- },
- },
- category: 'jetpack',
- description: __(
- 'Control block visibility based on how often a visitor has viewed the page.',
- 'jetpack'
- ),
- icon,
- keywords: [
- _x( 'return', 'block search term', 'jetpack' ),
- _x( 'visitors', 'block search term', 'jetpack' ),
- _x( 'visibility', 'block search term', 'jetpack' ),
- ],
- supports: { html: false },
- title: __( 'Repeat Visitor', 'jetpack' ),
- edit,
- save,
-};
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/repeat-visitor.php b/plugins/jetpack/extensions/blocks/repeat-visitor/repeat-visitor.php
index ccde0648..2facf626 100644
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/repeat-visitor.php
+++ b/plugins/jetpack/extensions/blocks/repeat-visitor/repeat-visitor.php
@@ -25,6 +25,8 @@ jetpack_register_block(
function jetpack_repeat_visitor_block_render( $attributes, $content ) {
Jetpack_Gutenberg::load_assets_as_required( 'repeat-visitor' );
+ $classes = Jetpack_Gutenberg::block_classes( 'repeat-visitor', $attributes );
+
$count = isset( $_COOKIE['jp-visit-counter'] ) ? intval( $_COOKIE['jp-visit-counter'] ) : 0;
$criteria = isset( $attributes['criteria'] ) ? $attributes['criteria'] : 'after-visits';
$threshold = isset( $attributes['threshold'] ) ? intval( $attributes['threshold'] ) : 3;
@@ -37,5 +39,5 @@ function jetpack_repeat_visitor_block_render( $attributes, $content ) {
}
// return an empty div so that view script increments the visit counter in the cookie.
- return '<div class="wp-block-jetpack-repeat-visitor"></div>';
+ return '<div class="' . esc_attr( $classes ) . '"></div>';
}
diff --git a/plugins/jetpack/extensions/blocks/repeat-visitor/view.js b/plugins/jetpack/extensions/blocks/repeat-visitor/view.js
deleted file mode 100644
index 0273932c..00000000
--- a/plugins/jetpack/extensions/blocks/repeat-visitor/view.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * External dependencies
- */
-import cookie from 'cookie';
-
-/**
- * Internal dependencies
- */
-import { COOKIE_NAME, MAX_COOKIE_AGE } from './constants';
-
-function getViewCount() {
- const cookies = cookie.parse( document.cookie );
- const value = cookies[ COOKIE_NAME ] || 0;
- return +value;
-}
-
-function setViewCount( value ) {
- document.cookie = cookie.serialize( COOKIE_NAME, value, {
- path: window.location.pathname,
- maxAge: MAX_COOKIE_AGE,
- } );
-}
-
-function incrementCookieValue() {
- const repeatVisitorBlocks = Array.from(
- document.querySelectorAll( '.wp-block-jetpack-repeat-visitor' )
- );
- if ( repeatVisitorBlocks.length === 0 ) {
- return;
- }
-
- setViewCount( getViewCount() + 1 );
-}
-
-window && window.addEventListener( 'load', incrementCookieValue );
diff --git a/plugins/jetpack/extensions/blocks/seo/editor.js b/plugins/jetpack/extensions/blocks/seo/editor.js
deleted file mode 100644
index 9adee220..00000000
--- a/plugins/jetpack/extensions/blocks/seo/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../shared/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/seo/editor.scss b/plugins/jetpack/extensions/blocks/seo/editor.scss
deleted file mode 100644
index 70c801d2..00000000
--- a/plugins/jetpack/extensions/blocks/seo/editor.scss
+++ /dev/null
@@ -1,15 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.jetpack-seo-message-box {
- background-color: $light-gray-300;
- border-radius: 4px;
-}
-
-.jetpack-seo-message-box textarea {
- width: 100%;
-}
-
-.jetpack-seo-character-count {
- padding-bottom: 5px;
- padding-left: 5px;
-}
diff --git a/plugins/jetpack/extensions/blocks/seo/index.js b/plugins/jetpack/extensions/blocks/seo/index.js
deleted file mode 100644
index 98bdca97..00000000
--- a/plugins/jetpack/extensions/blocks/seo/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Fragment } from '@wordpress/element';
-import { PanelBody } from '@wordpress/components';
-import { PluginPrePublishPanel } from '@wordpress/edit-post';
-
-/**
- * Internal dependencies
- */
-import './editor.scss';
-import JetpackPluginSidebar from '../../shared/jetpack-plugin-sidebar';
-import SeoPanel from './panel';
-
-export const name = 'seo';
-
-export const settings = {
- render: () => (
- <Fragment>
- <JetpackPluginSidebar>
- <PanelBody title={ __( 'SEO Description', 'jetpack' ) }>
- <SeoPanel />
- </PanelBody>
- </JetpackPluginSidebar>
- <PluginPrePublishPanel
- initialOpen
- id="seo-title"
- title={
- <span id="seo-defaults" key="seo-title-span">
- { __( 'SEO Description', 'jetpack' ) }
- </span>
- }
- >
- <SeoPanel />
- </PluginPrePublishPanel>
- </Fragment>
- ),
-};
diff --git a/plugins/jetpack/extensions/blocks/seo/panel.js b/plugins/jetpack/extensions/blocks/seo/panel.js
deleted file mode 100644
index 38496052..00000000
--- a/plugins/jetpack/extensions/blocks/seo/panel.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _n, sprintf } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import { get } from 'lodash';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-class SeoPanel extends Component {
- onMessageChange = event => {
- this.props.updateSeoDescription( event.target.value );
- };
-
- render() {
- const { seoDescription } = this.props;
-
- return (
- <div className="jetpack-seo-message-box">
- <textarea
- value={ seoDescription }
- onChange={ this.onMessageChange }
- placeholder={ __( 'Write a description…', 'jetpack' ) }
- rows={ 4 }
- />
- <div className="jetpack-seo-character-count">
- { sprintf(
- _n( '%d character', '%d characters', seoDescription.length, 'jetpack' ),
- seoDescription.length
- ) }
- </div>
- </div>
- );
- }
-}
-
-export default compose( [
- withSelect( select => ( {
- seoDescription: get(
- select( 'core/editor' ).getEditedPostAttribute( 'meta' ),
- [ 'advanced_seo_description' ],
- ''
- ),
- } ) ),
- withDispatch( dispatch => ( {
- updateSeoDescription( seoDescription ) {
- dispatch( 'core/editor' ).editPost( {
- meta: {
- advanced_seo_description: seoDescription,
- },
- } );
- },
- } ) ),
-] )( SeoPanel );
diff --git a/plugins/jetpack/extensions/blocks/sharing/editor.js b/plugins/jetpack/extensions/blocks/sharing/editor.js
deleted file mode 100644
index 9adee220..00000000
--- a/plugins/jetpack/extensions/blocks/sharing/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../shared/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/sharing/index.js b/plugins/jetpack/extensions/blocks/sharing/index.js
deleted file mode 100644
index 7f1e0df2..00000000
--- a/plugins/jetpack/extensions/blocks/sharing/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Internal dependencies
- */
-import SharingCheckbox from './sharing-checkbox';
-
-export const name = 'sharing';
-
-export const settings = { render: SharingCheckbox };
diff --git a/plugins/jetpack/extensions/blocks/sharing/sharing-checkbox.js b/plugins/jetpack/extensions/blocks/sharing/sharing-checkbox.js
deleted file mode 100644
index dfe1e6c5..00000000
--- a/plugins/jetpack/extensions/blocks/sharing/sharing-checkbox.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { CheckboxControl } from '@wordpress/components';
-import { compose } from '@wordpress/compose';
-import { PostTypeSupportCheck } from '@wordpress/editor';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import JetpackLikesAndSharingPanel from '../../shared/jetpack-likes-and-sharing-panel';
-
-const SharingCheckbox = ( { isSharingEnabled, editPost } ) => (
- <PostTypeSupportCheck supportKeys="jetpack-sharing-buttons">
- <JetpackLikesAndSharingPanel>
- <CheckboxControl
- label={ __( 'Show sharing buttons.', 'jetpack' ) }
- checked={ isSharingEnabled }
- onChange={ value => {
- editPost( { jetpack_sharing_enabled: value } );
- } }
- />
- </JetpackLikesAndSharingPanel>
- </PostTypeSupportCheck>
-);
-
-// Fetch the post meta.
-const applyWithSelect = withSelect( select => {
- const { getEditedPostAttribute } = select( 'core/editor' );
- const isSharingEnabled = getEditedPostAttribute( 'jetpack_sharing_enabled' );
-
- return { isSharingEnabled };
-} );
-
-// Provide method to update post meta.
-const applyWithDispatch = withDispatch( dispatch => {
- const { editPost } = dispatch( 'core/editor' );
-
- return { editPost };
-} );
-
-// Combine the higher-order components.
-export default compose( [ applyWithSelect, applyWithDispatch ] )( SharingCheckbox );
diff --git a/plugins/jetpack/extensions/blocks/shortlinks/editor.js b/plugins/jetpack/extensions/blocks/shortlinks/editor.js
deleted file mode 100644
index 9adee220..00000000
--- a/plugins/jetpack/extensions/blocks/shortlinks/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../shared/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/shortlinks/index.js b/plugins/jetpack/extensions/blocks/shortlinks/index.js
deleted file mode 100644
index 16d9b8b7..00000000
--- a/plugins/jetpack/extensions/blocks/shortlinks/index.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { get } from 'lodash';
-import { PanelBody } from '@wordpress/components';
-import { withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import ClipboardInput from '../../shared/clipboard-input';
-import JetpackPluginSidebar from '../../shared/jetpack-plugin-sidebar';
-
-export const name = 'shortlinks';
-
-export const settings = {
- render: () => <Shortlinks />,
-};
-
-class ShortlinksPanel extends Component {
- render() {
- const { shortlink } = this.props;
-
- if ( ! shortlink ) {
- return null;
- }
-
- return (
- <JetpackPluginSidebar>
- <PanelBody title={ __( 'Shortlink', 'jetpack' ) } className="jetpack-shortlinks__panel">
- <ClipboardInput link={ shortlink } />
- </PanelBody>
- </JetpackPluginSidebar>
- );
- }
-}
-
-const Shortlinks = withSelect( select => {
- const currentPost = select( 'core/editor' ).getCurrentPost();
- return {
- shortlink: get( currentPost, 'jetpack_shortlink', '' ),
- };
-} )( ShortlinksPanel );
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/constants.js b/plugins/jetpack/extensions/blocks/simple-payments/constants.js
deleted file mode 100644
index e593f947..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/constants.js
+++ /dev/null
@@ -1,39 +0,0 @@
-export const SIMPLE_PAYMENTS_PRODUCT_POST_TYPE = 'jp_pay_product';
-
-export const DEFAULT_CURRENCY = 'USD';
-
-// https://developer.paypal.com/docs/integration/direct/rest/currency-codes/
-// If this list changes, Simple Payments in Jetpack must be updated as well.
-// See https://github.com/Automattic/jetpack/blob/master/modules/simple-payments/simple-payments.php
-
-/**
- * Indian Rupee not supported because at the time of the creation of this file
- * because it's limited to in-country PayPal India accounts only.
- * Discussion: https://github.com/Automattic/wp-calypso/pull/28236
- */
-export const SUPPORTED_CURRENCY_LIST = [
- DEFAULT_CURRENCY,
- 'EUR',
- 'AUD',
- 'BRL',
- 'CAD',
- 'CZK',
- 'DKK',
- 'HKD',
- 'HUF',
- 'ILS',
- 'JPY',
- 'MYR',
- 'MXN',
- 'TWD',
- 'NZD',
- 'NOK',
- 'PHP',
- 'PLN',
- 'GBP',
- 'RUB',
- 'SGD',
- 'SEK',
- 'CHF',
- 'THB',
-];
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/edit.js b/plugins/jetpack/extensions/blocks/simple-payments/edit.js
deleted file mode 100644
index f49ca94d..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/edit.js
+++ /dev/null
@@ -1,579 +0,0 @@
-/**
- * External dependencies
- */
-import classNames from 'classnames';
-import emailValidator from 'email-validator';
-import { __, _n, sprintf } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { compose, withInstanceId } from '@wordpress/compose';
-import { dispatch, withSelect } from '@wordpress/data';
-import { get, isEmpty, isEqual, pick, trimEnd } from 'lodash';
-import { getCurrencyDefaults } from '@automattic/format-currency';
-import {
- Disabled,
- ExternalLink,
- SelectControl,
- TextareaControl,
- TextControl,
- ToggleControl,
-} from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import HelpMessage from './help-message';
-import ProductPlaceholder from './product-placeholder';
-import FeaturedMedia from './featured-media';
-import { decimalPlaces, formatPrice } from './utils';
-import { SIMPLE_PAYMENTS_PRODUCT_POST_TYPE, SUPPORTED_CURRENCY_LIST } from './constants';
-
-class SimplePaymentsEdit extends Component {
- state = {
- fieldEmailError: null,
- fieldPriceError: null,
- fieldTitleError: null,
- isSavingProduct: false,
- };
-
- /**
- * We'll use this flag to inject attributes one time when the product entity is loaded.
- *
- * It is based on the presence of a `productId` attribute.
- *
- * If present, initially we are waiting for attributes to be injected.
- * If absent, we may save the product in the future but do not need to inject attributes based
- * on the response as they will have come from our product submission.
- */
- shouldInjectPaymentAttributes = !! this.props.attributes.productId;
-
- componentDidMount() {
- // Try to get the simplePayment loaded into attributes if possible.
- this.injectPaymentAttributes();
-
- const { attributes, hasPublishAction } = this.props;
- const { productId } = attributes;
-
- // If the user can publish save an empty product so that we have an ID and can save
- // concurrently with the post that contains the Simple Payment.
- if ( ! productId && hasPublishAction ) {
- this.saveProduct();
- }
- }
-
- componentDidUpdate( prevProps ) {
- const { hasPublishAction, isSelected } = this.props;
-
- if ( ! isEqual( prevProps.simplePayment, this.props.simplePayment ) ) {
- this.injectPaymentAttributes();
- }
-
- if (
- ! prevProps.isSaving &&
- this.props.isSaving &&
- hasPublishAction &&
- this.validateAttributes()
- ) {
- // Validate and save product on post save
- this.saveProduct();
- } else if ( prevProps.isSelected && ! isSelected ) {
- // Validate on block deselect
- this.validateAttributes();
- }
- }
-
- injectPaymentAttributes() {
- /**
- * Prevent injecting the product attributes when not desired.
- *
- * When we first load a product, we should inject its attributes as our initial form state.
- * When subsequent saves occur, we should avoid injecting attributes so that we do not
- * overwrite changes that the user has made with stale state from the previous save.
- */
-
- const { simplePayment } = this.props;
- if ( ! this.shouldInjectPaymentAttributes || isEmpty( simplePayment ) ) {
- return;
- }
-
- const { attributes, setAttributes } = this.props;
- const { content, currency, email, featuredMediaId, multiple, price, title } = attributes;
-
- setAttributes( {
- content: get( simplePayment, [ 'content', 'raw' ], content ),
- currency: get( simplePayment, [ 'meta', 'spay_currency' ], currency ),
- email: get( simplePayment, [ 'meta', 'spay_email' ], email ),
- featuredMediaId: get( simplePayment, [ 'featured_media' ], featuredMediaId ),
- multiple: Boolean( get( simplePayment, [ 'meta', 'spay_multiple' ], Boolean( multiple ) ) ),
- price: get( simplePayment, [ 'meta', 'spay_price' ], price || undefined ),
- title: get( simplePayment, [ 'title', 'raw' ], title ),
- } );
-
- this.shouldInjectPaymentAttributes = ! this.shouldInjectPaymentAttributes;
- }
-
- toApi() {
- const { attributes } = this.props;
- const {
- content,
- currency,
- email,
- featuredMediaId,
- multiple,
- price,
- productId,
- title,
- } = attributes;
-
- return {
- id: productId,
- content,
- featured_media: featuredMediaId,
- meta: {
- spay_currency: currency,
- spay_email: email,
- spay_multiple: multiple,
- spay_price: price,
- },
- status: productId ? 'publish' : 'draft',
- title,
- };
- }
-
- saveProduct() {
- if ( this.state.isSavingProduct ) {
- return;
- }
-
- const { attributes, setAttributes } = this.props;
- const { email } = attributes;
- const { saveEntityRecord } = dispatch( 'core' );
-
- this.setState( { isSavingProduct: true }, () => {
- saveEntityRecord( 'postType', SIMPLE_PAYMENTS_PRODUCT_POST_TYPE, this.toApi() )
- .then( record => {
- if ( record ) {
- setAttributes( { productId: record.id } );
- }
-
- return record;
- } )
- .catch( error => {
- // Nothing we can do about errors without details at the moment
- if ( ! error || ! error.data ) {
- return;
- }
-
- const {
- data: { key: apiErrorKey },
- } = error;
-
- // @TODO errors in other fields
- this.setState( {
- fieldEmailError:
- apiErrorKey === 'spay_email'
- ? sprintf( __( '%s is not a valid email address.', 'jetpack' ), email )
- : null,
- fieldPriceError:
- apiErrorKey === 'spay_price' ? __( 'Invalid price.', 'jetpack' ) : null,
- } );
- } )
- .finally( () => {
- this.setState( {
- isSavingProduct: false,
- } );
- } );
- } );
- }
-
- validateAttributes = () => {
- const isPriceValid = this.validatePrice();
- const isTitleValid = this.validateTitle();
- const isEmailValid = this.validateEmail();
- const isCurrencyValid = this.validateCurrency();
-
- return isPriceValid && isTitleValid && isEmailValid && isCurrencyValid;
- };
-
- /**
- * Validate currency
- *
- * This method does not include validation UI. Currency selection should not allow for invalid
- * values. It is primarily to ensure that the currency is valid to save.
- *
- * @return {boolean} True if currency is valid
- */
- validateCurrency = () => {
- const { currency } = this.props.attributes;
- return SUPPORTED_CURRENCY_LIST.includes( currency );
- };
-
- /**
- * Validate price
- *
- * Stores error message in state.fieldPriceError
- *
- * @returns {Boolean} True when valid, false when invalid
- */
- validatePrice = () => {
- const { currency, price } = this.props.attributes;
- const { precision } = getCurrencyDefaults( currency );
-
- if ( ! price || parseFloat( price ) === 0 ) {
- this.setState( {
- fieldPriceError: __(
- 'If you’re selling something, you need a price tag. Add yours here.',
- 'jetpack'
- ),
- } );
- return false;
- }
-
- if ( Number.isNaN( parseFloat( price ) ) ) {
- this.setState( {
- fieldPriceError: __( 'Invalid price', 'jetpack' ),
- } );
- return false;
- }
-
- if ( parseFloat( price ) < 0 ) {
- this.setState( {
- fieldPriceError: __(
- 'Your price is negative — enter a positive number so people can pay the right amount.',
- 'jetpack'
- ),
- } );
- return false;
- }
-
- if ( decimalPlaces( price ) > precision ) {
- if ( precision === 0 ) {
- this.setState( {
- fieldPriceError: __(
- 'We know every penny counts, but prices in this currency can’t contain decimal values.',
- 'jetpack'
- ),
- } );
- return false;
- }
-
- this.setState( {
- fieldPriceError: sprintf(
- _n(
- 'The price cannot have more than %d decimal place.',
- 'The price cannot have more than %d decimal places.',
- precision,
- 'jetpack'
- ),
- precision
- ),
- } );
- return false;
- }
-
- if ( this.state.fieldPriceError ) {
- this.setState( { fieldPriceError: null } );
- }
-
- return true;
- };
-
- /**
- * Validate email
- *
- * Stores error message in state.fieldEmailError
- *
- * @returns {Boolean} True when valid, false when invalid
- */
- validateEmail = () => {
- const { email } = this.props.attributes;
- if ( ! email ) {
- this.setState( {
- fieldEmailError: __(
- 'We want to make sure payments reach you, so please add an email address.',
- 'jetpack'
- ),
- } );
- return false;
- }
-
- if ( ! emailValidator.validate( email ) ) {
- this.setState( {
- fieldEmailError: sprintf( __( '%s is not a valid email address.', 'jetpack' ), email ),
- } );
- return false;
- }
-
- if ( this.state.fieldEmailError ) {
- this.setState( { fieldEmailError: null } );
- }
-
- return true;
- };
-
- /**
- * Validate title
- *
- * Stores error message in state.fieldTitleError
- *
- * @returns {Boolean} True when valid, false when invalid
- */
- validateTitle = () => {
- const { title } = this.props.attributes;
- if ( ! title ) {
- this.setState( {
- fieldTitleError: __(
- 'Please add a brief title so that people know what they’re paying for.',
- 'jetpack'
- ),
- } );
- return false;
- }
-
- if ( this.state.fieldTitleError ) {
- this.setState( { fieldTitleError: null } );
- }
-
- return true;
- };
-
- handleEmailChange = email => {
- this.props.setAttributes( { email } );
- this.setState( { fieldEmailError: null } );
- };
-
- handleFeaturedMediaSelect = media => {
- this.props.setAttributes( { featuredMediaId: get( media, 'id', 0 ) } );
- };
-
- handleContentChange = content => {
- this.props.setAttributes( { content } );
- };
-
- handlePriceChange = price => {
- price = parseFloat( price );
- if ( ! isNaN( price ) ) {
- this.props.setAttributes( { price } );
- } else {
- this.props.setAttributes( { price: undefined } );
- }
- this.setState( { fieldPriceError: null } );
- };
-
- handleCurrencyChange = currency => {
- this.props.setAttributes( { currency } );
- };
-
- handleMultipleChange = multiple => {
- this.props.setAttributes( { multiple: !! multiple } );
- };
-
- handleTitleChange = title => {
- this.props.setAttributes( { title } );
- this.setState( { fieldTitleError: null } );
- };
-
- getCurrencyList = SUPPORTED_CURRENCY_LIST.map( value => {
- const { symbol } = getCurrencyDefaults( value );
- // if symbol is equal to the code (e.g., 'CHF' === 'CHF'), don't duplicate it.
- // trim the dot at the end, e.g., 'kr.' becomes 'kr'
- const label = symbol === value ? value : `${ value } ${ trimEnd( symbol, '.' ) }`;
- return { value, label };
- } );
-
- render() {
- const { fieldEmailError, fieldPriceError, fieldTitleError } = this.state;
- const {
- attributes,
- featuredMedia,
- instanceId,
- isSelected,
- setAttributes,
- simplePayment,
- } = this.props;
- const {
- content,
- currency,
- email,
- featuredMediaId,
- featuredMediaUrl: featuredMediaUrlAttribute,
- featuredMediaTitle: featuredMediaTitleAttribute,
- multiple,
- price,
- productId,
- title,
- } = attributes;
-
- const featuredMediaUrl =
- featuredMediaUrlAttribute || ( featuredMedia && featuredMedia.source_url );
- const featuredMediaTitle =
- featuredMediaTitleAttribute || ( featuredMedia && featuredMedia.alt_text );
-
- /**
- * The only disabled state that concerns us is when we expect a product but don't have it in
- * local state.
- */
- const isDisabled = productId && isEmpty( simplePayment );
-
- if ( ! isSelected && isDisabled ) {
- return (
- <div className="simple-payments__loading">
- <ProductPlaceholder
- aria-busy="true"
- content="█████"
- formattedPrice="█████"
- title="█████"
- />
- </div>
- );
- }
-
- if (
- ! isSelected &&
- email &&
- price &&
- title &&
- ! fieldEmailError &&
- ! fieldPriceError &&
- ! fieldTitleError
- ) {
- return (
- <ProductPlaceholder
- aria-busy="false"
- content={ content }
- featuredMediaUrl={ featuredMediaUrl }
- featuredMediaTitle={ featuredMediaTitle }
- formattedPrice={ formatPrice( price, currency ) }
- multiple={ multiple }
- title={ title }
- />
- );
- }
-
- const Wrapper = isDisabled ? Disabled : 'div';
-
- return (
- <Wrapper className="wp-block-jetpack-simple-payments">
- <FeaturedMedia
- { ...{ featuredMediaId, featuredMediaUrl, featuredMediaTitle, setAttributes } }
- />
- <div>
- <TextControl
- aria-describedby={ `${ instanceId }-title-error` }
- className={ classNames( 'simple-payments__field', 'simple-payments__field-title', {
- 'simple-payments__field-has-error': fieldTitleError,
- } ) }
- label={ __( 'Item name', 'jetpack' ) }
- onChange={ this.handleTitleChange }
- placeholder={ __( 'Item name', 'jetpack' ) }
- required
- type="text"
- value={ title }
- />
- <HelpMessage id={ `${ instanceId }-title-error` } isError>
- { fieldTitleError }
- </HelpMessage>
-
- <TextareaControl
- className="simple-payments__field simple-payments__field-content"
- label={ __( 'Describe your item in a few words', 'jetpack' ) }
- onChange={ this.handleContentChange }
- placeholder={ __( 'Describe your item in a few words', 'jetpack' ) }
- value={ content }
- />
-
- <div className="simple-payments__price-container">
- <SelectControl
- className="simple-payments__field simple-payments__field-currency"
- label={ __( 'Currency', 'jetpack' ) }
- onChange={ this.handleCurrencyChange }
- options={ this.getCurrencyList }
- value={ currency }
- />
- <TextControl
- aria-describedby={ `${ instanceId }-price-error` }
- className={ classNames( 'simple-payments__field', 'simple-payments__field-price', {
- 'simple-payments__field-has-error': fieldPriceError,
- } ) }
- label={ __( 'Price', 'jetpack' ) }
- onChange={ this.handlePriceChange }
- placeholder={ formatPrice( 0, currency, false ) }
- required
- step="1"
- type="number"
- value={ price || '' }
- />
- <HelpMessage id={ `${ instanceId }-price-error` } isError>
- { fieldPriceError }
- </HelpMessage>
- </div>
-
- <div className="simple-payments__field-multiple">
- <ToggleControl
- checked={ Boolean( multiple ) }
- label={ __( 'Allow people to buy more than one item at a time', 'jetpack' ) }
- onChange={ this.handleMultipleChange }
- />
- </div>
-
- <TextControl
- aria-describedby={ `${ instanceId }-email-${ fieldEmailError ? 'error' : 'help' }` }
- className={ classNames( 'simple-payments__field', 'simple-payments__field-email', {
- 'simple-payments__field-has-error': fieldEmailError,
- } ) }
- label={ __( 'Email', 'jetpack' ) }
- onChange={ this.handleEmailChange }
- placeholder={ __( 'Email', 'jetpack' ) }
- required
- type="email"
- value={ email }
- />
- <HelpMessage id={ `${ instanceId }-email-error` } isError>
- { fieldEmailError }
- </HelpMessage>
- <HelpMessage id={ `${ instanceId }-email-help` }>
- { __(
- 'Enter the email address associated with your PayPal account. Don’t have an account?',
- 'jetpack'
- ) + ' ' }
- <ExternalLink href="https://www.paypal.com/">
- { __( 'Create one on PayPal', 'jetpack' ) }
- </ExternalLink>
- </HelpMessage>
- </div>
- </Wrapper>
- );
- }
-}
-
-const mapSelectToProps = withSelect( ( select, props ) => {
- const { getEntityRecord, getMedia } = select( 'core' );
- const { isSavingPost, getCurrentPost } = select( 'core/editor' );
-
- const { productId, featuredMediaId } = props.attributes;
-
- const fields = [
- [ 'content' ],
- [ 'meta', 'spay_currency' ],
- [ 'meta', 'spay_email' ],
- [ 'meta', 'spay_multiple' ],
- [ 'meta', 'spay_price' ],
- [ 'title', 'raw' ],
- [ 'featured_media' ],
- ];
-
- const simplePayment = productId
- ? pick( getEntityRecord( 'postType', SIMPLE_PAYMENTS_PRODUCT_POST_TYPE, productId ), fields )
- : undefined;
-
- return {
- hasPublishAction: !! get( getCurrentPost(), [ '_links', 'wp:action-publish' ] ),
- isSaving: !! isSavingPost(),
- simplePayment,
- featuredMedia: featuredMediaId ? getMedia( featuredMediaId ) : null,
- };
-} );
-
-export default compose(
- mapSelectToProps,
- withInstanceId
-)( SimplePaymentsEdit );
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/editor.js b/plugins/jetpack/extensions/blocks/simple-payments/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/editor.scss b/plugins/jetpack/extensions/blocks/simple-payments/editor.scss
deleted file mode 100644
index 3345a324..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/editor.scss
+++ /dev/null
@@ -1,63 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-@import '../../shared/styles/gutenberg-variables.scss';
-
-.wp-block-jetpack-simple-payments {
- font-family: $default-font;
- display: grid;
- grid-template-columns: 200px auto;
- grid-column-gap: 10px;
-
- .simple-payments__field {
- .components-base-control__label {
- display: none;
- }
- .components-base-control__field {
- margin-bottom: 1em;
- }
- // Reset empty space under textarea on Chrome
- textarea {
- display: block;
- }
- }
-
- .simple-payments__field-has-error {
- .components-text-control__input,
- .components-textarea-control__input {
- border-color: var( --color-error );
- }
- }
-
- .simple-payments__price-container {
- display: flex;
- flex-wrap: wrap;
- .simple-payments__field {
- margin-right: 10px;
- }
- .simple-payments__help-message {
- flex: 1 1 100%;
- margin-top: 0;
- }
- }
-
- .simple-payments__field-price {
- .components-text-control__input {
- max-width: 90px;
- }
- }
-
- .simple-payments__field-email {
- .components-text-control__input {
- max-width: 400px;
- }
- }
-
- .simple-payments__field-multiple {
- .components-toggle-control__label {
- line-height: 1.4em;
- }
- }
-
- .simple-payments__field-content .components-textarea-control__input {
- min-height: 32px;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/featured-media.js b/plugins/jetpack/extensions/blocks/simple-payments/featured-media.js
deleted file mode 100644
index c0da48a9..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/featured-media.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { BlockControls, MediaPlaceholder, MediaUpload } from '@wordpress/editor';
-import { Fragment } from '@wordpress/element';
-import { get } from 'lodash';
-import { IconButton, Toolbar, ToolbarButton } from '@wordpress/components';
-
-const onSelectMedia = setAttributes => media =>
- setAttributes( {
- featuredMediaId: get( media, 'id', 0 ),
- featuredMediaUrl: get( media, 'url', null ),
- featuredMediaTitle: get( media, 'title', null ),
- } );
-
-export default ( { featuredMediaId, featuredMediaUrl, featuredMediaTitle, setAttributes } ) => {
- if ( ! featuredMediaId ) {
- return (
- <MediaPlaceholder
- icon="format-image"
- labels={ {
- title: __( 'Product Image', 'jetpack' ),
- } }
- accept="image/*"
- allowedTypes={ [ 'image' ] }
- onSelect={ onSelectMedia( setAttributes ) }
- />
- );
- }
-
- return (
- <div>
- <Fragment>
- <BlockControls>
- <Toolbar>
- <MediaUpload
- onSelect={ onSelectMedia( setAttributes ) }
- allowedTypes={ [ 'image' ] }
- value={ featuredMediaId }
- render={ ( { open } ) => (
- <IconButton
- className="components-toolbar__control"
- label={ __( 'Edit Image', 'jetpack' ) }
- icon="edit"
- onClick={ open }
- />
- ) }
- />
- <ToolbarButton
- icon={ 'trash' }
- title={ __( 'Remove Image', 'jetpack' ) }
- onClick={ () =>
- setAttributes( {
- featuredMediaId: null,
- featuredMediaUrl: null,
- featuredMediaTitle: null,
- } )
- }
- />
- </Toolbar>
- </BlockControls>
- <figure>
- <img src={ featuredMediaUrl } alt={ featuredMediaTitle } />
- </figure>
- </Fragment>
- </div>
- );
-};
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/help-message.js b/plugins/jetpack/extensions/blocks/simple-payments/help-message.js
deleted file mode 100644
index 57a6e681..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/help-message.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * External dependencies
- */
-import classNames from 'classnames';
-
-/**
- * Internal dependencies
- */
-import GridiconNoticeOutline from 'gridicons/dist/notice-outline';
-import './help-message.scss';
-
-export default ( { children = null, isError = false, ...props } ) => {
- const classes = classNames( 'simple-payments__help-message', {
- 'simple-payments__help-message-is-error': isError,
- } );
-
- return (
- children && (
- <div className={ classes } { ...props }>
- { isError && <GridiconNoticeOutline size="24" /> }
- <span>{ children }</span>
- </div>
- )
- );
-};
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/help-message.scss b/plugins/jetpack/extensions/blocks/simple-payments/help-message.scss
deleted file mode 100644
index 86f50f9e..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/help-message.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-
-.wp-block-jetpack-simple-payments {
- .simple-payments__help-message {
- display: flex;
- font-size: 13px;
- line-height: 1.4em;
- margin-bottom: 1em;
- margin-top: -0.5em;
- svg {
- margin-right: 5px;
- min-width: 24px;
- }
- > span {
- margin-top: 2px;
- }
- &.simple-payments__help-message-is-error {
- color: var( --color-error );
- svg {
- fill: var( --color-error );
- }
- }
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/index.js b/plugins/jetpack/extensions/blocks/simple-payments/index.js
deleted file mode 100644
index a1f0e0ed..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/index.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { ExternalLink, Path, SVG } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import { DEFAULT_CURRENCY } from './constants';
-
-/**
- * Styles
- */
-import './editor.scss';
-
-export const name = 'simple-payments';
-
-export const settings = {
- title: __( 'Simple Payments button', 'jetpack' ),
-
- description: (
- <Fragment>
- <p>
- { __(
- 'Lets you create and embed credit and debit card payment buttons with minimal setup.',
- 'jetpack'
- ) }
- </p>
- <ExternalLink href="https://support.wordpress.com/simple-payments/">
- { __( 'Support reference', 'jetpack' ) }
- </ExternalLink>
- </Fragment>
- ),
-
- icon: (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z" />
- </SVG>
- ),
-
- category: 'jetpack',
-
- keywords: [
- _x( 'shop', 'block search term', 'jetpack' ),
- _x( 'sell', 'block search term', 'jetpack' ),
- 'PayPal',
- ],
-
- attributes: {
- currency: {
- type: 'string',
- default: DEFAULT_CURRENCY,
- },
- content: {
- type: 'string',
- default: '',
- },
- email: {
- type: 'string',
- default: '',
- },
- featuredMediaId: {
- type: 'number',
- default: 0,
- },
- featuredMediaUrl: {
- type: 'string',
- default: null,
- },
- featuredMediaTitle: {
- type: 'string',
- default: null,
- },
- multiple: {
- type: 'boolean',
- default: false,
- },
- price: {
- type: 'number',
- },
- productId: {
- type: 'number',
- },
- title: {
- type: 'string',
- default: '',
- },
- },
-
- transforms: {
- from: [
- {
- type: 'shortcode',
- tag: 'simple-payment',
- attributes: {
- productId: {
- type: 'number',
- shortcode: ( { named: { id } } ) => {
- if ( ! id ) {
- return;
- }
-
- const result = parseInt( id, 10 );
- if ( result ) {
- return result;
- }
- },
- },
- },
- },
- ],
- },
-
- edit,
-
- save,
-
- supports: {
- className: false,
- customClassName: false,
- html: false,
- // Disabled due several problems because the block uses custom post type to store information
- // https://github.com/Automattic/jetpack/issues/11789
- reusable: false,
- },
-};
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/paypal-button-2x.png b/plugins/jetpack/extensions/blocks/simple-payments/paypal-button-2x.png
deleted file mode 100644
index ceea141d..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/paypal-button-2x.png
+++ /dev/null
Binary files differ
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/paypal-button.png b/plugins/jetpack/extensions/blocks/simple-payments/paypal-button.png
deleted file mode 100644
index 13bbad02..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/paypal-button.png
+++ /dev/null
Binary files differ
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.js b/plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.js
deleted file mode 100644
index 3f80c79c..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-
-/**
- * Internal dependencies
- */
-import './product-placeholder.scss';
-import paypalImage from './paypal-button.png';
-import paypalImage2x from './paypal-button-2x.png';
-
-export default ( {
- title = '',
- content = '',
- formattedPrice = '',
- multiple = false,
- featuredMediaUrl = null,
- featuredMediaTitle = null,
-} ) => (
- <div className="jetpack-simple-payments-wrapper">
- <div className="jetpack-simple-payments-product">
- { featuredMediaUrl && (
- <div className="jetpack-simple-payments-product-image">
- <figure className="jetpack-simple-payments-image">
- <img src={ featuredMediaUrl } alt={ featuredMediaTitle } />
- </figure>
- </div>
- ) }
- <div className="jetpack-simple-payments-details">
- { title && (
- <div className="jetpack-simple-payments-title">
- <p>{ title }</p>
- </div>
- ) }
- { content && (
- <div className="jetpack-simple-payments-description">
- <p>{ content }</p>
- </div>
- ) }
- { formattedPrice && (
- <div className="jetpack-simple-payments-price">
- <p>{ formattedPrice }</p>
- </div>
- ) }
- <div className="jetpack-simple-payments-purchase-box">
- { multiple && (
- <div className="jetpack-simple-payments-items">
- <input
- className="jetpack-simple-payments-items-number"
- readOnly
- type="number"
- value="1"
- />
- </div>
- ) }
- <div className="jetpack-simple-payments-button">
- <img
- alt={ __( 'Pay with PayPal', 'jetpack' ) }
- src={ paypalImage }
- srcSet={ `${ paypalImage2x } 2x` }
- />
- </div>
- </div>
- </div>
- </div>
- </div>
-);
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.scss b/plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.scss
deleted file mode 100644
index e138c863..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/product-placeholder.scss
+++ /dev/null
@@ -1,93 +0,0 @@
-@import '../../shared/styles/jetpack-variables.scss';
-
-.simple-payments__loading {
- animation: simple-payments-loading 1600ms ease-in-out infinite;
-}
-
-@keyframes simple-payments-loading {
- 0% {
- opacity: 0.5;
- }
- 50% {
- opacity: 0.7;
- }
- 100% {
- opacity: 0.5;
- }
-}
-
-.jetpack-simple-payments-wrapper {
- margin-bottom: $jetpack-block-margin-bottom;
-}
-
-/* Higher specificity in order to reset paragraph style */
-body .jetpack-simple-payments-wrapper .jetpack-simple-payments-details p {
- margin: 0 0 $jetpack-block-margin-bottom;
- padding: 0;
-}
-
-.jetpack-simple-payments-product {
- display: flex;
- flex-direction: column;
-}
-
-.jetpack-simple-payments-product-image {
- flex: 0 0 30%;
- margin-bottom: $jetpack-block-margin-bottom;
-}
-
-.jetpack-simple-payments-image {
- box-sizing: border-box;
- min-width: 70px;
- padding-top: 100%;
- position: relative;
-}
-
-.jetpack-simple-payments-image img {
- border: 0;
- border-radius: 0;
- height: auto;
- left: 50%;
- margin: 0;
- max-height: 100%;
- max-width: 100%;
- padding: 0;
- position: absolute;
- top: 50%;
- transform: translate( -50%, -50% );
- width: auto;
-}
-
-.jetpack-simple-payments-title p,
-.jetpack-simple-payments-price p {
- font-weight: bold;
-}
-
-.jetpack-simple-payments-purchase-box {
- align-items: flex-start;
- display: flex;
-}
-
-.jetpack-simple-payments-items {
- flex: 0 0 auto;
- margin-right: 10px;
-}
-
-input[type='number'].jetpack-simple-payments-items-number {
- background: var( --color-white );
- font-size: 16px;
- line-height: 1;
- max-width: 60px;
- padding: 4px 8px;
-}
-
-@media screen and ( min-width: 400px ) {
- .jetpack-simple-payments-product {
- flex-direction: row;
- }
-
- .jetpack-simple-payments-product-image + .jetpack-simple-payments-details {
- flex-basis: 70%;
- padding-left: 1em;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/save.js b/plugins/jetpack/extensions/blocks/simple-payments/save.js
deleted file mode 100644
index ed81e7a8..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/save.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * External dependencies
- */
-import { RawHTML } from '@wordpress/element';
-
-export default function Save( { attributes } ) {
- const { productId } = attributes;
- return productId ? <RawHTML>{ `[simple-payment id="${ productId }"]` }</RawHTML> : null;
-}
diff --git a/plugins/jetpack/extensions/blocks/simple-payments/utils.js b/plugins/jetpack/extensions/blocks/simple-payments/utils.js
deleted file mode 100644
index c29e367b..00000000
--- a/plugins/jetpack/extensions/blocks/simple-payments/utils.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * External dependencies
- */
-import { getCurrencyDefaults } from '@automattic/format-currency';
-import { trimEnd } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import { SIMPLE_PAYMENTS_PRODUCT_POST_TYPE } from './constants';
-
-export const isValidSimplePaymentsProduct = product =>
- product.type === SIMPLE_PAYMENTS_PRODUCT_POST_TYPE && product.status === 'publish';
-
-// based on https://stackoverflow.com/a/10454560/59752
-export const decimalPlaces = number => {
- const match = ( '' + number ).match( /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/ );
- if ( ! match ) {
- return 0;
- }
- return Math.max( 0, ( match[ 1 ] ? match[ 1 ].length : 0 ) - ( match[ 2 ] ? +match[ 2 ] : 0 ) );
-};
-
-export const formatPrice = ( price, currency, withSymbol = true ) => {
- const { precision, symbol } = getCurrencyDefaults( currency );
- const value = price.toFixed( precision );
- // Trim the dot at the end of symbol, e.g., 'kr.' becomes 'kr'
- return withSymbol ? `${ value } ${ trimEnd( symbol, '.' ) }` : value;
-};
diff --git a/plugins/jetpack/extensions/blocks/slideshow/create-swiper.js b/plugins/jetpack/extensions/blocks/slideshow/create-swiper.js
deleted file mode 100644
index 72a54f56..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/create-swiper.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * External dependencies
- */
-import { mapValues, merge } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import './style.scss';
-
-export default async function createSwiper(
- container = '.swiper-container',
- params = {},
- callbacks = {}
-) {
- const defaultParams = {
- effect: 'slide',
- grabCursor: true,
- init: true,
- initialSlide: 0,
- navigation: {
- nextEl: '.swiper-button-next',
- prevEl: '.swiper-button-prev',
- },
- pagination: {
- bulletElement: 'button',
- clickable: true,
- el: '.swiper-pagination',
- type: 'bullets',
- },
- preventClicksPropagation: false /* Necessary for normal block interactions */,
- releaseFormElements: false,
- setWrapperSize: true,
- touchStartPreventDefault: false,
- on: mapValues(
- callbacks,
- callback =>
- function() {
- callback( this );
- }
- ),
- };
- const [ { default: Swiper } ] = await Promise.all( [
- import( /* webpackChunkName: "swiper" */ 'swiper/dist/js/swiper.js' ),
- import( /* webpackChunkName: "swiper" */ 'swiper/dist/css/swiper.css' ),
- ] );
- return new Swiper( container, merge( {}, defaultParams, params ) );
-}
diff --git a/plugins/jetpack/extensions/blocks/slideshow/edit.js b/plugins/jetpack/extensions/blocks/slideshow/edit.js
deleted file mode 100644
index 9c03f029..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/edit.js
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Component, Fragment } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import { filter, pick } from 'lodash';
-import { isBlobURL } from '@wordpress/blob';
-import { withDispatch } from '@wordpress/data';
-import {
- BlockControls,
- BlockIcon,
- InspectorControls,
- MediaPlaceholder,
- MediaUpload,
- mediaUpload,
-} from '@wordpress/editor';
-import {
- DropZone,
- FormFileUpload,
- IconButton,
- PanelBody,
- RangeControl,
- SelectControl,
- ToggleControl,
- Toolbar,
- withNotices,
-} from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { icon } from '.';
-import Slideshow from './slideshow';
-import './editor.scss';
-
-const ALLOWED_MEDIA_TYPES = [ 'image' ];
-
-const effectOptions = [
- { label: _x( 'Slide', 'Slideshow transition effect', 'jetpack' ), value: 'slide' },
- { label: _x( 'Fade', 'Slideshow transition effect', 'jetpack' ), value: 'fade' },
-];
-
-export const pickRelevantMediaFiles = image =>
- pick( image, [ 'alt', 'id', 'link', 'url', 'caption' ] );
-
-class SlideshowEdit extends Component {
- constructor() {
- super( ...arguments );
- this.state = {
- selectedImage: null,
- };
- }
- setAttributes( attributes ) {
- if ( attributes.ids ) {
- throw new Error(
- 'The "ids" attribute should not be changed directly. It is managed automatically when "images" attribute changes'
- );
- }
-
- if ( attributes.images ) {
- attributes = {
- ...attributes,
- ids: attributes.images.map( ( { id } ) => parseInt( id, 10 ) ),
- };
- }
-
- this.props.setAttributes( attributes );
- }
- onSelectImages = images => {
- const mapped = images.map( image => pickRelevantMediaFiles( image ) );
- this.setAttributes( {
- images: mapped,
- } );
- };
- onRemoveImage = index => {
- return () => {
- const images = filter( this.props.attributes.images, ( img, i ) => index !== i );
- this.setState( { selectedImage: null } );
- this.setAttributes( { images } );
- };
- };
- addFiles = files => {
- const currentImages = this.props.attributes.images || [];
- const { lockPostSaving, unlockPostSaving, noticeOperations } = this.props;
- const lockName = 'slideshowBlockLock';
- lockPostSaving( lockName );
- mediaUpload( {
- allowedTypes: ALLOWED_MEDIA_TYPES,
- filesList: files,
- onFileChange: images => {
- const imagesNormalized = images.map( image => pickRelevantMediaFiles( image ) );
- this.setAttributes( {
- images: [ ...currentImages, ...imagesNormalized ],
- } );
- if ( ! imagesNormalized.every( image => isBlobURL( image.url ) ) ) {
- unlockPostSaving( lockName );
- }
- },
- onError: noticeOperations.createErrorNotice,
- } );
- };
- uploadFromFiles = event => this.addFiles( event.target.files );
- render() {
- const {
- attributes,
- className,
- isSelected,
- noticeOperations,
- noticeUI,
- setAttributes,
- } = this.props;
- const { align, autoplay, delay, effect, images } = attributes;
- const prefersReducedMotion =
- typeof window !== 'undefined' &&
- window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches;
- const controls = (
- <Fragment>
- <InspectorControls>
- <PanelBody title={ __( 'Autoplay', 'jetpack' ) }>
- <ToggleControl
- label={ __( 'Autoplay', 'jetpack' ) }
- help={ __( 'Autoplay between slides', 'jetpack' ) }
- checked={ autoplay }
- onChange={ value => {
- setAttributes( { autoplay: value } );
- } }
- />
- { autoplay && (
- <RangeControl
- label={ __( 'Delay between transitions (in seconds)', 'jetpack' ) }
- value={ delay }
- onChange={ value => {
- setAttributes( { delay: value } );
- } }
- min={ 1 }
- max={ 5 }
- />
- ) }
- { autoplay && prefersReducedMotion && (
- <span>
- { __(
- 'The Reduce Motion accessibility option is selected, therefore autoplay will be disabled in this browser.',
- 'jetpack'
- ) }
- </span>
- ) }
- </PanelBody>
- <PanelBody title={ __( 'Effects', 'jetpack' ) }>
- <SelectControl
- label={ __( 'Transition effect', 'jetpack' ) }
- value={ effect }
- onChange={ value => {
- setAttributes( { effect: value } );
- } }
- options={ effectOptions }
- />
- </PanelBody>
- </InspectorControls>
- <BlockControls>
- { !! images.length && (
- <Toolbar>
- <MediaUpload
- onSelect={ this.onSelectImages }
- allowedTypes={ ALLOWED_MEDIA_TYPES }
- multiple
- gallery
- value={ images.map( img => img.id ) }
- render={ ( { open } ) => (
- <IconButton
- className="components-toolbar__control"
- label={ __( 'Edit Slideshow', 'jetpack' ) }
- icon="edit"
- onClick={ open }
- />
- ) }
- />
- </Toolbar>
- ) }
- </BlockControls>
- </Fragment>
- );
-
- if ( images.length === 0 ) {
- return (
- <Fragment>
- { controls }
- <MediaPlaceholder
- icon={ <BlockIcon icon={ icon } /> }
- className={ className }
- labels={ {
- title: __( 'Slideshow', 'jetpack' ),
- instructions: __(
- 'Drag images, upload new ones or select files from your library.',
- 'jetpack'
- ),
- } }
- onSelect={ this.onSelectImages }
- accept="image/*"
- allowedTypes={ ALLOWED_MEDIA_TYPES }
- multiple
- notices={ noticeUI }
- onError={ noticeOperations.createErrorNotice }
- />
- </Fragment>
- );
- }
- return (
- <Fragment>
- { controls }
- { noticeUI }
- <Slideshow
- align={ align }
- autoplay={ autoplay }
- className={ className }
- delay={ delay }
- effect={ effect }
- images={ images }
- onError={ noticeOperations.createErrorNotice }
- />
- <DropZone onFilesDrop={ this.addFiles } />
- { isSelected && (
- <div className="wp-block-jetpack-slideshow__add-item">
- <FormFileUpload
- multiple
- isLarge
- className="wp-block-jetpack-slideshow__add-item-button"
- onChange={ this.uploadFromFiles }
- accept="image/*"
- icon="insert"
- >
- { __( 'Upload an image', 'jetpack' ) }
- </FormFileUpload>
- </div>
- ) }
- </Fragment>
- );
- }
-}
-export default compose(
- withDispatch( dispatch => {
- const { lockPostSaving, unlockPostSaving } = dispatch( 'core/editor' );
- return {
- lockPostSaving,
- unlockPostSaving,
- };
- } ),
- withNotices
-)( SlideshowEdit );
diff --git a/plugins/jetpack/extensions/blocks/slideshow/editor.js b/plugins/jetpack/extensions/blocks/slideshow/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/slideshow/editor.scss b/plugins/jetpack/extensions/blocks/slideshow/editor.scss
deleted file mode 100644
index 11c07c25..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/editor.scss
+++ /dev/null
@@ -1,44 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.wp-block-jetpack-slideshow__add-item {
- margin-top: 4px;
- width: 100%;
-
- .components-form-file-upload,
- .components-button.wp-block-jetpack-slideshow__add-item-button {
- width: 100%;
- height: 100%;
- }
-
- .components-button.wp-block-jetpack-slideshow__add-item-button {
- display: flex;
- flex-direction: column;
- justify-content: center;
- box-shadow: none;
- border: none;
- border-radius: 0;
- min-height: 100px;
-
- .dashicon {
- margin-top: 10px;
- }
-
- &:hover,
- &:focus {
- border: 1px solid $dark-gray-500;
- }
- }
-}
-
-.wp-block-jetpack-slideshow_slide {
- .components-spinner {
- position: absolute;
- top: 50%;
- left: 50%;
- margin-top: -9px;
- margin-left: -9px;
- }
- &.is-transient img {
- opacity: 0.3;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/slideshow/index.js b/plugins/jetpack/extensions/blocks/slideshow/index.js
deleted file mode 100644
index 9f4b2807..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/index.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import transforms from './transforms';
-
-export const icon = (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path d="M0 0h24v24H0z" fill="none" />
- <Path d="M10 8v8l5-4-5-4zm9-5H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z" />
- </SVG>
-);
-
-const attributes = {
- align: {
- default: 'center',
- type: 'string',
- },
- autoplay: {
- type: 'boolean',
- default: false,
- },
- delay: {
- type: 'number',
- default: 3,
- },
- ids: {
- default: [],
- type: 'array',
- },
- images: {
- type: 'array',
- default: [],
- source: 'query',
- selector: '.swiper-slide',
- query: {
- alt: {
- source: 'attribute',
- selector: 'img',
- attribute: 'alt',
- default: '',
- },
- caption: {
- type: 'string',
- source: 'html',
- selector: 'figcaption',
- },
- id: {
- source: 'attribute',
- selector: 'img',
- attribute: 'data-id',
- },
- url: {
- source: 'attribute',
- selector: 'img',
- attribute: 'src',
- },
- },
- },
- effect: {
- type: 'string',
- default: 'slide',
- },
-};
-
-export const name = 'slideshow';
-
-export const settings = {
- title: __( 'Slideshow', 'jetpack' ),
- category: 'jetpack',
- keywords: [
- _x( 'image', 'block search term', 'jetpack' ),
- _x( 'gallery', 'block search term', 'jetpack' ),
- _x( 'slider', 'block search term', 'jetpack' ),
- ],
- description: __( 'Add an interactive slideshow.', 'jetpack' ),
- attributes,
- supports: {
- align: [ 'center', 'wide', 'full' ],
- html: false,
- },
- icon,
- edit,
- save,
- transforms,
-};
diff --git a/plugins/jetpack/extensions/blocks/slideshow/save.js b/plugins/jetpack/extensions/blocks/slideshow/save.js
deleted file mode 100644
index 59879ded..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/save.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Internal dependencies
- */
-import Slideshow from './slideshow';
-
-export default ( { attributes: { align, autoplay, delay, effect, images }, className } ) => (
- <Slideshow
- align={ align }
- autoplay={ autoplay }
- className={ className }
- delay={ delay }
- effect={ effect }
- images={ images }
- />
-);
diff --git a/plugins/jetpack/extensions/blocks/slideshow/slideshow.js b/plugins/jetpack/extensions/blocks/slideshow/slideshow.js
deleted file mode 100644
index b7d97c1a..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/slideshow.js
+++ /dev/null
@@ -1,232 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import ResizeObserver from 'resize-observer-polyfill';
-import { __ } from '@wordpress/i18n';
-import { Component, createRef } from '@wordpress/element';
-import { isBlobURL } from '@wordpress/blob';
-import { isEqual } from 'lodash';
-import { RichText } from '@wordpress/editor';
-import { Spinner } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import createSwiper from './create-swiper';
-import {
- swiperApplyAria,
- swiperInit,
- swiperPaginationRender,
- swiperResize,
-} from './swiper-callbacks';
-
-class Slideshow extends Component {
- pendingRequestAnimationFrame = null;
- resizeObserver = null;
- static defaultProps = {
- effect: 'slide',
- };
-
- constructor( props ) {
- super( props );
-
- this.slideshowRef = createRef();
- this.btnNextRef = createRef();
- this.btnPrevRef = createRef();
- this.paginationRef = createRef();
- }
-
- componentDidMount() {
- const { onError } = this.props;
- this.buildSwiper()
- .then( swiper => {
- this.swiperInstance = swiper;
- this.initializeResizeObserver( swiper );
- } )
- .catch( () => {
- onError( __( 'The Swiper library could not be loaded.', 'jetpack' ) );
- } );
- }
-
- componentWillUnmount() {
- this.clearResizeObserver();
- this.clearPendingRequestAnimationFrame();
- }
-
- componentDidUpdate( prevProps ) {
- const { align, autoplay, delay, effect, images, onError } = this.props;
-
- /* A change in alignment or images only needs an update */
- if ( align !== prevProps.align || ! isEqual( images, prevProps.images ) ) {
- this.swiperInstance && this.swiperInstance.update();
- }
- /* A change in effect requires a full rebuild */
- if (
- effect !== prevProps.effect ||
- autoplay !== prevProps.autoplay ||
- delay !== prevProps.delay ||
- images !== prevProps.images
- ) {
- let realIndex;
- if ( ! this.swiperIndex ) {
- realIndex = 0;
- } else if ( images.length === prevProps.images.length ) {
- realIndex = this.swiperInstance.realIndex;
- } else {
- realIndex = prevProps.images.length;
- }
- this.swiperInstance && this.swiperInstance.destroy( true, true );
- this.buildSwiper( realIndex )
- .then( swiper => {
- this.swiperInstance = swiper;
- this.initializeResizeObserver( swiper );
- } )
- .catch( () => {
- onError( __( 'The Swiper library could not be loaded.', 'jetpack' ) );
- } );
- }
- }
-
- initializeResizeObserver = swiper => {
- this.clearResizeObserver();
- this.resizeObserver = new ResizeObserver( () => {
- this.clearPendingRequestAnimationFrame();
- this.pendingRequestAnimationFrame = requestAnimationFrame( () => {
- swiperResize( swiper );
- swiper.update();
- } );
- } );
- this.resizeObserver.observe( swiper.el );
- };
-
- clearPendingRequestAnimationFrame = () => {
- if ( this.pendingRequestAnimationFrame ) {
- cancelAnimationFrame( this.pendingRequestAnimationFrame );
- this.pendingRequestAnimationFrame = null;
- }
- };
-
- clearResizeObserver = () => {
- if ( this.resizeObserver ) {
- this.resizeObserver.disconnect();
- this.resizeObserver = null;
- }
- };
-
- render() {
- const { autoplay, className, delay, effect, images } = this.props;
- // Note: React omits the data attribute if the value is null, but NOT if it is false.
- // This is the reason for the unusual logic related to autoplay below.
- /* eslint-disable jsx-a11y/anchor-is-valid */
- return (
- <div
- className={ className }
- data-autoplay={ autoplay || null }
- data-delay={ autoplay ? delay : null }
- data-effect={ effect }
- >
- <div
- className="wp-block-jetpack-slideshow_container swiper-container"
- ref={ this.slideshowRef }
- >
- <ul className="wp-block-jetpack-slideshow_swiper-wrappper swiper-wrapper">
- { images.map( ( { alt, caption, id, url } ) => (
- <li
- className={ classnames(
- 'wp-block-jetpack-slideshow_slide',
- 'swiper-slide',
- isBlobURL( url ) && 'is-transient'
- ) }
- key={ id }
- >
- <figure>
- <img
- alt={ alt }
- className={
- `wp-block-jetpack-slideshow_image wp-image-${ id }` /* wp-image-${ id } makes WordPress add a srcset */
- }
- data-id={ id }
- src={ url }
- />
- { isBlobURL( url ) && <Spinner /> }
- { caption && (
- <RichText.Content
- className="wp-block-jetpack-slideshow_caption gallery-caption"
- tagName="figcaption"
- value={ caption }
- />
- ) }
- </figure>
- </li>
- ) ) }
- </ul>
- <a
- className="wp-block-jetpack-slideshow_button-prev swiper-button-prev swiper-button-white"
- ref={ this.btnPrevRef }
- role="button"
- />
- <a
- className="wp-block-jetpack-slideshow_button-next swiper-button-next swiper-button-white"
- ref={ this.btnNextRef }
- role="button"
- />
- <a
- aria-label="Pause Slideshow"
- className="wp-block-jetpack-slideshow_button-pause"
- role="button"
- />
- <div
- className="wp-block-jetpack-slideshow_pagination swiper-pagination swiper-pagination-white"
- ref={ this.paginationRef }
- />
- </div>
- </div>
- );
- /* eslint-enable jsx-a11y/anchor-is-valid */
- }
-
- prefersReducedMotion = () => {
- return (
- typeof window !== 'undefined' &&
- window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches
- );
- };
-
- buildSwiper = ( initialSlide = 0 ) =>
- // Using refs instead of className-based selectors allows us to
- // have multiple swipers on one page without collisions, and
- // without needing to add IDs or the like.
- createSwiper(
- this.slideshowRef.current,
- {
- autoplay:
- this.props.autoplay && ! this.prefersReducedMotion()
- ? {
- delay: this.props.delay * 1000,
- disableOnInteraction: false,
- }
- : false,
- effect: this.props.effect,
- loop: true,
- initialSlide,
- navigation: {
- nextEl: this.btnNextRef.current,
- prevEl: this.btnPrevRef.current,
- },
- pagination: {
- clickable: true,
- el: this.paginationRef.current,
- type: 'bullets',
- },
- },
- {
- init: swiperInit,
- imagesReady: swiperResize,
- paginationRender: swiperPaginationRender,
- transitionEnd: swiperApplyAria,
- }
- );
-}
-
-export default Slideshow;
diff --git a/plugins/jetpack/extensions/blocks/slideshow/slideshow.php b/plugins/jetpack/extensions/blocks/slideshow/slideshow.php
index be9ae6c0..ba18661c 100644
--- a/plugins/jetpack/extensions/blocks/slideshow/slideshow.php
+++ b/plugins/jetpack/extensions/blocks/slideshow/slideshow.php
@@ -24,5 +24,166 @@ jetpack_register_block(
*/
function jetpack_slideshow_block_load_assets( $attr, $content ) {
Jetpack_Gutenberg::load_assets_as_required( 'slideshow' );
+ if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) {
+ return jetpack_slideshow_block_render_amp( $attr );
+ }
return $content;
}
+
+/**
+ * Render slideshow block for AMP
+ *
+ * @param array $attr Array containing the slideshow block attributes.
+ *
+ * @return string
+ */
+function jetpack_slideshow_block_render_amp( $attr ) {
+ static $wp_block_jetpack_slideshow_id = 0;
+ $wp_block_jetpack_slideshow_id++;
+
+ $ids = empty( $attr['ids'] ) ? array() : $attr['ids'];
+ $autoplay = empty( $attr['autoplay'] ) ? false : $attr['autoplay'];
+
+ $extras = array(
+ 'wp-amp-block',
+ $autoplay ? 'wp-block-jetpack-slideshow__autoplay' : null,
+ $autoplay ? 'wp-block-jetpack-slideshow__autoplay-playing' : null,
+ );
+ $classes = Jetpack_Gutenberg::block_classes( 'slideshow', $attr, $extras );
+
+ return sprintf(
+ '<div class="%1$s" id="wp-block-jetpack-slideshow__%2$d"><div class="wp-block-jetpack-slideshow_container swiper-container">%3$s%4$s%5$s</div></div>',
+ esc_attr( $classes ),
+ absint( $wp_block_jetpack_slideshow_id ),
+ jetpack_slideshow_block_amp_carousel( $attr, $wp_block_jetpack_slideshow_id ),
+ $autoplay ? jetpack_slideshow_block_autoplay_ui( $wp_block_jetpack_slideshow_id ) : '',
+ jetpack_slideshow_block_bullets( $ids, $wp_block_jetpack_slideshow_id )
+ );
+}
+
+/**
+ * Generate amp-carousel markup
+ *
+ * @param array $attr Array of block attributes.
+ * @param int $block_ordinal The ordinal number of the block, used in unique ID.
+ *
+ * @return string amp-carousel markup.
+ */
+function jetpack_slideshow_block_amp_carousel( $attr, $block_ordinal ) {
+ $ids = empty( $attr['ids'] ) ? array() : $attr['ids'];
+ $first_image = wp_get_attachment_metadata( $ids[0] );
+ $delay = empty( $attr['delay'] ) ? 3 : absint( $attr['delay'] );
+ $autoplay = empty( $attr['autoplay'] ) ? false : $attr['autoplay'];
+ $width = empty( $first_image['width'] ) ? 800 : $first_image['width'];
+ $height = empty( $first_image['height'] ) ? 600 : $first_image['height'];
+ return sprintf(
+ '<amp-carousel width="%1$d" height="%2$d" layout="responsive" type="slides" data-next-button-aria-label="%3$s" data-prev-button-aria-label="%4$s" controls loop %5$s id="wp-block-jetpack-slideshow__amp-carousel__%6$s" on="slideChange:wp-block-jetpack-slideshow__amp-pagination__%6$s.toggle(index=event.index, value=true)">%7$s</amp-carousel>',
+ esc_attr( $width ),
+ esc_attr( $height ),
+ esc_attr__( 'Next Slide', 'jetpack' ),
+ esc_attr__( 'Previous Slide', 'jetpack' ),
+ $autoplay ? 'autoplay delay=' . esc_attr( $delay * 1000 ) : '',
+ absint( $block_ordinal ),
+ implode( '', jetpack_slideshow_block_slides( $ids, $width, $height ) )
+ );
+}
+
+/**
+ * Generate array of slides markup
+ *
+ * @param array $ids Array of image ids.
+ * @param int $width Width of the container.
+ * @param int $height Height of the container.
+ *
+ * @return array Array of slides markup.
+ */
+function jetpack_slideshow_block_slides( $ids = array(), $width = 400, $height = 300 ) {
+ return array_map(
+ function( $id ) use ( $width, $height ) {
+ $caption = wp_get_attachment_caption( $id );
+ $figcaption = $caption ? sprintf(
+ '<figcaption class="wp-block-jetpack-slideshow_caption gallery-caption">%s</figcaption>',
+ wp_kses_post( $caption )
+ ) : '';
+ $image = wp_get_attachment_image(
+ $id,
+ array( $width, $height ),
+ false,
+ array(
+ 'class' => 'wp-block-jetpack-slideshow_image',
+ 'object-fit' => 'contain',
+ )
+ );
+ return sprintf(
+ '<div class="wp-block-jetpack-slideshow_slide"><figure>%s%s</figure></div>',
+ $image,
+ $figcaption
+ );
+ },
+ $ids
+ );
+}
+
+/**
+ * Generate array of bullets markup
+ *
+ * @param array $ids Array of image ids.
+ * @param int $block_ordinal The ordinal number of the block, used in unique ID.
+ *
+ * @return array Array of bullets markup.
+ */
+function jetpack_slideshow_block_bullets( $ids = array(), $block_ordinal = 0 ) {
+ $buttons = array_map(
+ function( $index ) {
+ $aria_label = sprintf(
+ /* translators: %d: Slide number. */
+ __( 'Go to slide %d', 'jetpack' ),
+ absint( $index + 1 )
+ );
+ return sprintf(
+ '<button option="%d" class="swiper-pagination-bullet" tabindex="0" role="button" aria-label="%s" %s></button>',
+ absint( $index ),
+ esc_attr( $aria_label ),
+ 0 === $index ? 'selected' : ''
+ );
+ },
+ array_keys( $ids )
+ );
+
+ return sprintf(
+ '<amp-selector id="wp-block-jetpack-slideshow__amp-pagination__%1$d" class="wp-block-jetpack-slideshow_pagination swiper-pagination swiper-pagination-bullets amp-pagination" on="select:wp-block-jetpack-slideshow__amp-carousel__%1$d.goToSlide(index=event.targetOption)" layout="container">%2$s</amp-selector>',
+ absint( $block_ordinal ),
+ implode( '', $buttons )
+ );
+}
+
+/**
+ * Generate autoplay play/pause UI.
+ *
+ * @param int $block_ordinal The ordinal number of the block, used in unique ID.
+ *
+ * @return string Autoplay UI markup.
+ */
+function jetpack_slideshow_block_autoplay_ui( $block_ordinal = 0 ) {
+ $block_id = sprintf(
+ 'wp-block-jetpack-slideshow__%d',
+ absint( $block_ordinal )
+ );
+ $amp_carousel_id = sprintf(
+ 'wp-block-jetpack-slideshow__amp-carousel__%d',
+ absint( $block_ordinal )
+ );
+ $autoplay_pause = sprintf(
+ '<a aria-label="%s" class="wp-block-jetpack-slideshow_button-pause" role="button" on="tap:%s.toggleAutoplay(toggleOn=false),%s.toggleClass(class=wp-block-jetpack-slideshow__autoplay-playing,force=false)"></a>',
+ esc_attr__( 'Pause Slideshow', 'jetpack' ),
+ esc_attr( $amp_carousel_id ),
+ esc_attr( $block_id )
+ );
+ $autoplay_play = sprintf(
+ '<a aria-label="%s" class="wp-block-jetpack-slideshow_button-play" role="button" on="tap:%s.toggleAutoplay(toggleOn=true),%s.toggleClass(class=wp-block-jetpack-slideshow__autoplay-playing,force=true)"></a>',
+ esc_attr__( 'Play Slideshow', 'jetpack' ),
+ esc_attr( $amp_carousel_id ),
+ esc_attr( $block_id )
+ );
+ return $autoplay_pause . $autoplay_play;
+}
diff --git a/plugins/jetpack/extensions/blocks/slideshow/style.scss b/plugins/jetpack/extensions/blocks/slideshow/style.scss
deleted file mode 100644
index c1d1fc50..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/style.scss
+++ /dev/null
@@ -1,165 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-@import '../../shared/styles/jetpack-variables.scss';
-
-.wp-block-jetpack-slideshow {
- margin-bottom: $jetpack-block-margin-bottom;
- position: relative;
-
- .wp-block-jetpack-slideshow_container {
- width: 100%;
- overflow: hidden;
- opacity: 0;
-
- &.wp-swiper-initialized {
- opacity: 1;
- }
-
- // High specifity to override theme styles
- .wp-block-jetpack-slideshow_swiper-wrappper,
- .wp-block-jetpack-slideshow_slide {
- padding: 0;
- margin: 0;
- line-height: normal;
- }
- }
-
- .wp-block-jetpack-slideshow_slide {
- background: rgba( 0, 0, 0, 0.1 );
- display: flex;
- height: 100%;
- width: 100%;
- figure {
- align-items: center;
- display: flex;
- height: 100%;
- justify-content: center;
- margin: 0;
- position: relative;
- width: 100%;
- }
- }
-
- .swiper-container-fade .wp-block-jetpack-slideshow_slide {
- background: var( --color-neutral-0 );
- }
-
- .wp-block-jetpack-slideshow_image {
- display: block;
- height: auto;
- max-height: 100%;
- max-width: 100%;
- width: auto;
- object-fit: contain;
- }
-
- .wp-block-jetpack-slideshow_button-prev,
- .wp-block-jetpack-slideshow_button-next,
- .wp-block-jetpack-slideshow_button-pause {
- background-color: rgba( 0, 0, 0, 0.5 );
- background-position: center;
- background-repeat: no-repeat;
- background-size: 24px;
- border: 0;
- border-radius: 4px;
- box-shadow: none;
- height: 48px;
- margin: -24px 0 0;
- padding: 0;
- transition: background-color 250ms;
- width: 48px;
-
- &:focus,
- &:hover {
- background-color: rgba( 0, 0, 0, 0.75 );
- }
-
- &:focus {
- outline: thin dotted $white;
- outline-offset: -4px;
- }
- }
-
- &.swiper-container-rtl .swiper-button-prev.swiper-button-white,
- &.swiper-container-rtl .wp-block-jetpack-slideshow_button-prev,
- .swiper-button-next.swiper-button-white,
- .wp-block-jetpack-slideshow_button-next {
- background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M5.88 4.12L13.76 12l-7.88 7.88L8 22l10-10L8 2z' fill='white'/%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3C/svg%3E" );
- }
-
- &.swiper-container-rtl .swiper-button-next.swiper-button-white,
- &.swiper-container-rtl .wp-block-jetpack-slideshow_button-next,
- .swiper-button-prev.swiper-button-white,
- .wp-block-jetpack-slideshow_button-prev {
- background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M18 4.12L10.12 12 18 19.88 15.88 22l-10-10 10-10z' fill='white'/%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3C/svg%3E" );
- }
-
- .wp-block-jetpack-slideshow_button-pause {
- background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M6 19h4V5H6v14zm8-14v14h4V5h-4z' fill='white'/%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3C/svg%3E" );
- display: none;
- margin-top: 0;
- position: absolute;
- right: 10px;
- top: 10px;
- z-index: 1;
- }
-
- .wp-block-jetpack-slideshow_autoplay-paused .wp-block-jetpack-slideshow_button-pause {
- background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M8 5v14l11-7z' fill='white'/%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3C/svg%3E" );
- }
-
- &[data-autoplay='true'] .wp-block-jetpack-slideshow_button-pause {
- display: block;
- }
-
- .wp-block-jetpack-slideshow_caption.gallery-caption {
- background-color: rgba( 0, 0, 0, 0.5 );
- box-sizing: border-box;
- bottom: 0;
- color: $white;
- cursor: text;
- left: 0;
- margin: 0 !important;
- padding: 0.75em;
- position: absolute;
- right: 0;
- text-align: initial;
- z-index: 1;
- a {
- color: inherit;
- }
- }
-
- .wp-block-jetpack-slideshow_pagination.swiper-pagination-bullets {
- bottom: 0;
- line-height: 24px;
- padding: 10px 0 2px;
- position: relative;
-
- .swiper-pagination-bullet {
- background: currentColor;
- color: currentColor;
- height: 16px;
- opacity: 0.5;
- transform: scale( 0.75 );
- transition: opacity 250ms, transform 250ms;
- vertical-align: top;
- width: 16px;
-
- &:focus,
- &:hover {
- opacity: 1;
- }
-
- &:focus {
- outline: thin dotted;
- outline-offset: 0;
- }
- }
-
- .swiper-pagination-bullet-active {
- background-color: currentColor;
- opacity: 1;
- transform: scale( 1 );
- }
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/slideshow/swiper-callbacks.js b/plugins/jetpack/extensions/blocks/slideshow/swiper-callbacks.js
deleted file mode 100644
index 2410f234..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/swiper-callbacks.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * External dependencies
- */
-import { escapeHTML } from '@wordpress/escape-html';
-import { forEach } from 'lodash';
-
-const SIXTEEN_BY_NINE = 16 / 9;
-const MAX_HEIGHT_PERCENT_OF_WINDOW_HEIGHT = 0.8;
-const SANITY_MAX_HEIGHT = 600;
-const PAUSE_CLASS = 'wp-block-jetpack-slideshow_autoplay-paused';
-
-function swiperInit( swiper ) {
- swiperResize( swiper );
- swiperApplyAria( swiper );
- swiper.el
- .querySelector( '.wp-block-jetpack-slideshow_button-pause' )
- .addEventListener( 'click', function() {
- // Handle destroyed Swiper instances
- if ( ! swiper.el ) {
- return;
- }
- if ( swiper.el.classList.contains( PAUSE_CLASS ) ) {
- swiper.el.classList.remove( PAUSE_CLASS );
- swiper.autoplay.start();
- this.setAttribute( 'aria-label', 'Pause Slideshow' );
- } else {
- swiper.el.classList.add( PAUSE_CLASS );
- swiper.autoplay.stop();
- this.setAttribute( 'aria-label', 'Play Slideshow' );
- }
- } );
-}
-
-function swiperResize( swiper ) {
- if ( ! swiper || ! swiper.el ) {
- return;
- }
- const img = swiper.el.querySelector( '.swiper-slide[data-swiper-slide-index="0"] img' );
- if ( ! img ) {
- return;
- }
- const aspectRatio = img.clientWidth / img.clientHeight;
- const sanityAspectRatio = Math.max( Math.min( aspectRatio, SIXTEEN_BY_NINE ), 1 );
- const sanityHeight =
- typeof window !== 'undefined'
- ? window.innerHeight * MAX_HEIGHT_PERCENT_OF_WINDOW_HEIGHT
- : SANITY_MAX_HEIGHT;
- const swiperHeight = Math.min( swiper.width / sanityAspectRatio, sanityHeight );
- const wrapperHeight = `${ Math.floor( swiperHeight ) }px`;
- const buttonTop = `${ Math.floor( swiperHeight / 2 ) }px`;
-
- swiper.el.classList.add( 'wp-swiper-initialized' );
- swiper.wrapperEl.style.height = wrapperHeight;
- swiper.el.querySelector( '.wp-block-jetpack-slideshow_button-prev' ).style.top = buttonTop;
- swiper.el.querySelector( '.wp-block-jetpack-slideshow_button-next' ).style.top = buttonTop;
-}
-
-function announceCurrentSlide( swiper ) {
- const currentSlide = swiper.slides[ swiper.activeIndex ];
- if ( ! currentSlide ) {
- return;
- }
- const figcaption = currentSlide.getElementsByTagName( 'FIGCAPTION' )[ 0 ];
- const img = currentSlide.getElementsByTagName( 'IMG' )[ 0 ];
- if ( swiper.a11y.liveRegion ) {
- swiper.a11y.liveRegion[ 0 ].innerHTML = figcaption
- ? figcaption.innerHTML
- : escapeHTML( img.alt );
- }
-}
-
-function swiperApplyAria( swiper ) {
- forEach( swiper.slides, ( slide, index ) => {
- slide.setAttribute( 'aria-hidden', index === swiper.activeIndex ? 'false' : 'true' );
- if ( index === swiper.activeIndex ) {
- slide.setAttribute( 'tabindex', '-1' );
- } else {
- slide.removeAttribute( 'tabindex' );
- }
- } );
- announceCurrentSlide( swiper );
-}
-
-function swiperPaginationRender( swiper ) {
- forEach( swiper.pagination.bullets, bullet => {
- bullet.addEventListener( 'click', () => {
- const currentSlide = swiper.slides[ swiper.realIndex ];
- setTimeout( () => {
- currentSlide.focus();
- }, 500 );
- } );
- } );
-}
-
-export { swiperApplyAria, swiperInit, swiperPaginationRender, swiperResize };
diff --git a/plugins/jetpack/extensions/blocks/slideshow/transforms.js b/plugins/jetpack/extensions/blocks/slideshow/transforms.js
deleted file mode 100644
index bcff28e5..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/transforms.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * External dependencies
- */
-import { createBlock } from '@wordpress/blocks';
-import { filter } from 'lodash';
-
-/**
- * Filter valid images
- *
- * @param {array} images Array of image objects
- * @return {array} Array of image objects which have id and url
- */
-function getValidImages( images ) {
- return filter( images, ( { id, url } ) => id && url );
-}
-
-const transforms = {
- from: [
- {
- type: 'block',
- isMultiBlock: true,
- blocks: [ 'core/image' ],
- isMatch: images => getValidImages( images ).length > 0,
- transform: images => {
- const validImages = getValidImages( images );
- return createBlock( 'jetpack/slideshow', {
- images: validImages.map( ( { alt, caption, id, url } ) => ( {
- alt,
- caption,
- id,
- url,
- } ) ),
- ids: validImages.map( ( { id } ) => id ),
- } );
- },
- },
- {
- type: 'block',
- blocks: [ 'core/gallery', 'jetpack/tiled-gallery' ],
- transform: ( { images } ) => {
- const validImages = getValidImages( images );
- if ( validImages.length > 0 ) {
- return createBlock( 'jetpack/slideshow', {
- images: validImages.map( ( { alt, caption, id, url } ) => ( {
- alt,
- caption,
- id,
- url,
- } ) ),
- ids: validImages.map( ( { id } ) => id ),
- } );
- }
- return createBlock( 'jetpack/slideshow' );
- },
- },
- ],
- to: [
- {
- type: 'block',
- blocks: [ 'core/gallery' ],
- transform: ( { images, ids } ) => createBlock( 'core/gallery', { images, ids } ),
- },
- {
- type: 'block',
- blocks: [ 'core/image' ],
- transform: ( { images } ) => {
- if ( images.length > 0 ) {
- return images.map( ( { id, url, alt, caption } ) =>
- createBlock( 'core/image', { id, url, alt, caption } )
- );
- }
- return createBlock( 'core/image' );
- },
- },
- ],
-};
-
-export default transforms;
diff --git a/plugins/jetpack/extensions/blocks/slideshow/view.js b/plugins/jetpack/extensions/blocks/slideshow/view.js
deleted file mode 100644
index 6d807897..00000000
--- a/plugins/jetpack/extensions/blocks/slideshow/view.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * External dependencies
- */
-import { forEach } from 'lodash';
-import ResizeObserver from 'resize-observer-polyfill';
-
-/**
- * Internal dependencies
- */
-import createSwiper from './create-swiper';
-import {
- swiperApplyAria,
- swiperInit,
- swiperPaginationRender,
- swiperResize,
-} from './swiper-callbacks';
-
-typeof window !== 'undefined' &&
- window.addEventListener( 'load', function() {
- const slideshowBlocks = document.getElementsByClassName( 'wp-block-jetpack-slideshow' );
- forEach( slideshowBlocks, slideshowBlock => {
- const { autoplay, delay, effect } = slideshowBlock.dataset;
- const prefersReducedMotion = window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches;
- const shouldAutoplay = autoplay && ! prefersReducedMotion;
- const slideshowContainer = slideshowBlock.getElementsByClassName( 'swiper-container' )[ 0 ];
- let pendingRequestAnimationFrame = null;
- createSwiper(
- slideshowContainer,
- {
- autoplay: shouldAutoplay
- ? {
- delay: delay * 1000,
- disableOnInteraction: false,
- }
- : false,
- effect,
- init: true,
- initialSlide: 0,
- loop: true,
- keyboard: {
- enabled: true,
- onlyInViewport: true,
- },
- },
- {
- init: swiperInit,
- imagesReady: swiperResize,
- paginationRender: swiperPaginationRender,
- transitionEnd: swiperApplyAria,
- }
- )
- .then( swiper => {
- new ResizeObserver( () => {
- if ( pendingRequestAnimationFrame ) {
- cancelAnimationFrame( pendingRequestAnimationFrame );
- pendingRequestAnimationFrame = null;
- }
- pendingRequestAnimationFrame = requestAnimationFrame( () => {
- swiperResize( swiper );
- swiper.update();
- } );
- } ).observe( swiper.el );
- } )
- .catch( () => {
- slideshowBlock
- .querySelector( '.wp-block-jetpack-slideshow_container' )
- .classList.add( 'wp-swiper-initialized' );
- } );
- } );
- } );
diff --git a/plugins/jetpack/extensions/blocks/subscriptions/edit.js b/plugins/jetpack/extensions/blocks/subscriptions/edit.js
deleted file mode 100644
index 25482110..00000000
--- a/plugins/jetpack/extensions/blocks/subscriptions/edit.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-import { __, _n, sprintf } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { TextControl, ToggleControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import SubmitButton from '../../shared/submit-button';
-
-class SubscriptionEdit extends Component {
- state = {
- subscriberCountString: '',
- };
-
- componentDidMount() {
- // Get the subscriber count so it is available right away if the user toggles the setting
- this.get_subscriber_count();
- }
-
- render() {
- const { attributes, className, isSelected, setAttributes } = this.props;
- const { subscribePlaceholder, showSubscribersTotal } = attributes;
-
- if ( isSelected ) {
- return (
- <div className={ className } role="form">
- <ToggleControl
- label={ __( 'Show total subscribers', 'jetpack' ) }
- checked={ showSubscribersTotal }
- onChange={ () => {
- setAttributes( { showSubscribersTotal: ! showSubscribersTotal } );
- } }
- />
- <TextControl
- placeholder={ subscribePlaceholder }
- disabled={ true }
- onChange={ () => {} }
- />
- <SubmitButton { ...this.props } />
- </div>
- );
- }
-
- return (
- <div className={ className } role="form">
- { showSubscribersTotal && <p role="heading">{ this.state.subscriberCountString }</p> }
- <TextControl placeholder={ subscribePlaceholder } />
-
- <SubmitButton { ...this.props } />
- </div>
- );
- }
-
- get_subscriber_count() {
- apiFetch( { path: '/wpcom/v2/subscribers/count' } ).then( count => {
- // Handle error condition
- if ( ! count.hasOwnProperty( 'count' ) ) {
- this.setState( {
- subscriberCountString: __( 'Subscriber count unavailable', 'jetpack' ),
- } );
- } else {
- this.setState( {
- subscriberCountString: sprintf(
- _n( 'Join %s other subscriber', 'Join %s other subscribers', count.count, 'jetpack' ),
- count.count
- ),
- } );
- }
- } );
- }
-
- onChangeSubmit( submitButtonText ) {
- this.props.setAttributes( { submitButtonText } );
- }
-}
-
-export default SubscriptionEdit;
diff --git a/plugins/jetpack/extensions/blocks/subscriptions/editor.js b/plugins/jetpack/extensions/blocks/subscriptions/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/subscriptions/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/subscriptions/index.js b/plugins/jetpack/extensions/blocks/subscriptions/index.js
deleted file mode 100644
index 007b0d1e..00000000
--- a/plugins/jetpack/extensions/blocks/subscriptions/index.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { isEmpty } from 'lodash';
-import { Path } from '@wordpress/components';
-import { RawHTML } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import renderMaterialIcon from '../../shared/render-material-icon';
-
-export const name = 'subscriptions';
-export const settings = {
- title: __( 'Subscription Form', 'jetpack' ),
-
- description: (
- <p>
- { __(
- 'A form enabling readers to get notifications when new posts are published from this site.',
- 'jetpack'
- ) }
- </p>
- ),
- icon: renderMaterialIcon(
- <Path d="M23 16v2h-3v3h-2v-3h-3v-2h3v-3h2v3h3zM20 2v9h-4v3h-3v4H4c-1.1 0-2-.9-2-2V2h18zM8 13v-1H4v1h4zm3-3H4v1h7v-1zm0-2H4v1h7V8zm7-4H4v2h14V4z" />
- ),
- category: 'jetpack',
-
- keywords: [
- _x( 'subscribe', 'block search term', 'jetpack' ),
- _x( 'join', 'block search term', 'jetpack' ),
- _x( 'follow', 'block search term', 'jetpack' ),
- ],
-
- attributes: {
- subscribePlaceholder: { type: 'string', default: __( 'Email Address', 'jetpack' ) },
- subscribeButton: { type: 'string', default: __( 'Subscribe', 'jetpack' ) },
- showSubscribersTotal: { type: 'boolean', default: false },
- submitButtonText: {
- type: 'string',
- default: __( 'Subscribe', 'jetpack' ),
- },
- customBackgroundButtonColor: { type: 'string' },
- customTextButtonColor: { type: 'string' },
- submitButtonClasses: { type: 'string' },
- },
- edit,
- save,
- deprecated: [
- {
- attributes: {
- subscribeButton: { type: 'string', default: __( 'Subscribe', 'jetpack' ) },
- showSubscribersTotal: { type: 'boolean', default: false },
- },
- migrate: attr => {
- return {
- subscribeButton: '',
- submitButtonText: attr.subscribeButton,
- showSubscribersTotal: attr.showSubscribersTotal,
- customBackgroundButtonColor: '',
- customTextButtonColor: '',
- submitButtonClasses: '',
- };
- },
-
- isEligible: attr => {
- if ( ! isEmpty( attr.subscribeButton ) ) {
- return false;
- }
- return true;
- },
- save: function( { attributes } ) {
- return (
- <RawHTML>{ `[jetpack_subscription_form show_subscribers_total="${
- attributes.showSubscribersTotal
- }" show_only_email_and_button="true"]` }</RawHTML>
- );
- },
- },
- ],
-};
diff --git a/plugins/jetpack/extensions/blocks/subscriptions/save.js b/plugins/jetpack/extensions/blocks/subscriptions/save.js
deleted file mode 100644
index a7db7fe6..00000000
--- a/plugins/jetpack/extensions/blocks/subscriptions/save.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * External dependencies
- */
-import { RawHTML } from '@wordpress/element';
-
-export default function Save( { attributes } ) {
- const {
- showSubscribersTotal,
- submitButtonClasses,
- customBackgroundButtonColor,
- customTextButtonColor,
- submitButtonText,
- } = attributes;
- return (
- <RawHTML>{ `[jetpack_subscription_form show_only_email_and_button="true" custom_background_button_color="${ customBackgroundButtonColor }" custom_text_button_color="${ customTextButtonColor }" submit_button_text="${ submitButtonText }" submit_button_classes="${ submitButtonClasses }" show_subscribers_total="${ showSubscribersTotal }" ]` }</RawHTML>
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/constants.js b/plugins/jetpack/extensions/blocks/tiled-gallery/constants.js
deleted file mode 100644
index 0df90737..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/constants.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export const ALLOWED_MEDIA_TYPES = [ 'image' ];
-export const DEFAULT_GALLERY_WIDTH = 580;
-export const GUTTER_WIDTH = 4;
-export const MAX_COLUMNS = 20;
-export const PHOTON_MAX_RESIZE = 2000;
-
-/**
- * Layouts
- */
-export const LAYOUT_CIRCLE = 'circle';
-export const LAYOUT_COLUMN = 'columns';
-export const LAYOUT_DEFAULT = 'rectangular';
-export const LAYOUT_SQUARE = 'square';
-export const LAYOUT_STYLES = [
- {
- isDefault: true,
- name: LAYOUT_DEFAULT,
- },
- {
- name: LAYOUT_CIRCLE,
- },
- {
- name: LAYOUT_SQUARE,
- },
- {
- name: LAYOUT_COLUMN,
- },
-];
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/css-gram.scss b/plugins/jetpack/extensions/blocks/tiled-gallery/css-gram.scss
deleted file mode 100644
index 9fd2f49c..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/css-gram.scss
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * This code is based on CSS gram:
- * https://github.com/una/CSSgram/tree/master
- *
- * Due to the packaging options available, the source has been duplicated and adapted here
- * to best fit our specific needs.
- */
-
-/* From https://github.com/una/CSSgram/blob/0.1.12/source/scss/_shared.scss */
-@mixin pseudo-elem {
- content: '';
- display: block;
- height: 100%;
- width: 100%;
- top: 0;
- left: 0;
- position: absolute;
- pointer-events: none;
-}
-
-@mixin filter-base {
- position: relative;
-
- img {
- width: 100%;
- z-index: 1;
- }
-
- &::before {
- @include pseudo-elem;
- z-index: 2;
- }
-
- &::after {
- @include pseudo-elem;
- z-index: 3;
- }
-}
-
-/**
- * 1977
- * From https://github.com/una/CSSgram/blob/0.1.12/source/scss/1977.scss
- */
-@mixin _1977( $filters... ) {
- @include filter-base;
- filter: contrast( 1.1 ) brightness( 1.1 ) saturate( 1.3 ) $filters;
-
- &::after {
- background: rgba( 243, 106, 188, 0.3 );
- mix-blend-mode: screen;
- }
-
- @content;
-}
-
-/*
- * Clarendon
- * From https://github.com/una/CSSgram/blob/0.1.12/source/scss/clarendon.scss
- */
-@mixin clarendon( $filters... ) {
- @include filter-base;
- filter: contrast( 1.2 ) saturate( 1.35 ) $filters;
-
- &::before {
- background: rgba( 127, 187, 227, 0.2 );
- mix-blend-mode: overlay;
- }
-
- @content;
-}
-
-/**
- * Gingham
- * From https://github.com/una/CSSgram/blob/0.1.12/source/scss/gingham.scss
- */
-@mixin gingham( $filters... ) {
- @include filter-base;
- filter: brightness( 1.05 ) hue-rotate( -10deg ) $filters;
-
- &::after {
- background: rgb( 230, 230, 250 );
- mix-blend-mode: soft-light;
- }
-
- @content;
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/constants.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/constants.js
deleted file mode 100644
index 55a451fc..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/constants.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export const ALLOWED_MEDIA_TYPES = [ 'image' ];
-export const GUTTER_WIDTH = 4;
-export const MAX_COLUMNS = 20;
-export const PHOTON_MAX_RESIZE = 2000;
-
-/**
- * Layouts
- */
-export const LAYOUT_CIRCLE = 'circle';
-export const LAYOUT_COLUMN = 'columns';
-export const LAYOUT_DEFAULT = 'rectangular';
-export const LAYOUT_SQUARE = 'square';
-export const LAYOUT_STYLES = [
- {
- isDefault: true,
- name: LAYOUT_DEFAULT,
- },
- {
- name: LAYOUT_CIRCLE,
- },
- {
- name: LAYOUT_SQUARE,
- },
- {
- name: LAYOUT_COLUMN,
- },
-];
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/image.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/image.js
deleted file mode 100644
index 61d4a2cd..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/image.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * External Dependencies
- */
-import { isBlobURL } from '@wordpress/blob';
-
-export default function GalleryImageSave( props ) {
- const {
- 'aria-label': ariaLabel,
- alt,
- // caption,
- height,
- id,
- link,
- linkTo,
- origUrl,
- url,
- width,
- } = props;
-
- if ( isBlobURL( origUrl ) ) {
- return null;
- }
-
- let href;
-
- switch ( linkTo ) {
- case 'media':
- href = url;
- break;
- case 'attachment':
- href = link;
- break;
- }
-
- const img = (
- <img
- alt={ alt }
- aria-label={ ariaLabel }
- data-height={ height }
- data-id={ id }
- data-link={ link }
- data-url={ origUrl }
- data-width={ width }
- src={ url }
- />
- );
-
- return (
- <figure className="tiled-gallery__item">{ href ? <a href={ href }>{ img }</a> : img }</figure>
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/index.js
deleted file mode 100644
index 69539d00..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/index.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Internal dependencies
- */
-export { default as save } from './save';
-import { LAYOUT_DEFAULT } from './constants';
-
-export const attributes = {
- // Set default align
- align: {
- default: 'center',
- type: 'string',
- },
- // Set default className (used with block styles)
- className: {
- default: `is-style-${ LAYOUT_DEFAULT }`,
- type: 'string',
- },
- columns: {
- type: 'number',
- },
- ids: {
- default: [],
- type: 'array',
- },
- images: {
- type: 'array',
- default: [],
- source: 'query',
- selector: '.tiled-gallery__item',
- query: {
- alt: {
- attribute: 'alt',
- default: '',
- selector: 'img',
- source: 'attribute',
- },
- caption: {
- selector: 'figcaption',
- source: 'html',
- type: 'string',
- },
- height: {
- attribute: 'data-height',
- selector: 'img',
- source: 'attribute',
- type: 'number',
- },
- id: {
- attribute: 'data-id',
- selector: 'img',
- source: 'attribute',
- },
- link: {
- attribute: 'data-link',
- selector: 'img',
- source: 'attribute',
- },
- url: {
- attribute: 'data-url',
- selector: 'img',
- source: 'attribute',
- },
- width: {
- attribute: 'data-width',
- selector: 'img',
- source: 'attribute',
- type: 'number',
- },
- },
- },
- linkTo: {
- default: 'none',
- type: 'string',
- },
-};
-
-export const support = {
- align: [ 'center', 'wide', 'full' ],
- customClassName: false,
- html: false,
-};
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/column.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/column.js
deleted file mode 100644
index a3ed5cdf..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/column.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Column( { children } ) {
- return <div className="tiled-gallery__col">{ children }</div>;
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/gallery.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/gallery.js
deleted file mode 100644
index 94fc61e4..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/gallery.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function Gallery( { children, galleryRef } ) {
- return (
- <div className="tiled-gallery__gallery" ref={ galleryRef }>
- { children }
- </div>
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/index.js
deleted file mode 100644
index 3b434fe4..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/index.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * External dependencies
- */
-import photon from 'photon';
-import { __, sprintf } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { format as formatUrl, parse as parseUrl } from 'url';
-import { isBlobURL } from '@wordpress/blob';
-
-/**
- * Internal dependencies
- */
-import Image from '../image';
-import Mosaic from './mosaic';
-import Square from './square';
-import { PHOTON_MAX_RESIZE } from '../constants';
-
-export default class Layout extends Component {
- photonize( { height, width, url } ) {
- if ( ! url ) {
- return;
- }
-
- // Do not Photonize images that are still uploading or from localhost
- if ( isBlobURL( url ) || /^https?:\/\/localhost/.test( url ) ) {
- return url;
- }
-
- // Drop query args, photon URLs can't handle them
- // This should be the "raw" url, we'll add dimensions later
- const cleanUrl = url.split( '?', 1 )[ 0 ];
-
- const photonImplementation = isWpcomFilesUrl( url ) ? photonWpcomImage : photon;
-
- const { layoutStyle } = this.props;
-
- if ( isSquareishLayout( layoutStyle ) && width && height ) {
- const size = Math.min( PHOTON_MAX_RESIZE, width, height );
- return photonImplementation( cleanUrl, { resize: `${ size },${ size }` } );
- }
- return photonImplementation( cleanUrl );
- }
-
- // This is tricky:
- // - We need to "photonize" to resize the images at appropriate dimensions
- // - The resize will depend on the image size and the layout in some cases
- // - Handlers need to be created by index so that the image changes can be applied correctly.
- // This is because the images are stored in an array in the block attributes.
- renderImage( img, i ) {
- const { images, linkTo, selectedImage } = this.props;
-
- /* translators: %1$d is the order number of the image, %2$d is the total number of images. */
- const ariaLabel = sprintf(
- __( 'image %1$d of %2$d in gallery', 'jetpack' ),
- i + 1,
- images.length
- );
- return (
- <Image
- alt={ img.alt }
- aria-label={ ariaLabel }
- height={ img.height }
- id={ img.id }
- origUrl={ img.url }
- isSelected={ selectedImage === i }
- key={ i }
- link={ img.link }
- linkTo={ linkTo }
- url={ this.photonize( img ) }
- width={ img.width }
- />
- );
- }
-
- render() {
- const { align, children, className, columns, images, layoutStyle } = this.props;
-
- const LayoutRenderer = isSquareishLayout( layoutStyle ) ? Square : Mosaic;
-
- const renderedImages = this.props.images.map( this.renderImage, this );
-
- return (
- <div className={ className }>
- <LayoutRenderer
- align={ align }
- columns={ columns }
- images={ images }
- layoutStyle={ layoutStyle }
- renderedImages={ renderedImages }
- />
- { children }
- </div>
- );
- }
-}
-
-function isSquareishLayout( layout ) {
- return [ 'circle', 'square' ].includes( layout );
-}
-
-function isWpcomFilesUrl( url ) {
- const { host } = parseUrl( url );
- return /\.files\.wordpress\.com$/.test( host );
-}
-
-/**
- * Apply photon arguments to *.files.wordpress.com images
- *
- * This function largely duplicates the functionlity of the photon.js lib.
- * This is necessary because we want to serve images from *.files.wordpress.com so that private
- * WordPress.com sites can use this block which depends on a Photon-like image service.
- *
- * If we pass all images through Photon servers, some images are unreachable. *.files.wordpress.com
- * is already photon-like so we can pass it the same parameters for image resizing.
- *
- * @param {string} url Image url
- * @param {Object} opts Options to pass to photon
- *
- * @return {string} Url string with options applied
- */
-function photonWpcomImage( url, opts = {} ) {
- // Adhere to the same options API as the photon.js lib
- const photonLibMappings = {
- width: 'w',
- height: 'h',
- letterboxing: 'lb',
- removeLetterboxing: 'ulb',
- };
-
- // Discard some param parts
- const { auth, hash, port, query, search, ...urlParts } = parseUrl( url );
-
- // Build query
- // This reduction intentionally mutates the query as it is built internally.
- urlParts.query = Object.keys( opts ).reduce(
- ( q, key ) =>
- Object.assign( q, {
- [ photonLibMappings.hasOwnProperty( key ) ? photonLibMappings[ key ] : key ]: opts[ key ],
- } ),
- {}
- );
-
- return formatUrl( urlParts );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js
deleted file mode 100644
index 8c56b164..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * External dependencies
- */
-import { Component, createRef } from '@wordpress/element';
-import ResizeObserver from 'resize-observer-polyfill';
-
-/**
- * Internal dependencies
- */
-import Column from '../column';
-import Gallery from '../gallery';
-import Row from '../row';
-import { getGalleryRows, handleRowResize } from './resize';
-import { imagesToRatios, ratiosToColumns, ratiosToMosaicRows } from './ratios';
-
-export default class Mosaic extends Component {
- gallery = createRef();
- pendingRaf = null;
- ro = null; // resizeObserver instance
-
- componentDidMount() {
- this.observeResize();
- }
-
- componentWillUnmount() {
- this.unobserveResize();
- }
-
- componentDidUpdate( prevProps ) {
- if ( prevProps.images !== this.props.images || prevProps.align !== this.props.align ) {
- this.triggerResize();
- } else if ( 'columns' === this.props.layoutStyle && prevProps.columns !== this.props.columns ) {
- this.triggerResize();
- }
- }
-
- handleGalleryResize = entries => {
- if ( this.pendingRaf ) {
- cancelAnimationFrame( this.pendingRaf );
- this.pendingRaf = null;
- }
- this.pendingRaf = requestAnimationFrame( () => {
- for ( const { contentRect, target } of entries ) {
- const { width } = contentRect;
- getGalleryRows( target ).forEach( row => handleRowResize( row, width ) );
- }
- } );
- };
-
- triggerResize() {
- if ( this.gallery.current ) {
- this.handleGalleryResize( [
- {
- target: this.gallery.current,
- contentRect: { width: this.gallery.current.clientWidth },
- },
- ] );
- }
- }
-
- observeResize() {
- this.triggerResize();
- this.ro = new ResizeObserver( this.handleGalleryResize );
- if ( this.gallery.current ) {
- this.ro.observe( this.gallery.current );
- }
- }
-
- unobserveResize() {
- if ( this.ro ) {
- this.ro.disconnect();
- this.ro = null;
- }
- if ( this.pendingRaf ) {
- cancelAnimationFrame( this.pendingRaf );
- this.pendingRaf = null;
- }
- }
-
- render() {
- const { align, columns, images, layoutStyle, renderedImages } = this.props;
-
- const ratios = imagesToRatios( images );
- const rows =
- 'columns' === layoutStyle
- ? ratiosToColumns( ratios, columns )
- : ratiosToMosaicRows( ratios, { isWide: [ 'full', 'wide' ].includes( align ) } );
-
- let cursor = 0;
- return (
- <Gallery galleryRef={ this.gallery }>
- { rows.map( ( row, rowIndex ) => (
- <Row key={ rowIndex }>
- { row.map( ( colSize, colIndex ) => {
- const columnImages = renderedImages.slice( cursor, cursor + colSize );
- cursor += colSize;
- return <Column key={ colIndex }>{ columnImages }</Column>;
- } ) }
- </Row>
- ) ) }
- </Gallery>
- );
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/ratios.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/ratios.js
deleted file mode 100644
index 8accd552..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/ratios.js
+++ /dev/null
@@ -1,280 +0,0 @@
-/**
- * External dependencies
- */
-import {
- drop,
- every,
- isEqual,
- map,
- overEvery,
- some,
- sum,
- take,
- takeRight,
- takeWhile,
- zipWith,
-} from 'lodash';
-
-export function imagesToRatios( images ) {
- return map( images, ratioFromImage );
-}
-
-export function ratioFromImage( { height, width } ) {
- return height && width ? width / height : 1;
-}
-
-/**
- * Build three columns, each of which should contain approximately 1/3 of the total ratio
- *
- * @param {Array.<number>} ratios Ratios of images put into shape
- * @param {number} columnCount Number of columns
- *
- * @return {Array.<Array.<number>>} Shape of rows and columns
- */
-export function ratiosToColumns( ratios, columnCount ) {
- // If we don't have more than 1 per column, just return a simple 1 ratio per column shape
- if ( ratios.length <= columnCount ) {
- return [ Array( ratios.length ).fill( 1 ) ];
- }
-
- const total = sum( ratios );
- const targetColRatio = total / columnCount;
-
- const row = [];
- let toProcess = ratios;
- let accumulatedRatio = 0;
-
- // We skip the last column in the loop and add rest later
- for ( let i = 0; i < columnCount - 1; i++ ) {
- const colSize = takeWhile( toProcess, ratio => {
- const shouldTake = accumulatedRatio <= ( i + 1 ) * targetColRatio;
- if ( shouldTake ) {
- accumulatedRatio += ratio;
- }
- return shouldTake;
- } ).length;
- row.push( colSize );
- toProcess = drop( toProcess, colSize );
- }
-
- // Don't calculate last column, just add what's left
- row.push( toProcess.length );
-
- // A shape is an array of rows. Wrap our row in an array.
- return [ row ];
-}
-
-/**
- * These are partially applied functions.
- * They rely on helper function (defined below) to create a function that expects to be passed ratios
- * during processing.
- *
- * …FitsNextImages() functions should be passed ratios to be processed
- * …IsNotRecent() functions should be passed the processed shapes
- */
-
-const reverseSymmetricRowIsNotRecent = isNotRecentShape( [ 2, 1, 2 ], 5 );
-const reverseSymmetricFitsNextImages = checkNextRatios( [
- isLandscape,
- isLandscape,
- isPortrait,
- isLandscape,
- isLandscape,
-] );
-const longSymmetricRowFitsNextImages = checkNextRatios( [
- isLandscape,
- isLandscape,
- isLandscape,
- isPortrait,
- isLandscape,
- isLandscape,
- isLandscape,
-] );
-const longSymmetricRowIsNotRecent = isNotRecentShape( [ 3, 1, 3 ], 5 );
-const symmetricRowFitsNextImages = checkNextRatios( [
- isPortrait,
- isLandscape,
- isLandscape,
- isPortrait,
-] );
-const symmetricRowIsNotRecent = isNotRecentShape( [ 1, 2, 1 ], 5 );
-const oneThreeFitsNextImages = checkNextRatios( [
- isPortrait,
- isLandscape,
- isLandscape,
- isLandscape,
-] );
-const oneThreeIsNotRecent = isNotRecentShape( [ 1, 3 ], 3 );
-const threeOneIsFitsNextImages = checkNextRatios( [
- isLandscape,
- isLandscape,
- isLandscape,
- isPortrait,
-] );
-const threeOneIsNotRecent = isNotRecentShape( [ 3, 1 ], 3 );
-const oneTwoFitsNextImages = checkNextRatios( [
- lt( 1.6 ),
- overEvery( gte( 0.9 ), lt( 2 ) ),
- overEvery( gte( 0.9 ), lt( 2 ) ),
-] );
-const oneTwoIsNotRecent = isNotRecentShape( [ 1, 2 ], 3 );
-const fiveIsNotRecent = isNotRecentShape( [ 1, 1, 1, 1, 1 ], 1 );
-const fourIsNotRecent = isNotRecentShape( [ 1, 1, 1, 1 ], 1 );
-const threeIsNotRecent = isNotRecentShape( [ 1, 1, 1 ], 3 );
-const twoOneFitsNextImages = checkNextRatios( [
- overEvery( gte( 0.9 ), lt( 2 ) ),
- overEvery( gte( 0.9 ), lt( 2 ) ),
- lt( 1.6 ),
-] );
-const twoOneIsNotRecent = isNotRecentShape( [ 2, 1 ], 3 );
-const panoramicFitsNextImages = checkNextRatios( [ isPanoramic ] );
-
-export function ratiosToMosaicRows( ratios, { isWide } = {} ) {
- // This function will recursively process the input until it is consumed
- const go = ( processed, toProcess ) => {
- if ( ! toProcess.length ) {
- return processed;
- }
-
- let next;
-
- if (
- /* Reverse_Symmetric_Row */
- toProcess.length > 15 &&
- reverseSymmetricFitsNextImages( toProcess ) &&
- reverseSymmetricRowIsNotRecent( processed )
- ) {
- next = [ 2, 1, 2 ];
- } else if (
- /* Long_Symmetric_Row */
- toProcess.length > 15 &&
- longSymmetricRowFitsNextImages( toProcess ) &&
- longSymmetricRowIsNotRecent( processed )
- ) {
- next = [ 3, 1, 3 ];
- } else if (
- /* Symmetric_Row */
- toProcess.length !== 5 &&
- symmetricRowFitsNextImages( toProcess ) &&
- symmetricRowIsNotRecent( processed )
- ) {
- next = [ 1, 2, 1 ];
- } else if (
- /* One_Three */
- oneThreeFitsNextImages( toProcess ) &&
- oneThreeIsNotRecent( processed )
- ) {
- next = [ 1, 3 ];
- } else if (
- /* Three_One */
- threeOneIsFitsNextImages( toProcess ) &&
- threeOneIsNotRecent( processed )
- ) {
- next = [ 3, 1 ];
- } else if (
- /* One_Two */
- oneTwoFitsNextImages( toProcess ) &&
- oneTwoIsNotRecent( processed )
- ) {
- next = [ 1, 2 ];
- } else if (
- /* Five */
- isWide &&
- ( toProcess.length === 5 || ( toProcess.length !== 10 && toProcess.length > 6 ) ) &&
- fiveIsNotRecent( processed ) &&
- sum( take( toProcess, 5 ) ) < 5
- ) {
- next = [ 1, 1, 1, 1, 1 ];
- } else if (
- /* Four */
- isFourValidCandidate( processed, toProcess )
- ) {
- next = [ 1, 1, 1, 1 ];
- } else if (
- /* Three */
- isThreeValidCandidate( processed, toProcess, isWide )
- ) {
- next = [ 1, 1, 1 ];
- } else if (
- /* Two_One */
- twoOneFitsNextImages( toProcess ) &&
- twoOneIsNotRecent( processed )
- ) {
- next = [ 2, 1 ];
- } else if ( /* Panoramic */ panoramicFitsNextImages( toProcess ) ) {
- next = [ 1 ];
- } else if ( /* One_One */ toProcess.length > 3 ) {
- next = [ 1, 1 ];
- } else {
- // Everything left
- next = Array( toProcess.length ).fill( 1 );
- }
-
- // Add row
- const nextProcessed = processed.concat( [ next ] );
-
- // Trim consumed images from next processing step
- const consumedImages = sum( next );
- const nextToProcess = toProcess.slice( consumedImages );
-
- return go( nextProcessed, nextToProcess );
- };
- return go( [], ratios );
-}
-
-function isThreeValidCandidate( processed, toProcess, isWide ) {
- const ratio = sum( take( toProcess, 3 ) );
- return (
- toProcess.length >= 3 &&
- toProcess.length !== 4 &&
- toProcess.length !== 6 &&
- threeIsNotRecent( processed ) &&
- ( ratio < 2.5 ||
- ( ratio < 5 &&
- /* nextAreSymettric */
- ( toProcess.length >= 3 &&
- /* @FIXME floating point equality?? */ toProcess[ 0 ] === toProcess[ 2 ] ) ) ||
- isWide )
- );
-}
-
-function isFourValidCandidate( processed, toProcess ) {
- const ratio = sum( take( toProcess, 4 ) );
- return (
- ( fourIsNotRecent( processed ) && ( ratio < 3.5 && toProcess.length > 5 ) ) ||
- ( ratio < 7 && toProcess.length === 4 )
- );
-}
-
-function isNotRecentShape( shape, numRecents ) {
- return recents =>
- ! some( takeRight( recents, numRecents ), recentShape => isEqual( recentShape, shape ) );
-}
-
-function checkNextRatios( shape ) {
- return ratios =>
- ratios.length >= shape.length &&
- every( zipWith( shape, ratios.slice( 0, shape.length ), ( f, r ) => f( r ) ) );
-}
-
-function isLandscape( ratio ) {
- return ratio >= 1 && ratio < 2;
-}
-
-function isPortrait( ratio ) {
- return ratio < 1;
-}
-
-function isPanoramic( ratio ) {
- return ratio >= 2;
-}
-
-// >=
-function gte( n ) {
- return m => m >= n;
-}
-
-// <
-function lt( n ) {
- return m => m < n;
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/resize.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/resize.js
deleted file mode 100644
index 022729c8..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/resize.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Internal dependencies
- */
-import { GUTTER_WIDTH } from '../../constants';
-
-/**
- * Distribute a difference across ns so that their sum matches the target
- *
- * @param {Array<number>} parts Array of numbers to fit
- * @param {number} target Number that sum should match
- * @return {Array<number>} Adjusted parts
- */
-function adjustFit( parts, target ) {
- const diff = target - parts.reduce( ( sum, n ) => sum + n, 0 );
- const partialDiff = diff / parts.length;
- return parts.map( p => p + partialDiff );
-}
-
-export function handleRowResize( row, width ) {
- applyRowRatio( row, getRowRatio( row ), width );
-}
-
-function getRowRatio( row ) {
- const result = getRowCols( row )
- .map( getColumnRatio )
- .reduce(
- ( [ ratioA, weightedRatioA ], [ ratioB, weightedRatioB ] ) => {
- return [ ratioA + ratioB, weightedRatioA + weightedRatioB ];
- },
- [ 0, 0 ]
- );
- return result;
-}
-
-export function getGalleryRows( gallery ) {
- return Array.from( gallery.querySelectorAll( '.tiled-gallery__row' ) );
-}
-
-function getRowCols( row ) {
- return Array.from( row.querySelectorAll( '.tiled-gallery__col' ) );
-}
-
-function getColImgs( col ) {
- return Array.from(
- col.querySelectorAll( '.tiled-gallery__item > img, .tiled-gallery__item > a > img' )
- );
-}
-
-function getColumnRatio( col ) {
- const imgs = getColImgs( col );
- const imgCount = imgs.length;
- const ratio =
- 1 /
- imgs.map( getImageRatio ).reduce( ( partialColRatio, imgRatio ) => {
- return partialColRatio + 1 / imgRatio;
- }, 0 );
- const result = [ ratio, ratio * imgCount || 1 ];
- return result;
-}
-
-function getImageRatio( img ) {
- const w = parseInt( img.dataset.width, 10 );
- const h = parseInt( img.dataset.height, 10 );
- const result = w && ! Number.isNaN( w ) && h && ! Number.isNaN( h ) ? w / h : 1;
- return result;
-}
-
-function applyRowRatio( row, [ ratio, weightedRatio ], width ) {
- const rawHeight =
- ( 1 / ratio ) * ( width - GUTTER_WIDTH * ( row.childElementCount - 1 ) - weightedRatio );
-
- applyColRatio( row, {
- rawHeight,
- rowWidth: width - GUTTER_WIDTH * ( row.childElementCount - 1 ),
- } );
-}
-
-function applyColRatio( row, { rawHeight, rowWidth } ) {
- const cols = getRowCols( row );
-
- const colWidths = cols.map(
- col => ( rawHeight - GUTTER_WIDTH * ( col.childElementCount - 1 ) ) * getColumnRatio( col )[ 0 ]
- );
-
- const adjustedWidths = adjustFit( colWidths, rowWidth );
-
- cols.forEach( ( col, i ) => {
- const rawWidth = colWidths[ i ];
- const width = adjustedWidths[ i ];
- applyImgRatio( col, {
- colHeight: rawHeight - GUTTER_WIDTH * ( col.childElementCount - 1 ),
- width,
- rawWidth,
- } );
- } );
-}
-
-function applyImgRatio( col, { colHeight, width, rawWidth } ) {
- const imgHeights = getColImgs( col ).map( img => rawWidth / getImageRatio( img ) );
- const adjustedHeights = adjustFit( imgHeights, colHeight );
-
- // Set size of col children, not the <img /> element
- Array.from( col.children ).forEach( ( item, i ) => {
- const height = adjustedHeights[ i ];
- item.setAttribute( 'style', `height:${ height }px;width:${ width }px;` );
- } );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/row.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/row.js
deleted file mode 100644
index 200a58c2..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/row.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-
-export default function Row( { children, className } ) {
- return <div className={ classnames( 'tiled-gallery__row', className ) }>{ children }</div>;
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/square.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/square.js
deleted file mode 100644
index 2a1ab888..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/layout/square.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * External dependencies
- */
-import { chunk, drop, take } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import Row from './row';
-import Column from './column';
-import Gallery from './gallery';
-import { MAX_COLUMNS } from '../constants';
-
-export default function Square( { columns, renderedImages } ) {
- const columnCount = Math.min( MAX_COLUMNS, columns );
-
- const remainder = renderedImages.length % columnCount;
-
- return (
- <Gallery>
- { [
- ...( remainder ? [ take( renderedImages, remainder ) ] : [] ),
- ...chunk( drop( renderedImages, remainder ), columnCount ),
- ].map( ( imagesInRow, rowIndex ) => (
- <Row key={ rowIndex } className={ `columns-${ imagesInRow.length }` }>
- { imagesInRow.map( ( image, colIndex ) => (
- <Column key={ colIndex }>{ image }</Column>
- ) ) }
- </Row>
- ) ) }
- </Gallery>
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/save.js b/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/save.js
deleted file mode 100644
index 2a157a30..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/deprecated/v1/save.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Internal dependencies
- */
-import Layout from './layout';
-import { getActiveStyleName } from '../../../../shared/block-styles';
-import { LAYOUT_STYLES } from './constants';
-
-export function defaultColumnsNumber( attributes ) {
- return Math.min( 3, attributes.images.length );
-}
-
-export default function TiledGallerySave( { attributes } ) {
- const { images } = attributes;
-
- if ( ! images.length ) {
- return null;
- }
-
- const { align, className, columns = defaultColumnsNumber( attributes ), linkTo } = attributes;
-
- return (
- <Layout
- align={ align }
- className={ className }
- columns={ columns }
- images={ images }
- layoutStyle={ getActiveStyleName( LAYOUT_STYLES, className ) }
- linkTo={ linkTo }
- />
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/edit.js b/plugins/jetpack/extensions/blocks/tiled-gallery/edit.js
deleted file mode 100644
index 45574252..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/edit.js
+++ /dev/null
@@ -1,289 +0,0 @@
-/**
- * External Dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Component, Fragment } from '@wordpress/element';
-import { filter, get, pick } from 'lodash';
-import {
- BlockControls,
- BlockIcon,
- InspectorControls,
- MediaPlaceholder,
- MediaUpload,
- mediaUpload,
-} from '@wordpress/editor';
-import {
- DropZone,
- FormFileUpload,
- IconButton,
- PanelBody,
- RangeControl,
- SelectControl,
- Toolbar,
- withNotices,
-} from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import FilterToolbar from './filter-toolbar';
-import Layout from './layout';
-import { ALLOWED_MEDIA_TYPES, LAYOUT_STYLES, MAX_COLUMNS } from './constants';
-import { getActiveStyleName } from '../../shared/block-styles';
-import { icon } from '.';
-
-const linkOptions = [
- { value: 'attachment', label: __( 'Attachment Page', 'jetpack' ) },
- { value: 'media', label: __( 'Media File', 'jetpack' ) },
- { value: 'none', label: __( 'None', 'jetpack' ) },
-];
-
-// @TODO keep here or move to ./layout ?
-function layoutSupportsColumns( layout ) {
- return [ 'columns', 'circle', 'square' ].includes( layout );
-}
-
-export function defaultColumnsNumber( attributes ) {
- return Math.min( 3, attributes.images.length );
-}
-
-export const pickRelevantMediaFiles = image => {
- const imageProps = pick( image, [ [ 'alt' ], [ 'id' ], [ 'link' ] ] );
- imageProps.url =
- get( image, [ 'sizes', 'large', 'url' ] ) ||
- get( image, [ 'media_details', 'sizes', 'large', 'source_url' ] ) ||
- image.url;
- return imageProps;
-};
-
-class TiledGalleryEdit extends Component {
- state = {
- selectedImage: null,
- };
-
- static getDerivedStateFromProps( props, state ) {
- // Deselect images when deselecting the block
- if ( ! props.isSelected && null !== state.selectedImage ) {
- return { selectedImage: null };
- }
- return null;
- }
-
- setAttributes( attributes ) {
- if ( attributes.ids ) {
- throw new Error(
- 'The "ids" attribute should not be changed directly. It is managed automatically when "images" attribute changes'
- );
- }
-
- if ( attributes.images ) {
- attributes = {
- ...attributes,
- ids: attributes.images.map( ( { id } ) => parseInt( id, 10 ) ),
- };
- }
-
- this.props.setAttributes( attributes );
- }
-
- addFiles = files => {
- const currentImages = this.props.attributes.images || [];
- const { noticeOperations } = this.props;
- mediaUpload( {
- allowedTypes: ALLOWED_MEDIA_TYPES,
- filesList: files,
- onFileChange: images => {
- const imagesNormalized = images.map( image => pickRelevantMediaFiles( image ) );
- this.setAttributes( { images: currentImages.concat( imagesNormalized ) } );
- },
- onError: noticeOperations.createErrorNotice,
- } );
- };
-
- onRemoveImage = index => () => {
- const images = filter( this.props.attributes.images, ( img, i ) => index !== i );
- const { columns } = this.props.attributes;
- this.setState( {
- selectedImage: null,
- } );
- this.setAttributes( {
- images,
- columns: columns ? Math.min( images.length, columns ) : columns,
- } );
- };
-
- onSelectImage = index => () => {
- if ( this.state.selectedImage !== index ) {
- this.setState( {
- selectedImage: index,
- } );
- }
- };
-
- onSelectImages = images => {
- const { columns } = this.props.attributes;
- this.setAttributes( {
- columns: columns ? Math.min( images.length, columns ) : columns,
- images: images.map( image => pickRelevantMediaFiles( image ) ),
- } );
- };
-
- setColumnsNumber = value => this.setAttributes( { columns: value } );
-
- setImageAttributes = index => attributes => {
- const {
- attributes: { images },
- } = this.props;
- if ( ! images[ index ] ) {
- return;
- }
- this.setAttributes( {
- images: [
- ...images.slice( 0, index ),
- { ...images[ index ], ...attributes },
- ...images.slice( index + 1 ),
- ],
- } );
- };
-
- setLinkTo = value => this.setAttributes( { linkTo: value } );
-
- uploadFromFiles = event => this.addFiles( event.target.files );
-
- render() {
- const { selectedImage } = this.state;
- const {
- attributes,
- isSelected,
- className,
- noticeOperations,
- noticeUI,
- setAttributes,
- } = this.props;
- const {
- align,
- columns = defaultColumnsNumber( attributes ),
- imageFilter,
- images,
- linkTo,
- } = attributes;
-
- const dropZone = <DropZone onFilesDrop={ this.addFiles } />;
-
- const controls = (
- <BlockControls>
- { !! images.length && (
- <Fragment>
- <Toolbar>
- <MediaUpload
- onSelect={ this.onSelectImages }
- allowedTypes={ ALLOWED_MEDIA_TYPES }
- multiple
- gallery
- value={ images.map( img => img.id ) }
- render={ ( { open } ) => (
- <IconButton
- className="components-toolbar__control"
- label={ __( 'Edit Gallery', 'jetpack' ) }
- icon="edit"
- onClick={ open }
- />
- ) }
- />
- </Toolbar>
- <FilterToolbar
- value={ imageFilter }
- onChange={ value => {
- setAttributes( { imageFilter: value } );
- this.setState( { selectedImage: null } );
- } }
- />
- </Fragment>
- ) }
- </BlockControls>
- );
-
- if ( images.length === 0 ) {
- return (
- <Fragment>
- { controls }
- <MediaPlaceholder
- icon={ <BlockIcon icon={ icon } /> }
- className={ className }
- labels={ {
- title: __( 'Tiled Gallery', 'jetpack' ),
- name: __( 'images', 'jetpack' ),
- } }
- onSelect={ this.onSelectImages }
- accept="image/*"
- allowedTypes={ ALLOWED_MEDIA_TYPES }
- multiple
- notices={ noticeUI }
- onError={ noticeOperations.createErrorNotice }
- />
- </Fragment>
- );
- }
-
- const layoutStyle = getActiveStyleName( LAYOUT_STYLES, attributes.className );
-
- return (
- <Fragment>
- { controls }
- <InspectorControls>
- <PanelBody title={ __( 'Tiled Gallery settings', 'jetpack' ) }>
- { layoutSupportsColumns( layoutStyle ) && images.length > 1 && (
- <RangeControl
- label={ __( 'Columns', 'jetpack' ) }
- value={ columns }
- onChange={ this.setColumnsNumber }
- min={ 1 }
- max={ Math.min( MAX_COLUMNS, images.length ) }
- />
- ) }
- <SelectControl
- label={ __( 'Link To', 'jetpack' ) }
- value={ linkTo }
- onChange={ this.setLinkTo }
- options={ linkOptions }
- />
- </PanelBody>
- </InspectorControls>
-
- { noticeUI }
-
- <Layout
- align={ align }
- className={ className }
- columns={ columns }
- imageFilter={ imageFilter }
- images={ images }
- layoutStyle={ layoutStyle }
- linkTo={ linkTo }
- onRemoveImage={ this.onRemoveImage }
- onSelectImage={ this.onSelectImage }
- selectedImage={ isSelected ? selectedImage : null }
- setImageAttributes={ this.setImageAttributes }
- >
- { dropZone }
- { isSelected && (
- <div className="tiled-gallery__add-item">
- <FormFileUpload
- multiple
- isLarge
- className="tiled-gallery__add-item-button"
- onChange={ this.uploadFromFiles }
- accept="image/*"
- icon="insert"
- >
- { __( 'Upload an image', 'jetpack' ) }
- </FormFileUpload>
- </div>
- ) }
- </Layout>
- </Fragment>
- );
- }
-}
-
-export default withNotices( TiledGalleryEdit );
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/editor.js b/plugins/jetpack/extensions/blocks/tiled-gallery/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/editor.scss b/plugins/jetpack/extensions/blocks/tiled-gallery/editor.scss
deleted file mode 100644
index 7663d70c..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/editor.scss
+++ /dev/null
@@ -1,148 +0,0 @@
-@import './view.scss';
-@import './variables.scss';
-@import '../../shared/styles/gutenberg-colors.scss';
-
-// inspired by from assets/shared/_animations loading-fade
-@keyframes tiled-gallery-img-placeholder {
- 0% {
- background-color: var( --color-neutral-0 );
- }
- 50% {
- background-color: rgba( var( --color-neutral-0-rgb ), 0.5 );
- }
- 100% {
- background-color: var( --color-neutral-0 );
- }
-}
-
-.wp-block-jetpack-tiled-gallery {
- // Ensure that selected image outlines are visibile
- padding-left: 4px;
- padding-right: 4px;
-
- &.is-style-square,
- &.is-style-circle {
- .tiled-gallery__item.is-transient img {
- // Transient images (no src attribute) occupy no vertical space.
- // If on a row by themself, the row is hidden.
- // By setting the bottom margin, ensure they occupy the correct vertical space.
- margin-bottom: 100%;
- }
- }
-
- .tiled-gallery__item {
- // Hide the focus outline that otherwise briefly appears when selecting a block.
- > img:focus {
- outline: none;
- }
-
- > img {
- // Inspired by Calypso's placeholder mixin
- animation: tiled-gallery-img-placeholder 1.6s ease-in-out infinite;
- }
-
- &.is-selected {
- outline: 4px solid $tiled-gallery-selection;
-
- // Disable filters when selected
- filter: none;
- &::before,
- &::after {
- content: none;
- }
- }
-
- &.is-transient {
- height: 100%;
- width: 100%;
- img {
- background-position: center;
- background-size: cover;
- height: 100%;
- opacity: 0.3;
- width: 100%;
- }
- }
- }
-
- .tiled-gallery__add-item {
- margin-top: $tiled-gallery-gutter;
- width: 100%;
-
- .components-form-file-upload,
- .components-button.tiled-gallery__add-item-button {
- width: 100%;
- height: 100%;
- }
-
- .components-button.tiled-gallery__add-item-button {
- display: flex;
- flex-direction: column;
- justify-content: center;
- box-shadow: none;
- border: none;
- border-radius: 0;
- min-height: 100px;
-
- .dashicon {
- margin-top: 10px;
- }
-
- &:hover,
- &:focus {
- border: 1px solid $dark-gray-500;
- }
- }
- }
-
- .tiled-gallery__item__inline-menu {
- background-color: $tiled-gallery-selection;
- display: inline-flex;
- padding: 0 0 2px 2px;
- position: absolute;
- right: 0;
- top: 0;
-
- .components-button {
- color: var( --color-white );
- &:hover,
- &:focus {
- color: var( --color-white );
- }
- }
- }
-
- .tiled-gallery__item__remove {
- padding: 0;
- }
-
- .tiled-gallery__item .components-spinner {
- position: absolute;
- top: 50%;
- left: 50%;
- margin: 0;
- transform: translate( -50%, -50% );
- }
-
- // Hide upload buttons in style picker preview
- .editor-block-preview__content & {
- .editor-media-placeholder {
- display: none;
- }
- }
-}
-
-.tiled-gallery__filter-picker-menu {
- $active-item-outline-width: 2px;
- padding: 7px;
-
- // Leave space between elements for active state styling
- .components-menu-item__button + .components-menu-item__button {
- margin-top: $active-item-outline-width;
- }
-
- .components-menu-item__button.is-active {
- color: $dark-gray-900;
- box-shadow: 0 0 0 $active-item-outline-width $dark-gray-500 !important;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/filter-toolbar.js b/plugins/jetpack/extensions/blocks/tiled-gallery/filter-toolbar.js
deleted file mode 100644
index 7d86f335..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/filter-toolbar.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * External Dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { Dropdown, MenuItem, NavigableMenu, Path, SVG, Toolbar } from '@wordpress/components';
-
-const availableFilters = [
- {
- icon: (
- /* No filter */
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z" />
- </SVG>
- ),
- title: _x( 'Original', 'image style', 'jetpack' ),
- value: undefined,
- },
- {
- icon: (
- /* 1 */
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm11 10h2V5h-4v2h2v8zm7-14H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z" />
- </SVG>
- ),
- title: _x( 'Black and White', 'image style', 'jetpack' ),
- value: 'black-and-white',
- },
- {
- icon: (
- /* 2 */
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-4-4h-4v-2h2c1.1 0 2-.89 2-2V7c0-1.11-.9-2-2-2h-4v2h4v2h-2c-1.1 0-2 .89-2 2v4h6v-2z" />
- </SVG>
- ),
- title: _x( 'Sepia', 'image style', 'jetpack' ),
- value: 'sepia',
- },
- {
- icon: (
- /* 3 */
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M21 1H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm14 8v-1.5c0-.83-.67-1.5-1.5-1.5.83 0 1.5-.67 1.5-1.5V7c0-1.11-.9-2-2-2h-4v2h4v2h-2v2h2v2h-4v2h4c1.1 0 2-.89 2-2z" />
- </SVG>
- ),
- title: '1977',
- value: '1977',
- },
- {
- icon: (
- /* 4 */
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm12 10h2V5h-2v4h-2V5h-2v6h4v4zm6-14H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z" />
- </SVG>
- ),
- title: _x( 'Clarendon', 'image style', 'jetpack' ),
- value: 'clarendon',
- },
- {
- icon: (
- /* 5 */
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0z" />
- <Path d="M21 1H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm14 8v-2c0-1.11-.9-2-2-2h-2V7h4V5h-6v6h4v2h-4v2h4c1.1 0 2-.89 2-2z" />
- </SVG>
- ),
- title: _x( 'Gingham', 'image style', 'jetpack' ),
- value: 'gingham',
- },
-];
-
-const label = __( 'Pick an image filter', 'jetpack' );
-
-export default function FilterToolbar( { value, onChange } ) {
- return (
- <Dropdown
- position="bottom right"
- className="editor-block-switcher"
- contentClassName="editor-block-switcher__popover"
- renderToggle={ ( { onToggle, isOpen } ) => {
- return (
- <Toolbar
- controls={ [
- {
- onClick: onToggle,
- extraProps: {
- 'aria-haspopup': 'true',
- 'aria-expanded': isOpen,
- },
- title: label,
- tooltip: label,
- icon: (
- <SVG
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- >
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M19 10v9H4.98V5h9V3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-9h-2zm-2.94-2.06L17 10l.94-2.06L20 7l-2.06-.94L17 4l-.94 2.06L14 7zM12 8l-1.25 2.75L8 12l2.75 1.25L12 16l1.25-2.75L16 12l-2.75-1.25z" />
- </SVG>
- ),
- },
- ] }
- />
- );
- } }
- renderContent={ ( { onClose } ) => {
- const applyOrUnset = nextValue => () => {
- onChange( value === nextValue ? undefined : nextValue );
- onClose();
- };
- return (
- <NavigableMenu className="tiled-gallery__filter-picker-menu">
- { availableFilters.map( ( { icon, title, value: filterValue } ) => (
- <MenuItem
- className={ value === filterValue ? 'is-active' : undefined }
- icon={ icon }
- isSelected={ value === filterValue }
- key={ filterValue || 'original' }
- onClick={ applyOrUnset( filterValue ) }
- role="menuitemcheckbox"
- >
- { title }
- </MenuItem>
- ) ) }
- </NavigableMenu>
- );
- } }
- />
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js b/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js
deleted file mode 100644
index e4d77349..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * External Dependencies
- */
-import classnames from 'classnames';
-import { __ } from '@wordpress/i18n';
-import { BACKSPACE, DELETE } from '@wordpress/keycodes';
-import { Component, createRef, Fragment } from '@wordpress/element';
-import { IconButton, Spinner } from '@wordpress/components';
-import { isBlobURL } from '@wordpress/blob';
-import { withSelect } from '@wordpress/data';
-
-class GalleryImageEdit extends Component {
- img = createRef();
-
- onImageClick = () => {
- if ( ! this.props.isSelected ) {
- this.props.onSelect();
- }
- };
-
- onImageKeyDown = event => {
- if (
- this.img.current === document.activeElement &&
- this.props.isSelected &&
- [ BACKSPACE, DELETE ].includes( event.keyCode )
- ) {
- this.props.onRemove();
- }
- };
-
- componentDidUpdate() {
- const { alt, height, image, link, url, width } = this.props;
-
- if ( image ) {
- const nextAtts = {};
-
- if ( ! alt && image.alt_text ) {
- nextAtts.alt = image.alt_text;
- }
- if ( ! height && image.media_details && image.media_details.height ) {
- nextAtts.height = +image.media_details.height;
- }
- if ( ! link && image.link ) {
- nextAtts.link = image.link;
- }
- if ( ! url && image.source_url ) {
- nextAtts.url = image.source_url;
- }
- if ( ! width && image.media_details && image.media_details.width ) {
- nextAtts.width = +image.media_details.width;
- }
-
- if ( Object.keys( nextAtts ).length ) {
- this.props.setAttributes( nextAtts );
- }
- }
- }
-
- render() {
- const {
- 'aria-label': ariaLabel,
- alt,
- height,
- id,
- imageFilter,
- isSelected,
- link,
- linkTo,
- onRemove,
- origUrl,
- url,
- width,
- } = this.props;
-
- let href;
-
- switch ( linkTo ) {
- case 'media':
- href = url;
- break;
- case 'attachment':
- href = link;
- break;
- }
-
- const isTransient = isBlobURL( origUrl );
-
- const img = (
- // Disable reason: Image itself is not meant to be interactive, but should
- // direct image selection and unfocus caption fields.
- /* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex */
- <Fragment>
- <img
- alt={ alt }
- aria-label={ ariaLabel }
- data-height={ height }
- data-id={ id }
- data-link={ link }
- data-url={ origUrl }
- data-width={ width }
- onClick={ this.onImageClick }
- onKeyDown={ this.onImageKeyDown }
- ref={ this.img }
- src={ isTransient ? undefined : url }
- tabIndex="0"
- style={ isTransient ? { backgroundImage: `url(${ url })` } : undefined }
- />
- { isTransient && <Spinner /> }
- </Fragment>
- /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex */
- );
-
- // Disable reason: Each block can be selected by clicking on it and we should keep the same saved markup
- return (
- <figure
- className={ classnames( 'tiled-gallery__item', {
- 'is-selected': isSelected,
- 'is-transient': isTransient,
- [ `filter__${ imageFilter }` ]: !! imageFilter,
- } ) }
- >
- { isSelected && (
- <div className="tiled-gallery__item__inline-menu">
- <IconButton
- icon="no-alt"
- onClick={ onRemove }
- className="tiled-gallery__item__remove"
- label={ __( 'Remove Image', 'jetpack' ) }
- />
- </div>
- ) }
- { /* Keep the <a> HTML structure, but ensure there is no navigation from edit */
- /* eslint-disable-next-line jsx-a11y/anchor-is-valid */ }
- { href ? <a>{ img }</a> : img }
- </figure>
- );
- }
-}
-
-export default withSelect( ( select, ownProps ) => {
- const { getMedia } = select( 'core' );
- const { id } = ownProps;
-
- return {
- image: id ? getMedia( id ) : null,
- };
-} )( GalleryImageEdit );
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/save.js b/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/save.js
deleted file mode 100644
index 347a6f85..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/save.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * External Dependencies
- */
-import classnames from 'classnames';
-import { isBlobURL } from '@wordpress/blob';
-
-export default function GalleryImageSave( props ) {
- const { alt, imageFilter, height, id, link, linkTo, origUrl, url, width } = props;
-
- if ( isBlobURL( origUrl ) ) {
- return null;
- }
-
- let href;
-
- switch ( linkTo ) {
- case 'media':
- href = url;
- break;
- case 'attachment':
- href = link;
- break;
- }
-
- const img = (
- <img
- alt={ alt }
- data-height={ height }
- data-id={ id }
- data-link={ link }
- data-url={ origUrl }
- data-width={ width }
- src={ url }
- />
- );
-
- return (
- <figure
- className={ classnames( 'tiled-gallery__item', {
- [ `filter__${ imageFilter }` ]: !! imageFilter,
- } ) }
- >
- { href ? <a href={ href }>{ img }</a> : img }
- </figure>
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/index.js
deleted file mode 100644
index 42079113..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/index.js
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '@wordpress/i18n';
-import { createBlock } from '@wordpress/blocks';
-import { filter } from 'lodash';
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import {
- LAYOUT_CIRCLE,
- LAYOUT_COLUMN,
- LAYOUT_DEFAULT,
- LAYOUT_SQUARE,
- LAYOUT_STYLES,
-} from './constants';
-
-/**
- * Style dependencies
- */
-import './editor.scss';
-
-import * as deprecatedV1 from './deprecated/v1';
-
-// Style names are translated. Avoid introducing an i18n dependency elsewhere (view)
-// by only including the labels here, the only place they're needed.
-//
-// Map style names to labels and merge them together.
-const styleNames = {
- [ LAYOUT_DEFAULT ]: _x( 'Tiled mosaic', 'Tiled gallery layout', 'jetpack' ),
- [ LAYOUT_CIRCLE ]: _x( 'Circles', 'Tiled gallery layout', 'jetpack' ),
- [ LAYOUT_COLUMN ]: _x( 'Tiled columns', 'Tiled gallery layout', 'jetpack' ),
- [ LAYOUT_SQUARE ]: _x( 'Square tiles', 'Tiled gallery layout', 'jetpack' ),
-};
-const layoutStylesWithLabels = LAYOUT_STYLES.map( style => ( {
- ...style,
- label: styleNames[ style.name ],
-} ) );
-
-/**
- * Filter valid images
- *
- * @param {array} images Array of image objects
- * @return {array} Array of image objects which have id and url
- */
-function getValidImages( images ) {
- return filter( images, ( { id, url } ) => id && url );
-}
-
-const blockAttributes = {
- // Set default align
- align: {
- default: 'center',
- type: 'string',
- },
- // Set default className (used with block styles)
- className: {
- default: `is-style-${ LAYOUT_DEFAULT }`,
- type: 'string',
- },
- columns: {
- type: 'number',
- },
- ids: {
- default: [],
- type: 'array',
- },
- imageFilter: {
- type: 'string',
- },
- images: {
- type: 'array',
- default: [],
- source: 'query',
- selector: '.tiled-gallery__item',
- query: {
- alt: {
- attribute: 'alt',
- default: '',
- selector: 'img',
- source: 'attribute',
- },
- height: {
- attribute: 'data-height',
- selector: 'img',
- source: 'attribute',
- type: 'number',
- },
- id: {
- attribute: 'data-id',
- selector: 'img',
- source: 'attribute',
- },
- link: {
- attribute: 'data-link',
- selector: 'img',
- source: 'attribute',
- },
- url: {
- attribute: 'data-url',
- selector: 'img',
- source: 'attribute',
- },
- width: {
- attribute: 'data-width',
- selector: 'img',
- source: 'attribute',
- type: 'number',
- },
- },
- },
- linkTo: {
- default: 'none',
- type: 'string',
- },
-};
-
-export const name = 'tiled-gallery';
-
-export const icon = (
- <SVG viewBox="0 0 24 24" width={ 24 } height={ 24 }>
- <Path
- fill="currentColor"
- d="M19 5v2h-4V5h4M9 5v6H5V5h4m10 8v6h-4v-6h4M9 17v2H5v-2h4M21 3h-8v6h8V3zM11 3H3v10h8V3zm10 8h-8v10h8V11zm-10 4H3v6h8v-6z"
- />
- </SVG>
-);
-
-export const settings = {
- attributes: blockAttributes,
- category: 'jetpack',
- description: __( 'Display multiple images in an elegantly organized tiled layout.', 'jetpack' ),
- icon,
- keywords: [
- _x( 'images', 'block search term', 'jetpack' ),
- _x( 'photos', 'block search term', 'jetpack' ),
- _x( 'pictures', 'block search term', 'jetpack' ),
- ],
- styles: layoutStylesWithLabels,
- supports: {
- align: [ 'center', 'wide', 'full' ],
- customClassName: false,
- html: false,
- },
- title: __( 'Tiled Gallery', 'jetpack' ),
- transforms: {
- from: [
- {
- type: 'block',
- isMultiBlock: true,
- blocks: [ 'core/image' ],
- isMatch: images => getValidImages( images ).length > 0,
- transform: images => {
- const validImages = getValidImages( images );
- return createBlock( `jetpack/${ name }`, {
- images: validImages.map( ( { id, url, alt } ) => ( {
- id,
- url,
- alt,
- } ) ),
- ids: validImages.map( ( { id } ) => id ),
- } );
- },
- },
- {
- type: 'block',
- blocks: [ 'core/gallery', 'jetpack/slideshow' ],
- transform: ( { images } ) => {
- const validImages = getValidImages( images );
- if ( validImages.length > 0 ) {
- return createBlock( `jetpack/${ name }`, {
- images: validImages.map( ( { id, url, alt } ) => ( {
- id,
- url,
- alt,
- } ) ),
- ids: validImages.map( ( { id } ) => id ),
- } );
- }
- return createBlock( `jetpack/${ name }` );
- },
- },
- ],
- to: [
- {
- type: 'block',
- blocks: [ 'core/gallery' ],
- transform: ( { images, ids, columns, linkTo } ) =>
- createBlock( 'core/gallery', { images, ids, columns, imageCrop: true, linkTo } ),
- },
- {
- type: 'block',
- blocks: [ 'core/image' ],
- transform: ( { align, images } ) => {
- if ( images.length > 0 ) {
- return images.map( ( { id, url, alt } ) =>
- createBlock( 'core/image', { align, id, url, alt } )
- );
- }
- return createBlock( 'core/image' );
- },
- },
- ],
- },
- edit,
- save,
- deprecated: [ deprecatedV1 ],
-};
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/column.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/column.js
deleted file mode 100644
index a3ed5cdf..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/column.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Column( { children } ) {
- return <div className="tiled-gallery__col">{ children }</div>;
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/gallery.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/gallery.js
deleted file mode 100644
index 94fc61e4..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/gallery.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function Gallery( { children, galleryRef } ) {
- return (
- <div className="tiled-gallery__gallery" ref={ galleryRef }>
- { children }
- </div>
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/index.js
deleted file mode 100644
index abcb5641..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/index.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * External dependencies
- */
-import photon from 'photon';
-import { __, sprintf } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { format as formatUrl, parse as parseUrl } from 'url';
-import { isBlobURL } from '@wordpress/blob';
-
-/**
- * Internal dependencies
- */
-import GalleryImageEdit from '../gallery-image/edit';
-import GalleryImageSave from '../gallery-image/save';
-import Mosaic from './mosaic';
-import Square from './square';
-import { PHOTON_MAX_RESIZE } from '../constants';
-
-export default class Layout extends Component {
- photonize( { height, width, url } ) {
- if ( ! url ) {
- return;
- }
-
- // Do not Photonize images that are still uploading or from localhost
- if ( isBlobURL( url ) || /^https?:\/\/localhost/.test( url ) ) {
- return url;
- }
-
- // Drop query args, photon URLs can't handle them
- // This should be the "raw" url, we'll add dimensions later
- const cleanUrl = url.split( '?', 1 )[ 0 ];
-
- const photonImplementation = isWpcomFilesUrl( url ) ? photonWpcomImage : photon;
-
- const { layoutStyle } = this.props;
-
- if ( isSquareishLayout( layoutStyle ) && width && height ) {
- const size = Math.min( PHOTON_MAX_RESIZE, width, height );
- return photonImplementation( cleanUrl, { resize: `${ size },${ size }` } );
- }
- return photonImplementation( cleanUrl );
- }
-
- // This is tricky:
- // - We need to "photonize" to resize the images at appropriate dimensions
- // - The resize will depend on the image size and the layout in some cases
- // - Handlers need to be created by index so that the image changes can be applied correctly.
- // This is because the images are stored in an array in the block attributes.
- renderImage( img, i ) {
- const {
- imageFilter,
- images,
- isSave,
- linkTo,
- onRemoveImage,
- onSelectImage,
- selectedImage,
- setImageAttributes,
- } = this.props;
-
- /* translators: %1$d is the order number of the image, %2$d is the total number of images. */
- const ariaLabel = sprintf(
- __( 'image %1$d of %2$d in gallery', 'jetpack' ),
- i + 1,
- images.length
- );
- const Image = isSave ? GalleryImageSave : GalleryImageEdit;
-
- return (
- <Image
- alt={ img.alt }
- aria-label={ ariaLabel }
- height={ img.height }
- id={ img.id }
- imageFilter={ imageFilter }
- isSelected={ selectedImage === i }
- key={ i }
- link={ img.link }
- linkTo={ linkTo }
- onRemove={ isSave ? undefined : onRemoveImage( i ) }
- onSelect={ isSave ? undefined : onSelectImage( i ) }
- origUrl={ img.url }
- setAttributes={ isSave ? undefined : setImageAttributes( i ) }
- url={ this.photonize( img ) }
- width={ img.width }
- />
- );
- }
-
- render() {
- const { align, children, className, columns, images, layoutStyle } = this.props;
-
- const LayoutRenderer = isSquareishLayout( layoutStyle ) ? Square : Mosaic;
-
- const renderedImages = this.props.images.map( this.renderImage, this );
-
- return (
- <div className={ className }>
- <LayoutRenderer
- align={ align }
- columns={ columns }
- images={ images }
- layoutStyle={ layoutStyle }
- renderedImages={ renderedImages }
- />
- { children }
- </div>
- );
- }
-}
-
-function isSquareishLayout( layout ) {
- return [ 'circle', 'square' ].includes( layout );
-}
-
-function isWpcomFilesUrl( url ) {
- const { host } = parseUrl( url );
- return /\.files\.wordpress\.com$/.test( host );
-}
-
-/**
- * Apply photon arguments to *.files.wordpress.com images
- *
- * This function largely duplicates the functionlity of the photon.js lib.
- * This is necessary because we want to serve images from *.files.wordpress.com so that private
- * WordPress.com sites can use this block which depends on a Photon-like image service.
- *
- * If we pass all images through Photon servers, some images are unreachable. *.files.wordpress.com
- * is already photon-like so we can pass it the same parameters for image resizing.
- *
- * @param {string} url Image url
- * @param {Object} opts Options to pass to photon
- *
- * @return {string} Url string with options applied
- */
-function photonWpcomImage( url, opts = {} ) {
- // Adhere to the same options API as the photon.js lib
- const photonLibMappings = {
- width: 'w',
- height: 'h',
- letterboxing: 'lb',
- removeLetterboxing: 'ulb',
- };
-
- // Discard some param parts
- const { auth, hash, port, query, search, ...urlParts } = parseUrl( url );
-
- // Build query
- // This reduction intentionally mutates the query as it is built internally.
- urlParts.query = Object.keys( opts ).reduce(
- ( q, key ) =>
- Object.assign( q, {
- [ photonLibMappings.hasOwnProperty( key ) ? photonLibMappings[ key ] : key ]: opts[ key ],
- } ),
- {}
- );
-
- return formatUrl( urlParts );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/index.js
deleted file mode 100644
index 8c56b164..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/index.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * External dependencies
- */
-import { Component, createRef } from '@wordpress/element';
-import ResizeObserver from 'resize-observer-polyfill';
-
-/**
- * Internal dependencies
- */
-import Column from '../column';
-import Gallery from '../gallery';
-import Row from '../row';
-import { getGalleryRows, handleRowResize } from './resize';
-import { imagesToRatios, ratiosToColumns, ratiosToMosaicRows } from './ratios';
-
-export default class Mosaic extends Component {
- gallery = createRef();
- pendingRaf = null;
- ro = null; // resizeObserver instance
-
- componentDidMount() {
- this.observeResize();
- }
-
- componentWillUnmount() {
- this.unobserveResize();
- }
-
- componentDidUpdate( prevProps ) {
- if ( prevProps.images !== this.props.images || prevProps.align !== this.props.align ) {
- this.triggerResize();
- } else if ( 'columns' === this.props.layoutStyle && prevProps.columns !== this.props.columns ) {
- this.triggerResize();
- }
- }
-
- handleGalleryResize = entries => {
- if ( this.pendingRaf ) {
- cancelAnimationFrame( this.pendingRaf );
- this.pendingRaf = null;
- }
- this.pendingRaf = requestAnimationFrame( () => {
- for ( const { contentRect, target } of entries ) {
- const { width } = contentRect;
- getGalleryRows( target ).forEach( row => handleRowResize( row, width ) );
- }
- } );
- };
-
- triggerResize() {
- if ( this.gallery.current ) {
- this.handleGalleryResize( [
- {
- target: this.gallery.current,
- contentRect: { width: this.gallery.current.clientWidth },
- },
- ] );
- }
- }
-
- observeResize() {
- this.triggerResize();
- this.ro = new ResizeObserver( this.handleGalleryResize );
- if ( this.gallery.current ) {
- this.ro.observe( this.gallery.current );
- }
- }
-
- unobserveResize() {
- if ( this.ro ) {
- this.ro.disconnect();
- this.ro = null;
- }
- if ( this.pendingRaf ) {
- cancelAnimationFrame( this.pendingRaf );
- this.pendingRaf = null;
- }
- }
-
- render() {
- const { align, columns, images, layoutStyle, renderedImages } = this.props;
-
- const ratios = imagesToRatios( images );
- const rows =
- 'columns' === layoutStyle
- ? ratiosToColumns( ratios, columns )
- : ratiosToMosaicRows( ratios, { isWide: [ 'full', 'wide' ].includes( align ) } );
-
- let cursor = 0;
- return (
- <Gallery galleryRef={ this.gallery }>
- { rows.map( ( row, rowIndex ) => (
- <Row key={ rowIndex }>
- { row.map( ( colSize, colIndex ) => {
- const columnImages = renderedImages.slice( cursor, cursor + colSize );
- cursor += colSize;
- return <Column key={ colIndex }>{ columnImages }</Column>;
- } ) }
- </Row>
- ) ) }
- </Gallery>
- );
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/ratios.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/ratios.js
deleted file mode 100644
index 8accd552..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/ratios.js
+++ /dev/null
@@ -1,280 +0,0 @@
-/**
- * External dependencies
- */
-import {
- drop,
- every,
- isEqual,
- map,
- overEvery,
- some,
- sum,
- take,
- takeRight,
- takeWhile,
- zipWith,
-} from 'lodash';
-
-export function imagesToRatios( images ) {
- return map( images, ratioFromImage );
-}
-
-export function ratioFromImage( { height, width } ) {
- return height && width ? width / height : 1;
-}
-
-/**
- * Build three columns, each of which should contain approximately 1/3 of the total ratio
- *
- * @param {Array.<number>} ratios Ratios of images put into shape
- * @param {number} columnCount Number of columns
- *
- * @return {Array.<Array.<number>>} Shape of rows and columns
- */
-export function ratiosToColumns( ratios, columnCount ) {
- // If we don't have more than 1 per column, just return a simple 1 ratio per column shape
- if ( ratios.length <= columnCount ) {
- return [ Array( ratios.length ).fill( 1 ) ];
- }
-
- const total = sum( ratios );
- const targetColRatio = total / columnCount;
-
- const row = [];
- let toProcess = ratios;
- let accumulatedRatio = 0;
-
- // We skip the last column in the loop and add rest later
- for ( let i = 0; i < columnCount - 1; i++ ) {
- const colSize = takeWhile( toProcess, ratio => {
- const shouldTake = accumulatedRatio <= ( i + 1 ) * targetColRatio;
- if ( shouldTake ) {
- accumulatedRatio += ratio;
- }
- return shouldTake;
- } ).length;
- row.push( colSize );
- toProcess = drop( toProcess, colSize );
- }
-
- // Don't calculate last column, just add what's left
- row.push( toProcess.length );
-
- // A shape is an array of rows. Wrap our row in an array.
- return [ row ];
-}
-
-/**
- * These are partially applied functions.
- * They rely on helper function (defined below) to create a function that expects to be passed ratios
- * during processing.
- *
- * …FitsNextImages() functions should be passed ratios to be processed
- * …IsNotRecent() functions should be passed the processed shapes
- */
-
-const reverseSymmetricRowIsNotRecent = isNotRecentShape( [ 2, 1, 2 ], 5 );
-const reverseSymmetricFitsNextImages = checkNextRatios( [
- isLandscape,
- isLandscape,
- isPortrait,
- isLandscape,
- isLandscape,
-] );
-const longSymmetricRowFitsNextImages = checkNextRatios( [
- isLandscape,
- isLandscape,
- isLandscape,
- isPortrait,
- isLandscape,
- isLandscape,
- isLandscape,
-] );
-const longSymmetricRowIsNotRecent = isNotRecentShape( [ 3, 1, 3 ], 5 );
-const symmetricRowFitsNextImages = checkNextRatios( [
- isPortrait,
- isLandscape,
- isLandscape,
- isPortrait,
-] );
-const symmetricRowIsNotRecent = isNotRecentShape( [ 1, 2, 1 ], 5 );
-const oneThreeFitsNextImages = checkNextRatios( [
- isPortrait,
- isLandscape,
- isLandscape,
- isLandscape,
-] );
-const oneThreeIsNotRecent = isNotRecentShape( [ 1, 3 ], 3 );
-const threeOneIsFitsNextImages = checkNextRatios( [
- isLandscape,
- isLandscape,
- isLandscape,
- isPortrait,
-] );
-const threeOneIsNotRecent = isNotRecentShape( [ 3, 1 ], 3 );
-const oneTwoFitsNextImages = checkNextRatios( [
- lt( 1.6 ),
- overEvery( gte( 0.9 ), lt( 2 ) ),
- overEvery( gte( 0.9 ), lt( 2 ) ),
-] );
-const oneTwoIsNotRecent = isNotRecentShape( [ 1, 2 ], 3 );
-const fiveIsNotRecent = isNotRecentShape( [ 1, 1, 1, 1, 1 ], 1 );
-const fourIsNotRecent = isNotRecentShape( [ 1, 1, 1, 1 ], 1 );
-const threeIsNotRecent = isNotRecentShape( [ 1, 1, 1 ], 3 );
-const twoOneFitsNextImages = checkNextRatios( [
- overEvery( gte( 0.9 ), lt( 2 ) ),
- overEvery( gte( 0.9 ), lt( 2 ) ),
- lt( 1.6 ),
-] );
-const twoOneIsNotRecent = isNotRecentShape( [ 2, 1 ], 3 );
-const panoramicFitsNextImages = checkNextRatios( [ isPanoramic ] );
-
-export function ratiosToMosaicRows( ratios, { isWide } = {} ) {
- // This function will recursively process the input until it is consumed
- const go = ( processed, toProcess ) => {
- if ( ! toProcess.length ) {
- return processed;
- }
-
- let next;
-
- if (
- /* Reverse_Symmetric_Row */
- toProcess.length > 15 &&
- reverseSymmetricFitsNextImages( toProcess ) &&
- reverseSymmetricRowIsNotRecent( processed )
- ) {
- next = [ 2, 1, 2 ];
- } else if (
- /* Long_Symmetric_Row */
- toProcess.length > 15 &&
- longSymmetricRowFitsNextImages( toProcess ) &&
- longSymmetricRowIsNotRecent( processed )
- ) {
- next = [ 3, 1, 3 ];
- } else if (
- /* Symmetric_Row */
- toProcess.length !== 5 &&
- symmetricRowFitsNextImages( toProcess ) &&
- symmetricRowIsNotRecent( processed )
- ) {
- next = [ 1, 2, 1 ];
- } else if (
- /* One_Three */
- oneThreeFitsNextImages( toProcess ) &&
- oneThreeIsNotRecent( processed )
- ) {
- next = [ 1, 3 ];
- } else if (
- /* Three_One */
- threeOneIsFitsNextImages( toProcess ) &&
- threeOneIsNotRecent( processed )
- ) {
- next = [ 3, 1 ];
- } else if (
- /* One_Two */
- oneTwoFitsNextImages( toProcess ) &&
- oneTwoIsNotRecent( processed )
- ) {
- next = [ 1, 2 ];
- } else if (
- /* Five */
- isWide &&
- ( toProcess.length === 5 || ( toProcess.length !== 10 && toProcess.length > 6 ) ) &&
- fiveIsNotRecent( processed ) &&
- sum( take( toProcess, 5 ) ) < 5
- ) {
- next = [ 1, 1, 1, 1, 1 ];
- } else if (
- /* Four */
- isFourValidCandidate( processed, toProcess )
- ) {
- next = [ 1, 1, 1, 1 ];
- } else if (
- /* Three */
- isThreeValidCandidate( processed, toProcess, isWide )
- ) {
- next = [ 1, 1, 1 ];
- } else if (
- /* Two_One */
- twoOneFitsNextImages( toProcess ) &&
- twoOneIsNotRecent( processed )
- ) {
- next = [ 2, 1 ];
- } else if ( /* Panoramic */ panoramicFitsNextImages( toProcess ) ) {
- next = [ 1 ];
- } else if ( /* One_One */ toProcess.length > 3 ) {
- next = [ 1, 1 ];
- } else {
- // Everything left
- next = Array( toProcess.length ).fill( 1 );
- }
-
- // Add row
- const nextProcessed = processed.concat( [ next ] );
-
- // Trim consumed images from next processing step
- const consumedImages = sum( next );
- const nextToProcess = toProcess.slice( consumedImages );
-
- return go( nextProcessed, nextToProcess );
- };
- return go( [], ratios );
-}
-
-function isThreeValidCandidate( processed, toProcess, isWide ) {
- const ratio = sum( take( toProcess, 3 ) );
- return (
- toProcess.length >= 3 &&
- toProcess.length !== 4 &&
- toProcess.length !== 6 &&
- threeIsNotRecent( processed ) &&
- ( ratio < 2.5 ||
- ( ratio < 5 &&
- /* nextAreSymettric */
- ( toProcess.length >= 3 &&
- /* @FIXME floating point equality?? */ toProcess[ 0 ] === toProcess[ 2 ] ) ) ||
- isWide )
- );
-}
-
-function isFourValidCandidate( processed, toProcess ) {
- const ratio = sum( take( toProcess, 4 ) );
- return (
- ( fourIsNotRecent( processed ) && ( ratio < 3.5 && toProcess.length > 5 ) ) ||
- ( ratio < 7 && toProcess.length === 4 )
- );
-}
-
-function isNotRecentShape( shape, numRecents ) {
- return recents =>
- ! some( takeRight( recents, numRecents ), recentShape => isEqual( recentShape, shape ) );
-}
-
-function checkNextRatios( shape ) {
- return ratios =>
- ratios.length >= shape.length &&
- every( zipWith( shape, ratios.slice( 0, shape.length ), ( f, r ) => f( r ) ) );
-}
-
-function isLandscape( ratio ) {
- return ratio >= 1 && ratio < 2;
-}
-
-function isPortrait( ratio ) {
- return ratio < 1;
-}
-
-function isPanoramic( ratio ) {
- return ratio >= 2;
-}
-
-// >=
-function gte( n ) {
- return m => m >= n;
-}
-
-// <
-function lt( n ) {
- return m => m < n;
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/resize.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/resize.js
deleted file mode 100644
index 022729c8..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/resize.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Internal dependencies
- */
-import { GUTTER_WIDTH } from '../../constants';
-
-/**
- * Distribute a difference across ns so that their sum matches the target
- *
- * @param {Array<number>} parts Array of numbers to fit
- * @param {number} target Number that sum should match
- * @return {Array<number>} Adjusted parts
- */
-function adjustFit( parts, target ) {
- const diff = target - parts.reduce( ( sum, n ) => sum + n, 0 );
- const partialDiff = diff / parts.length;
- return parts.map( p => p + partialDiff );
-}
-
-export function handleRowResize( row, width ) {
- applyRowRatio( row, getRowRatio( row ), width );
-}
-
-function getRowRatio( row ) {
- const result = getRowCols( row )
- .map( getColumnRatio )
- .reduce(
- ( [ ratioA, weightedRatioA ], [ ratioB, weightedRatioB ] ) => {
- return [ ratioA + ratioB, weightedRatioA + weightedRatioB ];
- },
- [ 0, 0 ]
- );
- return result;
-}
-
-export function getGalleryRows( gallery ) {
- return Array.from( gallery.querySelectorAll( '.tiled-gallery__row' ) );
-}
-
-function getRowCols( row ) {
- return Array.from( row.querySelectorAll( '.tiled-gallery__col' ) );
-}
-
-function getColImgs( col ) {
- return Array.from(
- col.querySelectorAll( '.tiled-gallery__item > img, .tiled-gallery__item > a > img' )
- );
-}
-
-function getColumnRatio( col ) {
- const imgs = getColImgs( col );
- const imgCount = imgs.length;
- const ratio =
- 1 /
- imgs.map( getImageRatio ).reduce( ( partialColRatio, imgRatio ) => {
- return partialColRatio + 1 / imgRatio;
- }, 0 );
- const result = [ ratio, ratio * imgCount || 1 ];
- return result;
-}
-
-function getImageRatio( img ) {
- const w = parseInt( img.dataset.width, 10 );
- const h = parseInt( img.dataset.height, 10 );
- const result = w && ! Number.isNaN( w ) && h && ! Number.isNaN( h ) ? w / h : 1;
- return result;
-}
-
-function applyRowRatio( row, [ ratio, weightedRatio ], width ) {
- const rawHeight =
- ( 1 / ratio ) * ( width - GUTTER_WIDTH * ( row.childElementCount - 1 ) - weightedRatio );
-
- applyColRatio( row, {
- rawHeight,
- rowWidth: width - GUTTER_WIDTH * ( row.childElementCount - 1 ),
- } );
-}
-
-function applyColRatio( row, { rawHeight, rowWidth } ) {
- const cols = getRowCols( row );
-
- const colWidths = cols.map(
- col => ( rawHeight - GUTTER_WIDTH * ( col.childElementCount - 1 ) ) * getColumnRatio( col )[ 0 ]
- );
-
- const adjustedWidths = adjustFit( colWidths, rowWidth );
-
- cols.forEach( ( col, i ) => {
- const rawWidth = colWidths[ i ];
- const width = adjustedWidths[ i ];
- applyImgRatio( col, {
- colHeight: rawHeight - GUTTER_WIDTH * ( col.childElementCount - 1 ),
- width,
- rawWidth,
- } );
- } );
-}
-
-function applyImgRatio( col, { colHeight, width, rawWidth } ) {
- const imgHeights = getColImgs( col ).map( img => rawWidth / getImageRatio( img ) );
- const adjustedHeights = adjustFit( imgHeights, colHeight );
-
- // Set size of col children, not the <img /> element
- Array.from( col.children ).forEach( ( item, i ) => {
- const height = adjustedHeights[ i ];
- item.setAttribute( 'style', `height:${ height }px;width:${ width }px;` );
- } );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/index.js.snap b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/index.js.snap
deleted file mode 100644
index e726fa52..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/index.js.snap
+++ /dev/null
@@ -1,98 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders as expected 1`] = `
-<Gallery
- galleryRef={
- Object {
- "current": null,
- }
- }
->
- <Row
- key="0"
- >
- <Column
- key="0"
- >
- 0
- </Column>
- </Row>
- <Row
- key="1"
- >
- <Column
- key="0"
- >
- 1
- </Column>
- </Row>
- <Row
- key="2"
- >
- <Column
- key="0"
- >
- 2
- </Column>
- <Column
- key="1"
- >
- 3
- </Column>
- <Column
- key="2"
- >
- 4
- </Column>
- <Column
- key="3"
- >
- 5
- </Column>
- </Row>
- <Row
- key="3"
- >
- <Column
- key="0"
- >
- 6
- </Column>
- <Column
- key="1"
- >
- 7
- </Column>
- </Row>
- <Row
- key="4"
- >
- <Column
- key="0"
- >
- 8
- </Column>
- <Column
- key="1"
- >
- 9
- 10
- </Column>
- </Row>
- <Row
- key="5"
- >
- <Column
- key="0"
- >
- 11
- 12
- </Column>
- <Column
- key="1"
- >
- 13
- </Column>
- </Row>
-</Gallery>
-`;
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/ratios.js.snap b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/ratios.js.snap
deleted file mode 100644
index df02118c..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/ratios.js.snap
+++ /dev/null
@@ -1,30 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ratiosToMosaicRows transforms as expected 1`] = `
-Array [
- Array [
- 1,
- ],
- Array [
- 1,
- ],
- Array [
- 1,
- 1,
- 1,
- 1,
- ],
- Array [
- 1,
- 1,
- ],
- Array [
- 1,
- 2,
- ],
- Array [
- 2,
- 1,
- ],
-]
-`;
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/fixtures/ratios.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/fixtures/ratios.js
deleted file mode 100644
index 77db288c..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/fixtures/ratios.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export const ratios = [
- 4,
- 2.26056338028169,
- 0.6676143094053542,
- 0.75,
- 0.7444409646100846,
- 0.6666666666666666,
- 0.8000588062334607,
- 3.6392174704276616,
- 1.335559265442404,
- 1.509433962264151,
- 1.6,
- 1.3208430913348945,
- 1.3553937789543349,
- 1.499531396438613,
-];
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/index.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/index.js
deleted file mode 100644
index 72e49ba6..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * External dependencies
- */
-import React from 'react';
-import { range } from 'lodash';
-import { shallow } from 'enzyme';
-
-/**
- * Internal dependencies
- */
-import Mosaic from '..';
-import * as imageSets from '../../test/fixtures/image-sets';
-
-test( 'renders as expected', () => {
- Object.keys( imageSets ).forEach( k => {
- const images = imageSets[ k ];
- expect(
- shallow( <Mosaic images={ images } renderedImages={ range( images.length ) } /> )
- ).toMatchSnapshot();
- } );
-} );
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/ratios.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/ratios.js
deleted file mode 100644
index 3756b971..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/mosaic/test/ratios.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Internal dependencies
- */
-import { ratiosToMosaicRows } from '../ratios';
-import { ratios } from './fixtures/ratios';
-
-describe( 'ratiosToMosaicRows', () => {
- test( 'transforms as expected', () => {
- expect( ratiosToMosaicRows( ratios ) ).toMatchSnapshot();
- } );
-} );
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/row.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/row.js
deleted file mode 100644
index 200a58c2..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/row.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-
-export default function Row( { children, className } ) {
- return <div className={ classnames( 'tiled-gallery__row', className ) }>{ children }</div>;
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/square.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/square.js
deleted file mode 100644
index 2a1ab888..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/square.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * External dependencies
- */
-import { chunk, drop, take } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import Row from './row';
-import Column from './column';
-import Gallery from './gallery';
-import { MAX_COLUMNS } from '../constants';
-
-export default function Square( { columns, renderedImages } ) {
- const columnCount = Math.min( MAX_COLUMNS, columns );
-
- const remainder = renderedImages.length % columnCount;
-
- return (
- <Gallery>
- { [
- ...( remainder ? [ take( renderedImages, remainder ) ] : [] ),
- ...chunk( drop( renderedImages, remainder ), columnCount ),
- ].map( ( imagesInRow, rowIndex ) => (
- <Row key={ rowIndex } className={ `columns-${ imagesInRow.length }` }>
- { imagesInRow.map( ( image, colIndex ) => (
- <Column key={ colIndex }>{ image }</Column>
- ) ) }
- </Row>
- ) ) }
- </Gallery>
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/test/fixtures/image-sets.js b/plugins/jetpack/extensions/blocks/tiled-gallery/layout/test/fixtures/image-sets.js
deleted file mode 100644
index fd477f5a..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/layout/test/fixtures/image-sets.js
+++ /dev/null
@@ -1,103 +0,0 @@
-export const imageSet1 = [
- {
- alt: '',
- id: 163,
- url: 'https://example.files.wordpress.com/2018/12/architecture-bay-bridge-356830.jpg',
- height: 2048,
- width: 8192,
- },
- {
- alt: '',
- id: 162,
- url: 'https://example.files.wordpress.com/2018/12/bloom-blossom-flora-40797-1.jpg',
- height: 1562,
- width: 3531,
- },
- {
- alt: '',
- id: 161,
- url: 'https://example.files.wordpress.com/2018/12/architecture-building-city-597049.jpg',
- height: 4221,
- width: 2818,
- },
- {
- alt: '',
- id: 160,
- url: 'https://example.files.wordpress.com/2018/12/architecture-art-blue-699466.jpg',
- height: 4032,
- width: 3024,
- },
- {
- alt: '',
- id: 159,
- url:
- 'https://example.files.wordpress.com/2018/12/black-and-white-construction-ladder-54335.jpg',
- height: 3193,
- width: 2377,
- },
- {
- alt: '',
- id: 158,
- url: 'https://example.files.wordpress.com/2018/12/architecture-buildings-city-1672110.jpg',
- height: 6000,
- width: 4000,
- },
- {
- alt: '',
- id: 157,
- url:
- 'https://example.files.wordpress.com/2018/12/architectural-design-architecture-black-and-white-1672122-1.jpg',
- height: 3401,
- width: 2721,
- },
- {
- alt: '',
- id: 156,
- url: 'https://example.files.wordpress.com/2018/12/grass-hd-wallpaper-lake-127753.jpg',
- height: 2198,
- width: 7999,
- },
- {
- alt: '',
- id: 122,
- url: 'https://example.files.wordpress.com/2018/12/texaco-car-1.jpg',
- height: 599,
- width: 800,
- },
- {
- alt: '',
- id: 92,
- url: 'https://example.files.wordpress.com/2018/12/43824553435_ea38cbc92a_m.jpg',
- height: 159,
- width: 240,
- },
- {
- alt: '',
- id: 90,
- url: 'https://example.files.wordpress.com/2018/12/42924685680_7b5632e58e_m.jpg',
- height: 150,
- width: 240,
- },
- {
- alt: '',
- id: 89,
- url:
- 'https://example.files.wordpress.com/2018/12/31962299833_1e106f7f7a_z-1-e1545262352979.jpg',
- height: 427,
- width: 564,
- },
- {
- alt: '',
- id: 88,
- url: 'https://example.files.wordpress.com/2018/12/29797558147_3c72afa8f4_k.jpg',
- height: 1511,
- width: 2048,
- },
- {
- alt: '',
- id: 8,
- url: 'https://example.files.wordpress.com/2018/11/person-smartphone-office-table.jpeg',
- height: 1067,
- width: 1600,
- },
-];
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/save.js b/plugins/jetpack/extensions/blocks/tiled-gallery/save.js
deleted file mode 100644
index e21e56e1..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/save.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Internal dependencies
- */
-import Layout from './layout';
-import { defaultColumnsNumber } from './edit';
-import { getActiveStyleName } from '../../shared/block-styles';
-import { LAYOUT_STYLES } from './constants';
-
-export default function TiledGallerySave( { attributes } ) {
- const { imageFilter, images } = attributes;
-
- if ( ! images.length ) {
- return null;
- }
-
- const { align, className, columns = defaultColumnsNumber( attributes ), linkTo } = attributes;
-
- return (
- <Layout
- align={ align }
- className={ className }
- columns={ columns }
- imageFilter={ imageFilter }
- images={ images }
- isSave
- layoutStyle={ getActiveStyleName( LAYOUT_STYLES, className ) }
- linkTo={ linkTo }
- />
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php b/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
index bcfdaf1f..d53feae4 100644
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
+++ b/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
@@ -44,6 +44,10 @@ class Jetpack_Tiled_Gallery_Block {
$is_squareish_layout = self::is_squareish_layout( $attr );
+ $jetpack_plan = Jetpack_Plan::get();
+
+ wp_localize_script( 'jetpack-gallery-settings', 'jetpack_plan', array( 'data' => $jetpack_plan['product_slug'] ) );
+
if ( preg_match_all( '/<img [^>]+>/', $content, $images ) ) {
/**
* This block processes all of the images that are found and builds $find and $replace.
@@ -85,7 +89,7 @@ class Jetpack_Tiled_Gallery_Block {
$srcset_src = add_query_arg(
array(
'resize' => $w . ',' . $w,
- 'strip' => 'all',
+ 'strip' => 'info',
),
$orig_src
);
@@ -104,7 +108,7 @@ class Jetpack_Tiled_Gallery_Block {
for ( $w = $min_width; $w <= $max_width; $w = min( $max_width, $w + self::IMG_SRCSET_WIDTH_STEP ) ) {
$srcset_src = add_query_arg(
array(
- 'strip' => 'all',
+ 'strip' => 'info',
'w' => $w,
),
$orig_src
@@ -163,9 +167,4 @@ class Jetpack_Tiled_Gallery_Block {
}
}
-if (
- ( defined( 'IS_WPCOM' ) && IS_WPCOM )
- || class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' )
-) {
- Jetpack_Tiled_Gallery_Block::register();
-}
+Jetpack_Tiled_Gallery_Block::register();
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/variables.scss b/plugins/jetpack/extensions/blocks/tiled-gallery/variables.scss
deleted file mode 100644
index f0054531..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/variables.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-$tiled-gallery-gutter: 4px; // Fixed in JS, see `LayoutStyles` from `edit.jsx`
-$tiled-gallery-selection: #0085ba; // Gutenberg primary theme color (https://github.com/WordPress/gutenberg/blob/6928e41c8afd7daa3a709afdda7eee48218473b7/bin/packages/post-css-config.js#L4)
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/view.js b/plugins/jetpack/extensions/blocks/tiled-gallery/view.js
deleted file mode 100644
index 1f45b13d..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/view.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Internal dependencies
- */
-import './view.scss';
-import ResizeObserver from 'resize-observer-polyfill';
-import { handleRowResize } from './layout/mosaic/resize';
-
-/**
- * Handler for Gallery ResizeObserver
- *
- * @param {Array<ResizeObserverEntry>} galleries Resized galleries
- */
-function handleObservedResize( galleries ) {
- if ( handleObservedResize.pendingRaf ) {
- cancelAnimationFrame( handleObservedResize.pendingRaf );
- }
- handleObservedResize.pendingRaf = requestAnimationFrame( () => {
- handleObservedResize.pendingRaf = null;
- for ( const gallery of galleries ) {
- const { width: galleryWidth } = gallery.contentRect;
- // We can't use childNodes becuase post content may contain unexpected text nodes
- const rows = Array.from( gallery.target.querySelectorAll( '.tiled-gallery__row' ) );
- rows.forEach( row => handleRowResize( row, galleryWidth ) );
- }
- } );
-}
-
-/**
- * Get all the galleries on the document
- *
- * @return {Array} List of gallery nodes
- */
-function getGalleries() {
- return Array.from(
- document.querySelectorAll(
- '.wp-block-jetpack-tiled-gallery.is-style-rectangular > .tiled-gallery__gallery,' +
- '.wp-block-jetpack-tiled-gallery.is-style-columns > .tiled-gallery__gallery'
- )
- );
-}
-
-/**
- * Setup ResizeObserver to follow each gallery on the page
- */
-const observeGalleries = () => {
- const galleries = getGalleries();
-
- if ( galleries.length === 0 ) {
- return;
- }
-
- const observer = new ResizeObserver( handleObservedResize );
-
- galleries.forEach( gallery => observer.observe( gallery ) );
-};
-
-if ( typeof window !== 'undefined' && typeof document !== 'undefined' ) {
- // `DOMContentLoaded` may fire before the script has a chance to run
- if ( document.readyState === 'loading' ) {
- document.addEventListener( 'DOMContentLoaded', observeGalleries );
- } else {
- observeGalleries();
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/view.scss b/plugins/jetpack/extensions/blocks/tiled-gallery/view.scss
deleted file mode 100644
index 456f8acb..00000000
--- a/plugins/jetpack/extensions/blocks/tiled-gallery/view.scss
+++ /dev/null
@@ -1,115 +0,0 @@
-@import '../../shared/styles/jetpack-variables.scss';
-@import './variables.scss';
-@import './css-gram.scss';
-
-$tiled-gallery-max-column-count: 20;
-
-.wp-block-jetpack-tiled-gallery {
- margin: 0 auto $jetpack-block-margin-bottom;
-
- &.is-style-circle .tiled-gallery__item img {
- border-radius: 50%;
- }
-
- &.is-style-square,
- &.is-style-circle {
- .tiled-gallery__row {
- flex-grow: 1;
- width: 100%;
-
- @for $cols from 1 through $tiled-gallery-max-column-count {
- &.columns-#{$cols} {
- .tiled-gallery__col {
- width: calc( ( 100% - #{ $tiled-gallery-gutter * ( $cols - 1 ) } ) / #{$cols} );
- }
- }
- }
- }
- }
-
- &.is-style-columns,
- &.is-style-rectangular {
- .tiled-gallery__item {
- display: flex;
- }
- }
-}
-
-.tiled-gallery__gallery {
- width: 100%;
- display: flex;
- padding: 0;
- flex-wrap: wrap;
-}
-
-.tiled-gallery__row {
- width: 100%;
- display: flex;
- flex-direction: row;
- justify-content: center;
- margin: 0;
-
- & + & {
- margin-top: $tiled-gallery-gutter;
- }
-}
-
-.tiled-gallery__col {
- display: flex;
- flex-direction: column;
- justify-content: center;
- margin: 0;
-
- & + & {
- margin-left: $tiled-gallery-gutter;
- }
-}
-
-.tiled-gallery__item {
- justify-content: center;
- margin: 0;
- overflow: hidden;
- padding: 0;
- position: relative;
-
- &.filter__black-and-white {
- filter: grayscale( 100% );
- }
-
- &.filter__sepia {
- filter: sepia( 100% );
- }
-
- &.filter__1977 {
- @include _1977;
- }
-
- &.filter__clarendon {
- @include clarendon;
- }
-
- &.filter__gingham {
- @include gingham;
- }
-
- & + & {
- margin-top: $tiled-gallery-gutter;
- }
-
- > img {
- background-color: rgba( 0, 0, 0, 0.1 );
- }
-
- > a,
- > a > img,
- > img {
- display: block;
- height: auto;
- margin: 0;
- max-width: 100%;
- object-fit: cover;
- object-position: center;
- padding: 0;
- width: 100%;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/videopress/edit.js b/plugins/jetpack/extensions/blocks/videopress/edit.js
deleted file mode 100644
index cd73e564..00000000
--- a/plugins/jetpack/extensions/blocks/videopress/edit.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-import classnames from 'classnames';
-import { __ } from '@wordpress/i18n';
-import { BlockControls, RichText } from '@wordpress/editor';
-import { Component, createRef, Fragment } from '@wordpress/element';
-import { compose, createHigherOrderComponent } from '@wordpress/compose';
-import { Disabled, IconButton, SandBox, Toolbar } from '@wordpress/components';
-import { get } from 'lodash';
-import { isBlobURL } from '@wordpress/blob';
-import { withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import Loading from './loading';
-
-const VideoPressEdit = CoreVideoEdit =>
- class extends Component {
- constructor() {
- super( ...arguments );
- this.state = {
- media: null,
- isFetchingMedia: false,
- fallback: false,
- };
- this.posterImageButton = createRef();
- }
-
- componentDidMount() {
- const { guid } = this.props.attributes;
- if ( ! guid ) {
- this.setGuid();
- }
- }
-
- componentDidUpdate( prevProps ) {
- const { attributes } = this.props;
-
- if ( attributes.id !== prevProps.attributes.id ) {
- this.setGuid();
- }
- }
-
- fallbackToCore = () => {
- this.props.setAttributes( { guid: undefined } );
- this.setState( { fallback: true } );
- };
-
- setGuid = async () => {
- const { attributes, setAttributes } = this.props;
- const { id } = attributes;
-
- if ( ! id ) {
- setAttributes( { guid: undefined } );
- return;
- }
-
- try {
- this.setState( { isFetchingMedia: true } );
- const media = await apiFetch( { path: `/wp/v2/media/${ id }` } );
- this.setState( { isFetchingMedia: false } );
-
- const { id: currentId } = this.props.attributes;
- if ( id !== currentId ) {
- // Video was changed in the editor while fetching data for the previous video;
- return;
- }
-
- this.setState( { media } );
- const guid = get( media, 'jetpack_videopress_guid' );
- if ( guid ) {
- setAttributes( { guid } );
- } else {
- this.fallbackToCore();
- }
- } catch ( e ) {
- this.setState( { isFetchingMedia: false } );
- this.fallbackToCore();
- }
- };
-
- switchToEditing = () => {
- this.props.setAttributes( {
- id: undefined,
- guid: undefined,
- src: undefined,
- } );
- };
-
- onRemovePoster = () => {
- this.props.setAttributes( { poster: '' } );
-
- // Move focus back to the Media Upload button.
- this.posterImageButton.current.focus();
- };
-
- render() {
- const {
- attributes,
- className,
- isFetchingPreview,
- isSelected,
- isUploading,
- preview,
- setAttributes,
- } = this.props;
- const { fallback, isFetchingMedia } = this.state;
-
- if ( isUploading ) {
- return <Loading text={ __( 'Uploading…', 'jetpack' ) } />;
- }
-
- if ( isFetchingMedia || isFetchingPreview ) {
- return <Loading text={ __( 'Embedding…', 'jetpack' ) } />;
- }
-
- if ( fallback || ! preview ) {
- return <CoreVideoEdit { ...this.props } />;
- }
-
- const { html, scripts } = preview;
- const { caption } = attributes;
-
- return (
- <Fragment>
- <BlockControls>
- <Toolbar>
- <IconButton
- className="components-icon-button components-toolbar__control"
- label={ __( 'Edit video', 'jetpack' ) }
- onClick={ this.switchToEditing }
- icon="edit"
- />
- </Toolbar>
- </BlockControls>
- <figure className={ classnames( className, 'wp-block-embed', 'is-type-video' ) }>
- { /*
- Disable the video player so the user clicking on it won't play the
- video when the controls are enabled.
- */ }
- <Disabled>
- <div className="wp-block-embed__wrapper">
- <SandBox html={ html } scripts={ scripts } />
- </div>
- </Disabled>
- { ( ! RichText.isEmpty( caption ) || isSelected ) && (
- <RichText
- tagName="figcaption"
- placeholder={ __( 'Write caption…', 'jetpack' ) }
- value={ caption }
- onChange={ value => setAttributes( { caption: value } ) }
- inlineToolbar
- />
- ) }
- </figure>
- </Fragment>
- );
- }
- };
-
-export default createHigherOrderComponent(
- compose( [
- withSelect( ( select, ownProps ) => {
- const { guid, src } = ownProps.attributes;
- const { getEmbedPreview, isRequestingEmbedPreview } = select( 'core' );
-
- const url = !! guid && `https://videopress.com/v/${ guid }`;
- const preview = !! url && getEmbedPreview( url );
-
- const isFetchingEmbedPreview = !! url && isRequestingEmbedPreview( url );
- const isUploading = isBlobURL( src );
-
- return {
- isFetchingPreview: isFetchingEmbedPreview,
- isUploading,
- preview,
- };
- } ),
- VideoPressEdit,
- ] ),
- 'withVideoPressEdit'
-);
diff --git a/plugins/jetpack/extensions/blocks/videopress/editor.js b/plugins/jetpack/extensions/blocks/videopress/editor.js
deleted file mode 100644
index 0cb7f476..00000000
--- a/plugins/jetpack/extensions/blocks/videopress/editor.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * External dependencies
- */
-import { createBlobURL } from '@wordpress/blob';
-import { createBlock } from '@wordpress/blocks';
-import { mediaUpload } from '@wordpress/editor';
-import { addFilter } from '@wordpress/hooks';
-import { every } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import withVideoPressEdit from './edit';
-import withVideoPressSave from './save';
-import getJetpackExtensionAvailability from '../../shared/get-jetpack-extension-availability';
-
-const addVideoPressSupport = ( settings, name ) => {
- if ( 'core/video' !== name ) {
- return settings;
- }
-
- const { available, unavailableReason } = getJetpackExtensionAvailability( 'videopress' );
-
- // We customize the video block even if VideoPress it not available so we can support videos that were uploaded to
- // VideoPress if it was available in the past (i.e. before a plan downgrade).
- if ( available || [ 'missing_plan', 'missing_module' ].includes( unavailableReason ) ) {
- return {
- ...settings,
-
- attributes: {
- autoplay: {
- type: 'boolean',
- },
- caption: {
- type: 'string',
- source: 'html',
- selector: 'figcaption',
- },
- controls: {
- type: 'boolean',
- default: true,
- },
- guid: {
- type: 'string',
- },
- id: {
- type: 'number',
- },
- loop: {
- type: 'boolean',
- },
- muted: {
- type: 'boolean',
- },
- poster: {
- type: 'string',
- },
- preload: {
- type: 'string',
- default: 'metadata',
- },
- src: {
- type: 'string',
- },
- },
-
- transforms: {
- ...settings.transforms,
- from: [
- {
- type: 'files',
- isMatch: files => every( files, file => file.type.indexOf( 'video/' ) === 0 ),
- // We define a higher priority (lower number) than the default of 10. This ensures that this
- // transformation prevails over the core video block default transformations.
- priority: 9,
- transform: ( files, onChange ) => {
- const blocks = [];
- files.forEach( file => {
- const block = createBlock( 'core/video', {
- src: createBlobURL( file ),
- } );
- mediaUpload( {
- filesList: [ file ],
- onFileChange: ( [ { id, url } ] ) => {
- onChange( block.clientId, { id, src: url } );
- },
- allowedTypes: [ 'video' ],
- } );
- blocks.push( block );
- } );
- return blocks;
- },
- },
- ],
- },
-
- supports: {
- ...settings.supports,
- reusable: false,
- },
-
- edit: withVideoPressEdit( settings.edit ),
-
- save: withVideoPressSave( settings.save ),
-
- deprecated: [
- {
- attributes: settings.attributes,
- save: settings.save,
- isEligible: attrs => ! attrs.guid,
- },
- ],
- };
- }
-
- return settings;
-};
-
-addFilter( 'blocks.registerBlockType', 'jetpack/videopress', addVideoPressSupport );
diff --git a/plugins/jetpack/extensions/blocks/videopress/index.js b/plugins/jetpack/extensions/blocks/videopress/index.js
deleted file mode 100644
index 60d3531f..00000000
--- a/plugins/jetpack/extensions/blocks/videopress/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Internal dependencies
- */
-// Register the hook that customize the core video block
-import './editor';
-
-// This is exporting deliberately an empty object so we don't break `getExtensions`
-// at the same time we don't register any new plugin or block
-export const settings = {};
diff --git a/plugins/jetpack/extensions/blocks/videopress/loading.js b/plugins/jetpack/extensions/blocks/videopress/loading.js
deleted file mode 100644
index 76c25d4c..00000000
--- a/plugins/jetpack/extensions/blocks/videopress/loading.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * External dependencies
- */
-import { Spinner } from '@wordpress/components';
-
-const Loading = ( { text } ) => (
- <div className="wp-block-embed is-loading">
- <Spinner />
- <p>{ text }</p>
- </div>
-);
-
-export default Loading;
diff --git a/plugins/jetpack/extensions/blocks/videopress/save.js b/plugins/jetpack/extensions/blocks/videopress/save.js
deleted file mode 100644
index 52790480..00000000
--- a/plugins/jetpack/extensions/blocks/videopress/save.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * External dependencies
- */
-import { createHigherOrderComponent } from '@wordpress/compose';
-import { RichText } from '@wordpress/editor';
-
-const VideoPressSave = CoreVideoSave => props => {
- const { attributes: { caption, guid } = {} } = props;
-
- if ( ! guid ) {
- /**
- * We return the element produced by the render so Gutenberg can add the block class when cloning the element.
- * This is due to the fact that `React.cloneElement` ignores the class name when we clone a component to be
- * rendered (i.e. `React.cloneElement( <CoreVideoSave { ...props } />, { className: 'wp-block-video' } )`).
- *
- * @see https://github.com/WordPress/gutenberg/blob/3f1324b53cc8bb45d08d12d5321d6f88510bed09/packages/blocks/src/api/serializer.js#L78-L96
- * @see https://github.com/WordPress/gutenberg/blob/c5f9bd88125282a0c35f887cc8d835f065893112/packages/editor/src/hooks/generated-class-name.js#L42
- * @see https://github.com/Automattic/wp-calypso/pull/30546#issuecomment-463637946
- */
- return CoreVideoSave( props );
- }
-
- const url = `https://videopress.com/v/${ guid }`;
-
- return (
- <figure className="wp-block-embed is-type-video is-provider-videopress">
- <div className="wp-block-embed__wrapper">
- { `\n${ url }\n` /* URL needs to be on its own line. */ }
- </div>
- { ! RichText.isEmpty( caption ) && (
- <RichText.Content tagName="figcaption" value={ caption } />
- ) }
- </figure>
- );
-};
-
-export default createHigherOrderComponent( VideoPressSave, 'withVideoPressSave' );
diff --git a/plugins/jetpack/extensions/blocks/wordads/constants.js b/plugins/jetpack/extensions/blocks/wordads/constants.js
deleted file mode 100644
index 6cf647af..00000000
--- a/plugins/jetpack/extensions/blocks/wordads/constants.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Path, SVG } from '@wordpress/components';
-
-export const DEFAULT_FORMAT = 'mrec';
-export const AD_FORMATS = [
- {
- height: 250,
- icon: (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zm-7-2h2V7h-4v2h2z" />
- </SVG>
- ),
- name: __( 'Rectangle 300x250', 'jetpack' ),
- tag: DEFAULT_FORMAT,
- width: 300,
- editorPadding: 30,
- },
- {
- height: 90,
- icon: (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zm-4-4h-4v-2h2c1.1 0 2-.89 2-2V9c0-1.11-.9-2-2-2H9v2h4v2h-2c-1.1 0-2 .89-2 2v4h6v-2z" />
- </SVG>
- ),
- name: __( 'Leaderboard 728x90', 'jetpack' ),
- tag: 'leaderboard',
- width: 728,
- editorPadding: 60,
- },
- {
- height: 50,
- icon: (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zm-4-4v-1.5c0-.83-.67-1.5-1.5-1.5.83 0 1.5-.67 1.5-1.5V9c0-1.11-.9-2-2-2H9v2h4v2h-2v2h2v2H9v2h4c1.1 0 2-.89 2-2z" />
- </SVG>
- ),
- name: __( 'Mobile Leaderboard 320x50', 'jetpack' ),
- tag: 'mobile_leaderboard',
- width: 320,
- editorPadding: 100,
- },
- {
- height: 600,
- icon: (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M.04 0h24v24h-24V0z" />
- <Path d="M19.04 3h-14c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16h-14V5h14v14zm-6-2h2V7h-2v4h-2V7h-2v6h4z" />
- </SVG>
- ),
- name: __( 'Wide Skyscraper 160x600', 'jetpack' ),
- tag: 'wideskyscraper',
- width: 160,
- editorPadding: 30,
- },
-];
diff --git a/plugins/jetpack/extensions/blocks/wordads/edit.js b/plugins/jetpack/extensions/blocks/wordads/edit.js
deleted file mode 100644
index 2067d0cd..00000000
--- a/plugins/jetpack/extensions/blocks/wordads/edit.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { BlockControls } from '@wordpress/editor';
-import { Component, Fragment } from '@wordpress/element';
-import { Placeholder, ToggleControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import FormatPicker from './format-picker';
-import { AD_FORMATS } from './constants';
-import { icon, title } from './';
-
-import './editor.scss';
-
-class WordAdsEdit extends Component {
- handleHideMobileChange = hideMobile => {
- this.props.setAttributes( { hideMobile: !! hideMobile } );
- };
-
- render() {
- const { attributes, setAttributes } = this.props;
- const { format, hideMobile } = attributes;
- const selectedFormatObject = AD_FORMATS.filter( ( { tag } ) => tag === format )[ 0 ];
-
- return (
- <Fragment>
- <BlockControls>
- <FormatPicker
- value={ format }
- onChange={ nextFormat => setAttributes( { format: nextFormat } ) }
- />
- </BlockControls>
- <div className={ `wp-block-jetpack-wordads jetpack-wordads-${ format }` }>
- <div
- className="jetpack-wordads__ad"
- style={ {
- width: selectedFormatObject.width,
- height: selectedFormatObject.height + selectedFormatObject.editorPadding,
- } }
- >
- <Placeholder icon={ icon } label={ title } />
- <ToggleControl
- checked={ Boolean( hideMobile ) }
- label={ __( 'Hide ad on mobile views', 'jetpack' ) }
- onChange={ this.handleHideMobileChange }
- />
- </div>
- </div>
- </Fragment>
- );
- }
-}
-export default WordAdsEdit;
diff --git a/plugins/jetpack/extensions/blocks/wordads/editor.js b/plugins/jetpack/extensions/blocks/wordads/editor.js
deleted file mode 100644
index d05f4039..00000000
--- a/plugins/jetpack/extensions/blocks/wordads/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../shared/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/plugins/jetpack/extensions/blocks/wordads/editor.scss b/plugins/jetpack/extensions/blocks/wordads/editor.scss
deleted file mode 100644
index b7be4878..00000000
--- a/plugins/jetpack/extensions/blocks/wordads/editor.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-@import '../../shared/styles/gutenberg-colors.scss';
-
-.wp-block-jetpack-wordads {
- background: $white;
-}
-
-[data-type='jetpack/wordads'][data-align='center'] .jetpack-wordads__ad {
- margin: 0 auto;
-}
-
-.jetpack-wordads__ad {
- display: flex;
- overflow: hidden;
- flex-direction: column;
- max-width: 100%;
-
- .components-placeholder {
- flex-grow: 2;
- }
-
- .components-toggle-control__label {
- line-height: 1.4em;
- }
-
- .components-base-control__field {
- padding: 7px;
- }
-}
-
-.jetpack-wordads-leaderboard .components-placeholder {
- min-height: 90px;
-}
-
-.jetpack-wordads-mobile_leaderboard .components-placeholder {
- min-height: 72px;
-}
-
-.wp-block-jetpack-wordads__format-picker {
- $active-item-outline-width: 2px;
-
- padding: 7px;
-
- // Leave space between elements for active state styling
- .components-menu-item__button + .components-menu-item__button {
- margin-top: $active-item-outline-width;
- }
-
- .components-menu-item__button.is-active {
- color: $dark-gray-900;
- box-shadow: 0 0 0 $active-item-outline-width $dark-gray-500 !important;
- }
-}
diff --git a/plugins/jetpack/extensions/blocks/wordads/format-picker.js b/plugins/jetpack/extensions/blocks/wordads/format-picker.js
deleted file mode 100644
index b058ab03..00000000
--- a/plugins/jetpack/extensions/blocks/wordads/format-picker.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * External Dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { Dropdown, MenuItem, NavigableMenu, Path, SVG, Toolbar } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { AD_FORMATS } from './constants';
-
-const label = __( 'Pick an ad format', 'jetpack' );
-
-export default function FormatPicker( { value, onChange } ) {
- return (
- <Dropdown
- position="bottom right"
- renderToggle={ ( { onToggle, isOpen } ) => {
- return (
- <Toolbar
- controls={ [
- {
- icon: (
- <SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M1 9h2V7H1v2zm0 4h2v-2H1v2zm0-8h2V3c-1.1 0-2 .9-2 2zm8 16h2v-2H9v2zm-8-4h2v-2H1v2zm2 4v-2H1c0 1.1.9 2 2 2zM21 3h-8v6h10V5c0-1.1-.9-2-2-2zm0 14h2v-2h-2v2zM9 5h2V3H9v2zM5 21h2v-2H5v2zM5 5h2V3H5v2zm16 16c1.1 0 2-.9 2-2h-2v2zm0-8h2v-2h-2v2zm-8 8h2v-2h-2v2zm4 0h2v-2h-2v2z" />
- </SVG>
- ),
- title: label,
- onClick: onToggle,
- extraProps: { 'aria-expanded': isOpen },
- className: 'wp-block-jetpack-wordads__format-picker-icon',
- },
- ] }
- />
- );
- } }
- renderContent={ ( { onClose } ) => (
- <NavigableMenu className="wp-block-jetpack-wordads__format-picker">
- { AD_FORMATS.map( ( { tag, name, icon } ) => (
- <MenuItem
- className={ tag === value ? 'is-active' : undefined }
- icon={ icon }
- isSelected={ tag === value }
- key={ tag }
- onClick={ () => {
- onChange( tag );
- onClose();
- } }
- role="menuitemcheckbox"
- >
- { name }
- </MenuItem>
- ) ) }
- </NavigableMenu>
- ) }
- />
- );
-}
diff --git a/plugins/jetpack/extensions/blocks/wordads/index.js b/plugins/jetpack/extensions/blocks/wordads/index.js
deleted file mode 100644
index 7a6a0238..00000000
--- a/plugins/jetpack/extensions/blocks/wordads/index.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { ExternalLink, Path, SVG } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import { DEFAULT_FORMAT } from './constants';
-
-export const name = 'wordads';
-export const title = __( 'Ad', 'jetpack' );
-
-export const icon = (
- <SVG xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <Path fill="none" d="M0 0h24v24H0V0z" />
- <Path d="M12,8H4A2,2 0 0,0 2,10V14A2,2 0 0,0 4,16H5V20A1,1 0 0,0 6,21H8A1,1 0 0,0 9,20V16H12L17,20V4L12,8M15,15.6L13,14H4V10H13L15,8.4V15.6M21.5,12C21.5,13.71 20.54,15.26 19,16V8C20.53,8.75 21.5,10.3 21.5,12Z" />
- </SVG>
-);
-
-export const settings = {
- title,
-
- description: (
- <Fragment>
- <p>{ __( 'Earn income by adding high quality ads to your post', 'jetpack' ) }</p>
- <ExternalLink href="https://wordads.co/">
- { __( 'Learn all about WordAds', 'jetpack' ) }
- </ExternalLink>
- </Fragment>
- ),
-
- icon,
- attributes: {
- align: {
- type: 'string',
- default: 'center',
- },
- format: {
- type: 'string',
- default: DEFAULT_FORMAT,
- },
- hideMobile: {
- type: 'boolean',
- default: false,
- },
- },
-
- category: 'jetpack',
-
- keywords: [ __( 'ads', 'jetpack' ), 'WordAds', __( 'Advertisement', 'jetpack' ) ],
-
- supports: {
- align: [ 'left', 'center', 'right' ],
- alignWide: false,
- className: false,
- customClassName: false,
- html: false,
- reusable: false,
- },
- edit,
- save: () => null,
-};
diff --git a/plugins/jetpack/extensions/blocks/wordads/wordads.php b/plugins/jetpack/extensions/blocks/wordads/wordads.php
index 8cb8ea2a..9f67d58b 100644
--- a/plugins/jetpack/extensions/blocks/wordads/wordads.php
+++ b/plugins/jetpack/extensions/blocks/wordads/wordads.php
@@ -76,7 +76,12 @@ class Jetpack_WordAds_Gutenblock {
global $wordads;
/** This filter is already documented in modules/wordads/wordads.php `insert_ad()` */
- if ( empty( $wordads ) || is_feed() || apply_filters( 'wordads_inpost_disable', false ) ) {
+ if (
+ empty( $wordads )
+ || empty( $wordads->params )
+ || is_feed()
+ || apply_filters( 'wordads_inpost_disable', false )
+ ) {
return '';
}
diff --git a/plugins/jetpack/extensions/editor.js b/plugins/jetpack/extensions/editor.js
deleted file mode 100644
index 34458e4c..00000000
--- a/plugins/jetpack/extensions/editor.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Internal dependencies
- */
-import './shared/public-path';
-import './shared/block-category';
diff --git a/plugins/jetpack/extensions/index.json b/plugins/jetpack/extensions/index.json
deleted file mode 100644
index e8cdcfed..00000000
--- a/plugins/jetpack/extensions/index.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "production": [
- "business-hours",
- "contact-form",
- "contact-info",
- "gif",
- "likes",
- "mailchimp",
- "map",
- "markdown",
- "publicize",
- "related-posts",
- "repeat-visitor",
- "sharing",
- "shortlinks",
- "simple-payments",
- "slideshow",
- "subscriptions",
- "tiled-gallery",
- "videopress",
- "wordads"
- ],
- "beta": [ "seo", "membership-button" ]
-}
diff --git a/plugins/jetpack/extensions/shared/styles/gutenberg-colors.scss b/plugins/jetpack/extensions/shared/styles/gutenberg-colors.scss
deleted file mode 100644
index 78bf62c0..00000000
--- a/plugins/jetpack/extensions/shared/styles/gutenberg-colors.scss
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Gutenberg colors
- *
- * Unfortunately these are not currently (04/2019) published to NPM.
- *
- * https://github.com/WordPress/gutenberg/blob/df6a17c8eb07e1355527b01e99ee22cf4c2338d7/assets/stylesheets/_colors.scss
- */
-
-// Hugo's new WordPress shades of gray, from http://codepen.io/hugobaeta/pen/grJjVp.
-$black: #000;
-$dark-gray-900: #191e23;
-$dark-gray-800: #23282d;
-$dark-gray-700: #32373c;
-$dark-gray-600: #40464d;
-$dark-gray-500: #555d66; // Use this most of the time for dark items.
-$dark-gray-400: #606a73;
-$dark-gray-300: #6c7781; // Lightest gray that can be used for AA text contrast.
-$dark-gray-200: #7e8993;
-$dark-gray-150: #8d96a0; // Lightest gray that can be used for AA non-text contrast.
-$dark-gray-100: #8f98a1;
-$light-gray-900: #a2aab2;
-$light-gray-800: #b5bcc2;
-$light-gray-700: #ccd0d4;
-$light-gray-600: #d7dade;
-$light-gray-500: #e2e4e7; // Good for "grayed" items and borders.
-$light-gray-400: #e8eaeb; // Good for "readonly" input fields and special text selection.
-$light-gray-300: #edeff0;
-$light-gray-200: #f3f4f5;
-$light-gray-100: #f8f9f9;
-$white: #fff;
-
-
-// Dark opacities, for use with light themes.
-$dark-opacity-900: rgba(#000510, 0.9);
-$dark-opacity-800: rgba(#00000a, 0.85);
-$dark-opacity-700: rgba(#06060b, 0.8);
-$dark-opacity-600: rgba(#000913, 0.75);
-$dark-opacity-500: rgba(#0a1829, 0.7);
-$dark-opacity-400: rgba(#0a1829, 0.65);
-$dark-opacity-300: rgba(#0e1c2e, 0.62);
-$dark-opacity-200: rgba(#162435, 0.55);
-$dark-opacity-100: rgba(#223443, 0.5);
-$dark-opacity-light-900: rgba(#304455, 0.45);
-$dark-opacity-light-800: rgba(#425863, 0.4);
-$dark-opacity-light-700: rgba(#667886, 0.35);
-$dark-opacity-light-600: rgba(#7b86a2, 0.3);
-$dark-opacity-light-500: rgba(#9197a2, 0.25);
-$dark-opacity-light-400: rgba(#95959c, 0.2);
-$dark-opacity-light-300: rgba(#829493, 0.15);
-$dark-opacity-light-200: rgba(#8b8b96, 0.1);
-$dark-opacity-light-100: rgba(#747474, 0.05);
-
-// Light opacities, for use with dark themes.
-$light-opacity-900: rgba($white, 1);
-$light-opacity-800: rgba($white, 0.9);
-$light-opacity-700: rgba($white, 0.85);
-$light-opacity-600: rgba($white, 0.8);
-$light-opacity-500: rgba($white, 0.75);
-$light-opacity-400: rgba($white, 0.7);
-$light-opacity-300: rgba($white, 0.65);
-$light-opacity-200: rgba($white, 0.6);
-$light-opacity-100: rgba($white, 0.55);
-$light-opacity-light-900: rgba($white, 0.5);
-$light-opacity-light-800: rgba($white, 0.45);
-$light-opacity-light-700: rgba($white, 0.4);
-$light-opacity-light-600: rgba($white, 0.35);
-$light-opacity-light-500: rgba($white, 0.3);
-$light-opacity-light-400: rgba($white, 0.25);
-$light-opacity-light-300: rgba($white, 0.2);
-$light-opacity-light-200: rgba($white, 0.15);
-$light-opacity-light-100: rgba($white, 0.1);
-
-// Additional colors.
-// Some are from https://make.wordpress.org/design/handbook/foundations/colors/.
-$blue-wordpress-700: #00669b;
-$blue-dark-900: #0071a1;
-
-$blue-medium-900: #006589;
-$blue-medium-800: #00739c;
-$blue-medium-700: #007fac;
-$blue-medium-600: #008dbe;
-$blue-medium-500: #00a0d2;
-$blue-medium-400: #33b3db;
-$blue-medium-300: #66c6e4;
-$blue-medium-200: #bfe7f3;
-$blue-medium-100: #e5f5fa;
-$blue-medium-highlight: #b3e7fe;
-$blue-medium-focus: #007cba;
-
-// Alert colors.
-$alert-yellow: #f0b849;
-$alert-red: #d94f4f;
-$alert-green: #4ab866;
diff --git a/plugins/jetpack/extensions/shared/styles/gutenberg-variables.scss b/plugins/jetpack/extensions/shared/styles/gutenberg-variables.scss
deleted file mode 100644
index 20911c4a..00000000
--- a/plugins/jetpack/extensions/shared/styles/gutenberg-variables.scss
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Gutenberg variables
- *
- * Unfortunately these are not currently (04/2019) published to NPM.
- *
- * https://github.com/WordPress/gutenberg/blob/df6a17c8eb07e1355527b01e99ee22cf4c2338d7/assets/stylesheets/_variables.scss
- */
-
-$default-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
-$default-font-size: 13px;
-$default-line-height: 1.4;
-$editor-font: "Noto Serif", serif;
-$editor-html-font: Menlo, Consolas, monaco, monospace;
-$editor-font-size: 16px;
-$text-editor-font-size: 14px;
-
-// @TODO: From which file in Gutenberg are these coming from?
-// Used in business-hours
-$break-xlarge: 1080px;
-//$break-large: 960px; // admin sidebar auto folds
-//$break-medium: 782px; // editor sidebar auto folds
-$break-small: 600px;
diff --git a/plugins/jetpack/extensions/shared/styles/jetpack-variables.scss b/plugins/jetpack/extensions/shared/styles/jetpack-variables.scss
deleted file mode 100644
index 51aecc74..00000000
--- a/plugins/jetpack/extensions/shared/styles/jetpack-variables.scss
+++ /dev/null
@@ -1 +0,0 @@
-$jetpack-block-margin-bottom: 1.5em;
diff --git a/plugins/jetpack/extensions/view.js b/plugins/jetpack/extensions/view.js
deleted file mode 100644
index 42ea5a34..00000000
--- a/plugins/jetpack/extensions/view.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Internal dependencies
- */
-import './shared/public-path';