Skip to content

Commit 76e1657

Browse files
authored
Merge pull request #1074 from Automattic/core-themes
Add sanitizer to fixup issues with core themes; add header video support
2 parents c8d56ed + 2fc015d commit 76e1657

10 files changed

+1145
-3
lines changed

includes/amp-helper-functions.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,10 @@ function amp_get_content_sanitizers( $post = null ) {
524524
*/
525525
$sanitizers = apply_filters( 'amp_content_sanitizers',
526526
array(
527+
'AMP_Core_Theme_Sanitizer' => array(
528+
'template' => get_template(),
529+
'stylesheet' => get_stylesheet(),
530+
),
527531
'AMP_Img_Sanitizer' => array(),
528532
'AMP_Form_Sanitizer' => array(),
529533
'AMP_Comments_Sanitizer' => array(),

includes/class-amp-autoloader.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class AMP_Autoloader {
8282
'AMP_Style_Sanitizer' => 'includes/sanitizers/class-amp-style-sanitizer',
8383
'AMP_Tag_And_Attribute_Sanitizer' => 'includes/sanitizers/class-amp-tag-and-attribute-sanitizer',
8484
'AMP_Video_Sanitizer' => 'includes/sanitizers/class-amp-video-sanitizer',
85+
'AMP_Core_Theme_Sanitizer' => 'includes/sanitizers/class-amp-core-theme-sanitizer',
8586
'AMP_Customizer_Design_Settings' => 'includes/settings/class-amp-customizer-design-settings',
8687
'AMP_Customizer_Settings' => 'includes/settings/class-amp-customizer-settings',
8788
'AMP_Content' => 'includes/templates/class-amp-content',

includes/class-amp-theme-support.php

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ public static function finish_init() {
159159
self::$sanitizer_classes = amp_get_content_sanitizers();
160160
self::$sanitizer_classes = AMP_Validation_Manager::filter_sanitizer_args( self::$sanitizer_classes );
161161
self::$embed_handlers = self::register_content_embed_handlers();
162+
163+
foreach ( self::$sanitizer_classes as $sanitizer_class => $args ) {
164+
if ( method_exists( $sanitizer_class, 'add_buffering_hooks' ) ) {
165+
call_user_func( array( $sanitizer_class, 'add_buffering_hooks' ), $args );
166+
}
167+
}
162168
}
163169

164170
/**
@@ -303,6 +309,10 @@ public static function add_hooks() {
303309
add_action( 'comment_form', array( __CLASS__, 'amend_comment_form' ), 100 );
304310
remove_action( 'comment_form', 'wp_comment_form_unfiltered_html_nonce' );
305311
add_filter( 'wp_kses_allowed_html', array( __CLASS__, 'whitelist_layout_in_wp_kses_allowed_html' ), 10 );
312+
add_filter( 'get_header_image_tag', array( __CLASS__, 'conditionally_output_header' ), 10, 3 );
313+
add_action( 'wp_enqueue_scripts', function() {
314+
wp_dequeue_script( 'comment-reply' ); // Handled largely by AMP_Comments_Sanitizer and *reply* methods in this class.
315+
} );
306316

307317
// @todo Add character conversion.
308318
}
@@ -1264,4 +1274,89 @@ public static function enqueue_assets() {
12641274
// Enqueue default styles expected by sanitizer.
12651275
wp_enqueue_style( 'amp-default', amp_get_asset_url( 'css/amp-default.css' ), array(), AMP__VERSION );
12661276
}
1277+
1278+
/**
1279+
* Conditionally replace the header image markup with a header video or image.
1280+
*
1281+
* This is JS-driven in Core themes like Twenty Sixteen and Twenty Seventeen.
1282+
* So in order for the header video to display,
1283+
* this replaces the markup of the header image.
1284+
*
1285+
* @since 1.0
1286+
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L54
1287+
* @param string $html The image markup to filter.
1288+
* @param array $header The header config array.
1289+
* @param array $atts The image markup attributes.
1290+
* @return string $html Filtered markup.
1291+
*/
1292+
public static function conditionally_output_header( $html, $header, $atts ) {
1293+
unset( $header );
1294+
if ( ! is_header_video_active() ) {
1295+
return $html;
1296+
};
1297+
1298+
if ( ! has_header_video() ) {
1299+
return AMP_HTML_Utils::build_tag( 'amp-img', $atts );
1300+
}
1301+
1302+
return self::output_header_video( $atts );
1303+
}
1304+
1305+
/**
1306+
* Replace the header image markup with a header video.
1307+
*
1308+
* @since 1.0
1309+
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L54
1310+
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L78
1311+
*
1312+
* @param array $atts The header tag attributes array.
1313+
* @return string $html Filtered markup.
1314+
*/
1315+
public static function output_header_video( $atts ) {
1316+
// Remove the script for video.
1317+
wp_deregister_script( 'wp-custom-header' );
1318+
$video_settings = get_header_video_settings();
1319+
1320+
$parsed_url = wp_parse_url( $video_settings['videoUrl'] );
1321+
$query = isset( $parsed_url['query'] ) ? wp_parse_args( $parsed_url['query'] ) : null;
1322+
$video_attributes = array(
1323+
'media' => '(min-width: ' . $video_settings['minWidth'] . 'px)',
1324+
'width' => $video_settings['width'],
1325+
'height' => $video_settings['height'],
1326+
'layout' => 'responsive',
1327+
'autoplay' => '',
1328+
'id' => 'wp-custom-header-video',
1329+
);
1330+
1331+
// Create image banner to stay behind the video.
1332+
$image_header = AMP_HTML_Utils::build_tag( 'amp-img', $atts );
1333+
1334+
// If the video URL is for YouTube, return an <amp-youtube> element.
1335+
if ( isset( $parsed_url['host'], $query['v'] ) && ( false !== strpos( $parsed_url['host'], 'youtube' ) ) ) {
1336+
$video_header = AMP_HTML_Utils::build_tag(
1337+
'amp-youtube',
1338+
array_merge(
1339+
$video_attributes,
1340+
array(
1341+
'data-videoid' => $query['v'],
1342+
'data-param-rel' => '0', // Don't show related videos.
1343+
'data-param-showinfo' => '0', // Don't show video title at the top.
1344+
'data-param-controls' => '0', // Don't show video controls.
1345+
)
1346+
)
1347+
);
1348+
} else {
1349+
$video_header = AMP_HTML_Utils::build_tag(
1350+
'amp-video',
1351+
array_merge(
1352+
$video_attributes,
1353+
array(
1354+
'src' => $video_settings['videoUrl'],
1355+
)
1356+
)
1357+
);
1358+
}
1359+
1360+
return $image_header . $video_header;
1361+
}
12671362
}

includes/sanitizers/class-amp-base-sanitizer.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,22 @@ public function __construct( $dom, $args = array() ) {
121121
}
122122
}
123123

124+
/**
125+
* Add filters to manipulate output during output buffering before the DOM is constructed.
126+
*
127+
* Add actions and filters before the page is rendered so that the sanitizer can fix issues during output buffering.
128+
* This provides an alternative to manipulating the DOM in the sanitize method. This is a static function because
129+
* it is invoked before the class is instantiated, as the DOM is not available yet. This method is only called
130+
* when 'amp' theme support is present. It is conceptually similar to the AMP_Base_Embed_Handler class's register_embed
131+
* method.
132+
*
133+
* @since 1.0
134+
* @see \AMP_Base_Embed_Handler::register_embed()
135+
*
136+
* @param array $args Args.
137+
*/
138+
public static function add_buffering_hooks( $args = array() ) {}
139+
124140
/**
125141
* Get mapping of HTML selectors to the AMP component selectors which they may be converted into.
126142
*

0 commit comments

Comments
 (0)