Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Gutenberg] Add amp-fit-text support to text blocks #1151

Merged
merged 14 commits into from
May 25, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .jshintrc

This file was deleted.

27 changes: 27 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"boss": true,
"curly": true,
"eqeqeq": true,
"eqnull": true,
"es3": true,
"esversion": 6,
"expr": true,
"immed": true,
"noarg": true,
"nonbsp": true,
"onevar": true,
"quotmark": "single",
"trailing": true,
"undef": true,
"unused": true,

"browser": true,

"globals": {
"_": false,
"Backbone": false,
"jQuery": false,
"JSON": false,
"wp": false
}
}
1 change: 1 addition & 0 deletions amp.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ function amp_init() {
add_filter( 'request', 'amp_force_query_var_value' );
add_action( 'admin_init', 'AMP_Options_Manager::register_settings' );
add_action( 'wp_loaded', 'amp_post_meta_box' );
add_action( 'wp_loaded', 'amp_editor_core_blocks' );
add_action( 'wp_loaded', 'amp_add_options_menu' );
add_action( 'parse_query', 'amp_correct_query_when_is_front_page' );

Expand Down
10 changes: 10 additions & 0 deletions assets/css/amp-default.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@
/** Force the image into a box of fixed dimensions and use object-fit to scale. **/
object-fit: contain;
}

.entry__content amp-fit-text blockquote,
amp-fit-text h1,
amp-fit-text h2,
amp-fit-text h3,
amp-fit-text h4,
amp-fit-text h5,
amp-fit-text h6 {
font-size: inherit;
}
194 changes: 194 additions & 0 deletions assets/js/amp-editor-blocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/* exported ampEditorBlocks */
/* eslint no-magic-numbers: [ "error", { "ignore": [ 1, -1, 0 ] } ] */

var ampEditorBlocks = ( function() {
var component = {

/**
* Holds data.
*/
data: {
textBlocks: [
'core/paragraph',
'core/heading',
'core/code',
'core/quote',
'core/subhead'
]
}
};

/**
* Set data, add filters.
*
* @param {Array} data Data.
*/
component.boot = function boot( data ) {
_.extend( component.data, data );

wp.hooks.addFilter( 'blocks.registerBlockType', 'ampEditorBlocks/addAttributes', component.addAMPAttributes );
wp.hooks.addFilter( 'blocks.BlockEdit', 'ampEditorBlocks/filterEdit', component.filterBlocksEdit );
wp.hooks.addFilter( 'blocks.getSaveElement', 'ampEditorBlocks/filterSave', component.filterBlocksSave );
};

/**
* Add AMP attributes to every core block.
*
* @param {Object} settings Settings.
* @param {string} name Block name.
* @return {*} Settings.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return is {Object}, no?

*/
component.addAMPAttributes = function addAMPAttributes( settings, name ) {
// Fit-text for text blocks.
if ( -1 !== component.data.textBlocks.indexOf( name ) ) {
if ( ! settings.attributes ) {
settings.attributes = {};
}
settings.attributes.ampFitText = {
type: 'boolean',
default: false
};
settings.attributes.minFont = {
type: 'number'
};
settings.attributes.maxFont = {
type: 'number'
};
settings.attributes.height = {
type: 'number',
default: 50
};
}
return settings;
};

/**
* Filters blocks edit function of all blocks.
*
* @param {Function} BlockEdit Edit function.
* @return {Function} Edit function.
*/
component.filterBlocksEdit = function filterBlocksEdit( BlockEdit ) {
var el = wp.element.createElement;

return function( props ) {
var name = props.name,
inspectorControls;

if ( -1 !== component.data.textBlocks.indexOf( name ) ) {
inspectorControls = component.setUpTextBlocksInspectorControls( props );
}

// Return original.
return [
inspectorControls,
el( BlockEdit, _.assign( {
key: 'original'
}, props ) )
];
};
};

/**
* Setup inspector controls for text blocks.
*
* @param {Object} props Props.
* @return {Object|Element|*|{$$typeof, type, key, ref, props, _owner}} Inspector Controls.
*/
component.setUpTextBlocksInspectorControls = function setUpInspectorControls( props ) {
var ampFitText = props.attributes.ampFitText,
minFont = props.attributes.minFont,
maxFont = props.attributes.maxFont,
height = props.attributes.height,
isSelected = props.isSelected,
el = wp.element.createElement,
InspectorControls = wp.blocks.InspectorControls,
TextControl = wp.components.TextControl,
ToggleControl = wp.components.ToggleControl,
PanelBody = wp.components.PanelBody,
label = 'Use AMP Fit Text';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs translation


if ( ampFitText ) {
return isSelected && (
el( InspectorControls, { key: 'inspector' },
el( PanelBody, { title: 'AMP Settings' },
el( ToggleControl, {
label: label,
checked: ampFitText,
onChange: function() {
props.setAttributes( { ampFitText: ! ampFitText } );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should ampFitText be replaced with event.checked?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the core blocks seem to use negating the current value for toggle controls (as far as I've seen), thought of staying consistent with the core blocks when using that. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this also result in the font-size-picker and range-control under Text Settings to be hidden when ampFitText is true?

}
} ),
el( TextControl, {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the font-size-picker control be used instead?

label: 'Height (px)',
value: height,
onChange: function( nextHeight ) {
props.setAttributes( { height: nextHeight } );
}
} ),
el( TextControl, {
label: 'Min font (px)',
value: minFont,
onChange: function( nextMinFont ) {
props.setAttributes( { minFont: nextMinFont } );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort if nextMinFont is larger than maxFont

}
} ),
el( TextControl, {
label: 'Max font (px)',
value: maxFont,
onChange: function( nextMaxFont ) {
props.setAttributes( { maxFont: nextMaxFont } );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure the height is set to be the Math.max() of the nextMaxFont and its current value.

}
} )
)
)
);
}

return isSelected && (
el( InspectorControls, { key: 'inspector' },
el( PanelBody, { title: 'AMP Settings' },
el( ToggleControl, {
label: label,
checked: ampFitText,
onChange: function() {
props.setAttributes( { ampFitText: ! ampFitText } );
}
} )
)
)
);
};

/**
* Filters blocks save function for core blocks except for dynamic blocks.
*
* @param {Object} element Element.
* @param {Object} blockType Block type.
* @param {Object} attributes Attributes.
* @return {Object} Element.
*/
component.filterBlocksSave = function filterBlocksSave( element, blockType, attributes ) {
var fitTextProps = {
layout: 'fixed-height',
children: element
};
// If the blockType is a dynamic block or if AMP layout isn't return original method.
if ( -1 === component.data.textBlocks.indexOf( blockType.name ) || ! attributes.ampFitText ) {
return element;
}

if ( attributes.minFont ) {
fitTextProps[ 'min-font-size' ] = attributes.minFont;
}
if ( attributes.maxFont ) {
fitTextProps[ 'max-font-size' ] = attributes.maxFont;
}
if ( attributes.height ) {
fitTextProps.height = attributes.height;
}
return wp.element.createElement( 'amp-fit-text', fitTextProps );
};

return component;
}() );
66 changes: 66 additions & 0 deletions includes/admin/class-amp-editor-blocks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/**
* AMP Editor Blocks extending.
*
* @package AMP
* @since 1.0
*/

/**
* Class AMP_Editor_Blocks
*/
class AMP_Editor_Blocks {

/**
* Init.
*/
public function init() {
if ( function_exists( 'gutenberg_init' ) ) {
add_action( 'admin_enqueue_scripts', array( $this, 'add_editor_filters' ) );
add_filter( 'wp_kses_allowed_html', array( $this, 'whitelist_layout_in_wp_kses_allowed_html' ), 10 );
}
}

/**
* Whitelist used data-amp-* attributes.
*
* @param array $context Array of contexts.
* @return mixed Modified array.
*/
public function whitelist_layout_in_wp_kses_allowed_html( $context ) {
foreach ( $context as $tag ) {
$tag['data-amp-fit-text'] = true;
}
return $context;
}

/**
* Enqueue filters for extending core blocks attributes.
* Has to be loaded before registering the blocks in registerCoreBlocks.
*/
public function add_editor_filters() {
wp_enqueue_script(
'amp-editor-blocks',
amp_get_asset_url( 'js/amp-editor-blocks.js' ),
array( 'amp-runtime', 'underscore', 'wp-hooks' ),
AMP__VERSION,
true
);

$dynamic_blocks = array();
$block_type_registry = WP_Block_Type_Registry::get_instance();
$block_types = $block_type_registry->get_all_registered();

foreach ( $block_types as $block_type ) {
if ( $block_type->is_dynamic() ) {
$dynamic_blocks[] = $block_type->name;
}
}

wp_add_inline_script( 'amp-editor-blocks', sprintf( 'ampEditorBlocks.boot( %s );',
wp_json_encode( array(
'dynamicBlocks' => $dynamic_blocks,
) )
) );
}
}
8 changes: 8 additions & 0 deletions includes/admin/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,11 @@ function amp_post_meta_box() {
$post_meta_box = new AMP_Post_Meta_Box();
$post_meta_box->init();
}

/**
* Bootstrap AMP Editor core blocks.
*/
function amp_editor_core_blocks() {
$editor_blocks = new AMP_Editor_Blocks();
$editor_blocks->init();
}
1 change: 1 addition & 0 deletions includes/class-amp-autoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class AMP_Autoloader {
* @var string[]
*/
private static $_classmap = array(
'AMP_Editor_Blocks' => 'includes/admin/class-amp-editor-blocks',
'AMP_Theme_Support' => 'includes/class-amp-theme-support',
'AMP_Response_Headers' => 'includes/class-amp-response-headers',
'AMP_Comment_Walker' => 'includes/class-amp-comment-walker',
Expand Down