diff --git a/.svnignore b/.svnignore
index 8dfbb716215fa..f9c2d78d307e7 100644
--- a/.svnignore
+++ b/.svnignore
@@ -41,16 +41,3 @@ yarn.lock
docker
bin/pre-commit-hook.js
yarn-error.log
-extensions/**/*.css
-extensions/**/*.gif
-extensions/**/*.jpeg
-extensions/**/*.jpg
-extensions/**/*.js
-extensions/**/*.json
-extensions/**/*.jsx
-extensions/**/*.md
-extensions/**/*.png
-extensions/**/*.sass
-extensions/**/*.scss
-extensions/**/*.svg
-**/__snapshots__
diff --git a/bin/build-asset-cdn-json.php b/bin/build-asset-cdn-json.php
index aebe99f45fdfc..09c64e0ab4b6e 100644
--- a/bin/build-asset-cdn-json.php
+++ b/bin/build-asset-cdn-json.php
@@ -1,48 +1,20 @@
$value ) {
- $path_from_repo_root = str_replace( $path, '', $path_to_file );
-
- // Ignore top-level files.
- if ( false === strpos( $path_from_repo_root, '/' ) ) {
+foreach ( $regex as $file => $value ) {
+ $file = str_replace( $path, '', $file );
+ $directory = substr( $file, 0, strpos( $file, '/' ) );
+ if ( in_array( $directory, array( 'node_modules', 'tests' ) ) ) {
continue;
}
-
- // Ignore explicit ignore list.
- foreach ( $ignore_paths as $ignore_path ) {
- if ( 0 === strpos( $path_from_repo_root, $ignore_path ) ) {
- continue 2;
- }
- }
-
- $manifest[] = $path_from_repo_root;
+ $manifest[] = $file;
}
$export = var_export( $manifest, true );
-file_put_contents( $path . 'modules/photon-cdn/jetpack-manifest.php', " {
- const { day } = this.props;
- const { opening, closing } = interval;
- return (
-
-
-
- { intervalIndex === 0 && this.renderDayToggle() }
-
-
- {
- this.setHour( value, 'opening', intervalIndex );
- } }
- />
- {
- this.setHour( value, 'closing', intervalIndex );
- } }
- />
-
-
- { day.hours.length > 1 && (
- {
- this.removeInterval( intervalIndex );
- } }
- />
- ) }
-
-
- { intervalIndex === day.hours.length - 1 && (
-
-
-
-
- { __( 'Add Hours' ) }
-
-
-
-
- ) }
-
- );
- };
-
- 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 (
-
- { localization.days[ day.name ] }
-
-
- );
- }
-
- renderClosed() {
- const { day } = this.props;
- return (
-
-
- { this.renderDayToggle() }
-
-
-
-
- );
- }
-
- render() {
- const { day } = this.props;
- return this.isClosed() ? this.renderClosed() : day.hours.map( this.renderInterval );
- }
-}
-
-export default DayEdit;
diff --git a/extensions/blocks/business-hours/components/day-preview.js b/extensions/blocks/business-hours/components/day-preview.js
deleted file mode 100644
index e9413d8ed90e1..0000000000000
--- a/extensions/blocks/business-hours/components/day-preview.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * External dependencies
- */
-import { Component, Fragment } from '@wordpress/element';
-import { date } from '@wordpress/date';
-import { isEmpty } from 'lodash';
-import { sprintf } from '@wordpress/i18n';
-
-/**
- * Internal dependencies
- */
-import { _x } from '../../../utils/i18n';
-
-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 (
-
- { sprintf(
- _x( 'From %s to %s', 'from business opening hour to closing hour' ),
- this.formatTime( interval.opening ),
- this.formatTime( interval.closing )
- ) }
-
- );
- };
-
- 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 (
-
- { localization.days[ day.name ] }
- { isEmpty( hours ) ? (
- { _x( 'Closed', 'business is closed on a full day' ) }
- ) : (
- hours.map( this.renderInterval )
- ) }
-
- );
- }
-}
-
-export default DayPreview;
diff --git a/extensions/blocks/business-hours/edit.js b/extensions/blocks/business-hours/edit.js
deleted file mode 100644
index 821631e8f4c0e..0000000000000
--- a/extensions/blocks/business-hours/edit.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * External dependencies
- */
-import { BlockIcon } from '@wordpress/editor';
-import { Component } from '@wordpress/element';
-import { Placeholder } from '@wordpress/components';
-import apiFetch from '@wordpress/api-fetch';
-import classNames from 'classnames';
-import { __experimentalGetSettings } from '@wordpress/date';
-
-/**
- * Internal dependencies
- */
-import DayEdit from './components/day-edit';
-import DayPreview from './components/day-preview';
-import { icon } from '.';
-import { __ } from '../../utils/i18n';
-
-const defaultLocalization = {
- days: {
- Sun: __( 'Sunday' ),
- Mon: __( 'Monday' ),
- Tue: __( 'Tuesday' ),
- Wed: __( 'Wednesday' ),
- Thu: __( 'Thursday' ),
- Fri: __( 'Friday' ),
- Sat: __( 'Saturday' ),
- },
- 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 (
- }
- label={ __( 'Loading business hours' ) }
- />
- );
- }
-
- if ( ! isSelected ) {
- const settings = __experimentalGetSettings();
- const {
- formats: { time },
- } = settings;
- return (
-
- { localizedWeek.map( ( day, key ) => {
- return (
-
- );
- } ) }
-
- );
- }
-
- return (
-
- { localizedWeek.map( ( day, key ) => {
- return (
-
- );
- } ) }
-
- );
- }
-}
-
-export default BusinessHours;
diff --git a/extensions/blocks/business-hours/editor.js b/extensions/blocks/business-hours/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/business-hours/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/business-hours/editor.scss b/extensions/blocks/business-hours/editor.scss
deleted file mode 100644
index cb919a6d5153d..0000000000000
--- a/extensions/blocks/business-hours/editor.scss
+++ /dev/null
@@ -1,132 +0,0 @@
-// @TODO: Use Gutenberg variables
-$break-xlarge: 1080px;
-$break-large: 960px; // admin sidebar auto folds
-$break-medium: 782px; // editor sidebar auto folds
-$break-small: 600px;
-
-.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/extensions/blocks/business-hours/index.js b/extensions/blocks/business-hours/index.js
deleted file mode 100644
index c1a2bbf062807..0000000000000
--- a/extensions/blocks/business-hours/index.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * External dependencies
- */
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __, _x } from '../../utils/i18n';
-import renderMaterialIcon from '../../utils/render-material-icon';
-
-import './editor.scss';
-import BusinessHours from './edit';
-
-/**
- * Block Registrations:
- */
-
-export const name = 'business-hours';
-
-export const icon = renderMaterialIcon(
-
-);
-
-export const settings = {
- title: __( 'Business Hours' ),
- description: __( 'Display opening hours for your business.' ),
- icon,
- category: 'jetpack',
- supports: {
- html: true,
- },
- keywords: [
- _x( 'opening hours', 'block search term' ),
- _x( 'closing time', 'block search term' ),
- _x( 'schedule', 'block search term' ),
- ],
- 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 => ,
-
- save: () => null,
-};
diff --git a/extensions/blocks/contact-form/components/jetpack-contact-form.js b/extensions/blocks/contact-form/components/jetpack-contact-form.js
deleted file mode 100644
index d17f970cf1432..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-contact-form.js
+++ /dev/null
@@ -1,261 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import { Button, PanelBody, Placeholder, TextControl, Path } from '@wordpress/components';
-import { InnerBlocks, InspectorControls } from '@wordpress/editor';
-import { Component, Fragment } from '@wordpress/element';
-import { sprintf } from '@wordpress/i18n';
-import emailValidator from 'email-validator';
-import { compose, withInstanceId } from '@wordpress/compose';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../../utils/i18n';
-import renderMaterialIcon from '../../../utils/render-material-icon';
-import SubmitButton from '../../../utils/submit-button';
-import HelpMessage from '../../../shared/help-message';
-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?'
- );
- }
-
- getEmailHelpMessage() {
- return __( 'You can enter multiple email addresses separated by commas.' );
- }
-
- 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.' ), errors[ 0 ].email );
- }
- return errors[ 0 ];
- }
-
- if ( errors.length === 2 ) {
- return sprintf(
- __( '%s and %s are not a valid email address.' ),
- errors[ 0 ].email,
- errors[ 1 ].email
- );
- }
- const inValidEmails = errors.map( error => error.email );
- return sprintf( __( '%s are not a valid email address.' ), 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 (
-
-
-
- { this.getfieldEmailError( fieldEmailError ) }
-
-
- { this.getEmailHelpMessage() }
-
-
-
-
- );
- }
-
- 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 (
-
-
-
- { this.renderToAndSubjectFields() }
-
-
-
- { ! hasFormSettingsSet && (
-
- ) }
- >
-
-
- ) }
- { hasFormSettingsSet && (
-
- ) }
- { hasFormSettingsSet &&
}
-
-
- );
- }
-}
-
-export default compose( [ withInstanceId ] )( JetpackContactForm );
diff --git a/extensions/blocks/contact-form/components/jetpack-field-checkbox.js b/extensions/blocks/contact-form/components/jetpack-field-checkbox.js
deleted file mode 100644
index d378c58936c97..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-field-checkbox.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * External dependencies
- */
-import { BaseControl, PanelBody, TextControl, ToggleControl } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-import { withInstanceId } from '@wordpress/compose';
-import { InspectorControls } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-import { __ } from '../../../utils/i18n';
-
-const JetpackFieldCheckbox = ( {
- instanceId,
- required,
- label,
- setAttributes,
- isSelected,
- defaultValue,
- id,
-} ) => {
- return (
-
-
-
-
-
- setAttributes( { defaultValue: value } ) }
- />
- setAttributes( { id: value } ) }
- />
-
-
-
- }
- />
- );
-};
-
-export default withInstanceId( JetpackFieldCheckbox );
diff --git a/extensions/blocks/contact-form/components/jetpack-field-label.js b/extensions/blocks/contact-form/components/jetpack-field-label.js
deleted file mode 100644
index 3493cab951f32..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-field-label.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * External dependencies
- */
-import { PlainText } from '@wordpress/editor';
-import { ToggleControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../../utils/i18n';
-
-const JetpackFieldLabel = ( { setAttributes, label, resetFocus, isSelected, required } ) => {
- return (
-
-
{
- resetFocus && resetFocus();
- setAttributes( { label: value } );
- } }
- placeholder={ __( 'Write label…' ) }
- />
- { isSelected && (
- setAttributes( { required: value } ) }
- />
- ) }
- { ! isSelected && required && { __( '(required)' ) } }
-
- );
-};
-
-export default JetpackFieldLabel;
diff --git a/extensions/blocks/contact-form/components/jetpack-field-multiple.js b/extensions/blocks/contact-form/components/jetpack-field-multiple.js
deleted file mode 100644
index 791bc9c62c819..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-field-multiple.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * External dependencies
- */
-import { BaseControl, IconButton, TextControl, PanelBody } from '@wordpress/components';
-import { withInstanceId } from '@wordpress/compose';
-import { Component, Fragment } from '@wordpress/element';
-import { InspectorControls } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-import JetpackOption from './jetpack-option';
-import { __ } from '../../../utils/i18n';
-
-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 (
-
- this.setState( { inFocus: null } ) }
- />
- }
- >
-
- { options.map( ( option, index ) => (
-
- ) ) }
-
- { isSelected && (
-
- { __( 'Add option' ) }
-
- ) }
-
-
-
-
- setAttributes( { id: value } ) }
- />
-
-
-
- );
- }
-}
-
-export default withInstanceId( JetpackFieldMultiple );
diff --git a/extensions/blocks/contact-form/components/jetpack-field-required-toggle.js b/extensions/blocks/contact-form/components/jetpack-field-required-toggle.js
deleted file mode 100644
index bab73001bd812..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-field-required-toggle.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * External dependencies
- */
-import { ToggleControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../../utils/i18n';
-
-const JetpackFieldRequiredToggle = ( { required, onChange } ) => {
- return ;
-};
-
-export default JetpackFieldRequiredToggle;
diff --git a/extensions/blocks/contact-form/components/jetpack-field-textarea.js b/extensions/blocks/contact-form/components/jetpack-field-textarea.js
deleted file mode 100644
index 186fc1e80953b..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-field-textarea.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * External dependencies
- */
-import { TextareaControl, TextControl, PanelBody } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-import { InspectorControls } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-import { __ } from '../../../utils/i18n';
-
-function JetpackFieldTextarea( {
- required,
- label,
- setAttributes,
- isSelected,
- defaultValue,
- placeholder,
- id,
-} ) {
- return (
-
-
-
- }
- placeholder={ placeholder }
- value={ placeholder }
- onChange={ value => setAttributes( { placeholder: value } ) }
- title={ __( 'Set the placeholder text' ) }
- />
-
-
-
- setAttributes( { defaultValue: value } ) }
- />
- setAttributes( { id: value } ) }
- />
-
-
-
- );
-}
-
-export default JetpackFieldTextarea;
diff --git a/extensions/blocks/contact-form/components/jetpack-field.js b/extensions/blocks/contact-form/components/jetpack-field.js
deleted file mode 100644
index 77c3ffaa87213..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-field.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * External dependencies
- */
-import { TextControl, PanelBody } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-import classNames from 'classnames';
-import { InspectorControls } from '@wordpress/editor';
-
-/**
- * Internal dependencies
- */
-import JetpackFieldLabel from './jetpack-field-label';
-import { __ } from '../../../utils/i18n';
-
-function JetpackField( {
- isSelected,
- type,
- required,
- label,
- setAttributes,
- defaultValue,
- placeholder,
- id,
-} ) {
- return (
-
-
-
- }
- placeholder={ placeholder }
- value={ placeholder }
- onChange={ value => setAttributes( { placeholder: value } ) }
- title={ __( 'Set the placeholder text' ) }
- />
-
-
-
- setAttributes( { defaultValue: value } ) }
- />
- setAttributes( { id: value } ) }
- />
-
-
-
- );
-}
-
-export default JetpackField;
diff --git a/extensions/blocks/contact-form/components/jetpack-option.js b/extensions/blocks/contact-form/components/jetpack-option.js
deleted file mode 100644
index 5d3052b8ab356..0000000000000
--- a/extensions/blocks/contact-form/components/jetpack-option.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * External dependencies
- */
-import { IconButton } from '@wordpress/components';
-import { Component, createRef } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../../utils/i18n';
-
-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 (
-
- { type && type !== 'select' && (
-
- ) }
-
- { isSelected && (
-
- ) }
-
- );
- }
-}
-
-export default JetpackOption;
diff --git a/extensions/blocks/contact-form/editor.js b/extensions/blocks/contact-form/editor.js
deleted file mode 100644
index 5b6bd3cdd88a0..0000000000000
--- a/extensions/blocks/contact-form/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { childBlocks, name, settings } from '.';
-
-registerJetpackBlock( name, settings, childBlocks );
diff --git a/extensions/blocks/contact-form/editor.scss b/extensions/blocks/contact-form/editor.scss
deleted file mode 100644
index b988f7f40ef6f..0000000000000
--- a/extensions/blocks/contact-form/editor.scss
+++ /dev/null
@@ -1,694 +0,0 @@
-
-.jetpack-contact-form {
- padding: 10px 18px;
-
- &.has-intro {
- padding: 0;
- }
-}
-
-.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;
-
- .components-form-toggle {
- margin: 2px 8px 0 0;
- }
- }
-
- .required {
- color: #dc3232;
- }
-
- .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: #fff;
- border-radius: 0;
- font-weight: 600;
- margin: 0;
- margin-bottom: 2px;
- padding: 0;
-
- &:focus {
- border-color: #fff;
- 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 #8d96a0;
- 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: #fff;
- 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: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
- 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: #fff;
- 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: #fff;
- 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: #fff;
- 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: #fff;
- 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: #fff 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/extensions/blocks/contact-form/index.js b/extensions/blocks/contact-form/index.js
deleted file mode 100644
index c3e75cbd21495..0000000000000
--- a/extensions/blocks/contact-form/index.js
+++ /dev/null
@@ -1,440 +0,0 @@
-/**
- * External dependencies
- */
-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 { __ } from '../../utils/i18n';
-import renderMaterialIcon from '../../utils/render-material-icon';
-
-export const name = 'contact-form';
-
-export const settings = {
- title: __( 'Form' ),
- description: __( 'A simple way to get feedback from folks visiting your site.' ),
- icon: renderMaterialIcon(
-
- ),
- keywords: [ __( 'email' ), __( 'feedback' ), __( 'contact' ) ],
- category: 'jetpack',
- supports: {
- reusable: false,
- html: false,
- },
- attributes: {
- subject: {
- type: 'string',
- default: '',
- },
- to: {
- type: 'string',
- default: '',
- },
- submitButtonText: {
- type: 'string',
- default: __( 'Submit' ),
- },
- 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' ),
- },
- },
-
- edit: JetpackContactForm,
- save: InnerBlocks.Content,
- deprecated: [
- {
- attributes: {
- subject: {
- type: 'string',
- default: '',
- },
- to: {
- type: 'string',
- default: '',
- },
- submit_button_text: {
- type: 'string',
- default: __( 'Submit' ),
- },
- 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 => (
-
-);
-
-const editMultiField = type => props => (
-
-);
-
-export const childBlocks = [
- {
- name: 'field-text',
- settings: {
- ...FieldDefaults,
- title: __( 'Text' ),
- description: __( 'When you need just a small amount of text, add a text input.' ),
- icon: renderMaterialIcon( ),
- edit: editField( 'text' ),
- },
- },
- {
- name: 'field-name',
- settings: {
- ...FieldDefaults,
- title: __( 'Name' ),
- description: __( 'Introductions are important. Add an input for folks to add their name.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: editField( 'text' ),
- },
- },
- {
- name: 'field-email',
- settings: {
- ...FieldDefaults,
- title: __( 'Email' ),
- keywords: [ __( 'e-mail' ), __( 'mail' ), 'email' ],
- description: __( 'Want to reply to folks? Add an email address input.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: editField( 'email' ),
- },
- },
-
- {
- name: 'field-url',
- settings: {
- ...FieldDefaults,
- title: __( 'Website' ),
- keywords: [ 'url', __( 'internet page' ), 'link' ],
- description: __( 'Add an address input for a website.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: editField( 'url' ),
- },
- },
-
- {
- name: 'field-date',
- settings: {
- ...FieldDefaults,
- title: __( 'Date Picker' ),
- keywords: [ __( 'Calendar' ), __( 'day month year', 'block search term' ) ],
- description: __( 'The best way to set a date. Add a date picker.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: editField( 'text' ),
- },
- },
- {
- name: 'field-telephone',
- settings: {
- ...FieldDefaults,
- title: __( 'Telephone' ),
- keywords: [ __( 'Phone' ), __( 'Cellular phone' ), __( 'Mobile' ) ],
- description: __( 'Add a phone number input.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: editField( 'tel' ),
- },
- },
- {
- name: 'field-textarea',
- settings: {
- ...FieldDefaults,
- title: __( 'Message' ),
- keywords: [ __( 'Textarea' ), 'textarea', __( 'Multiline text' ) ],
- description: __( 'Let folks speak their mind. This text box is great for longer responses.' ),
- icon: renderMaterialIcon( ),
- edit: props => (
-
- ),
- },
- },
- {
- name: 'field-checkbox',
- settings: {
- ...FieldDefaults,
- title: __( 'Checkbox' ),
- keywords: [ __( 'Confirm' ), __( 'Accept' ) ],
- description: __( 'Add a single checkbox.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: props => (
-
- ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: '',
- },
- },
- },
- },
- {
- name: 'field-checkbox-multiple',
- settings: {
- ...FieldDefaults,
- title: __( 'Checkbox Group' ),
- keywords: [ __( 'Choose Multiple' ), __( 'Option' ) ],
- description: __( 'People love options. Add several checkbox items.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: editMultiField( 'checkbox' ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: 'Choose several',
- },
- },
- },
- },
- {
- name: 'field-radio',
- settings: {
- ...FieldDefaults,
- title: __( 'Radio' ),
- keywords: [ __( 'Choose' ), __( 'Select' ), __( 'Option' ) ],
- description: __(
- 'Inspired by radios, only one radio item can be selected at a time. Add several radio button items.'
- ),
- icon: renderMaterialIcon(
-
-
-
-
- ),
- edit: editMultiField( 'radio' ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: 'Choose one',
- },
- },
- },
- },
- {
- name: 'field-select',
- settings: {
- ...FieldDefaults,
- title: __( 'Select' ),
- keywords: [ __( 'Choose' ), __( 'Dropdown' ), __( 'Option' ) ],
- description: __( 'Compact, but powerful. Add a select box with several items.' ),
- icon: renderMaterialIcon(
-
- ),
- edit: editMultiField( 'select' ),
- attributes: {
- ...FieldDefaults.attributes,
- label: {
- type: 'string',
- default: 'Select one',
- },
- },
- },
- },
-];
diff --git a/extensions/blocks/contact-info/address/edit.js b/extensions/blocks/contact-info/address/edit.js
deleted file mode 100644
index 5ba64592556fa..0000000000000
--- a/extensions/blocks/contact-info/address/edit.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import { PlainText } from '@wordpress/editor';
-import { Component, Fragment } from '@wordpress/element';
-import { ToggleControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../../utils/i18n';
-import { default as 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 = (
-
- setAttributes( { linkToGoogleMaps: newlinkToGoogleMaps } )
- }
- />
- );
-
- return (
-
- { ! isSelected && hasContent && save( this.props ) }
- { ( isSelected || ! hasContent ) && (
-
- setAttributes( { address: newAddress } ) }
- onKeyDown={ this.preventEnterKey }
- />
- setAttributes( { addressLine2: newAddressLine2 } ) }
- onKeyDown={ this.preventEnterKey }
- />
- setAttributes( { addressLine3: newAddressLine3 } ) }
- onKeyDown={ this.preventEnterKey }
- />
- setAttributes( { city: newCity } ) }
- onKeyDown={ this.preventEnterKey }
- />
- setAttributes( { region: newRegion } ) }
- onKeyDown={ this.preventEnterKey }
- />
- setAttributes( { postal: newPostal } ) }
- onKeyDown={ this.preventEnterKey }
- />
- setAttributes( { country: newCountry } ) }
- onKeyDown={ this.preventEnterKey }
- />
- { externalLink }
-
- ) }
-
- );
- }
-}
-
-export default AddressEdit;
diff --git a/extensions/blocks/contact-info/address/editor.js b/extensions/blocks/contact-info/address/editor.js
deleted file mode 100644
index 4f9f21a0fde07..0000000000000
--- a/extensions/blocks/contact-info/address/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/contact-info/address/index.js b/extensions/blocks/contact-info/address/index.js
deleted file mode 100644
index 7e0daca65cbe4..0000000000000
--- a/extensions/blocks/contact-info/address/index.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, Circle } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import renderMaterialIcon from '../../../utils/render-material-icon';
-import { __, _x } from '../../../utils/i18n';
-
-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' ),
- description: __( 'Lets you add a physical address with Schema markup.' ),
- keywords: [
- _x( 'location', 'block search term' ),
- _x( 'direction', 'block search term' ),
- _x( 'place', 'block search term' ),
- ],
- icon: renderMaterialIcon(
-
-
-
-
- ),
- category: 'jetpack',
- attributes,
- parent: [ 'jetpack/contact-info' ],
- edit,
- save,
-};
diff --git a/extensions/blocks/contact-info/address/save.js b/extensions/blocks/contact-info/address/save.js
deleted file mode 100644
index 9369b12d8e43b..0000000000000
--- a/extensions/blocks/contact-info/address/save.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * External dependencies
- */
-import { Fragment } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../../utils/i18n';
-
-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 },
-} ) => (
-
- { address && (
- { address }
- ) }
- { addressLine2 && (
- { addressLine2 }
- ) }
- { addressLine3 && (
- { addressLine3 }
- ) }
- { city && ! ( region || postal ) && { city }
}
- { city && ( region || postal ) && (
-
- { [
- { city } ,
- ', ',
- { region } ,
- ' ',
- { postal } ,
- ] }
-
- ) }
- { ! city && ( region || postal ) && (
-
- { [
- { region } ,
- ' ',
- { postal } ,
- ] }
-
- ) }
- { country && { country }
}
-
-);
-
-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 ) && (
-
- { props.attributes.linkToGoogleMaps && (
-
-
-
- ) }
- { ! props.attributes.linkToGoogleMaps &&
}
-
- );
-
-export default save;
diff --git a/extensions/blocks/contact-info/edit.js b/extensions/blocks/contact-info/edit.js
deleted file mode 100644
index b3ba63a66536b..0000000000000
--- a/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 (
-
-
-
- );
-};
-
-export default ContactInfoEdit;
diff --git a/extensions/blocks/contact-info/editor.js b/extensions/blocks/contact-info/editor.js
deleted file mode 100644
index 5b6bd3cdd88a0..0000000000000
--- a/extensions/blocks/contact-info/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { childBlocks, name, settings } from '.';
-
-registerJetpackBlock( name, settings, childBlocks );
diff --git a/extensions/blocks/contact-info/editor.scss b/extensions/blocks/contact-info/editor.scss
deleted file mode 100644
index 2e1e08a1cec89..0000000000000
--- a/extensions/blocks/contact-info/editor.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-.jetpack-contact-info-block {
- padding: 10px 18px;
- /* 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/extensions/blocks/contact-info/email/edit.js b/extensions/blocks/contact-info/email/edit.js
deleted file mode 100644
index 164b57eb206fa..0000000000000
--- a/extensions/blocks/contact-info/email/edit.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Internal dependencies
- */
-import save from './save';
-import { __ } from '../../../utils/i18n';
-import simpleInput from '../../../utils/simple-input';
-
-const EmailEdit = props => {
- const { setAttributes } = props;
- return simpleInput( 'email', props, __( 'Email' ), save, nextValue =>
- setAttributes( { email: nextValue } )
- );
-};
-
-export default EmailEdit;
diff --git a/extensions/blocks/contact-info/email/editor.js b/extensions/blocks/contact-info/email/editor.js
deleted file mode 100644
index 4f9f21a0fde07..0000000000000
--- a/extensions/blocks/contact-info/email/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/contact-info/email/index.js b/extensions/blocks/contact-info/email/index.js
deleted file mode 100644
index 8b87f75b7f5a6..0000000000000
--- a/extensions/blocks/contact-info/email/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * External dependencies
- */
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import renderMaterialIcon from '../../../utils/render-material-icon';
-import { __, _x } from '../../../utils/i18n';
-
-const attributes = {
- email: {
- type: 'string',
- default: '',
- },
-};
-
-export const name = 'email';
-
-export const settings = {
- title: __( 'Email Address' ),
- description: __(
- 'Lets you add an email address with an automatically generated click-to-email link.'
- ),
- keywords: [
- 'e-mail', // not translatable on purpose
- 'email', // not translatable on purpose
- _x( 'message', 'block search term' ),
- ],
- icon: renderMaterialIcon(
-
- ),
- category: 'jetpack',
- attributes,
- edit,
- save,
- parent: [ 'jetpack/contact-info' ],
-};
diff --git a/extensions/blocks/contact-info/email/save.js b/extensions/blocks/contact-info/email/save.js
deleted file mode 100644
index e0eb0204d1545..0000000000000
--- a/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.
-
- { email }
-
- ) : (
- // Email with punctionation.
-
-
- { emailToValidate }
-
- { email.slice( -( email.length - emailToValidate.length ) ) }
-
- );
- }
- // Just a plain string.
- return { email } ;
- } );
- return explodedInput;
-};
-
-const save = ( { attributes: { email }, className } ) =>
- email && { renderEmail( email ) }
;
-
-export default save;
diff --git a/extensions/blocks/contact-info/index.js b/extensions/blocks/contact-info/index.js
deleted file mode 100644
index da9b43977ac8d..0000000000000
--- a/extensions/blocks/contact-info/index.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * External dependencies
- */
-import { InnerBlocks } from '@wordpress/editor';
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import renderMaterialIcon from '../../utils/render-material-icon';
-import { __, _x } from '../../utils/i18n';
-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 } ) => (
-
-
-
-);
-
-export const name = 'contact-info';
-
-export const settings = {
- title: __( 'Contact Info' ),
- description: __(
- 'Lets you add an email address, phone number, and physical address with improved markup for better SEO results.'
- ),
- keywords: [
- _x( 'email', 'block search term' ),
- _x( 'phone', 'block search term' ),
- _x( 'address', 'block search term' ),
- ],
- icon: renderMaterialIcon(
-
- ),
- 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/extensions/blocks/contact-info/phone/edit.js b/extensions/blocks/contact-info/phone/edit.js
deleted file mode 100644
index 9be393ff1475f..0000000000000
--- a/extensions/blocks/contact-info/phone/edit.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Internal dependencies
- */
-import save from './save';
-import { __ } from '../../../utils/i18n';
-import simpleInput from '../../../utils/simple-input';
-
-const PhoneEdit = props => {
- const { setAttributes } = props;
- return simpleInput( 'phone', props, __( 'Phone number' ), save, nextValue =>
- setAttributes( { phone: nextValue } )
- );
-};
-
-export default PhoneEdit;
diff --git a/extensions/blocks/contact-info/phone/editor.js b/extensions/blocks/contact-info/phone/editor.js
deleted file mode 100644
index 4f9f21a0fde07..0000000000000
--- a/extensions/blocks/contact-info/phone/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/contact-info/phone/index.js b/extensions/blocks/contact-info/phone/index.js
deleted file mode 100644
index 5a52f99493cff..0000000000000
--- a/extensions/blocks/contact-info/phone/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * External dependencies
- */
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import renderMaterialIcon from '../../../utils/render-material-icon';
-import { __, _x } from '../../../utils/i18n';
-
-const attributes = {
- phone: {
- type: 'string',
- default: '',
- },
-};
-
-export const name = 'phone';
-
-export const settings = {
- title: __( 'Phone Number' ),
- description: __(
- 'Lets you add a phone number with an automatically generated click-to-call link.'
- ),
- keywords: [
- _x( 'mobile', 'block search term' ),
- _x( 'telephone', 'block search term' ),
- _x( 'cell', 'block search term' ),
- ],
- icon: renderMaterialIcon(
-
- ),
- category: 'jetpack',
- attributes,
- parent: [ 'jetpack/contact-info' ],
- edit,
- save,
-};
diff --git a/extensions/blocks/contact-info/phone/save.js b/extensions/blocks/contact-info/phone/save.js
deleted file mode 100644
index 50f6791464a06..0000000000000
--- a/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() ? (
-
- { prefix }
-
- ) : null;
- return [
- prefixSpan,
-
- { phoneNumber }
- ,
- ];
-}
-
-const save = ( { attributes: { phone }, className } ) =>
- phone && { renderPhone( phone ) }
;
-
-export default save;
diff --git a/extensions/blocks/contact-info/style.scss b/extensions/blocks/contact-info/style.scss
deleted file mode 100644
index 8f81ca897b1d9..0000000000000
--- a/extensions/blocks/contact-info/style.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.wp-block-jetpack-contact-info {
- margin-bottom: 1.5em;
-}
diff --git a/extensions/blocks/contact-info/view.js b/extensions/blocks/contact-info/view.js
deleted file mode 100644
index fd92905ca5dd0..0000000000000
--- a/extensions/blocks/contact-info/view.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Internal dependencies
- */
-
-import './style.scss';
diff --git a/extensions/blocks/gif/edit.js b/extensions/blocks/gif/edit.js
deleted file mode 100644
index 96c7c2a914598..0000000000000
--- a/extensions/blocks/gif/edit.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '../../utils/i18n';
-import classNames from 'classnames';
-import { Component, createRef } from '@wordpress/element';
-import { Button, PanelBody, Path, Placeholder, SVG, TextControl } from '@wordpress/components';
-import { InspectorControls, RichText } from '@wordpress/editor';
-
-import { icon, title } from './';
-
-const GIPHY_API_KEY = 't1PkR1Vq0mzHueIFBvZSZErgFs9NBmYW';
-const INPUT_PROMPT = __( 'Search for a term or paste a Giphy URL' );
-
-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 = (
-
- );
- return (
-
-
-
-
-
-
-
-
-
- { ! giphyUrl ? (
-
- { inputFields }
-
- ) : (
-
- { isSelected && inputFields }
- { isSelected && results && results.length > 1 && (
-
- { results.map( thumbnail => {
- const thumbnailStyle = {
- backgroundImage: `url(${ thumbnail.images.downsized_still.url })`,
- };
- return (
- {
- this.thumbnailClicked( thumbnail );
- } }
- style={ thumbnailStyle }
- />
- );
- } ) }
-
- ) }
-
- { ( ! RichText.isEmpty( caption ) || isSelected ) && !! giphyUrl && (
- {
- this.setState( { captionFocus: true } );
- } }
- onChange={ value => setAttributes( { caption: value } ) }
- placeholder={ __( 'Write caption…' ) }
- tagName="figcaption"
- value={ caption }
- />
- ) }
-
- ) }
-
- );
- }
-}
-export default GifEdit;
diff --git a/extensions/blocks/gif/editor.js b/extensions/blocks/gif/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/gif/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/gif/editor.scss b/extensions/blocks/gif/editor.scss
deleted file mode 100644
index 6505083f85efc..0000000000000
--- a/extensions/blocks/gif/editor.scss
+++ /dev/null
@@ -1,84 +0,0 @@
-.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 #555d66;
- }
- &:focus {
- box-shadow: 0 0 0 2px #00a0d2;
- outline: 0;
- }
- }
-}
-.components-panel__body-gif-branding {
- svg {
- display: block;
- margin: 0 auto;
- max-width: 200px;
- }
- svg path {
- fill: #ccc;
- }
-}
diff --git a/extensions/blocks/gif/index.js b/extensions/blocks/gif/index.js
deleted file mode 100644
index 045d1618173f9..0000000000000
--- a/extensions/blocks/gif/index.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import { __ } from '../../utils/i18n';
-
-// Ordering is important! Editor overrides style!
-import './style.scss';
-import './editor.scss';
-
-export const name = 'gif';
-export const title = __( 'GIF' );
-
-export const icon = (
-
-
-
-
-);
-
-export const settings = {
- title,
- icon,
- category: 'jetpack',
- keywords: [ __( 'animated' ), __( 'giphy' ), __( 'image' ) ],
- description: __( 'Search for and insert an animated image.' ),
- 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/extensions/blocks/gif/style.scss b/extensions/blocks/gif/style.scss
deleted file mode 100644
index 2e7b057a79ac4..0000000000000
--- a/extensions/blocks/gif/style.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-.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: #555d66;
- 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/extensions/blocks/gif/view.js b/extensions/blocks/gif/view.js
deleted file mode 100644
index 6a6dda31712c5..0000000000000
--- a/extensions/blocks/gif/view.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Internal dependencies
- */
-import './style.scss';
diff --git a/extensions/blocks/mailchimp/edit.js b/extensions/blocks/mailchimp/edit.js
deleted file mode 100644
index 8941092eb831f..0000000000000
--- a/extensions/blocks/mailchimp/edit.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-import { __ } from '../../utils/i18n';
-import classnames from 'classnames';
-import SubmitButton from '../../utils/submit-button';
-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 = (
-
-
-
- );
- const placeholder = (
-
-
- { __(
- 'You need to connect your Mailchimp account and choose a list in order to start collecting Email subscribers.'
- ) }
-
-
-
- { __( 'Set up Mailchimp form' ) }
-
-
-
-
- { __( 'Re-check Connection' ) }
-
-
-
- );
- const inspectorControls = (
-
-
-
-
-
-
-
-
-
-
- { __( 'Manage Connection' ) }
-
-
- );
- const blockClasses = classnames( className, {
- [ `${ classPrefix }notication-audition` ]: audition,
- } );
- const blockContent = (
-
-
false }
- placeholder={ emailPlaceholder }
- title={ __( 'You can edit the email placeholder in the sidebar.' ) }
- type="email"
- />
-
- setAttributes( { consentText: value } ) }
- inlineToolbar
- />
- { audition && (
-
- { this.labelForAuditionType( audition ) }
-
- ) }
-
- );
- return (
-
- { noticeUI }
- { connected === API_STATE_LOADING && waiting }
- { connected === API_STATE_NOTCONNECTED && placeholder }
- { connected === API_STATE_CONNECTED && inspectorControls }
- { connected === API_STATE_CONNECTED && blockContent }
-
- );
- };
-}
-
-export default withNotices( MailchimpSubscribeEdit );
diff --git a/extensions/blocks/mailchimp/editor.js b/extensions/blocks/mailchimp/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/mailchimp/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/mailchimp/editor.scss b/extensions/blocks/mailchimp/editor.scss
deleted file mode 100644
index 84de75481ad0a..0000000000000
--- a/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/extensions/blocks/mailchimp/index.js b/extensions/blocks/mailchimp/index.js
deleted file mode 100644
index a14f2f5d4cbbb..0000000000000
--- a/extensions/blocks/mailchimp/index.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __, _x } from '../../utils/i18n';
-import edit from './edit';
-import './editor.scss';
-
-export const name = 'mailchimp';
-
-export const icon = (
-
-
-
-
-);
-
-export const settings = {
- title: __( 'Mailchimp' ),
- icon,
- description: __( 'A form enabling readers to join a Mailchimp list.' ),
- category: 'jetpack',
- keywords: [
- _x( 'email', 'block search term' ),
- _x( 'subscription', 'block search term' ),
- _x( 'newsletter', 'block search term' ),
- ],
- attributes: {
- emailPlaceholder: {
- type: 'string',
- default: __( 'Enter your email' ),
- },
- submitButtonText: {
- type: 'string',
- default: __( 'Join my email list' ),
- },
- 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.'
- ),
- },
- processingLabel: {
- type: 'string',
- default: __( 'Processing…' ),
- },
- successLabel: {
- type: 'string',
- default: __( "Success! You're on the list." ),
- },
- errorLabel: {
- type: 'string',
- default: __(
- "Whoops! There was an error and we couldn't process your subscription. Please reload the page and try again."
- ),
- },
- },
- edit,
- save: () => null,
-};
diff --git a/extensions/blocks/mailchimp/view.js b/extensions/blocks/mailchimp/view.js
deleted file mode 100644
index a2ec768045560..0000000000000
--- a/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/extensions/blocks/mailchimp/view.scss b/extensions/blocks/mailchimp/view.scss
deleted file mode 100644
index 56b852e28ffaa..0000000000000
--- a/extensions/blocks/mailchimp/view.scss
+++ /dev/null
@@ -1,32 +0,0 @@
-.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: $muriel-hot-red-500;
- color: #fff;
- }
-
- &.wp-block-jetpack-mailchimp_processing {
- background-color: rgba( 0, 0, 0, 0.025 );
- }
-
- &.wp-block-jetpack-mailchimp_success {
- background-color: $muriel-hot-green-500;
- color: #fff;
- }
- }
-
-}
diff --git a/extensions/blocks/map/add-point/index.js b/extensions/blocks/map/add-point/index.js
deleted file mode 100644
index dc08337d98afc..0000000000000
--- a/extensions/blocks/map/add-point/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-import { Button, Dashicon, Popover } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import LocationSearch from '../location-search';
-import { __ } from '../../../utils/i18n';
-import './style.scss';
-
-export class AddPoint extends Component {
- render() {
- const { onClose, onAddPoint, onError, apiKey } = this.props;
- return (
-
- { __( 'Add marker' ) }
-
-
-
-
-
-
-
- );
- }
-}
-
-AddPoint.defaultProps = {
- onAddPoint: () => {},
- onClose: () => {},
- onError: () => {},
-};
-
-export default AddPoint;
diff --git a/extensions/blocks/map/add-point/oval.svg b/extensions/blocks/map/add-point/oval.svg
deleted file mode 100644
index cb149ec47cc3d..0000000000000
--- a/extensions/blocks/map/add-point/oval.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- Oval Copy
- Created with Sketch.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/extensions/blocks/map/add-point/style.scss b/extensions/blocks/map/add-point/style.scss
deleted file mode 100644
index 9cce943eb3831..0000000000000
--- a/extensions/blocks/map/add-point/style.scss
+++ /dev/null
@@ -1,46 +0,0 @@
-
-.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;
- box-shadow: none;
- }
-}
-.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: #aaa;
- }
-}
diff --git a/extensions/blocks/map/component.js b/extensions/blocks/map/component.js
deleted file mode 100644
index efd19c3a0d411..0000000000000
--- a/extensions/blocks/map/component.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '../../utils/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 (
-
- );
- } );
- const infoWindow = mapboxgl && (
- this.setState( { activeMarker: null } ) }
- >
- { activeMarker && admin && (
-
- updateActiveMarker( { title: value } ) }
- />
- updateActiveMarker( { caption: value } ) }
- />
-
- { __( 'Delete Marker' ) }
-
-
- ) }
-
- { activeMarker && ! admin && (
-
- { title }
- { caption }
-
- ) }
-
- );
- return (
-
-
- { mapMarkers }
-
- { infoWindow }
- { addPoint }
-
- );
- }
- 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/extensions/blocks/map/edit.js b/extensions/blocks/map/edit.js
deleted file mode 100644
index 54168e1dbd0e3..0000000000000
--- a/extensions/blocks/map/edit.js
+++ /dev/null
@@ -1,282 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-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 { __ } from '../../utils/i18n';
-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 = (
-
-
-
-
- this.setState( { addPointVisibility: true } ) }
- />
-
-
-
-
- setAttributes( { mapStyle: value } ) }
- options={ settings.mapStyleOptions }
- />
- setAttributes( { mapDetails: value } ) }
- />
-
- setAttributes( { markerColor: value } ),
- label: 'Marker Color',
- },
- ] }
- />
- { points.length ? (
-
- {
- setAttributes( { points: value } );
- } }
- />
-
- ) : null }
-
- this.setState( { apiKeyControl: value } ) }
- />
-
-
- { __( 'Update Token' ) }
-
-
- { __( 'Remove Token' ) }
-
-
-
-
-
- );
- const placholderAPIStateLoading = (
-
-
-
- );
- const placeholderAPIStateFailure = (
-
-
-
- { __( 'To use the map block, you need an Access Token.' ) }
-
-
- { __( 'Create an account or log in to Mapbox.' ) }
-
-
- { __(
- 'Locate and copy the default access token. Then, paste it into the field below.'
- ) }
-
-
-
- { __( 'Set Token' ) }
-
-
-
- );
- const placeholderAPIStateSuccess = (
-
- { inspectorControls }
-
-
{
- 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 && (
- this.setState( { addPointVisibility: false } ) }
- apiKey={ apiKey }
- onError={ this.onError }
- tagName="AddPoint"
- />
- ) }
-
-
-
- );
- return (
-
- { noticeUI }
- { apiState === API_STATE_LOADING && placholderAPIStateLoading }
- { apiState === API_STATE_FAILURE && placeholderAPIStateFailure }
- { apiState === API_STATE_SUCCESS && placeholderAPIStateSuccess }
-
- );
- }
-}
-
-export default withNotices( MapEdit );
diff --git a/extensions/blocks/map/editor.js b/extensions/blocks/map/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/map/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/map/editor.scss b/extensions/blocks/map/editor.scss
deleted file mode 100644
index ab66d12b53279..0000000000000
--- a/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/extensions/blocks/map/index.js b/extensions/blocks/map/index.js
deleted file mode 100644
index 2e66caaebd597..0000000000000
--- a/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/extensions/blocks/map/info-window/index.js b/extensions/blocks/map/info-window/index.js
deleted file mode 100644
index f469efad91c8f..0000000000000
--- a/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/extensions/blocks/map/location-search/index.js b/extensions/blocks/map/location-search/index.js
deleted file mode 100644
index 43c2d9edb0d2e..0000000000000
--- a/extensions/blocks/map/location-search/index.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * External dependencies
- */
-import { Component, createRef } from '@wordpress/element';
-import { BaseControl, TextControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import Lookup from '../lookup';
-import { __ } from '../../../utils/i18n';
-
-const placeholderText = __( 'Add a marker…' );
-
-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 => { option.place_name } ,
- 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 (
-
-
-
- { ( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) => (
-
- ) }
-
-
-
- );
- }
-}
-
-LocationSearch.defaultProps = {
- onError: () => {},
-};
-
-export default LocationSearch;
diff --git a/extensions/blocks/map/locations/index.js b/extensions/blocks/map/locations/index.js
deleted file mode 100644
index 80385891a2656..0000000000000
--- a/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 ) => (
-
- this.setMarkerField( 'title', title, index ) }
- />
- this.setMarkerField( 'caption', caption, index ) }
- />
-
- Delete Marker
-
-
- ) );
- return (
-
- );
- }
-}
-
-Locations.defaultProps = {
- points: Object.freeze( [] ),
- onChange: () => {},
-};
-
-export default Locations;
diff --git a/extensions/blocks/map/locations/style.scss b/extensions/blocks/map/locations/style.scss
deleted file mode 100644
index 73f5e8b51d2e1..0000000000000
--- a/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/extensions/blocks/map/lookup/index.js b/extensions/blocks/map/lookup/index.js
deleted file mode 100644
index e4ded4d691fee..0000000000000
--- a/extensions/blocks/map/lookup/index.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-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 { sprintf } from '@wordpress/i18n';
-import { withInstanceId, compose } from '@wordpress/compose';
-
-/**
- * Internal dependencies
- */
-import { __, _n } from '../../../utils/i18n';
-
-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'
- ),
- filteredOptions.length
- ),
- 'assertive'
- );
- } else {
- debouncedSpeak( __( 'No results.' ), '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 (
-
- { children( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) }
- { isExpanded && (
-
-
- { map( filteredOptions, ( option, index ) => (
- this.select( option ) }
- >
- { option.label }
-
- ) ) }
-
-
- ) }
-
- );
- }
-}
-export default compose( [
- withSpokenMessages,
- withInstanceId,
- withFocusOutside, // this MUST be the innermost HOC as it calls handleFocusOutside
-] )( Lookup );
diff --git a/extensions/blocks/map/map-marker/index.js b/extensions/blocks/map/map-marker/index.js
deleted file mode 100644
index e8db9934a76e4..0000000000000
--- a/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 =
- ' ';
- }
- render() {
- return null;
- }
-}
-
-MapMarker.defaultProps = {
- point: {},
- map: null,
- markerColor: '#000000',
- mapboxgl: null,
- onClick: () => {},
-};
-
-export default MapMarker;
diff --git a/extensions/blocks/map/map-marker/style.scss b/extensions/blocks/map/map-marker/style.scss
deleted file mode 100644
index 6c5a2a65a1cc8..0000000000000
--- a/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/extensions/blocks/map/map-theme-picker/index.js b/extensions/blocks/map/map-theme-picker/index.js
deleted file mode 100644
index a4286f1f496c7..0000000000000
--- a/extensions/blocks/map/map-theme-picker/index.js
+++ /dev/null
@@ -1,49 +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 (
- onChange( option.value ) }
- >
- { option.label }
-
- );
- } );
- return (
-
- { label }
- { buttons }
-
- );
- }
-}
-
-MapThemePicker.defaultProps = {
- label: '',
- options: [],
- value: null,
- onChange: () => {},
-};
-
-export default MapThemePicker;
diff --git a/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg b/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg
deleted file mode 100644
index 34cc14120423d..0000000000000
Binary files a/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg and /dev/null differ
diff --git a/extensions/blocks/map/map-theme-picker/map-theme_default.jpg b/extensions/blocks/map/map-theme-picker/map-theme_default.jpg
deleted file mode 100644
index 35505eb164be3..0000000000000
Binary files a/extensions/blocks/map/map-theme-picker/map-theme_default.jpg and /dev/null differ
diff --git a/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg b/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg
deleted file mode 100644
index ef6ae41708ada..0000000000000
Binary files a/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg and /dev/null differ
diff --git a/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg b/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg
deleted file mode 100644
index eee1a2dae1c3d..0000000000000
Binary files a/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg and /dev/null differ
diff --git a/extensions/blocks/map/map-theme-picker/style.scss b/extensions/blocks/map/map-theme-picker/style.scss
deleted file mode 100644
index b970fa502c818..0000000000000
--- a/extensions/blocks/map/map-theme-picker/style.scss
+++ /dev/null
@@ -1,35 +0,0 @@
-
-.component__map-theme-picker__button {
- .edit-post-settings-sidebar__panel-block & {
- border: 1px solid lightgray;
- border-radius: 100%;
- width: 56px;
- height: 56px;
- margin: 2px;
- text-indent: -9999px;
- background-color: lightgray;
- 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/extensions/blocks/map/mapbox-map-formatter/index.js b/extensions/blocks/map/mapbox-map-formatter/index.js
deleted file mode 100644
index 6ec21ad855f60..0000000000000
--- a/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/extensions/blocks/map/save.js b/extensions/blocks/map/save.js
deleted file mode 100644
index ffa82641dcd83..0000000000000
--- a/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 (
-
- { point.title }
-
- );
- } );
- const alignClassName = align ? `align${ align }` : null;
- // All camelCase attribute names converted to snake_case data attributes
- return (
-
- { points.length > 0 &&
}
-
- );
- }
-}
-
-export default MapSave;
diff --git a/extensions/blocks/map/settings.js b/extensions/blocks/map/settings.js
deleted file mode 100644
index ce0ceaeee2ba5..0000000000000
--- a/extensions/blocks/map/settings.js
+++ /dev/null
@@ -1,100 +0,0 @@
-// Disable forbidden etc. so that frontend component does not depend on @wordpress/component
-/* eslint-disable react/forbid-elements */
-/**
- * External dependencies
- */
-import { __ } from '../../utils/i18n';
-
-export const settings = {
- name: 'map',
- prefix: 'jetpack',
- title: __( 'Map' ),
- icon: (
- /* Do not use SVG components from @wordpress/component to avoid frontend bloat */
-
-
-
-
- ),
- category: 'jetpack',
- keywords: [ __( 'map' ), __( 'location' ) ],
- description: __( 'Add an interactive map showing one or more locations.' ),
- 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' ),
- },
- {
- value: 'black_and_white',
- label: __( 'Black and white' ),
- },
- {
- value: 'satellite',
- label: __( 'Satellite' ),
- },
- {
- value: 'terrain',
- label: __( 'Terrain' ),
- },
- ],
- validAlignments: [ 'center', 'wide', 'full' ],
- markerIcon: (
- /* Do not use SVG components from @wordpress/component to avoid frontend bloat */
-
-
-
-
-
-
-
-
- ),
-};
diff --git a/extensions/blocks/map/style.scss b/extensions/blocks/map/style.scss
deleted file mode 100644
index 72fc4a4abbc75..0000000000000
--- a/extensions/blocks/map/style.scss
+++ /dev/null
@@ -1,21 +0,0 @@
-
-.wp-block-jetpack-map {
- .wp-block-jetpack-map__gm-container {
- width: 100%;
- overflow: hidden;
- background: lightgray;
- 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/extensions/blocks/map/view.js b/extensions/blocks/map/view.js
deleted file mode 100644
index fc825d6704185..0000000000000
--- a/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/extensions/blocks/markdown/edit.js b/extensions/blocks/markdown/edit.js
deleted file mode 100644
index da938f30527d0..0000000000000
--- a/extensions/blocks/markdown/edit.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * External dependencies
- */
-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';
-import { __ } from '../../utils/i18n';
-
-/**
- * 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 (
-
- { label }
-
- );
- }
-
- render() {
- const { attributes, className, isSelected } = this.props;
- const { source } = attributes;
- const { activePanel } = this.state;
-
- if ( ! isSelected && this.isEmpty() ) {
- return (
-
- { __( 'Write your _Markdown_ **here**…' ) }
-
- );
- }
-
- return (
-
-
-
- { this.renderToolbarButton( PANEL_EDITOR, __( 'Markdown' ) ) }
- { this.renderToolbarButton( PANEL_PREVIEW, __( 'Preview' ) ) }
-
-
-
- { activePanel === PANEL_PREVIEW || ! isSelected ? (
-
- ) : (
-
- ) }
-
- );
- }
-}
-
-export default compose( [
- withSelect( select => ( {
- currentBlockId: select( 'core/editor' ).getSelectedBlockClientId(),
- } ) ),
- withDispatch( ( dispatch, { currentBlockId } ) => ( {
- removeBlock: () => dispatch( 'core/editor' ).removeBlocks( currentBlockId ),
- } ) ),
-] )( MarkdownEdit );
diff --git a/extensions/blocks/markdown/editor.js b/extensions/blocks/markdown/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/markdown/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/markdown/editor.scss b/extensions/blocks/markdown/editor.scss
deleted file mode 100644
index 66fe610e4949c..0000000000000
--- a/extensions/blocks/markdown/editor.scss
+++ /dev/null
@@ -1,148 +0,0 @@
-// @TODO: Replace with Gutenberg variables
-$black: #000;
-$dark-gray-100: #8f98a1;
-$dark-gray-800: #23282d;
-$editor-html-font: Menlo, Consolas, monaco, monospace;
-$light-gray-200: #f3f4f5;
-$light-gray-500: #e2e4e7;
-$text-editor-font-size: inherit;
-
-.wp-block-jetpack-markdown__placeholder {
- opacity: 0.62; // See https://github.com/WordPress/gutenberg/blob/c0f87a212b0ad25c18ac5bf8c2e9b1cb780f1a14/packages/editor/src/components/rich-text/style.scss#L110
- 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;
- }
-
- 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;
- }
- }
-
- code,
- pre {
- color: $dark-gray-800;
- font-family: $editor-html-font;
- }
-
- code {
- background: $light-gray-200;
- border-radius: 2px;
- font-size: $text-editor-font-size;
- padding: 2px;
- }
-
- pre {
- border-radius: 4px;
- border: 1px solid $light-gray-500;
- font-size: 14px;
- 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: 14px;
-
- &:focus {
- border-color: transparent;
- box-shadow: 0 0 0 transparent;
- }
- }
-}
diff --git a/extensions/blocks/markdown/index.js b/extensions/blocks/markdown/index.js
deleted file mode 100644
index be38d73e2d584..0000000000000
--- a/extensions/blocks/markdown/index.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * External dependencies
- */
-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';
-import { __ } from '../../utils/i18n';
-
-export const name = 'markdown';
-
-export const settings = {
- title: __( 'Markdown' ),
-
- description: (
-
- { __( 'Use regular characters and punctuation to style text, links, and lists.' ) }
-
- { __( 'Support reference' ) }
-
-
- ),
-
- icon: (
-
-
-
-
- ),
-
- category: 'jetpack',
-
- keywords: [ __( 'formatting' ), __( 'syntax' ), __( 'markup' ) ],
-
- attributes: {
- //The Markdown source is saved in the block content comments delimiter
- source: { type: 'string' },
- },
-
- supports: {
- html: false,
- },
-
- edit,
-
- save,
-};
diff --git a/extensions/blocks/markdown/renderer.js b/extensions/blocks/markdown/renderer.js
deleted file mode 100644
index a77d24f24ebf5..0000000000000
--- a/extensions/blocks/markdown/renderer.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * External dependencies
- */
-import MarkdownIt from 'markdown-it';
-import { RawHTML } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-
-/**
- * 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?' ) );
-
- if ( ! hasConfirmed ) {
- event.preventDefault();
- }
- }
-};
-
-export default ( { className, source = '' } ) => (
-
- { source.length ? markdownConverter.render( source ) : '' }
-
-);
diff --git a/extensions/blocks/markdown/save.js b/extensions/blocks/markdown/save.js
deleted file mode 100644
index 06d08138f7604..0000000000000
--- a/extensions/blocks/markdown/save.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Internal dependencies
- */
-import MarkdownRenderer from './renderer';
-
-export default ( { attributes, className } ) => (
-
-);
diff --git a/extensions/blocks/publicize/connection-verify.js b/extensions/blocks/publicize/connection-verify.js
deleted file mode 100644
index 92cd1f62ff583..0000000000000
--- a/extensions/blocks/publicize/connection-verify.js
+++ /dev/null
@@ -1,115 +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 { Button, Notice } from '@wordpress/components';
-import { Component, Fragment } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-
-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 (
-
-
- { __(
- 'Before you hit Publish, please refresh the following connection(s) to make sure we can Publicize your post:'
- ) }
-
- { refreshableConnections.map( connection => (
-
- { connection.refresh_text }
-
- ) ) }
-
- );
- }
-
- return null;
- }
-
- renderNonRefreshableConnections() {
- const { failedConnections } = this.props;
- const nonRefreshableConnections = failedConnections.filter(
- connection => ! connection.can_refresh
- );
-
- if ( nonRefreshableConnections.length ) {
- return nonRefreshableConnections.map( connection => (
-
- { connection.test_message }
-
- ) );
- }
-
- return null;
- }
-
- render() {
- return (
-
- { this.renderRefreshableConnections() }
- { this.renderNonRefreshableConnections() }
-
- );
- }
-}
-
-export default compose( [
- withSelect( select => ( {
- failedConnections: select( 'jetpack/publicize' ).getFailedConnections(),
- } ) ),
- withDispatch( dispatch => ( {
- refreshConnections: dispatch( 'jetpack/publicize' ).refreshConnectionTestResults,
- } ) ),
-] )( PublicizeConnectionVerify );
diff --git a/extensions/blocks/publicize/connection.js b/extensions/blocks/publicize/connection.js
deleted file mode 100644
index 3bbb810c55321..0000000000000
--- a/extensions/blocks/publicize/connection.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * Publicize connection form component.
- *
- * Component to display connection label and a
- * checkbox to enable/disable the connection for sharing.
- */
-
-/**
- * External dependencies
- */
-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 { __ } from '../../utils/i18n';
-import PublicizeServiceIcon from './service-icon';
-import getSiteFragment from '../../shared/get-site-fragment';
-
-class PublicizeConnection extends Component {
- state = {
- showGooglePlusNotice: true,
- };
-
- /**
- * Hide notice when it's removed
- */
- onRemoveGooglePlusNotice = () => {
- this.setState( {
- showGooglePlusNotice: false,
- } );
- };
-
- /**
- * If this is the Google+ connection, display a notice.
- *
- * @param {string} serviceName Name of the connnected social network.
- * @returns {object} Message warning users of Google+ shutting down.
- */
- maybeDisplayGooglePlusNotice = serviceName =>
- 'google-plus' === serviceName &&
- this.state.showGooglePlusNotice && (
-
- { __(
- 'Google+ will shut down in April 2019. You can keep posting with your existing Google+ connection through March.'
- ) }
-
- { __( ' Learn more' ) }.
-
-
- );
-
- /**
- * 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() && (
-
-
- { __(
- 'Your LinkedIn connection needs to be reauthenticated ' +
- 'to continue working – head to Sharing to take care of it.'
- ) }
-
-
- { __( 'Go to Sharing settings' ) }
-
-
- );
-
- /**
- * 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 = (
-
- );
-
- if ( disabled || this.connectionIsFailing() || this.connectionNeedsReauth() ) {
- toggle = { toggle } ;
- }
-
- return (
-
- { this.maybeDisplayGooglePlusNotice( serviceName ) }
- { this.maybeDisplayLinkedInNotice() }
-
-
-
- { label }
-
- { toggle }
-
-
- );
- }
-}
-
-export default withSelect( select => ( {
- failedConnections: select( 'jetpack/publicize' ).getFailedConnections(),
- mustReauthConnections: select( 'jetpack/publicize' ).getMustReauthConnections(),
-} ) )( PublicizeConnection );
diff --git a/extensions/blocks/publicize/editor.js b/extensions/blocks/publicize/editor.js
deleted file mode 100644
index e2811b0c0d125..0000000000000
--- a/extensions/blocks/publicize/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../utils/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/extensions/blocks/publicize/editor.scss b/extensions/blocks/publicize/editor.scss
deleted file mode 100644
index ba40bef74b909..0000000000000
--- a/extensions/blocks/publicize/editor.scss
+++ /dev/null
@@ -1,105 +0,0 @@
-
-// @TODO: Replace with Gutenberg variables
-$dark-gray-500: #555d66;
-
-.jetpack-publicize-message-box {
- background-color: #edeff0;
- 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 );
- }
- &.is-google-plus {
- fill: var( --color-gplus );
- }
-}
-
-.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/extensions/blocks/publicize/form-unwrapped.js b/extensions/blocks/publicize/form-unwrapped.js
deleted file mode 100644
index d9640bab79102..0000000000000
--- a/extensions/blocks/publicize/form-unwrapped.js
+++ /dev/null
@@ -1,113 +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 { 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';
-import { __, _n } from '../../utils/i18n';
-
-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 (
-
- );
- }
-}
-
-export default PublicizeFormUnwrapped;
diff --git a/extensions/blocks/publicize/form.js b/extensions/blocks/publicize/form.js
deleted file mode 100644
index 7785d6d8b685d..0000000000000
--- a/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/get';
-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/extensions/blocks/publicize/index.js b/extensions/blocks/publicize/index.js
deleted file mode 100644
index 8f29e933cf42b..0000000000000
--- a/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 { 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';
-import { __ } from '../../utils/i18n';
-
-export const name = 'publicize';
-
-export const settings = {
- render: () => (
-
-
-
-
-
-
-
- { __( 'Share this post' ) }
-
- }
- >
-
-
-
- ),
-};
diff --git a/extensions/blocks/publicize/panel.js b/extensions/blocks/publicize/panel.js
deleted file mode 100644
index 55cb3989599f0..0000000000000
--- a/extensions/blocks/publicize/panel.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Publicize sharing panel component.
- *
- * Displays Publicize notifications if no
- * services are connected or displays form if
- * services are connected.
- */
-
-/**
- * External dependencies
- */
-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';
-import { __ } from '../../utils/i18n';
-
-const PublicizePanel = ( { connections, refreshConnections } ) => (
-
- { connections && connections.some( connection => connection.enabled ) && (
-
- ) }
- { __( "Connect and select the accounts where you'd like to share your post." ) }
- { connections && connections.length > 0 && (
-
- ) }
- { connections && 0 === connections.length && (
-
- ) }
-
-);
-
-export default compose( [
- withSelect( select => ( {
- connections: select( 'core/editor' ).getEditedPostAttribute( 'jetpack_publicize_connections' ),
- } ) ),
- withDispatch( dispatch => ( {
- refreshConnections: dispatch( 'core/editor' ).refreshPost,
- } ) ),
-] )( PublicizePanel );
diff --git a/extensions/blocks/publicize/service-icon.js b/extensions/blocks/publicize/service-icon.js
deleted file mode 100644
index ff15c7cacd711..0000000000000
--- a/extensions/blocks/publicize/service-icon.js
+++ /dev/null
@@ -1,74 +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 = (
-
-
-
-
-
-
-);
-const TwitterIcon = (
-
-
-
-
-
-
-);
-const LinkedinIcon = (
-
-
-
-
-
-
-);
-const TumblrIcon = (
-
-
-
-
-
-
-);
-const GooglePlusIcon = (
-
-
-
-
-
-
-);
-
-export default ( { serviceName } ) => {
- const defaultProps = {
- className: `jetpack-publicize-gutenberg-social-icon is-${ serviceName }`,
- size: 24,
- };
-
- switch ( serviceName ) {
- case 'facebook':
- return ;
- case 'twitter':
- return ;
- case 'linkedin':
- return ;
- case 'tumblr':
- return ;
- case 'google-plus':
- return ;
- }
-
- return null;
-};
diff --git a/extensions/blocks/publicize/settings-button.js b/extensions/blocks/publicize/settings-button.js
deleted file mode 100644
index 7f97d457c00d6..0000000000000
--- a/extensions/blocks/publicize/settings-button.js
+++ /dev/null
@@ -1,71 +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 classnames from 'classnames';
-import { Component } from '@wordpress/element';
-import { ExternalLink } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-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/sharing/${ 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 (
-
- { __( 'Connect an account' ) }
-
- );
- }
-}
-
-export default PublicizeSettingsButton;
diff --git a/extensions/blocks/publicize/store/actions.js b/extensions/blocks/publicize/store/actions.js
deleted file mode 100644
index e5b7169428a85..0000000000000
--- a/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/extensions/blocks/publicize/store/controls.js b/extensions/blocks/publicize/store/controls.js
deleted file mode 100644
index afe6eccdf59e4..0000000000000
--- a/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/extensions/blocks/publicize/store/effects.js b/extensions/blocks/publicize/store/effects.js
deleted file mode 100644
index 594c8b72a6d09..0000000000000
--- a/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/extensions/blocks/publicize/store/index.js b/extensions/blocks/publicize/store/index.js
deleted file mode 100644
index 337167bc97caf..0000000000000
--- a/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/extensions/blocks/publicize/store/middlewares.js b/extensions/blocks/publicize/store/middlewares.js
deleted file mode 100644
index 1403b8084f1dc..0000000000000
--- a/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/extensions/blocks/publicize/store/reducer.js b/extensions/blocks/publicize/store/reducer.js
deleted file mode 100644
index 80af0701001a3..0000000000000
--- a/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/extensions/blocks/publicize/store/selectors.js b/extensions/blocks/publicize/store/selectors.js
deleted file mode 100644
index db86a4fec0d5c..0000000000000
--- a/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/extensions/blocks/related-posts/edit.js b/extensions/blocks/related-posts/edit.js
deleted file mode 100644
index f6816e822e909..0000000000000
--- a/extensions/blocks/related-posts/edit.js
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * External dependencies
- */
-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';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-
-export const MAX_POSTS_TO_SHOW = 6;
-
-function PlaceholderPostEdit( props ) {
- return (
-
-
- { __( "Preview unavailable: you haven't published enough posts with similar content." ) }
-
- { props.displayThumbnails && (
-
-
- { __( 'Grey square' ) }
-
-
-
- { __( 'Icon for image' ) }
-
-
-
-
- ) }
-
- { props.displayDate && (
-
- { __( 'August 3, 2018' ) }
-
- ) }
- { props.displayContext && (
-
- { __( 'In “Uncategorized”' ) }
-
- ) }
-
- );
-}
-
-function RelatedPostsEditItem( props ) {
- return (
-
-
- { props.post.title }
-
- { props.displayThumbnails && props.post.img && props.post.img.src && (
-
-
-
- ) }
- { props.displayDate && (
-
- { props.post.date }
-
- ) }
- { props.displayContext && (
-
- { props.post.context }
-
- ) }
-
- );
-}
-
-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 (
-
-
- { props.posts.slice( 0, topRowEnd ) }
-
- { displayLowerRow && (
-
- { props.posts.slice( topRowEnd ) }
-
- ) }
-
- );
-}
-
-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' ),
- onClick: () => setAttributes( { postLayout: 'grid' } ),
- isActive: postLayout === 'grid',
- },
- {
- icon: 'list-view',
- title: __( 'List View' ),
- 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(
-
- );
- } else {
- displayPosts.push(
-
- );
- }
- }
-
- return (
-
-
-
- setAttributes( { displayThumbnails: value } ) }
- />
- setAttributes( { displayDate: value } ) }
- />
- setAttributes( { displayContext: value } ) }
- />
-
- setAttributes( { postsToShow: Math.min( value, MAX_POSTS_TO_SHOW ) } )
- }
- min={ 1 }
- max={ MAX_POSTS_TO_SHOW }
- />
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-export default compose(
- withInstanceId,
- withSelect( select => {
- const { getCurrentPost } = select( 'core/editor' );
- const posts = get( getCurrentPost(), 'jetpack-related-posts', [] );
-
- return {
- posts,
- };
- } )
-)( RelatedPostsEdit );
diff --git a/extensions/blocks/related-posts/editor.js b/extensions/blocks/related-posts/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/related-posts/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/related-posts/index.js b/extensions/blocks/related-posts/index.js
deleted file mode 100644
index 486cad0f75f3e..0000000000000
--- a/extensions/blocks/related-posts/index.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * External dependencies
- */
-import { G, Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import './style.scss';
-import edit from './edit';
-import { __, _x } from '../../utils/i18n';
-
-export const name = 'related-posts';
-
-export const settings = {
- title: __( 'Related Posts' ),
-
- icon: (
-
-
-
-
-
- ),
-
- category: 'jetpack',
-
- keywords: [
- _x( 'Similar content', 'block search term' ),
- _x( 'Linked', 'block search term' ),
- _x( 'Connected', 'block search term' ),
- ],
-
- 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/extensions/blocks/related-posts/style.scss b/extensions/blocks/related-posts/style.scss
deleted file mode 100644
index 8008c57aad8dc..0000000000000
--- a/extensions/blocks/related-posts/style.scss
+++ /dev/null
@@ -1,87 +0,0 @@
-// @TODO: Replace with Gutenberg variables
-
-.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/extensions/blocks/repeat-visitor/components/edit.js b/extensions/blocks/repeat-visitor/components/edit.js
deleted file mode 100644
index 2ad72b4e00930..0000000000000
--- a/extensions/blocks/repeat-visitor/components/edit.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * External dependencies
- */
-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 { sprintf } from '@wordpress/i18n';
-import { __, _n } from '../../../utils/i18n';
-import { CRITERIA_AFTER, CRITERIA_BEFORE } from '../constants';
-import { icon } from '../index';
-
-const RADIO_OPTIONS = [
- {
- value: CRITERIA_AFTER,
- label: __( 'Show after threshold' ),
- },
- {
- value: CRITERIA_BEFORE,
- label: __( 'Show before threshold' ),
- },
-];
-
-class RepeatVisitorEdit extends Component {
- componentDidMount() {
- this.props.setAttributes( { isThresholdValid: true } );
- }
-
- setCriteria = criteria => this.props.setAttributes( { criteria } );
- setThreshold = threshold => {
- if ( /^\d+$/.test( threshold ) && +threshold > 0 ) {
- this.props.setAttributes( { threshold, isThresholdValid: true } );
- return;
- }
- this.props.setAttributes( { 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 at least once.',
- 'This block will only appear to people who have visited this page at least %d times.',
- +this.props.attributes.threshold
- ),
- this.props.attributes.threshold
- );
- }
-
- return sprintf(
- _n(
- 'This block will only appear to people who have never visited this page before.',
- 'This block will only appear to people who have visited this page less than %d times.',
- +this.props.attributes.threshold
- ),
- this.props.attributes.threshold
- );
- }
-
- render() {
- return (
-
-
-
-
-
-
-
-
- { this.getNoticeLabel() }
-
-
-
- );
- }
-}
-
-export default withSelect( ( select, ownProps ) => {
- const { isBlockSelected, hasSelectedInnerBlock } = select( 'core/editor' );
- return {
- isSelected: isBlockSelected( ownProps.clientId ) || hasSelectedInnerBlock( ownProps.clientId ),
- };
-} )( RepeatVisitorEdit );
diff --git a/extensions/blocks/repeat-visitor/components/save.js b/extensions/blocks/repeat-visitor/components/save.js
deleted file mode 100644
index 7484c06d9e5f9..0000000000000
--- a/extensions/blocks/repeat-visitor/components/save.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * External dependencies
- */
-import { InnerBlocks } from '@wordpress/editor';
-
-export default ( { className } ) => {
- return (
-
-
-
- );
-};
diff --git a/extensions/blocks/repeat-visitor/constants.js b/extensions/blocks/repeat-visitor/constants.js
deleted file mode 100644
index 09f459d2947d7..0000000000000
--- a/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/extensions/blocks/repeat-visitor/editor.js b/extensions/blocks/repeat-visitor/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/repeat-visitor/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/repeat-visitor/editor.scss b/extensions/blocks/repeat-visitor/editor.scss
deleted file mode 100644
index 72b90c39d3d3c..0000000000000
--- a/extensions/blocks/repeat-visitor/editor.scss
+++ /dev/null
@@ -1,54 +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: $muriel-hot-red-500;
- }
-}
-
-.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/extensions/blocks/repeat-visitor/index.js b/extensions/blocks/repeat-visitor/index.js
deleted file mode 100644
index 52246fa2a5b60..0000000000000
--- a/extensions/blocks/repeat-visitor/index.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * External dependencies
- */
-import { Path } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __, _x } from '../../utils/i18n';
-import renderMaterialIcon from '../../utils/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(
-
-);
-export const settings = {
- attributes: {
- criteria: {
- type: 'string',
- default: CRITERIA_AFTER,
- },
- threshold: {
- type: 'number',
- default: DEFAULT_THRESHOLD,
- },
- isThresholdValid: {
- type: 'boolean',
- default: true,
- },
- },
- category: 'jetpack',
- description: __( 'Control block visibility based on how often a visitor has viewed the page.' ),
- icon,
- keywords: [
- _x( 'traffic', 'block search term' ),
- _x( 'visitors', 'block search term' ),
- _x( 'visibility', 'block search term' ),
- ],
- supports: { html: false },
- title: __( 'Repeat Visitor' ),
- edit,
- save,
-};
diff --git a/extensions/blocks/repeat-visitor/view.js b/extensions/blocks/repeat-visitor/view.js
deleted file mode 100644
index 0273932ca04e1..0000000000000
--- a/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/extensions/blocks/seo/editor.js b/extensions/blocks/seo/editor.js
deleted file mode 100644
index e2811b0c0d125..0000000000000
--- a/extensions/blocks/seo/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../utils/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/extensions/blocks/seo/editor.scss b/extensions/blocks/seo/editor.scss
deleted file mode 100644
index ea00e7faf8f50..0000000000000
--- a/extensions/blocks/seo/editor.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-// @TODO: Replace with Gutenberg variables
-$light-gray-300: #edeff0;
-
-.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/extensions/blocks/seo/index.js b/extensions/blocks/seo/index.js
deleted file mode 100644
index 12747d5d79b17..0000000000000
--- a/extensions/blocks/seo/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * External dependencies
- */
-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';
-import { __ } from '../../utils/i18n';
-
-export const name = 'seo';
-
-export const settings = {
- render: () => (
-
-
-
-
-
-
-
- { __( 'SEO Description' ) }
-
- }
- >
-
-
-
- ),
-};
diff --git a/extensions/blocks/seo/panel.js b/extensions/blocks/seo/panel.js
deleted file mode 100644
index 7c408791910d7..0000000000000
--- a/extensions/blocks/seo/panel.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import { get } from 'lodash';
-import { sprintf } from '@wordpress/i18n';
-import { withDispatch, withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import { __, _n } from '../../utils/i18n';
-
-class SeoPanel extends Component {
- onMessageChange = event => {
- this.props.updateSeoDescription( event.target.value );
- };
-
- render() {
- const { seoDescription } = this.props;
-
- return (
-
-
-
- { sprintf(
- _n( '%d character', '%d characters', seoDescription.length ),
- seoDescription.length
- ) }
-
-
- );
- }
-}
-
-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/extensions/blocks/shortlinks/editor.js b/extensions/blocks/shortlinks/editor.js
deleted file mode 100644
index e2811b0c0d125..0000000000000
--- a/extensions/blocks/shortlinks/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import { name, settings } from '.';
-import registerJetpackPlugin from '../../utils/register-jetpack-plugin';
-
-registerJetpackPlugin( name, settings );
diff --git a/extensions/blocks/shortlinks/index.js b/extensions/blocks/shortlinks/index.js
deleted file mode 100644
index 11effa9ccf114..0000000000000
--- a/extensions/blocks/shortlinks/index.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-import { get } from 'lodash';
-import { PanelBody } from '@wordpress/components';
-import { withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import ClipboardInput from '../../utils/clipboard-input';
-import JetpackPluginSidebar from '../../shared/jetpack-plugin-sidebar';
-import { __ } from '../../utils/i18n';
-
-export const name = 'shortlinks';
-
-export const settings = {
- render: () => ,
-};
-
-class ShortlinksPanel extends Component {
- render() {
- const { shortlink } = this.props;
-
- if ( ! shortlink ) {
- return null;
- }
-
- return (
-
-
-
-
-
- );
- }
-}
-
-const Shortlinks = withSelect( select => {
- const currentPost = select( 'core/editor' ).getCurrentPost();
- return {
- shortlink: get( currentPost, 'jetpack_shortlink', '' ),
- };
-} )( ShortlinksPanel );
diff --git a/extensions/blocks/simple-payments/constants.js b/extensions/blocks/simple-payments/constants.js
deleted file mode 100644
index e593f9476210a..0000000000000
--- a/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/extensions/blocks/simple-payments/edit.js b/extensions/blocks/simple-payments/edit.js
deleted file mode 100644
index 9f71c6e1a1a12..0000000000000
--- a/extensions/blocks/simple-payments/edit.js
+++ /dev/null
@@ -1,578 +0,0 @@
-/**
- * External dependencies
- */
-import classNames from 'classnames';
-import emailValidator from 'email-validator';
-import { Component } from '@wordpress/element';
-import { compose, withInstanceId } from '@wordpress/compose';
-import { dispatch, withSelect } from '@wordpress/data';
-import { get, isEqual, pick, trimEnd } from 'lodash';
-import { sprintf } from '@wordpress/i18n';
-import {
- Disabled,
- ExternalLink,
- SelectControl,
- TextareaControl,
- TextControl,
- ToggleControl,
-} from '@wordpress/components';
-import { getCurrencyDefaults } from '@automattic/format-currency';
-
-/**
- * Internal dependencies
- */
-import HelpMessage from './help-message';
-import ProductPlaceholder from './product-placeholder';
-import FeaturedMedia from './featured-media';
-import { __, _n } from '../../utils/i18n';
-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.
- */
- if ( ! this.shouldInjectPaymentAttributes ) {
- return;
- }
-
- const { attributes, setAttributes, simplePayment } = this.props;
- const {
- content,
- currency,
- email,
- featuredMediaId,
- multiple,
- price,
- productId,
- title,
- } = attributes;
-
- if ( productId && simplePayment ) {
- 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.' ), email )
- : null,
- fieldPriceError: apiErrorKey === 'spay_price' ? __( 'Invalid price.' ) : 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.' ),
- } );
- return false;
- }
-
- if ( Number.isNaN( parseFloat( price ) ) ) {
- this.setState( {
- fieldPriceError: __( 'Invalid price' ),
- } );
- return false;
- }
-
- if ( parseFloat( price ) < 0 ) {
- this.setState( {
- fieldPriceError: __(
- 'Your price is negative — enter a positive number so people can pay the right amount.'
- ),
- } );
- 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.'
- ),
- } );
- 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
- ),
- 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.'
- ),
- } );
- return false;
- }
-
- if ( ! emailValidator.validate( email ) ) {
- this.setState( {
- fieldEmailError: sprintf( __( '%s is not a valid email address.' ), 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.'
- ),
- } );
- 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 && ! simplePayment;
-
- if ( ! isSelected && isDisabled ) {
- return (
-
- );
- }
-
- if (
- ! isSelected &&
- email &&
- price &&
- title &&
- ! fieldEmailError &&
- ! fieldPriceError &&
- ! fieldTitleError
- ) {
- return (
-
- );
- }
-
- const Wrapper = isDisabled ? Disabled : 'div';
-
- return (
-
-
-
-
-
- { fieldTitleError }
-
-
-
-
-
-
-
-
- { fieldPriceError }
-
-
-
-
-
-
-
-
-
- { fieldEmailError }
-
-
- { __(
- 'Enter the email address associated with your PayPal account. Don’t have an account?'
- ) + ' ' }
-
- { __( 'Create one on PayPal' ) }
-
-
-
-
- );
- }
-}
-
-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/extensions/blocks/simple-payments/editor.js b/extensions/blocks/simple-payments/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/simple-payments/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/simple-payments/editor.scss b/extensions/blocks/simple-payments/editor.scss
deleted file mode 100644
index 76d6fd9d065fb..0000000000000
--- a/extensions/blocks/simple-payments/editor.scss
+++ /dev/null
@@ -1,62 +0,0 @@
-
-.wp-block-jetpack-simple-payments {
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell,
- Helvetica Neue, sans-serif;
- 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/extensions/blocks/simple-payments/featured-media.js b/extensions/blocks/simple-payments/featured-media.js
deleted file mode 100644
index 4737b85100047..0000000000000
--- a/extensions/blocks/simple-payments/featured-media.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * External dependencies
- */
-import { Fragment } from '@wordpress/element';
-import { IconButton, Toolbar, ToolbarButton } from '@wordpress/components';
-import { BlockControls, MediaPlaceholder, MediaUpload } from '@wordpress/editor';
-import { get } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-
-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 (
-
- );
- }
-
- return (
-
-
-
-
- (
-
- ) }
- />
-
- setAttributes( {
- featuredMediaId: null,
- featuredMediaUrl: null,
- featuredMediaTitle: null,
- } )
- }
- />
-
-
-
-
-
-
-
- );
-};
diff --git a/extensions/blocks/simple-payments/help-message.js b/extensions/blocks/simple-payments/help-message.js
deleted file mode 100644
index 57a6e6819ebb1..0000000000000
--- a/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 && (
-
- { isError && }
- { children }
-
- )
- );
-};
diff --git a/extensions/blocks/simple-payments/help-message.scss b/extensions/blocks/simple-payments/help-message.scss
deleted file mode 100644
index 86f50f9e3b9b7..0000000000000
--- a/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/extensions/blocks/simple-payments/index.js b/extensions/blocks/simple-payments/index.js
deleted file mode 100644
index 223c20c823e19..0000000000000
--- a/extensions/blocks/simple-payments/index.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * External dependencies
- */
-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';
-import { __, _x } from '../../utils/i18n';
-
-/**
- * Styles
- */
-import './editor.scss';
-
-export const name = 'simple-payments';
-
-export const settings = {
- title: __( 'Simple Payments button' ),
-
- description: (
-
-
- { __(
- 'Lets you create and embed credit and debit card payment buttons with minimal setup.'
- ) }
-
-
- { __( 'Support reference' ) }
-
-
- ),
-
- icon: (
-
-
-
-
- ),
-
- category: 'jetpack',
-
- keywords: [ _x( 'shop', 'block search term' ), _x( 'sell', 'block search term' ), '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,
- reusable: false,
- },
-};
diff --git a/extensions/blocks/simple-payments/paypal-button-2x.png b/extensions/blocks/simple-payments/paypal-button-2x.png
deleted file mode 100644
index ceea141d3ae93..0000000000000
Binary files a/extensions/blocks/simple-payments/paypal-button-2x.png and /dev/null differ
diff --git a/extensions/blocks/simple-payments/paypal-button.png b/extensions/blocks/simple-payments/paypal-button.png
deleted file mode 100644
index 13bbad02e25fa..0000000000000
Binary files a/extensions/blocks/simple-payments/paypal-button.png and /dev/null differ
diff --git a/extensions/blocks/simple-payments/product-placeholder.js b/extensions/blocks/simple-payments/product-placeholder.js
deleted file mode 100644
index c8f82870ed03e..0000000000000
--- a/extensions/blocks/simple-payments/product-placeholder.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '../../utils/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,
-} ) => (
-
-
- { featuredMediaUrl && (
-
-
-
-
-
- ) }
-
- { title && (
-
- ) }
- { content && (
-
- ) }
- { formattedPrice && (
-
- ) }
-
- { multiple && (
-
-
-
- ) }
-
-
-
-
-
-
-
-);
diff --git a/extensions/blocks/simple-payments/product-placeholder.scss b/extensions/blocks/simple-payments/product-placeholder.scss
deleted file mode 100644
index ca99e1e0b3aee..0000000000000
--- a/extensions/blocks/simple-payments/product-placeholder.scss
+++ /dev/null
@@ -1,92 +0,0 @@
-
-.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: 1.5em;
-}
-
-/* Higher specificity in order to reset paragraph style */
-body .jetpack-simple-payments-wrapper .jetpack-simple-payments-details p {
- margin: 0 0 1.5em;
- padding: 0;
-}
-
-.jetpack-simple-payments-product {
- display: flex;
- flex-direction: column;
-}
-
-.jetpack-simple-payments-product-image {
- flex: 0 0 30%;
- margin-bottom: 1.5em;
-}
-
-.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/extensions/blocks/simple-payments/save.js b/extensions/blocks/simple-payments/save.js
deleted file mode 100644
index ed81e7a8f1b6d..0000000000000
--- a/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 ? { `[simple-payment id="${ productId }"]` } : null;
-}
diff --git a/extensions/blocks/simple-payments/utils.js b/extensions/blocks/simple-payments/utils.js
deleted file mode 100644
index c29e367baad3e..0000000000000
--- a/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/extensions/blocks/slideshow/create-swiper.js b/extensions/blocks/slideshow/create-swiper.js
deleted file mode 100644
index 72a54f56a93fe..0000000000000
--- a/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/extensions/blocks/slideshow/edit.js b/extensions/blocks/slideshow/edit.js
deleted file mode 100644
index 0934cb7b5cfcc..0000000000000
--- a/extensions/blocks/slideshow/edit.js
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * External dependencies
- */
-import { __, _x } from '../../utils/i18n';
-import { isBlobURL } from '@wordpress/blob';
-import { compose } from '@wordpress/compose';
-import { withDispatch } from '@wordpress/data';
-import { Component, Fragment } from '@wordpress/element';
-import {
- BlockControls,
- MediaUpload,
- MediaPlaceholder,
- InspectorControls,
- mediaUpload,
-} from '@wordpress/editor';
-
-import {
- DropZone,
- FormFileUpload,
- IconButton,
- PanelBody,
- RangeControl,
- SelectControl,
- ToggleControl,
- Toolbar,
- withNotices,
-} from '@wordpress/components';
-import { filter, pick } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import Slideshow from './slideshow';
-import './editor.scss';
-
-const ALLOWED_MEDIA_TYPES = [ 'image' ];
-
-const effectOptions = [
- { label: _x( 'Slide', 'Slideshow transition effect' ), value: 'slide' },
- { label: _x( 'Fade', 'Slideshow transition effect' ), value: 'fade' },
-];
-
-export const pickRelevantMediaFiles = image =>
- pick( image, [ 'alt', 'id', 'link', 'url', 'caption' ] );
-
-class SlideshowEdit extends Component {
- constructor() {
- super( ...arguments );
- this.state = {
- selectedImage: null,
- };
- }
- onSelectImages = images => {
- const { setAttributes } = this.props;
- const mapped = images.map( image => pickRelevantMediaFiles( image ) );
- setAttributes( {
- images: mapped,
- } );
- };
- onRemoveImage = index => {
- return () => {
- const images = filter( this.props.attributes.images, ( img, i ) => index !== i );
- this.setState( { selectedImage: null } );
- this.props.setAttributes( { images } );
- };
- };
- addFiles = files => {
- const currentImages = this.props.attributes.images || [];
- const { lockPostSaving, unlockPostSaving, noticeOperations, setAttributes } = this.props;
- const lockName = 'slideshowBlockLock';
- lockPostSaving( lockName );
- mediaUpload( {
- allowedTypes: ALLOWED_MEDIA_TYPES,
- filesList: files,
- onFileChange: images => {
- const imagesNormalized = images.map( image => pickRelevantMediaFiles( image ) );
- 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 = (
-
-
-
- {
- setAttributes( { autoplay: value } );
- } }
- />
- { autoplay && (
- {
- setAttributes( { delay: value } );
- } }
- min={ 1 }
- max={ 5 }
- />
- ) }
- { autoplay && prefersReducedMotion && (
-
- { __(
- 'The Reduce Motion accessibility option is selected, therefore autoplay will be disabled in this browser.'
- ) }
-
- ) }
-
-
- {
- setAttributes( { effect: value } );
- } }
- options={ effectOptions }
- />
-
-
-
- { !! images.length && (
-
- img.id ) }
- render={ ( { open } ) => (
-
- ) }
- />
-
- ) }
-
-
- );
-
- if ( images.length === 0 ) {
- return (
-
- { controls }
-
-
- );
- }
- return (
-
- { controls }
- { noticeUI }
-
-
- { isSelected && (
-
-
- { __( 'Upload an image' ) }
-
-
- ) }
-
- );
- }
-}
-export default compose(
- withDispatch( dispatch => {
- const { lockPostSaving, unlockPostSaving } = dispatch( 'core/editor' );
- return {
- lockPostSaving,
- unlockPostSaving,
- };
- } ),
- withNotices
-)( SlideshowEdit );
diff --git a/extensions/blocks/slideshow/editor.js b/extensions/blocks/slideshow/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/slideshow/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/slideshow/editor.scss b/extensions/blocks/slideshow/editor.scss
deleted file mode 100644
index b04e53eec9655..0000000000000
--- a/extensions/blocks/slideshow/editor.scss
+++ /dev/null
@@ -1,43 +0,0 @@
-.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 #555d66;
- }
- }
-
-}
-
-.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/extensions/blocks/slideshow/index.js b/extensions/blocks/slideshow/index.js
deleted file mode 100644
index 1844a9e5f07fb..0000000000000
--- a/extensions/blocks/slideshow/index.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, SVG } from '@wordpress/components';
-import { __ } from '../../utils/i18n';
-
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import transforms from './transforms';
-
-const icon = (
-
-
-
-
-);
-
-const attributes = {
- align: {
- default: 'center',
- type: 'string',
- },
- autoplay: {
- type: 'boolean',
- default: false,
- },
- delay: {
- type: 'number',
- default: 3,
- },
- 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' ),
- category: 'jetpack',
- keywords: [ __( 'image' ), __( 'gallery' ), __( 'slider' ) ],
- description: __( 'Add an interactive slideshow.' ),
- attributes,
- supports: {
- align: [ 'center', 'wide', 'full' ],
- html: false,
- },
- icon,
- edit,
- save,
- transforms,
-};
diff --git a/extensions/blocks/slideshow/save.js b/extensions/blocks/slideshow/save.js
deleted file mode 100644
index 59879ded67abd..0000000000000
--- a/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 } ) => (
-
-);
diff --git a/extensions/blocks/slideshow/slideshow.js b/extensions/blocks/slideshow/slideshow.js
deleted file mode 100644
index 9d395df75c5c0..0000000000000
--- a/extensions/blocks/slideshow/slideshow.js
+++ /dev/null
@@ -1,228 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '../../utils/i18n';
-import ResizeObserver from 'resize-observer-polyfill';
-import classnames from 'classnames';
-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.' ) );
- } );
- }
-
- 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
- ) {
- const realIndex =
- images.length === prevProps.images.length
- ? this.swiperInstance.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.' ) );
- } );
- }
- }
-
- 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 (
-
-
-
- { images.map( ( { alt, caption, id, url } ) => (
-
-
-
- { isBlobURL( url ) && }
- { caption && (
-
- ) }
-
-
- ) ) }
-
-
-
-
-
-
-
- );
- /* 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/extensions/blocks/slideshow/slideshow.php b/extensions/blocks/slideshow/slideshow.php
index 4f53ef8f10b32..3004594137290 100644
--- a/extensions/blocks/slideshow/slideshow.php
+++ b/extensions/blocks/slideshow/slideshow.php
@@ -25,7 +25,6 @@
function jetpack_slideshow_block_load_assets( $attr, $content ) {
$dependencies = array(
'lodash',
- 'wp-escape-html',
'wp-polyfill',
);
diff --git a/extensions/blocks/slideshow/style.scss b/extensions/blocks/slideshow/style.scss
deleted file mode 100644
index 701658fbb9ba1..0000000000000
--- a/extensions/blocks/slideshow/style.scss
+++ /dev/null
@@ -1,162 +0,0 @@
-.wp-block-jetpack-slideshow {
- margin-bottom: 1.5em;
- 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 #fff;
- 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: #fff;
- 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/extensions/blocks/slideshow/swiper-callbacks.js b/extensions/blocks/slideshow/swiper-callbacks.js
deleted file mode 100644
index 6765f3b2270e7..0000000000000
--- a/extensions/blocks/slideshow/swiper-callbacks.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * External dependencies
- */
-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/extensions/blocks/slideshow/transforms.js b/extensions/blocks/slideshow/transforms.js
deleted file mode 100644
index f0fba8cb1335e..0000000000000
--- a/extensions/blocks/slideshow/transforms.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * External dependencies
- */
-import { createBlock } from '@wordpress/blocks';
-import { filter } from 'lodash';
-
-const transforms = {
- from: [
- {
- type: 'block',
- blocks: [ 'core/gallery', 'jetpack/tiled-gallery' ],
- transform: attributes => {
- const validImages = filter( attributes.images, ( { id, url } ) => id && url );
- if ( validImages.length > 0 ) {
- return createBlock( 'jetpack/slideshow', {
- images: validImages.map( ( { id, url, alt, caption } ) => ( {
- id,
- url,
- alt,
- caption,
- } ) ),
- } );
- }
- return createBlock( 'jetpack/slideshow' );
- },
- },
- ],
- to: [
- {
- type: 'block',
- blocks: [ 'core/gallery' ],
- transform: ( { images } ) => createBlock( 'core/gallery', { images } ),
- },
- {
- type: 'block',
- blocks: [ 'jetpack/tiled-gallery' ],
- transform: ( { images } ) => createBlock( 'jetpack/tiled-gallery', { images }, [] ),
- },
- {
- 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/extensions/blocks/slideshow/view.js b/extensions/blocks/slideshow/view.js
deleted file mode 100644
index 6d8078972525f..0000000000000
--- a/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/extensions/blocks/subscriptions/edit.js b/extensions/blocks/subscriptions/edit.js
deleted file mode 100644
index 787a49a1d411e..0000000000000
--- a/extensions/blocks/subscriptions/edit.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-import { TextControl, ToggleControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-import SubmitButton from '../../utils/submit-button';
-import apiFetch from '@wordpress/api-fetch';
-import { sprintf, _n } from '@wordpress/i18n';
-
-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 (
-
- {
- setAttributes( { showSubscribersTotal: ! showSubscribersTotal } );
- } }
- />
- {} }
- />
-
-
- );
- }
-
- return (
-
- { showSubscribersTotal &&
{ this.state.subscriberCountString }
}
-
-
-
-
- );
- }
-
- get_subscriber_count() {
- apiFetch( { path: '/wpcom/v2/subscribers/count' } ).then( count => {
- // Handle error condition
- if ( ! count.hasOwnProperty( 'count' ) ) {
- this.setState( {
- subscriberCountString: __( 'Subscriber count unavailable' ),
- } );
- } else {
- this.setState( {
- subscriberCountString: sprintf(
- _n( 'Join %s other subscriber', 'Join %s other subscribers', count.count ),
- count.count
- ),
- } );
- }
- } );
- }
-
- onChangeSubmit( submitButtonText ) {
- this.props.setAttributes( { submitButtonText } );
- }
-}
-
-export default SubscriptionEdit;
diff --git a/extensions/blocks/subscriptions/editor.js b/extensions/blocks/subscriptions/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/subscriptions/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/subscriptions/index.js b/extensions/blocks/subscriptions/index.js
deleted file mode 100644
index fbd27697d5756..0000000000000
--- a/extensions/blocks/subscriptions/index.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Internal dependencies
- */
-import edit from './edit';
-import save from './save';
-import { __ } from '../../utils/i18n';
-import renderMaterialIcon from '../../utils/render-material-icon';
-import { Path } from '@wordpress/components';
-import { isEmpty } from 'lodash';
-import { RawHTML } from '@wordpress/element';
-
-export const name = 'subscriptions';
-export const settings = {
- title: __( 'Subscription Form' ),
-
- description: (
-
- { __(
- 'A form enabling readers to get notifications when new posts are published from this site.'
- ) }
-
- ),
- icon: renderMaterialIcon(
-
- ),
- category: 'jetpack',
-
- keywords: [ __( 'subscribe' ), __( 'join' ), __( 'follow' ) ],
-
- attributes: {
- subscribePlaceholder: { type: 'string', default: __( 'Email Address' ) },
- subscribeButton: { type: 'string', default: __( 'Subscribe' ) },
- showSubscribersTotal: { type: 'boolean', default: false },
- submitButtonText: {
- type: 'string',
- default: __( 'Subscribe' ),
- },
- customBackgroundButtonColor: { type: 'string' },
- customTextButtonColor: { type: 'string' },
- submitButtonClasses: { type: 'string' },
- },
- edit,
- save,
- deprecated: [
- {
- attributes: {
- subscribeButton: { type: 'string', default: __( 'Subscribe' ) },
- 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 (
- { `[jetpack_subscription_form show_subscribers_total="${
- attributes.showSubscribersTotal
- }" show_only_email_and_button="true"]` }
- );
- },
- },
- ],
-};
diff --git a/extensions/blocks/subscriptions/save.js b/extensions/blocks/subscriptions/save.js
deleted file mode 100644
index a7db7fe6288a8..0000000000000
--- a/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 (
- { `[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 }" ]` }
- );
-}
diff --git a/extensions/blocks/tiled-gallery/constants.js b/extensions/blocks/tiled-gallery/constants.js
deleted file mode 100644
index 0df9073729066..0000000000000
--- a/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/extensions/blocks/tiled-gallery/css-gram.scss b/extensions/blocks/tiled-gallery/css-gram.scss
deleted file mode 100644
index 9fd2f49c52aa1..0000000000000
--- a/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/extensions/blocks/tiled-gallery/deprecated/v1/constants.js b/extensions/blocks/tiled-gallery/deprecated/v1/constants.js
deleted file mode 100644
index 55a451fccf618..0000000000000
--- a/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/extensions/blocks/tiled-gallery/deprecated/v1/image.js b/extensions/blocks/tiled-gallery/deprecated/v1/image.js
deleted file mode 100644
index 61d4a2cd05cef..0000000000000
--- a/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 = (
-
- );
-
- return (
- { href ? { img } : img }
- );
-}
diff --git a/extensions/blocks/tiled-gallery/deprecated/v1/index.js b/extensions/blocks/tiled-gallery/deprecated/v1/index.js
deleted file mode 100644
index 69539d007cdef..0000000000000
--- a/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/extensions/blocks/tiled-gallery/deprecated/v1/layout/column.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/column.js
deleted file mode 100644
index a3ed5cdf04cbb..0000000000000
--- a/extensions/blocks/tiled-gallery/deprecated/v1/layout/column.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Column( { children } ) {
- return { children }
;
-}
diff --git a/extensions/blocks/tiled-gallery/deprecated/v1/layout/gallery.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/gallery.js
deleted file mode 100644
index 94fc61e4be980..0000000000000
--- a/extensions/blocks/tiled-gallery/deprecated/v1/layout/gallery.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function Gallery( { children, galleryRef } ) {
- return (
-
- { children }
-
- );
-}
diff --git a/extensions/blocks/tiled-gallery/deprecated/v1/layout/index.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/index.js
deleted file mode 100644
index 0ae3f744860b0..0000000000000
--- a/extensions/blocks/tiled-gallery/deprecated/v1/layout/index.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * External dependencies
- */
-import photon from 'photon';
-import { Component } from '@wordpress/element';
-import { format as formatUrl, parse as parseUrl } from 'url';
-import { isBlobURL } from '@wordpress/blob';
-import { sprintf } from '@wordpress/i18n';
-
-/**
- * Internal dependencies
- */
-import Image from '../image';
-import Mosaic from './mosaic';
-import Square from './square';
-import { __ } from '../../../../../utils/i18n';
-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' ), i + 1, images.length );
- return (
-
- );
- }
-
- 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 (
-
-
- { children }
-
- );
- }
-}
-
-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/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/index.js
deleted file mode 100644
index 8c56b1641dd1e..0000000000000
--- a/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 (
-
- { rows.map( ( row, rowIndex ) => (
-
- { row.map( ( colSize, colIndex ) => {
- const columnImages = renderedImages.slice( cursor, cursor + colSize );
- cursor += colSize;
- return { columnImages } ;
- } ) }
-
- ) ) }
-
- );
- }
-}
diff --git a/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/ratios.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/ratios.js
deleted file mode 100644
index 8accd552b710a..0000000000000
--- a/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.} ratios Ratios of images put into shape
- * @param {number} columnCount Number of columns
- *
- * @return {Array.>} 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/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/resize.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/mosaic/resize.js
deleted file mode 100644
index 022729c8bac72..0000000000000
--- a/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} parts Array of numbers to fit
- * @param {number} target Number that sum should match
- * @return {Array} 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 element
- Array.from( col.children ).forEach( ( item, i ) => {
- const height = adjustedHeights[ i ];
- item.setAttribute( 'style', `height:${ height }px;width:${ width }px;` );
- } );
-}
diff --git a/extensions/blocks/tiled-gallery/deprecated/v1/layout/row.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/row.js
deleted file mode 100644
index 200a58c2e3acf..0000000000000
--- a/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 { children }
;
-}
diff --git a/extensions/blocks/tiled-gallery/deprecated/v1/layout/square.js b/extensions/blocks/tiled-gallery/deprecated/v1/layout/square.js
deleted file mode 100644
index 2a1ab888b1916..0000000000000
--- a/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 (
-
- { [
- ...( remainder ? [ take( renderedImages, remainder ) ] : [] ),
- ...chunk( drop( renderedImages, remainder ), columnCount ),
- ].map( ( imagesInRow, rowIndex ) => (
-
- { imagesInRow.map( ( image, colIndex ) => (
- { image }
- ) ) }
-
- ) ) }
-
- );
-}
diff --git a/extensions/blocks/tiled-gallery/deprecated/v1/save.js b/extensions/blocks/tiled-gallery/deprecated/v1/save.js
deleted file mode 100644
index 1a5b0b66eff79..0000000000000
--- a/extensions/blocks/tiled-gallery/deprecated/v1/save.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Internal dependencies
- */
-import Layout from './layout';
-import { getActiveStyleName } from '../../../../utils';
-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 (
-
- );
-}
diff --git a/extensions/blocks/tiled-gallery/edit.js b/extensions/blocks/tiled-gallery/edit.js
deleted file mode 100644
index 17524c6d20235..0000000000000
--- a/extensions/blocks/tiled-gallery/edit.js
+++ /dev/null
@@ -1,293 +0,0 @@
-/**
- * External Dependencies
- */
-import { Component, Fragment } from '@wordpress/element';
-import { filter, get, pick } from 'lodash';
-import {
- BlockControls,
- 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 { __ } from '../../utils/i18n';
-import { ALLOWED_MEDIA_TYPES, LAYOUT_STYLES, MAX_COLUMNS } from './constants';
-import { getActiveStyleName } from '../../utils';
-import { icon } from '.';
-
-const linkOptions = [
- { value: 'attachment', label: __( 'Attachment Page' ) },
- { value: 'media', label: __( 'Media File' ) },
- { value: 'none', label: __( 'None' ) },
-];
-
-// @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' ],
- /* @TODO Captions disabled [ 'caption' ], */
- ] );
- 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 = ;
-
- const controls = (
-
- { !! images.length && (
-
-
- img.id ) }
- render={ ( { open } ) => (
-
- ) }
- />
-
- {
- setAttributes( { imageFilter: value } );
- this.setState( { selectedImage: null } );
- } }
- />
-
- ) }
-
- );
-
- if ( images.length === 0 ) {
- return (
-
- { controls }
- { icon } }
- className={ className }
- labels={ {
- title: __( 'Tiled Gallery' ),
- name: __( 'images' ),
- } }
- onSelect={ this.onSelectImages }
- accept="image/*"
- allowedTypes={ ALLOWED_MEDIA_TYPES }
- multiple
- notices={ noticeUI }
- onError={ noticeOperations.createErrorNotice }
- />
-
- );
- }
-
- const layoutStyle = getActiveStyleName( LAYOUT_STYLES, attributes.className );
-
- return (
-
- { controls }
-
-
- { layoutSupportsColumns( layoutStyle ) && images.length > 1 && (
-
- ) }
-
-
-
-
- { noticeUI }
-
-
- { dropZone }
- { isSelected && (
-
-
- { __( 'Upload an image' ) }
-
-
- ) }
-
-
- );
- }
-}
-
-export default withNotices( TiledGalleryEdit );
diff --git a/extensions/blocks/tiled-gallery/editor.js b/extensions/blocks/tiled-gallery/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/tiled-gallery/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/tiled-gallery/editor.scss b/extensions/blocks/tiled-gallery/editor.scss
deleted file mode 100644
index 4d7c9f5597dd7..0000000000000
--- a/extensions/blocks/tiled-gallery/editor.scss
+++ /dev/null
@@ -1,183 +0,0 @@
-@import './view.scss';
-@import './variables.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;
-
- .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 img {
- opacity: 0.3;
- }
-
- /* @TODO Caption has been commented out */
- // .editor-rich-text {
- // position: absolute;
- // bottom: 0;
- // width: 100%;
- // max-height: 100%;
- // overflow-y: auto;
- // }
-
- // .editor-rich-text figcaption:not( [data-is-placeholder-visible='true'] ) {
- // position: relative;
- // overflow: hidden;
- // color: var( --color-white );
- // }
-
- // &.is-selected .editor-rich-text {
- // // IE calculates this incorrectly, so leave it to modern browsers.
- // @supports ( position: sticky ) {
- // right: 0;
- // left: 0;
- // margin-top: -4px;
- // }
-
- // // Override negative margins so this toolbar isn't hidden by overflow. Overflow is needed for long captions.
- // .editor-rich-text__inline-toolbar {
- // top: 0;
- // }
-
- // // Make extra space for the inline toolbar.
- // .editor-rich-text__tinymce {
- // padding-top: 48px;
- // }
- // }
- }
-
- // Circle layout doesn't support captions
- // @TODO handle this in the component
- /* @TODO Caption has been commented out */
- // &.is-style-circle .tiled-gallery__item .editor-rich-text {
- // display: none;
- // }
-
- .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: $tiled-gallery-add-item-border-width solid $tiled-gallery-add-item-border-color;
- }
- }
- }
-
- .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%;
- transform: translate( -50%, -50% );
- }
-
- // Hide captions and upload buttons in style picker preview
- .editor-block-preview__content & {
- /* @TODO Caption has been commented out */
- // figcaption,
- .editor-media-placeholder {
- display: none;
- }
- }
-
- // Matches with `.dashicon` in `MediaPlaceholder` component
- .tiled-gallery__media-placeholder-icon {
- height: 20px;
- margin-right: 1ch; // stylelint-disable-line unit-whitelist
- width: 20px;
- }
-}
-
-.tiled-gallery__filter-picker-menu {
- $active-item-outline-width: 2px;
-
- // @TODO replace with Gutenberg variables
- $dark-gray-500: #555d66;
- $dark-gray-900: #191e23;
-
- 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/extensions/blocks/tiled-gallery/filter-toolbar.js b/extensions/blocks/tiled-gallery/filter-toolbar.js
deleted file mode 100644
index 7938cf997e8fd..0000000000000
--- a/extensions/blocks/tiled-gallery/filter-toolbar.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * External Dependencies
- */
-import { Dropdown, MenuItem, NavigableMenu, Path, SVG, Toolbar } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __, _x } from '../../utils/i18n';
-
-const availableFilters = [
- {
- icon: (
- /* No filter */
-
-
-
-
- ),
- title: _x( 'Original', 'image style' ),
- value: undefined,
- },
- {
- icon: (
- /* 1 */
-
-
-
-
- ),
- title: _x( 'Black and White', 'image style' ),
- value: 'black-and-white',
- },
- {
- icon: (
- /* 2 */
-
-
-
-
- ),
- title: _x( 'Sepia', 'image style' ),
- value: 'sepia',
- },
- {
- icon: (
- /* 3 */
-
-
-
-
- ),
- title: '1977',
- value: '1977',
- },
- {
- icon: (
- /* 4 */
-
-
-
-
- ),
- title: _x( 'Clarendon', 'image style' ),
- value: 'clarendon',
- },
- {
- icon: (
- /* 5 */
-
-
-
-
- ),
- title: _x( 'Gingham', 'image style' ),
- value: 'gingham',
- },
-];
-
-const label = __( 'Pick an image filter' );
-
-export default function FilterToolbar( { value, onChange } ) {
- return (
- {
- return (
-
-
-
-
- ),
- },
- ] }
- />
- );
- } }
- renderContent={ ( { onClose } ) => {
- const applyOrUnset = nextValue => () => {
- onChange( value === nextValue ? undefined : nextValue );
- onClose();
- };
- return (
-
- { availableFilters.map( ( { icon, title, value: filterValue } ) => (
-
- { title }
-
- ) ) }
-
- );
- } }
- />
- );
-}
diff --git a/extensions/blocks/tiled-gallery/gallery-image/edit.js b/extensions/blocks/tiled-gallery/gallery-image/edit.js
deleted file mode 100644
index 2aa86544dd9e2..0000000000000
--- a/extensions/blocks/tiled-gallery/gallery-image/edit.js
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * External Dependencies
- */
-import classnames from 'classnames';
-import { BACKSPACE, DELETE } from '@wordpress/keycodes';
-import { Component, createRef, Fragment } from '@wordpress/element';
-import { IconButton, Spinner } from '@wordpress/components';
-import { isBlobURL } from '@wordpress/blob';
-/* @TODO Caption has been commented out */
-// import { RichText } from '@wordpress/editor';
-import { withSelect } from '@wordpress/data';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../../utils/i18n';
-
-class GalleryImageEdit extends Component {
- img = createRef();
-
- /* @TODO Caption has been commented out */
- // state = {
- // captionSelected: false,
- // };
-
- // onSelectCaption = () => {
- // if ( ! this.state.captionSelected ) {
- // this.setState( {
- // captionSelected: true,
- // } );
- // }
-
- // if ( ! this.props.isSelected ) {
- // this.props.onSelect();
- // }
- // };
-
- onImageClick = () => {
- if ( ! this.props.isSelected ) {
- this.props.onSelect();
- }
-
- // if ( this.state.captionSelected ) {
- // this.setState( {
- // captionSelected: false,
- // } );
- // }
- };
-
- onImageKeyDown = event => {
- if (
- this.img.current === document.activeElement &&
- this.props.isSelected &&
- [ BACKSPACE, DELETE ].includes( event.keyCode )
- ) {
- this.props.onRemove();
- }
- };
-
- /* @TODO Caption has been commented out */
- // static getDerivedStateFromProps( props, state ) {
- // // unselect the caption so when the user selects other image and comeback
- // // the caption is not immediately selected
- // if ( ! props.isSelected && state.captionSelected ) {
- // return { captionSelected: false };
- // }
- // return null;
- // }
-
- 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,
- // caption,
- height,
- id,
- imageFilter,
- isSelected,
- link,
- linkTo,
- onRemove,
- origUrl,
- // setAttributes,
- url,
- width,
- } = this.props;
-
- let href;
-
- switch ( linkTo ) {
- case 'media':
- href = url;
- break;
- case 'attachment':
- href = link;
- break;
- }
-
- 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 */
-
-
- { isBlobURL( origUrl ) && }
-
- /* 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 (
-
- { isSelected && (
-
-
-
- ) }
- { /* Keep the HTML structure, but ensure there is no navigation from edit */
- /* eslint-disable-next-line jsx-a11y/anchor-is-valid */ }
- { href ? { img } : img }
- { /* ( ! RichText.isEmpty( caption ) || isSelected ) && (
- setAttributes( { caption: newCaption } ) }
- unstableOnFocus={ this.onSelectCaption }
- inlineToolbar
- />
- ) */ }
-
- );
- }
-}
-
-export default withSelect( ( select, ownProps ) => {
- const { getMedia } = select( 'core' );
- const { id } = ownProps;
-
- return {
- image: id ? getMedia( id ) : null,
- };
-} )( GalleryImageEdit );
diff --git a/extensions/blocks/tiled-gallery/gallery-image/save.js b/extensions/blocks/tiled-gallery/gallery-image/save.js
deleted file mode 100644
index ac57133da7229..0000000000000
--- a/extensions/blocks/tiled-gallery/gallery-image/save.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * External Dependencies
- */
-import classnames from 'classnames';
-import { isBlobURL } from '@wordpress/blob';
-
-/* @TODO Caption has been commented out */
-// import { RichText } from '@wordpress/editor';
-
-export default function GalleryImageSave( props ) {
- const {
- alt,
- // caption,
- 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 = (
-
- );
-
- return (
-
- { href ? { img } : img }
- { /* ! RichText.isEmpty( caption ) && (
-
- ) */ }
-
- );
-}
diff --git a/extensions/blocks/tiled-gallery/index.js b/extensions/blocks/tiled-gallery/index.js
deleted file mode 100644
index 2a6d979a57019..0000000000000
--- a/extensions/blocks/tiled-gallery/index.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * External dependencies
- */
-import { createBlock } from '@wordpress/blocks';
-import { filter } from 'lodash';
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __, _x } from '../../utils/i18n';
-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' ),
- [ LAYOUT_CIRCLE ]: _x( 'Circles', 'Tiled gallery layout' ),
- [ LAYOUT_COLUMN ]: _x( 'Tiled columns', 'Tiled gallery layout' ),
- [ LAYOUT_SQUARE ]: _x( 'Square tiles', 'Tiled gallery layout' ),
-};
-const layoutStylesWithLabels = LAYOUT_STYLES.map( style => ( {
- ...style,
- label: styleNames[ style.name ],
-} ) );
-
-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',
- },
- 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 name = 'tiled-gallery';
-
-export const icon = (
-
-
-
-);
-
-export const settings = {
- attributes: blockAttributes,
- category: 'jetpack',
- description: __( 'Display multiple images in an elegantly organized tiled layout.' ),
- icon,
- keywords: [
- _x( 'images', 'block search term' ),
- _x( 'photos', 'block search term' ),
- _x( 'masonry', 'block search term' ),
- ],
- styles: layoutStylesWithLabels,
- supports: {
- align: [ 'center', 'wide', 'full' ],
- customClassName: false,
- html: false,
- },
- title: __( 'Tiled Gallery' ),
- transforms: {
- from: [
- {
- type: 'block',
- blocks: [ 'core/gallery' ],
- transform: attributes => {
- const validImages = filter( attributes.images, ( { id, url } ) => id && url );
- if ( validImages.length > 0 ) {
- return createBlock( `jetpack/${ name }`, {
- images: validImages.map( ( { id, url, alt, caption } ) => ( {
- id,
- url,
- alt,
- caption,
- } ) ),
- } );
- }
- return createBlock( `jetpack/${ name }` );
- },
- },
- ],
- to: [
- {
- type: 'block',
- blocks: [ 'core/gallery' ],
- transform: ( { images, columns, linkTo } ) =>
- createBlock( 'core/gallery', { images, columns, imageCrop: true, linkTo } ),
- },
- {
- 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' );
- },
- },
- ],
- },
- edit,
- save,
- deprecated: [ deprecatedV1 ],
-};
diff --git a/extensions/blocks/tiled-gallery/layout/column.js b/extensions/blocks/tiled-gallery/layout/column.js
deleted file mode 100644
index a3ed5cdf04cbb..0000000000000
--- a/extensions/blocks/tiled-gallery/layout/column.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function Column( { children } ) {
- return { children }
;
-}
diff --git a/extensions/blocks/tiled-gallery/layout/gallery.js b/extensions/blocks/tiled-gallery/layout/gallery.js
deleted file mode 100644
index 94fc61e4be980..0000000000000
--- a/extensions/blocks/tiled-gallery/layout/gallery.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function Gallery( { children, galleryRef } ) {
- return (
-
- { children }
-
- );
-}
diff --git a/extensions/blocks/tiled-gallery/layout/index.js b/extensions/blocks/tiled-gallery/layout/index.js
deleted file mode 100644
index e375ffe3063b9..0000000000000
--- a/extensions/blocks/tiled-gallery/layout/index.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * External dependencies
- */
-import photon from 'photon';
-import { Component } from '@wordpress/element';
-import { format as formatUrl, parse as parseUrl } from 'url';
-import { isBlobURL } from '@wordpress/blob';
-import { sprintf } from '@wordpress/i18n';
-
-/**
- * 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';
-import { __ } from '../../../utils/i18n';
-
-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' ), i + 1, images.length );
- const Image = isSave ? GalleryImageSave : GalleryImageEdit;
-
- return (
-
- );
- }
-
- 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 (
-
-
- { children }
-
- );
- }
-}
-
-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/extensions/blocks/tiled-gallery/layout/mosaic/index.js b/extensions/blocks/tiled-gallery/layout/mosaic/index.js
deleted file mode 100644
index 8c56b1641dd1e..0000000000000
--- a/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 (
-
- { rows.map( ( row, rowIndex ) => (
-
- { row.map( ( colSize, colIndex ) => {
- const columnImages = renderedImages.slice( cursor, cursor + colSize );
- cursor += colSize;
- return { columnImages } ;
- } ) }
-
- ) ) }
-
- );
- }
-}
diff --git a/extensions/blocks/tiled-gallery/layout/mosaic/ratios.js b/extensions/blocks/tiled-gallery/layout/mosaic/ratios.js
deleted file mode 100644
index 8accd552b710a..0000000000000
--- a/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.} ratios Ratios of images put into shape
- * @param {number} columnCount Number of columns
- *
- * @return {Array.>} 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/extensions/blocks/tiled-gallery/layout/mosaic/resize.js b/extensions/blocks/tiled-gallery/layout/mosaic/resize.js
deleted file mode 100644
index 022729c8bac72..0000000000000
--- a/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} parts Array of numbers to fit
- * @param {number} target Number that sum should match
- * @return {Array} 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 element
- Array.from( col.children ).forEach( ( item, i ) => {
- const height = adjustedHeights[ i ];
- item.setAttribute( 'style', `height:${ height }px;width:${ width }px;` );
- } );
-}
diff --git a/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/index.js.snap b/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/index.js.snap
deleted file mode 100644
index e726fa521fa5b..0000000000000
--- a/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`] = `
-
-
-
- 0
-
-
-
-
- 1
-
-
-
-
- 2
-
-
- 3
-
-
- 4
-
-
- 5
-
-
-
-
- 6
-
-
- 7
-
-
-
-
- 8
-
-
- 9
- 10
-
-
-
-
- 11
- 12
-
-
- 13
-
-
-
-`;
diff --git a/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/ratios.js.snap b/extensions/blocks/tiled-gallery/layout/mosaic/test/__snapshots__/ratios.js.snap
deleted file mode 100644
index df02118c594b9..0000000000000
--- a/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/extensions/blocks/tiled-gallery/layout/mosaic/test/fixtures/ratios.js b/extensions/blocks/tiled-gallery/layout/mosaic/test/fixtures/ratios.js
deleted file mode 100644
index 77db288c5b0f8..0000000000000
--- a/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/extensions/blocks/tiled-gallery/layout/mosaic/test/index.js b/extensions/blocks/tiled-gallery/layout/mosaic/test/index.js
deleted file mode 100644
index 57e991d23b463..0000000000000
--- a/extensions/blocks/tiled-gallery/layout/mosaic/test/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * External dependencies
- */
-import Adapter from 'enzyme-adapter-react-16';
-import Enzyme, { shallow } from 'enzyme';
-import React from 'react';
-import { createSerializer } from 'enzyme-to-json';
-import { range } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import Mosaic from '..';
-import * as imageSets from '../../test/fixtures/image-sets';
-
-Enzyme.configure( { adapter: new Adapter() } );
-expect.addSnapshotSerializer( createSerializer( { mode: 'deep' } ) );
-
-test( 'renders as expected', () => {
- Object.keys( imageSets ).forEach( k => {
- const images = imageSets[ k ];
- expect(
- shallow( )
- ).toMatchSnapshot();
- } );
-} );
diff --git a/extensions/blocks/tiled-gallery/layout/mosaic/test/ratios.js b/extensions/blocks/tiled-gallery/layout/mosaic/test/ratios.js
deleted file mode 100644
index 3756b971e03ce..0000000000000
--- a/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/extensions/blocks/tiled-gallery/layout/row.js b/extensions/blocks/tiled-gallery/layout/row.js
deleted file mode 100644
index 200a58c2e3acf..0000000000000
--- a/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 { children }
;
-}
diff --git a/extensions/blocks/tiled-gallery/layout/square.js b/extensions/blocks/tiled-gallery/layout/square.js
deleted file mode 100644
index 2a1ab888b1916..0000000000000
--- a/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 (
-
- { [
- ...( remainder ? [ take( renderedImages, remainder ) ] : [] ),
- ...chunk( drop( renderedImages, remainder ), columnCount ),
- ].map( ( imagesInRow, rowIndex ) => (
-
- { imagesInRow.map( ( image, colIndex ) => (
- { image }
- ) ) }
-
- ) ) }
-
- );
-}
diff --git a/extensions/blocks/tiled-gallery/layout/test/fixtures/image-sets.js b/extensions/blocks/tiled-gallery/layout/test/fixtures/image-sets.js
deleted file mode 100644
index 07c6bef746a9a..0000000000000
--- a/extensions/blocks/tiled-gallery/layout/test/fixtures/image-sets.js
+++ /dev/null
@@ -1,117 +0,0 @@
-export const imageSet1 = [
- {
- alt: '',
- id: 163,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/architecture-bay-bridge-356830.jpg',
- height: 2048,
- width: 8192,
- },
- {
- alt: '',
- id: 162,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/bloom-blossom-flora-40797-1.jpg',
- height: 1562,
- width: 3531,
- },
- {
- alt: '',
- id: 161,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/architecture-building-city-597049.jpg',
- height: 4221,
- width: 2818,
- },
- {
- alt: '',
- id: 160,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/architecture-art-blue-699466.jpg',
- height: 4032,
- width: 3024,
- },
- {
- alt: '',
- id: 159,
- caption: '',
- url:
- 'https://example.files.wordpress.com/2018/12/black-and-white-construction-ladder-54335.jpg',
- height: 3193,
- width: 2377,
- },
- {
- alt: '',
- id: 158,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/architecture-buildings-city-1672110.jpg',
- height: 6000,
- width: 4000,
- },
- {
- alt: '',
- id: 157,
- caption: '',
- url:
- 'https://example.files.wordpress.com/2018/12/architectural-design-architecture-black-and-white-1672122-1.jpg',
- height: 3401,
- width: 2721,
- },
- {
- alt: '',
- id: 156,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/grass-hd-wallpaper-lake-127753.jpg',
- height: 2198,
- width: 7999,
- },
- {
- alt: '',
- id: 122,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/texaco-car-1.jpg',
- height: 599,
- width: 800,
- },
- {
- alt: '',
- id: 92,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/43824553435_ea38cbc92a_m.jpg',
- height: 159,
- width: 240,
- },
- {
- alt: '',
- id: 90,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/42924685680_7b5632e58e_m.jpg',
- height: 150,
- width: 240,
- },
- {
- alt: '',
- id: 89,
- caption: '',
- url:
- 'https://example.files.wordpress.com/2018/12/31962299833_1e106f7f7a_z-1-e1545262352979.jpg',
- height: 427,
- width: 564,
- },
- {
- alt: '',
- id: 88,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/12/29797558147_3c72afa8f4_k.jpg',
- height: 1511,
- width: 2048,
- },
- {
- alt: '',
- id: 8,
- caption: '',
- url: 'https://example.files.wordpress.com/2018/11/person-smartphone-office-table.jpeg',
- height: 1067,
- width: 1600,
- },
-];
diff --git a/extensions/blocks/tiled-gallery/save.js b/extensions/blocks/tiled-gallery/save.js
deleted file mode 100644
index 8d69444ff5309..0000000000000
--- a/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 '../../utils';
-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 (
-
- );
-}
diff --git a/extensions/blocks/tiled-gallery/variables.scss b/extensions/blocks/tiled-gallery/variables.scss
deleted file mode 100644
index 6472bae167b0b..0000000000000
--- a/extensions/blocks/tiled-gallery/variables.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-$tiled-gallery-add-item-border-color: #555d66; // Gutenberg $dark-gray-500
-$tiled-gallery-add-item-border-width: 1px; // Gutenberg $border-width
-$tiled-gallery-caption-background-color: #000;
-$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/extensions/blocks/tiled-gallery/view.js b/extensions/blocks/tiled-gallery/view.js
deleted file mode 100644
index 1f45b13ddc347..0000000000000
--- a/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} 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/extensions/blocks/tiled-gallery/view.scss b/extensions/blocks/tiled-gallery/view.scss
deleted file mode 100644
index d7e475c5d6244..0000000000000
--- a/extensions/blocks/tiled-gallery/view.scss
+++ /dev/null
@@ -1,135 +0,0 @@
-@import './variables.scss';
-@import './css-gram.scss';
-
-$tiled-gallery-max-column-count: 20;
-
-.wp-block-jetpack-tiled-gallery {
- margin: 0 auto 1.5em;
-
- &.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%;
- }
-
- /* @TODO Caption has been commented out */
- // figcaption {
- // position: absolute;
- // bottom: 0;
- // width: 100%;
- // max-height: 100%;
- // overflow: auto;
- // padding: 40px 10px 5px;
- // color: var( --color-white );
- // text-align: center;
- // font-size: $root-font-size;
- // // stylelint-disable function-parentheses-space-inside
- // background: linear-gradient(
- // 0deg,
- // rgba( $color: $tiled-gallery-caption-background-color, $alpha: 0.7 ) 0,
- // rgba( $color: $tiled-gallery-caption-background-color, $alpha: 0.3 ) 60%,
- // transparent
- // );
- // // stylelint-enable function-parentheses-space-inside
- // }
-}
diff --git a/extensions/blocks/videopress/edit.js b/extensions/blocks/videopress/edit.js
deleted file mode 100644
index ab3e487a99e1d..0000000000000
--- a/extensions/blocks/videopress/edit.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * External dependencies
- */
-import apiFetch from '@wordpress/api-fetch';
-import { isBlobURL } from '@wordpress/blob';
-import { compose, createHigherOrderComponent } from '@wordpress/compose';
-import { withSelect } from '@wordpress/data';
-import { Disabled, IconButton, SandBox, Toolbar } from '@wordpress/components';
-import { BlockControls, RichText } from '@wordpress/editor';
-import { Component, createRef, Fragment } from '@wordpress/element';
-import classnames from 'classnames';
-import { get } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-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 ;
- }
-
- if ( isFetchingMedia || isFetchingPreview ) {
- return ;
- }
-
- if ( fallback || ! preview ) {
- return ;
- }
-
- const { html, scripts } = preview;
- const { caption } = attributes;
-
- return (
-
-
-
-
-
-
-
- { /*
- Disable the video player so the user clicking on it won't play the
- video when the controls are enabled.
- */ }
-
-
-
-
-
- { ( ! RichText.isEmpty( caption ) || isSelected ) && (
- setAttributes( { caption: value } ) }
- inlineToolbar
- />
- ) }
-
-
- );
- }
- };
-
-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/extensions/blocks/videopress/editor.js b/extensions/blocks/videopress/editor.js
deleted file mode 100644
index c8d2e87d82cf1..0000000000000
--- a/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 '../../utils/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/extensions/blocks/videopress/index.js b/extensions/blocks/videopress/index.js
deleted file mode 100644
index 60d3531f4ddc5..0000000000000
--- a/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/extensions/blocks/videopress/loading.js b/extensions/blocks/videopress/loading.js
deleted file mode 100644
index 76c25d4cf06a8..0000000000000
--- a/extensions/blocks/videopress/loading.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * External dependencies
- */
-import { Spinner } from '@wordpress/components';
-
-const Loading = ( { text } ) => (
-
-);
-
-export default Loading;
diff --git a/extensions/blocks/videopress/save.js b/extensions/blocks/videopress/save.js
deleted file mode 100644
index 52790480769af..0000000000000
--- a/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( , { 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 (
-
-
- { `\n${ url }\n` /* URL needs to be on its own line. */ }
-
- { ! RichText.isEmpty( caption ) && (
-
- ) }
-
- );
-};
-
-export default createHigherOrderComponent( VideoPressSave, 'withVideoPressSave' );
diff --git a/extensions/blocks/vr/edit.js b/extensions/blocks/vr/edit.js
deleted file mode 100644
index 9ee1dc35219c3..0000000000000
--- a/extensions/blocks/vr/edit.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-import { Placeholder, SelectControl, TextControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import VRImageSave from './save';
-import { __ } from '../../utils/i18n';
-
-export default class VRImageEdit extends Component {
- onChangeUrl = value => void this.props.setAttributes( { url: value.trim() } );
- onChangeView = value => void this.props.setAttributes( { view: value } );
-
- render() {
- const { attributes, className } = this.props;
-
- if ( attributes.url && attributes.view ) {
- return ;
- }
-
- return (
-
-
-
-
- );
- }
-}
diff --git a/extensions/blocks/vr/editor.js b/extensions/blocks/vr/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/vr/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/vr/editor.scss b/extensions/blocks/vr/editor.scss
deleted file mode 100644
index 3f628c193b59c..0000000000000
--- a/extensions/blocks/vr/editor.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-
-.wp-block-jetpack-vr {
- position: relative;
- max-width: 525px;
- margin-left: auto;
- margin-right: auto;
- overflow: hidden;
-
- .components-placeholder__fieldset {
- justify-content: space-around;
- }
-}
diff --git a/extensions/blocks/vr/index.js b/extensions/blocks/vr/index.js
deleted file mode 100644
index 7e02cfe2fefbf..0000000000000
--- a/extensions/blocks/vr/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Internal dependencies
- */
-import './editor.scss';
-import VRImageEdit from './edit';
-import VRImageSave from './save';
-import { __ } from '../../utils/i18n';
-
-export const name = 'vr';
-
-export const settings = {
- title: __( 'VR Image' ),
- description: __( 'Embed 360° photos and Virtual Reality (VR) content' ),
- icon: 'embed-photo',
- category: 'jetpack',
- keywords: [ __( 'vr' ), __( 'panorama' ), __( '360' ) ],
- supports: {
- html: false,
- },
- attributes: {
- url: {
- type: 'string',
- },
- view: {
- type: 'string',
- },
- },
- edit: VRImageEdit,
- save: VRImageSave,
-};
diff --git a/extensions/blocks/vr/save.js b/extensions/blocks/vr/save.js
deleted file mode 100644
index ab341f798ed77..0000000000000
--- a/extensions/blocks/vr/save.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * External dependencies
- */
-import { addQueryArgs } from '@wordpress/url';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-
-export default ( { attributes: { url, view }, className } ) => (
-
-
-
-);
diff --git a/extensions/blocks/wordads/constants.js b/extensions/blocks/wordads/constants.js
deleted file mode 100644
index 1c56fd7d589f1..0000000000000
--- a/extensions/blocks/wordads/constants.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, SVG } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-
-export const DEFAULT_FORMAT = 'mrec';
-export const AD_FORMATS = [
- {
- height: 250,
- icon: (
-
-
-
-
- ),
- name: __( 'Rectangle 300x250' ),
- tag: DEFAULT_FORMAT,
- width: 300,
- editorPadding: 30,
- },
- {
- height: 90,
- icon: (
-
-
-
-
- ),
- name: __( 'Leaderboard 728x90' ),
- tag: 'leaderboard',
- width: 728,
- editorPadding: 40,
- },
- {
- height: 50,
- icon: (
-
-
-
-
- ),
- name: __( 'Mobile Leaderboard 320x50' ),
- tag: 'mobile_leaderboard',
- width: 320,
- editorPadding: 60,
- },
- {
- height: 600,
- icon: (
-
-
-
-
- ),
- name: __( 'Wide Skyscraper 160x600' ),
- tag: 'wideskyscraper',
- width: 160,
- editorPadding: 30,
- },
-];
diff --git a/extensions/blocks/wordads/edit.js b/extensions/blocks/wordads/edit.js
deleted file mode 100644
index 720588f25bb48..0000000000000
--- a/extensions/blocks/wordads/edit.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '../../utils/i18n';
-import { BlockControls } from '@wordpress/editor';
-import { Component, Fragment } from '@wordpress/element';
-import { Placeholder } 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 {
- render() {
- const { attributes, setAttributes } = this.props;
- const { format } = attributes;
- const selectedFormatObject = AD_FORMATS.filter( ( { tag } ) => tag === format )[ 0 ];
-
- return (
-
-
- setAttributes( { format: nextFormat } ) }
- />
-
-
-
-
{ __( 'Advertisements' ) }
-
-
{ __( 'Report this Ad' ) }
-
-
-
- );
- }
-}
-export default WordAdsEdit;
diff --git a/extensions/blocks/wordads/editor.js b/extensions/blocks/wordads/editor.js
deleted file mode 100644
index babee275335fe..0000000000000
--- a/extensions/blocks/wordads/editor.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Internal dependencies
- */
-import registerJetpackBlock from '../../utils/register-jetpack-block';
-import { name, settings } from '.';
-
-registerJetpackBlock( name, settings );
diff --git a/extensions/blocks/wordads/editor.scss b/extensions/blocks/wordads/editor.scss
deleted file mode 100644
index 5643383ec889f..0000000000000
--- a/extensions/blocks/wordads/editor.scss
+++ /dev/null
@@ -1,61 +0,0 @@
-.wp-block-jetpack-wordads {
- background: var( --color-white );
-}
-
-[data-type='jetpack/wordads'][data-align='center'] .jetpack-wordads__ad {
- margin: 0 auto;
-}
-
-.jetpack-wordads__header,
-.jetpack-wordads__footer {
- font-size: 10px;
- font-family: sans-serif;
-}
-
-.jetpack-wordads__header {
- text-align: left;
-}
-
-.jetpack-wordads__footer {
- text-transform: uppercase;
- text-align: right;
-}
-
-.jetpack-wordads__ad {
- display: flex;
- overflow: hidden;
- flex-direction: column;
- max-width: 100%;
-
- .components-placeholder {
- flex-grow: 2;
- }
-}
-
-.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;
-
- // @TODO replace with Gutenberg variables
- $dark-gray-500: #555d66;
- $dark-gray-900: #191e23;
-
- 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/extensions/blocks/wordads/format-picker.js b/extensions/blocks/wordads/format-picker.js
deleted file mode 100644
index 3f113f0e9c299..0000000000000
--- a/extensions/blocks/wordads/format-picker.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * External Dependencies
- */
-import { Dropdown, MenuItem, NavigableMenu, Path, SVG, Toolbar } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-import { AD_FORMATS } from './constants';
-
-const label = __( 'Pick an ad format' );
-
-export default function FormatPicker( { value, onChange } ) {
- return (
- {
- return (
-
-
-
-
- ),
- title: label,
- onClick: onToggle,
- extraProps: { 'aria-expanded': isOpen },
- className: 'wp-block-jetpack-wordads__format-picker-icon',
- },
- ] }
- />
- );
- } }
- renderContent={ ( { onClose } ) => (
-
- { AD_FORMATS.map( ( { tag, name, icon } ) => (
- {
- onChange( tag );
- onClose();
- } }
- role="menuitemcheckbox"
- >
- { name }
-
- ) ) }
-
- ) }
- />
- );
-}
diff --git a/extensions/blocks/wordads/index.js b/extensions/blocks/wordads/index.js
deleted file mode 100644
index c42d1bfb29506..0000000000000
--- a/extensions/blocks/wordads/index.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * External dependencies
- */
-import { ExternalLink, Path, SVG } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import { __ } from '../../utils/i18n';
-import edit from './edit';
-import { DEFAULT_FORMAT } from './constants';
-
-export const name = 'wordads';
-export const title = __( 'Ad' );
-
-export const icon = (
-
-
-
-
-);
-
-export const settings = {
- title,
-
- description: (
-
- { __( 'Earn income by adding high quality ads to your post' ) }
- { __( 'Learn all about WordAds' ) }
-
- ),
-
- icon,
- attributes: {
- align: {
- type: 'string',
- default: 'center',
- },
- format: {
- type: 'string',
- default: DEFAULT_FORMAT,
- },
- },
-
- category: 'jetpack',
-
- keywords: [ __( 'ads' ), 'WordAds', __( 'Advertisement' ) ],
-
- supports: {
- align: [ 'left', 'center', 'right' ],
- alignWide: false,
- className: false,
- customClassName: false,
- html: false,
- reusable: false,
- },
- edit,
- save: () => null,
-};
diff --git a/extensions/shared/README.md b/extensions/shared/README.md
deleted file mode 100644
index 25a49ce1ba42c..0000000000000
--- a/extensions/shared/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Jetpack Block Editor Extensions: Shared
-
-The shared directory is meant to contain components, scripts, and stylesheets that are used in multiple blocks.
diff --git a/extensions/shared/frontend-management.js b/extensions/shared/frontend-management.js
deleted file mode 100644
index dbb830e6e816e..0000000000000
--- a/extensions/shared/frontend-management.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * External dependencies
- */
-import { assign, kebabCase } from 'lodash';
-import { createElement, render } from '@wordpress/element';
-
-export class FrontendManagement {
- blockIterator( rootNode, blocks ) {
- blocks.forEach( block => {
- this.initializeFrontendReactBlocks( block.component, block.options, rootNode );
- } );
- }
- initializeFrontendReactBlocks( component, options = {}, rootNode ) {
- const { attributes, name, prefix } = options.settings;
- const { selector } = options;
- const fullName = prefix && prefix.length ? `${ prefix }/${ name }` : name;
- const blockClass = `.wp-block-${ fullName.replace( '/', '-' ) }`;
-
- const blockNodeList = rootNode.querySelectorAll( blockClass );
- for ( const node of blockNodeList ) {
- const data = this.extractAttributesFromContainer( node, attributes );
- assign( data, options.props );
- const children = this.extractChildrenFromContainer( node );
- const el = createElement( component, data, children );
- render( el, selector ? node.querySelector( selector ) : node );
- }
- }
- extractAttributesFromContainer( node, attributes ) {
- const data = {};
- for ( const name in attributes ) {
- const attribute = attributes[ name ];
- const dataAttributeName = 'data-' + kebabCase( name );
- data[ name ] = node.getAttribute( dataAttributeName );
- if ( attribute.type === 'boolean' ) {
- data[ name ] = data[ name ] === 'false' ? false : !! data[ name ];
- }
- if ( attribute.type === 'array' || attribute.type === 'object' ) {
- try {
- data[ name ] = JSON.parse( data[ name ] );
- } catch ( e ) {
- // console.log( 'Error decoding JSON data for field ' + name, e);
- data[ name ] = null;
- }
- }
- }
- return data;
- }
- extractChildrenFromContainer( node ) {
- const children = [ ...node.childNodes ];
- return children.map( child => {
- const attr = {};
- for ( let i = 0; i < child.attributes.length; i++ ) {
- const attribute = child.attributes[ i ];
- attr[ attribute.nodeName ] = attribute.nodeValue;
- }
- attr.dangerouslySetInnerHTML = {
- __html: child.innerHTML,
- };
- return createElement( child.tagName.toLowerCase(), attr );
- } );
- }
-}
-
-export default FrontendManagement;
diff --git a/extensions/shared/get-site-fragment.js b/extensions/shared/get-site-fragment.js
deleted file mode 100644
index 6d141e4e70ce7..0000000000000
--- a/extensions/shared/get-site-fragment.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * External dependencies
- */
-import { includes } from 'lodash';
-
-/**
- * Internal dependencies
- */
-// FIXME: REMOVE!
-import { getSiteFragment as getCalypsoSiteFragment } from '../../../../client/lib/route/path';
-
-/**
- * Returns the site fragment in the environment we're running Gutenberg in.
- *
- * @returns {?Number|String} Site fragment (ID or slug); null for WP.org wp-admin.
- */
-export default function getSiteFragment() {
- // WP.com wp-admin exposes the site ID in window._currentSiteId
- if ( window && window._currentSiteId ) {
- return window._currentSiteId;
- }
-
- // FIXME: REMOVE THIS BLOCK! vvv
- // Calypso will contain a site slug or ID in the site fragment.
- // WP.org will contain either `post` or `post-new.php`.
- const siteFragment = getCalypsoSiteFragment( window.location.pathname );
- if ( ! includes( [ 'post.php', 'post-new.php' ], siteFragment ) ) {
- return siteFragment || null;
- }
- // FIXME: REMOVE TO HERE ^^^
-
- // Gutenberg in Jetpack adds a site fragment in the initial state
- if (
- window &&
- window.Jetpack_Editor_Initial_State &&
- window.Jetpack_Editor_Initial_State.siteFragment
- ) {
- return window.Jetpack_Editor_Initial_State.siteFragment;
- }
-
- return null;
-}
diff --git a/extensions/shared/help-message.js b/extensions/shared/help-message.js
deleted file mode 100644
index 4c3b7eb78ab21..0000000000000
--- a/extensions/shared/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( 'help-message', {
- 'help-message-is-error': isError,
- } );
-
- return (
- children && (
-
- { isError && }
- { children }
-
- )
- );
-};
diff --git a/extensions/shared/help-message.scss b/extensions/shared/help-message.scss
deleted file mode 100644
index b8ea026fa4560..0000000000000
--- a/extensions/shared/help-message.scss
+++ /dev/null
@@ -1,21 +0,0 @@
-
-.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;
- }
- &.help-message-is-error {
- color: var( --color-error );
- svg {
- fill: var( --color-error );
- }
- }
-}
diff --git a/extensions/shared/jetpack-logo.js b/extensions/shared/jetpack-logo.js
deleted file mode 100644
index 0d13127b9689f..0000000000000
--- a/extensions/shared/jetpack-logo.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, Polygon, SVG } from '@wordpress/components';
-import classNames from 'classnames';
-
-export default ( { size = 24, className } ) => (
-
-
-
-
-
-);
diff --git a/extensions/shared/jetpack-plugin-sidebar.js b/extensions/shared/jetpack-plugin-sidebar.js
deleted file mode 100644
index b3cfd3d789a39..0000000000000
--- a/extensions/shared/jetpack-plugin-sidebar.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * External dependencies
- */
-import { createSlotFill } from '@wordpress/components';
-import { Fragment } from '@wordpress/element';
-import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/edit-post';
-import { registerPlugin } from '@wordpress/plugins';
-
-/**
- * Internal dependencies
- */
-import './jetpack-plugin-sidebar.scss';
-import JetpackLogo from './jetpack-logo';
-
-const { Fill, Slot } = createSlotFill( 'JetpackPluginSidebar' );
-
-const JetpackPluginSidebar = ( { children } ) => { children } ;
-
-JetpackPluginSidebar.Slot = () => (
-
- { fills => {
- if ( ! fills.length ) {
- return null;
- }
-
- return (
-
- }>
- Jetpack
-
- }>
- { fills }
-
-
- );
- } }
-
-);
-
-registerPlugin( 'jetpack-sidebar', {
- render: () => ,
-} );
-
-export default JetpackPluginSidebar;
diff --git a/extensions/shared/jetpack-plugin-sidebar.scss b/extensions/shared/jetpack-plugin-sidebar.scss
deleted file mode 100644
index 494cba0f8e582..0000000000000
--- a/extensions/shared/jetpack-plugin-sidebar.scss
+++ /dev/null
@@ -1,42 +0,0 @@
-.edit-post-pinned-plugins,
-.edit-post-more-menu__content {
- .components-icon-button {
- .jetpack-logo {
- width: 20px;
- height: 20px;
- }
- }
-}
-
-.edit-post-more-menu__content {
- .components-icon-button {
- .jetpack-logo {
- margin-right: 4px;
- }
- }
-}
-
-.edit-post-pinned-plugins {
- .components-icon-button {
- &:not( .is-toggled ),
- &:hover,
- &.is-toggled,
- &.is-toggled:hover {
- .jetpack-logo,
- .jetpack-logo__icon-circle,
- .jetpack-logo__icon-triangle {
- stroke: none !important;
- }
-
- .jetpack-logo__icon-circle {
- // CSS colour variables are not available in Gutenberg extensions when built by SDK
- fill: $green-jetpack !important;
- }
-
- .jetpack-logo__icon-triangle {
- // CSS colour variables are not available in Gutenberg extensions when built by SDK
- fill: var( --color-white ) !important;
- }
- }
- }
-}
diff --git a/extensions/shared/test/get-site-fragment.js b/extensions/shared/test/get-site-fragment.js
deleted file mode 100644
index ec51761bde343..0000000000000
--- a/extensions/shared/test/get-site-fragment.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Internal dependencies
- */
-import getSiteFragment from '../get-site-fragment';
-
-describe( 'getSiteFragment()', () => {
- let beforeWindow;
-
- beforeAll( () => {
- beforeWindow = global.window;
- global.window = {
- location: {},
- };
- } );
-
- afterAll( () => {
- global.window = beforeWindow;
- } );
-
- test( 'should return null by default', () => {
- window.location.pathname = '/';
- expect( getSiteFragment() ).toBeNull();
- } );
-
- test( 'should return null when editing a post in wp-admin', () => {
- window.location.pathname = '/wp-admin/post.php';
- expect( getSiteFragment() ).toBeNull();
- } );
-
- test( 'should return null when starting a new post in wp-admin', () => {
- window.location.pathname = '/wp-admin/post-new.php';
- expect( getSiteFragment() ).toBeNull();
- } );
-
- test( 'should return site fragment when starting a post in calypso', () => {
- window.location.pathname = '/block-editor/post/yourjetpack.blog';
- expect( getSiteFragment() ).toBe( 'yourjetpack.blog' );
- } );
-
- test( 'should return site fragment when editing a post in calypso', () => {
- window.location.pathname = '/block-editor/post/yourjetpack.blog/123';
- expect( getSiteFragment() ).toBe( 'yourjetpack.blog' );
- } );
-
- test( 'should return site ID when _currentSiteId is exposed', () => {
- window.location.pathname = '/block-editor/post/yourjetpack.blog/123';
- window._currentSiteId = 12345678;
- expect( getSiteFragment() ).toBe( 12345678 );
- } );
-
- test( 'should return site slug when editing a post in Gutenberg in WP-Admin', () => {
- delete window._currentSiteId;
- window.Jetpack_Editor_Initial_State = {
- siteFragment: 'yourjetpack.blog',
- };
- expect( getSiteFragment() ).toBe( 'yourjetpack.blog' );
- } );
-} );
diff --git a/extensions/utils/README.md b/extensions/utils/README.md
deleted file mode 100644
index 54faf077c1658..0000000000000
--- a/extensions/utils/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Jetpack Block Editor Extensions: Utils
-
-This folder contains files that are not automatically bundled,
-but included on an individual basis instead.
-
-## getJetpackData()
-
-Gets a list of available blocks, and jetpack's connection status.
-On a Jetpack site, there are special cases when a block is considered unavailable.
-For example, the site may not have the required module, they may not have the required plan,
-or the site admin may have filtered out the use of a certain block.
-
-## registerJetpackBlock()
-
-This util will only register a block if it meets the availability requirements described above.
-
-
-## registerJetpackPlugin()
-
-This util will only register a Gutenberg plugin if it meets the availability requirements described above.
diff --git a/extensions/utils/block-styles.js b/extensions/utils/block-styles.js
deleted file mode 100644
index 5a278356fc6d3..0000000000000
--- a/extensions/utils/block-styles.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * External dependencies
- */
-import TokenList from '@wordpress/token-list';
-import { find } from 'lodash';
-
-/**
- * Returns the active style from the given className.
- *
- * From @link https://github.com/WordPress/gutenberg/blob/ddac4f3cf8fd311169c7e125411343a437bdbb5a/packages/editor/src/components/block-styles/index.js#L20-L42
- *
- * @param {Array} styles Block style variations.
- * @param {string} className Class name
- *
- * @return {Object?} The active style.
- */
-function getActiveStyle( styles, className ) {
- for ( const style of new TokenList( className ).values() ) {
- if ( style.indexOf( 'is-style-' ) === -1 ) {
- continue;
- }
-
- const potentialStyleName = style.substring( 9 );
- const activeStyle = find( styles, { name: potentialStyleName } );
- if ( activeStyle ) {
- return activeStyle;
- }
- }
-
- return find( styles, 'isDefault' );
-}
-
-export function getActiveStyleName( styles, className ) {
- const style = getActiveStyle( styles, className );
- return style ? style.name : null;
-}
-
-export function getDefaultStyleClass( styles ) {
- const defaultStyle = find( styles, 'isDefault' );
- return defaultStyle ? `is-style-${ defaultStyle.name }` : null;
-}
-
-/**
- * Checks if className has a class selector starting with `is-style-`
- * Does not check validity of found style.
- *
- * @param {String} classNames Optional. Space separated classNames. Defaults to ''.
- * @return {Boolean} true if `classNames` has a Gutenberg style class
- */
-export function hasStyleClass( classNames = '' ) {
- return classNames.split( ' ' ).some( className => className.startsWith( 'is-style-' ) );
-}
diff --git a/extensions/utils/clipboard-input.js b/extensions/utils/clipboard-input.js
deleted file mode 100644
index 44250540f6c9a..0000000000000
--- a/extensions/utils/clipboard-input.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * External dependencies
- */
-import { Component } from '@wordpress/element';
-import { ClipboardButton, TextControl } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import { __, _x } from './i18n';
-import './clipboard-input.scss';
-
-class ClipboardInput extends Component {
- state = {
- hasCopied: false,
- };
-
- onCopy = () => this.setState( { hasCopied: true } );
-
- onFinishCopy = () => this.setState( { hasCopied: false } );
-
- onFocus = event => event.target.select();
-
- render() {
- const { link } = this.props;
- const { hasCopied } = this.state;
-
- if ( ! link ) {
- return null;
- }
-
- return (
-
-
-
- { hasCopied ? __( 'Copied!' ) : _x( 'Copy', 'verb' ) }
-
-
- );
- }
-}
-
-export default ClipboardInput;
diff --git a/extensions/utils/clipboard-input.scss b/extensions/utils/clipboard-input.scss
deleted file mode 100644
index d0118a3efc72c..0000000000000
--- a/extensions/utils/clipboard-input.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.jetpack-clipboard-input {
- display: flex;
-
- .components-clipboard-button {
- margin: 2px 0 0 6px;
- }
-}
diff --git a/extensions/utils/get-jetpack-data.js b/extensions/utils/get-jetpack-data.js
deleted file mode 100644
index 6871383a6dc0e..0000000000000
--- a/extensions/utils/get-jetpack-data.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * External Dependencies
- */
-import { get } from 'lodash';
-
-export const JETPACK_DATA_PATH = 'Jetpack_Editor_Initial_State';
-
-export default function getJetpackData() {
- return get( 'object' === typeof window ? window : null, [ JETPACK_DATA_PATH ], null );
-}
diff --git a/extensions/utils/get-jetpack-extension-availability.js b/extensions/utils/get-jetpack-extension-availability.js
deleted file mode 100644
index a3636f1c91289..0000000000000
--- a/extensions/utils/get-jetpack-extension-availability.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * External dependencies
- */
-import { get, includes } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import extensionSlugsJson from '../preset/index.json';
-import getJetpackData from './get-jetpack-data';
-
-/**
- * Return whether a Jetpack Gutenberg extension is available or not.
- *
- * Defaults to `false` for production blocks, and to `true` for beta blocks.
- * This is to make it easier for folks to write their first block without needing
- * to touch the server side.
- *
- * @param {string} name The extension's name (without the `jetpack/` prefix)
- * @returns {object} Object indicating if the extension is available (property `available`) and the reason why it is
- * unavailable (property `unavailable_reason`).
- */
-export default function getJetpackExtensionAvailability( name ) {
- const data = getJetpackData();
- const defaultAvailability = includes( extensionSlugsJson.beta, name );
- const available = get( data, [ 'available_blocks', name, 'available' ], defaultAvailability );
- const unavailableReason = get(
- data,
- [ 'available_blocks', name, 'unavailable_reason' ],
- 'unknown'
- );
-
- return {
- available,
- ...( ! available && { unavailableReason } ),
- };
-}
diff --git a/extensions/utils/i18n.js b/extensions/utils/i18n.js
deleted file mode 100644
index 0759252b02b17..0000000000000
--- a/extensions/utils/i18n.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * This contains a set of wrappers for all the @wordpress/i18n localization functions.
- * Each of the wrappers has the same signature like the original corresponding function,
- * but without the textdomain at the end.
- *
- * The wrappers are necessary because we'd like to reuse i18n-calypso provided translations
- * for our Gutenberg blocks, but we'd also like to not include i18n-calypso in block bundles.
- * Instead, we use @wordpress/i18n, but it requires a textdomain in order to know where
- * to look for the translations.
- *
- * In the same time, we use those blocks in Jetpack, and in order to be able to index the
- * translations there without issues, the localization function calls in the source code
- * must not contain a textdomain.
- */
-
-/**
- * External dependencies
- */
-import { __ as wpI18n__, _n as wpI18n_n, _x as wpI18n_x, _nx as wpI18n_nx } from '@wordpress/i18n';
-
-/**
- * Module variables
- */
-const TEXTDOMAIN = 'jetpack';
-
-/**
- * Add a textdomain to arguments of a localization function call.
- *
- * @param {Array} originalArgs Arguments that the localization function was called with.
- *
- * @return {Array} Arguments, with textdomain added as the last one.
- */
-const addTextdomain = originalArgs => {
- const args = [ ...originalArgs ];
- args.push( TEXTDOMAIN );
- return args;
-};
-
-/**
- * Retrieve the translation of text.
- *
- * @see https://developer.wordpress.org/reference/functions/__/
- *
- * @param {string} text Text to translate.
- * @param {?string} domain Domain to retrieve the translated text.
- *
- * @return {string} Translated text.
- */
-export function __() {
- return wpI18n__( ...addTextdomain( arguments ) );
-}
-
-/**
- * Translates and retrieves the singular or plural form based on the supplied
- * number.
- *
- * @see https://developer.wordpress.org/reference/functions/_n/
- *
- * @param {string} single The text to be used if the number is singular.
- * @param {string} plural The text to be used if the number is plural.
- * @param {number} number The number to compare against to use either the
- * singular or plural form.
- * @param {?string} domain Domain to retrieve the translated text.
- *
- * @return {string} The translated singular or plural form.
- */
-export function _n() {
- return wpI18n_n( ...addTextdomain( arguments ) );
-}
-
-/**
- * Retrieve translated string with gettext context.
- *
- * @see https://developer.wordpress.org/reference/functions/_x/
- *
- * @param {string} text Text to translate.
- * @param {string} context Context information for the translators.
- * @param {?string} domain Domain to retrieve the translated text.
- *
- * @return {string} Translated context string without pipe.
- */
-export function _x() {
- return wpI18n_x( ...addTextdomain( arguments ) );
-}
-
-/**
- * Translates and retrieves the singular or plural form based on the supplied
- * number, with gettext context.
- *
- * @see https://developer.wordpress.org/reference/functions/_nx/
- *
- * @param {string} single The text to be used if the number is singular.
- * @param {string} plural The text to be used if the number is plural.
- * @param {number} number The number to compare against to use either the
- * singular or plural form.
- * @param {string} context Context information for the translators.
- * @param {?string} domain Domain to retrieve the translated text.
- *
- * @return {string} The translated singular or plural form.
- */
-export function _nx() {
- return wpI18n_nx( ...addTextdomain( arguments ) );
-}
diff --git a/extensions/utils/index.js b/extensions/utils/index.js
deleted file mode 100644
index 13e2e308b4974..0000000000000
--- a/extensions/utils/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { getActiveStyleName, getDefaultStyleClass, hasStyleClass } from './block-styles';
diff --git a/extensions/utils/register-jetpack-block.js b/extensions/utils/register-jetpack-block.js
deleted file mode 100644
index be72fe373ab9e..0000000000000
--- a/extensions/utils/register-jetpack-block.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * External dependencies
- */
-import { registerBlockType } from '@wordpress/blocks';
-
-/**
- * Internal dependencies
- */
-import getJetpackExtensionAvailability from './get-jetpack-extension-availability';
-
-/**
- * Registers a gutenberg block if the availability requirements are met.
- *
- * @param {string} name The block's name.
- * @param {object} settings The block's settings.
- * @param {object} childBlocks The block's child blocks.
- * @returns {object|false} Either false if the block is not available, or the results of `registerBlockType`
- */
-export default function registerJetpackBlock( name, settings, childBlocks = [] ) {
- const { available, unavailableReason } = getJetpackExtensionAvailability( name );
- const unavailable = ! available;
-
- if ( unavailable ) {
- if ( 'production' !== process.env.NODE_ENV ) {
- // eslint-disable-next-line no-console
- console.warn(
- `Block ${ name } couldn't be registered because it is unavailable (${ unavailableReason }).`
- );
- }
- return false;
- }
-
- const result = registerBlockType( `jetpack/${ name }`, settings );
-
- // Register child blocks. Using `registerBlockType()` directly avoids availability checks -- if
- // their parent is available, we register them all, without checking for their individual availability.
- childBlocks.forEach( childBlock =>
- registerBlockType( `jetpack/${ childBlock.name }`, childBlock.settings )
- );
-
- return result;
-}
diff --git a/extensions/utils/register-jetpack-plugin.js b/extensions/utils/register-jetpack-plugin.js
deleted file mode 100644
index 8d891462b9ef5..0000000000000
--- a/extensions/utils/register-jetpack-plugin.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * External dependencies
- */
-import { registerPlugin } from '@wordpress/plugins';
-
-/**
- * Internal dependencies
- */
-import getJetpackExtensionAvailability from './get-jetpack-extension-availability';
-
-/**
- * Registers a Gutenberg block if the availability requirements are met.
- *
- * @param {string} name The plugin's name
- * @param {object} settings The plugin's settings.
- * @returns {object|false} Either false if the plugin is not available, or the results of `registerPlugin`
- */
-export default function registerJetpackPlugin( name, settings ) {
- const { available, unavailableReason } = getJetpackExtensionAvailability( name );
- const unavailable = ! available;
-
- if ( unavailable ) {
- if ( 'production' !== process.env.NODE_ENV ) {
- // eslint-disable-next-line no-console
- console.warn(
- `Plugin ${ name } couldn't be registered because it is unavailable (${ unavailableReason }).`
- );
- }
- return false;
- }
-
- return registerPlugin( `jetpack-${ name }`, settings );
-}
diff --git a/extensions/utils/render-material-icon.js b/extensions/utils/render-material-icon.js
deleted file mode 100644
index 82d245915631a..0000000000000
--- a/extensions/utils/render-material-icon.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * External dependencies
- */
-import { Path, SVG } from '@wordpress/components';
-
-const renderMaterialIcon = svg => (
-
-
- { svg }
-
-);
-
-export default renderMaterialIcon;
diff --git a/extensions/utils/simple-input.js b/extensions/utils/simple-input.js
deleted file mode 100644
index c55a5a6f6670b..0000000000000
--- a/extensions/utils/simple-input.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * External dependencies
- */
-import { PlainText } from '@wordpress/editor';
-
-const simpleInput = ( type, props, label, view, onChange ) => {
- const { isSelected } = props;
- const value = props.attributes[ type ];
- return (
-
- { ! isSelected && value !== '' && view( props ) }
- { ( isSelected || value === '' ) && (
-
- ) }
-
- );
-};
-
-export default simpleInput;
diff --git a/extensions/utils/submit-button.js b/extensions/utils/submit-button.js
deleted file mode 100644
index bc3d090328482..0000000000000
--- a/extensions/utils/submit-button.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import { Component, Fragment } from '@wordpress/element';
-import { compose } from '@wordpress/compose';
-import { withFallbackStyles } from '@wordpress/components';
-import {
- InspectorControls,
- PanelColorSettings,
- ContrastChecker,
- RichText,
- withColors,
-} from '@wordpress/editor';
-import { isEqual, get } from 'lodash';
-
-/**
- * Internal dependencies
- */
-import { __ } from './i18n';
-
-const { getComputedStyle } = window;
-
-const applyFallbackStyles = withFallbackStyles( ( node, ownProps ) => {
- const { textButtonColor, backgroundButtonColor } = ownProps;
- const backgroundColorValue = backgroundButtonColor && backgroundButtonColor.color;
- const textColorValue = textButtonColor && textButtonColor.color;
- //avoid the use of querySelector if textColor color is known and verify if node is available.
-
- let textNode;
- let button;
-
- if ( ! textColorValue && node ) {
- textNode = node.querySelector( '[contenteditable="true"]' );
- }
-
- if ( node.querySelector( '.wp-block-button__link' ) ) {
- button = node.querySelector( '.wp-block-button__link' );
- } else {
- button = node;
- }
-
- let fallbackBackgroundColor;
- let fallbackTextColor;
-
- if ( node ) {
- fallbackBackgroundColor = getComputedStyle( button ).backgroundColor;
- }
-
- if ( textNode ) {
- fallbackTextColor = getComputedStyle( textNode ).color;
- }
-
- return {
- fallbackBackgroundColor: backgroundColorValue || fallbackBackgroundColor,
- fallbackTextColor: textColorValue || fallbackTextColor,
- };
-} );
-
-class SubmitButton extends Component {
- componentDidUpdate( prevProps ) {
- if (
- ! isEqual( this.props.textButtonColor, prevProps.textButtonColor ) ||
- ! isEqual( this.props.backgroundButtonColor, prevProps.backgroundButtonColor )
- ) {
- const buttonClasses = this.getButtonClasses();
- this.props.setAttributes( { submitButtonClasses: buttonClasses } );
- }
- }
- getButtonClasses() {
- const { textButtonColor, backgroundButtonColor } = this.props;
- const textClass = get( textButtonColor, 'class' );
- const backgroundClass = get( backgroundButtonColor, 'class' );
- return classnames( 'wp-block-button__link', {
- 'has-text-color': textButtonColor,
- [ textClass ]: textClass,
- 'has-background': backgroundButtonColor,
- [ backgroundClass ]: backgroundClass,
- } );
- }
- render() {
- const {
- attributes,
- fallbackBackgroundColor,
- fallbackTextColor,
- setAttributes,
- setBackgroundButtonColor,
- setTextButtonColor,
- } = this.props;
-
- const backgroundColor = attributes.customBackgroundButtonColor || fallbackBackgroundColor;
- const color = attributes.customTextButtonColor || fallbackTextColor;
- const buttonStyle = { border: 'none', backgroundColor, color };
- const buttonClasses = this.getButtonClasses();
-
- return (
-
-
- setAttributes( { submitButtonText: nextValue } ) }
- className={ buttonClasses }
- style={ buttonStyle }
- keepPlaceholderOnFocus
- formattingControls={ [] }
- />
-
-
- {
- setBackgroundButtonColor( nextColour );
- setAttributes( { customBackgroundButtonColor: nextColour } );
- },
- label: __( 'Background Color' ),
- },
- {
- value: color,
- onChange: nextColour => {
- setTextButtonColor( nextColour );
- setAttributes( { customTextButtonColor: nextColour } );
- },
- label: __( 'Text Color' ),
- },
- ] }
- />
-
-
-
- );
- }
-}
-
-export default compose( [
- withColors( 'backgroundButtonColor', { textButtonColor: 'color' } ),
- applyFallbackStyles,
-] )( SubmitButton );
diff --git a/extensions/utils/text-match-replace.js b/extensions/utils/text-match-replace.js
deleted file mode 100644
index b339719f5e1b7..0000000000000
--- a/extensions/utils/text-match-replace.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * External dependencies
- */
-import { isRegExp, escapeRegExp, isString, flatten } from 'lodash';
-
-/**
- * Given a string, replace every substring that is matched by the `match` regex
- * with the result of calling `fn` on matched substring. The result will be an
- * array with all odd indexed elements containing the replacements. The primary
- * use case is similar to using String.prototype.replace except for React.
- *
- * React will happily render an array as children of a react element, which
- * makes this approach very useful for tasks like surrounding certain text
- * within a string with react elements.
- *
- * Example:
- * matchReplace(
- * 'Emphasize all phone numbers like 884-555-4443.',
- * /([\d|-]+)/g,
- * (number, i) => {number}
- * );
- * // => ['Emphasize all phone numbers like ', 884-555-4443 , '.'
- *
- * @param {string} text - The text that you want to replace
- * @param {regexp|str} match Must contain a matching group
- * @param {function} fn function that helps replace the matched text
- * @return {array} An array of string or react components
- */
-function replaceString( text, match, fn ) {
- let curCharStart = 0;
- let curCharLen = 0;
-
- if ( text === '' ) {
- return text;
- } else if ( ! text || ! isString( text ) ) {
- throw new TypeError( 'First argument must be a string' );
- }
-
- let re = match;
-
- if ( ! isRegExp( re ) ) {
- re = new RegExp( '(' + escapeRegExp( re ) + ')', 'gi' );
- }
-
- const result = text.split( re );
- // Apply fn to all odd elements
- for ( let i = 1, length = result.length; i < length; i += 2 ) {
- curCharLen = result[ i ].length;
- curCharStart += result[ i - 1 ].length;
- if ( result[ i ] ) {
- result[ i ] = fn( result[ i ], i, curCharStart );
- }
- curCharStart += curCharLen;
- }
-
- return result;
-}
-
-const textMatchReplace = ( source, match, fn ) => {
- if ( ! Array.isArray( source ) ) source = [ source ];
-
- return flatten(
- source.map( x => {
- return isString( x ) ? replaceString( x, match, fn ) : x;
- } )
- );
-};
-
-export default textMatchReplace;
diff --git a/tools/build-release-branch.sh b/tools/build-release-branch.sh
index 801a37e292c3a..b225559448fff 100755
--- a/tools/build-release-branch.sh
+++ b/tools/build-release-branch.sh
@@ -1,5 +1,4 @@
#!/bin/bash
-
# This script can build a new set of release branches, or update an existing release branch.
# It doesn't care which branch you're currently standing on.
#
@@ -17,68 +16,54 @@
# Exit the build in scary red text if error
function exit_build {
- echo -e "${RED}Something went wrong and the build has stopped. See error above for more details."
- exit 1
+ echo -e "${RED}Something went wrong and the build has stopped. See error above for more details."
+ exit 1
}
trap 'exit_build' ERR
# Instructions
function usage {
- echo "usage: $0 [-n new] [-u update ]"
- echo " -n Create new release branches"
- echo " -u Update existing release built branch"
- echo " Can take an extra param that refers to an existing branch."
- echo " Example: $0 -u master-stable"
- echo " -h help"
- exit 1
+ echo "usage: $0 [-n new] [-u update ]"
+ echo " -n Create new release branches"
+ echo " -u Update existing release built branch"
+ echo " Can take an extra param that refers to an existing branch."
+ echo " Example: $0 -u master-stable"
+ echo " -h help"
+ exit 1
}
# This creates a new .gitignore file based on master, but removes the items we need for release builds
function create_release_gitignore {
- # Copy .gitignore to temp file
- mv .gitignore .gitignore-tmp
-
- # Create empty .gitignore
- touch .gitignore
-
- # Add things to the new .gitignore file, stopping at the things we want to keep.
- while IFS='' read -r line || [[ -n "$line" ]]; do
- if [ "$line" == "## Things we will need in release branches" ]; then
- break
- fi
- echo "$line" >> .gitignore
- done < ".gitignore-tmp"
-
- # Add custom stuff to .gitignore release
- echo "/_inc/client" >> .gitignore
- echo "/docker/" >> .gitignore
-
- # Needs to stay in sync with .svnignore and `create_new_release_branches` in this file.
- echo "__snapshots__/" >> .gitignore
- echo "/extensions/**/*.css" >> .gitignore
- echo "/extensions/**/*.gif" >> .gitignore
- echo "/extensions/**/*.jpeg" >> .gitignore
- echo "/extensions/**/*.jpg" >> .gitignore
- echo "/extensions/**/*.js" >> .gitignore
- echo "/extensions/**/*.json" >> .gitignore
- echo "/extensions/**/*.jsx" >> .gitignore
- echo "/extensions/**/*.md" >> .gitignore
- echo "/extensions/**/*.png" >> .gitignore
- echo "/extensions/**/*.sass" >> .gitignore
- echo "/extensions/**/*.scss" >> .gitignore
- echo "/extensions/**/*.svg" >> .gitignore
-
- # Remove old .gitignore
- rm .gitignore-tmp
-
- git commit .gitignore -m "updated .gitignore"
+ # Copy .gitignore to temp file
+ mv .gitignore .gitignore-tmp
+
+ # Create empty .gitignore
+ touch .gitignore
+
+ # Add things to the new .gitignore file, stopping at the things we want to keep.
+ while IFS='' read -r line || [[ -n "$line" ]]
+ do
+ if [ "$line" == "## Things we will need in release branches" ]
+ then
+ break
+ fi
+ echo "$line" >> .gitignore
+ done < ".gitignore-tmp"
+
+ # Add custom stuff to .gitignore release
+ echo "/_inc/client" >> .gitignore
+
+ # Remove old .gitignore
+ rm .gitignore-tmp
+
+ git commit .gitignore -m "updated .gitignore"
}
# Remove stuff from .svnignore for releases
function modify_svnignore {
- awk '!/.eslintrc.js/' .svnignore > temp && mv temp .svnignore
- awk '!/.eslintignore/' .svnignore > temp && mv temp .svnignore
- git commit .svnignore -m "Updated .svnignore"
+ awk '!/.eslintrc.js/' .svnignore > temp && mv temp .svnignore
+ awk '!/.eslintignore/' .svnignore > temp && mv temp .svnignore
+ git commit .svnignore -m "Updated .svnignore"
}
# This function will create a new set of release branches.
@@ -86,60 +71,62 @@ function modify_svnignore {
# These branches will be created off of master.
function create_new_release_branches {
- # Prompt for version number.
- read -p "What version are you releasing? Please write in x.x syntax. Example: 4.9 - " version
-
- # Declare the new branch names.
- NEW_UNBUILT_BRANCH="branch-$version"
- NEW_BUILT_BRANCH="branch-$version-built"
-
- # Check if branch already exists, if not, create new branch named "branch-x.x"
- if [[ -n $( git branch -r | grep "$NEW_UNBUILT_BRANCH" ) ]]; then
- echo "$NEW_UNBUILT_BRANCH already exists. Exiting..."
- exit 1
- else
- echo ""
- echo "Creating new unbuilt branch $NEW_UNBUILT_BRANCH from current master branch..."
- echo ""
- # reset --hard to remote master in case they have local commits in their repo
- git checkout master && git pull && git reset --hard origin/master
-
- # Create new branch, push to repo
- git checkout -b $NEW_UNBUILT_BRANCH
-
- git push -u origin $NEW_UNBUILT_BRANCH
- echo ""
- echo "$NEW_UNBUILT_BRANCH created."
- echo ""
- # Verify you want a built version
- read -n1 -p "Would you like to create a built version of $NEW_UNBUILT_BRANCH as new $NEW_BUILT_BRANCH? [y/N]" reply
- if [[ 'y' == $reply || 'Y' == $reply ]]; then
- # make sure we're still checked out on the right branch
- git checkout $NEW_UNBUILT_BRANCH
-
- git checkout -b $NEW_BUILT_BRANCH
-
- # New .gitignore for release branches
- echo ""
- echo "Creating new .gitignore"
- echo ""
- create_release_gitignore
-
- # Remove stuff from svnignore
- modify_svnignore
-
- git checkout $NEW_UNBUILT_BRANCH
-
- git push -u origin $NEW_BUILT_BRANCH
-
- # Script will continue on to actually build the plugin onto this new branch...
- else
- # Nothing left to do...
- echo ""
- echo "Ok, all done then."
- exit 1
- fi
- fi
+ # Prompt for version number.
+ read -p "What version are you releasing? Please write in x.x syntax. Example: 4.9 - " version
+
+ # Declare the new branch names.
+ NEW_UNBUILT_BRANCH="branch-$version"
+ NEW_BUILT_BRANCH="branch-$version-built"
+
+ # Check if branch already exists, if not, create new branch named "branch-x.x"
+ if [[ -n $( git branch -r | grep "$NEW_UNBUILT_BRANCH" ) ]];
+ then
+ echo "$NEW_UNBUILT_BRANCH already exists. Exiting..."
+ exit 1
+ else
+ echo ""
+ echo "Creating new unbuilt branch $NEW_UNBUILT_BRANCH from current master branch..."
+ echo ""
+ # reset --hard to remote master in case they have local commits in their repo
+ git checkout master && git pull && git reset --hard origin/master
+
+ # Create new branch, push to repo
+ git checkout -b $NEW_UNBUILT_BRANCH
+
+ git push -u origin $NEW_UNBUILT_BRANCH
+ echo ""
+ echo "$NEW_UNBUILT_BRANCH created."
+ echo ""
+ # Verify you want a built version
+ read -n1 -p "Would you like to create a built version of $NEW_UNBUILT_BRANCH as new $NEW_BUILT_BRANCH? [y/N]" reply
+ if [[ 'y' == $reply || 'Y' == $reply ]]
+ then
+ # make sure we're still checked out on the right branch
+ git checkout $NEW_UNBUILT_BRANCH
+
+ git checkout -b $NEW_BUILT_BRANCH
+
+ # New .gitignore for release branches
+ echo ""
+ echo "Creating new .gitignore"
+ echo ""
+ create_release_gitignore
+
+ # Remove stuff from svnignore
+ modify_svnignore
+
+ git checkout $NEW_UNBUILT_BRANCH
+
+ git push -u origin $NEW_BUILT_BRANCH
+
+ # Script will continue on to actually build the plugin onto this new branch...
+ else
+ # Nothing left to do...
+ echo ""
+ echo "Ok, all done then."
+ exit 1
+ fi
+ fi
}
# Script parameter, what do you want to do?
@@ -155,50 +142,56 @@ TMP_LOCAL_BUILT_VERSION="/tmp/jetpack2"
# Make sure we don't have uncommitted changes.
if [[ -n $( git status -s --porcelain ) ]]; then
- echo "Uncommitted changes found."
- echo "Please deal with them and try again clean."
- exit 1
+ echo "Uncommitted changes found."
+ echo "Please deal with them and try again clean."
+ exit 1
fi
# Check the command
-if [[ 'new' == $COMMAND || '-n' == $COMMAND ]]; then
- create_new_release_branches
-elif [[ 'update' = $COMMAND || '-u' = $COMMAND ]]; then
- # It's possible they passed the branch name directly to the script
- if [[ -z $2 ]]; then
- read -p "What branch are you updating? (enter full branch name): " branch
- UPDATE_BUILT_BRANCH=$branch
- else
- UPDATE_BUILT_BRANCH=$2
- fi
+if [[ 'new' == $COMMAND || '-n' == $COMMAND ]]
+then
+ create_new_release_branches
+elif [[ 'update' = $COMMAND || '-u' = $COMMAND ]]
+then
+ # It's possible they passed the branch name directly to the script
+ if [[ -z $2 ]]
+ then
+ read -p "What branch are you updating? (enter full branch name): " branch
+ UPDATE_BUILT_BRANCH=$branch
+ else
+ UPDATE_BUILT_BRANCH=$2
+ fi
else
- usage
+ usage
fi
# Cast the branch name that we'll be building to a single var.
-if [[ -n $NEW_BUILT_BRANCH ]]; then
- BUILD_TARGET=$NEW_BUILT_BRANCH
-elif [[ -n $UPDATE_BUILT_BRANCH ]]; then
- BUILD_TARGET=$UPDATE_BUILT_BRANCH
+if [[ -n $NEW_BUILT_BRANCH ]]
+then
+ BUILD_TARGET=$NEW_BUILT_BRANCH
+elif [[ -n $UPDATE_BUILT_BRANCH ]]
+then
+ BUILD_TARGET=$UPDATE_BUILT_BRANCH
else
- echo ""
- echo "No target branch specified. How did you make it this far?"
- exit 1
+ echo ""
+ echo "No target branch specified. How did you make it this far?"
+ exit 1
fi
### This bit is the engine that will build a branch and push to another one ####
# Make sure we're trying to deploy something that exists.
if [[ -z $( git branch -r | grep "$BUILD_TARGET" ) ]]; then
- echo "Branch $BUILD_TARGET not found in git repository."
- echo ""
- exit 1
+ echo "Branch $BUILD_TARGET not found in git repository."
+ echo ""
+ exit 1
fi
read -p "You are about to deploy a new production build to the $BUILD_TARGET branch from the $CURRENT_BRANCH branch. Are you sure? [y/N]" -n 1 -r
-if [[ $REPLY != "y" && $REPLY != "Y" ]]; then
- exit 1
+if [[ $REPLY != "y" && $REPLY != "Y" ]]
+then
+ exit 1
fi
echo ""
@@ -206,9 +199,9 @@ echo "Building Jetpack"
# Checking for yarn
hash yarn 2>/dev/null || {
- echo >&2 "This script requires you to have yarn package manager installed."
- echo >&2 "Please install it following the instructions on https://yarnpkg.com. Aborting.";
- exit 1;
+ echo >&2 "This script requires you to have yarn package manager installed."
+ echo >&2 "Please install it following the instructions on https://yarnpkg.com. Aborting.";
+ exit 1;
}
# Start clean by removing previously installed dependencies and built files
@@ -234,7 +227,8 @@ echo "Purging paths included in .svnignore"
# check .svnignore
for file in $( cat "$DIR/.svnignore" 2>/dev/null ); do
# We want to commit changes to to-test.md as well as the testing tips.
- if [[ $file == "to-test.md" || $file == "docs/testing/testing-tips.md" ]]; then
+ if [[ $file == "to-test.md" || $file == "docs/testing/testing-tips.md" ]]
+ then
continue;
fi
rm -rf TMP_LOCAL_BUILT_VERSION/$file