Skip to content

Commit 35bf862

Browse files
authored
Merge pull request #6546 from ampproject/add/sandboxing-levels
Experimental: Add sandboxing levels
2 parents 68bccbf + faaf295 commit 35bf862

35 files changed

+3383
-859
lines changed

.phpstorm.meta.php

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
'reader_theme_support_features' => \AmpProject\AmpWP\ReaderThemeSupportFeatures::class,
5252
'rest.options_controller' => \AmpProject\AmpWP\OptionsRESTController::class,
5353
'rest.validation_counts_controller' => \AmpProject\AmpWP\Validation\ValidationCountsRestController::class,
54+
'sandboxing' => \AmpProject\AmpWP\Sandboxing::class,
5455
'save_post_validation_event' => \AmpProject\AmpWP\Validation\SavePostValidationEvent::class,
5556
'server_timing' => \AmpProject\AmpWP\Instrumentation\ServerTiming::class,
5657
'site_health_integration' => \AmpProject\AmpWP\Admin\SiteHealth::class,

assets/src/settings-page/template-modes.js

+65-2
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ function getReaderNotice( selected ) {
101101
* @param {boolean} props.focusReaderThemes Whether the reader themes drawer should be opened and focused.
102102
*/
103103
export function TemplateModes( { focusReaderThemes } ) {
104-
const { editedOptions } = useContext( Options );
104+
const { editedOptions, updateOptions } = useContext( Options );
105105
const { selectedTheme, templateModeWasOverridden } = useContext( ReaderThemes );
106106

107-
const { theme_support: themeSupport } = editedOptions;
107+
const { theme_support: themeSupport, sandboxing_level: sandboxingLevel } = editedOptions;
108108

109109
const { readerNoticeSmall, readerNoticeLarge } = useMemo(
110110
() => getReaderNotice( READER === themeSupport ),
@@ -138,6 +138,69 @@ export function TemplateModes( { focusReaderThemes } ) {
138138
</AMPNotice>
139139
)
140140
}
141+
{
142+
sandboxingLevel && (
143+
<fieldset>
144+
<h4 className="title">
145+
{ __( 'Sandboxing Level (Experimental)', 'amp' ) }
146+
</h4>
147+
<p>
148+
{ __( 'Try out a more flexible AMP by generating pages that use AMP components without requiring AMP validity! By selecting a sandboxing level, you are indicating the minimum degree of sanitization. For example, if you selected level 1 but have a page without any POST form and no custom scripts, it will still be served as valid AMP, the same as if you had selected level 3.', 'amp' ) }
149+
</p>
150+
<ol>
151+
<li>
152+
<input
153+
type="radio"
154+
id="sandboxing-level-1"
155+
checked={ 1 === sandboxingLevel }
156+
onChange={ () => {
157+
updateOptions( { sandboxing_level: 1 } );
158+
} }
159+
/>
160+
<label htmlFor="sandboxing-level-1">
161+
<strong>
162+
{ __( 'Loose:', 'amp' ) }
163+
</strong>
164+
{ ' ' + __( 'Do not remove any AMP-invalid markup by default, including custom scripts. CSS tree-shaking is disabled.', 'amp' ) }
165+
</label>
166+
</li>
167+
<li>
168+
<input
169+
type="radio"
170+
id="sandboxing-level-2"
171+
checked={ 2 === sandboxingLevel }
172+
onChange={ () => {
173+
updateOptions( { sandboxing_level: 2 } );
174+
} }
175+
/>
176+
<label htmlFor="sandboxing-level-2">
177+
<strong>
178+
{ __( 'Moderate:', 'amp' ) }
179+
</strong>
180+
{ ' ' + __( 'Remove non-AMP markup, but allow POST forms. CSS tree shaking is enabled.', 'amp' ) }
181+
</label>
182+
</li>
183+
<li>
184+
<input
185+
type="radio"
186+
id="sandboxing-level-3"
187+
checked={ 3 === sandboxingLevel }
188+
onChange={ () => {
189+
updateOptions( { sandboxing_level: 3 } );
190+
} }
191+
/>
192+
<label htmlFor="sandboxing-level-3">
193+
<strong>
194+
{ __( 'Strict:', 'amp' ) }
195+
</strong>
196+
{ ' ' + __( 'Require valid AMP.', 'amp' ) }
197+
</label>
198+
</li>
199+
200+
</ol>
201+
</fieldset>
202+
)
203+
}
141204
</TemplateModeOption>
142205
<TemplateModeOption
143206
details={ __( 'In Transitional mode the active theme\'s templates are used to generate both the AMP and non-AMP versions of your content, allowing for each canonical URL to have a corresponding (paired) AMP URL. This mode is useful to progressively transition towards a fully AMP-compatible site. Depending on your themes/plugins, a varying level of development work may be required.', 'amp' ) }

includes/amp-helper-functions.php

+38-41
Original file line numberDiff line numberDiff line change
@@ -1405,10 +1405,6 @@ function amp_is_dev_mode() {
14051405
( is_admin_bar_showing() && is_user_logged_in() )
14061406
||
14071407
is_customize_preview()
1408-
||
1409-
// Force dev mode for Bento since it currently requires the Bento experiment opt-in script.
1410-
// @todo Remove this once Bento no longer requires an experiment to opt-in. See <https://amp.dev/documentation/guides-and-tutorials/start/bento_guide/?format=websites#enable-bento-experiment>.
1411-
amp_is_bento_enabled()
14121408
)
14131409
);
14141410
}
@@ -1435,26 +1431,6 @@ function amp_is_native_img_used() {
14351431
return (bool) apply_filters( 'amp_native_img_used', false );
14361432
}
14371433

1438-
/**
1439-
* Determine whether to allow native `POST` forms without conversion to use the `action-xhr` attribute and use the amp-form component.
1440-
*
1441-
* @since 2.2
1442-
* @link https://github.com/ampproject/amphtml/issues/27638
1443-
*
1444-
* @return bool Whether to allow native `POST` forms.
1445-
*/
1446-
function amp_is_native_post_form_allowed() {
1447-
/**
1448-
* Filters whether to allow native `POST` forms without conversion to use the `action-xhr` attribute and use the amp-form component.
1449-
*
1450-
* @since 2.2
1451-
* @link https://github.com/ampproject/amphtml/issues/27638
1452-
*
1453-
* @param bool $use_native Whether to allow native `POST` forms.
1454-
*/
1455-
return (bool) apply_filters( 'amp_native_post_form_allowed', false );
1456-
}
1457-
14581434
/**
14591435
* Get content sanitizers.
14601436
*
@@ -1499,18 +1475,16 @@ function amp_get_content_sanitizers( $post = null ) {
14991475
AMP_Theme_Support::TRANSITIONAL_MODE_SLUG === AMP_Options_Manager::get_option( Option::THEME_SUPPORT )
15001476
);
15011477

1502-
$native_img_used = amp_is_native_img_used();
1503-
$native_post_forms_allowed = amp_is_native_post_form_allowed();
1478+
$native_img_used = amp_is_native_img_used();
15041479

15051480
$sanitizers = [
1506-
// The AMP_Script_Sanitizer runs first because based on whether it allows custom scripts
1507-
// to be kept, it may impact the behavior of other sanitizers. For example, if custom
1508-
// scripts are kept then this is a signal that tree shaking in AMP_Style_Sanitizer cannot be
1509-
// performed.
1510-
AMP_Script_Sanitizer::class => [],
1481+
// Embed sanitization must come first because it strips out custom scripts associated with embeds.
15111482
AMP_Embed_Sanitizer::class => [
15121483
'amp_to_amp_linking_enabled' => $amp_to_amp_linking_enabled,
15131484
],
1485+
AMP_O2_Player_Sanitizer::class => [],
1486+
AMP_Playbuzz_Sanitizer::class => [],
1487+
15141488
AMP_Core_Theme_Sanitizer::class => [
15151489
'template' => get_template(),
15161490
'stylesheet' => get_stylesheet(),
@@ -1519,21 +1493,25 @@ function amp_get_content_sanitizers( $post = null ) {
15191493
],
15201494
'native_img_used' => $native_img_used,
15211495
],
1496+
1497+
AMP_Comments_Sanitizer::class => [
1498+
'comments_live_list' => ! empty( $theme_support_args['comments_live_list'] ),
1499+
],
1500+
1501+
// The AMP_Script_Sanitizer runs here because based on whether it allows custom scripts
1502+
// to be kept, it may impact the behavior of other sanitizers. For example, if custom
1503+
// scripts are kept then this is a signal that tree shaking in AMP_Style_Sanitizer cannot be
1504+
// performed.
1505+
AMP_Script_Sanitizer::class => [],
1506+
15221507
AMP_Srcset_Sanitizer::class => [],
15231508
AMP_Img_Sanitizer::class => [
15241509
'align_wide_support' => current_theme_supports( 'align-wide' ),
15251510
'native_img_used' => $native_img_used,
15261511
],
1527-
AMP_Form_Sanitizer::class => [
1528-
'native_post_forms_allowed' => $native_post_forms_allowed,
1529-
],
1530-
AMP_Comments_Sanitizer::class => [
1531-
'comments_live_list' => ! empty( $theme_support_args['comments_live_list'] ),
1532-
],
1512+
AMP_Form_Sanitizer::class => [],
15331513
AMP_Video_Sanitizer::class => [],
1534-
AMP_O2_Player_Sanitizer::class => [],
15351514
AMP_Audio_Sanitizer::class => [],
1536-
AMP_Playbuzz_Sanitizer::class => [],
15371515
AMP_Object_Sanitizer::class => [],
15381516
AMP_Iframe_Sanitizer::class => [
15391517
'add_placeholder' => true,
@@ -1651,8 +1629,27 @@ function amp_get_content_sanitizers( $post = null ) {
16511629
*/
16521630
$sanitizers[ AMP_Style_Sanitizer::class ]['allow_transient_caching'] = apply_filters( 'amp_parsed_css_transient_caching_allowed', true );
16531631

1654-
// Force layout, style, meta, and validating sanitizers to be at the end.
1655-
foreach ( [ AMP_Layout_Sanitizer::class, AMP_Style_Sanitizer::class, AMP_Meta_Sanitizer::class, AMP_Tag_And_Attribute_Sanitizer::class ] as $class_name ) {
1632+
// Force core essential sanitizers to appear at the end at the end, with non-essential and third-party sanitizers appearing before.
1633+
$expected_final_sanitizer_order = [
1634+
AMP_Core_Theme_Sanitizer::class, // Must come before script sanitizer since onclick attributes are removed.
1635+
AMP_Script_Sanitizer::class, // Must come before sanitizers for images, videos, audios, comments, forms, and styles.
1636+
AMP_Form_Sanitizer::class, // Must come before comments sanitizer.
1637+
AMP_Comments_Sanitizer::class, // Also must come after the form sanitizer.
1638+
AMP_Srcset_Sanitizer::class,
1639+
AMP_Img_Sanitizer::class,
1640+
AMP_Video_Sanitizer::class,
1641+
AMP_Audio_Sanitizer::class,
1642+
AMP_Object_Sanitizer::class,
1643+
AMP_Iframe_Sanitizer::class,
1644+
AMP_Gallery_Block_Sanitizer::class,
1645+
AMP_Block_Sanitizer::class,
1646+
AMP_Accessibility_Sanitizer::class,
1647+
AMP_Layout_Sanitizer::class,
1648+
AMP_Style_Sanitizer::class,
1649+
AMP_Meta_Sanitizer::class,
1650+
AMP_Tag_And_Attribute_Sanitizer::class,
1651+
];
1652+
foreach ( $expected_final_sanitizer_order as $class_name ) {
16561653
if ( isset( $sanitizers[ $class_name ] ) ) {
16571654
$sanitizer = $sanitizers[ $class_name ];
16581655
unset( $sanitizers[ $class_name ] );

0 commit comments

Comments
 (0)