Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@westonruter
Last active April 20, 2018 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westonruter/f272303fc4bf2d5d71fe1bd88a5fcee3 to your computer and use it in GitHub Desktop.
Save westonruter/f272303fc4bf2d5d71fe1bd88a5fcee3 to your computer and use it in GitHub Desktop.
<?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