-
Notifications
You must be signed in to change notification settings - Fork 384
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
Add sanitizer to fixup issues with core themes #1074
Changes from 11 commits
8643b8b
4692577
51eb633
fc0bea1
7f738c1
cbacd9d
f186cd9
31cb154
a36a281
f5ca657
601c005
80e2355
dc9e628
54e025a
65aec1e
a91f0e2
e47275c
d41e498
d3b8eae
d2247ff
3bb3dd8
ac98dfc
93c87eb
7b9acc6
df2e561
bca1ead
e1fc251
d55cf6a
425c80a
70d1440
2cdb1c8
1fdb325
2fc015d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -250,6 +250,14 @@ public static function register_paired_hooks() { | |
*/ | ||
public static function add_hooks() { | ||
|
||
add_filter( 'amp_content_sanitizers', function( $sanitizers ) { | ||
$sanitizers['AMP_Core_Theme_Sanitizer'] = array( | ||
'template' => get_template(), | ||
'stylesheet' => get_stylesheet(), | ||
); | ||
return $sanitizers; | ||
} ); | ||
|
||
// Remove core actions which are invalid AMP. | ||
remove_action( 'wp_head', 'wp_post_preview_js', 1 ); | ||
remove_action( 'wp_head', 'print_emoji_detection_script', 7 ); | ||
|
@@ -303,6 +311,7 @@ public static function add_hooks() { | |
add_action( 'comment_form', array( __CLASS__, 'amend_comment_form' ), 100 ); | ||
remove_action( 'comment_form', 'wp_comment_form_unfiltered_html_nonce' ); | ||
add_filter( 'wp_kses_allowed_html', array( __CLASS__, 'whitelist_layout_in_wp_kses_allowed_html' ), 10 ); | ||
add_filter( 'get_header_image_tag', array( __CLASS__, 'conditionally_output_header' ), 10, 3 ); | ||
|
||
// @todo Add character conversion. | ||
} | ||
|
@@ -1243,4 +1252,112 @@ public static function enqueue_assets() { | |
// Enqueue default styles expected by sanitizer. | ||
wp_enqueue_style( 'amp-default', amp_get_asset_url( 'css/amp-default.css' ), array(), AMP__VERSION ); | ||
} | ||
|
||
/** | ||
* Conditionally replace the header image markup with a header video or image. | ||
* | ||
* This is JS-driven in Core themes like Twenty Sixteen and Twenty Seventeen. | ||
* So in order for the header video to display, | ||
* this replaces the markup of the header image. | ||
* | ||
* @since 1.0 | ||
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L54 | ||
* @param string $html The image markup to filter. | ||
* @param array $header The header config array. | ||
* @param array $atts The image markup attributes. | ||
* @return string $html Filtered markup. | ||
*/ | ||
public static function conditionally_output_header( $html, $header, $atts ) { | ||
if ( ! is_header_video_active() ) { | ||
return $html; | ||
}; | ||
|
||
if ( ! has_header_video() ) { | ||
return self::output_header_image( $atts ); | ||
} | ||
|
||
return self::output_header_video( $atts ); | ||
} | ||
|
||
/** | ||
* Replace the header image markup with a header video. | ||
* | ||
* This is JS-driven in Core themes like Twenty Sixteen and Twenty Seventeen. | ||
* So in order for the header video to display, | ||
* this replaces the markup of the header image. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't a blocker, but maybe this 3-line DocBlock description could be removed. It looks to be the same as in |
||
* | ||
* @since 1.0 | ||
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L54 | ||
* @param array $atts The header tag attributes array. | ||
* @return string $html Filtered markup. | ||
*/ | ||
public static function output_header_video( $atts ) { | ||
// Remove the script for video. | ||
wp_deregister_script( 'wp-custom-header' ); | ||
$video_settings = get_header_video_settings(); | ||
|
||
$parsed_url = wp_parse_url( $video_settings['videoUrl'] ); | ||
$query = isset( $parsed_url['query'] ) ? wp_parse_args( $parsed_url['query'] ) : null; | ||
$video_attributes = array( | ||
'media' => '(min-width: ' . $video_settings['minWidth'] . 'px)', | ||
'width' => $video_settings['width'], | ||
'height' => $video_settings['height'], | ||
'layout' => 'fill', | ||
'autoplay' => '', | ||
'id' => 'wp-custom-header-video', | ||
); | ||
|
||
$atts['placeholder'] = ''; | ||
$image_placeholder = self::output_header_image( $atts ); | ||
|
||
// If the video URL is for YouTube, return an <amp-youtube> element. | ||
if ( isset( $parsed_url['host'], $query['v'] ) && ( false !== strpos( $parsed_url['host'], 'youtube' ) ) ) { | ||
$video_header = AMP_HTML_Utils::build_tag( | ||
'amp-youtube', | ||
array_merge( | ||
$video_attributes, | ||
array( | ||
'data-videoid' => $query['v'], | ||
'data-param-rel' => '0', // Don't show related videos. | ||
'data-param-showinfo' => '0', // Don't show video title at the top. | ||
'data-param-controls' => '0', // Don't show video controls. | ||
) | ||
) | ||
); | ||
} else { | ||
$video_header = AMP_HTML_Utils::build_tag( | ||
'amp-video', | ||
array_merge( | ||
$video_attributes, | ||
array( | ||
'src' => $video_settings['videoUrl'], | ||
) | ||
) | ||
); | ||
} | ||
return $image_placeholder . $video_header; | ||
} | ||
|
||
/** | ||
* Replace the header image markup with a header image. | ||
* | ||
* This is JS-driven in Core themes like Twenty Sixteen and Twenty Seventeen. | ||
* So in order for the header video to display, | ||
* this replaces the markup of the header image. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the suggestion above, maybe these 3 lines could be removed. |
||
* | ||
* @since 1.0 | ||
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L54 | ||
* @param array $atts The image tag attributes. | ||
* @return string $html Filtered markup. | ||
*/ | ||
public static function output_header_image( $atts ) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't a blocker, but this might be cleaner as: public static function output_header_image( $atts ) {
return AMP_HTML_Utils::build_tag( 'amp-img', $atts );
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I'm going to just remove the method entirely. There's no need for it. |
||
$atts['layout'] = 'fill'; | ||
unset( $atts['width'] ); | ||
|
||
$place_holder = AMP_HTML_Utils::build_tag( 'img', $atts ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, sorry, it was, I removed it for testing something, but forgot to revert 601c005 |
||
|
||
return $place_holder; | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be great to eventually go back and add tests for this class, and other new methods. |
||
/** | ||
* Class AMP_Core_Theme_Sanitizer. | ||
* | ||
* @package AMP | ||
* @since 1.0 | ||
*/ | ||
|
||
/** | ||
* Class AMP_Core_Theme_Sanitizer | ||
* | ||
* Fixes up common issues in core themes and others. | ||
* | ||
* @since 1.0 | ||
*/ | ||
class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer { | ||
|
||
/** | ||
* Config for features needed by themes. | ||
* | ||
* @var array | ||
*/ | ||
public $theme_features = array( | ||
'twentyseventeen' => array( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a great idea to pass an array of arguments to each of the methods, depending on the theme. |
||
'force_svg_support' => array(), | ||
'force_fixed_background_support' => array(), | ||
// @todo Header video probably needs special support in the plugin generally. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #1078 |
||
// @todo Header image is not styled properly. Needs layout=responsive and other things? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #1094 (comment) |
||
// @todo Dequeue scripts and replace with AMP functionality where possible. | ||
), | ||
); | ||
|
||
/** | ||
* Fix up core themes to do things in the AMP way. | ||
* | ||
* @since 1.0 | ||
*/ | ||
public function sanitize() { | ||
$theme_features = array(); | ||
|
||
// Find theme features for core theme. | ||
$theme_candidates = wp_array_slice_assoc( $this->args, array( 'stylesheet', 'template' ) ); | ||
foreach ( $theme_candidates as $theme_candidate ) { | ||
if ( isset( $this->theme_features[ $theme_candidate ] ) ) { | ||
$theme_features = $this->theme_features[ $theme_candidate ]; | ||
break; | ||
} | ||
} | ||
|
||
// Allow specific theme features to be requested even if the theme is not in core. | ||
if ( isset( $this->args['theme_features'] ) ) { | ||
$theme_features = array_merge( $this->args['theme_features'], $theme_features ); | ||
} | ||
|
||
foreach ( $theme_features as $theme_feature => $feature_args ) { | ||
if ( method_exists( $this, $theme_feature ) ) { | ||
call_user_func( array( $this, $theme_feature ), $feature_args ); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Force SVG support, replacing no-svg class name with svg class name. | ||
* | ||
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/assets/js/global.js#L211-L213 | ||
* @link https://caniuse.com/#feat=svg | ||
*/ | ||
public function force_svg_support() { | ||
$this->dom->documentElement->setAttribute( | ||
'class', | ||
preg_replace( | ||
'/(^|\s)no-svg(\s|$)/', | ||
' svg ', | ||
$this->dom->documentElement->getAttribute( 'class' ) | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* Force support for fixed background-attachment. | ||
* | ||
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/assets/js/global.js#L215-L217 | ||
* @link https://caniuse.com/#feat=background-attachment | ||
*/ | ||
public function force_fixed_background_support() { | ||
$this->dom->documentElement->setAttribute( | ||
'class', | ||
$this->dom->documentElement->getAttribute( 'class' ) . ' background-fixed' | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice use of these helper functions to simplify
conditionally_output_header()