Skip to content

Commit

Permalink
#2427 Gutenberg compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
MARQAS committed Aug 14, 2018
1 parent cfa76a8 commit 93147eb
Show file tree
Hide file tree
Showing 4 changed files with 453 additions and 0 deletions.
6 changes: 6 additions & 0 deletions includes/vendor/amp/includes/class-amp-post-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
require_once( AMP__VENDOR__DIR__ . '/includes/sanitizers/class-amp-rule-spec.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/sanitizers/class-amp-allowed-tags-generated.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/sanitizers/class-amp-tag-and-attribute-sanitizer.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/sanitizers/class-amp-gallery-block-sanitizer.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/sanitizers/class-amp-block-sanitizer.php' );

require_once( AMP__VENDOR__DIR__ . '/includes/embeds/class-amp-twitter-embed.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/embeds/class-amp-youtube-embed.php' );
Expand All @@ -31,6 +33,7 @@
require_once( AMP__VENDOR__DIR__ . '/includes/embeds/class-amp-pinterest-embed.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/embeds/class-amp-wistia-embed.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/embeds/class-amp-polldaddy-embed.php' );
require_once( AMP__VENDOR__DIR__ . '/includes/embeds/class-amp-core-block-handler.php' );

class AMP_Post_Template {
const SITE_ICON_SIZE = 32;
Expand Down Expand Up @@ -259,6 +262,7 @@ private function build_post_content() {

$amp_content = new AMP_Content( $new_post_content,
apply_filters( 'amp_content_embed_handlers', array(
'AMP_Core_Block_Handler' => array(),
'AMP_Twitter_Embed_Handler' => array(),
'AMP_YouTube_Embed_Handler' => array(),
'AMP_DailyMotion_Embed_Handler' => array(),
Expand All @@ -276,12 +280,14 @@ private function build_post_content() {
'AMP_Style_Sanitizer' => array(),
'AMP_Blacklist_Sanitizer' => array(),
'AMP_Img_Sanitizer' => array(),
'AMP_Gallery_Block_Sanitizer' => array(),
'AMP_Video_Sanitizer' => array(),
'AMP_Audio_Sanitizer' => array(),
'AMP_Playbuzz_Sanitizer' => array(),
'AMP_Iframe_Sanitizer' => array(
'add_placeholder' => true,
),
'AMP_Block_Sanitizer' => array(),
), $this->post ),
array(
'content_max_width' => $this->get( 'content_max_width' ),
Expand Down
117 changes: 117 additions & 0 deletions includes/vendor/amp/includes/embeds/class-amp-core-block-handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
namespace AMPforWP\AMPVendor;
/**
* Class AMP_Core_Block_Handler
*
*/

/**
* Class AMP_Core_Block_Handler
*
* @since 1.0
*/
class AMP_Core_Block_Handler extends AMP_Base_Embed_Handler {

/**
* Original block callback.
*
* @var array
*/
public $original_categories_callback;

/**
* Block name.
*
* @var string
*/
public $block_name = 'core/categories';

/**
* Register embed.
*/
public function register_embed() {
if ( class_exists( 'WP_Block_Type_Registry' ) ) {
$registry = \WP_Block_Type_Registry::get_instance();
$block = $registry->get_registered( $this->block_name );

if ( $block ) {
$this->original_categories_callback = $block->render_callback;
$block->render_callback = array( $this, 'render' );
}
}
}

/**
* Unregister embed.
*/
public function unregister_embed() {
if ( class_exists( 'WP_Block_Type_Registry' ) ) {
$registry = \WP_Block_Type_Registry::get_instance();
$block = $registry->get_registered( $this->block_name );

if ( $block && ! empty( $this->original_categories_callback ) ) {
$block->render_callback = $this->original_categories_callback;
$this->original_categories_callback = null;
}
}
}

/**
* Render Gutenberg block. This is essentially the same method as the original.
* Difference is excluding the disallowed JS script, adding <form> tags, and using on:change for <select>.
*
* @param array $attributes Attributes.
* @return string Rendered.
*/
public function render( $attributes ) {
static $block_id = 0;
$block_id++;

$align = 'center';
if ( isset( $attributes['align'] ) && in_array( $attributes['align'], array( 'left', 'right', 'full' ), true ) ) {
$align = $attributes['align'];
}

$args = array(
'echo' => false,
'hierarchical' => ! empty( $attributes['showHierarchy'] ),
'orderby' => 'name',
'show_count' => ! empty( $attributes['showPostCounts'] ),
'title_li' => '',
);

if ( ! empty( $attributes['displayAsDropdown'] ) ) {
$id = 'wp-block-categories-dropdown-' . $block_id;
$form_id = $id . '-form';
$args['id'] = $id;
$args['show_option_none'] = __( 'Select Category', 'amp' );
$wrapper_markup = '<div class="%1$s">%2$s</div>';
$items_markup = wp_dropdown_categories( $args );
$type = 'dropdown';

$items_markup = preg_replace(
'/(?<=<select\b)/',
sprintf( ' on="change:%s.submit"', esc_attr( $form_id ) ),
$items_markup,
1
);
} else {
$wrapper_markup = '<div class="%1$s"><ul>%2$s</ul></div>';
$items_markup = wp_list_categories( $args );
$type = 'list';
}

$class = "wp-block-categories wp-block-categories-{$type} align{$align}";

$block_content = sprintf(
$wrapper_markup,
esc_attr( $class ),
$items_markup
);

if ( ! empty( $attributes['displayAsDropdown'] ) ) {
$block_content = sprintf( '<form action="%s" method="get" target="_top" id="%s">%s</form>', esc_url( home_url() ), esc_attr( $form_id ), $block_content );
}
return $block_content;
}
}
133 changes: 133 additions & 0 deletions includes/vendor/amp/includes/sanitizers/class-amp-block-sanitizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php
namespace AMPforWP\AMPVendor;
/**
* Class AMP_Block_Sanitizer.
*
*/

/**
* Class AMP_Block_Sanitizer
*
* Modifies elements created as blocks to match the blocks' AMP-specific configuration.
*/
class AMP_Block_Sanitizer extends AMP_Base_Sanitizer {

/**
* Tag.
*
* @var string Figure tag to identify wrapper around AMP elements.
* @since 1.0
*/
public static $tag = 'figure';

/**
* Sanitize the AMP elements contained by <figure> element where necessary.
*
* @since 0.2
*/
public function sanitize() {
$nodes = $this->dom->getElementsByTagName( self::$tag );
$num_nodes = $nodes->length;
if ( 0 === $num_nodes ) {
return;
}

for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
$node = $nodes->item( $i );

// We're looking for <figure> elements that have one child node only.
if ( 1 !== count( $node->childNodes ) ) {
continue;
}

$attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );

// We are only looking for <figure> elements which have wp-block-embed as class.
if ( ! isset( $attributes['class'] ) || false === strpos( $attributes['class'], 'wp-block-embed' ) ) {
continue;
}

// We are looking for <figure> elements with layout attribute only.
if (
! isset( $attributes['data-amp-layout'] ) &&
! isset( $attributes['data-amp-noloading'] ) &&
! isset( $attributes['data-amp-lightbox'] )
) {
continue;
}

$amp_el_found = false;

foreach ( $node->childNodes as $child_node ) {

// We are looking for child elements which start with 'amp-'.
if ( 0 !== strpos( $child_node->tagName, 'amp-' ) ) {
continue;
}
$amp_el_found = true;

$this->set_attributes( $child_node, $node, $attributes );
}

if ( false === $amp_el_found ) {
continue;
}
$this->did_convert_elements = true;
}
}

/**
* Sets necessary attributes to both parent and AMP element node.
*
* @param DOMNode $node AMP element node.
* @param DOMNode $parent_node <figure> node.
* @param array $attributes Current attributes of the AMP element.
*/
protected function set_attributes( $node, $parent_node, $attributes ) {

if ( isset( $attributes['data-amp-layout'] ) ) {
$node->setAttribute( 'layout', $attributes['data-amp-layout'] );
}
if ( isset( $attributes['data-amp-noloading'] ) && true === filter_var( $attributes['data-amp-noloading'], FILTER_VALIDATE_BOOLEAN ) ) {
$node->setAttribute( 'noloading', '' );
}

$layout = $node->getAttribute( 'layout' );

// The width has to be unset / auto in case of fixed-height.
if ( 'fixed-height' === $layout ) {
if ( ! isset( $attributes['height'] ) ) {
$node->setAttribute( 'height', self::FALLBACK_HEIGHT );
}
$node->setAttribute( 'width', 'auto' );

$height = $node->getAttribute( 'height' );
if ( is_numeric( $height ) ) {
$height .= 'px';
}
$parent_node->setAttribute( 'style', "height: $height; width: auto;" );

// The parent element should have width/height set and position set in case of 'fill'.
} elseif ( 'fill' === $layout ) {
if ( ! isset( $attributes['height'] ) ) {
$attributes['height'] = self::FALLBACK_HEIGHT;
}
$parent_node->setAttribute( 'style', 'position:relative; width: 100%; height: ' . $attributes['height'] . 'px;' );
$node->removeAttribute( 'width' );
$node->removeAttribute( 'height' );
} elseif ( 'responsive' === $layout ) {
$parent_node->setAttribute( 'style', 'position:relative; width: 100%; height: auto' );
} elseif ( 'fixed' === $layout ) {
if ( ! isset( $attributes['height'] ) ) {
$node->setAttribute( 'height', self::FALLBACK_HEIGHT );
}
}

// Set the fallback layout in case needed.
$attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
$attributes = $this->set_layout( $attributes );
if ( $layout !== $attributes['layout'] ) {
$node->setAttribute( 'layout', $attributes['layout'] );
}
}
}
Loading

0 comments on commit 93147eb

Please sign in to comment.