AMP for WordPress - Version 1.5.3

Version Description

Download this release

Release Info

Developer westonruter
Plugin Icon 128x128 AMP for WordPress
Version 1.5.3
Comparing to
See all releases

Code changes from version 1.5.2 to 1.5.3

amp.php CHANGED
@@ -5,17 +5,19 @@
5
  * Plugin URI: https://amp-wp.org
6
  * Author: AMP Project Contributors
7
  * Author URI: https://github.com/ampproject/amp-wp/graphs/contributors
8
- * Version: 1.5.2
9
  * Text Domain: amp
10
  * Domain Path: /languages/
11
  * License: GPLv2 or later
 
 
12
  *
13
  * @package AMP
14
  */
15
 
16
  define( 'AMP__FILE__', __FILE__ );
17
  define( 'AMP__DIR__', dirname( __FILE__ ) );
18
- define( 'AMP__VERSION', '1.5.2' );
19
 
20
  /**
21
  * Errors encountered while loading the plugin.
5
  * Plugin URI: https://amp-wp.org
6
  * Author: AMP Project Contributors
7
  * Author URI: https://github.com/ampproject/amp-wp/graphs/contributors
8
+ * Version: 1.5.3
9
  * Text Domain: amp
10
  * Domain Path: /languages/
11
  * License: GPLv2 or later
12
+ * Requires at least: 4.9
13
+ * Requires PHP: 5.6
14
  *
15
  * @package AMP
16
  */
17
 
18
  define( 'AMP__FILE__', __FILE__ );
19
  define( 'AMP__DIR__', dirname( __FILE__ ) );
20
+ define( 'AMP__VERSION', '1.5.3' );
21
 
22
  /**
23
  * Errors encountered while loading the plugin.
includes/amp-helper-functions.php CHANGED
@@ -124,7 +124,7 @@ function amp_init() {
124
  */
125
  $options = get_option( AMP_Options_Manager::OPTION_NAME, [] );
126
  $old_version = isset( $options['version'] ) ? $options['version'] : '0.0';
127
- if ( AMP__VERSION !== $old_version ) {
128
  /**
129
  * Triggers when after amp_init when the plugin version has updated.
130
  *
@@ -1220,6 +1220,7 @@ function amp_get_content_sanitizers( $post = null ) {
1220
  'AMP_Style_Sanitizer' => [],
1221
  'AMP_Meta_Sanitizer' => [],
1222
  'AMP_Layout_Sanitizer' => [],
 
1223
  'AMP_Tag_And_Attribute_Sanitizer' => [], // Note: This whitelist sanitizer must come at the end to clean up any remaining issues the other sanitizers didn't catch.
1224
  ];
1225
 
124
  */
125
  $options = get_option( AMP_Options_Manager::OPTION_NAME, [] );
126
  $old_version = isset( $options['version'] ) ? $options['version'] : '0.0';
127
+ if ( AMP__VERSION !== $old_version && is_admin() && current_user_can( 'manage_options' ) ) {
128
  /**
129
  * Triggers when after amp_init when the plugin version has updated.
130
  *
1220
  'AMP_Style_Sanitizer' => [],
1221
  'AMP_Meta_Sanitizer' => [],
1222
  'AMP_Layout_Sanitizer' => [],
1223
+ 'AMP_Accessibility_Sanitizer' => [],
1224
  'AMP_Tag_And_Attribute_Sanitizer' => [], // Note: This whitelist sanitizer must come at the end to clean up any remaining issues the other sanitizers didn't catch.
1225
  ];
1226
 
includes/class-amp-theme-support.php CHANGED
@@ -2023,6 +2023,7 @@ class AMP_Theme_Support {
2023
 
2024
  // Respond early with results if performing a validate request.
2025
  if ( AMP_Validation_Manager::$is_validate_request ) {
 
2026
  header( 'Content-Type: application/json; charset=utf-8' );
2027
  return wp_json_encode(
2028
  AMP_Validation_Manager::get_validate_response_data( $sanitization_results ),
2023
 
2024
  // Respond early with results if performing a validate request.
2025
  if ( AMP_Validation_Manager::$is_validate_request ) {
2026
+ status_header( 200 );
2027
  header( 'Content-Type: application/json; charset=utf-8' );
2028
  return wp_json_encode(
2029
  AMP_Validation_Manager::get_validate_response_data( $sanitization_results ),
includes/options/class-amp-options-manager.php CHANGED
@@ -5,6 +5,8 @@
5
  * @package AMP
6
  */
7
 
 
 
8
  /**
9
  * Class AMP_Options_Manager
10
  */
@@ -262,6 +264,12 @@ class AMP_Options_Manager {
262
  }
263
  }
264
 
 
 
 
 
 
 
265
  // Store the current version with the options so we know the format.
266
  $options['version'] = AMP__VERSION;
267
 
5
  * @package AMP
6
  */
7
 
8
+ use AmpProject\AmpWP\Option;
9
+
10
  /**
11
  * Class AMP_Options_Manager
12
  */
264
  }
265
  }
266
 
267
+ if ( array_key_exists( Option::DISABLE_CSS_TRANSIENT_CACHING, $new_options ) && true === $new_options[ Option::DISABLE_CSS_TRANSIENT_CACHING ] ) {
268
+ $options[ Option::DISABLE_CSS_TRANSIENT_CACHING ] = true;
269
+ } else {
270
+ unset( $options[ Option::DISABLE_CSS_TRANSIENT_CACHING ] );
271
+ }
272
+
273
  // Store the current version with the options so we know the format.
274
  $options['version'] = AMP__VERSION;
275
 
includes/sanitizers/class-amp-accessibility-sanitizer.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class AMP_Accessibility_Sanitizer.
4
+ *
5
+ * @package AmpProject\AmpWP
6
+ */
7
+
8
+ use AmpProject\Attribute;
9
+ use AmpProject\Role;
10
+
11
+ /**
12
+ * Sanitizes attributes required for AMP accessibility requirements.
13
+ *
14
+ * @since 1.5.3
15
+ */
16
+ class AMP_Accessibility_Sanitizer extends AMP_Base_Sanitizer {
17
+
18
+ /**
19
+ * Sanitize.
20
+ */
21
+ public function sanitize() {
22
+ $this->add_role_and_tabindex_to_on_tap_actors();
23
+ }
24
+
25
+ /**
26
+ * Adds the role and tabindex attributes to all elements that use a tap action via AMP's "on" event.
27
+ */
28
+ public function add_role_and_tabindex_to_on_tap_actors() {
29
+ $predicates = [
30
+ '@on',
31
+ 'contains( @on, "tap:" )',
32
+ 'not( @tabindex ) or not( @role )',
33
+ 'not( self::button )',
34
+ 'not( self::a[ @href ] )',
35
+ ];
36
+
37
+ $expression = sprintf(
38
+ '//*[ %s ]',
39
+ implode(
40
+ ' and ',
41
+ array_map(
42
+ static function ( $predicate ) {
43
+ return "( $predicate )";
44
+ },
45
+ $predicates
46
+ )
47
+ )
48
+ );
49
+
50
+ $attributes = [
51
+ Attribute::ROLE => Role::BUTTON,
52
+ Attribute::TABINDEX => '0',
53
+ ];
54
+
55
+ /**
56
+ * Element.
57
+ *
58
+ * @var DOMElement $element
59
+ */
60
+ foreach ( $this->dom->xpath->query( $expression ) as $element ) {
61
+ foreach ( $attributes as $attribute_name => $attribute_value ) {
62
+ if ( ! $element->hasAttribute( $attribute_name ) ) {
63
+ $element->setAttribute( $attribute_name, $attribute_value );
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
includes/sanitizers/class-amp-core-theme-sanitizer.php CHANGED
@@ -6,7 +6,9 @@
6
  * @since 1.0
7
  */
8
 
 
9
  use AmpProject\Dom\Document;
 
10
 
11
  /**
12
  * Class AMP_Core_Theme_Sanitizer
@@ -54,15 +56,15 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
54
  * @var array
55
  */
56
  protected static $modal_roles = [
57
- 'navigation',
58
- 'menu',
59
- 'search',
60
- 'alert',
61
- 'figure',
62
- 'form',
63
- 'img',
64
- 'toolbar',
65
- 'tooltip',
66
  ];
67
 
68
  /**
@@ -602,13 +604,13 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
602
  public function add_smooth_scrolling( $link_xpaths ) {
603
  foreach ( $link_xpaths as $link_xpath ) {
604
  foreach ( $this->dom->xpath->query( $link_xpath ) as $link ) {
605
- if ( $link instanceof DOMElement && preg_match( '/#(.+)/', $link->getAttribute( 'href' ), $matches ) ) {
606
- $link->setAttribute( 'on', sprintf( 'tap:%s.scrollTo(duration=600)', $matches[1] ) );
607
 
608
  // Prevent browser from jumping immediately to the link target.
609
- $link->removeAttribute( 'href' );
610
- $link->setAttribute( 'tabindex', '0' );
611
- $link->setAttribute( 'role', 'button' );
612
  }
613
  }
614
  }
@@ -1026,7 +1028,7 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
1026
  *
1027
  * @var DOMElement $link
1028
  */
1029
- $link->setAttribute( 'tabindex', '-1' );
1030
  }
1031
 
1032
  $navigation_top->parentNode->insertBefore( $navigation_top_fixed, $navigation_top->nextSibling );
@@ -1551,8 +1553,8 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
1551
  $a->setAttribute( 'class', 'slider-active' );
1552
  }
1553
  $a->setAttribute( Document::AMP_BIND_DATA_ATTR_PREFIX . 'class', "$selected_slide_state_id == $i ? 'slider-active' : ''" );
1554
- $a->setAttribute( 'role', 'button' );
1555
- $a->setAttribute( 'on', "tap:AMP.setState( { $selected_slide_state_id: $i } )" );
1556
  $li->setAttribute( 'option', (string) $i );
1557
  $a->appendChild( $this->dom->createTextNode( $i + 1 ) );
1558
  $li->appendChild( $a );
@@ -1599,9 +1601,9 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
1599
  $search_input_el->setAttribute( 'id', $search_input_id );
1600
  $on .= ",$search_input_id.focus()";
1601
  }
1602
- $search_toggle_link->setAttribute( 'on', $on );
1603
- $search_toggle_link->setAttribute( 'tabindex', '0' );
1604
- $search_toggle_link->setAttribute( 'role', 'button' );
1605
 
1606
  // Set visibility and aria-expanded based of the link based on whether the search bar is expanded.
1607
  $search_toggle_link->setAttribute( 'aria-expanded', wp_json_encode( $hidden ) );
@@ -1688,9 +1690,9 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
1688
  *
1689
  * @var DOMElement $event_element
1690
  */
1691
- $event_element->setAttribute( 'role', $this->guess_modal_role( $modal_content_node ) );
1692
  // Setting tabindex to -1 (not reachable) as keyboard focus is handled through toggles.
1693
- $event_element->setAttribute( 'tabindex', -1 );
1694
  }
1695
 
1696
  $parent_node = $modal_content_node->parentNode;
@@ -2012,11 +2014,11 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
2012
  */
2013
  protected function guess_modal_role( DOMElement $modal ) {
2014
  // No classes to base our guess on, so keep it generic.
2015
- if ( ! $modal->hasAttribute( 'class' ) ) {
2016
- return 'dialog';
2017
  }
2018
 
2019
- $classes = preg_split( '/\s+/', trim( $modal->getAttribute( 'class' ) ) );
2020
 
2021
  foreach ( self::$modal_roles as $role ) {
2022
  if ( in_array( $role, $classes, true ) ) {
@@ -2025,6 +2027,6 @@ class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
2025
  }
2026
 
2027
  // None of the roles we are looking for match any of the classes.
2028
- return 'dialog';
2029
  }
2030
  }
6
  * @since 1.0
7
  */
8
 
9
+ use AmpProject\Attribute;
10
  use AmpProject\Dom\Document;
11
+ use AmpProject\Role;
12
 
13
  /**
14
  * Class AMP_Core_Theme_Sanitizer
56
  * @var array
57
  */
58
  protected static $modal_roles = [
59
+ Role::NAVIGATION,
60
+ Role::MENU,
61
+ Role::SEARCH,
62
+ Role::ALERT,
63
+ Role::FIGURE,
64
+ Role::FORM,
65
+ Role::IMG,
66
+ Role::TOOLBAR,
67
+ Role::TOOLTIP,
68
  ];
69
 
70
  /**
604
  public function add_smooth_scrolling( $link_xpaths ) {
605
  foreach ( $link_xpaths as $link_xpath ) {
606
  foreach ( $this->dom->xpath->query( $link_xpath ) as $link ) {
607
+ if ( $link instanceof DOMElement && preg_match( '/#(.+)/', $link->getAttribute( Attribute::HREF ), $matches ) ) {
608
+ $link->setAttribute( Attribute::ON, sprintf( 'tap:%s.scrollTo(duration=600)', $matches[1] ) );
609
 
610
  // Prevent browser from jumping immediately to the link target.
611
+ $link->removeAttribute( Attribute::HREF );
612
+ $link->setAttribute( Attribute::TABINDEX, '0' );
613
+ $link->setAttribute( Attribute::ROLE, Role::BUTTON );
614
  }
615
  }
616
  }
1028
  *
1029
  * @var DOMElement $link
1030
  */
1031
+ $link->setAttribute( Attribute::TABINDEX, '-1' );
1032
  }
1033
 
1034
  $navigation_top->parentNode->insertBefore( $navigation_top_fixed, $navigation_top->nextSibling );
1553
  $a->setAttribute( 'class', 'slider-active' );
1554
  }
1555
  $a->setAttribute( Document::AMP_BIND_DATA_ATTR_PREFIX . 'class', "$selected_slide_state_id == $i ? 'slider-active' : ''" );
1556
+ $a->setAttribute( Attribute::ROLE, Role::BUTTON );
1557
+ $a->setAttribute( Attribute::ON, "tap:AMP.setState( { $selected_slide_state_id: $i } )" );
1558
  $li->setAttribute( 'option', (string) $i );
1559
  $a->appendChild( $this->dom->createTextNode( $i + 1 ) );
1560
  $li->appendChild( $a );
1601
  $search_input_el->setAttribute( 'id', $search_input_id );
1602
  $on .= ",$search_input_id.focus()";
1603
  }
1604
+ $search_toggle_link->setAttribute( Attribute::ON, $on );
1605
+ $search_toggle_link->setAttribute( Attribute::TABINDEX, '0' );
1606
+ $search_toggle_link->setAttribute( Attribute::ROLE, Role::BUTTON );
1607
 
1608
  // Set visibility and aria-expanded based of the link based on whether the search bar is expanded.
1609
  $search_toggle_link->setAttribute( 'aria-expanded', wp_json_encode( $hidden ) );
1690
  *
1691
  * @var DOMElement $event_element
1692
  */
1693
+ $event_element->setAttribute( Attribute::ROLE, $this->guess_modal_role( $modal_content_node ) );
1694
  // Setting tabindex to -1 (not reachable) as keyboard focus is handled through toggles.
1695
+ $event_element->setAttribute( Attribute::TABINDEX, -1 );
1696
  }
1697
 
1698
  $parent_node = $modal_content_node->parentNode;
2014
  */
2015
  protected function guess_modal_role( DOMElement $modal ) {
2016
  // No classes to base our guess on, so keep it generic.
2017
+ if ( ! $modal->hasAttribute( Attribute::CLASS_ ) ) {
2018
+ return Role::DIALOG;
2019
  }
2020
 
2021
+ $classes = preg_split( '/\s+/', trim( $modal->getAttribute( Attribute::CLASS_ ) ) );
2022
 
2023
  foreach ( self::$modal_roles as $role ) {
2024
  if ( in_array( $role, $classes, true ) ) {
2027
  }
2028
 
2029
  // None of the roles we are looking for match any of the classes.
2030
+ return Role::DIALOG;
2031
  }
2032
  }
includes/sanitizers/class-amp-form-sanitizer.php CHANGED
@@ -7,6 +7,7 @@
7
  */
8
 
9
  use AmpProject\DevMode;
 
10
 
11
  /**
12
  * Class AMP_Form_Sanitizer
@@ -201,17 +202,14 @@ class AMP_Form_Sanitizer extends AMP_Base_Sanitizer {
201
  'submitting' => null,
202
  ];
203
 
204
- $templates = $form->getElementsByTagName( 'template' );
205
- for ( $i = $templates->length - 1; $i >= 0; $i-- ) {
206
- /**
207
- * Parent node.
208
- *
209
- * @var DOMElement $parent
210
- */
211
- $parent = $templates->item( $i )->parentNode;
212
- foreach ( array_keys( $elements ) as $attribute ) {
213
- if ( $parent->hasAttribute( $attribute ) ) {
214
- $elements[ $attribute ] = $parent;
215
  }
216
  }
217
  }
7
  */
8
 
9
  use AmpProject\DevMode;
10
+ use AmpProject\Dom\Document;
11
 
12
  /**
13
  * Class AMP_Form_Sanitizer
202
  'submitting' => null,
203
  ];
204
 
205
+ $templates = $this->dom->xpath->query( Document::XPATH_MUSTACHE_TEMPLATE_ELEMENTS_QUERY, $form );
206
+ foreach ( $templates as $template ) {
207
+ $parent = $template->parentNode;
208
+ if ( $parent instanceof DOMElement ) {
209
+ foreach ( array_keys( $elements ) as $attribute ) {
210
+ if ( $parent->hasAttribute( $attribute ) ) {
211
+ $elements[ $attribute ] = $parent;
212
+ }
 
 
 
213
  }
214
  }
215
  }
includes/sanitizers/class-amp-style-sanitizer.php CHANGED
@@ -5,7 +5,6 @@
5
  * @package AMP
6
  */
7
 
8
- use AmpProject\AmpWP\BackgroundTask\MonitorCssTransientCaching;
9
  use AmpProject\AmpWP\Option;
10
  use AmpProject\AmpWP\RemoteRequest\CachedRemoteGetRequest;
11
  use AmpProject\AmpWP\RemoteRequest\WpHttpRemoteGetRequest;
@@ -2668,7 +2667,7 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
2668
  // Skip processing stylesheets that contain mustache template variables if the element is inside of a mustache template.
2669
  if (
2670
  preg_match( '/{{[^}]+?}}/', $value ) &&
2671
- 0 !== $this->dom->xpath->query( '//template[ @type="amp-mustache" ]//.', $element )->length
2672
  ) {
2673
  return;
2674
  }
5
  * @package AMP
6
  */
7
 
 
8
  use AmpProject\AmpWP\Option;
9
  use AmpProject\AmpWP\RemoteRequest\CachedRemoteGetRequest;
10
  use AmpProject\AmpWP\RemoteRequest\WpHttpRemoteGetRequest;
2667
  // Skip processing stylesheets that contain mustache template variables if the element is inside of a mustache template.
2668
  if (
2669
  preg_match( '/{{[^}]+?}}/', $value ) &&
2670
+ 0 !== $this->dom->xpath->query( '//template[ @type="amp-mustache" ]//.|//script[ @template="amp-mustache" and @type="text/plain" ]//.', $element )->length
2671
  ) {
2672
  return;
2673
  }
includes/sanitizers/class-amp-tag-and-attribute-sanitizer.php CHANGED
@@ -5,8 +5,11 @@
5
  * @package AMP
6
  */
7
 
 
8
  use AmpProject\CssLength;
9
  use AmpProject\Dom\Document;
 
 
10
 
11
  /**
12
  * Strips the tags and attributes from the content that are not allowed by the AMP spec.
@@ -1253,7 +1256,7 @@ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
1253
 
1254
  // Check the context to see if we are currently within a template tag.
1255
  // If this is the case and the attribute value contains a template placeholder, we skip sanitization.
1256
- if ( ! empty( $this->open_elements['template'] ) && preg_match( '/{{[^}]+?}}/', $attr_node->nodeValue ) ) {
1257
  continue;
1258
  }
1259
 
@@ -1338,6 +1341,10 @@ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
1338
  return true;
1339
  }
1340
 
 
 
 
 
1341
  $layout_attr = $node->getAttribute( 'layout' );
1342
  $allow_fluid = AMP_Rule_Spec::LAYOUT_FLUID === $layout_attr;
1343
  $allow_auto = true;
@@ -1445,6 +1452,56 @@ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
1445
  return true;
1446
  }
1447
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1448
  /**
1449
  * Calculate the effective width from the input layout and input width.
1450
  *
5
  * @package AMP
6
  */
7
 
8
+ use AmpProject\Attribute;
9
  use AmpProject\CssLength;
10
  use AmpProject\Dom\Document;
11
+ use AmpProject\Extension;
12
+ use AmpProject\Tag;
13
 
14
  /**
15
  * Strips the tags and attributes from the content that are not allowed by the AMP spec.
1256
 
1257
  // Check the context to see if we are currently within a template tag.
1258
  // If this is the case and the attribute value contains a template placeholder, we skip sanitization.
1259
+ if ( $this->is_inside_mustache_template( $node ) && preg_match( '/{{[^}]+?}}/', $attr_node->nodeValue ) ) {
1260
  continue;
1261
  }
1262
 
1341
  return true;
1342
  }
1343
 
1344
+ if ( $this->is_inside_mustache_template( $node ) && $this->has_layout_attribute_with_mustache_variable( $node ) ) {
1345
+ return true;
1346
+ }
1347
+
1348
  $layout_attr = $node->getAttribute( 'layout' );
1349
  $allow_fluid = AMP_Rule_Spec::LAYOUT_FLUID === $layout_attr;
1350
  $allow_auto = true;
1452
  return true;
1453
  }
1454
 
1455
+ /**
1456
+ * Whether the node is inside a mustache template.
1457
+ *
1458
+ * @since 1.5.3
1459
+ *
1460
+ * @param DOMElement $node The node to examine.
1461
+ * @return bool Whether the node is inside a valid mustache template.
1462
+ */
1463
+ private function is_inside_mustache_template( DOMElement $node ) {
1464
+ if ( ! empty( $this->open_elements[ Tag::TEMPLATE ] ) ) {
1465
+ while ( $node->parentNode instanceof DOMElement ) {
1466
+ $node = $node->parentNode;
1467
+ if ( Tag::TEMPLATE === $node->nodeName && Extension::MUSTACHE === $node->getAttribute( Attribute::TYPE ) ) {
1468
+ return true;
1469
+ }
1470
+ }
1471
+ } elseif ( ! empty( $this->open_elements[ Tag::SCRIPT ] ) ) {
1472
+ while ( $node->parentNode instanceof DOMElement ) {
1473
+ $node = $node->parentNode;
1474
+ if ( Tag::SCRIPT === $node->nodeName && Extension::MUSTACHE === $node->getAttribute( Attribute::TEMPLATE ) && Attribute::TYPE_TEXT_PLAIN === $node->getAttribute( Attribute::TYPE ) ) {
1475
+ return true;
1476
+ }
1477
+ }
1478
+ }
1479
+ return false;
1480
+ }
1481
+
1482
+ /**
1483
+ * Whether the node has a layout attribute with variable syntax, like {{foo}}.
1484
+ *
1485
+ * This is important for whether to validate the layout of the node.
1486
+ * Similar to the validation logic in the AMP validator.
1487
+ *
1488
+ * @see https://github.com/ampproject/amphtml/blob/c083d2c6120a251dcc9b0beb33c0336c7d3ca5a8/validator/engine/validator.js#L4038-L4054
1489
+ *
1490
+ * @since 1.5.3
1491
+ *
1492
+ * @param DOMElement $node The node to examine.
1493
+ * @return bool Whether the node has a layout attribute with variable syntax.
1494
+ */
1495
+ private function has_layout_attribute_with_mustache_variable( DOMElement $node ) {
1496
+ foreach ( [ Attribute::LAYOUT, Attribute::WIDTH, Attribute::HEIGHT, Attribute::SIZES, Attribute::HEIGHTS ] as $attribute ) {
1497
+ if ( preg_match( '/{{[^}]+?}}/', $node->getAttribute( $attribute ) ) ) {
1498
+ return true;
1499
+ }
1500
+ }
1501
+
1502
+ return false;
1503
+ }
1504
+
1505
  /**
1506
  * Calculate the effective width from the input layout and input width.
1507
  *
includes/templates/class-amp-post-template.php CHANGED
@@ -342,8 +342,17 @@ class AMP_Post_Template {
342
  * Build post content.
343
  */
344
  private function build_post_content() {
345
- /** This filter is documented in wp-includes/post-template.php */
346
- $content = apply_filters( 'the_content', get_the_content( null, false, $this->post ) );
 
 
 
 
 
 
 
 
 
347
 
348
  $this->add_data_by_key( 'post_amp_content', $content );
349
  }
342
  * Build post content.
343
  */
344
  private function build_post_content() {
345
+ if ( post_password_required( $this->post ) ) {
346
+ $content = get_the_password_form( $this->post );
347
+ } else {
348
+ /**
349
+ * This filter is documented in wp-includes/post-template.php.
350
+ *
351
+ * Note: This is intentionally not using get_the_content() because the legacy behavior of posts in
352
+ * Reader mode is to display multi-page posts as a single page without any pagination links.
353
+ */
354
+ $content = apply_filters( 'the_content', $this->post->post_content );
355
+ }
356
 
357
  $this->add_data_by_key( 'post_amp_content', $content );
358
  }
includes/validation/class-amp-validated-url-post-type.php CHANGED
@@ -1928,7 +1928,7 @@ class AMP_Validated_URL_Post_Type {
1928
  printf(
1929
  ' | <a href="%s">%s</a>',
1930
  esc_url( AMP_Theme_Support::get_paired_browsing_url( self::get_url_from_post( $post ) ) ),
1931
- esc_html__( 'Paired browsing', 'amp' )
1932
  );
1933
  }
1934
  ?>
1928
  printf(
1929
  ' | <a href="%s">%s</a>',
1930
  esc_url( AMP_Theme_Support::get_paired_browsing_url( self::get_url_from_post( $post ) ) ),
1931
+ esc_html__( 'Paired Browsing', 'amp' )
1932
  );
1933
  }
1934
  ?>
includes/validation/class-amp-validation-manager.php CHANGED
@@ -2077,7 +2077,7 @@ class AMP_Validation_Manager {
2077
  break;
2078
  }
2079
 
2080
- $validation_url = $location_header;
2081
  }
2082
 
2083
  if ( is_wp_error( $r ) ) {
2077
  break;
2078
  }
2079
 
2080
+ $validation_url = add_query_arg( $added_query_vars, $location_header );
2081
  }
2082
 
2083
  if ( is_wp_error( $r ) ) {
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: google, xwp, automattic, westonruter, albertomedina, schlessera, s
3
  Tags: amp, mobile, optimization, accelerated mobile pages, framework, components, blocks, performance, ux, seo, official
4
  Requires at least: 4.9
5
  Tested up to: 5.4
6
- Stable tag: 1.5.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  Requires PHP: 5.6
3
  Tags: amp, mobile, optimization, accelerated mobile pages, framework, components, blocks, performance, ux, seo, official
4
  Requires at least: 4.9
5
  Tested up to: 5.4
6
+ Stable tag: 1.5.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  Requires PHP: 5.6
src/Admin/ReenableCssTransientCachingAjaxAction.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class ReenableCssTransientCachingAjaxAction.
4
+ *
5
+ * @package AmpProject\AmpWP
6
+ */
7
+
8
+ namespace AmpProject\AmpWP\Admin;
9
+
10
+ use AMP_Options_Manager;
11
+ use AmpProject\AmpWP\Option;
12
+
13
+ /**
14
+ * Base class to define a new AJAX action.
15
+ *
16
+ * @package AmpProject\AmpWP
17
+ */
18
+ final class ReenableCssTransientCachingAjaxAction {
19
+
20
+ /**
21
+ * Action to use for enqueueing the JS logic at the backend.
22
+ *
23
+ * @var string
24
+ */
25
+ const BACKEND_ENQUEUE_ACTION = 'admin_enqueue_scripts';
26
+
27
+ /**
28
+ * AJAX action name to use.
29
+ *
30
+ * @var string
31
+ */
32
+ const AJAX_ACTION = 'amp_reenable_css_transient_caching';
33
+
34
+ /**
35
+ * Selector to attach the click handler to.
36
+ *
37
+ * @var string
38
+ */
39
+ const SELECTOR = 'a.reenable-css-transient-caching';
40
+
41
+ /**
42
+ * Register the AJAX action with the WordPress system.
43
+ */
44
+ public function register() {
45
+ add_action( static::BACKEND_ENQUEUE_ACTION, [ $this, 'register_ajax_script' ] );
46
+ add_action( 'wp_ajax_' . self::AJAX_ACTION, [ $this, 'reenable_css_transient_caching' ] );
47
+ }
48
+
49
+ /**
50
+ * Register the AJAX logic.
51
+ *
52
+ * @param string $hook_suffix Hook suffix to identify from what admin page the call is coming from.
53
+ */
54
+ public function register_ajax_script( $hook_suffix ) {
55
+ if ( 'site-health.php' !== $hook_suffix ) {
56
+ return;
57
+ }
58
+
59
+ $script = <<< 'JS_SCRIPT'
60
+ ;( function () {
61
+ window.addEventListener( 'DOMContentLoaded', ( event ) => {
62
+ var selector = SELECTOR;
63
+ ( document.querySelectorAll( selector ) || [] )
64
+ .forEach( ( element ) => {
65
+ element.addEventListener( 'click', function ( event ) {
66
+ event.preventDefault();
67
+ if ( element.classList.contains( 'disabled' ) ) {
68
+ return;
69
+ }
70
+ wp.ajax.post( ACTION, ARGUMENTS )
71
+ .done( function () {
72
+ element.classList.remove( 'ajax-failure' );
73
+ element.classList.add( 'ajax-success' )
74
+ element.classList.add( 'disabled' )
75
+ } )
76
+ .fail( function () {
77
+ element.classList.remove( 'ajax-success' );
78
+ element.classList.add( 'ajax-failure' )
79
+ element.classList.add( 'disabled' )
80
+ } );
81
+ } );
82
+ } );
83
+ } );
84
+ } )();
85
+ JS_SCRIPT;
86
+
87
+ $replacements = array_map(
88
+ 'wp_json_encode',
89
+ [
90
+ 'SELECTOR' => self::SELECTOR,
91
+ 'ACTION' => self::AJAX_ACTION,
92
+ 'ARGUMENTS' => [ 'nonce' => wp_create_nonce( self::AJAX_ACTION ) ],
93
+ ]
94
+ );
95
+
96
+ $script = str_replace(
97
+ array_keys( $replacements ),
98
+ array_values( $replacements ),
99
+ $script
100
+ );
101
+
102
+ wp_enqueue_script( 'wp-util' );
103
+ wp_add_inline_script( 'wp-util', $script );
104
+ }
105
+
106
+ /**
107
+ * Re-enable the CSS Transient caching.
108
+ *
109
+ * This is triggered via an AJAX call from the Site Health panel.
110
+ */
111
+ public function reenable_css_transient_caching() {
112
+ check_ajax_referer( self::AJAX_ACTION, 'nonce' );
113
+
114
+ if ( ! current_user_can( 'manage_options' ) ) {
115
+ wp_send_json_error( 'Unauthorized.', 401 );
116
+ }
117
+
118
+ $result = AMP_Options_Manager::update_option( Option::DISABLE_CSS_TRANSIENT_CACHING, false );
119
+
120
+ if ( false === $result ) {
121
+ wp_send_json_error( 'CSS transient caching could not be re-enabled.', 500 );
122
+ }
123
+
124
+ wp_send_json_success( 'CSS transient caching was re-enabled.', 200 );
125
+ }
126
+ }
src/Admin/SiteHealth.php CHANGED
@@ -29,6 +29,9 @@ final class SiteHealth {
29
  add_filter( 'site_status_tests', [ $this, 'add_tests' ] );
30
  add_filter( 'debug_information', [ $this, 'add_debug_information' ] );
31
  add_filter( 'site_status_test_php_modules', [ $this, 'add_extensions' ] );
 
 
 
32
  }
33
 
34
  /**
@@ -62,6 +65,21 @@ final class SiteHealth {
62
  return $tests;
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * Gets the test result data for whether there is a persistent object cache.
67
  *
@@ -75,13 +93,7 @@ final class SiteHealth {
75
  'color' => $is_using_object_cache ? 'green' : 'orange',
76
  ],
77
  'description' => esc_html__( 'The AMP plugin performs at its best when persistent object cache is enabled. Object caching is used to more effectively store image dimensions and parsed CSS.', 'amp' ),
78
- 'actions' => sprintf(
79
- '<p><a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
80
- 'https://codex.wordpress.org/Class_Reference/WP_Object_Cache#Persistent_Caching',
81
- esc_html__( 'Learn more about persistent object caching', 'amp' ),
82
- /* translators: The accessibility text. */
83
- esc_html__( '(opens in a new tab)', 'amp' )
84
- ),
85
  'test' => 'amp_persistent_object_cache',
86
  ];
87
 
@@ -240,11 +252,13 @@ final class SiteHealth {
240
  * @return array The test data.
241
  */
242
  public function css_transient_caching() {
 
 
243
  if ( wp_using_ext_object_cache() ) {
244
  $status = 'good';
245
  $color = 'blue';
246
  $label = __( 'Transient caching of parsed stylesheets is not used due to external object cache', 'amp' );
247
- } elseif ( AMP_Options_Manager::get_option( Option::DISABLE_CSS_TRANSIENT_CACHING, false ) ) {
248
  $status = 'recommended';
249
  $color = 'orange';
250
  $label = __( 'Transient caching of parsed stylesheets is disabled', 'amp' );
@@ -254,16 +268,40 @@ final class SiteHealth {
254
  $label = __( 'Transient caching of parsed stylesheets is enabled', 'amp' );
255
  }
256
 
257
- return [
258
  'badge' => [
259
  'label' => esc_html__( 'AMP', 'amp' ),
260
  'color' => $color,
261
  ],
262
- 'description' => esc_html__( 'On sites which have highly variable CSS and are not using a persistent object cache, the transient caching of parsed stylesheets may be automatically disabled in order to prevent a site from filling up its wp_options table with too many transients.', 'amp' ),
 
 
 
 
 
 
 
 
 
 
 
263
  'test' => 'amp_css_transient_caching',
264
  'status' => $status,
265
  'label' => esc_html( $label ),
266
  ];
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  }
268
 
269
  /**
@@ -502,4 +540,41 @@ final class SiteHealth {
502
  ]
503
  );
504
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
  }
29
  add_filter( 'site_status_tests', [ $this, 'add_tests' ] );
30
  add_filter( 'debug_information', [ $this, 'add_debug_information' ] );
31
  add_filter( 'site_status_test_php_modules', [ $this, 'add_extensions' ] );
32
+ add_action( 'admin_print_styles', [ $this, 'add_styles' ] );
33
+
34
+ ( new ReenableCssTransientCachingAjaxAction() )->register();
35
  }
36
 
37
  /**
65
  return $tests;
66
  }
67
 
68
+ /**
69
+ * Get action HTML for the link to learn more about persistent object caching.
70
+ *
71
+ * @return string HTML.
72
+ */
73
+ private function get_persistent_object_cache_learn_more_action() {
74
+ return sprintf(
75
+ '<p><a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
76
+ esc_url( 'https://make.wordpress.org/hosting/handbook/handbook/performance/#object-cache' ),
77
+ esc_html__( 'Learn more about persistent object caching', 'amp' ),
78
+ /* translators: The accessibility text. */
79
+ esc_html__( '(opens in a new tab)', 'amp' )
80
+ );
81
+ }
82
+
83
  /**
84
  * Gets the test result data for whether there is a persistent object cache.
85
  *
93
  'color' => $is_using_object_cache ? 'green' : 'orange',
94
  ],
95
  'description' => esc_html__( 'The AMP plugin performs at its best when persistent object cache is enabled. Object caching is used to more effectively store image dimensions and parsed CSS.', 'amp' ),
96
+ 'actions' => $this->get_persistent_object_cache_learn_more_action(),
 
 
 
 
 
 
97
  'test' => 'amp_persistent_object_cache',
98
  ];
99
 
252
  * @return array The test data.
253
  */
254
  public function css_transient_caching() {
255
+ $disabled = AMP_Options_Manager::get_option( Option::DISABLE_CSS_TRANSIENT_CACHING, false );
256
+
257
  if ( wp_using_ext_object_cache() ) {
258
  $status = 'good';
259
  $color = 'blue';
260
  $label = __( 'Transient caching of parsed stylesheets is not used due to external object cache', 'amp' );
261
+ } elseif ( $disabled ) {
262
  $status = 'recommended';
263
  $color = 'orange';
264
  $label = __( 'Transient caching of parsed stylesheets is disabled', 'amp' );
268
  $label = __( 'Transient caching of parsed stylesheets is enabled', 'amp' );
269
  }
270
 
271
+ $data = [
272
  'badge' => [
273
  'label' => esc_html__( 'AMP', 'amp' ),
274
  'color' => $color,
275
  ],
276
+ 'description' => wp_kses(
277
+ sprintf(
278
+ /* translators: %1$s is wp_options table, %2$s is the amp_css_transient_monitoring_threshold filter, and %3$s is the amp_css_transient_monitoring_sampling_range filter */
279
+ __( 'On sites which have highly variable CSS and are not using a persistent object cache, the transient caching of parsed stylesheets may be automatically disabled in order to prevent a site from filling up its <code>%1$s</code> table with too many transients. Examples of highly variable CSS include dynamically-generated style rules with selectors referring to user IDs or elements being given randomized background colors. There are two filters which may be used to configure the CSS transient monitoring: <code>%2$s</code> and <code>%3$s</code>.', 'amp' ),
280
+ 'wp_options',
281
+ 'amp_css_transient_monitoring_threshold',
282
+ 'amp_css_transient_monitoring_sampling_range'
283
+ ),
284
+ [
285
+ 'code' => [],
286
+ ]
287
+ ),
288
  'test' => 'amp_css_transient_caching',
289
  'status' => $status,
290
  'label' => esc_html( $label ),
291
  ];
292
+
293
+ if ( $disabled ) {
294
+ $data['description'] .= ' ' . esc_html__( 'If you have identified and eliminated the cause of the variable CSS, please re-enable transient caching to reduce the amount of CSS processing required to generate AMP pages.', 'amp' );
295
+ $data['actions'] = sprintf(
296
+ '<p><a class="button reenable-css-transient-caching" href="#">%s</a><span class="dashicons dashicons-yes success-icon"></span><span class="dashicons dashicons-no failure-icon"></span><span class="success-text">%s</span><span class="failure-text">%s</span></p>',
297
+ esc_html__( 'Re-enable transient caching', 'amp' ),
298
+ esc_html__( 'Reload the page to refresh the diagnostic check.', 'amp' ),
299
+ esc_html__( 'The operation failed, please reload the page and try again.', 'amp' )
300
+ );
301
+ $data['actions'] .= $this->get_persistent_object_cache_learn_more_action();
302
+ }
303
+
304
+ return $data;
305
  }
306
 
307
  /**
540
  ]
541
  );
542
  }
543
+
544
+ /**
545
+ * Add needed styles for the Site Health integration.
546
+ */
547
+ public function add_styles() {
548
+ echo '
549
+ <style>
550
+ .wp-core-ui .button.reenable-css-transient-caching ~ .success-icon,
551
+ .wp-core-ui .button.reenable-css-transient-caching ~ .success-text,
552
+ .wp-core-ui .button.reenable-css-transient-caching ~ .failure-icon,
553
+ .wp-core-ui .button.reenable-css-transient-caching ~ .failure-text {
554
+ display: none;
555
+ }
556
+
557
+ .wp-core-ui .button.reenable-css-transient-caching ~ .success-icon,
558
+ .wp-core-ui .button.reenable-css-transient-caching ~ .failure-icon {
559
+ font-size: xx-large;
560
+ padding-right: 1rem;
561
+ }
562
+
563
+ .wp-core-ui .button.reenable-css-transient-caching.ajax-success ~ .success-icon,
564
+ .wp-core-ui .button.reenable-css-transient-caching.ajax-success ~ .success-text,
565
+ .wp-core-ui .button.reenable-css-transient-caching.ajax-failure ~ .failure-icon,
566
+ .wp-core-ui .button.reenable-css-transient-caching.ajax-failure ~ .failure-text {
567
+ display: inline-block;
568
+ }
569
+
570
+ .wp-core-ui .button.reenable-css-transient-caching.ajax-success ~ .success-icon {
571
+ color: #46b450;
572
+ }
573
+
574
+ .wp-core-ui .button.reenable-css-transient-caching.ajax-failure ~ .failure-icon {
575
+ color: #dc3232;
576
+ }
577
+ </style>
578
+ ';
579
+ }
580
  }
vendor/ampproject/common/src/Attribute.php CHANGED
@@ -46,11 +46,14 @@ interface Attribute
46
  const LOOP = 'loop';
47
  const MEDIA = 'media';
48
  const NAME = 'name';
 
49
  const PROFILE = 'profile';
50
  const REL = 'rel';
51
  const ROLE = 'role';
52
  const SIZES = 'sizes';
53
  const SRC = 'src';
 
 
54
  const TYPE = 'type';
55
  const VIEWPORT = 'viewport';
56
  const WIDTH = 'width';
@@ -59,9 +62,12 @@ interface Attribute
59
  const ALL_AMP4ADS = [self::AMP4ADS, self::AMP4ADS_EMOJI, self::AMP4ADS_EMOJI_ALT];
60
  const ALL_AMP4EMAIL = [self::AMP4EMAIL, self::AMP4EMAIL_EMOJI, self::AMP4EMAIL_EMOJI_ALT];
61
 
62
- const TYPE_HTML = 'text/html';
63
- const TYPE_JSON = 'application/json';
64
- const TYPE_LD_JSON = 'application/ld+json';
 
 
 
65
 
66
  const REL_CANONICAL = 'canonical';
67
  const REL_DNS_PREFETCH = 'dns-prefetch';
46
  const LOOP = 'loop';
47
  const MEDIA = 'media';
48
  const NAME = 'name';
49
+ const ON = 'on';
50
  const PROFILE = 'profile';
51
  const REL = 'rel';
52
  const ROLE = 'role';
53
  const SIZES = 'sizes';
54
  const SRC = 'src';
55
+ const TABINDEX = 'tabindex';
56
+ const TEMPLATE = 'template';
57
  const TYPE = 'type';
58
  const VIEWPORT = 'viewport';
59
  const WIDTH = 'width';
62
  const ALL_AMP4ADS = [self::AMP4ADS, self::AMP4ADS_EMOJI, self::AMP4ADS_EMOJI_ALT];
63
  const ALL_AMP4EMAIL = [self::AMP4EMAIL, self::AMP4EMAIL_EMOJI, self::AMP4EMAIL_EMOJI_ALT];
64
 
65
+ const ALL_BOILERPLATES = [self::AMP_BOILERPLATE, self::AMP4ADS_BOILERPLATE, self::AMP4EMAIL_BOILERPLATE];
66
+
67
+ const TYPE_HTML = 'text/html';
68
+ const TYPE_JSON = 'application/json';
69
+ const TYPE_LD_JSON = 'application/ld+json';
70
+ const TYPE_TEXT_PLAIN = 'text/plain';
71
 
72
  const REL_CANONICAL = 'canonical';
73
  const REL_DNS_PREFETCH = 'dns-prefetch';
vendor/ampproject/common/src/Dom/Document.php CHANGED
@@ -119,6 +119,13 @@ final class Document extends DOMDocument
119
  */
120
  const XPATH_URL_ENCODED_ATTRIBUTES_QUERY = './/*/@src|.//*/@href|.//*/@action';
121
 
 
 
 
 
 
 
 
122
  /**
123
  * Error message to use when the __get() is triggered for an unknown property.
124
  *
@@ -1185,9 +1192,8 @@ final class Document extends DOMDocument
1185
  */
1186
  private function replaceMustacheTemplateTokens()
1187
  {
1188
- $templates = $this->getElementsByTagName(Tag::TEMPLATE);
1189
-
1190
- if (! $templates || 0 === count($templates)) {
1191
  return;
1192
  }
1193
 
@@ -1253,7 +1259,6 @@ final class Document extends DOMDocument
1253
  '{{#',
1254
  '{{^',
1255
  '{{/',
1256
- '{{/',
1257
  '{{',
1258
  '}}',
1259
  ];
119
  */
120
  const XPATH_URL_ENCODED_ATTRIBUTES_QUERY = './/*/@src|.//*/@href|.//*/@action';
121
 
122
+ /**
123
+ * Xpath query to fetch the elements containing Mustache templates (both <template type=amp-mustache> and <script type=text/plain template=amp-mustache>).
124
+ *
125
+ * @var string
126
+ */
127
+ const XPATH_MUSTACHE_TEMPLATE_ELEMENTS_QUERY = './/self::template[ @type = "amp-mustache" ]|//self::script[ @type = "text/plain" and @template = "amp-mustache" ]';
128
+
129
  /**
130
  * Error message to use when the __get() is triggered for an unknown property.
131
  *
1192
  */
1193
  private function replaceMustacheTemplateTokens()
1194
  {
1195
+ $templates = $this->xpath->query(self::XPATH_MUSTACHE_TEMPLATE_ELEMENTS_QUERY, $this->body);
1196
+ if (0 === $templates->length) {
 
1197
  return;
1198
  }
1199
 
1259
  '{{#',
1260
  '{{^',
1261
  '{{/',
 
1262
  '{{',
1263
  '}}',
1264
  ];
vendor/ampproject/common/src/Role.php ADDED
@@ -0,0 +1,508 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace AmpProject;
4
+
5
+ /**
6
+ * Interface with constants for the different types of accessibility roles.
7
+ *
8
+ * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques
9
+ *
10
+ * @package ampproject/common
11
+ */
12
+ interface Role
13
+ {
14
+
15
+ /**
16
+ * A message with an alert or error information.
17
+ *
18
+ * @var string
19
+ */
20
+ const ALERT = 'alert';
21
+
22
+ /**
23
+ * A separate window with an alert or error information.
24
+ *
25
+ * @var string
26
+ */
27
+ const ALERTDIALOG = 'alertdialog';
28
+
29
+ /**
30
+ * A software unit executing a set of tasks for its users.
31
+ *
32
+ * @var string
33
+ */
34
+ const APPLICATION = 'application';
35
+
36
+ /**
37
+ * A section of a page that could easily stand on its own on a page, in a document, or on a website.
38
+ *
39
+ * @var string
40
+ */
41
+ const ARTICLE = 'article';
42
+
43
+ /**
44
+ * A region that contains mostly site-oriented content, rather than page-specific content.
45
+ *
46
+ * @var string
47
+ */
48
+ const BANNER = 'banner';
49
+
50
+ /**
51
+ * Allows for user-triggered actions.
52
+ *
53
+ * @var string
54
+ */
55
+ const BUTTON = 'button';
56
+
57
+ /**
58
+ * An element as being a cell in a tabular container that does not contain column or row header information.
59
+ *
60
+ * @var string
61
+ */
62
+ const CELL = 'cell';
63
+
64
+ /**
65
+ * A control that has three possible values, (true, false, mixed).
66
+ *
67
+ * @var string
68
+ */
69
+ const CHECKBOX = 'checkbox';
70
+
71
+ /**
72
+ * A table cell containing header information for a column.
73
+ *
74
+ * @var string
75
+ */
76
+ const COLUMNHEADER = 'columnheader';
77
+
78
+ /**
79
+ * Combobox is a presentation of a select, where users can type to locate a selected item.
80
+ *
81
+ * @var string
82
+ */
83
+ const COMBOBOX = 'combobox';
84
+
85
+ /**
86
+ * A supporting section of the document, designed to be complementary to the main content at a similar level in the DOM hierarchy, but remains meaningful when separated from the main content.
87
+ *
88
+ * @var string
89
+ */
90
+ const COMPLEMENTARY = 'complementary';
91
+
92
+ /**
93
+ * A large perceivable region that contains information about the parent document.
94
+ *
95
+ * @var string
96
+ */
97
+ const CONTENTINFO = 'contentinfo';
98
+
99
+ /**
100
+ * A definition of a term or concept.
101
+ *
102
+ * @var string
103
+ */
104
+ const DEFINITION = 'definition';
105
+
106
+ /**
107
+ * Descriptive content for a page element which references this element via describedby.
108
+ *
109
+ * @var string
110
+ */
111
+ const DESCRIPTION = 'description';
112
+
113
+ /**
114
+ * A dialog is a small application window that sits above the application and is designed to interrupt the current processing of an application in order to prompt the user to enter information or require a response.
115
+ *
116
+ * @var string
117
+ */
118
+ const DIALOG = 'dialog';
119
+
120
+ /**
121
+ * A list of references to members of a single group.
122
+ *
123
+ * @var string
124
+ */
125
+ const DIRECTORY = 'directory';
126
+
127
+ /**
128
+ * Content that contains related information, such as a book.
129
+ *
130
+ * @var string
131
+ */
132
+ const DOCUMENT = 'document';
133
+
134
+ /**
135
+ * A scrollable list of articles where scrolling may cause articles to be added to or removed from either end of the list.
136
+ *
137
+ * @var string
138
+ */
139
+ const FEED = 'feed';
140
+
141
+ /**
142
+ * A figure inside page content where appropriate semantics do not already exist.
143
+ *
144
+ * @var string
145
+ */
146
+ const FIGURE = 'figure';
147
+
148
+ /**
149
+ * A landmark region that contains a collection of items and objects that, as a whole, combine to create a form.
150
+ *
151
+ * @var string
152
+ */
153
+ const FORM = 'form';
154
+
155
+ /**
156
+ * A grid contains cells of tabular data arranged in rows and columns (e.g., a table).
157
+ *
158
+ * @var string
159
+ */
160
+ const GRID = 'grid';
161
+
162
+ /**
163
+ * A gridcell is a table cell in a grid. Gridcells may be active, editable, and selectable. Cells may have relationships such as controls to address the application of functional relationships.
164
+ *
165
+ * @var string
166
+ */
167
+ const GRIDCELL = 'gridcell';
168
+
169
+ /**
170
+ * A group is a section of user interface objects which would not be included in a page summary or table of contents by an assistive technology. See region for sections of user interface objects that should be included in a page summary or table of contents.
171
+ *
172
+ * @var string
173
+ */
174
+ const GROUP = 'group';
175
+
176
+ /**
177
+ * A heading for a section of the page.
178
+ *
179
+ * @var string
180
+ */
181
+ const HEADING = 'heading';
182
+
183
+ /**
184
+ * An img is a container for a collection elements that form an image.
185
+ *
186
+ * @var string
187
+ */
188
+ const IMG = 'img';
189
+
190
+ /**
191
+ * Interactive reference to a resource (note, that in XHTML 2.0 any element can have an href attribute and thus be a link)
192
+ *
193
+ * @var string
194
+ */
195
+ const LINK = 'link';
196
+
197
+ /**
198
+ * Group of non-interactive list items. Lists contain children whose role is listitem.
199
+ *
200
+ * Uses an underscore as "list" is a conflicting PHP keyword.
201
+ *
202
+ * @var string
203
+ */
204
+ const LIST_ = 'list';
205
+
206
+ /**
207
+ * A list box is a widget that allows the user to select one or more items from a list. Items within the list are static and may contain images. List boxes contain children whose role is option.
208
+ *
209
+ * @var string
210
+ */
211
+ const LISTBOX = 'listbox';
212
+
213
+ /**
214
+ * A single item in a list.
215
+ *
216
+ * @var string
217
+ */
218
+ const LISTITEM = 'listitem';
219
+
220
+ /**
221
+ * A region where new information is added and old information may disappear such as chat logs, messaging, game log or an error log. In contrast to other regions, in this role there is a relationship between the arrival of new items in the log and the reading order. The log contains a meaningful sequence and new information is added only to the end of the log, not at arbitrary points.
222
+ *
223
+ * @var string
224
+ */
225
+ const LOG = 'log';
226
+
227
+ /**
228
+ * The main content of a document.
229
+ *
230
+ * @var string
231
+ */
232
+ const MAIN = 'main';
233
+
234
+ /**
235
+ * A marquee is used to scroll text across the page.
236
+ *
237
+ * @var string
238
+ */
239
+ const MARQUEE = 'marquee';
240
+
241
+ /**
242
+ * Content that represents a mathematical expression.
243
+ *
244
+ * @var string
245
+ */
246
+ const MATH = 'math';
247
+
248
+ /**
249
+ * Offers a list of choices to the user.
250
+ *
251
+ * @var string
252
+ */
253
+ const MENU = 'menu';
254
+
255
+ /**
256
+ * A menubar is a container of menu items. Each menu item may activate a new sub-menu. Navigation behavior should be similar to the typical menu bar graphical user interface.
257
+ *
258
+ * @var string
259
+ */
260
+ const MENUBAR = 'menubar';
261
+
262
+ /**
263
+ * A link in a menu. This is an option in a group of choices contained in a menu.
264
+ *
265
+ * @var string
266
+ */
267
+ const MENUITEM = 'menuitem';
268
+
269
+ /**
270
+ * Defines a menuitem which is checkable (tri-state).
271
+ *
272
+ * @var string
273
+ */
274
+ const MENUITEMCHECKBOX = 'menuitemcheckbox';
275
+
276
+ /**
277
+ * Indicates a menu item which is part of a group of menuitemradio roles.
278
+ *
279
+ * @var string
280
+ */
281
+ const MENUITEMRADIO = 'menuitemradio';
282
+
283
+ /**
284
+ * A collection of navigational elements (usually links) for navigating the document or related documents.
285
+ *
286
+ * @var string
287
+ */
288
+ const NAVIGATION = 'navigation';
289
+
290
+ /**
291
+ * An element whose implicit native role semantics will not be mapped to the accessibility API.
292
+ *
293
+ * @var string
294
+ */
295
+ const NONE = 'none';
296
+
297
+ /**
298
+ * A section whose content is parenthetic or ancillary to the main content of the resource.
299
+ *
300
+ * @var string
301
+ */
302
+ const NOTE = 'note';
303
+
304
+ /**
305
+ * A selectable item in a list represented by a select.
306
+ *
307
+ * @var string
308
+ */
309
+ const OPTION = 'option';
310
+
311
+ /**
312
+ * An element whose role is presentational does not need to be mapped to the accessibility API.
313
+ *
314
+ * @var string
315
+ */
316
+ const PRESENTATION = 'presentation';
317
+
318
+ /**
319
+ * Used by applications for tasks that take a long time to execute, to show the execution progress.
320
+ *
321
+ * @var string
322
+ */
323
+ const PROGRESSBAR = 'progressbar';
324
+
325
+ /**
326
+ * A radio is an option in single-select list. Only one radio control in a radiogroup can be selected at the same time.
327
+ *
328
+ * @var string
329
+ */
330
+ const RADIO = 'radio';
331
+
332
+ /**
333
+ * A group of radio controls.
334
+ *
335
+ * @var string
336
+ */
337
+ const RADIOGROUP = 'radiogroup';
338
+
339
+ /**
340
+ * Region is a large perceivable section on the web page.
341
+ *
342
+ * @var string
343
+ */
344
+ const REGION = 'region';
345
+
346
+ /**
347
+ * A row of table cells.
348
+ *
349
+ * @var string
350
+ */
351
+ const ROW = 'row';
352
+
353
+ /**
354
+ * A structure containing one or more row elements in a tabular container.
355
+ *
356
+ * @var string
357
+ */
358
+ const ROWGROUP = 'rowgroup';
359
+
360
+ /**
361
+ * A table cell containing header information for a row.
362
+ *
363
+ * @var string
364
+ */
365
+ const ROWHEADER = 'rowheader';
366
+
367
+ /**
368
+ * Scroll bar to navigate the horizontal or vertical dimensions of the page.
369
+ *
370
+ * @var string
371
+ */
372
+ const SCROLLBAR = 'scrollbar';
373
+
374
+ /**
375
+ * A section of the page used to search the page, site, or collection of sites.
376
+ *
377
+ * @var string
378
+ */
379
+ const SEARCH = 'search';
380
+
381
+ /**
382
+ * An entry field to provide a query to search for.
383
+ *
384
+ * @var string
385
+ */
386
+ const SEARCHBOX = 'searchbox';
387
+
388
+ /**
389
+ * A line or bar that separates and distinguishes sections of content.
390
+ *
391
+ * @var string
392
+ */
393
+ const SEPARATOR = 'separator';
394
+
395
+ /**
396
+ * A user input where the user selects an input in a given range. This form of range expects an analog keyboard interface.
397
+ *
398
+ * @var string
399
+ */
400
+ const SLIDER = 'slider';
401
+
402
+ /**
403
+ * A form of Range that expects a user selecting from discrete choices.
404
+ *
405
+ * @var string
406
+ */
407
+ const SPINBUTTON = 'spinbutton';
408
+
409
+ /**
410
+ * This is a container for process advisory information to give feedback to the user.
411
+ *
412
+ * @var string
413
+ */
414
+ const STATUS = 'status';
415
+
416
+ /**
417
+ * Functionally identical to a checkbox but represents the states "on"/"off" instead of "checked"/"unchecked".
418
+ *
419
+ * Uses an underscore as "list" is a conflicting PHP keyword.
420
+ *
421
+ * @var string
422
+ */
423
+ const SWITCH_ = 'switch';
424
+
425
+ /**
426
+ * A header for a tabpanel.
427
+ *
428
+ * @var string
429
+ */
430
+ const TAB = 'tab';
431
+
432
+ /**
433
+ * A non-interactive table structure containing data arranged in rows and columns.
434
+ *
435
+ * @var string
436
+ */
437
+ const TABLE = 'table';
438
+
439
+ /**
440
+ * A list of tabs, which are references to tabpanels.
441
+ *
442
+ * @var string
443
+ */
444
+ const TABLIST = 'tablist';
445
+
446
+ /**
447
+ * Tabpanel is a container for the resources associated with a tab.
448
+ *
449
+ * @var string
450
+ */
451
+ const TABPANEL = 'tabpanel';
452
+
453
+ /**
454
+ * A word or phrase with a corresponding definition.
455
+ *
456
+ * @var string
457
+ */
458
+ const TERM = 'term';
459
+
460
+ /**
461
+ * Inputs that allow free-form text as their value.
462
+ *
463
+ * @var string
464
+ */
465
+ const TEXTBOX = 'textbox';
466
+
467
+ /**
468
+ * A numerical counter which indicates an amount of elapsed time from a start point, or the time remaining until an end point.
469
+ *
470
+ * @var string
471
+ */
472
+ const TIMER = 'timer';
473
+
474
+ /**
475
+ * A toolbar is a collection of commonly used functions represented in compact visual form.
476
+ *
477
+ * @var string
478
+ */
479
+ const TOOLBAR = 'toolbar';
480
+
481
+ /**
482
+ * A popup that displays a description for an element when a user passes over or rests on that element. Supplement to the normal tooltip processing of the user agent.
483
+ *
484
+ * @var string
485
+ */
486
+ const TOOLTIP = 'tooltip';
487
+
488
+ /**
489
+ * A form of a list having groups inside groups, where sub trees can be collapsed and expanded.
490
+ *
491
+ * @var string
492
+ */
493
+ const TREE = 'tree';
494
+
495
+ /**
496
+ * A grid whose rows can be expanded and collapsed in the same manner as for a tree.
497
+ *
498
+ * @var string
499
+ */
500
+ const TREEGRID = 'treegrid';
501
+
502
+ /**
503
+ * An option item of a tree. This is an element within a tree that may be expanded or collapsed.
504
+ *
505
+ * @var string
506
+ */
507
+ const TREEITEM = 'treeitem';
508
+ }
vendor/ampproject/optimizer/resources/local_fallback/rtv/metadata CHANGED
@@ -1 +1 @@
1
- {"ampRuntimeVersion":"012002251816300","ampCssUrl":"https://cdn.ampproject.org/rtv/012002251816300/v0.css","canaryPercentage":"0.005","diversions":["002002251816300","032002251816300","022002251816300"],"ltsRuntimeVersion":"012002191527100","ltsCssUrl":"https://cdn.ampproject.org/rtv/012002191527100/v0.css"}
1
+ {"ampRuntimeVersion":"012004030010070","ampCssUrl":"https://cdn.ampproject.org/rtv/012004030010070/v0.css","canaryPercentage":"0.005","diversions":["002004012111560","002004012158290","022004030010070","032004012111560","032004012158290","042004030033570"],"ltsRuntimeVersion":"012002251816300","ltsCssUrl":"https://cdn.ampproject.org/rtv/012002251816300/v0.css"}
vendor/ampproject/optimizer/src/Transformer/AmpBoilerplate.php CHANGED
@@ -4,7 +4,6 @@ namespace AmpProject\Optimizer\Transformer;
4
 
5
  use AmpProject\Amp;
6
  use AmpProject\Attribute;
7
- use AmpProject\DevMode;
8
  use AmpProject\Dom\Document;
9
  use AmpProject\Optimizer\ErrorCollection;
10
  use AmpProject\Optimizer\Transformer;
@@ -12,8 +11,8 @@ use AmpProject\Tag;
12
  use DOMElement;
13
 
14
  /**
15
- * Transformer that removes <style> and <noscript> tags in <head>, keeping only the amp-custom style tag. It then
16
- * inserts the amp-boilerplate.
17
  *
18
  * This is ported from the Go optimizer.
19
  *
@@ -68,31 +67,44 @@ final class AmpBoilerplate implements Transformer
68
  }
69
 
70
  /**
71
- * Remove all <style> and <noscript> tags except for the <style amp-custom> tag.
72
  *
73
  * @param Document $document Document to remove the tags from.
74
  */
75
  private function removeStyleAndNoscriptTags(Document $document)
76
  {
77
- $headNode = $document->head->firstChild;
78
- $devMode = DevMode::isActiveForDocument($document);
79
- while ($headNode) {
80
- $nextSibling = $headNode->nextSibling;
81
- if ($headNode instanceof DOMElement && (! $devMode || ! DevMode::hasExemptionForNode($headNode))) {
82
- switch ($headNode->tagName) {
83
- case Tag::STYLE:
84
- if (! $headNode->hasAttribute(Attribute::AMP_CUSTOM)) {
85
- $document->head->removeChild($headNode);
86
- }
87
- break;
88
- case Tag::NOSCRIPT:
89
- $document->head->removeChild($headNode);
90
- break;
91
- }
92
  }
 
 
 
 
 
 
 
93
 
94
- $headNode = $nextSibling;
 
 
 
 
 
 
 
 
 
 
 
95
  }
 
 
96
  }
97
 
98
  /**
4
 
5
  use AmpProject\Amp;
6
  use AmpProject\Attribute;
 
7
  use AmpProject\Dom\Document;
8
  use AmpProject\Optimizer\ErrorCollection;
9
  use AmpProject\Optimizer\Transformer;
11
  use DOMElement;
12
 
13
  /**
14
+ * Transformer that removes AMP boilerplate <style> and <noscript> tags in <head>, keeping only the amp-custom style tag.
15
+ * It then (re-)inserts the amp-boilerplate unless the document is marked with the i-amphtml-no-boilerplate attribute.
16
  *
17
  * This is ported from the Go optimizer.
18
  *
67
  }
68
 
69
  /**
70
+ * Remove all <style> and <noscript> tags which are for the boilerplate.
71
  *
72
  * @param Document $document Document to remove the tags from.
73
  */
74
  private function removeStyleAndNoscriptTags(Document $document)
75
  {
76
+ /**
77
+ * Style element.
78
+ *
79
+ * @var DOMElement $style
80
+ */
81
+ foreach (iterator_to_array($document->head->getElementsByTagName('style')) as $style) {
82
+ if (! $this->isBoilerplateStyle($style)) {
83
+ continue;
 
 
 
 
 
 
 
84
  }
85
+ if (Tag::NOSCRIPT === $style->parentNode->nodeName) {
86
+ $style->parentNode->parentNode->removeChild($style->parentNode);
87
+ } else {
88
+ $style->parentNode->removeChild($style);
89
+ }
90
+ }
91
+ }
92
 
93
+ /**
94
+ * Check whether an element is a boilerplate style.
95
+ *
96
+ * @param DOMElement $element Element to check.
97
+ * @return bool Whether the element is a boilerplate style.
98
+ */
99
+ private function isBoilerplateStyle(DOMElement $element)
100
+ {
101
+ foreach (Attribute::ALL_BOILERPLATES as $boilerplate) {
102
+ if ($element->hasAttribute($boilerplate)) {
103
+ return true;
104
+ }
105
  }
106
+
107
+ return false;
108
  }
109
 
110
  /**
vendor/ampproject/optimizer/src/Transformer/ServerSideRendering.php CHANGED
@@ -11,6 +11,7 @@ use AmpProject\Layout;
11
  use AmpProject\Optimizer\Error;
12
  use AmpProject\Optimizer\ErrorCollection;
13
  use AmpProject\Optimizer\Transformer;
 
14
  use AmpProject\Tag;
15
  use DOMElement;
16
 
@@ -525,7 +526,7 @@ final class ServerSideRendering implements Transformer
525
  $sizer_img->setAttribute(Attribute::ALT, '');
526
  $sizer_img->setAttribute(Attribute::ARIA_HIDDEN, 'true');
527
  $sizer_img->setAttribute(Attribute::CLASS_, Amp::INTRINSIC_SIZER_ELEMENT);
528
- $sizer_img->setAttribute(Attribute::ROLE, 'presentation');
529
 
530
  // Temporarily cast decimal dimensions to integers. Can be reverted when/if the AMP Validator allows decimals.
531
  // Note that the floor value is used because two elements with width=99.5 in a container 199px-wide will not fit
11
  use AmpProject\Optimizer\Error;
12
  use AmpProject\Optimizer\ErrorCollection;
13
  use AmpProject\Optimizer\Transformer;
14
+ use AmpProject\Role;
15
  use AmpProject\Tag;
16
  use DOMElement;
17
 
526
  $sizer_img->setAttribute(Attribute::ALT, '');
527
  $sizer_img->setAttribute(Attribute::ARIA_HIDDEN, 'true');
528
  $sizer_img->setAttribute(Attribute::CLASS_, Amp::INTRINSIC_SIZER_ELEMENT);
529
+ $sizer_img->setAttribute(Attribute::ROLE, Role::PRESENTATION);
530
 
531
  // Temporarily cast decimal dimensions to integers. Can be reverted when/if the AMP Validator allows decimals.
532
  // Note that the floor value is used because two elements with width=99.5 in a container 199px-wide will not fit
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit0c4a9bc9296b6e3c5b3991f4494de9ef::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit4ec3764ba81323ddf112cd91ef3337df::getLoader();
vendor/composer/autoload_classmap.php CHANGED
@@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  'AMP_Admin_Pointer' => $baseDir . '/includes/admin/class-amp-admin-pointer.php',
10
  'AMP_Admin_Pointers' => $baseDir . '/includes/admin/class-amp-admin-pointers.php',
11
  'AMP_Allowed_Tags_Generated' => $baseDir . '/includes/sanitizers/class-amp-allowed-tags-generated.php',
@@ -90,6 +91,7 @@ return array(
90
  'AMP_WordPress_TV_Embed_Handler' => $baseDir . '/includes/embeds/class-amp-wordpress-tv-embed-handler.php',
91
  'AMP_YouTube_Embed_Handler' => $baseDir . '/includes/embeds/class-amp-youtube-embed-handler.php',
92
  'AmpProject\\Amp' => $vendorDir . '/ampproject/common/src/Amp.php',
 
93
  'AmpProject\\AmpWP\\Admin\\SiteHealth' => $baseDir . '/src/Admin/SiteHealth.php',
94
  'AmpProject\\AmpWP\\BackgroundTask\\CronBasedBackgroundTask' => $baseDir . '/src/BackgroundTask/CronBasedBackgroundTask.php',
95
  'AmpProject\\AmpWP\\BackgroundTask\\MonitorCssTransientCaching' => $baseDir . '/src/BackgroundTask/MonitorCssTransientCaching.php',
@@ -154,6 +156,7 @@ return array(
154
  'AmpProject\\RemoteRequest\\RemoteGetRequestResponse' => $vendorDir . '/ampproject/common/src/RemoteRequest/RemoteGetRequestResponse.php',
155
  'AmpProject\\RemoteRequest\\StubbedRemoteGetRequest' => $vendorDir . '/ampproject/common/src/RemoteRequest/StubbedRemoteGetRequest.php',
156
  'AmpProject\\Response' => $vendorDir . '/ampproject/common/src/Response.php',
 
157
  'AmpProject\\RuntimeVersion' => $vendorDir . '/ampproject/common/src/RuntimeVersion.php',
158
  'AmpProject\\Tag' => $vendorDir . '/ampproject/common/src/Tag.php',
159
  'FasterImage\\Exception\\InvalidImageException' => $vendorDir . '/fasterimage/fasterimage/src/FasterImage/Exception/InvalidImageException.php',
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'AMP_Accessibility_Sanitizer' => $baseDir . '/includes/sanitizers/class-amp-accessibility-sanitizer.php',
10
  'AMP_Admin_Pointer' => $baseDir . '/includes/admin/class-amp-admin-pointer.php',
11
  'AMP_Admin_Pointers' => $baseDir . '/includes/admin/class-amp-admin-pointers.php',
12
  'AMP_Allowed_Tags_Generated' => $baseDir . '/includes/sanitizers/class-amp-allowed-tags-generated.php',
91
  'AMP_WordPress_TV_Embed_Handler' => $baseDir . '/includes/embeds/class-amp-wordpress-tv-embed-handler.php',
92
  'AMP_YouTube_Embed_Handler' => $baseDir . '/includes/embeds/class-amp-youtube-embed-handler.php',
93
  'AmpProject\\Amp' => $vendorDir . '/ampproject/common/src/Amp.php',
94
+ 'AmpProject\\AmpWP\\Admin\\ReenableCssTransientCachingAjaxAction' => $baseDir . '/src/Admin/ReenableCssTransientCachingAjaxAction.php',
95
  'AmpProject\\AmpWP\\Admin\\SiteHealth' => $baseDir . '/src/Admin/SiteHealth.php',
96
  'AmpProject\\AmpWP\\BackgroundTask\\CronBasedBackgroundTask' => $baseDir . '/src/BackgroundTask/CronBasedBackgroundTask.php',
97
  'AmpProject\\AmpWP\\BackgroundTask\\MonitorCssTransientCaching' => $baseDir . '/src/BackgroundTask/MonitorCssTransientCaching.php',
156
  'AmpProject\\RemoteRequest\\RemoteGetRequestResponse' => $vendorDir . '/ampproject/common/src/RemoteRequest/RemoteGetRequestResponse.php',
157
  'AmpProject\\RemoteRequest\\StubbedRemoteGetRequest' => $vendorDir . '/ampproject/common/src/RemoteRequest/StubbedRemoteGetRequest.php',
158
  'AmpProject\\Response' => $vendorDir . '/ampproject/common/src/Response.php',
159
+ 'AmpProject\\Role' => $vendorDir . '/ampproject/common/src/Role.php',
160
  'AmpProject\\RuntimeVersion' => $vendorDir . '/ampproject/common/src/RuntimeVersion.php',
161
  'AmpProject\\Tag' => $vendorDir . '/ampproject/common/src/Tag.php',
162
  'FasterImage\\Exception\\InvalidImageException' => $vendorDir . '/fasterimage/fasterimage/src/FasterImage/Exception/InvalidImageException.php',
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit0c4a9bc9296b6e3c5b3991f4494de9ef
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit0c4a9bc9296b6e3c5b3991f4494de9ef
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInit0c4a9bc9296b6e3c5b3991f4494de9ef', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
- spl_autoload_unregister(array('ComposerAutoloaderInit0c4a9bc9296b6e3c5b3991f4494de9ef', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
- call_user_func(\Composer\Autoload\ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
@@ -51,19 +51,19 @@ class ComposerAutoloaderInit0c4a9bc9296b6e3c5b3991f4494de9ef
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
- $includeFiles = Composer\Autoload\ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
- composerRequire0c4a9bc9296b6e3c5b3991f4494de9ef($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
- function composerRequire0c4a9bc9296b6e3c5b3991f4494de9ef($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit4ec3764ba81323ddf112cd91ef3337df
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit4ec3764ba81323ddf112cd91ef3337df', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit4ec3764ba81323ddf112cd91ef3337df', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit4ec3764ba81323ddf112cd91ef3337df::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInit4ec3764ba81323ddf112cd91ef3337df::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire4ec3764ba81323ddf112cd91ef3337df($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequire4ec3764ba81323ddf112cd91ef3337df($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef
8
  {
9
  public static $files = array (
10
  '6f5653f9af3eab04254ad2c7f20515c8' => __DIR__ . '/../..' . '/back-compat/back-compat.php',
@@ -56,6 +56,7 @@ class ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef
56
  );
57
 
58
  public static $classMap = array (
 
59
  'AMP_Admin_Pointer' => __DIR__ . '/../..' . '/includes/admin/class-amp-admin-pointer.php',
60
  'AMP_Admin_Pointers' => __DIR__ . '/../..' . '/includes/admin/class-amp-admin-pointers.php',
61
  'AMP_Allowed_Tags_Generated' => __DIR__ . '/../..' . '/includes/sanitizers/class-amp-allowed-tags-generated.php',
@@ -140,6 +141,7 @@ class ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef
140
  'AMP_WordPress_TV_Embed_Handler' => __DIR__ . '/../..' . '/includes/embeds/class-amp-wordpress-tv-embed-handler.php',
141
  'AMP_YouTube_Embed_Handler' => __DIR__ . '/../..' . '/includes/embeds/class-amp-youtube-embed-handler.php',
142
  'AmpProject\\Amp' => __DIR__ . '/..' . '/ampproject/common/src/Amp.php',
 
143
  'AmpProject\\AmpWP\\Admin\\SiteHealth' => __DIR__ . '/../..' . '/src/Admin/SiteHealth.php',
144
  'AmpProject\\AmpWP\\BackgroundTask\\CronBasedBackgroundTask' => __DIR__ . '/../..' . '/src/BackgroundTask/CronBasedBackgroundTask.php',
145
  'AmpProject\\AmpWP\\BackgroundTask\\MonitorCssTransientCaching' => __DIR__ . '/../..' . '/src/BackgroundTask/MonitorCssTransientCaching.php',
@@ -204,6 +206,7 @@ class ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef
204
  'AmpProject\\RemoteRequest\\RemoteGetRequestResponse' => __DIR__ . '/..' . '/ampproject/common/src/RemoteRequest/RemoteGetRequestResponse.php',
205
  'AmpProject\\RemoteRequest\\StubbedRemoteGetRequest' => __DIR__ . '/..' . '/ampproject/common/src/RemoteRequest/StubbedRemoteGetRequest.php',
206
  'AmpProject\\Response' => __DIR__ . '/..' . '/ampproject/common/src/Response.php',
 
207
  'AmpProject\\RuntimeVersion' => __DIR__ . '/..' . '/ampproject/common/src/RuntimeVersion.php',
208
  'AmpProject\\Tag' => __DIR__ . '/..' . '/ampproject/common/src/Tag.php',
209
  'FasterImage\\Exception\\InvalidImageException' => __DIR__ . '/..' . '/fasterimage/fasterimage/src/FasterImage/Exception/InvalidImageException.php',
@@ -255,10 +258,10 @@ class ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef
255
  public static function getInitializer(ClassLoader $loader)
256
  {
257
  return \Closure::bind(function () use ($loader) {
258
- $loader->prefixLengthsPsr4 = ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef::$prefixLengthsPsr4;
259
- $loader->prefixDirsPsr4 = ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef::$prefixDirsPsr4;
260
- $loader->prefixesPsr0 = ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef::$prefixesPsr0;
261
- $loader->classMap = ComposerStaticInit0c4a9bc9296b6e3c5b3991f4494de9ef::$classMap;
262
 
263
  }, null, ClassLoader::class);
264
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit4ec3764ba81323ddf112cd91ef3337df
8
  {
9
  public static $files = array (
10
  '6f5653f9af3eab04254ad2c7f20515c8' => __DIR__ . '/../..' . '/back-compat/back-compat.php',
56
  );
57
 
58
  public static $classMap = array (
59
+ 'AMP_Accessibility_Sanitizer' => __DIR__ . '/../..' . '/includes/sanitizers/class-amp-accessibility-sanitizer.php',
60
  'AMP_Admin_Pointer' => __DIR__ . '/../..' . '/includes/admin/class-amp-admin-pointer.php',
61
  'AMP_Admin_Pointers' => __DIR__ . '/../..' . '/includes/admin/class-amp-admin-pointers.php',
62
  'AMP_Allowed_Tags_Generated' => __DIR__ . '/../..' . '/includes/sanitizers/class-amp-allowed-tags-generated.php',
141
  'AMP_WordPress_TV_Embed_Handler' => __DIR__ . '/../..' . '/includes/embeds/class-amp-wordpress-tv-embed-handler.php',
142
  'AMP_YouTube_Embed_Handler' => __DIR__ . '/../..' . '/includes/embeds/class-amp-youtube-embed-handler.php',
143
  'AmpProject\\Amp' => __DIR__ . '/..' . '/ampproject/common/src/Amp.php',
144
+ 'AmpProject\\AmpWP\\Admin\\ReenableCssTransientCachingAjaxAction' => __DIR__ . '/../..' . '/src/Admin/ReenableCssTransientCachingAjaxAction.php',
145
  'AmpProject\\AmpWP\\Admin\\SiteHealth' => __DIR__ . '/../..' . '/src/Admin/SiteHealth.php',
146
  'AmpProject\\AmpWP\\BackgroundTask\\CronBasedBackgroundTask' => __DIR__ . '/../..' . '/src/BackgroundTask/CronBasedBackgroundTask.php',
147
  'AmpProject\\AmpWP\\BackgroundTask\\MonitorCssTransientCaching' => __DIR__ . '/../..' . '/src/BackgroundTask/MonitorCssTransientCaching.php',
206
  'AmpProject\\RemoteRequest\\RemoteGetRequestResponse' => __DIR__ . '/..' . '/ampproject/common/src/RemoteRequest/RemoteGetRequestResponse.php',
207
  'AmpProject\\RemoteRequest\\StubbedRemoteGetRequest' => __DIR__ . '/..' . '/ampproject/common/src/RemoteRequest/StubbedRemoteGetRequest.php',
208
  'AmpProject\\Response' => __DIR__ . '/..' . '/ampproject/common/src/Response.php',
209
+ 'AmpProject\\Role' => __DIR__ . '/..' . '/ampproject/common/src/Role.php',
210
  'AmpProject\\RuntimeVersion' => __DIR__ . '/..' . '/ampproject/common/src/RuntimeVersion.php',
211
  'AmpProject\\Tag' => __DIR__ . '/..' . '/ampproject/common/src/Tag.php',
212
  'FasterImage\\Exception\\InvalidImageException' => __DIR__ . '/..' . '/fasterimage/fasterimage/src/FasterImage/Exception/InvalidImageException.php',
258
  public static function getInitializer(ClassLoader $loader)
259
  {
260
  return \Closure::bind(function () use ($loader) {
261
+ $loader->prefixLengthsPsr4 = ComposerStaticInit4ec3764ba81323ddf112cd91ef3337df::$prefixLengthsPsr4;
262
+ $loader->prefixDirsPsr4 = ComposerStaticInit4ec3764ba81323ddf112cd91ef3337df::$prefixDirsPsr4;
263
+ $loader->prefixesPsr0 = ComposerStaticInit4ec3764ba81323ddf112cd91ef3337df::$prefixesPsr0;
264
+ $loader->classMap = ComposerStaticInit4ec3764ba81323ddf112cd91ef3337df::$classMap;
265
 
266
  }, null, ClassLoader::class);
267
  }