diff --git a/assets/js/amp-editor-blocks.js b/assets/js/amp-editor-blocks.js index 4308a572b41..aebf1da26f6 100644 --- a/assets/js/amp-editor-blocks.js +++ b/assets/js/amp-editor-blocks.js @@ -1,5 +1,5 @@ /* exported ampEditorBlocks */ -/* eslint no-magic-numbers: [ "error", { "ignore": [ 1, -1, 0 ] } ] */ +/* eslint no-magic-numbers: [ "error", { "ignore": [ 1, -1, 0, 4 ] } ] */ var ampEditorBlocks = ( function() { // eslint-disable-line no-unused-vars var component, __; @@ -152,13 +152,14 @@ var ampEditorBlocks = ( function() { // eslint-disable-line no-unused-vars * Add extra data-amp-layout attribute to save to DB. * * @param {Object} props Properties. - * @param {string} blockType Block type. + * @param {Object} blockType Block type. * @param {Object} attributes Attributes. * @return {Object} Props. */ component.addAMPExtraProps = function addAMPExtraProps( props, blockType, attributes ) { var ampAttributes = {}; - if ( ! attributes.ampLayout && ! attributes.ampNoLoading ) { + + if ( 'amp/' === blockType.name.substr( 0, 4 ) ) { return props; } diff --git a/blocks/amp-brid-player/index.js b/blocks/amp-brid-player/index.js index 510b734d3c6..f2d89fcb02a 100644 --- a/blocks/amp-brid-player/index.js +++ b/blocks/amp-brid-player/index.js @@ -1,3 +1,8 @@ +/** + * Helper methods for blocks. + */ +import { getLayoutControls, getMediaPlaceholder } from '../utils.js'; + /** * Internal block libraries. */ @@ -8,7 +13,6 @@ const { Fragment } = wp.element; const { PanelBody, TextControl, - SelectControl, Placeholder, ToggleControl } = wp.components; @@ -29,26 +33,44 @@ export default registerBlockType( attributes: { autoPlay: { - default: false + type: 'boolean' }, dataPartner: { - type: 'number' + type: 'number', + source: 'attribute', + selector: 'amp-brid-player', + attribute: 'data-partner' }, dataPlayer: { - type: 'number' + type: 'number', + source: 'attribute', + selector: 'amp-brid-player', + attribute: 'data-player' }, dataVideo: { - type: 'number' + type: 'number', + source: 'attribute', + selector: 'amp-brid-player', + attribute: 'data-video' }, dataPlaylist: { - type: 'number' + type: 'number', + source: 'attribute', + selector: 'amp-brid-player', + attribute: 'data-playlist' }, dataOutstream: { - type: 'number' + type: 'number', + source: 'attribute', + selector: 'amp-brid-player', + attribute: 'data-outstream' }, - layout: { + ampLayout: { type: 'string', - default: 'responsive' + default: 'responsive', + source: 'attribute', + selector: 'amp-brid-player', + attribute: 'layout' }, width: { type: 'number', @@ -56,12 +78,16 @@ export default registerBlockType( }, height: { type: 'number', - default: 400 + default: 400, + source: 'attribute', + selector: 'amp-brid-player', + attribute: 'height' } }, - edit( { attributes, isSelected, setAttributes } ) { - const { autoPlay, dataPartner, dataPlayer, dataVideo, dataPlaylist, dataOutstream, layout, height, width } = attributes; + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { autoPlay, dataPartner, dataPlayer, dataVideo, dataPlaylist, dataOutstream } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) }, @@ -111,36 +137,15 @@ export default registerBlockType( checked={ autoPlay } onChange={ () => ( setAttributes( { autoPlay: ! autoPlay } ) ) } /> - ( setAttributes( { layout: value } ) ) } - /> - ( setAttributes( { width: value } ) ) } - /> - ( setAttributes( { height: value } ) ) } - /> + { + getLayoutControls( props, ampLayoutOptions ) + } ) } { - url && ( - -

{ url }

-

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

-
- ) - + url && getMediaPlaceholder( __( 'Brid Player', 'amp' ), url ) } { ! url && ( @@ -155,12 +160,12 @@ export default registerBlockType( save( { attributes } ) { let bridProps = { - layout: attributes.layout, + layout: attributes.ampLayout, height: attributes.height, 'data-player': attributes.dataPlayer, 'data-partner': attributes.dataPartner }; - if ( 'fixed-height' !== attributes.layout && attributes.width ) { + if ( 'fixed-height' !== attributes.ampLayout && attributes.width ) { bridProps.width = attributes.width; } if ( attributes.dataPlaylist ) { diff --git a/blocks/amp-ima-video/index.js b/blocks/amp-ima-video/index.js index 093f5ad8a3e..2a1f1c9c659 100644 --- a/blocks/amp-ima-video/index.js +++ b/blocks/amp-ima-video/index.js @@ -1,3 +1,8 @@ +/** + * Helper methods for blocks. + */ +import { getLayoutControls, getMediaPlaceholder } from '../utils.js'; + /** * Internal block libraries. */ @@ -8,7 +13,6 @@ const { Fragment } = wp.element; const { PanelBody, TextControl, - SelectControl, Placeholder, ToggleControl } = wp.components; @@ -30,33 +34,55 @@ export default registerBlockType( // @todo Perhaps later add subtitles option and additional source options? attributes: { dataDelayAdRequest: { - default: false + default: false, + source: 'attribute', + selector: 'amp-ima-video', + attribute: 'data-delay-ad-request' }, dataTag: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-ima-video', + attribute: 'data-tag' }, dataSrc: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-ima-video', + attribute: 'data-src' }, dataPoster: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-ima-video', + attribute: 'data-poster' }, - layout: { + ampLayout: { type: 'string', - default: 'responsive' + default: 'responsive', + source: 'attribute', + selector: 'amp-ima-video', + attribute: 'layout' }, width: { type: 'number', - default: 600 + default: 600, + source: 'attribute', + selector: 'amp-ima-video', + attribute: 'width' }, height: { type: 'number', - default: 400 + default: 400, + source: 'attribute', + selector: 'amp-ima-video', + attribute: 'height' } }, - edit( { attributes, isSelected, setAttributes } ) { - const { dataDelayAdRequest, dataTag, dataSrc, dataPoster, layout, height, width } = attributes; + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { dataDelayAdRequest, dataTag, dataSrc, dataPoster } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, { value: 'fixed', label: __( 'Fixed', 'amp' ) } @@ -92,35 +118,15 @@ export default registerBlockType( checked={ dataDelayAdRequest } onChange={ () => ( setAttributes( { dataDelayAdRequest: ! dataDelayAdRequest } ) ) } /> - ( setAttributes( { layout: value } ) ) } - /> - ( setAttributes( { width: value } ) ) } - /> - ( setAttributes( { height: value } ) ) } - /> + { + getLayoutControls( props, ampLayoutOptions ) + } ) } { - dataSet && ( - -

{ dataSrc }

-

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

-
- ) + dataSet && getMediaPlaceholder( __( 'IMA Video', 'amp' ), dataSrc ) } { ! dataSet && ( @@ -135,7 +141,7 @@ export default registerBlockType( save( { attributes } ) { let imaProps = { - layout: attributes.layout, + layout: attributes.ampLayout, height: attributes.height, width: attributes.width, 'data-tag': attributes.dataTag, diff --git a/blocks/amp-jwplayer/index.js b/blocks/amp-jwplayer/index.js index b764f928d21..094708f43d4 100644 --- a/blocks/amp-jwplayer/index.js +++ b/blocks/amp-jwplayer/index.js @@ -1,3 +1,8 @@ +/** + * Helper methods for blocks. + */ +import { getLayoutControls, getMediaPlaceholder } from '../utils.js'; + /** * Internal block libraries. */ @@ -8,7 +13,6 @@ const { Fragment } = wp.element; const { PanelBody, TextControl, - SelectControl, Placeholder } = wp.components; @@ -28,30 +32,49 @@ export default registerBlockType( attributes: { dataPlayerId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-jwplayer', + attribute: 'data-player-id' }, dataMediaId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-jwplayer', + attribute: 'data-media-id' }, dataPlaylistId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-jwplayer', + attribute: 'data-playlist-id' }, - layout: { + ampLayout: { type: 'string', - default: 'responsive' + default: 'responsive', + source: 'attribute', + selector: 'amp-jwplayer', + attribute: 'layout' }, width: { type: 'number', - default: 600 + default: 600, + source: 'attribute', + selector: 'amp-jwplayer', + attribute: 'width' }, height: { type: 'number', - default: 400 + default: 400, + source: 'attribute', + selector: 'amp-jwplayer', + attribute: 'height' } }, - edit( { attributes, isSelected, setAttributes } ) { - const { dataPlayerId, dataMediaId, dataPlaylistId, layout, height, width } = attributes; + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { dataPlayerId, dataMediaId, dataPlaylistId } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) }, @@ -90,35 +113,15 @@ export default registerBlockType( value={ dataPlaylistId } onChange={ value => ( setAttributes( { dataPlaylistId: value } ) ) } /> - ( setAttributes( { layout: value } ) ) } - /> - ( setAttributes( { width: value } ) ) } - /> - ( setAttributes( { height: value } ) ) } - /> + { + getLayoutControls( props, ampLayoutOptions ) + } ) } { - url && ( - -

{ url }

-

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

-
- ) + url && getMediaPlaceholder( __( 'JW Player', 'amp' ), url ) } { ! url && ( @@ -133,16 +136,17 @@ export default registerBlockType( save( { attributes } ) { let jwProps = { - layout: attributes.layout, + layout: attributes.ampLayout, height: attributes.height, 'data-player-id': attributes.dataPlayerId }; - if ( 'fixed-height' !== attributes.layout && attributes.width ) { + if ( 'fixed-height' !== attributes.ampLayout && attributes.width ) { jwProps.width = attributes.width; } if ( attributes.dataPlaylistId ) { jwProps[ 'data-playlist-id' ] = attributes.dataPlaylistId; - } else if ( attributes.dataMediaId ) { + } + if ( attributes.dataMediaId ) { jwProps[ 'data-media-id' ] = attributes.dataMediaId; } return ( diff --git a/blocks/amp-mathml/index.js b/blocks/amp-mathml/index.js index aadeba6ddc2..2b0662cb9e6 100644 --- a/blocks/amp-mathml/index.js +++ b/blocks/amp-mathml/index.js @@ -26,7 +26,10 @@ export default registerBlockType( attributes: { dataFormula: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-mathml', + attribute: 'data-formula' } }, diff --git a/blocks/amp-o2-player/index.js b/blocks/amp-o2-player/index.js index 41a111d5538..d0fea52808f 100644 --- a/blocks/amp-o2-player/index.js +++ b/blocks/amp-o2-player/index.js @@ -1,3 +1,8 @@ +/** + * Helper methods for blocks. + */ +import { getLayoutControls, getMediaPlaceholder } from '../utils.js'; + /** * Internal block libraries. */ @@ -8,7 +13,6 @@ const { Fragment } = wp.element; const { PanelBody, TextControl, - SelectControl, Placeholder, ToggleControl } = wp.components; @@ -30,37 +34,59 @@ export default registerBlockType( // @todo Add other useful macro toggles, e.g. showing relevant content. attributes: { dataPid: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-o2-player', + attribute: 'data-pid' }, dataVid: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-o2-player', + attribute: 'data-vid' }, dataBcid: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-o2-player', + attribute: 'data-bcid' }, dataBid: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-o2-player', + attribute: 'data-bid' }, autoPlay: { type: 'boolean', default: false }, - layout: { + ampLayout: { type: 'string', - default: 'responsive' + default: 'responsive', + source: 'attribute', + selector: 'amp-o2-player', + attribute: 'layout' }, width: { type: 'number', - default: 600 + default: 600, + source: 'attribute', + selector: 'amp-o2-player', + attribute: 'width' }, height: { type: 'number', - default: 400 + default: 400, + source: 'attribute', + selector: 'amp-o2-player', + attribute: 'height' } }, - edit( { attributes, isSelected, setAttributes } ) { - const { autoPlay, dataPid, dataVid, dataBcid, dataBid, layout, height, width } = attributes; + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { autoPlay, dataPid, dataVid, dataBcid, dataBid } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) }, @@ -105,35 +131,15 @@ export default registerBlockType( checked={ autoPlay } onChange={ () => ( setAttributes( { autoPlay: ! autoPlay } ) ) } /> - ( setAttributes( { layout: value } ) ) } - /> - ( setAttributes( { width: value } ) ) } - /> - ( setAttributes( { height: value } ) ) } - /> + { + getLayoutControls( props, ampLayoutOptions ) + } ) } { - url && ( - -

{ url }

-

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

-
- ) + url && getMediaPlaceholder( __( 'O2 Player', 'amp' ), url ) } { ! url && ( @@ -148,11 +154,11 @@ export default registerBlockType( save( { attributes } ) { let o2Props = { - layout: attributes.layout, + layout: attributes.ampLayout, height: attributes.height, 'data-pid': attributes.dataPid }; - if ( 'fixed-height' !== attributes.layout && attributes.width ) { + if ( 'fixed-height' !== attributes.ampLayout && attributes.width ) { o2Props.width = attributes.width; } if ( ! attributes.autoPlay ) { diff --git a/blocks/amp-ooyala-player/index.js b/blocks/amp-ooyala-player/index.js index f4f396c6788..2d9e1fb1019 100644 --- a/blocks/amp-ooyala-player/index.js +++ b/blocks/amp-ooyala-player/index.js @@ -1,3 +1,8 @@ +/** + * Helper methods for blocks. + */ +import { getLayoutControls, getMediaPlaceholder } from '../utils.js'; + /** * Internal block libraries. */ @@ -30,34 +35,56 @@ export default registerBlockType( // @todo Add data-config attribute? attributes: { dataEmbedCode: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-ooyala-player', + attribute: 'data-embedcode' }, dataPlayerId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-ooyala-player', + attribute: 'data-playerid' }, dataPcode: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-ooyala-player', + attribute: 'data-pcode' }, dataPlayerVersion: { type: 'string', - default: 'v3' + default: 'v3', + source: 'attribute', + selector: 'amp-ooyala-player', + attribute: 'data-playerversion' }, - layout: { + ampLayout: { type: 'string', - default: 'fixed' + default: 'fixed', + source: 'attribute', + selector: 'amp-ooyala-player', + attribute: 'layout' }, width: { type: 'number', - default: 600 + default: 600, + source: 'attribute', + selector: 'amp-ooyala-player', + attribute: 'width' }, height: { type: 'number', - default: 400 + default: 400, + source: 'attribute', + selector: 'amp-ooyala-player', + attribute: 'height' } }, - edit( { attributes, isSelected, setAttributes } ) { - const { dataEmbedCode, dataPlayerId, dataPcode, dataPlayerVersion, layout, height, width } = attributes; + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { dataEmbedCode, dataPlayerId, dataPcode, dataPlayerVersion } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, { value: 'fixed', label: __( 'Fixed', 'amp' ) }, @@ -99,35 +126,15 @@ export default registerBlockType( ] } onChange={ value => ( setAttributes( { dataPlayerVersion: value } ) ) } /> - ( setAttributes( { layout: value } ) ) } - /> - ( setAttributes( { width: value } ) ) } - /> - ( setAttributes( { height: value } ) ) } - /> + { + getLayoutControls( props, ampLayoutOptions ) + } ) } { - url && ( - -

{ url }

-

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

-
- ) + url && getMediaPlaceholder( __( 'Ooyala Player', 'amp' ), url ) } { ! url && ( @@ -141,17 +148,17 @@ export default registerBlockType( }, save( { attributes } ) { - const { dataEmbedCode, dataPlayerId, dataPcode, dataPlayerVersion, layout, height, width } = attributes; + const { dataEmbedCode, dataPlayerId, dataPcode, dataPlayerVersion, ampLayout, height, width } = attributes; let ooyalaProps = { - layout: layout, + layout: ampLayout, height: height, 'data-embedcode': dataEmbedCode, 'data-playerid': dataPlayerId, 'data-pcode': dataPcode, 'data-playerversion': dataPlayerVersion }; - if ( 'fixed-height' !== layout && width ) { + if ( 'fixed-height' !== ampLayout && width ) { ooyalaProps.width = width; } return ( diff --git a/blocks/amp-reach-player/index.js b/blocks/amp-reach-player/index.js index ff297598e87..549e1d4ce22 100644 --- a/blocks/amp-reach-player/index.js +++ b/blocks/amp-reach-player/index.js @@ -1,3 +1,8 @@ +/** + * Helper methods for blocks. + */ +import { getLayoutControls, getMediaPlaceholder } from '../utils.js'; + /** * Internal block libraries. */ @@ -8,7 +13,6 @@ const { Fragment } = wp.element; const { PanelBody, TextControl, - SelectControl, Placeholder } = wp.components; @@ -29,24 +33,37 @@ export default registerBlockType( attributes: { dataEmbedId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-reach-player', + attribute: 'data-embed-id' }, - layout: { + ampLayout: { type: 'string', - default: 'fixed-height' + default: 'fixed-height', + source: 'attribute', + selector: 'amp-reach-player', + attribute: 'layout' }, width: { type: 'number', - default: 600 + default: 600, + source: 'attribute', + selector: 'amp-reach-player', + attribute: 'width' }, height: { type: 'number', - default: 400 + default: 400, + source: 'attribute', + selector: 'amp-reach-player', + attribute: 'height' } }, - edit( { attributes, isSelected, setAttributes } ) { - const { dataEmbedId, layout, height, width } = attributes; + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { dataEmbedId } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, { value: 'fixed-height', label: __( 'Fixed Height', 'amp' ) }, @@ -70,35 +87,15 @@ export default registerBlockType( value={ dataEmbedId } onChange={ value => ( setAttributes( { dataEmbedId: value } ) ) } /> - ( setAttributes( { layout: value } ) ) } - /> - ( setAttributes( { width: value } ) ) } - /> - ( setAttributes( { height: value } ) ) } - /> + { + getLayoutControls( props, ampLayoutOptions ) + } ) } { - url && ( - -

{ url }

-

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

-
- ) + url && getMediaPlaceholder( __( 'Reach Player', 'amp' ), url ) } { ! url && ( @@ -112,14 +109,14 @@ export default registerBlockType( }, save( { attributes } ) { - const { dataEmbedId, layout, height, width } = attributes; + const { dataEmbedId, ampLayout, height, width } = attributes; let reachProps = { - layout: layout, + layout: ampLayout, height: height, 'data-embed-id': dataEmbedId }; - if ( 'fixed-height' !== layout && width ) { + if ( 'fixed-height' !== ampLayout && width ) { reachProps.width = width; } return ( diff --git a/blocks/amp-springboard-player/index.js b/blocks/amp-springboard-player/index.js index 7f997096c46..e3ab43f5e13 100644 --- a/blocks/amp-springboard-player/index.js +++ b/blocks/amp-springboard-player/index.js @@ -1,3 +1,8 @@ +/** + * Helper methods for blocks. + */ +import { getLayoutControls, getMediaPlaceholder } from '../utils.js'; + /** * Internal block libraries. */ @@ -28,41 +33,69 @@ export default registerBlockType( attributes: { dataSiteId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'data-site-id' }, dataContentId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'data-content-id' }, dataPlayerId: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'data-player-id' }, dataDomain: { - type: 'string' + type: 'string', + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'data-domain' }, dataMode: { type: 'string', - default: 'video' + default: 'video', + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'data-mode' }, dataItems: { type: 'number', - default: 1 + default: 1, + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'data-items' }, - layout: { + ampLayout: { type: 'string', - default: 'responsive' + default: 'responsive', + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'layout' }, width: { type: 'number', - default: 600 + default: 600, + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'width' }, height: { type: 'number', - default: 400 + default: 400, + source: 'attribute', + selector: 'amp-springboard-player', + attribute: 'height' } }, - edit( { attributes, isSelected, setAttributes } ) { - const { dataSiteId, dataPlayerId, dataContentId, dataDomain, dataMode, dataItems, layout, height, width } = attributes; + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { dataSiteId, dataPlayerId, dataContentId, dataDomain, dataMode, dataItems } = attributes; const ampLayoutOptions = [ { value: 'responsive', label: __( 'Responsive', 'amp' ) }, { value: 'fixed', label: __( 'Fixed', 'amp' ) }, @@ -115,35 +148,15 @@ export default registerBlockType( value={ dataItems } onChange={ value => ( setAttributes( { dataItems: value } ) ) } /> - ( setAttributes( { layout: value } ) ) } - /> - ( setAttributes( { width: value } ) ) } - /> - ( setAttributes( { height: value } ) ) } - /> + { + getLayoutControls( props, ampLayoutOptions ) + } ) } { - url && ( - -

{ url }

-

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

-
- ) + url && getMediaPlaceholder( __( 'Springboard Player', 'amp' ), url ) } { ! url && ( @@ -157,9 +170,9 @@ export default registerBlockType( }, save( { attributes } ) { - const { dataSiteId, dataPlayerId, dataContentId, dataDomain, dataMode, dataItems, layout, height, width } = attributes; + const { dataSiteId, dataPlayerId, dataContentId, dataDomain, dataMode, dataItems, ampLayout, height, width } = attributes; let springboardProps = { - layout: layout, + layout: ampLayout, height: height, 'data-site-id': dataSiteId, 'data-mode': dataMode, @@ -168,7 +181,7 @@ export default registerBlockType( 'data-domain': dataDomain, 'data-items': dataItems }; - if ( 'fixed-height' !== layout && width ) { + if ( 'fixed-height' !== ampLayout && width ) { springboardProps.width = attributes.width; } return ( diff --git a/blocks/amp-timeago/index.js b/blocks/amp-timeago/index.js new file mode 100644 index 00000000000..d80d1ea27be --- /dev/null +++ b/blocks/amp-timeago/index.js @@ -0,0 +1,173 @@ +/* global moment */ + +/** + * Helper methods for blocks. + */ +import { getLayoutControls } from '../utils.js'; + +/** + * Internal block libraries. + */ +const { __ } = wp.i18n; +const { + registerBlockType +} = wp.blocks; +const { + InspectorControls, + BlockAlignmentToolbar, + BlockControls +} = wp.editor; +const { + DateTimePicker, + PanelBody, + TextControl +} = wp.components; +import timeago from 'timeago.js'; + +/** + * Register block. + */ +export default registerBlockType( + 'amp/amp-timeago', + { + title: __( 'AMP Timeago' ), + category: 'common', + icon: 'backup', + keywords: [ + __( 'Time difference' ), + __( 'Time ago' ), + __( 'Date' ) + ], + + attributes: { + align: { + type: 'string' + }, + cutoff: { + type: 'number', + source: 'attribute', + selector: 'amp-timeago', + attribute: 'cutoff' + }, + dateTime: { + type: 'string', + source: 'attribute', + selector: 'amp-timeago', + attribute: 'datetime' + }, + ampLayout: { + type: 'string', + source: 'attribute', + selector: 'amp-timeago', + attribute: 'layout' + }, + width: { + type: 'number', + source: 'attribute', + selector: 'amp-timeago', + attribute: 'width' + }, + height: { + type: 'number', + source: 'attribute', + selector: 'amp-timeago', + attribute: 'height' + } + }, + + getEditWrapperProps( attributes ) { + const { align } = attributes; + if ( 'left' === align || 'right' === align || 'center' === align ) { + return { 'data-align': align }; + } + }, + + edit( props ) { + const { attributes, isSelected, setAttributes } = props; + const { align, cutoff } = attributes; + let timeAgo; + if ( attributes.dateTime ) { + if ( attributes.cutoff && attributes.cutoff < Math.abs( moment( attributes.dateTime ).diff( moment(), 'seconds' ) ) ) { + timeAgo = moment( attributes.dateTime ).format( 'dddd D MMMM HH:mm' ); + } else { + timeAgo = timeago().format( attributes.dateTime ); + } + } else { + timeAgo = timeago().format( new Date() ); + setAttributes( { dateTime: moment( moment(), moment.ISO_8601, true ).format() } ); + } + + const ampLayoutOptions = [ + { value: '', label: __( 'Responsive', 'amp' ) }, // Default for amp-timeago. + { value: 'fixed', label: __( 'Fixed', 'amp' ) }, + { value: 'fixed-height', label: __( 'Fixed height', 'amp' ) } + ]; + + return [ + isSelected && ( + + + ( setAttributes( { dateTime: moment( value, moment.ISO_8601, true ).format() } ) ) } // eslint-disable-line + /> + { + getLayoutControls( props, ampLayoutOptions ) + } + ( setAttributes( { cutoff: value } ) ) } + /> + + + ), + + { + setAttributes( { align: nextAlign } ); + } } + controls={ [ 'left', 'center', 'right' ] } + /> + , + + ]; + }, + + save( { attributes } ) { + let timeagoProps = { + layout: 'responsive', + className: 'align' + ( attributes.align || 'none' ), + datetime: attributes.dateTime, + locale: 'en' + }; + if ( attributes.cutoff ) { + timeagoProps.cutoff = attributes.cutoff; + } + if ( attributes.ampLayout ) { + switch ( attributes.ampLayout ) { + case 'fixed-height': + if ( attributes.height ) { + timeagoProps.height = attributes.height; + timeagoProps.layout = attributes.ampLayout; + } + break; + case 'fixed': + if ( attributes.height && attributes.width ) { + timeagoProps.height = attributes.height; + timeagoProps.width = attributes.width; + timeagoProps.layout = attributes.ampLayout; + } + break; + } + } + return ( + { moment( attributes.dateTime ).format( 'dddd D MMMM HH:mm' ) } + ); + } + } +); diff --git a/blocks/index.js b/blocks/index.js index d72e20ff51b..72228fd53c2 100644 --- a/blocks/index.js +++ b/blocks/index.js @@ -2,6 +2,7 @@ * Import blocks. */ import './amp-mathml'; +import './amp-timeago'; import './amp-o2-player'; import './amp-ooyala-player'; import './amp-reach-player'; diff --git a/blocks/utils.js b/blocks/utils.js new file mode 100644 index 00000000000..9e775fdc37d --- /dev/null +++ b/blocks/utils.js @@ -0,0 +1,82 @@ +const { __ } = wp.i18n; +const { + TextControl, + SelectControl, + Notice, + Placeholder +} = wp.components; + +/** + * Display media placeholder. + * + * @param {string} name Block's name. + * @param {string|boolean} url URL. + * @return {XML} Placeholder. + */ +export function getMediaPlaceholder( name, url ) { + return ( + +

{ url }

+

{ __( 'Previews for this are unavailable in the editor, sorry!', 'amp' ) }

+
+ ); +} + +/** + * Layout controls for AMP blocks' attributes: layout, width, height. + * + * @param {Object} props Props. + * @param {Array} ampLayoutOptions Layout options. + * @return {[XML,*,XML,*,XML]} Controls. + */ +export function getLayoutControls( props, ampLayoutOptions ) { + // @todo Move getting ampLayoutOptions to utils as well. + const { attributes, setAttributes } = props; + const { ampLayout, height, width } = attributes; + const showHeightNotice = ! height && ( 'fixed' === ampLayout || 'fixed-height' === ampLayout ); + const showWidthNotice = ! width && 'fixed' === ampLayout; + + return [ + ( setAttributes( { ampLayout: value } ) ) } + />, + showWidthNotice && ( + + { + wp.i18n.sprintf( + __( 'Width is required for %s layout', 'amp' ), + ampLayout + ) + } + + ), + ( setAttributes( { width: value } ) ) } + />, + showHeightNotice && ( + + { + wp.i18n.sprintf( + __( 'Height is required for %s layout', 'amp' ), + ampLayout + ) + } + + ), + ( setAttributes( { height: value } ) ) } + /> + ]; +} diff --git a/includes/admin/class-amp-editor-blocks.php b/includes/admin/class-amp-editor-blocks.php index 63c8da18e01..5c046964285 100644 --- a/includes/admin/class-amp-editor-blocks.php +++ b/includes/admin/class-amp-editor-blocks.php @@ -25,6 +25,7 @@ class AMP_Editor_Blocks { */ public $amp_blocks = array( 'amp-mathml', + 'amp-timeago', 'amp-o2-player', 'amp-ooyala-player', 'amp-reach-player', @@ -71,6 +72,7 @@ public function whitelist_block_atts_in_wp_kses_allowed_html( $tags, $context ) $tags[ $amp_block ] = array(); } + // @todo The global attributes included here should be matched up with what is actually used by each block. $tags[ $amp_block ] = array_merge( array_fill_keys( array( @@ -121,6 +123,12 @@ public function enqueue_block_editor_assets() { AMP__VERSION ); + wp_add_inline_script( + 'amp-editor-blocks-build', + 'wp.i18n.setLocaleData( ' . wp_json_encode( gutenberg_get_jed_locale_data( 'amp' ) ) . ', "amp" );', + 'before' + ); + wp_enqueue_script( 'amp-editor-blocks', amp_get_asset_url( 'js/amp-editor-blocks.js' ), @@ -131,8 +139,7 @@ public function enqueue_block_editor_assets() { wp_add_inline_script( 'amp-editor-blocks', - 'wp.i18n.setLocaleData( ' . wp_json_encode( gutenberg_get_jed_locale_data( 'amp' ) ) . ', "amp" );' . sprintf( 'ampEditorBlocks.boot();' ), - 'before' + 'ampEditorBlocks.boot();' ); } diff --git a/package-lock.json b/package-lock.json index 093d0c2b235..4edcc254144 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/jquery": { + "version": "2.0.49", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-2.0.49.tgz", + "integrity": "sha512-/9xLnYmohN/vD2gDnLS4cym8TUmrJu7DvZa/LELKzZjdPsvWVJiedsdu2SXNtb/DA7FGimqL2g0IoyhbNKLl8g==", + "dev": true + }, "@wordpress/babel-plugin-makepot": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-makepot/-/babel-plugin-makepot-1.0.1.tgz", @@ -5852,6 +5858,15 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, + "timeago.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/timeago.js/-/timeago.js-3.0.2.tgz", + "integrity": "sha1-MqZ+fA2IfqQspYjTquJvd95edsw=", + "dev": true, + "requires": { + "@types/jquery": "^2.0.40" + } + }, "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", diff --git a/package.json b/package.json index 6eeab252afe..5e1b02e2b74 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "grunt-contrib-jshint": "^1.1.0", "grunt-shell": "^2.1.0", "grunt-wp-deploy": "^1.2.1", + "timeago.js": "3.0.2", "webpack": "^3.12.0" }, "main": "blocks/index.js",