Last active
April 20, 2018 00:25
-
-
Save westonruter/f272303fc4bf2d5d71fe1bd88a5fcee3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: AMP Content Styles Workaround | |
* Description: Temporary measure for dealing with external stylesheets and style elements in content. | |
* Author: Weston Ruter, XWP | |
*/ | |
add_action( 'amp_init', function() { | |
// Version compare because this should be addressed by 1.0. | |
if ( version_compare( AMP__VERSION, '1.0', '>=' ) ) { | |
return; | |
} | |
add_filter( 'amp_content_sanitizers', function( $sanitizers ) { | |
return array_merge( | |
array( | |
'My_AMP_Internalize_External_CSS_Sanitizer' => array(), | |
), | |
$sanitizers | |
); | |
} ); | |
class My_AMP_Internalize_External_CSS_Sanitizer extends AMP_Base_Sanitizer { | |
public function sanitize() { | |
$xpath = new DOMXPath( $this->dom ); | |
$lower_case = 'translate( %s, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" )'; // In XPath 2.0 this is lower-case(). | |
$predicates = array( | |
sprintf( '( self::link and @href and %s = "stylesheet" )', sprintf( $lower_case, '@rel' ) ), | |
); | |
if ( ! current_theme_supports( 'amp' ) ) { | |
$predicates[] = sprintf( '( self::style and ( not( @type ) or %s = "text/css" ) )', sprintf( $lower_case, '@type' ) ); | |
} | |
$elements = array(); | |
foreach ( $xpath->query( '//*[ ' . implode( ' or ', $predicates ) . ' ]' ) as $element ) { | |
$elements[] = $element; | |
} | |
$css = ''; | |
foreach ( $elements as $element ) { | |
if ( 'style' === $element->nodeName ) { | |
$css .= $element->textContent; | |
} elseif ( 'link' === $element->nodeName ) { | |
$href = $element->getAttribute( 'href' ); | |
if ( ! preg_match( '#^(https?:)?//#', $href, $matches ) ) { | |
continue; | |
} | |
if ( empty( $matches[1] ) ) { | |
$href = ( is_ssl() ? 'https' : 'http' ) . ':' . $href; | |
} | |
$cache_key = md5( $href ); | |
$contents = get_transient( $cache_key ); | |
if ( false === $contents ) { | |
$r = wp_remote_get( $href ); | |
if ( 200 !== wp_remote_retrieve_response_code( $r ) ) { | |
$contents = new WP_Error( wp_remote_retrieve_response_code( $r ) ); | |
} else { | |
$contents = wp_remote_retrieve_body( $r ); | |
} | |
set_transient( $cache_key, $contents, MONTH_IN_SECONDS ); | |
} | |
if ( ! is_wp_error( $contents ) ) { | |
$css .= $contents; | |
} | |
} | |
$element->parentNode->removeChild( $element ); | |
} | |
if ( empty( $css ) ) { | |
return; | |
} | |
if ( current_theme_supports( 'amp' ) ) { | |
$style = $this->dom->createElement( 'style' ); | |
$style->setAttribute( 'type', 'text/css' ); | |
$style->appendChild( $this->dom->createTextNode( $css ) ); | |
$head = $this->dom->getElementsByTagName( 'head' )->item( 0 ); | |
if ( $head ) { | |
$head->appendChild( $style ); | |
} | |
} else { | |
add_action( 'amp_post_template_css', function() use ( $css ) { | |
echo $css; | |
} ); | |
} | |
} | |
} | |
} ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment