Skip to content

Commit

Permalink
Merge pull request #6546 from ampproject/add/sandboxing-levels
Browse files Browse the repository at this point in the history
Experimental: Add sandboxing levels
  • Loading branch information
westonruter authored Oct 13, 2021
2 parents 68bccbf + faaf295 commit 35bf862
Show file tree
Hide file tree
Showing 35 changed files with 3,383 additions and 859 deletions.
1 change: 1 addition & 0 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
'reader_theme_support_features' => \AmpProject\AmpWP\ReaderThemeSupportFeatures::class,
'rest.options_controller' => \AmpProject\AmpWP\OptionsRESTController::class,
'rest.validation_counts_controller' => \AmpProject\AmpWP\Validation\ValidationCountsRestController::class,
'sandboxing' => \AmpProject\AmpWP\Sandboxing::class,
'save_post_validation_event' => \AmpProject\AmpWP\Validation\SavePostValidationEvent::class,
'server_timing' => \AmpProject\AmpWP\Instrumentation\ServerTiming::class,
'site_health_integration' => \AmpProject\AmpWP\Admin\SiteHealth::class,
Expand Down
67 changes: 65 additions & 2 deletions assets/src/settings-page/template-modes.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ function getReaderNotice( selected ) {
* @param {boolean} props.focusReaderThemes Whether the reader themes drawer should be opened and focused.
*/
export function TemplateModes( { focusReaderThemes } ) {
const { editedOptions } = useContext( Options );
const { editedOptions, updateOptions } = useContext( Options );
const { selectedTheme, templateModeWasOverridden } = useContext( ReaderThemes );

const { theme_support: themeSupport } = editedOptions;
const { theme_support: themeSupport, sandboxing_level: sandboxingLevel } = editedOptions;

const { readerNoticeSmall, readerNoticeLarge } = useMemo(
() => getReaderNotice( READER === themeSupport ),
Expand Down Expand Up @@ -138,6 +138,69 @@ export function TemplateModes( { focusReaderThemes } ) {
</AMPNotice>
)
}
{
sandboxingLevel && (
<fieldset>
<h4 className="title">
{ __( 'Sandboxing Level (Experimental)', 'amp' ) }
</h4>
<p>
{ __( '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' ) }
</p>
<ol>
<li>
<input
type="radio"
id="sandboxing-level-1"
checked={ 1 === sandboxingLevel }
onChange={ () => {
updateOptions( { sandboxing_level: 1 } );
} }
/>
<label htmlFor="sandboxing-level-1">
<strong>
{ __( 'Loose:', 'amp' ) }
</strong>
{ ' ' + __( 'Do not remove any AMP-invalid markup by default, including custom scripts. CSS tree-shaking is disabled.', 'amp' ) }
</label>
</li>
<li>
<input
type="radio"
id="sandboxing-level-2"
checked={ 2 === sandboxingLevel }
onChange={ () => {
updateOptions( { sandboxing_level: 2 } );
} }
/>
<label htmlFor="sandboxing-level-2">
<strong>
{ __( 'Moderate:', 'amp' ) }
</strong>
{ ' ' + __( 'Remove non-AMP markup, but allow POST forms. CSS tree shaking is enabled.', 'amp' ) }
</label>
</li>
<li>
<input
type="radio"
id="sandboxing-level-3"
checked={ 3 === sandboxingLevel }
onChange={ () => {
updateOptions( { sandboxing_level: 3 } );
} }
/>
<label htmlFor="sandboxing-level-3">
<strong>
{ __( 'Strict:', 'amp' ) }
</strong>
{ ' ' + __( 'Require valid AMP.', 'amp' ) }
</label>
</li>

</ol>
</fieldset>
)
}
</TemplateModeOption>
<TemplateModeOption
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' ) }
Expand Down
79 changes: 38 additions & 41 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1405,10 +1405,6 @@ function amp_is_dev_mode() {
( is_admin_bar_showing() && is_user_logged_in() )
||
is_customize_preview()
||
// Force dev mode for Bento since it currently requires the Bento experiment opt-in script.
// @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>.
amp_is_bento_enabled()
)
);
}
Expand All @@ -1435,26 +1431,6 @@ function amp_is_native_img_used() {
return (bool) apply_filters( 'amp_native_img_used', false );
}

/**
* Determine whether to allow native `POST` forms without conversion to use the `action-xhr` attribute and use the amp-form component.
*
* @since 2.2
* @link https://github.com/ampproject/amphtml/issues/27638
*
* @return bool Whether to allow native `POST` forms.
*/
function amp_is_native_post_form_allowed() {
/**
* Filters whether to allow native `POST` forms without conversion to use the `action-xhr` attribute and use the amp-form component.
*
* @since 2.2
* @link https://github.com/ampproject/amphtml/issues/27638
*
* @param bool $use_native Whether to allow native `POST` forms.
*/
return (bool) apply_filters( 'amp_native_post_form_allowed', false );
}

/**
* Get content sanitizers.
*
Expand Down Expand Up @@ -1499,18 +1475,16 @@ function amp_get_content_sanitizers( $post = null ) {
AMP_Theme_Support::TRANSITIONAL_MODE_SLUG === AMP_Options_Manager::get_option( Option::THEME_SUPPORT )
);

$native_img_used = amp_is_native_img_used();
$native_post_forms_allowed = amp_is_native_post_form_allowed();
$native_img_used = amp_is_native_img_used();

$sanitizers = [
// The AMP_Script_Sanitizer runs first because based on whether it allows custom scripts
// to be kept, it may impact the behavior of other sanitizers. For example, if custom
// scripts are kept then this is a signal that tree shaking in AMP_Style_Sanitizer cannot be
// performed.
AMP_Script_Sanitizer::class => [],
// Embed sanitization must come first because it strips out custom scripts associated with embeds.
AMP_Embed_Sanitizer::class => [
'amp_to_amp_linking_enabled' => $amp_to_amp_linking_enabled,
],
AMP_O2_Player_Sanitizer::class => [],
AMP_Playbuzz_Sanitizer::class => [],

AMP_Core_Theme_Sanitizer::class => [
'template' => get_template(),
'stylesheet' => get_stylesheet(),
Expand All @@ -1519,21 +1493,25 @@ function amp_get_content_sanitizers( $post = null ) {
],
'native_img_used' => $native_img_used,
],

AMP_Comments_Sanitizer::class => [
'comments_live_list' => ! empty( $theme_support_args['comments_live_list'] ),
],

// The AMP_Script_Sanitizer runs here because based on whether it allows custom scripts
// to be kept, it may impact the behavior of other sanitizers. For example, if custom
// scripts are kept then this is a signal that tree shaking in AMP_Style_Sanitizer cannot be
// performed.
AMP_Script_Sanitizer::class => [],

AMP_Srcset_Sanitizer::class => [],
AMP_Img_Sanitizer::class => [
'align_wide_support' => current_theme_supports( 'align-wide' ),
'native_img_used' => $native_img_used,
],
AMP_Form_Sanitizer::class => [
'native_post_forms_allowed' => $native_post_forms_allowed,
],
AMP_Comments_Sanitizer::class => [
'comments_live_list' => ! empty( $theme_support_args['comments_live_list'] ),
],
AMP_Form_Sanitizer::class => [],
AMP_Video_Sanitizer::class => [],
AMP_O2_Player_Sanitizer::class => [],
AMP_Audio_Sanitizer::class => [],
AMP_Playbuzz_Sanitizer::class => [],
AMP_Object_Sanitizer::class => [],
AMP_Iframe_Sanitizer::class => [
'add_placeholder' => true,
Expand Down Expand Up @@ -1651,8 +1629,27 @@ function amp_get_content_sanitizers( $post = null ) {
*/
$sanitizers[ AMP_Style_Sanitizer::class ]['allow_transient_caching'] = apply_filters( 'amp_parsed_css_transient_caching_allowed', true );

// Force layout, style, meta, and validating sanitizers to be at the end.
foreach ( [ AMP_Layout_Sanitizer::class, AMP_Style_Sanitizer::class, AMP_Meta_Sanitizer::class, AMP_Tag_And_Attribute_Sanitizer::class ] as $class_name ) {
// Force core essential sanitizers to appear at the end at the end, with non-essential and third-party sanitizers appearing before.
$expected_final_sanitizer_order = [
AMP_Core_Theme_Sanitizer::class, // Must come before script sanitizer since onclick attributes are removed.
AMP_Script_Sanitizer::class, // Must come before sanitizers for images, videos, audios, comments, forms, and styles.
AMP_Form_Sanitizer::class, // Must come before comments sanitizer.
AMP_Comments_Sanitizer::class, // Also must come after the form sanitizer.
AMP_Srcset_Sanitizer::class,
AMP_Img_Sanitizer::class,
AMP_Video_Sanitizer::class,
AMP_Audio_Sanitizer::class,
AMP_Object_Sanitizer::class,
AMP_Iframe_Sanitizer::class,
AMP_Gallery_Block_Sanitizer::class,
AMP_Block_Sanitizer::class,
AMP_Accessibility_Sanitizer::class,
AMP_Layout_Sanitizer::class,
AMP_Style_Sanitizer::class,
AMP_Meta_Sanitizer::class,
AMP_Tag_And_Attribute_Sanitizer::class,
];
foreach ( $expected_final_sanitizer_order as $class_name ) {
if ( isset( $sanitizers[ $class_name ] ) ) {
$sanitizer = $sanitizers[ $class_name ];
unset( $sanitizers[ $class_name ] );
Expand Down
Loading

0 comments on commit 35bf862

Please sign in to comment.