diff options
Diffstat (limited to 'plugins/jetpack/extensions/blocks/map')
27 files changed, 92 insertions, 1659 deletions
diff --git a/plugins/jetpack/extensions/blocks/map/add-point/index.js b/plugins/jetpack/extensions/blocks/map/add-point/index.js deleted file mode 100644 index a4c6e2e1..00000000 --- a/plugins/jetpack/extensions/blocks/map/add-point/index.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * External dependencies - */ -import { __ } from '@wordpress/i18n'; -import { Component } from '@wordpress/element'; -import { Button, Dashicon, Popover } from '@wordpress/components'; - -/** - * Internal dependencies - */ -import './style.scss'; -import LocationSearch from '../location-search'; - -export class AddPoint extends Component { - render() { - const { onClose, onAddPoint, onError, apiKey } = this.props; - return ( - <Button className="component__add-point"> - { __( 'Add marker', 'jetpack' ) } - <Popover className="component__add-point__popover"> - <Button className="component__add-point__close" onClick={ onClose }> - <Dashicon icon="no" /> - </Button> - <LocationSearch - onAddPoint={ onAddPoint } - label={ __( 'Add a location', 'jetpack' ) } - apiKey={ apiKey } - onError={ onError } - /> - </Popover> - </Button> - ); - } -} - -AddPoint.defaultProps = { - onAddPoint: () => {}, - onClose: () => {}, - onError: () => {}, -}; - -export default AddPoint; diff --git a/plugins/jetpack/extensions/blocks/map/add-point/oval.svg b/plugins/jetpack/extensions/blocks/map/add-point/oval.svg deleted file mode 100644 index cb149ec4..00000000 --- a/plugins/jetpack/extensions/blocks/map/add-point/oval.svg +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg width="32px" height="38px" viewBox="0 0 32 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <!-- Generator: Sketch 52.1 (67048) - http://www.bohemiancoding.com/sketch --> - <title>Oval Copy</title> - <desc>Created with Sketch.</desc> - <defs> - <path d="M119,136 C119,136 135,124.692424 135,114 C135,103.307576 127.836556,98 119,98 C110.163444,98 103,103.307576 103,114 C103,124.692424 119,136 119,136 Z" id="path-1"></path> - <mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="32" height="38" fill="white"> - <use xlink:href="#path-1"></use> - </mask> - </defs> - <g id="Map-Block" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-dasharray="4"> - <g id="Revised-01-Placeholder-Copy" transform="translate(-496.000000, -376.000000)" stroke="#444444" stroke-width="4"> - <g id="Group" transform="translate(393.000000, 278.000000)"> - <use id="Oval-Copy" mask="url(#mask-2)" xlink:href="#path-1"></use> - </g> - </g> - </g> -</svg>
\ No newline at end of file diff --git a/plugins/jetpack/extensions/blocks/map/add-point/style.scss b/plugins/jetpack/extensions/blocks/map/add-point/style.scss deleted file mode 100644 index dba3c0c0..00000000 --- a/plugins/jetpack/extensions/blocks/map/add-point/style.scss +++ /dev/null @@ -1,46 +0,0 @@ -@import '../../../shared/styles/gutenberg-colors.scss'; - -.component__add-point { - position: absolute; - left: 50%; - top: 50%; - width: 32px; - height: 38px; - margin-top: -19px; - margin-left: -16px; - background-image: url( ./oval.svg ); - background-repeat: no-repeat; - text-indent: -9999px; - box-shadow: none; - background-color: transparent; - &.components-button:not( :disabled ):not( [aria-disabled='true'] ):focus { - background-color: transparent; - box-shadow: none; - } - &:focus, - &:active { - background-color: transparent; - } -} -.component__add-point__popover { - .components-button:not( :disabled ):not( [aria-disabled='true'] ):focus { - background-color: transparent; - box-shadow: none; - } - .components-popover__content { - padding: 0.1rem; - } - .components-location-search { - margin: 0.5rem; - } -} -.component__add-point__close { - margin: 0; - padding: 0; - border: none; - box-shadow: none; - float: right; - path { - color: $dark-gray-150; - } -} diff --git a/plugins/jetpack/extensions/blocks/map/component.js b/plugins/jetpack/extensions/blocks/map/component.js deleted file mode 100644 index c4ea55ae..00000000 --- a/plugins/jetpack/extensions/blocks/map/component.js +++ /dev/null @@ -1,332 +0,0 @@ -/** - * External dependencies - */ -import { __ } from '@wordpress/i18n'; -import { assign, debounce, get } from 'lodash'; -import { Button, Dashicon, TextareaControl, TextControl } from '@wordpress/components'; -import { Children, Component, createRef, Fragment } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import MapMarker from './map-marker/'; -import InfoWindow from './info-window/'; -import { mapboxMapFormatter } from './mapbox-map-formatter/'; - -export class Map extends Component { - // Lifecycle - constructor() { - super( ...arguments ); - - this.state = { - map: null, - fit_to_bounds: false, - loaded: false, - mapboxgl: null, - }; - - // Refs - this.mapRef = createRef(); - - // Debouncers - this.debouncedSizeMap = debounce( this.sizeMap, 250 ); - } - render() { - const { points, admin, children, markerColor } = this.props; - const { map, activeMarker, mapboxgl } = this.state; - const { onMarkerClick, deleteActiveMarker, updateActiveMarker } = this; - const currentPoint = get( activeMarker, 'props.point' ) || {}; - const { title, caption } = currentPoint; - const addPoint = Children.map( children, child => { - const tagName = get( child, 'props.tagName' ); - if ( 'AddPoint' === tagName ) { - return child; - } - } ); - const mapMarkers = - map && - mapboxgl && - points.map( ( point, index ) => { - return ( - <MapMarker - key={ index } - point={ point } - index={ index } - map={ map } - mapboxgl={ mapboxgl } - markerColor={ markerColor } - onClick={ onMarkerClick } - /> - ); - } ); - const infoWindow = mapboxgl && ( - <InfoWindow - activeMarker={ activeMarker } - map={ map } - mapboxgl={ mapboxgl } - unsetActiveMarker={ () => this.setState( { activeMarker: null } ) } - > - { activeMarker && admin && ( - <Fragment> - <TextControl - label={ __( 'Marker Title', 'jetpack' ) } - value={ title } - onChange={ value => updateActiveMarker( { title: value } ) } - /> - <TextareaControl - className="wp-block-jetpack-map__marker-caption" - label={ __( 'Marker Caption', 'jetpack' ) } - value={ caption } - rows="2" - tag="textarea" - onChange={ value => updateActiveMarker( { caption: value } ) } - /> - <Button onClick={ deleteActiveMarker } className="wp-block-jetpack-map__delete-btn"> - <Dashicon icon="trash" size="15" /> { __( 'Delete Marker', 'jetpack' ) } - </Button> - </Fragment> - ) } - - { activeMarker && ! admin && ( - <Fragment> - <h3>{ title }</h3> - <p>{ caption }</p> - </Fragment> - ) } - </InfoWindow> - ); - return ( - <Fragment> - <div className="wp-block-jetpack-map__gm-container" ref={ this.mapRef }> - { mapMarkers } - </div> - { infoWindow } - { addPoint } - </Fragment> - ); - } - componentDidMount() { - const { apiKey } = this.props; - if ( apiKey ) { - this.loadMapLibraries(); - } - } - componentWillUnmount() { - this.debouncedSizeMap.cancel(); - } - componentDidUpdate( prevProps ) { - const { apiKey, children, points, mapStyle, mapDetails } = this.props; - const { map } = this.state; - if ( apiKey && apiKey.length > 0 && apiKey !== prevProps.apiKey ) { - this.loadMapLibraries(); - } - // If the user has just clicked to show the Add Point component, hide info window. - // AddPoint is the only possible child. - if ( children !== prevProps.children && children !== false ) { - this.clearCurrentMarker(); - } - if ( points !== prevProps.points ) { - this.setBoundsByMarkers(); - } - if ( points.length !== prevProps.points.length ) { - this.clearCurrentMarker(); - } - if ( mapStyle !== prevProps.mapStyle || mapDetails !== prevProps.mapDetails ) { - map.setStyle( this.getMapStyle() ); - } - } - /* Event handling */ - onMarkerClick = marker => { - const { onMarkerClick } = this.props; - this.setState( { activeMarker: marker } ); - onMarkerClick(); - }; - onMapClick = () => { - this.setState( { activeMarker: null } ); - }; - clearCurrentMarker = () => { - this.setState( { activeMarker: null } ); - }; - updateActiveMarker = updates => { - const { points } = this.props; - const { activeMarker } = this.state; - const { index } = activeMarker.props; - const newPoints = points.slice( 0 ); - - assign( newPoints[ index ], updates ); - this.props.onSetPoints( newPoints ); - }; - deleteActiveMarker = () => { - const { points } = this.props; - const { activeMarker } = this.state; - const { index } = activeMarker.props; - const newPoints = points.slice( 0 ); - - newPoints.splice( index, 1 ); - this.props.onSetPoints( newPoints ); - this.setState( { activeMarker: null } ); - }; - // Various map functions - sizeMap = () => { - const { map } = this.state; - const mapEl = this.mapRef.current; - const blockWidth = mapEl.offsetWidth; - const maxHeight = window.innerHeight * 0.8; - const blockHeight = Math.min( blockWidth * ( 3 / 4 ), maxHeight ); - mapEl.style.height = blockHeight + 'px'; - map.resize(); - this.setBoundsByMarkers(); - }; - setBoundsByMarkers = () => { - const { zoom, points, onSetZoom } = this.props; - const { map, activeMarker, mapboxgl, zoomControl, boundsSetProgrammatically } = this.state; - if ( ! map ) { - return; - } - // If there are no points at all, there is no data to set bounds to. Abort the function. - if ( ! points.length ) { - return; - } - // If there is an open info window, resizing will probably move the info window which complicates interaction. - if ( activeMarker ) { - return; - } - const bounds = new mapboxgl.LngLatBounds(); - points.forEach( point => { - bounds.extend( [ point.coordinates.longitude, point.coordinates.latitude ] ); - } ); - - // If there are multiple points, zoom is determined by the area they cover, and zoom control is removed. - if ( points.length > 1 ) { - map.fitBounds( bounds, { - padding: { - top: 40, - bottom: 40, - left: 20, - right: 20, - }, - } ); - this.setState( { boundsSetProgrammatically: true } ); - map.removeControl( zoomControl ); - return; - } - // If there is only one point, center map around it. - map.setCenter( bounds.getCenter() ); - - // If the number of markers has just changed from > 1 to 1, set an arbitrary tight zoom, which feels like the original default. - if ( boundsSetProgrammatically ) { - const newZoom = 12; - map.setZoom( newZoom ); - onSetZoom( newZoom ); - } else { - // If there are one (or zero) points, and this is not a recent change, respect user's chosen zoom. - map.setZoom( parseInt( zoom, 10 ) ); - } - map.addControl( zoomControl ); - this.setState( { boundsSetProgrammatically: false } ); - }; - getMapStyle() { - const { mapStyle, mapDetails } = this.props; - return mapboxMapFormatter( mapStyle, mapDetails ); - } - getMapType() { - const { mapStyle } = this.props; - switch ( mapStyle ) { - case 'satellite': - return 'HYBRID'; - case 'terrain': - return 'TERRAIN'; - case 'black_and_white': - default: - return 'ROADMAP'; - } - } - // Script loading, browser geolocation - scriptsLoaded = () => { - const { mapCenter, points } = this.props; - this.setState( { loaded: true } ); - - // If the map has any points, skip geolocation and use what we have. - if ( points.length > 0 ) { - this.initMap( mapCenter ); - return; - } - this.initMap( mapCenter ); - }; - loadMapLibraries() { - const { apiKey } = this.props; - Promise.all( [ - import( /* webpackChunkName: "map/mapbox-gl" */ 'mapbox-gl' ), - import( /* webpackChunkName: "map/mapbox-gl" */ 'mapbox-gl/dist/mapbox-gl.css' ), - ] ).then( ( [ { default: mapboxgl } ] ) => { - mapboxgl.accessToken = apiKey; - this.setState( { mapboxgl: mapboxgl }, this.scriptsLoaded ); - } ); - } - initMap( mapCenter ) { - const { mapboxgl } = this.state; - const { zoom, onMapLoaded, onError, admin } = this.props; - let map = null; - try { - map = new mapboxgl.Map( { - container: this.mapRef.current, - style: this.getMapStyle(), - center: this.googlePoint2Mapbox( mapCenter ), - zoom: parseInt( zoom, 10 ), - pitchWithRotate: false, - attributionControl: false, - dragRotate: false, - } ); - } catch ( e ) { - onError( 'mapbox_error', e.message ); - return; - } - map.on( 'error', e => { - onError( 'mapbox_error', e.error.message ); - } ); - const zoomControl = new mapboxgl.NavigationControl( { - showCompass: false, - showZoom: true, - } ); - map.on( 'zoomend', () => { - this.props.onSetZoom( map.getZoom() ); - } ); - - /* Listen for clicks on the Map background, which hides the current popup. */ - map.getCanvas().addEventListener( 'click', this.onMapClick ); - this.setState( { map, zoomControl }, () => { - this.debouncedSizeMap(); - map.addControl( zoomControl ); - if ( ! admin ) { - map.addControl( new mapboxgl.FullscreenControl() ); - } - this.mapRef.current.addEventListener( 'alignmentChanged', this.debouncedSizeMap ); - map.resize(); - onMapLoaded(); - this.setState( { loaded: true } ); - window.addEventListener( 'resize', this.debouncedSizeMap ); - } ); - } - googlePoint2Mapbox( google_point ) { - const mapCenter = [ - google_point.longitude ? google_point.longitude : 0, - google_point.latitude ? google_point.latitude : 0, - ]; - return mapCenter; - } -} - -Map.defaultProps = { - points: [], - mapStyle: 'default', - zoom: 13, - onSetZoom: () => {}, - onMapLoaded: () => {}, - onMarkerClick: () => {}, - onError: () => {}, - markerColor: 'red', - apiKey: null, - mapCenter: {}, -}; - -export default Map; diff --git a/plugins/jetpack/extensions/blocks/map/edit.js b/plugins/jetpack/extensions/blocks/map/edit.js deleted file mode 100644 index 87889f63..00000000 --- a/plugins/jetpack/extensions/blocks/map/edit.js +++ /dev/null @@ -1,283 +0,0 @@ -/** - * External dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { __ } from '@wordpress/i18n'; -import { Component, createRef, Fragment } from '@wordpress/element'; -import { - Button, - ButtonGroup, - ExternalLink, - IconButton, - PanelBody, - Placeholder, - Spinner, - TextControl, - ToggleControl, - Toolbar, - withNotices, -} from '@wordpress/components'; -import { - BlockAlignmentToolbar, - BlockControls, - InspectorControls, - PanelColorSettings, -} from '@wordpress/editor'; - -/** - * Internal dependencies - */ -import AddPoint from './add-point'; -import Locations from './locations'; -import Map from './component.js'; -import MapThemePicker from './map-theme-picker'; -import { settings } from './settings.js'; - -const API_STATE_LOADING = 0; -const API_STATE_FAILURE = 1; -const API_STATE_SUCCESS = 2; - -class MapEdit extends Component { - constructor() { - super( ...arguments ); - this.state = { - addPointVisibility: false, - apiState: API_STATE_LOADING, - }; - this.mapRef = createRef(); - } - addPoint = point => { - const { attributes, setAttributes } = this.props; - const { points } = attributes; - const newPoints = points.slice( 0 ); - let duplicateFound = false; - points.map( existingPoint => { - if ( existingPoint.id === point.id ) { - duplicateFound = true; - } - } ); - if ( duplicateFound ) { - return; - } - newPoints.push( point ); - setAttributes( { points: newPoints } ); - this.setState( { addPointVisibility: false } ); - }; - updateAlignment = value => { - this.props.setAttributes( { align: value } ); - // Allow one cycle for alignment change to take effect - setTimeout( this.mapRef.current.sizeMap, 0 ); - }; - updateAPIKeyControl = value => { - this.setState( { - apiKeyControl: value, - } ); - }; - updateAPIKey = () => { - const { noticeOperations } = this.props; - const { apiKeyControl } = this.state; - noticeOperations.removeAllNotices(); - apiKeyControl && this.apiCall( apiKeyControl, 'POST' ); - }; - removeAPIKey = () => { - this.apiCall( null, 'DELETE' ); - }; - apiCall( serviceApiKey = null, method = 'GET' ) { - const { noticeOperations } = this.props; - const { apiKey } = this.state; - const path = '/wpcom/v2/service-api-keys/mapbox'; - const fetch = serviceApiKey - ? { path, method, data: { service_api_key: serviceApiKey } } - : { path, method }; - this.setState( { apiRequestOutstanding: true }, () => { - apiFetch( fetch ).then( - result => { - noticeOperations.removeAllNotices(); - this.setState( { - apiState: result.service_api_key ? API_STATE_SUCCESS : API_STATE_FAILURE, - apiKey: result.service_api_key, - apiKeyControl: result.service_api_key, - apiRequestOutstanding: false, - } ); - }, - result => { - this.onError( null, result.message ); - this.setState( { - apiRequestOutstanding: false, - apiKeyControl: apiKey, - } ); - } - ); - } ); - } - componentDidMount() { - this.apiCall(); - } - onError = ( code, message ) => { - const { noticeOperations } = this.props; - noticeOperations.removeAllNotices(); - noticeOperations.createErrorNotice( message ); - }; - render() { - const { className, setAttributes, attributes, noticeUI, notices } = this.props; - const { mapStyle, mapDetails, points, zoom, mapCenter, markerColor, align } = attributes; - const { - addPointVisibility, - apiKey, - apiKeyControl, - apiState, - apiRequestOutstanding, - } = this.state; - const inspectorControls = ( - <Fragment> - <BlockControls> - <BlockAlignmentToolbar - value={ align } - onChange={ this.updateAlignment } - controls={ [ 'center', 'wide', 'full' ] } - /> - <Toolbar> - <IconButton - icon={ settings.markerIcon } - label="Add a marker" - onClick={ () => this.setState( { addPointVisibility: true } ) } - /> - </Toolbar> - </BlockControls> - <InspectorControls> - <PanelBody title={ __( 'Map Theme', 'jetpack' ) }> - <MapThemePicker - value={ mapStyle } - onChange={ value => setAttributes( { mapStyle: value } ) } - options={ settings.mapStyleOptions } - /> - <ToggleControl - label={ __( 'Show street names', 'jetpack' ) } - checked={ mapDetails } - onChange={ value => setAttributes( { mapDetails: value } ) } - /> - </PanelBody> - <PanelColorSettings - title={ __( 'Colors', 'jetpack' ) } - initialOpen={ true } - colorSettings={ [ - { - value: markerColor, - onChange: value => setAttributes( { markerColor: value } ), - label: 'Marker Color', - }, - ] } - /> - { points.length ? ( - <PanelBody title={ __( 'Markers', 'jetpack' ) } initialOpen={ false }> - <Locations - points={ points } - onChange={ value => { - setAttributes( { points: value } ); - } } - /> - </PanelBody> - ) : null } - <PanelBody title={ __( 'Mapbox Access Token', 'jetpack' ) } initialOpen={ false }> - <TextControl - label={ __( 'Mapbox Access Token', 'jetpack' ) } - value={ apiKeyControl } - onChange={ value => this.setState( { apiKeyControl: value } ) } - /> - <ButtonGroup> - <Button type="button" onClick={ this.updateAPIKey } isDefault> - { __( 'Update Token', 'jetpack' ) } - </Button> - <Button type="button" onClick={ this.removeAPIKey } isDefault> - { __( 'Remove Token', 'jetpack' ) } - </Button> - </ButtonGroup> - </PanelBody> - </InspectorControls> - </Fragment> - ); - const placholderAPIStateLoading = ( - <Placeholder icon={ settings.icon }> - <Spinner /> - </Placeholder> - ); - const placeholderAPIStateFailure = ( - <Placeholder icon={ settings.icon } label={ __( 'Map', 'jetpack' ) } notices={ notices }> - <Fragment> - <div className="components-placeholder__instructions"> - { __( 'To use the map block, you need an Access Token.', 'jetpack' ) } - <br /> - <ExternalLink href="https://www.mapbox.com"> - { __( 'Create an account or log in to Mapbox.', 'jetpack' ) } - </ExternalLink> - <br /> - { __( - 'Locate and copy the default access token. Then, paste it into the field below.', - 'jetpack' - ) } - </div> - <TextControl - className="wp-block-jetpack-map-components-text-control-api-key" - disabled={ apiRequestOutstanding } - placeholder={ __( 'Paste Token Here', 'jetpack' ) } - value={ apiKeyControl } - onChange={ this.updateAPIKeyControl } - /> - <Button - className="wp-block-jetpack-map-components-text-control-api-key-submit" - isLarge - disabled={ apiRequestOutstanding || ! apiKeyControl || apiKeyControl.length < 1 } - onClick={ this.updateAPIKey } - > - { __( 'Set Token', 'jetpack' ) } - </Button> - </Fragment> - </Placeholder> - ); - const placeholderAPIStateSuccess = ( - <Fragment> - { inspectorControls } - <div className={ className }> - <Map - ref={ this.mapRef } - mapStyle={ mapStyle } - mapDetails={ mapDetails } - points={ points } - zoom={ zoom } - mapCenter={ mapCenter } - markerColor={ markerColor } - onSetZoom={ value => { - setAttributes( { zoom: value } ); - } } - admin={ true } - apiKey={ apiKey } - onSetPoints={ value => setAttributes( { points: value } ) } - onMapLoaded={ () => this.setState( { addPointVisibility: true } ) } - onMarkerClick={ () => this.setState( { addPointVisibility: false } ) } - onError={ this.onError } - > - { addPointVisibility && ( - <AddPoint - onAddPoint={ this.addPoint } - onClose={ () => this.setState( { addPointVisibility: false } ) } - apiKey={ apiKey } - onError={ this.onError } - tagName="AddPoint" - /> - ) } - </Map> - </div> - </Fragment> - ); - return ( - <Fragment> - { noticeUI } - { apiState === API_STATE_LOADING && placholderAPIStateLoading } - { apiState === API_STATE_FAILURE && placeholderAPIStateFailure } - { apiState === API_STATE_SUCCESS && placeholderAPIStateSuccess } - </Fragment> - ); - } -} - -export default withNotices( MapEdit ); diff --git a/plugins/jetpack/extensions/blocks/map/editor.js b/plugins/jetpack/extensions/blocks/map/editor.js deleted file mode 100644 index d05f4039..00000000 --- a/plugins/jetpack/extensions/blocks/map/editor.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Internal dependencies - */ -import registerJetpackBlock from '../../shared/register-jetpack-block'; -import { name, settings } from '.'; - -registerJetpackBlock( name, settings ); diff --git a/plugins/jetpack/extensions/blocks/map/editor.scss b/plugins/jetpack/extensions/blocks/map/editor.scss deleted file mode 100644 index ab66d12b..00000000 --- a/plugins/jetpack/extensions/blocks/map/editor.scss +++ /dev/null @@ -1,28 +0,0 @@ - -.wp-block-jetpack-map__delete-btn { - padding: 0; - svg { - margin-right: 0.4em; - } -} -.wp-block-jetpack-map-components-text-control-api-key { - margin-right: 4px; - &.components-base-control .components-base-control__field { - margin-bottom: 0; - } -} -.wp-block-jetpack-map-components-text-control-api-key-submit.is-large { - height: 31px; -} -.wp-block-jetpack-map-components-text-control-api-key-submit:disabled { - opacity: 1; -} -.wp-block[data-type='jetpack/map'] { - .components-placeholder__label { - svg { - fill: currentColor; - margin-right: 6px; - margin-right: 1ch; - } - } -} diff --git a/plugins/jetpack/extensions/blocks/map/index.js b/plugins/jetpack/extensions/blocks/map/index.js deleted file mode 100644 index 2e66caae..00000000 --- a/plugins/jetpack/extensions/blocks/map/index.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Internal dependencies - */ -import { settings as mapSettings } from './settings.js'; -import edit from './edit'; -import save from './save'; -import './style.scss'; -import './editor.scss'; - -export const { name } = mapSettings; - -export const settings = { - title: mapSettings.title, - icon: mapSettings.icon, - category: mapSettings.category, - keywords: mapSettings.keywords, - description: mapSettings.description, - attributes: mapSettings.attributes, - supports: mapSettings.supports, - getEditWrapperProps( attributes ) { - const { align } = attributes; - if ( -1 !== mapSettings.validAlignments.indexOf( align ) ) { - return { 'data-align': align }; - } - }, - edit, - save, -}; diff --git a/plugins/jetpack/extensions/blocks/map/info-window/index.js b/plugins/jetpack/extensions/blocks/map/info-window/index.js deleted file mode 100644 index f469efad..00000000 --- a/plugins/jetpack/extensions/blocks/map/info-window/index.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * External dependencies - */ - -import { Component, createPortal } from '@wordpress/element'; - -export class InfoWindow extends Component { - componentDidMount() { - const { mapboxgl } = this.props; - this.el = document.createElement( 'DIV' ); - this.infowindow = new mapboxgl.Popup( { - closeButton: true, - closeOnClick: false, - offset: { - left: [ 0, 0 ], - top: [ 0, 5 ], - right: [ 0, 0 ], - bottom: [ 0, -40 ], - }, - } ); - this.infowindow.setDOMContent( this.el ); - this.infowindow.on( 'close', this.closeClick ); - } - componentDidUpdate( prevProps ) { - if ( this.props.activeMarker !== prevProps.activeMarker ) { - this.props.activeMarker ? this.openWindow() : this.closeWindow(); - } - } - render() { - // Use React portal to render components directly into the Mapbox info window. - return this.el ? createPortal( this.props.children, this.el ) : null; - } - closeClick = () => { - this.props.unsetActiveMarker(); - }; - openWindow() { - const { map, activeMarker } = this.props; - this.infowindow.setLngLat( activeMarker.getPoint() ).addTo( map ); - } - closeWindow() { - this.infowindow.remove(); - } -} - -InfoWindow.defaultProps = { - unsetActiveMarker: () => {}, - activeMarker: null, - map: null, - mapboxgl: null, -}; - -export default InfoWindow; diff --git a/plugins/jetpack/extensions/blocks/map/location-search/index.js b/plugins/jetpack/extensions/blocks/map/location-search/index.js deleted file mode 100644 index aad845ca..00000000 --- a/plugins/jetpack/extensions/blocks/map/location-search/index.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * External dependencies - */ -import { __ } from '@wordpress/i18n'; -import { Component, createRef } from '@wordpress/element'; -import { BaseControl, TextControl } from '@wordpress/components'; - -/** - * Internal dependencies - */ -import Lookup from '../lookup'; - -const placeholderText = __( 'Add a marker…', 'jetpack' ); - -export class LocationSearch extends Component { - constructor() { - super( ...arguments ); - - this.textRef = createRef(); - this.containerRef = createRef(); - this.state = { - isEmpty: true, - }; - this.autocompleter = { - name: 'placeSearch', - options: this.search, - isDebounced: true, - getOptionLabel: option => <span>{ option.place_name }</span>, - getOptionKeywords: option => [ option.place_name ], - getOptionCompletion: this.getOptionCompletion, - }; - } - componentDidMount() { - setTimeout( () => { - this.containerRef.current.querySelector( 'input' ).focus(); - }, 50 ); - } - getOptionCompletion = option => { - const { value } = option; - const point = { - placeTitle: value.text, - title: value.text, - caption: value.place_name, - id: value.id, - coordinates: { - longitude: value.geometry.coordinates[ 0 ], - latitude: value.geometry.coordinates[ 1 ], - }, - }; - this.props.onAddPoint( point ); - return value.text; - }; - - search = value => { - const { apiKey, onError } = this.props; - const url = - 'https://api.mapbox.com/geocoding/v5/mapbox.places/' + - encodeURI( value ) + - '.json?access_token=' + - apiKey; - return new Promise( function( resolve, reject ) { - const xhr = new XMLHttpRequest(); - xhr.open( 'GET', url ); - xhr.onload = function() { - if ( xhr.status === 200 ) { - const res = JSON.parse( xhr.responseText ); - resolve( res.features ); - } else { - const res = JSON.parse( xhr.responseText ); - onError( res.statusText, res.responseJSON.message ); - reject( new Error( 'Mapbox Places Error' ) ); - } - }; - xhr.send(); - } ); - }; - onReset = () => { - this.textRef.current.value = null; - }; - render() { - const { label } = this.props; - return ( - <div ref={ this.containerRef }> - <BaseControl label={ label } className="components-location-search"> - <Lookup completer={ this.autocompleter } onReset={ this.onReset }> - { ( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) => ( - <TextControl - placeholder={ placeholderText } - ref={ this.textRef } - onChange={ onChange } - aria-expanded={ isExpanded } - aria-owns={ listBoxId } - aria-activedescendant={ activeId } - onKeyDown={ onKeyDown } - /> - ) } - </Lookup> - </BaseControl> - </div> - ); - } -} - -LocationSearch.defaultProps = { - onError: () => {}, -}; - -export default LocationSearch; diff --git a/plugins/jetpack/extensions/blocks/map/locations/index.js b/plugins/jetpack/extensions/blocks/map/locations/index.js deleted file mode 100644 index 80385891..00000000 --- a/plugins/jetpack/extensions/blocks/map/locations/index.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * External dependencies - */ -import { - Button, - Dashicon, - Panel, - PanelBody, - TextareaControl, - TextControl, -} from '@wordpress/components'; -import { Component } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import './style.scss'; - -export class Locations extends Component { - constructor() { - super( ...arguments ); - this.state = { - selectedCell: null, - }; - } - - onDeletePoint = e => { - const index = parseInt( e.target.getAttribute( 'data-id' ) ); - const { points, onChange } = this.props; - - const newPoints = points.slice( 0 ); - newPoints.splice( index, 1 ); - onChange( newPoints ); - }; - - setMarkerField( field, value, index ) { - const { points, onChange } = this.props; - - const newPoints = points.slice( 0 ); - newPoints[ index ][ field ] = value; - onChange( newPoints ); - } - - render() { - const { points } = this.props; - const rows = points.map( ( point, index ) => ( - <PanelBody title={ point.placeTitle } key={ point.id } initialOpen={ false }> - <TextControl - label="Marker Title" - value={ point.title } - onChange={ title => this.setMarkerField( 'title', title, index ) } - /> - <TextareaControl - label="Marker Caption" - value={ point.caption } - rows="3" - onChange={ caption => this.setMarkerField( 'caption', caption, index ) } - /> - <Button - data-id={ index } - onClick={ this.onDeletePoint } - className="component__locations__delete-btn" - > - <Dashicon icon="trash" size="15" /> Delete Marker - </Button> - </PanelBody> - ) ); - return ( - <div className="component__locations"> - <Panel className="component__locations__panel">{ rows }</Panel> - </div> - ); - } -} - -Locations.defaultProps = { - points: Object.freeze( [] ), - onChange: () => {}, -}; - -export default Locations; diff --git a/plugins/jetpack/extensions/blocks/map/locations/style.scss b/plugins/jetpack/extensions/blocks/map/locations/style.scss deleted file mode 100644 index 73f5e8b5..00000000 --- a/plugins/jetpack/extensions/blocks/map/locations/style.scss +++ /dev/null @@ -1,27 +0,0 @@ - -.component__locations__panel { - .edit-post-settings-sidebar__panel-block & { - margin-bottom: 1em; - &:empty { - display: none; - } - .components-panel__body:first-child { - border-top: none; - } - .components-panel__body, - .components-panel__body:first-child, - .components-panel__body:last-child { - max-width: 100%; - margin: 0; - } - .components-panel__body button { - padding-right: 40px; - } - } -} -.component__locations__delete-btn { - padding: 0; - svg { - margin-right: 0.4em; - } -} diff --git a/plugins/jetpack/extensions/blocks/map/lookup/index.js b/plugins/jetpack/extensions/blocks/map/lookup/index.js deleted file mode 100644 index c9d41969..00000000 --- a/plugins/jetpack/extensions/blocks/map/lookup/index.js +++ /dev/null @@ -1,230 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; -import { __, _n, sprintf } from '@wordpress/i18n'; -import { Button, Popover, withFocusOutside, withSpokenMessages } from '@wordpress/components'; -import { Component } from '@wordpress/element'; -import { debounce, map } from 'lodash'; -import { ENTER, ESCAPE, UP, DOWN, LEFT, RIGHT } from '@wordpress/keycodes'; -import { withInstanceId, compose } from '@wordpress/compose'; - -function filterOptions( options = [], maxResults = 10 ) { - const filtered = []; - for ( let i = 0; i < options.length; i++ ) { - const option = options[ i ]; - - // Merge label into keywords - let { keywords = [] } = option; - if ( 'string' === typeof option.label ) { - keywords = [ ...keywords, option.label ]; - } - - filtered.push( option ); - - // Abort early if max reached - if ( filtered.length === maxResults ) { - break; - } - } - - return filtered; -} - -export class Lookup extends Component { - static getInitialState() { - return { - selectedIndex: 0, - query: undefined, - filteredOptions: [], - isOpen: false, - }; - } - - constructor() { - super( ...arguments ); - this.debouncedLoadOptions = debounce( this.loadOptions, 250 ); - this.state = this.constructor.getInitialState(); - } - - componentWillUnmount() { - this.debouncedLoadOptions.cancel(); - } - - select = option => { - const { completer } = this.props; - const getOptionCompletion = completer.getOptionCompletion || {}; - getOptionCompletion( option ); - this.reset(); - }; - - reset = () => { - this.setState( this.constructor.getInitialState() ); - }; - - handleFocusOutside() { - this.reset(); - } - - loadOptions( completer, query ) { - const { options } = completer; - const promise = ( this.activePromise = Promise.resolve( - typeof options === 'function' ? options( query ) : options - ).then( optionsData => { - if ( promise !== this.activePromise ) { - // Another promise has become active since this one was asked to resolve, so do nothing, - // or else we might end triggering a race condition updating the state. - return; - } - const keyedOptions = optionsData.map( ( optionData, optionIndex ) => ( { - key: `${ optionIndex }`, - value: optionData, - label: completer.getOptionLabel( optionData ), - keywords: completer.getOptionKeywords ? completer.getOptionKeywords( optionData ) : [], - } ) ); - - const filteredOptions = filterOptions( keyedOptions ); - const selectedIndex = - filteredOptions.length === this.state.filteredOptions.length ? this.state.selectedIndex : 0; - this.setState( { - [ 'options' ]: keyedOptions, - filteredOptions, - selectedIndex, - isOpen: filteredOptions.length > 0, - } ); - this.announce( filteredOptions ); - } ) ); - } - - onChange = query => { - const { completer } = this.props; - const { options } = this.state; - - if ( ! query ) { - this.reset(); - return; - } - - if ( completer ) { - if ( completer.isDebounced ) { - this.debouncedLoadOptions( completer, query ); - } else { - this.loadOptions( completer, query ); - } - } - - const filteredOptions = completer ? filterOptions( options ) : []; - if ( completer ) { - this.setState( { selectedIndex: 0, filteredOptions, query } ); - } - }; - - onKeyDown = event => { - const { isOpen, selectedIndex, filteredOptions } = this.state; - if ( ! isOpen ) { - return; - } - let nextSelectedIndex; - switch ( event.keyCode ) { - case UP: - nextSelectedIndex = ( selectedIndex === 0 ? filteredOptions.length : selectedIndex ) - 1; - this.setState( { selectedIndex: nextSelectedIndex } ); - break; - - case DOWN: - nextSelectedIndex = ( selectedIndex + 1 ) % filteredOptions.length; - this.setState( { selectedIndex: nextSelectedIndex } ); - break; - - case ENTER: - this.select( filteredOptions[ selectedIndex ] ); - break; - - case LEFT: - case RIGHT: - case ESCAPE: - this.reset(); - return; - - default: - return; - } - - // Any handled keycode should prevent original behavior. This relies on - // the early return in the default case. - event.preventDefault(); - event.stopPropagation(); - }; - announce( filteredOptions ) { - const { debouncedSpeak } = this.props; - if ( ! debouncedSpeak ) { - return; - } - if ( filteredOptions.length ) { - debouncedSpeak( - sprintf( - _n( - '%d result found, use up and down arrow keys to navigate.', - '%d results found, use up and down arrow keys to navigate.', - filteredOptions.length, - 'jetpack', - 'jetpack' - ), - filteredOptions.length - ), - 'assertive' - ); - } else { - debouncedSpeak( __( 'No results.', 'jetpack' ), 'assertive' ); - } - } - render() { - const { onChange, onKeyDown } = this; - const { children, instanceId, completer } = this.props; - const { selectedIndex, filteredOptions } = this.state; - const { key: selectedKey = '' } = filteredOptions[ selectedIndex ] || {}; - const { className } = completer; - const isExpanded = filteredOptions.length > 0; - const listBoxId = isExpanded ? `components-autocomplete-listbox-${ instanceId }` : null; - const activeId = isExpanded - ? `components-autocomplete-item-${ instanceId }-${ selectedKey }` - : null; - return ( - <div className="components-autocomplete"> - { children( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) } - { isExpanded && ( - <Popover - focusOnMount={ false } - onClose={ this.reset } - position="top center" - className="components-autocomplete__popover" - noArrow - > - <div id={ listBoxId } role="listbox" className="components-autocomplete__results"> - { map( filteredOptions, ( option, index ) => ( - <Button - key={ option.key } - id={ `components-autocomplete-item-${ instanceId }-${ option.key }` } - role="option" - aria-selected={ index === selectedIndex } - disabled={ option.isDisabled } - className={ classnames( 'components-autocomplete__result', className, { - 'is-selected': index === selectedIndex, - } ) } - onClick={ () => this.select( option ) } - > - { option.label } - </Button> - ) ) } - </div> - </Popover> - ) } - </div> - ); - } -} -export default compose( [ - withSpokenMessages, - withInstanceId, - withFocusOutside, // this MUST be the innermost HOC as it calls handleFocusOutside -] )( Lookup ); diff --git a/plugins/jetpack/extensions/blocks/map/map-marker/index.js b/plugins/jetpack/extensions/blocks/map/map-marker/index.js deleted file mode 100644 index e8db9934..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-marker/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * External dependencies - */ -import { Component } from '@wordpress/element'; - -/** - * Internal dependencies - */ -import './style.scss'; - -export class MapMarker extends Component { - componentDidMount() { - this.renderMarker(); - } - componentWillUnmount() { - if ( this.marker ) { - this.marker.remove(); - } - } - componentDidUpdate() { - this.renderMarker(); - } - handleClick = () => { - const { onClick } = this.props; - onClick( this ); - }; - getPoint = () => { - const { point } = this.props; - return [ point.coordinates.longitude, point.coordinates.latitude ]; - }; - renderMarker() { - const { map, point, mapboxgl, markerColor } = this.props; - const { handleClick } = this; - const mapboxPoint = [ point.coordinates.longitude, point.coordinates.latitude ]; - const el = this.marker ? this.marker.getElement() : document.createElement( 'div' ); - if ( this.marker ) { - this.marker.setLngLat( mapboxPoint ); - } else { - el.className = 'wp-block-jetpack-map-marker'; - this.marker = new mapboxgl.Marker( el ) - .setLngLat( mapboxPoint ) - .setOffset( [ 0, -19 ] ) - .addTo( map ); - - this.marker.getElement().addEventListener( 'click', handleClick ); - } - el.innerHTML = - '<?xml version="1.0" encoding="UTF-8"?><svg version="1.1" viewBox="0 0 32 38" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g fill-rule="evenodd"><path id="d" d="m16 38s16-11.308 16-22-7.1634-16-16-16-16 5.3076-16 16 16 22 16 22z" fill="' + - markerColor + - '" mask="url(#c)"/></g></svg>'; - } - render() { - return null; - } -} - -MapMarker.defaultProps = { - point: {}, - map: null, - markerColor: '#000000', - mapboxgl: null, - onClick: () => {}, -}; - -export default MapMarker; diff --git a/plugins/jetpack/extensions/blocks/map/map-marker/style.scss b/plugins/jetpack/extensions/blocks/map/map-marker/style.scss deleted file mode 100644 index 6c5a2a65..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-marker/style.scss +++ /dev/null @@ -1,6 +0,0 @@ - -.wp-block-jetpack-map-marker { - width: 32px; - height: 38px; - opacity: 0.9; -} diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/index.js b/plugins/jetpack/extensions/blocks/map/map-theme-picker/index.js deleted file mode 100644 index e226534a..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/index.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * External dependencies - */ -import { Component } from '@wordpress/element'; -import { Button, ButtonGroup } from '@wordpress/components'; -import classnames from 'classnames'; - -/** - * Internal dependencies - */ -import './style.scss'; - -export class MapThemePicker extends Component { - render() { - const { options, value, onChange, label } = this.props; - const buttons = options.map( ( option, index ) => { - const classes = classnames( - 'component__map-theme-picker__button', - 'is-theme-' + option.value, - option.value === value ? 'is-selected' : '' - ); - return ( - <Button - className={ classes } - title={ option.label } - key={ index } - onClick={ () => onChange( option.value ) } - > - { option.label } - </Button> - ); - } ); - return ( - <div className="component__map-theme-picker components-base-control"> - { /* eslint-disable-next-line jsx-a11y/label-has-for */ } - <label className="components-base-control__label">{ label }</label> - <ButtonGroup>{ buttons }</ButtonGroup> - </div> - ); - } -} - -MapThemePicker.defaultProps = { - label: '', - options: [], - value: null, - onChange: () => {}, -}; - -export default MapThemePicker; diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg Binary files differdeleted file mode 100644 index 34cc1412..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_black_and_white.jpg +++ /dev/null diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_default.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_default.jpg Binary files differdeleted file mode 100644 index 35505eb1..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_default.jpg +++ /dev/null diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg Binary files differdeleted file mode 100644 index ef6ae417..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_satellite.jpg +++ /dev/null diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg b/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg Binary files differdeleted file mode 100644 index eee1a2da..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/map-theme_terrain.jpg +++ /dev/null diff --git a/plugins/jetpack/extensions/blocks/map/map-theme-picker/style.scss b/plugins/jetpack/extensions/blocks/map/map-theme-picker/style.scss deleted file mode 100644 index eb444c1c..00000000 --- a/plugins/jetpack/extensions/blocks/map/map-theme-picker/style.scss +++ /dev/null @@ -1,36 +0,0 @@ -@import '../../../shared/styles/gutenberg-colors.scss'; - -.component__map-theme-picker__button { - .edit-post-settings-sidebar__panel-block & { - border: 1px solid $light-gray-500; - border-radius: 100%; - width: 56px; - height: 56px; - margin: 2px; - text-indent: -9999px; - background-color: $light-gray-500; - background-position: center center; - background-repeat: no-repeat; - background-size: contain; - transform: scale( 1 ); - transition: transform 0.2s ease; - &:hover { - transform: scale( 1.1 ); - } - &.is-selected { - border-color: $black; - } - &.is-theme-default { - background-image: url( './map-theme_default.jpg' ); - } - &.is-theme-black_and_white { - background-image: url( './map-theme_black_and_white.jpg' ); - } - &.is-theme-satellite { - background-image: url( './map-theme_satellite.jpg' ); - } - &.is-theme-terrain { - background-image: url( './map-theme_terrain.jpg' ); - } - } -} diff --git a/plugins/jetpack/extensions/blocks/map/map.php b/plugins/jetpack/extensions/blocks/map/map.php index 8b8532c0..d0c82a0d 100644 --- a/plugins/jetpack/extensions/blocks/map/map.php +++ b/plugins/jetpack/extensions/blocks/map/map.php @@ -25,7 +25,99 @@ jetpack_register_block( function jetpack_map_block_load_assets( $attr, $content ) { $api_key = Jetpack_Options::get_option( 'mapbox_api_key' ); + if ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() ) { + static $map_block_counter = array(); + + $id = get_the_ID(); + if ( ! isset( $map_block_counter[ $id ] ) ) { + $map_block_counter[ $id ] = 0; + } + $map_block_counter[ $id ]++; + + $iframe_url = add_query_arg( + array( + 'map-block-counter' => absint( $map_block_counter[ $id ] ), + 'map-block-post-id' => $id, + ), + get_permalink() + ); + + $placeholder = preg_replace( '/(?<=<div\s)/', 'placeholder ', $content ); + + return sprintf( + '<amp-iframe src="%s" width="%d" height="%d" layout="responsive" allowfullscreen sandbox="allow-scripts">%s</amp-iframe>', + esc_url( $iframe_url ), + 4, + 3, + $placeholder + ); + } + Jetpack_Gutenberg::load_assets_as_required( 'map' ); return preg_replace( '/<div /', '<div data-api-key="' . esc_attr( $api_key ) . '" ', $content, 1 ); } + +/** + * Render a page containing only a single Map block. + */ +function jetpack_map_block_render_single_block_page() { + // phpcs:ignore WordPress.Security.NonceVerification + $map_block_counter = isset( $_GET, $_GET['map-block-counter'] ) ? absint( $_GET['map-block-counter'] ) : null; + // phpcs:ignore WordPress.Security.NonceVerification + $map_block_post_id = isset( $_GET, $_GET['map-block-post-id'] ) ? absint( $_GET['map-block-post-id'] ) : null; + + if ( ! $map_block_counter || ! $map_block_post_id ) { + return; + } + + /* Create an array of all root-level DIVs that are Map Blocks */ + $post = get_post( $map_block_post_id ); + + if ( ! class_exists( 'DOMDocument' ) ) { + return; + } + + $post_html = new DOMDocument(); + /** This filter is already documented in core/wp-includes/post-template.php */ + $content = apply_filters( 'the_content', $post->post_content ); + + /* Suppress warnings */ + libxml_use_internal_errors( true ); + @$post_html->loadHTML( $content ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged + libxml_use_internal_errors( false ); + + $xpath = new DOMXPath( $post_html ); + $container = $xpath->query( '//div[ contains( @class, "wp-block-jetpack-map" ) ]' )->item( $map_block_counter - 1 ); + + /* Check that we have a block matching the counter position */ + if ( ! $container ) { + return; + } + + /* Compile scripts and styles */ + ob_start(); + + add_filter( 'jetpack_is_amp_request', '__return_false' ); + + Jetpack_Gutenberg::load_assets_as_required( 'map' ); + wp_scripts()->do_items(); + wp_styles()->do_items(); + + add_filter( 'jetpack_is_amp_request', '__return_true' ); + + $head_content = ob_get_clean(); + + /* Put together a new complete document containing only the requested block markup and the scripts/styles needed to render it */ + $block_markup = $post_html->saveHTML( $container ); + $api_key = Jetpack_Options::get_option( 'mapbox_api_key' ); + $page_html = sprintf( + '<!DOCTYPE html><head><style>html, body { margin: 0; padding: 0; }</style>%s</head><body>%s</body>', + $head_content, + preg_replace( '/(?<=<div\s)/', 'data-api-key="' . esc_attr( $api_key ) . '" ', $block_markup, 1 ) + ); + echo $page_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + exit; +} + +add_action( 'wp', 'jetpack_map_block_render_single_block_page' ); diff --git a/plugins/jetpack/extensions/blocks/map/mapbox-map-formatter/index.js b/plugins/jetpack/extensions/blocks/map/mapbox-map-formatter/index.js deleted file mode 100644 index 6ec21ad8..00000000 --- a/plugins/jetpack/extensions/blocks/map/mapbox-map-formatter/index.js +++ /dev/null @@ -1,22 +0,0 @@ -export function mapboxMapFormatter( mapStyle, mapDetails ) { - const style_urls = { - default: { - details: 'mapbox://styles/automattic/cjolkhmez0qdd2ro82dwog1in', - no_details: 'mapbox://styles/automattic/cjolkci3905d82soef4zlmkdo', - }, - black_and_white: { - details: 'mapbox://styles/automattic/cjolkixvv0ty42spgt2k4j434', - no_details: 'mapbox://styles/automattic/cjolkgc540tvj2spgzzoq37k4', - }, - satellite: { - details: 'mapbox://styles/mapbox/satellite-streets-v10', - no_details: 'mapbox://styles/mapbox/satellite-v9', - }, - terrain: { - details: 'mapbox://styles/automattic/cjolkf8p405fh2soet2rdt96b', - no_details: 'mapbox://styles/automattic/cjolke6fz12ys2rpbpvgl12ha', - }, - }; - const style_url = style_urls[ mapStyle ][ mapDetails ? 'details' : 'no_details' ]; - return style_url; -} diff --git a/plugins/jetpack/extensions/blocks/map/save.js b/plugins/jetpack/extensions/blocks/map/save.js deleted file mode 100644 index ffa82641..00000000 --- a/plugins/jetpack/extensions/blocks/map/save.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * External dependencies - */ - -import { Component } from '@wordpress/element'; - -class MapSave extends Component { - render() { - const { attributes } = this.props; - const { align, mapStyle, mapDetails, points, zoom, mapCenter, markerColor } = attributes; - const pointsList = points.map( ( point, index ) => { - const { longitude, latitude } = point.coordinates; - const url = 'https://www.google.com/maps/search/?api=1&query=' + latitude + ',' + longitude; - return ( - <li key={ index }> - <a href={ url }>{ point.title }</a> - </li> - ); - } ); - const alignClassName = align ? `align${ align }` : null; - // All camelCase attribute names converted to snake_case data attributes - return ( - <div - className={ alignClassName } - data-map-style={ mapStyle } - data-map-details={ mapDetails } - data-points={ JSON.stringify( points ) } - data-zoom={ zoom } - data-map-center={ JSON.stringify( mapCenter ) } - data-marker-color={ markerColor } - > - { points.length > 0 && <ul>{ pointsList }</ul> } - </div> - ); - } -} - -export default MapSave; diff --git a/plugins/jetpack/extensions/blocks/map/settings.js b/plugins/jetpack/extensions/blocks/map/settings.js deleted file mode 100644 index e8bc87d2..00000000 --- a/plugins/jetpack/extensions/blocks/map/settings.js +++ /dev/null @@ -1,104 +0,0 @@ -// Disable forbidden <svg> etc. so that frontend component does not depend on @wordpress/component -/* eslint-disable react/forbid-elements */ -/** - * External dependencies - */ -import { __, _x } from '@wordpress/i18n'; - -export const settings = { - name: 'map', - prefix: 'jetpack', - title: __( 'Map', 'jetpack' ), - icon: ( - /* Do not use SVG components from @wordpress/component to avoid frontend bloat */ - <svg - xmlns="http://www.w3.org/2000/svg" - width="24" - height="24" - viewBox="0 0 24 24" - role="img" - aria-hidden="true" - focusable="false" - > - <path fill="none" d="M0 0h24v24H0V0z" /> - <path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z" /> - </svg> - ), - category: 'jetpack', - keywords: [ - _x( 'map', 'block search term', 'jetpack' ), - _x( 'location', 'block search term', 'jetpack' ), - _x( 'navigation', 'block search term', 'jetpack' ), - ], - description: __( 'Add an interactive map showing one or more locations.', 'jetpack' ), - attributes: { - align: { - type: 'string', - }, - points: { - type: 'array', - default: [], - }, - mapStyle: { - type: 'string', - default: 'default', - }, - mapDetails: { - type: 'boolean', - default: true, - }, - zoom: { - type: 'integer', - default: 13, - }, - mapCenter: { - type: 'object', - default: { - longitude: -122.41941550000001, - latitude: 37.7749295, - }, - }, - markerColor: { - type: 'string', - default: 'red', - }, - }, - supports: { - html: false, - }, - mapStyleOptions: [ - { - value: 'default', - label: __( 'Basic', 'jetpack' ), - }, - { - value: 'black_and_white', - label: __( 'Black and white', 'jetpack' ), - }, - { - value: 'satellite', - label: __( 'Satellite', 'jetpack' ), - }, - { - value: 'terrain', - label: __( 'Terrain', 'jetpack' ), - }, - ], - validAlignments: [ 'center', 'wide', 'full' ], - markerIcon: ( - /* Do not use SVG components from @wordpress/component to avoid frontend bloat */ - <svg width="14" height="20" viewBox="0 0 14 20" xmlns="http://www.w3.org/2000/svg"> - <g id="Page-1" fill="none" fillRule="evenodd"> - <g id="outline-add_location-24px" transform="translate(-5 -2)"> - <polygon id="Shape" points="0 0 24 0 24 24 0 24" /> - <path - d="M12,2 C8.14,2 5,5.14 5,9 C5,14.25 12,22 12,22 C12,22 19,14.25 19,9 C19,5.14 15.86,2 12,2 Z M7,9 C7,6.24 9.24,4 12,4 C14.76,4 17,6.24 17,9 C17,11.88 14.12,16.19 12,18.88 C9.92,16.21 7,11.85 7,9 Z M13,6 L11,6 L11,8 L9,8 L9,10 L11,10 L11,12 L13,12 L13,10 L15,10 L15,8 L13,8 L13,6 Z" - id="Shape" - fill="#000" - fillRule="nonzero" - /> - </g> - </g> - </svg> - ), -}; diff --git a/plugins/jetpack/extensions/blocks/map/style.scss b/plugins/jetpack/extensions/blocks/map/style.scss deleted file mode 100644 index a3a25f29..00000000 --- a/plugins/jetpack/extensions/blocks/map/style.scss +++ /dev/null @@ -1,22 +0,0 @@ -@import '../../shared/styles/gutenberg-colors.scss'; - -.wp-block-jetpack-map { - .wp-block-jetpack-map__gm-container { - width: 100%; - overflow: hidden; - background: $light-gray-500; - min-height: 400px; - text-align: left; - } - .mapboxgl-popup { - h3 { - font-size: 1.3125em; - font-weight: 400; - margin-bottom: 0.5rem; - } - p { - margin-bottom: 0; - } - max-width: 300px; - } -} diff --git a/plugins/jetpack/extensions/blocks/map/view.js b/plugins/jetpack/extensions/blocks/map/view.js deleted file mode 100644 index fc825d67..00000000 --- a/plugins/jetpack/extensions/blocks/map/view.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Internal dependencies - */ -import './style.scss'; -import component from './component.js'; -import { settings } from './settings.js'; -import FrontendManagement from '../../shared/frontend-management.js'; - -typeof window !== 'undefined' && - window.addEventListener( 'load', function() { - const frontendManagement = new FrontendManagement(); - // Add apiKey to attibutes so FrontendManagement knows about it. - // It is dynamically being added on the php side. - // So that it can be updated accross all the map blocks at the same time. - const apiKey = { - type: 'string', - default: '', - }; - frontendManagement.blockIterator( document, [ - { - component: component, - options: { - settings: { - ...settings, - attributes: { - ...settings.attributes, - apiKey, - }, - }, - }, - }, - ] ); - } ); |