Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce length of specificity-hacked CSS selectors #6312

Merged
merged 6 commits into from
Mar 3, 2022
Merged
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
17 changes: 8 additions & 9 deletions includes/sanitizers/class-amp-style-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1645,7 +1645,7 @@ private function fetch_external_stylesheet( $url ) {
*/
private function get_parsed_stylesheet( $stylesheet, $options = [] ) {
$cached = true;
$cache_group = 'amp-parsed-stylesheet-v38'; // This should be bumped whenever the PHP-CSS-Parser is updated or parsed format is updated.
$cache_group = 'amp-parsed-stylesheet-v39'; // This should be bumped whenever the PHP-CSS-Parser is updated or parsed format is updated.
$use_transients = $this->should_use_transient_caching();

// @todo If ValidationExemption::is_px_verified_for_node( $this->current_node ) then keep !important.
Expand Down Expand Up @@ -2917,16 +2917,15 @@ static function( Selector $old_selector ) {
if ( $old_selector->getSpecificity() % 10 > 0 ) {
$specificity_multiplier++;
}
$selector_mod = str_repeat( ':not(#_)', $specificity_multiplier ); // Here "_" is just a short single-char ID.

$new_selector = $old_selector->getSelector();

// Amend the selector mod to the first element in selector if it is already the root; otherwise add new root ancestor.
if ( preg_match( '/^\s*(html|:root)\b/i', $new_selector, $matches ) ) {
$new_selector = substr( $new_selector, 0, strlen( $matches[0] ) ) . $selector_mod . substr( $new_selector, strlen( $matches[0] ) );
if ( '#_)' === substr( $new_selector, -3 ) ) {
$new_selector = rtrim( $new_selector, ')' ) . str_repeat( '#_', $specificity_multiplier ) . ')';
} else {
$new_selector = sprintf( ':root%s %s', $selector_mod, $new_selector );
$new_selector .= ':not(' . str_repeat( '#_', $specificity_multiplier ) . ')'; // Here "_" is just a short single-char ID.
}

return new Selector( $new_selector );
},
$ruleset->getSelectors()
Expand Down Expand Up @@ -2975,9 +2974,9 @@ private function collect_inline_styles( DOMElement $element ) {
return;
}

$class = 'amp-wp-' . substr( md5( $value ), 0, 7 );
$root = ':root' . str_repeat( ':not(#_)', self::INLINE_SPECIFICITY_MULTIPLIER );
$rule = sprintf( '%s .%s { %s }', $root, $class, $value );
$class = 'amp-wp-' . substr( md5( $value ), 0, 7 );
$specificity = ':not(' . str_repeat( '#_', self::INLINE_SPECIFICITY_MULTIPLIER ) . ')';
$rule = sprintf( '.%s%s{%s}', $class, $specificity, $value );

$this->set_current_node( $element ); // And sources when needing to be located.

Expand Down
8 changes: 8 additions & 0 deletions includes/validation/class-amp-validated-url-post-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -2812,6 +2812,14 @@ static function ( $a, $b ) use ( $stylesheets ) {
$selector_html
);
}
$selector_html = preg_replace(
'/:not\((#_)+\)/',
sprintf(
'<abbr title="%s">$0</abbr>',
esc_attr__( 'Pseudo-class selector used to increase specificity for rule extracted from inline styles and/or properties with !important qualifiers.', 'amp' )
),
$selector_html
);

echo $selector_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

Expand Down
6 changes: 3 additions & 3 deletions tests/php/test-amp-bento-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function get_sanitizer_data() {
<html>
<head>
<meta charset="utf-8">
<style amp-custom>#my-accordion{display:block;outline:solid 2px red}amp-accordion#my-accordion{outline:solid 2px green}amp-accordion h2{text-transform:uppercase}:root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-a33452e{border:solid 1px black}
<style amp-custom>#my-accordion{display:block;outline:solid 2px red}amp-accordion#my-accordion{outline:solid 2px green}amp-accordion h2{text-transform:uppercase}.amp-wp-a33452e:not(#_#_#_#_#_){border:solid 1px black}

/*# sourceURL="amp-custom.css" */</style>
</head>
Expand Down Expand Up @@ -245,7 +245,7 @@ public function get_sanitizer_data() {
<script type="module" async="" src="https://cdn.ampproject.org/v0/bento-marquee-1.0.mjs" data-px-verified-tag></script>
<script nomodule="" async="" src="https://cdn.ampproject.org/v0/bento-marquee-1.0.js" data-px-verified-tag></script>
<link rel="stylesheet" type="text/css" href="https://cdn.ampproject.org/v0/bento-marquee-1.0.css" data-px-verified-tag data-px-verified-attrs="href">
<style amp-custom>#timeago{color:red}amp-timeago#timeago{color:blue}#marquee{display:block;outline:solid 2px red}bento-marquee#marquee{outline:solid 2px green}bento-marquee h2{text-transform:uppercase}:root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-c437205{border:solid 1px green}:root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-4d7586b{max-width:50vw}:root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-4ce7767{position:relative;width:100%;height:400px}
<style amp-custom>#timeago{color:red}amp-timeago#timeago{color:blue}#marquee{display:block;outline:solid 2px red}bento-marquee#marquee{outline:solid 2px green}bento-marquee h2{text-transform:uppercase}.amp-wp-c437205:not(#_#_#_#_#_){border:solid 1px green}.amp-wp-4d7586b:not(#_#_#_#_#_){max-width:50vw}.amp-wp-4ce7767:not(#_#_#_#_#_){position:relative;width:100%;height:400px}

/*# sourceURL="amp-custom.css" */</style>
</head>
Expand Down Expand Up @@ -415,7 +415,7 @@ public function get_sanitizer_data() {
<html>
<head>
<meta charset="utf-8">
<style amp-custom>:root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-3ef80bd{height:40px}:root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-120213e{height:40px;width:147px}
<style amp-custom>.amp-wp-3ef80bd:not(#_#_#_#_#_){height:40px}.amp-wp-120213e:not(#_#_#_#_#_){height:40px;width:147px}

/*# sourceURL="amp-custom.css" */</style>
</head>
Expand Down
2 changes: 1 addition & 1 deletion tests/php/test-amp-script-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ function ( Element $element ) {
$this->assertStringContainsString( '}amp-audio{', $css_text );
break;
case 3:
$this->assertStringContainsString( ':not(#_) amp-audio{', $css_text );
$this->assertStringContainsString( '}amp-audio:not(#_', $css_text );
break;
}

Expand Down
66 changes: 33 additions & 33 deletions tests/php/test-amp-style-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public function get_body_style_attribute_data() {
'<span style="color: #00ff00;">This is green.</span>',
'<span data-amp-original-style="color: #00ff00;" class="amp-wp-bb01159">This is green.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-bb01159{color:#0f0}',
'.amp-wp-bb01159:not(#_#_#_#_#_){color:#0f0}',
],
],

Expand All @@ -86,81 +86,81 @@ public function get_body_style_attribute_data() {
'<span style="color : #00ff00">This is green.</span>',
'<span data-amp-original-style="color : #00ff00" class="amp-wp-0837823">This is green.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-0837823{color:#0f0}',
'.amp-wp-0837823:not(#_#_#_#_#_){color:#0f0}',
],
],

'span_two_styles_reversed' => [
'<span style="color: #00ff00; background-color: #000;">This is green.</span>',
'<span data-amp-original-style="color: #00ff00; background-color: #000;" class="amp-wp-be0c539">This is green.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-be0c539{color:#0f0;background-color:#000}',
'.amp-wp-be0c539:not(#_#_#_#_#_){color:#0f0;background-color:#000}',
],
],

'span_display_none' => [
'<span style="display: none;">Kses-banned properties are allowed since Kses will have already applied if user does not have unfiltered_html.</span>',
'<span data-amp-original-style="display: none;" class="amp-wp-224b51a">Kses-banned properties are allowed since Kses will have already applied if user does not have unfiltered_html.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-224b51a{display:none}',
'.amp-wp-224b51a:not(#_#_#_#_#_){display:none}',
],
],

'!important_is_ok' => [
'<span style="padding:1px; margin: 2px !important; outline: 3px;">!important is converted.</span>',
'<span data-amp-original-style="padding:1px; margin: 2px !important; outline: 3px;" class="amp-wp-6a75598">!important is converted.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-6a75598{padding:1px;outline:3px}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-6a75598{margin:2px}',
'.amp-wp-6a75598:not(#_#_#_#_#_){padding:1px;outline:3px}.amp-wp-6a75598:not(#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_){margin:2px}',
],
],

'!important_with_spaces_also_converted' => [
'<span style="color: red ! important;">!important is converted.</span>',
'<span data-amp-original-style="color: red ! important;" class="amp-wp-952600b">!important is converted.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-952600b{color:red}',
'.amp-wp-952600b:not(#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_){color:red}',
],
],

'!important_multiple_is_converted' => [
'<span style="color: red !important; background: blue!important;">!important is converted.</span>',
'<span data-amp-original-style="color: red !important; background: blue!important;" class="amp-wp-1e2bfaa">!important is converted.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-1e2bfaa{color:red;background:blue}',
'.amp-wp-1e2bfaa:not(#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_){color:red;background:blue}',
],
],

'!important_takes_precedence_over_inline' => [
'<header id="header" style="display: none;"><h1>This is the header.</h1></header><style>#header { display: block !important;width: 100%;background: #fff; }',
'<header id="header" data-amp-original-style="display: none;" class="amp-wp-224b51a"><h1>This is the header.</h1></header>',
[
'#header{width:100%;background:#fff}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) #header{display:block}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-224b51a{display:none}',
'#header{width:100%;background:#fff}#header:not(#_#_#_#_#_#_#_){display:block}',
'.amp-wp-224b51a:not(#_#_#_#_#_){display:none}',
],
],

'two_nodes' => [
'<span style="color: #00ff00;"><span style="color: #ff0000;">This is red.</span></span>',
'<span data-amp-original-style="color: #00ff00;" class="amp-wp-bb01159"><span data-amp-original-style="color: #ff0000;" class="amp-wp-cc68ddc">This is red.</span></span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-bb01159{color:#0f0}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-cc68ddc{color:#f00}',
'.amp-wp-bb01159:not(#_#_#_#_#_){color:#0f0}',
'.amp-wp-cc68ddc:not(#_#_#_#_#_){color:#f00}',
],
],

'existing_class_attribute' => [
'<figure class="alignleft" style="background: #000"></figure>',
'<figure class="alignleft amp-wp-2864855" data-amp-original-style="background: #000"></figure>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-2864855{background:#000}',
'.amp-wp-2864855:not(#_#_#_#_#_){background:#000}',
],
],

'inline_style_element_with_multiple_rules_containing_selectors_is_removed' => [
'<style>div > span { font-weight:bold !important; font-style: italic; } @media screen and ( max-width: 640px ) { div > span { font-weight:normal !important; font-style: normal; } }</style><div><span>bold!</span></div>',
'<div><span>bold!</span></div>',
[
'div > span{font-style:italic}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) div > span{font-weight:bold}@media screen and ( max-width: 640px ){div > span{font-style:normal}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) div > span{font-weight:normal}}',
'div > span{font-style:italic}div > span:not(#_#_#_#_#_#_#_#_){font-weight:bold}@media screen and ( max-width: 640px ){div > span{font-style:normal}div > span:not(#_#_#_#_#_#_#_#_){font-weight:normal}}',
],
],

Expand All @@ -178,7 +178,7 @@ public function get_body_style_attribute_data() {
'<span style="color:brown; @media screen { color:green }">invalid @-rule omitted.</span>',
'<span data-amp-original-style="color:brown; @media screen { color:green }" class="amp-wp-481af57">invalid @-rule omitted.</span>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-481af57{color:brown}',
'.amp-wp-481af57:not(#_#_#_#_#_){color:brown}',
],
[],
],
Expand Down Expand Up @@ -247,9 +247,9 @@ public function get_body_style_attribute_data() {
'<style>#child {color:red !important} #parent #child {color:pink !important} .foo { color:blue !important; } #me .foo { color: green !important; }</style><div id="parent"><span id="child" class="foo bar baz">one</span><span style="color: yellow;">two</span><span style="color: purple !important;">three</span></div><div id="me"><span class="foo"></span></div>',
'<div id="parent"><span id="child" class="foo bar baz">one</span><span data-amp-original-style="color: yellow;" class="amp-wp-64b4fd4">two</span><span data-amp-original-style="color: purple !important;" class="amp-wp-ab79d9e">three</span></div><div id="me"><span class="foo"></span></div>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) #child{color:red}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) #parent #child{color:pink}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .foo{color:blue}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) #me .foo{color:green}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-64b4fd4{color:yellow}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-ab79d9e{color:purple}',
'#child:not(#_#_#_#_#_#_#_){color:red}#parent #child:not(#_#_#_#_#_#_#_#_){color:pink}.foo:not(#_#_#_#_#_#_#_){color:blue}#me .foo:not(#_#_#_#_#_#_#_#_){color:green}',
'.amp-wp-64b4fd4:not(#_#_#_#_#_){color:yellow}',
'.amp-wp-ab79d9e:not(#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_){color:purple}',
],
],

Expand All @@ -265,15 +265,15 @@ public function get_body_style_attribute_data() {
'<table><colgroup><col width="253"/></colgroup></table>',
'<table><colgroup><col data-amp-original-style="width: 253px" class="amp-wp-cbcb5c2"></colgroup></table>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-cbcb5c2{width:253px}',
'.amp-wp-cbcb5c2:not(#_#_#_#_#_){width:253px}',
],
],

'col_with_percent_width_attribute' => [
'<table><colgroup><col width="50%"/></colgroup></table>',
'<table><colgroup><col data-amp-original-style="width: 50%" class="amp-wp-cd7753e"></colgroup></table>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-cd7753e{width:50%}',
'.amp-wp-cd7753e:not(#_#_#_#_#_){width:50%}',
],
],

Expand All @@ -288,7 +288,7 @@ public function get_body_style_attribute_data() {
'<table><colgroup><col width="50" style="background-color: red; width: 60px"/></colgroup></table>',
'<table><colgroup><col data-amp-original-style="width: 50px;background-color: red; width: 60px" class="amp-wp-c8aa9e9"></colgroup></table>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-c8aa9e9{width:50px;width:60px;background-color:red}',
'.amp-wp-c8aa9e9:not(#_#_#_#_#_){width:50px;width:60px;background-color:red}',
],
],

Expand Down Expand Up @@ -352,8 +352,8 @@ public function get_body_style_attribute_data() {
',
[
'.custom-population{color:red}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-f2a1aff{color:blue}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-d4ea4c7{outline:solid 1px black}',
'.amp-wp-f2a1aff:not(#_#_#_#_#_){color:blue}',
'.amp-wp-d4ea4c7:not(#_#_#_#_#_){outline:solid 1px black}',
],
],
'with_mustache_template_script' => [
Expand Down Expand Up @@ -386,8 +386,8 @@ public function get_body_style_attribute_data() {
',
[
'.custom-population{color:red}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-f2a1aff{color:blue}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-d4ea4c7{outline:solid 1px black}',
'.amp-wp-f2a1aff:not(#_#_#_#_#_){color:blue}',
'.amp-wp-d4ea4c7:not(#_#_#_#_#_){outline:solid 1px black}',
],
],
'with_internal_amp_selectors_and_class_names' => [
Expand Down Expand Up @@ -531,9 +531,9 @@ public function get_link_and_style_test_data() {
'multiple_amp_custom_and_other_styles' => [
'<html amp><head><meta charset="utf-8"><style amp-custom>b {color:red !important}</style><style amp-custom>i {color:blue}</style><style type="text/css">u {color:green; text-decoration: underline !important}</style></head><body><style>s {color:yellow} /* So !important! */</style><b>1</b><i>i</i><u>u</u><s>s</s></body></html>',
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) b{color:red}',
'b:not(#_#_#_#_#_#_#_#_){color:red}',
'i{color:blue}',
'u{color:green}:root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) u{text-decoration:underline}',
'u{color:green}u:not(#_#_#_#_#_#_#_#_){text-decoration:underline}',
's{color:yellow}',
],
[],
Expand All @@ -547,7 +547,7 @@ public function get_link_and_style_test_data() {
'strong.before-dashicon',
'.dashicons-dashboard:before',
'strong.after-dashicon',
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) s{color:yellow}',
's:not(#_#_#_#_#_#_#_#_){color:yellow}',
],
[],
],
Expand Down Expand Up @@ -575,8 +575,8 @@ public function get_link_and_style_test_data() {
'style_on_root_element' => [
'<html amp style="color:red;"><head><meta charset="utf-8"><style amp-custom>html { background-color: blue !important; }</style></head><body>Hi</body></html>',
[
'html:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_){background-color:blue}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-10b06ba{color:red}',
'html:not(#_#_#_#_#_#_#_#_){background-color:blue}',
'.amp-wp-10b06ba:not(#_#_#_#_#_){color:red}',
],
[],
],
Expand Down Expand Up @@ -1099,10 +1099,10 @@ public function get_data_to_test_transform_important_qualifiers_arg() {
true, // should_sanitize
$html,
[
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .foo{color:red}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .foo[data-amp-original-style*="blue"]{outline:solid 2px green}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-9605c4d{background:blue}',
':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-32bb249{background:red}',
'.foo:not(#_#_#_#_#_#_#_){color:red}',
'.foo[data-amp-original-style*="blue"]:not(#_#_#_#_#_#_#_){outline:solid 2px green}',
'.amp-wp-9605c4d:not(#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_){background:blue}',
'.amp-wp-32bb249:not(#_#_#_#_#_){background:red}',
],
'<style amp-custom>',
'
Expand Down
4 changes: 2 additions & 2 deletions tests/php/test-class-amp-content-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function test_sanitize_document() {
$sanitize_results['scripts']
);
$this->assertEquals(
[ ':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-9f6e771{outline:solid 1px red}' ],
[ '.amp-wp-9f6e771:not(#_#_#_#_#_){outline:solid 1px red}' ],
$sanitize_results['stylesheets']
);
$this->assertEmpty( $sanitize_results['styles'] );
Expand Down Expand Up @@ -74,7 +74,7 @@ public function test_sanitize_all() {
$expected_return = [
'<amp-video src="https://example.com/foo.mp4" width="100" height="200" layout="intrinsic" data-amp-original-style="outline: solid 1px red;" class="amp-wp-9f6e771"><a href="https://example.com/foo.mp4" fallback="">https://example.com/foo.mp4</a><noscript><video src="https://example.com/foo.mp4" width="100" height="200"></video></noscript></amp-video>',
[ 'amp-video' => true ],
[ ':root:not(#_):not(#_):not(#_):not(#_):not(#_) .amp-wp-9f6e771{outline:solid 1px red}' ],
[ '.amp-wp-9f6e771:not(#_#_#_#_#_){outline:solid 1px red}' ],
];

$actual_return = AMP_Content_Sanitizer::sanitize(
Expand Down
Loading