Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions assets/src/admin/paired-browsing/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { addQueryArgs, hasQueryArg, removeQueryArgs } from '@wordpress/url';
import './app.css';

const { app, history } = window;
const { ampSlug, ampPairedBrowsingQueryVar, ampValidationErrorsQueryVar, documentTitlePrefix } = app;
const { ampSlug, ampRuntimeScriptSrc, ampPairedBrowsingQueryVar, ampValidationErrorsQueryVar, documentTitlePrefix } = app;

class PairedBrowsingApp {
/**
Expand Down Expand Up @@ -119,7 +119,7 @@ class PairedBrowsingApp {
* @return {boolean} True if AMP compatible, false if not.
*/
documentIsAmp( doc ) {
return doc.querySelector( 'head > script[src="https://cdn.ampproject.org/v0.js"]' );
return doc.querySelector( `head > script[src="${ampRuntimeScriptSrc}"]` );
}

/**
Expand Down
32 changes: 26 additions & 6 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -421,42 +421,60 @@ function amp_register_default_scripts( $wp_scripts ) {
}
}

/**
* Filters whether to use the LTS release channel.
*
* @since 1.5
*
* @param bool $use_lts Whether to use the LTS release channel. Defaults to false (so the stable channel is used).
*/
$lts_release_channel = apply_filters( 'amp_lts_release_channel', false );

if ( $lts_release_channel ) {
$base_url = 'https://cdn.ampproject.org/lts';
} else {
$base_url = 'https://cdn.ampproject.org';
}

// AMP Runtime.
$handle = 'amp-runtime';
$wp_scripts->add(
$handle,
'https://cdn.ampproject.org/v0.js',
$base_url . '/v0.js',
[],
null
);
$wp_scripts->add_data(
$handle,
'amp_script_attributes',
[
'async' => true,
'async' => true,
'crossorigin' => 'anonymous',
]
);

// Shadow AMP API.
$handle = 'amp-shadow';
$wp_scripts->add(
$handle,
'https://cdn.ampproject.org/shadow-v0.js',
$base_url . '/shadow-v0.js',
[],
null
);
$wp_scripts->add_data(
$handle,
'amp_script_attributes',
[
'async' => true,
'async' => true,
'crossorigin' => 'anonymous',
]
);

// Register all AMP components as defined in the spec.
foreach ( AMP_Allowed_Tags_Generated::get_extension_specs() as $extension_name => $extension_spec ) {
$src = sprintf(
'https://cdn.ampproject.org/v0/%s-%s.js',
'%s/v0/%s-%s.js',
$base_url,
$extension_name,
end( $extension_spec['version'] )
);
Expand Down Expand Up @@ -537,9 +555,11 @@ function amp_filter_script_loader_tag( $tag, $handle ) {
/*
* All scripts from AMP CDN should be loaded async.
* See <https://www.ampproject.org/docs/integration/pwa-amp/amp-in-pwa#include-"shadow-amp"-in-your-progressive-web-app>.
* For crossorigin=anonymous, see <https://github.com/ampproject/amphtml/issues/24731>.
*/
$attributes = [
'async' => true,
'async' => true,
'crossorigin' => 'anonymous',
];

// Add custom-template and custom-element attributes. All component scripts look like https://cdn.ampproject.org/v0/:name-:version.js.
Expand Down
26 changes: 16 additions & 10 deletions includes/class-amp-theme-support.php
Original file line number Diff line number Diff line change
Expand Up @@ -1626,8 +1626,9 @@ public static function ensure_required_markup( Document $dom, $script_handles =
$dom,
Tag::LINK,
[
Attribute::REL => Attribute::REL_PRECONNECT,
Attribute::HREF => 'https://cdn.ampproject.org',
Attribute::REL => Attribute::REL_PRECONNECT,
Attribute::HREF => 'https://cdn.ampproject.org',
Attribute::CROSSORIGIN => Attribute::CROSSORIGIN_ANONYMOUS,
]
),
],
Expand Down Expand Up @@ -1696,8 +1697,9 @@ public static function ensure_required_markup( Document $dom, $script_handles =
continue;
}
$attrs = [
Attribute::SRC => wp_scripts()->registered[ $missing_script_handle ]->src,
Attribute::ASYNC => '',
Attribute::SRC => wp_scripts()->registered[ $missing_script_handle ]->src,
Attribute::ASYNC => '',
Attribute::CROSSORIGIN => Attribute::CROSSORIGIN_ANONYMOUS,
];
if ( Extension::MUSTACHE === $missing_script_handle ) {
$attrs[ Attribute::CUSTOM_TEMPLATE ] = $missing_script_handle;
Expand Down Expand Up @@ -1736,9 +1738,10 @@ public static function ensure_required_markup( Document $dom, $script_handles =
$dom,
Tag::LINK,
[
Attribute::REL => Attribute::REL_PRELOAD,
'as' => Tag::SCRIPT,
Attribute::HREF => $runtime_src,
Attribute::REL => Attribute::REL_PRELOAD,
'as' => Tag::SCRIPT,
Attribute::HREF => $runtime_src,
Attribute::CROSSORIGIN => Attribute::CROSSORIGIN_ANONYMOUS,
]
);

Expand All @@ -1755,9 +1758,10 @@ public static function ensure_required_markup( Document $dom, $script_handles =
$dom,
Tag::LINK,
[
Attribute::REL => Attribute::REL_PRELOAD,
'as' => Tag::SCRIPT,
Attribute::HREF => $amp_scripts[ $script_handle ]->getAttribute( Attribute::SRC ),
Attribute::REL => Attribute::REL_PRELOAD,
'as' => Tag::SCRIPT,
Attribute::HREF => $amp_scripts[ $script_handle ]->getAttribute( Attribute::SRC ),
Attribute::CROSSORIGIN => Attribute::CROSSORIGIN_ANONYMOUS,
]
);
}
Expand Down Expand Up @@ -1791,6 +1795,7 @@ public static function ensure_required_markup( Document $dom, $script_handles =
$script = $dom->createElement( Tag::SCRIPT );
$script->setAttribute( Attribute::ASYNC, '' );
$script->setAttribute( Attribute::SRC, $runtime_src );
$script->setAttribute( Attribute::CROSSORIGIN, Attribute::CROSSORIGIN_ANONYMOUS );
$ordered_scripts[ Amp::RUNTIME ] = $script;
}

Expand Down Expand Up @@ -2382,6 +2387,7 @@ public static function serve_paired_browsing_experience( $template ) {
'ampPairedBrowsingQueryVar' => self::PAIRED_BROWSING_QUERY_VAR,
'ampValidationErrorsQueryVar' => AMP_Validation_Manager::VALIDATION_ERRORS_QUERY_VAR,
'documentTitlePrefix' => __( 'AMP Paired Browsing:', 'amp' ),
'ampRuntimeScriptSrc' => wp_scripts()->registered['amp-runtime']->src,
]
);

Expand Down
2 changes: 1 addition & 1 deletion includes/sanitizers/class-amp-style-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ private function process_link_element( DOMElement $element ) {
[
'rel' => 'preconnect',
'href' => 'https://fonts.gstatic.com/',
'crossorigin' => '',
'crossorigin' => 'anonymous',
]
);
$this->dom->head->insertBefore( $link ); // Note that \AMP_Theme_Support::ensure_required_markup() will put this in the optimal order.
Expand Down
3 changes: 3 additions & 0 deletions lib/common/src/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface Attribute
const CHARSET = 'charset';
const CLASS_ = 'class'; // Underscore needed because 'class' is a PHP keyword.
const CONTENT = 'content';
const CROSSORIGIN = 'crossorigin';
const CUSTOM_ELEMENT = 'custom-element';
const CUSTOM_TEMPLATE = 'custom-template';
const HEIGHT = 'height';
Expand Down Expand Up @@ -71,4 +72,6 @@ interface Attribute
const REL_PRELOAD = 'preload';
const REL_PRERENDER = 'prerender';
const REL_STYLESHEET = 'stylesheet';

const CROSSORIGIN_ANONYMOUS = 'anonymous';
}
12 changes: 6 additions & 6 deletions tests/php/test-amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -723,9 +723,9 @@ public function test_script_registering() {

$output = get_echo( 'wp_print_scripts' );

$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0.js\' async></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-mathml-0.1.js\' async custom-element="amp-mathml"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-mustache-latest.js\' async custom-template="amp-mustache"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0.js\' async crossorigin="anonymous"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-mathml-0.1.js\' async crossorigin="anonymous" custom-element="amp-mathml"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-mustache-latest.js\' async crossorigin="anonymous" custom-template="amp-mustache"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript

// Try rendering via amp_render_scripts() instead of amp_render_scripts(), which is how component scripts get added normally.
$output = amp_render_scripts(
Expand All @@ -736,13 +736,13 @@ public function test_script_registering() {
]
);
$this->assertNotContains( 'amp-mathml', $output, 'The amp-mathml component was already printed above.' );
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-mustache-2.0.js\' async custom-element="amp-carousel"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-accordion-0.1.js\' async custom-element="amp-accordion"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-mustache-2.0.js\' async crossorigin="anonymous" custom-element="amp-carousel"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-accordion-0.1.js\' async crossorigin="anonymous" custom-element="amp-accordion"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript

// Try some experimental component to ensure expected script attributes are added.
wp_register_script( 'amp-foo', 'https://cdn.ampproject.org/v0/amp-foo-0.1.js', [ 'amp-runtime' ], null ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NotInFooter, WordPress.WP.EnqueuedResourceParameters.MissingVersion
$output = get_echo( 'wp_print_scripts', [ 'amp-foo' ] );
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-foo-0.1.js\' async custom-element="amp-foo"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type=\'text/javascript\' src=\'https://cdn.ampproject.org/v0/amp-foo-0.1.js\' async crossorigin="anonymous" custom-element="amp-foo"></script>', $output ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
}

/**
Expand Down
24 changes: 12 additions & 12 deletions tests/php/test-class-amp-theme-support.php
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ public function test_validate_non_amp_theme() {
$this->assertContains( '<meta name="viewport" content="maximum-scale=1.0,width=device-width">', $sanitized_html );

// MathML script was added.
$this->assertContains( '<script type="text/javascript" src="https://cdn.ampproject.org/v0/amp-mathml-0.1.js" async custom-element="amp-mathml"></script>', $sanitized_html ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$this->assertContains( '<script type="text/javascript" src="https://cdn.ampproject.org/v0/amp-mathml-0.1.js" async crossorigin="anonymous" custom-element="amp-mathml"></script>', $sanitized_html ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
}

/**
Expand Down Expand Up @@ -1981,21 +1981,21 @@ static function ( $url ) {
'<meta name="viewport" content="width=device-width">',
'<meta name="generator" content="AMP Plugin',
'<title>',
'<link rel="preconnect" href="https://cdn.ampproject.org">',
'<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin="">',
'<link rel="preconnect" href="https://cdn.ampproject.org" crossorigin="anonymous">',
'<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin="anonymous">',
'<link rel="dns-prefetch" href="//cdn.ampproject.org">',
'<link rel="preload" as="script" href="https://cdn.ampproject.org/v0.js">',
'<link rel="preload" as="script" href="https://cdn.ampproject.org/v0/amp-dynamic-css-classes-0.1.js">',
'<link rel="preload" as="script" href="https://cdn.ampproject.org/v0/amp-experiment-1.0.js">',
'<script type="text/javascript" src="https://cdn.ampproject.org/v0.js" async></script>',
'<link rel="preload" as="script" href="https://cdn.ampproject.org/v0.js" crossorigin="anonymous">',
'<link rel="preload" as="script" href="https://cdn.ampproject.org/v0/amp-dynamic-css-classes-0.1.js" crossorigin="anonymous">',
'<link rel="preload" as="script" href="https://cdn.ampproject.org/v0/amp-experiment-1.0.js" crossorigin="anonymous">',
'<script type="text/javascript" src="https://cdn.ampproject.org/v0.js" async crossorigin="anonymous"></script>',

'<script async custom-element="amp-dynamic-css-classes" src="https://cdn.ampproject.org/v0/amp-dynamic-css-classes-0.1.js"></script>',
'<script src="https://cdn.ampproject.org/v0/amp-experiment-1.0.js" async="" custom-element="amp-experiment"></script>',
'<script src="https://cdn.ampproject.org/v0/amp-experiment-1.0.js" async="" crossorigin="anonymous" custom-element="amp-experiment"></script>',

'#<script( type=[\'"]text/javascript[\'"])? src=[\'"]https\://cdn\.ampproject\.org/v0/amp-ad-0\.1\.js[\'"] async(=[\'"][\'"])? custom-element=[\'"]amp-ad[\'"]>\s*</script>#s',
'#<script src=[\'"]https\://cdn\.ampproject\.org/v0/amp-audio-0\.1\.js[\'"] async(=[\'"][\'"])? custom-element=[\'"]amp-audio[\'"]>\s*</script>#s',
'<script type="text/javascript" src="https://cdn.ampproject.org/v0/amp-list-0.1.js" async custom-element="amp-list"></script>',
'<script type="text/javascript" src="https://cdn.ampproject.org/v0/amp-mathml-0.1.js" async custom-element="amp-mathml"></script>',
'#<script( type=[\'"]text/javascript[\'"])? src=[\'"]https\://cdn\.ampproject\.org/v0/amp-ad-0\.1\.js[\'"] async(=[\'"][\'"])? crossorigin=[\'"]anonymous[\'"] custom-element=[\'"]amp-ad[\'"]>\s*</script>#s',
'#<script src=[\'"]https\://cdn\.ampproject\.org/v0/amp-audio-0\.1\.js[\'"] async(=[\'"][\'"])? crossorigin=[\'"]anonymous[\'"] custom-element=[\'"]amp-audio[\'"]>\s*</script>#s',
'<script type="text/javascript" src="https://cdn.ampproject.org/v0/amp-list-0.1.js" async crossorigin="anonymous" custom-element="amp-list"></script>',
'<script type="text/javascript" src="https://cdn.ampproject.org/v0/amp-mathml-0.1.js" async crossorigin="anonymous" custom-element="amp-mathml"></script>',

'<link rel="icon" href="https://example.org/favicon.png" sizes="32x32">',
'<link rel="icon" href="https://example.org/favicon.png" sizes="192x192">',
Expand Down