Version Description
(2018-12-05) =
To learn how to use the new features in this release, please see the wiki pages for Adding Theme Support and Implementing Interactivity.
-
Add runtime CSS minification,
!importantreplacement, and tree shaking. See #1048, #1111, #1142, #1320, #1073. Props westonruter, hellofromtonya, amedina, pbakaus, igrigorik, camelburrito. - Keep track of new validation errors and add ability to accept/reject in order to allow or block AMP for a given URL. See #1003. Props westonruter.
- Redesign screens for Invalid URLs and Error Index. See #1394, #1361, #1444, #1448, #1452, #1397, #1446, #1364, #1449, #1418, #1451, #1429, #1408, #1414, #1409, #1373, #1462, #1471, #1485. Props kienstra, johnwatkins0, miina, jacobschweitzer, westonruter.
-
Extend admin screen options to add
amptheme support without any coding required. Toggle between classic, paired, and native. Includes options for whether sanitization should be done by default and whether tree shaking should always be allowed. See #1199, #1291, #1264. Props westonruter, AdelDima. - Add support for allowing a site subset to be native AMP. See #1235. Props westonruter.
- Add an admin pointer for updated AMP settings screen for version 1.0. See #1271, #1254. Props kienstra.
- Add support for three core themes (Twenty Fifteen, Twenty Sixteen, Twenty Seventeen) so that they can be used out of the box with AMP theme support added without needing to create a child theme. See #1074. Props westonruter, DavidCramer, kienstra.
- Add AMP support for Twenty Nineteen. See #1587, #1619. Props westonruter.
- Add AMP menu item to admin bar on frontend with indication of AMP validation status; accessing an AMP URL that has unaccepted validation errors will redirect to the non-AMP page and cause the AMP admin bar item to indicate the failure, along with a link to access the validation results. See #1199. Props westonruter.
- Add dynamic handling of validation errors. See #1093, #1063, #1087. Props westonruter.
- Add AMP validation of blocks. See #1019. Props westonruter.
- Add AMP-specific functionality to core blocks. See #1026, #1008. Props miina.
- Add AMP media blocks (when in native AMP mode). See #1155. Props miina.
- Add embed handler for Gfycat. See #1136. Props miina.
- Add amp-mathml block. See #1165. Props miina.
- Add Gutenberg amp-timeago block. See #1168. Props miina.
- Add
amp-fit-textsupport to text blocks. See #1151. Props miina. - Fix handling of font stylesheets with non-HTTPS scheme or scheme-less URLs. See #1077. Props westonruter.
- Fix issues in displaying native blocks. See #1022. Props miina.
- Gutenberg: Add AMP Carousel for Gallery and AMP Lightbox features for Gallery and Image. See #1121, #1065, #1187. Props miina, westonruter.
- Add "Enable AMP" toggle in Gutenberg editor. See #1275, #1230. Props kienstra.
- Cache post processor response. See #1156, #959. Props ThierryA.
- Add preload links & resource hints, and optimize order of elements in head. See #1295. Props westonruter.
- Automatically redirect to
?ampfrom/amp/URLs whenamptheme support is present. See #1203, #1194. Props westonruter. - Incorporate Server Timing API. See #990. Props westonruter.
- Add information about stylesheets included and excluded in
style[amp-custom]. See #1135. Props westonruter. - Fetch (local) stylesheets with
@import, instead of removing them. See #1181. Props miina. - Fetch external stylesheets (which aren't from whitelisted font CDNs) to include in amp-custom style. See #1174. Props miina.
- Transform CSS selectors according to sanitizer HTML element to AMP component conversions. See #1175. Props miina, westonruter.
- Rework displaying block validation messages. See #1682. Props miina.
- Ensure layout attributes are only allowed on supporting elements. See #1075. Props westonruter.
- Correct the width attribute in
coltags to the equivalent CSS rule. See #1064. Props amedina. - Ensure that video
sourceelements use HTTPS. See #1274, #976. Props hellofromtonya. - Preserve whitespace when serializing the DOM as HTML. See #1309, #1304. Props westonruter.
- Fix reporting the removal of unrecognized elements. See #1287, #1100. Props hellofromtonya.
- Remove space from
data: url()in stylesheets. See #1164, #1089. Props amedina, JonHendershot, westonruter, mehigh, davisshaver, Mte90. - Fix inconsistency between singular and plural. See #1114. Props garrett-eclipse.
- Disable AMP admin menu option when the AMP Customizer is not enabled or theme support is enabled. See #1080. Props oscarssanchez.
- Allow spaces around commas in value property lists. See #1112. Props westonruter.
- Restore admin bar on AMP pages and improve AMP menu items. See #1219. Props westonruter.
- Remove empty media queries. See #1423. Props korobochkin, westonruter.
- Update PHP-CSS-Parser and include tree shaker effectiveness in
style[amp-custom]manifest comment. See #1650. Props westonruter. - Display admin notice if there's no persistent object caching. See #1050. Props oscarssanchez.
- Re-use styling for unmoderated comments to apply to new accepted/rejected validation errors. See #1458. Props westonruter, johnwatkins0, jacobschweitzer.
- Update PHP-CSS-Parser to use new calc() support. See #1116, #1284. Props westonruter.
- Fix parsing CSS selectors which contain commas. See #1286. Props westonruter.
- Add sanitizer to support
amp-o2-player. See #1202. Props juanchaur1. - Update contributing.md and add code of conduct. See #1649. Props amedina.
- Add
AMP_Embed_Sanitizer. See #1128. Props juanchaur1. - Add
AMP_Script_Sanitizerto replacenoscriptelements with their contents. See #1226. Props westonruter. - Update generated tags file to 767. See #1665. Props miina.
- Fix header image filtering and YouTube header video detection. See #1208. Props westonruter.
- Improve support for Hulu & Imgur embeds. See #1218. Props miina.
- Fix integration with WordPress 5.0. See #1520. Props miina.
- Update spec generated from amphtml to file revision 675 and AMP v1531357871900. See #1312. Props westonruter.
- Opt-in to CORS mode for external font stylesheet links. See #1289. Props westonruter.
- PHPCS fixes, including PHP DocBlocks and strict comparisons. See #1002. Props paulschreiber.
- Fix generation of validation error when element has multiple invalid attributes. See #1461. Props westonruter.
- Prevent empty term status from being interpreted as new-rejected during bulk change. See #1460. Props westonruter.
- Add script to create built tag. See #1209. Props westonruter.
- Fix handling of amp-bind attributes to ensure that
>can appear inside attribute values. See #1119. Props westonruter. - Tree-shake CSS selectors for HTML elements that target non-active languages. See #1221. Props westonruter.
- Redirect to post list table in case of admin bar validate request failure. See #1229. Props westonruter.
- Amend AMP style elements with sourceURL comment for DevTools to be able to perform CSS code coverage. See #1584. Props westonruter.
- Prevent erroneously tree-shaking keyframe selectors like
from,to, and percentages. See #1211. Props westonruter. - Add caching of redirect to non-AMP URL when validation errors present. See #1207. Props westonruter.
- Discontinue using 'latest' version of component scripts. See #1464. Props westonruter.
- Ensure font stylesheets are requested in CORS mode in both AMP and non-AMP documents. See #1486. Props westonruter.
- Move any content output during shutdown to be injected before closing body tag. See #1102. Props westonruter.
- Fix obtaining source for widgets. See #1212. Props westonruter.
- Address issue where
<ul>is converted to an<amp-carousel>. See #1529. Props kienstra. - Construct schema.org meta script by appending text node. See #1220. Props westonruter.
- Eliminate
amp-wp-enforced-sizesstyle from theme support stylesheet. See #1153. Props westonruter. - Add support for extracting (pixel) dimensions from SVG images. See #1150. Props westonruter.
- Ensure redirect is only done if there are unsanitized errors. See #1241. Props westonruter.
- Deprecate
AMP_WP_Utils, in favor ofwp_parse_url(). See #995. Props paulschreiber. - Add WP-CLI script to test support for blocks. See #845. Props kienstra.
- Ensure translatable strings in blocks can actually be translated. See #1173. Props miina, swissspidy, westonruter.
- Look in entire document for Schema.org metadata not just head. See #1664. Props westonruter.
- Fix title display of Invalid URL page. See #1463. Props amedina.
- Add native/paired/classic mode to AMP generator meta. See #1465. Props westonruter.
- Prevent
is_amp_endpoint()from triggering notice when called on login, signup, or activate screens. See #1250. Props felixarntz. - Support extracting dimensions for single URLs. See #793. Props mjangda, mdbitz.
- Improve validation and presentation of analytics form. See #1299, #1133, #1296. Props westonruter, AdelDima.
- Prevent validation of auto-drafts, including when merely accessing New Post screen. See #1301. Props westonruter.
- Fix inability to move link element due to assigned parent. See #1322. Props westonruter.
- Gutenberg: Remove 'type' from attributes where 'source' is set. See #1622. Props miina.
- Gutenberg: Fix displaying validation warning and usage of PHP function. See #1612. Props miina.
- Fix stretched images in Twenty Seventeen them and Gutenberg. See #1321, #1281, #1237. Props hellofromtonya.
- Fix image dimension extractor so it does not disregard duplicate images. See #1314. Props lukas9393.
- Improve organization of third party code. See #1657. Props westonruter.
- Short-circuit polldaddy shortcode when no poll or survey supplied. See #1621. Props westonruter.
- Remove redundant version from composer.json and add PHP version requirement. See #1333, #1328, #1334, #1332. Props swissspidy.
- Add warning when AMP plugin is installed in incorrect directory. See #1593. Props westonruter.
- Store validation errors in order of occurrence in document. See #1335. Props westonruter.
- Add .editorconfig file. See #1336, #51. Props swissspidy.
- Update i18n to make use of updated WP-CLI command. See #1329, #1327, #1341, #1345, #1393. Props swissspidy, felixarntz, westonruter.
- Use all eligible post types when
all_templates_supportedis selected. See #1338, #1302, #1344. Props hellofromtonya, westonruter. - Address an issue with an invalid embed. See #1661. Props kienstra.
- Do not show fallback source as active theme if no validation errors. See #1592. Props westonruter.
- Respect default AMP enabled status when creating a new post in Gutenberg. See #1339. Props hellofromtonya.
- Fix incorrect attribution of theme as source for content validation errors. See #1467. Props westonruter.
- Move AMP Settings in editor to after default settings. See #1652. Props miina.
- Fix conversion of video to amp-video. See #1477. Props westonruter.
- Add new icon, text, and style to splash notice. See #1470. Props jacobschweitzer.
- Normalize 'ver' query param in script/style validation errors to prevent recurrence after accepted. See #1346. Props westonruter.
- Add bing-amp.com to the list of AMP Cache hosts. See #1447. Props westonruter.
- Add missing tabindex attribute to lightbox images. See #1350. Props amedina.
- Update AMP spec to 757 (v1811091519050). See #1588. Props westonruter, kienstra.
- Detect ineffectual post-processor response cache due to high MISS rates and auto-disable. See #1325, #1239. Props hellofromtonya, westonruter.
- Update regex for tag selectors. See #1534. Props swissspidy, westonruter.
- Update the validator spec version to 720 and AMP v1534879991178; add support for reference points. See #1315, #1386, #1330. Props westonruter.
- Update spec from revision 720 to 734. See #1475. Props kienstra.
- Fix form sanitizer's handling of relative actions by making them absolute. See #1352, #1349. Props ricardobrg.
- Skip Server-Timing header if not WP_DEBUG and user cannot manage_options. See #1354. Props westonruter.
- Fetch CSS over HTTP when URL lacks extension; convert font CDN stylesheets @imports to convert to links instead of fetching. See #1357, #1317. Props westonruter.
- Add WP-CLI command for testing the AMP compatibility of an entire site. See #1183, #1007. Props kienstra, westonruter.
- Update screenshots. See #1701. Props westonruter, amedina.
- Update the description of the AMP project in readme file. See #1693. Props amedina.
- Use new banner images. See #1692. Props cathibosco.
- Display when validation results are stale due to active theme/plugin changes. See #1375. Props westonruter.
- Fix displaying of expected notices when theme support enabled by theme. See #1374, #1358. Props westonruter.
- Update native mode description to mention AMP-first. See #1703. Props westonruter.
- Fix handling responses to form submissions from an AMP Cache. See #1382, #1356.
- Replace Gutenberg's deprecated isCleanNewPost selector. See #1387. Props miina.
- Updates php-css-parser to include fix for parsing calc() with negative values. See #1392. Props westonruter.
- Add embed support for Twitter timelines via new amp-twitter attributes. See #1396. Props felixarntz.
- Eliminate obsolete
sudo:falsefrom Travis config. See #1651. Props westonruter. - Fix tooltip position. See #1472. Props jacobschweitzer.
- Add error type filters on validation error and invalid URL screens. See #1373. Props kienstra.
- Default to auto sanitization and tree shaking being enabled. See #1402. Props westonruter.
- Prevent the admin pointer from staying below the viewport. See #1694. Props kienstra.
- Omit validation errors sanitized by filter or tree-shaking option; since sanitization is forced, there is no point to store. See (#1413)[https://github.com/ampproject/amp-wp/pull/1413]. Props westonruter.
- Prevent URL validation from happening during bulk imports. See #1424, #1404. Props westonruter.
- Normalize invalid URL stored for
amp_validated_urlpost type. See #1436. Props westonruter. - Make the default layout responsive for the
<amp-ooyala-player>block. See #1585. Props kienstra. - Add default values for AMP Timeago block. See #1586. Props kienstra.
- Expose and store queried object for validated URL; show edit link. See #1426, #1428, #1433. Props westonruter.
- Re-validate the site when switching modes and show the results in a notice. See #1443. Props kienstra, westonruter.
- Improve access to AMP admin screens for users who are not administrators. #1437. Props westonruter.
- Display a welcome notice on the main 'AMP Settings' page. See #1442. Props kienstra.
- Fix URL protocol validation and parsing attribute values with multiple URLs. See #1411, #1410. Props westonruter.
- Prevent a notice from appearing in the Compatibility Tool meta box. See #1605. Props kienstra.
- Restore ability to customize 'amp' query var when theme support added. #1455. Props westonruter.
- Add slug constants for theme support and post type support. #1456. Props westonruter.
- Fix ability to add AMP support for custom post types. See #1441. Props westonruter.
- Fix stretched logo and header issues in Twenty Seventeen. #1419. Props westonruter.
- Add caption support to all amp-instagram embeds. See #1438, #822. Props chandrapatel.
- Fix PHP warning generated by calls to
idn_to_utf8(). See #1440, #1439. Props kraftbj. - Fix PHP fatal error during AMP validation when a plugin uses a class method as an output buffer callback. #1453. Props westonruter.
- Update minimum PHP version from 5.3.2 to 5.3.6. See #1407, #1406. Props westonruter.
- Improve
package.jsonandcomposer.json. See #1405. Props swissspidy. - Ensure PHP file generated for use by translate.wordpress.org is free of syntax errors. See #1427, #1416. Props swissspidy, westonruter.
For a full list of the closed issues and merged pull requests in this release, see the 1.0 milestone.
Contributors in this release, including design, development, testing, and project management: Adel Tahri (AdelDima), Alberto Medina (amedina), Anne Louise Currie (alcurrie), Brandon Kraft (kraftbj), Cathi Bosco (cathibosco), Chandra Patel (chandrapatel), Claudio Sossi, Daniel Walmsley (gravityrail), David Cramer (DavidCramer), Felix Arntz (felixarntz), Garrett Hyder (garrett-eclipse), Jacob Schweitzer (jacobschweitzer), John Watkins0 (johnwatkins0), Joshua Wold (jwold), Juan Chaur (juanchaur1), Kevin Coleman (kevincoleman), Leo Postovoit (postphotos), Lukas Hettwer (lukas9393), Mackenzie Hartung (MackenzieHartung), Matthew Denton (mdbitz), Miina Sikk (miina), Mohammad Jangda (mjangda), Pascal Birchler (swissspidy), Oscar Snchez (oscarssanchez), Paul Schreiber (paulschreiber), Ricardo Gonalves (ricardobrg), Ryan Kienstra (kienstra), Thierry Muller (ThierryA), Tonya Mork (hellofromtonya), Weston Ruter (westonruter).
Release Info
| Developer | westonruter |
| Plugin | |
| Version | 1.0.0 |
| Comparing to | |
| See all releases | |
Code changes from version 0.7.2 to 1.0.0
- amp.php +230 -38
- assets/css/admin-bar.css +1058 -0
- assets/css/admin-tables.css +57 -0
- assets/css/amp-default.css +21 -7
- assets/css/amp-editor-blocks.css +4 -0
- assets/css/amp-post-meta-box.css +13 -0
- assets/css/amp-validation-error-taxonomy.css +279 -0
- assets/css/amp-validation-single-error-url.css +164 -0
- assets/css/amp-validation-tooltips.css +7 -0
- assets/images/amp-logo-icon.svg +10 -0
- assets/images/amp-welcome-icon.svg +139 -0
- assets/images/baseline-check-circle-green.svg +4 -0
- assets/images/baseline-error-green.svg +12 -0
- assets/images/baseline-error-red.svg +12 -0
- assets/images/baseline-error.svg +12 -0
- assets/images/down-triangle.svg +3 -0
- assets/images/editor-help.svg +1 -0
- assets/images/error-rejected.svg +1 -0
- assets/js/amp-admin-pointer.js +37 -0
- assets/js/amp-block-editor-toggle-compiled.js +76 -0
- assets/js/amp-block-validation.js +540 -0
- assets/js/amp-blocks-compiled.js +151 -0
- assets/js/amp-customize-controls.js +12 -13
- assets/js/amp-customize-preview.js +2 -3
- assets/js/amp-customizer-design-preview.js +3 -4
- assets/js/amp-editor-blocks.js +852 -0
- assets/js/amp-post-meta-box.js +7 -7
- assets/js/amp-validated-url-post-edit-screen.js +409 -0
- assets/js/amp-validated-urls-index.js +34 -0
- assets/js/amp-validation-detail-toggle-compiled.js +91 -0
- assets/js/amp-validation-single-error-url-details-compiled.js +84 -0
- assets/js/amp-validation-tooltips-compiled.js +84 -0
- assets/src/amp-block-editor-toggle.js +100 -0
- assets/src/amp-validation-detail-toggle.js +102 -0
- assets/src/amp-validation-single-error-url-details.js +159 -0
- assets/src/amp-validation-tooltips.js +22 -0
- back-compat/templates-v0-3/meta-time.php +2 -1
- includes/admin/class-amp-admin-pointer.php +143 -0
- includes/admin/class-amp-customizer.php +42 -23
- includes/admin/class-amp-editor-blocks.php +201 -0
- includes/admin/class-amp-post-meta-box.php +146 -7
- includes/admin/functions.php +48 -7
- includes/amp-frontend-actions.php +7 -24
- includes/amp-helper-functions.php +315 -86
- includes/amp-post-template-actions.php +7 -9
- includes/class-amp-autoloader.php +29 -11
- includes/class-amp-cli.php +680 -0
- includes/class-amp-http.php +441 -0
- includes/class-amp-post-type-support.php +64 -18
- includes/class-amp-theme-support.php +1279 -444
- includes/{lib/fasterimage/amp-fasterimage.php → deprecated.php} +5 -4
- includes/embeds/class-amp-base-embed-handler.php +38 -4
- includes/embeds/class-amp-core-block-handler.php +117 -0
- includes/embeds/class-amp-dailymotion-embed.php +83 -21
- includes/embeds/class-amp-facebook-embed.php +93 -6
- includes/embeds/class-amp-gallery-embed.php +85 -15
- includes/embeds/class-amp-gfycat-embed-handler.php +81 -0
- includes/embeds/class-amp-hulu-embed-handler.php +87 -0
- includes/embeds/class-amp-imgur-embed-handler.php +148 -0
- includes/embeds/class-amp-instagram-embed.php +122 -7
- includes/embeds/class-amp-soundcloud-embed.php +1 -1
- includes/embeds/class-amp-twitter-embed.php +244 -13
- includes/embeds/class-amp-vimeo-embed.php +87 -28
- includes/embeds/class-amp-youtube-embed.php +89 -23
- includes/options/class-amp-analytics-options-submenu.php +2 -2
- includes/options/class-amp-options-manager.php +369 -14
- includes/options/class-amp-options-menu.php +490 -39
- includes/options/views/class-amp-analytics-options-submenu-page.php +91 -6
- includes/sanitizers/class-amp-allowed-tags-generated.php +4928 -1080
- includes/sanitizers/class-amp-audio-sanitizer.php +29 -0
- includes/sanitizers/class-amp-base-sanitizer.php +275 -36
- includes/sanitizers/class-amp-block-sanitizer.php +137 -0
- includes/sanitizers/class-amp-core-theme-sanitizer.php +1151 -0
- includes/sanitizers/class-amp-embed-sanitizer.php +47 -0
- includes/sanitizers/class-amp-form-sanitizer.php +15 -0
- includes/sanitizers/class-amp-gallery-block-sanitizer.php +207 -0
- includes/sanitizers/class-amp-iframe-sanitizer.php +32 -34
- includes/sanitizers/class-amp-img-sanitizer.php +92 -12
- includes/sanitizers/class-amp-o2-player-sanitizer.php +140 -0
- includes/sanitizers/class-amp-playbuzz-sanitizer.php +14 -5
- includes/sanitizers/class-amp-rule-spec.php +13 -28
- includes/sanitizers/class-amp-script-sanitizer.php +49 -0
- includes/sanitizers/class-amp-style-sanitizer.php +1402 -240
|
@@ -1,11 +1,11 @@
|
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
* Plugin Name: AMP
|
| 4 |
-
* Description:
|
| 5 |
-
* Plugin URI: https://
|
| 6 |
* Author: WordPress.com VIP, XWP, Google, and contributors
|
| 7 |
-
* Author URI: https://github.com/
|
| 8 |
-
* Version: 0.
|
| 9 |
* Text Domain: amp
|
| 10 |
* Domain Path: /languages/
|
| 11 |
* License: GPLv2 or later
|
|
@@ -21,18 +21,80 @@
|
|
| 21 |
function _amp_print_php_version_admin_notice() {
|
| 22 |
?>
|
| 23 |
<div class="notice notice-error">
|
| 24 |
-
|
| 25 |
-
|
| 26 |
<?php
|
| 27 |
}
|
| 28 |
-
if ( version_compare( phpversion(), '5.3', '<' ) ) {
|
| 29 |
add_action( 'admin_notices', '_amp_print_php_version_admin_notice' );
|
| 30 |
return;
|
| 31 |
}
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
define( 'AMP__FILE__', __FILE__ );
|
| 34 |
define( 'AMP__DIR__', dirname( __FILE__ ) );
|
| 35 |
-
define( 'AMP__VERSION', '0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
require_once AMP__DIR__ . '/includes/class-amp-autoloader.php';
|
| 38 |
AMP_Autoloader::register();
|
|
@@ -42,6 +104,12 @@ require_once AMP__DIR__ . '/includes/amp-helper-functions.php';
|
|
| 42 |
require_once AMP__DIR__ . '/includes/admin/functions.php';
|
| 43 |
|
| 44 |
register_activation_hook( __FILE__, 'amp_activate' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
function amp_activate() {
|
| 46 |
amp_after_setup_theme();
|
| 47 |
if ( ! did_action( 'amp_init' ) ) {
|
|
@@ -51,8 +119,14 @@ function amp_activate() {
|
|
| 51 |
}
|
| 52 |
|
| 53 |
register_deactivation_hook( __FILE__, 'amp_deactivate' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
function amp_deactivate() {
|
| 55 |
-
// We need to manually remove the amp endpoint
|
| 56 |
global $wp_rewrite;
|
| 57 |
foreach ( $wp_rewrite->endpoints as $index => $endpoint ) {
|
| 58 |
if ( amp_get_slug() === $endpoint[1] ) {
|
|
@@ -73,6 +147,9 @@ add_action( 'wp_default_scripts', 'amp_register_default_scripts' );
|
|
| 73 |
// Ensure async and custom-element/custom-template attributes are present on script tags.
|
| 74 |
add_filter( 'script_loader_tag', 'amp_filter_script_loader_tag', PHP_INT_MAX, 2 );
|
| 75 |
|
|
|
|
|
|
|
|
|
|
| 76 |
/**
|
| 77 |
* Set up AMP.
|
| 78 |
*
|
|
@@ -84,6 +161,13 @@ add_filter( 'script_loader_tag', 'amp_filter_script_loader_tag', PHP_INT_MAX, 2
|
|
| 84 |
function amp_after_setup_theme() {
|
| 85 |
amp_get_slug(); // Ensure AMP_QUERY_VAR is set.
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
if ( false === apply_filters( 'amp_is_enabled', true ) ) {
|
| 88 |
return;
|
| 89 |
}
|
|
@@ -106,16 +190,27 @@ function amp_init() {
|
|
| 106 |
*/
|
| 107 |
do_action( 'amp_init' );
|
| 108 |
|
| 109 |
-
load_plugin_textdomain( 'amp', false, plugin_basename( AMP__DIR__ ) . '/languages' );
|
| 110 |
-
|
| 111 |
add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK );
|
| 112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
AMP_Theme_Support::init();
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
add_filter( 'request', 'amp_force_query_var_value' );
|
| 116 |
add_action( 'admin_init', 'AMP_Options_Manager::register_settings' );
|
|
|
|
| 117 |
add_action( 'wp_loaded', 'amp_post_meta_box' );
|
|
|
|
| 118 |
add_action( 'wp_loaded', 'amp_add_options_menu' );
|
|
|
|
| 119 |
add_action( 'parse_query', 'amp_correct_query_when_is_front_page' );
|
| 120 |
|
| 121 |
// Redirect the old url of amp page to the updated url.
|
|
@@ -127,10 +222,36 @@ function amp_init() {
|
|
| 127 |
|
| 128 |
// Add actions for legacy post templates.
|
| 129 |
add_action( 'wp', 'amp_maybe_add_actions' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
}
|
| 131 |
|
| 132 |
-
|
| 133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
function amp_force_query_var_value( $query_vars ) {
|
| 135 |
if ( isset( $query_vars[ amp_get_slug() ] ) && '' === $query_vars[ amp_get_slug() ] ) {
|
| 136 |
$query_vars[ amp_get_slug() ] = 1;
|
|
@@ -144,6 +265,7 @@ function amp_force_query_var_value( $query_vars ) {
|
|
| 144 |
* If the request is for an AMP page and this is in 'canonical mode,' redirect to the non-AMP page.
|
| 145 |
* It won't need this plugin's template system, nor the frontend actions like the 'rel' link.
|
| 146 |
*
|
|
|
|
| 147 |
* @global WP_Query $wp_query
|
| 148 |
* @since 0.2
|
| 149 |
* @return void
|
|
@@ -151,7 +273,7 @@ function amp_force_query_var_value( $query_vars ) {
|
|
| 151 |
function amp_maybe_add_actions() {
|
| 152 |
|
| 153 |
// Short-circuit when theme supports AMP, as everything is handled by AMP_Theme_Support.
|
| 154 |
-
if ( current_theme_supports(
|
| 155 |
return;
|
| 156 |
}
|
| 157 |
|
|
@@ -225,52 +347,111 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) {
|
|
| 225 |
}
|
| 226 |
|
| 227 |
/**
|
| 228 |
-
* Whether this is in 'canonical mode.
|
|
|
|
|
|
|
| 229 |
*
|
| 230 |
-
*
|
| 231 |
-
* Then, this will change the plugin from 'paired mode,' and it won't use its own templates.
|
| 232 |
-
* Nor output frontend markup like the 'rel' link. If the theme registers support for AMP with:
|
| 233 |
-
* `add_theme_support( 'amp', array( 'template_dir' => 'my-amp-templates' ) )`
|
| 234 |
-
* it will retain 'paired mode.
|
| 235 |
*
|
| 236 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
*/
|
| 238 |
function amp_is_canonical() {
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
return true;
|
| 242 |
}
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
}
|
| 248 |
}
|
| 249 |
-
|
|
|
|
|
|
|
| 250 |
}
|
| 251 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
function amp_load_classes() {
|
| 253 |
_deprecated_function( __FUNCTION__, '0.6' );
|
| 254 |
}
|
| 255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
function amp_add_frontend_actions() {
|
| 257 |
-
|
| 258 |
}
|
| 259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
function amp_add_post_template_actions() {
|
| 261 |
require_once AMP__DIR__ . '/includes/amp-post-template-actions.php';
|
| 262 |
require_once AMP__DIR__ . '/includes/amp-post-template-functions.php';
|
| 263 |
amp_post_template_init_hooks();
|
| 264 |
}
|
| 265 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
function amp_prepare_render() {
|
| 267 |
-
add_action( 'template_redirect', 'amp_render' );
|
| 268 |
}
|
| 269 |
|
| 270 |
/**
|
| 271 |
* Render AMP for queried post.
|
| 272 |
*
|
| 273 |
* @since 0.1
|
|
|
|
| 274 |
*/
|
| 275 |
function amp_render() {
|
| 276 |
// Note that queried object is used instead of the ID so that the_preview for the queried post can apply.
|
|
@@ -285,6 +466,8 @@ function amp_render() {
|
|
| 285 |
* Render AMP post template.
|
| 286 |
*
|
| 287 |
* @since 0.5
|
|
|
|
|
|
|
| 288 |
* @param WP_Post|int $post Post.
|
| 289 |
* @global WP_Query $wp_query
|
| 290 |
*/
|
|
@@ -317,6 +500,8 @@ function amp_render_post( $post ) {
|
|
| 317 |
/**
|
| 318 |
* Fires before rendering a post in AMP.
|
| 319 |
*
|
|
|
|
|
|
|
| 320 |
* @since 0.2
|
| 321 |
*
|
| 322 |
* @param int $post_id Post ID.
|
|
@@ -338,7 +523,7 @@ function amp_render_post( $post ) {
|
|
| 338 |
* Uses the priority of 12 for the 'after_setup_theme' action.
|
| 339 |
* Many themes run `add_theme_support()` on the 'after_setup_theme' hook, at the default priority of 10.
|
| 340 |
* And that function's documentation suggests adding it to that action.
|
| 341 |
-
* So this enables themes to `add_theme_support(
|
| 342 |
* And `amp_init_customizer()` will be able to recognize theme support by calling `amp_is_canonical()`.
|
| 343 |
*
|
| 344 |
* @since 0.4
|
|
@@ -350,16 +535,23 @@ add_action( 'plugins_loaded', '_amp_bootstrap_customizer', 9 ); // Should be hoo
|
|
| 350 |
|
| 351 |
/**
|
| 352 |
* Redirects the old AMP URL to the new AMP URL.
|
|
|
|
| 353 |
* If post slug is updated the amp page with old post slug will be redirected to the updated url.
|
| 354 |
*
|
| 355 |
-
* @
|
|
|
|
| 356 |
*
|
| 357 |
-
* @
|
|
|
|
| 358 |
*/
|
| 359 |
function amp_redirect_old_slug_to_new_url( $link ) {
|
| 360 |
|
| 361 |
-
if ( is_amp_endpoint() ) {
|
| 362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
}
|
| 364 |
|
| 365 |
return $link;
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
* Plugin Name: AMP
|
| 4 |
+
* Description: Enable AMP on your WordPress site, the WordPress way.
|
| 5 |
+
* Plugin URI: https://amp-wp.org
|
| 6 |
* Author: WordPress.com VIP, XWP, Google, and contributors
|
| 7 |
+
* Author URI: https://github.com/ampproject/amp-wp/graphs/contributors
|
| 8 |
+
* Version: 1.0.0
|
| 9 |
* Text Domain: amp
|
| 10 |
* Domain Path: /languages/
|
| 11 |
* License: GPLv2 or later
|
| 21 |
function _amp_print_php_version_admin_notice() {
|
| 22 |
?>
|
| 23 |
<div class="notice notice-error">
|
| 24 |
+
<p><?php esc_html_e( 'The AMP plugin requires PHP 5.3+. Please contact your host to update your PHP version.', 'amp' ); ?></p>
|
| 25 |
+
</div>
|
| 26 |
<?php
|
| 27 |
}
|
| 28 |
+
if ( version_compare( phpversion(), '5.3.6', '<' ) ) {
|
| 29 |
add_action( 'admin_notices', '_amp_print_php_version_admin_notice' );
|
| 30 |
return;
|
| 31 |
}
|
| 32 |
|
| 33 |
+
/**
|
| 34 |
+
* Print admin notice regarding DOM extension is not installed.
|
| 35 |
+
*
|
| 36 |
+
* @since 1.1
|
| 37 |
+
*/
|
| 38 |
+
function _amp_print_php_dom_document_notice() {
|
| 39 |
+
?>
|
| 40 |
+
<div class="notice notice-error">
|
| 41 |
+
<p><?php esc_html_e( 'The AMP plugin requires DOM extension in PHP. Please contact your host to install DOM extension.', 'amp' ); ?></p>
|
| 42 |
+
</div>
|
| 43 |
+
<?php
|
| 44 |
+
}
|
| 45 |
+
if ( ! class_exists( 'DOMDocument' ) ) {
|
| 46 |
+
add_action( 'admin_notices', '_amp_print_php_dom_document_notice' );
|
| 47 |
+
return;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
/**
|
| 51 |
+
* Print admin notice when composer install has not been performed.
|
| 52 |
+
*
|
| 53 |
+
* @since 1.0
|
| 54 |
+
*/
|
| 55 |
+
function _amp_print_composer_install_admin_notice() {
|
| 56 |
+
?>
|
| 57 |
+
<div class="notice notice-error">
|
| 58 |
+
<p><?php esc_html_e( 'You appear to be running the AMP plugin from source. Please do `composer install` to finish installation.', 'amp' ); ?></p>
|
| 59 |
+
</div>
|
| 60 |
+
<?php
|
| 61 |
+
}
|
| 62 |
+
if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) || ! file_exists( __DIR__ . '/vendor/sabberworm/php-css-parser' ) ) {
|
| 63 |
+
add_action( 'admin_notices', '_amp_print_composer_install_admin_notice' );
|
| 64 |
+
return;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
define( 'AMP__FILE__', __FILE__ );
|
| 68 |
define( 'AMP__DIR__', dirname( __FILE__ ) );
|
| 69 |
+
define( 'AMP__VERSION', '1.0.0' );
|
| 70 |
+
|
| 71 |
+
/**
|
| 72 |
+
* Print admin notice if plugin installed with incorrect slug (which impacts WordPress's auto-update system).
|
| 73 |
+
*
|
| 74 |
+
* @since 1.0
|
| 75 |
+
*/
|
| 76 |
+
function _amp_incorrect_plugin_slug_admin_notice() {
|
| 77 |
+
$actual_slug = basename( AMP__DIR__ );
|
| 78 |
+
?>
|
| 79 |
+
<div class="notice notice-warning">
|
| 80 |
+
<p>
|
| 81 |
+
<?php
|
| 82 |
+
echo wp_kses_post(
|
| 83 |
+
sprintf(
|
| 84 |
+
/* translators: %1$s is the current directory name, and %2$s is the required directory name */
|
| 85 |
+
__( 'You appear to have installed the AMP plugin incorrectly. It is currently installed in the <code>%1$s</code> directory, but it needs to be placed in a directory named <code>%2$s</code>. Please rename the directory. This is important for WordPress plugin auto-updates.', 'amp' ),
|
| 86 |
+
$actual_slug,
|
| 87 |
+
'amp'
|
| 88 |
+
)
|
| 89 |
+
);
|
| 90 |
+
?>
|
| 91 |
+
</p>
|
| 92 |
+
</div>
|
| 93 |
+
<?php
|
| 94 |
+
}
|
| 95 |
+
if ( 'amp' !== basename( AMP__DIR__ ) ) {
|
| 96 |
+
add_action( 'admin_notices', '_amp_incorrect_plugin_slug_admin_notice' );
|
| 97 |
+
}
|
| 98 |
|
| 99 |
require_once AMP__DIR__ . '/includes/class-amp-autoloader.php';
|
| 100 |
AMP_Autoloader::register();
|
| 104 |
require_once AMP__DIR__ . '/includes/admin/functions.php';
|
| 105 |
|
| 106 |
register_activation_hook( __FILE__, 'amp_activate' );
|
| 107 |
+
|
| 108 |
+
/**
|
| 109 |
+
* Handle activation of plugin.
|
| 110 |
+
*
|
| 111 |
+
* @since 0.2
|
| 112 |
+
*/
|
| 113 |
function amp_activate() {
|
| 114 |
amp_after_setup_theme();
|
| 115 |
if ( ! did_action( 'amp_init' ) ) {
|
| 119 |
}
|
| 120 |
|
| 121 |
register_deactivation_hook( __FILE__, 'amp_deactivate' );
|
| 122 |
+
|
| 123 |
+
/**
|
| 124 |
+
* Handle deactivation of plugin.
|
| 125 |
+
*
|
| 126 |
+
* @since 0.2
|
| 127 |
+
*/
|
| 128 |
function amp_deactivate() {
|
| 129 |
+
// We need to manually remove the amp endpoint.
|
| 130 |
global $wp_rewrite;
|
| 131 |
foreach ( $wp_rewrite->endpoints as $index => $endpoint ) {
|
| 132 |
if ( amp_get_slug() === $endpoint[1] ) {
|
| 147 |
// Ensure async and custom-element/custom-template attributes are present on script tags.
|
| 148 |
add_filter( 'script_loader_tag', 'amp_filter_script_loader_tag', PHP_INT_MAX, 2 );
|
| 149 |
|
| 150 |
+
// Ensure crossorigin=anonymous is added to font links.
|
| 151 |
+
add_filter( 'style_loader_tag', 'amp_filter_font_style_loader_tag_with_crossorigin_anonymous', 10, 4 );
|
| 152 |
+
|
| 153 |
/**
|
| 154 |
* Set up AMP.
|
| 155 |
*
|
| 161 |
function amp_after_setup_theme() {
|
| 162 |
amp_get_slug(); // Ensure AMP_QUERY_VAR is set.
|
| 163 |
|
| 164 |
+
/**
|
| 165 |
+
* Filters whether AMP is enabled on the current site.
|
| 166 |
+
*
|
| 167 |
+
* Useful if the plugin is network activated and you want to turn it off on select sites.
|
| 168 |
+
*
|
| 169 |
+
* @since 0.2
|
| 170 |
+
*/
|
| 171 |
if ( false === apply_filters( 'amp_is_enabled', true ) ) {
|
| 172 |
return;
|
| 173 |
}
|
| 190 |
*/
|
| 191 |
do_action( 'amp_init' );
|
| 192 |
|
|
|
|
|
|
|
| 193 |
add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK );
|
| 194 |
|
| 195 |
+
add_filter( 'allowed_redirect_hosts', array( 'AMP_HTTP', 'filter_allowed_redirect_hosts' ) );
|
| 196 |
+
AMP_HTTP::purge_amp_query_vars();
|
| 197 |
+
AMP_HTTP::send_cors_headers();
|
| 198 |
+
AMP_HTTP::handle_xhr_request();
|
| 199 |
AMP_Theme_Support::init();
|
| 200 |
+
AMP_Validation_Manager::init();
|
| 201 |
+
add_action( 'init', array( 'AMP_Post_Type_Support', 'add_post_type_support' ), 1000 ); // After post types have been defined.
|
| 202 |
+
|
| 203 |
+
if ( defined( 'WP_CLI' ) ) {
|
| 204 |
+
WP_CLI::add_command( 'amp', new AMP_CLI() );
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
add_filter( 'request', 'amp_force_query_var_value' );
|
| 208 |
add_action( 'admin_init', 'AMP_Options_Manager::register_settings' );
|
| 209 |
+
add_action( 'wp_loaded', 'amp_editor_core_blocks' );
|
| 210 |
add_action( 'wp_loaded', 'amp_post_meta_box' );
|
| 211 |
+
add_action( 'wp_loaded', 'amp_editor_core_blocks' );
|
| 212 |
add_action( 'wp_loaded', 'amp_add_options_menu' );
|
| 213 |
+
add_action( 'wp_loaded', 'amp_admin_pointer' );
|
| 214 |
add_action( 'parse_query', 'amp_correct_query_when_is_front_page' );
|
| 215 |
|
| 216 |
// Redirect the old url of amp page to the updated url.
|
| 222 |
|
| 223 |
// Add actions for legacy post templates.
|
| 224 |
add_action( 'wp', 'amp_maybe_add_actions' );
|
| 225 |
+
|
| 226 |
+
/*
|
| 227 |
+
* Broadcast plugin updates.
|
| 228 |
+
* Note that AMP_Options_Manager::get_option( 'version', '0.0' ) cannot be used because
|
| 229 |
+
* version was new option added, and in that case default would never be used for a site
|
| 230 |
+
* upgrading from a version prior to 1.0. So this is why get_option() is currently used.
|
| 231 |
+
*/
|
| 232 |
+
$options = get_option( AMP_Options_Manager::OPTION_NAME, array() );
|
| 233 |
+
$old_version = isset( $options['version'] ) ? $options['version'] : '0.0';
|
| 234 |
+
if ( AMP__VERSION !== $old_version ) {
|
| 235 |
+
/**
|
| 236 |
+
* Triggers when after amp_init when the plugin version has updated.
|
| 237 |
+
*
|
| 238 |
+
* @param string $old_version Old version.
|
| 239 |
+
*/
|
| 240 |
+
do_action( 'amp_plugin_update', $old_version );
|
| 241 |
+
AMP_Options_Manager::update_option( 'version', AMP__VERSION );
|
| 242 |
+
}
|
| 243 |
}
|
| 244 |
|
| 245 |
+
/**
|
| 246 |
+
* Make sure the `amp` query var has an explicit value.
|
| 247 |
+
*
|
| 248 |
+
* This avoids issues when filtering the deprecated `query_string` hook.
|
| 249 |
+
*
|
| 250 |
+
* @since 0.3.3
|
| 251 |
+
*
|
| 252 |
+
* @param array $query_vars Query vars.
|
| 253 |
+
* @return array Query vars.
|
| 254 |
+
*/
|
| 255 |
function amp_force_query_var_value( $query_vars ) {
|
| 256 |
if ( isset( $query_vars[ amp_get_slug() ] ) && '' === $query_vars[ amp_get_slug() ] ) {
|
| 257 |
$query_vars[ amp_get_slug() ] = 1;
|
| 265 |
* If the request is for an AMP page and this is in 'canonical mode,' redirect to the non-AMP page.
|
| 266 |
* It won't need this plugin's template system, nor the frontend actions like the 'rel' link.
|
| 267 |
*
|
| 268 |
+
* @deprecated This function is not used when 'amp' theme support is added.
|
| 269 |
* @global WP_Query $wp_query
|
| 270 |
* @since 0.2
|
| 271 |
* @return void
|
| 273 |
function amp_maybe_add_actions() {
|
| 274 |
|
| 275 |
// Short-circuit when theme supports AMP, as everything is handled by AMP_Theme_Support.
|
| 276 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 277 |
return;
|
| 278 |
}
|
| 279 |
|
| 347 |
}
|
| 348 |
|
| 349 |
/**
|
| 350 |
+
* Whether this is in 'canonical mode'.
|
| 351 |
+
*
|
| 352 |
+
* Themes can register support for this with `add_theme_support( AMP_Theme_Support::SLUG )`:
|
| 353 |
*
|
| 354 |
+
* add_theme_support( AMP_Theme_Support::SLUG );
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
*
|
| 356 |
+
* This will serve templates in native AMP, allowing you to use AMP components in your theme templates.
|
| 357 |
+
* If you want to make available in paired mode, where templates are served in AMP or non-AMP documents, do:
|
| 358 |
+
*
|
| 359 |
+
* add_theme_support( AMP_Theme_Support::SLUG, array(
|
| 360 |
+
* 'paired' => true,
|
| 361 |
+
* ) );
|
| 362 |
+
*
|
| 363 |
+
* Paired mode is also implied if you define a template_dir:
|
| 364 |
+
*
|
| 365 |
+
* add_theme_support( AMP_Theme_Support::SLUG, array(
|
| 366 |
+
* 'template_dir' => 'amp',
|
| 367 |
+
* ) );
|
| 368 |
+
*
|
| 369 |
+
* If you want to have AMP-specific templates in addition to serving native AMP, do:
|
| 370 |
+
*
|
| 371 |
+
* add_theme_support( AMP_Theme_Support::SLUG, array(
|
| 372 |
+
* 'paired' => false,
|
| 373 |
+
* 'template_dir' => 'amp',
|
| 374 |
+
* ) );
|
| 375 |
+
*
|
| 376 |
+
* If you want to force AMP to always be served on a given template, you can use the templates_supported arg,
|
| 377 |
+
* for example to always serve the Category template in AMP:
|
| 378 |
+
*
|
| 379 |
+
* add_theme_support( AMP_Theme_Support::SLUG, array(
|
| 380 |
+
* 'templates_supported' => array(
|
| 381 |
+
* 'is_category' => true,
|
| 382 |
+
* ),
|
| 383 |
+
* ) );
|
| 384 |
+
*
|
| 385 |
+
* Or if you want to force AMP to be used on all templates:
|
| 386 |
+
*
|
| 387 |
+
* add_theme_support( AMP_Theme_Support::SLUG, array(
|
| 388 |
+
* 'templates_supported' => 'all',
|
| 389 |
+
* ) );
|
| 390 |
+
*
|
| 391 |
+
* @see AMP_Theme_Support::read_theme_support()
|
| 392 |
+
* @return boolean Whether this is in AMP 'canonical' mode, that is whether it is native and there is not separate AMP URL current URL.
|
| 393 |
*/
|
| 394 |
function amp_is_canonical() {
|
| 395 |
+
if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 396 |
+
return false;
|
|
|
|
| 397 |
}
|
| 398 |
+
|
| 399 |
+
$args = AMP_Theme_Support::get_theme_support_args();
|
| 400 |
+
if ( isset( $args['paired'] ) ) {
|
| 401 |
+
return empty( $args['paired'] );
|
|
|
|
| 402 |
}
|
| 403 |
+
|
| 404 |
+
// If there is a template_dir, then paired mode is implied.
|
| 405 |
+
return empty( $args['template_dir'] );
|
| 406 |
}
|
| 407 |
|
| 408 |
+
/**
|
| 409 |
+
* Load classes.
|
| 410 |
+
*
|
| 411 |
+
* @since 0.2
|
| 412 |
+
* @deprecated As of 0.6 since autoloading is now employed.
|
| 413 |
+
*/
|
| 414 |
function amp_load_classes() {
|
| 415 |
_deprecated_function( __FUNCTION__, '0.6' );
|
| 416 |
}
|
| 417 |
|
| 418 |
+
/**
|
| 419 |
+
* Add frontend actions.
|
| 420 |
+
*
|
| 421 |
+
* @since 0.2
|
| 422 |
+
*/
|
| 423 |
function amp_add_frontend_actions() {
|
| 424 |
+
add_action( 'wp_head', 'amp_add_amphtml_link' );
|
| 425 |
}
|
| 426 |
|
| 427 |
+
/**
|
| 428 |
+
* Add post template actions.
|
| 429 |
+
*
|
| 430 |
+
* @since 0.2
|
| 431 |
+
* @deprecated This function is not used when 'amp' theme support is added.
|
| 432 |
+
*/
|
| 433 |
function amp_add_post_template_actions() {
|
| 434 |
require_once AMP__DIR__ . '/includes/amp-post-template-actions.php';
|
| 435 |
require_once AMP__DIR__ . '/includes/amp-post-template-functions.php';
|
| 436 |
amp_post_template_init_hooks();
|
| 437 |
}
|
| 438 |
|
| 439 |
+
/**
|
| 440 |
+
* Add action to do post template rendering at template_redirect action.
|
| 441 |
+
*
|
| 442 |
+
* @since 0.2
|
| 443 |
+
* @since 1.0 The amp_render() function is called at template_redirect action priority 11 instead of priority 10.
|
| 444 |
+
* @deprecated This function is not used when 'amp' theme support is added.
|
| 445 |
+
*/
|
| 446 |
function amp_prepare_render() {
|
| 447 |
+
add_action( 'template_redirect', 'amp_render', 11 );
|
| 448 |
}
|
| 449 |
|
| 450 |
/**
|
| 451 |
* Render AMP for queried post.
|
| 452 |
*
|
| 453 |
* @since 0.1
|
| 454 |
+
* @deprecated This function is not used when 'amp' theme support is added.
|
| 455 |
*/
|
| 456 |
function amp_render() {
|
| 457 |
// Note that queried object is used instead of the ID so that the_preview for the queried post can apply.
|
| 466 |
* Render AMP post template.
|
| 467 |
*
|
| 468 |
* @since 0.5
|
| 469 |
+
* @deprecated This function is not used when 'amp' theme support is added.
|
| 470 |
+
*
|
| 471 |
* @param WP_Post|int $post Post.
|
| 472 |
* @global WP_Query $wp_query
|
| 473 |
*/
|
| 500 |
/**
|
| 501 |
* Fires before rendering a post in AMP.
|
| 502 |
*
|
| 503 |
+
* This action is not triggered when 'amp' theme support is present. Instead, you should use 'template_redirect' action and check if `is_amp_endpoint()`.
|
| 504 |
+
*
|
| 505 |
* @since 0.2
|
| 506 |
*
|
| 507 |
* @param int $post_id Post ID.
|
| 523 |
* Uses the priority of 12 for the 'after_setup_theme' action.
|
| 524 |
* Many themes run `add_theme_support()` on the 'after_setup_theme' hook, at the default priority of 10.
|
| 525 |
* And that function's documentation suggests adding it to that action.
|
| 526 |
+
* So this enables themes to `add_theme_support( AMP_Theme_Support::SLUG )`.
|
| 527 |
* And `amp_init_customizer()` will be able to recognize theme support by calling `amp_is_canonical()`.
|
| 528 |
*
|
| 529 |
* @since 0.4
|
| 535 |
|
| 536 |
/**
|
| 537 |
* Redirects the old AMP URL to the new AMP URL.
|
| 538 |
+
*
|
| 539 |
* If post slug is updated the amp page with old post slug will be redirected to the updated url.
|
| 540 |
*
|
| 541 |
+
* @since 0.5
|
| 542 |
+
* @deprecated This function is irrelevant when 'amp' theme support is added.
|
| 543 |
*
|
| 544 |
+
* @param string $link New URL of the post.
|
| 545 |
+
* @return string URL to be redirected.
|
| 546 |
*/
|
| 547 |
function amp_redirect_old_slug_to_new_url( $link ) {
|
| 548 |
|
| 549 |
+
if ( is_amp_endpoint() && ! amp_is_canonical() ) {
|
| 550 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 551 |
+
$link = add_query_arg( amp_get_slug(), '', $link );
|
| 552 |
+
} else {
|
| 553 |
+
$link = trailingslashit( trailingslashit( $link ) . amp_get_slug() );
|
| 554 |
+
}
|
| 555 |
}
|
| 556 |
|
| 557 |
return $link;
|
|
@@ -0,0 +1,1058 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
This is forked from core's admin-bar.css from WP 4.9.6
|
| 3 |
+
- Rules for IE<9 have been removed.
|
| 4 |
+
- References to .hover have been replaced with :focus-within (which is not supported in IE11).
|
| 5 |
+
- A universal selector properties have been removed which interferes with AMP shadow elements.
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
#wpadminbar * {
|
| 10 |
+
height: auto;
|
| 11 |
+
width: auto;
|
| 12 |
+
margin: 0;
|
| 13 |
+
padding: 0;
|
| 14 |
+
/* Removed because interferes with amp-img>img: position: static; */
|
| 15 |
+
text-shadow: none;
|
| 16 |
+
text-transform: none;
|
| 17 |
+
letter-spacing: normal;
|
| 18 |
+
font-size: 13px;
|
| 19 |
+
font-weight: 400;
|
| 20 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
| 21 |
+
line-height: 32px;
|
| 22 |
+
border-radius: 0;
|
| 23 |
+
box-sizing: content-box;
|
| 24 |
+
transition: none;
|
| 25 |
+
-webkit-font-smoothing: subpixel-antialiased; /* Prevent Safari from switching to standard antialiasing on hover */
|
| 26 |
+
-moz-osx-font-smoothing: auto; /* Prevent Firefox from inheriting from themes that use other values */
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.rtl #wpadminbar * {
|
| 30 |
+
font-family: Tahoma, sans-serif;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
html:lang(he-il) .rtl #wpadminbar * {
|
| 34 |
+
font-family: Arial, sans-serif;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
#wpadminbar .ab-empty-item {
|
| 38 |
+
cursor: default;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
#wpadminbar .ab-empty-item,
|
| 42 |
+
#wpadminbar a.ab-item,
|
| 43 |
+
#wpadminbar > #wp-toolbar span.ab-label,
|
| 44 |
+
#wpadminbar > #wp-toolbar span.noticon {
|
| 45 |
+
color: #eee;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
#wpadminbar #wp-admin-bar-site-name a.ab-item,
|
| 49 |
+
#wpadminbar #wp-admin-bar-my-sites a.ab-item {
|
| 50 |
+
white-space: nowrap;
|
| 51 |
+
overflow: hidden;
|
| 52 |
+
text-overflow: ellipsis;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
#wpadminbar ul li:before,
|
| 56 |
+
#wpadminbar ul li:after {
|
| 57 |
+
content: normal;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
#wpadminbar a,
|
| 61 |
+
#wpadminbar a:hover,
|
| 62 |
+
#wpadminbar a img,
|
| 63 |
+
#wpadminbar a img:hover {
|
| 64 |
+
outline: none;
|
| 65 |
+
border: none;
|
| 66 |
+
text-decoration: none;
|
| 67 |
+
background: none;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
#wpadminbar a:focus,
|
| 71 |
+
#wpadminbar a:active,
|
| 72 |
+
#wpadminbar input[type="text"],
|
| 73 |
+
#wpadminbar input[type="password"],
|
| 74 |
+
#wpadminbar input[type="number"],
|
| 75 |
+
#wpadminbar input[type="search"],
|
| 76 |
+
#wpadminbar input[type="email"],
|
| 77 |
+
#wpadminbar input[type="url"],
|
| 78 |
+
#wpadminbar select,
|
| 79 |
+
#wpadminbar textarea,
|
| 80 |
+
#wpadminbar div {
|
| 81 |
+
box-shadow: none;
|
| 82 |
+
outline: none;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
#wpadminbar {
|
| 86 |
+
direction: ltr;
|
| 87 |
+
color: #ccc;
|
| 88 |
+
font-size: 13px;
|
| 89 |
+
font-weight: 400;
|
| 90 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
| 91 |
+
line-height: 32px;
|
| 92 |
+
height: 32px;
|
| 93 |
+
position: fixed;
|
| 94 |
+
top: 0;
|
| 95 |
+
left: 0;
|
| 96 |
+
width: 100%;
|
| 97 |
+
min-width: 600px; /* match the min-width of the body in wp-admin.css */
|
| 98 |
+
z-index: 99999;
|
| 99 |
+
background: #23282d;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
#wpadminbar .ab-sub-wrapper,
|
| 103 |
+
#wpadminbar ul,
|
| 104 |
+
#wpadminbar ul li {
|
| 105 |
+
background: none;
|
| 106 |
+
clear: none;
|
| 107 |
+
list-style: none;
|
| 108 |
+
margin: 0;
|
| 109 |
+
padding: 0;
|
| 110 |
+
position: relative;
|
| 111 |
+
text-indent: 0;
|
| 112 |
+
z-index: 99999;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
#wpadminbar ul#wp-admin-bar-root-default>li {
|
| 116 |
+
margin-right: 0;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
#wpadminbar .quicklinks ul {
|
| 120 |
+
text-align: left;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
#wpadminbar li {
|
| 124 |
+
float: left;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
#wpadminbar .ab-empty-item {
|
| 128 |
+
outline: none;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
#wpadminbar .quicklinks .ab-top-secondary > li {
|
| 132 |
+
float: right;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
#wpadminbar .quicklinks a,
|
| 136 |
+
#wpadminbar .quicklinks .ab-empty-item,
|
| 137 |
+
#wpadminbar .shortlink-input {
|
| 138 |
+
height: 32px;
|
| 139 |
+
display: block;
|
| 140 |
+
padding: 0 10px;
|
| 141 |
+
margin: 0;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
#wpadminbar .quicklinks > ul > li > a {
|
| 145 |
+
padding: 0 8px 0 7px;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
#wpadminbar .menupop .ab-sub-wrapper,
|
| 149 |
+
#wpadminbar .shortlink-input {
|
| 150 |
+
margin: 0;
|
| 151 |
+
padding: 0;
|
| 152 |
+
box-shadow: 0 3px 5px rgba(0,0,0,0.2);
|
| 153 |
+
background: #32373c;
|
| 154 |
+
display: none;
|
| 155 |
+
position: absolute;
|
| 156 |
+
float: none;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
#wpadminbar .ab-top-menu > .menupop > .ab-sub-wrapper {
|
| 160 |
+
min-width: 100%;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
#wpadminbar .ab-top-secondary .menupop .ab-sub-wrapper {
|
| 164 |
+
right: 0;
|
| 165 |
+
left: auto;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
#wpadminbar .ab-submenu {
|
| 169 |
+
padding: 6px 0;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
#wpadminbar .selected .shortlink-input {
|
| 173 |
+
display: block;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
#wpadminbar .quicklinks .menupop ul li {
|
| 177 |
+
float: none;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
#wpadminbar .quicklinks .menupop ul li a strong {
|
| 181 |
+
font-weight: 600;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
#wpadminbar .quicklinks .menupop ul li .ab-item,
|
| 185 |
+
#wpadminbar .quicklinks .menupop ul li a strong,
|
| 186 |
+
#wpadminbar .quicklinks .menupop:focus-within ul li .ab-item,
|
| 187 |
+
#wpadminbar.nojs .quicklinks .menupop:hover ul li .ab-item,
|
| 188 |
+
#wpadminbar .shortlink-input {
|
| 189 |
+
line-height: 26px;
|
| 190 |
+
height: 26px;
|
| 191 |
+
white-space: nowrap;
|
| 192 |
+
min-width: 140px;
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
#wpadminbar .shortlink-input {
|
| 196 |
+
width: 200px;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
#wpadminbar.nojs li:hover > .ab-sub-wrapper,
|
| 200 |
+
#wpadminbar li:focus-within > .ab-sub-wrapper {
|
| 201 |
+
display: block;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
#wpadminbar .menupop li:hover > .ab-sub-wrapper,
|
| 205 |
+
#wpadminbar .menupop li:focus-within > .ab-sub-wrapper {
|
| 206 |
+
margin-left: 100%;
|
| 207 |
+
margin-top: -32px;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
#wpadminbar .ab-top-secondary .menupop li:hover > .ab-sub-wrapper,
|
| 211 |
+
#wpadminbar .ab-top-secondary .menupop li:focus-within > .ab-sub-wrapper {
|
| 212 |
+
margin-left: 0;
|
| 213 |
+
left: inherit;
|
| 214 |
+
right: 100%;
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
#wpadminbar:not(.mobile) .ab-top-menu > li > .ab-item:focus,
|
| 218 |
+
#wpadminbar.nojq .quicklinks .ab-top-menu > li > .ab-item:focus,
|
| 219 |
+
#wpadminbar:not(.mobile) .ab-top-menu > li:hover > .ab-item,
|
| 220 |
+
#wpadminbar .ab-top-menu > li:focus-within > .ab-item {
|
| 221 |
+
background: #32373c;
|
| 222 |
+
color: #00b9eb;
|
| 223 |
+
}
|
| 224 |
+
#wpadminbar .ab-top-menu > li:focus-within > .ab-item {
|
| 225 |
+
background: #32373c;
|
| 226 |
+
color: #00b9eb;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
#wpadminbar:not(.mobile) > #wp-toolbar li:hover span.ab-label,
|
| 230 |
+
#wpadminbar > #wp-toolbar li:focus-within span.ab-label,
|
| 231 |
+
#wpadminbar:not(.mobile) > #wp-toolbar a:focus span.ab-label {
|
| 232 |
+
color: #00b9eb;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
#wpadminbar > #wp-toolbar > #wp-admin-bar-root-default .ab-icon,
|
| 236 |
+
#wpadminbar .ab-icon,
|
| 237 |
+
#wpadminbar .ab-item:before {
|
| 238 |
+
position: relative;
|
| 239 |
+
float: left;
|
| 240 |
+
font: normal 20px/1 dashicons;
|
| 241 |
+
speak: none;
|
| 242 |
+
padding: 4px 0;
|
| 243 |
+
-webkit-font-smoothing: antialiased;
|
| 244 |
+
-moz-osx-font-smoothing: grayscale;
|
| 245 |
+
background-image: none !important;
|
| 246 |
+
margin-right: 6px;
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
#wpadminbar .ab-icon:before,
|
| 250 |
+
#wpadminbar .ab-item:before,
|
| 251 |
+
#wpadminbar #adminbarsearch:before {
|
| 252 |
+
color: #a0a5aa;
|
| 253 |
+
color: rgba(240,245,250,0.6);
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
#wpadminbar .ab-icon:before,
|
| 257 |
+
#wpadminbar .ab-item:before,
|
| 258 |
+
#wpadminbar #adminbarsearch:before {
|
| 259 |
+
position: relative;
|
| 260 |
+
transition: all .1s ease-in-out;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
#wpadminbar .ab-label {
|
| 264 |
+
display: inline-block;
|
| 265 |
+
height: 32px;
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
#wpadminbar .ab-submenu .ab-item {
|
| 269 |
+
color: #b4b9be;
|
| 270 |
+
color: rgba(240,245,250,0.7);
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
#wpadminbar .quicklinks .menupop ul li a,
|
| 274 |
+
#wpadminbar .quicklinks .menupop ul li a strong,
|
| 275 |
+
#wpadminbar .quicklinks .menupop:focus-within ul li a,
|
| 276 |
+
#wpadminbar.nojs .quicklinks .menupop:hover ul li a {
|
| 277 |
+
color: #b4b9be;
|
| 278 |
+
color: rgba(240,245,250,0.7);
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
#wpadminbar .quicklinks .menupop ul li a:hover,
|
| 282 |
+
#wpadminbar .quicklinks .menupop ul li a:focus,
|
| 283 |
+
#wpadminbar .quicklinks .menupop ul li a:hover strong,
|
| 284 |
+
#wpadminbar .quicklinks .menupop ul li a:focus strong,
|
| 285 |
+
#wpadminbar .quicklinks .ab-sub-wrapper .menupop:focus-within > a,
|
| 286 |
+
#wpadminbar .quicklinks .menupop:focus-within ul li a:hover,
|
| 287 |
+
#wpadminbar .quicklinks .menupop:focus-within ul li a:focus,
|
| 288 |
+
#wpadminbar .quicklinks .menupop:focus-within ul li div[tabindex]:hover,
|
| 289 |
+
#wpadminbar .quicklinks .menupop:focus-within ul li div[tabindex]:focus,
|
| 290 |
+
#wpadminbar.nojs .quicklinks .menupop:hover ul li a:hover,
|
| 291 |
+
#wpadminbar.nojs .quicklinks .menupop:hover ul li a:focus,
|
| 292 |
+
#wpadminbar li:hover .ab-icon:before,
|
| 293 |
+
#wpadminbar li:hover .ab-item:before,
|
| 294 |
+
#wpadminbar li a:focus .ab-icon:before,
|
| 295 |
+
#wpadminbar li .ab-item:focus:before,
|
| 296 |
+
#wpadminbar li .ab-item:focus .ab-icon:before,
|
| 297 |
+
#wpadminbar li:focus-within .ab-icon:before,
|
| 298 |
+
#wpadminbar li:focus-within .ab-item:before,
|
| 299 |
+
#wpadminbar li:hover #adminbarsearch:before,
|
| 300 |
+
#wpadminbar li #adminbarsearch.adminbar-focused:before {
|
| 301 |
+
color: #00b9eb;
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
#wpadminbar.mobile .quicklinks .ab-icon:before,
|
| 305 |
+
#wpadminbar.mobile .quicklinks .ab-item:before {
|
| 306 |
+
color: #b4b9be;
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
#wpadminbar .menupop .menupop > .ab-item:before,
|
| 310 |
+
#wpadminbar .ab-top-secondary .menupop .menupop > .ab-item:before {
|
| 311 |
+
position: absolute;
|
| 312 |
+
font: normal 17px/1 dashicons;
|
| 313 |
+
speak: none;
|
| 314 |
+
-webkit-font-smoothing: antialiased;
|
| 315 |
+
-moz-osx-font-smoothing: grayscale;
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
#wpadminbar .menupop .menupop > .ab-item {
|
| 319 |
+
display: block;
|
| 320 |
+
padding-right: 2em;
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
#wpadminbar .menupop .menupop > .ab-item:before {
|
| 324 |
+
top: 1px;
|
| 325 |
+
right: 4px;
|
| 326 |
+
content: "\f139";
|
| 327 |
+
color: inherit;
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
#wpadminbar .ab-top-secondary .menupop .menupop > .ab-item {
|
| 331 |
+
padding-left: 2em;
|
| 332 |
+
padding-right: 1em;
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
#wpadminbar .ab-top-secondary .menupop .menupop > .ab-item:before {
|
| 336 |
+
top: 1px;
|
| 337 |
+
left: 6px;
|
| 338 |
+
content: "\f141";
|
| 339 |
+
}
|
| 340 |
+
|
| 341 |
+
#wpadminbar .quicklinks .menupop ul.ab-sub-secondary {
|
| 342 |
+
display: block;
|
| 343 |
+
position: relative;
|
| 344 |
+
right: auto;
|
| 345 |
+
margin: 0;
|
| 346 |
+
box-shadow: none;
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
#wpadminbar .quicklinks .menupop ul.ab-sub-secondary,
|
| 350 |
+
#wpadminbar .quicklinks .menupop ul.ab-sub-secondary .ab-submenu {
|
| 351 |
+
background: #464b50;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
#wpadminbar .quicklinks .menupop .ab-sub-secondary > li > a:hover,
|
| 355 |
+
#wpadminbar .quicklinks .menupop .ab-sub-secondary > li .ab-item:focus a {
|
| 356 |
+
color: #00b9eb;
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
#wpadminbar .quicklinks a span#ab-updates {
|
| 360 |
+
background: #eee;
|
| 361 |
+
color: #32373c;
|
| 362 |
+
display: inline;
|
| 363 |
+
padding: 2px 5px;
|
| 364 |
+
font-size: 10px;
|
| 365 |
+
font-weight: 600;
|
| 366 |
+
border-radius: 10px;
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
#wpadminbar .quicklinks a:hover span#ab-updates {
|
| 370 |
+
background: #fff;
|
| 371 |
+
color: #000;
|
| 372 |
+
}
|
| 373 |
+
|
| 374 |
+
#wpadminbar .ab-top-secondary {
|
| 375 |
+
float: right;
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
#wpadminbar ul li:last-child,
|
| 379 |
+
#wpadminbar ul li:last-child .ab-item {
|
| 380 |
+
box-shadow: none;
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
/**
|
| 384 |
+
* My Account
|
| 385 |
+
*/
|
| 386 |
+
#wp-admin-bar-my-account > ul {
|
| 387 |
+
min-width: 198px;
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
#wp-admin-bar-my-account > .ab-item:before {
|
| 391 |
+
content: "\f110";
|
| 392 |
+
top: 2px;
|
| 393 |
+
float: right;
|
| 394 |
+
margin-left: 6px;
|
| 395 |
+
margin-right: 0;
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
#wp-admin-bar-my-account.with-avatar > .ab-item:before {
|
| 399 |
+
display: none;
|
| 400 |
+
content: none;
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
#wp-admin-bar-my-account.with-avatar > ul {
|
| 404 |
+
min-width: 270px;
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
#wpadminbar #wp-admin-bar-user-actions > li {
|
| 408 |
+
margin-left: 16px;
|
| 409 |
+
margin-right: 16px;
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
#wpadminbar #wp-admin-bar-user-actions.ab-submenu {
|
| 413 |
+
padding: 6px 0 12px;
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
#wpadminbar #wp-admin-bar-my-account.with-avatar #wp-admin-bar-user-actions > li {
|
| 417 |
+
margin-left: 88px;
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
#wpadminbar #wp-admin-bar-user-info {
|
| 421 |
+
margin-top: 6px;
|
| 422 |
+
margin-bottom: 15px;
|
| 423 |
+
height: auto;
|
| 424 |
+
background: none;
|
| 425 |
+
}
|
| 426 |
+
|
| 427 |
+
#wp-admin-bar-user-info .avatar {
|
| 428 |
+
/* TODO: The amp-img>img does not get loaded since the container is initially hidden, and :hover does not trigger a re-calc. Resizing the window does, however. */
|
| 429 |
+
position: absolute;
|
| 430 |
+
left: -72px;
|
| 431 |
+
top: 4px;
|
| 432 |
+
width: 64px;
|
| 433 |
+
height: 64px;
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
+
#wpadminbar #wp-admin-bar-user-info a {
|
| 437 |
+
background: none;
|
| 438 |
+
height: auto;
|
| 439 |
+
}
|
| 440 |
+
|
| 441 |
+
#wpadminbar #wp-admin-bar-user-info span {
|
| 442 |
+
background: none;
|
| 443 |
+
padding: 0;
|
| 444 |
+
height: 18px;
|
| 445 |
+
}
|
| 446 |
+
|
| 447 |
+
#wpadminbar #wp-admin-bar-user-info .display-name,
|
| 448 |
+
#wpadminbar #wp-admin-bar-user-info .username {
|
| 449 |
+
display: block;
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
#wpadminbar #wp-admin-bar-user-info .username {
|
| 453 |
+
color: #a0a5aa;
|
| 454 |
+
font-size: 11px;
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
#wpadminbar #wp-admin-bar-my-account.with-avatar > .ab-empty-item img,
|
| 458 |
+
#wpadminbar #wp-admin-bar-my-account.with-avatar > a img {
|
| 459 |
+
width: 16px; /* Was auto. */
|
| 460 |
+
height: 16px;
|
| 461 |
+
padding: 0;
|
| 462 |
+
border: 1px solid #82878c;
|
| 463 |
+
background: #eee;
|
| 464 |
+
line-height: 24px;
|
| 465 |
+
vertical-align: middle;
|
| 466 |
+
margin: -4px 0 0 6px;
|
| 467 |
+
float: none;
|
| 468 |
+
display: inline-block; /* Was inline. */
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
/**
|
| 472 |
+
* WP Logo
|
| 473 |
+
*/
|
| 474 |
+
#wpadminbar #wp-admin-bar-wp-logo > .ab-item .ab-icon {
|
| 475 |
+
width: 15px;
|
| 476 |
+
height: 20px;
|
| 477 |
+
margin-right: 0;
|
| 478 |
+
padding: 6px 0 5px;
|
| 479 |
+
}
|
| 480 |
+
|
| 481 |
+
#wpadminbar #wp-admin-bar-wp-logo > .ab-item {
|
| 482 |
+
padding: 0 7px;
|
| 483 |
+
}
|
| 484 |
+
|
| 485 |
+
#wpadminbar #wp-admin-bar-wp-logo > .ab-item .ab-icon:before {
|
| 486 |
+
content: "\f120";
|
| 487 |
+
top: 2px;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
/*
|
| 491 |
+
* My Sites & Site Title
|
| 492 |
+
*/
|
| 493 |
+
#wpadminbar .quicklinks li .blavatar {
|
| 494 |
+
float: left;
|
| 495 |
+
font: normal 16px/1 dashicons !important;
|
| 496 |
+
speak: none;
|
| 497 |
+
-webkit-font-smoothing: antialiased;
|
| 498 |
+
-moz-osx-font-smoothing: grayscale;
|
| 499 |
+
color: #eee;
|
| 500 |
+
}
|
| 501 |
+
|
| 502 |
+
#wpadminbar .quicklinks li a:hover .blavatar,
|
| 503 |
+
#wpadminbar .quicklinks li a:focus .blavatar,
|
| 504 |
+
#wpadminbar .quicklinks .ab-sub-wrapper .menupop:focus-within > a .blavatar {
|
| 505 |
+
color: #00b9eb;
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
#wpadminbar .quicklinks li .blavatar:before {
|
| 509 |
+
content: "\f120";
|
| 510 |
+
height: 16px;
|
| 511 |
+
width: 16px;
|
| 512 |
+
display: inline-block;
|
| 513 |
+
margin: 6px 8px 0 -2px;
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
#wpadminbar #wp-admin-bar-appearance {
|
| 517 |
+
margin-top: -12px;
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
#wpadminbar #wp-admin-bar-my-sites > .ab-item:before,
|
| 521 |
+
#wpadminbar #wp-admin-bar-site-name > .ab-item:before {
|
| 522 |
+
content: "\f541";
|
| 523 |
+
top: 2px;
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
#wpadminbar #wp-admin-bar-customize > .ab-item:before {
|
| 527 |
+
content: "\f540";
|
| 528 |
+
top: 2px;
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
|
| 532 |
+
#wpadminbar #wp-admin-bar-edit > .ab-item:before {
|
| 533 |
+
content: "\f464";
|
| 534 |
+
top: 2px;
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
#wpadminbar #wp-admin-bar-site-name > .ab-item:before {
|
| 538 |
+
content: "\f226";
|
| 539 |
+
}
|
| 540 |
+
|
| 541 |
+
.wp-admin #wpadminbar #wp-admin-bar-site-name > .ab-item:before {
|
| 542 |
+
content: "\f102";
|
| 543 |
+
}
|
| 544 |
+
|
| 545 |
+
|
| 546 |
+
|
| 547 |
+
/**
|
| 548 |
+
* Comments
|
| 549 |
+
*/
|
| 550 |
+
#wpadminbar #wp-admin-bar-comments .ab-icon {
|
| 551 |
+
margin-right: 6px;
|
| 552 |
+
}
|
| 553 |
+
|
| 554 |
+
#wpadminbar #wp-admin-bar-comments .ab-icon:before {
|
| 555 |
+
content: "\f101";
|
| 556 |
+
top: 3px;
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
+
#wpadminbar #wp-admin-bar-comments .count-0 {
|
| 560 |
+
opacity: .5;
|
| 561 |
+
}
|
| 562 |
+
|
| 563 |
+
/**
|
| 564 |
+
* New Content
|
| 565 |
+
*/
|
| 566 |
+
#wpadminbar #wp-admin-bar-new-content .ab-icon:before {
|
| 567 |
+
content: "\f132";
|
| 568 |
+
top: 4px;
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
/**
|
| 572 |
+
* Updates
|
| 573 |
+
*/
|
| 574 |
+
#wpadminbar #wp-admin-bar-updates .ab-icon:before {
|
| 575 |
+
content: "\f463";
|
| 576 |
+
top: 2px;
|
| 577 |
+
}
|
| 578 |
+
|
| 579 |
+
/**
|
| 580 |
+
* Search
|
| 581 |
+
*/
|
| 582 |
+
#wpadminbar #wp-admin-bar-search .ab-item {
|
| 583 |
+
padding: 0;
|
| 584 |
+
background: transparent;
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
#wpadminbar #adminbarsearch {
|
| 588 |
+
position: relative;
|
| 589 |
+
height: 32px;
|
| 590 |
+
padding: 0 2px;
|
| 591 |
+
z-index: 1;
|
| 592 |
+
}
|
| 593 |
+
|
| 594 |
+
#wpadminbar #adminbarsearch:before {
|
| 595 |
+
position: absolute;
|
| 596 |
+
top: 6px;
|
| 597 |
+
left: 5px;
|
| 598 |
+
z-index: 20;
|
| 599 |
+
font: normal 20px/1 dashicons !important;
|
| 600 |
+
content: "\f179";
|
| 601 |
+
speak: none;
|
| 602 |
+
-webkit-font-smoothing: antialiased;
|
| 603 |
+
-moz-osx-font-smoothing: grayscale;
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
/* The admin bar search field needs to reset many styles that might be inherited from the active Theme CSS. See ticket #40313. */
|
| 607 |
+
#wpadminbar > #wp-toolbar > #wp-admin-bar-top-secondary > #wp-admin-bar-search #adminbarsearch input.adminbar-input {
|
| 608 |
+
display: inline-block;
|
| 609 |
+
float: none;
|
| 610 |
+
position: relative;
|
| 611 |
+
z-index: 30;
|
| 612 |
+
font-size: 13px;
|
| 613 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
| 614 |
+
line-height: 24px;
|
| 615 |
+
text-indent: 0;
|
| 616 |
+
height: 24px;
|
| 617 |
+
width: 24px;
|
| 618 |
+
max-width: none;
|
| 619 |
+
padding: 0 3px 0 24px;
|
| 620 |
+
margin: 0;
|
| 621 |
+
color: #ccc;
|
| 622 |
+
background-color: rgba( 255, 255, 255, 0 );
|
| 623 |
+
border: none;
|
| 624 |
+
outline: none;
|
| 625 |
+
cursor: pointer;
|
| 626 |
+
box-shadow: none;
|
| 627 |
+
box-sizing: border-box;
|
| 628 |
+
transition-duration: 400ms;
|
| 629 |
+
transition-property: width, background;
|
| 630 |
+
transition-timing-function: ease;
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
#wpadminbar > #wp-toolbar > #wp-admin-bar-top-secondary > #wp-admin-bar-search #adminbarsearch input.adminbar-input:focus {
|
| 634 |
+
z-index: 10;
|
| 635 |
+
color: #000;
|
| 636 |
+
width: 200px;
|
| 637 |
+
background-color: rgba( 255, 255, 255, 0.9 );
|
| 638 |
+
cursor: text;
|
| 639 |
+
border: 0;
|
| 640 |
+
}
|
| 641 |
+
|
| 642 |
+
/* Removed IE hacks. */
|
| 643 |
+
|
| 644 |
+
#wpadminbar #adminbarsearch .adminbar-button {
|
| 645 |
+
display: none;
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
+
/**
|
| 649 |
+
* Customize support classes
|
| 650 |
+
*/
|
| 651 |
+
.no-customize-support .hide-if-no-customize,
|
| 652 |
+
.customize-support .hide-if-customize,
|
| 653 |
+
.no-customize-support #wpadminbar .hide-if-no-customize,
|
| 654 |
+
.no-customize-support.wp-core-ui .hide-if-no-customize,
|
| 655 |
+
.no-customize-support .wp-core-ui .hide-if-no-customize,
|
| 656 |
+
.customize-support #wpadminbar .hide-if-customize,
|
| 657 |
+
.customize-support.wp-core-ui .hide-if-customize,
|
| 658 |
+
.customize-support .wp-core-ui .hide-if-customize {
|
| 659 |
+
display: none;
|
| 660 |
+
}
|
| 661 |
+
|
| 662 |
+
/* Skip link */
|
| 663 |
+
#wpadminbar .screen-reader-text,
|
| 664 |
+
#wpadminbar .screen-reader-text span {
|
| 665 |
+
border: 0;
|
| 666 |
+
clip: rect(1px, 1px, 1px, 1px);
|
| 667 |
+
-webkit-clip-path: inset(50%);
|
| 668 |
+
clip-path: inset(50%);
|
| 669 |
+
height: 1px;
|
| 670 |
+
margin: -1px;
|
| 671 |
+
overflow: hidden;
|
| 672 |
+
padding: 0;
|
| 673 |
+
position: absolute;
|
| 674 |
+
width: 1px;
|
| 675 |
+
word-wrap: normal !important;
|
| 676 |
+
}
|
| 677 |
+
|
| 678 |
+
#wpadminbar .screen-reader-shortcut {
|
| 679 |
+
position: absolute;
|
| 680 |
+
top: -1000em;
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
#wpadminbar .screen-reader-shortcut:focus {
|
| 684 |
+
left: 6px;
|
| 685 |
+
top: 7px;
|
| 686 |
+
height: auto;
|
| 687 |
+
width: auto;
|
| 688 |
+
display: block;
|
| 689 |
+
font-size: 14px;
|
| 690 |
+
font-weight: 600;
|
| 691 |
+
padding: 15px 23px 14px;
|
| 692 |
+
background: #f1f1f1;
|
| 693 |
+
color: #0073aa;
|
| 694 |
+
z-index: 100000;
|
| 695 |
+
line-height: normal;
|
| 696 |
+
text-decoration: none;
|
| 697 |
+
box-shadow: 0 0 2px 2px rgba(0,0,0,.6);
|
| 698 |
+
}
|
| 699 |
+
|
| 700 |
+
/**
|
| 701 |
+
* Removed IE 6-targeted rules
|
| 702 |
+
*/
|
| 703 |
+
|
| 704 |
+
/* Removed No @font-face support */
|
| 705 |
+
|
| 706 |
+
@media screen and ( max-width: 782px ) {
|
| 707 |
+
/* Toolbar Touchification*/
|
| 708 |
+
html #wpadminbar {
|
| 709 |
+
height: 46px;
|
| 710 |
+
min-width: 300px;
|
| 711 |
+
}
|
| 712 |
+
|
| 713 |
+
#wpadminbar * {
|
| 714 |
+
font-size: 14px;
|
| 715 |
+
font-weight: 400;
|
| 716 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
| 717 |
+
line-height: 32px;
|
| 718 |
+
}
|
| 719 |
+
|
| 720 |
+
#wpadminbar .quicklinks > ul > li > a,
|
| 721 |
+
#wpadminbar .quicklinks .ab-empty-item {
|
| 722 |
+
padding: 0;
|
| 723 |
+
height: 46px;
|
| 724 |
+
line-height: 46px;
|
| 725 |
+
width: auto;
|
| 726 |
+
}
|
| 727 |
+
|
| 728 |
+
#wpadminbar .ab-icon {
|
| 729 |
+
font: 40px/1 dashicons !important;
|
| 730 |
+
margin: 0;
|
| 731 |
+
padding: 0;
|
| 732 |
+
width: 52px;
|
| 733 |
+
height: 46px;
|
| 734 |
+
text-align: center;
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
#wpadminbar .ab-icon:before {
|
| 738 |
+
text-align: center;
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
#wpadminbar .ab-submenu {
|
| 742 |
+
padding: 0;
|
| 743 |
+
}
|
| 744 |
+
|
| 745 |
+
#wpadminbar #wp-admin-bar-site-name a.ab-item,
|
| 746 |
+
#wpadminbar #wp-admin-bar-my-sites a.ab-item,
|
| 747 |
+
#wpadminbar #wp-admin-bar-my-account a.ab-item {
|
| 748 |
+
text-overflow: clip;
|
| 749 |
+
}
|
| 750 |
+
|
| 751 |
+
#wpadminbar .ab-label {
|
| 752 |
+
display: none;
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
#wpadminbar .menupop li:hover > .ab-sub-wrapper,
|
| 756 |
+
#wpadminbar .menupop li:focus-within > .ab-sub-wrapper {
|
| 757 |
+
margin-top: -46px;
|
| 758 |
+
}
|
| 759 |
+
|
| 760 |
+
#wpadminbar .ab-top-menu .menupop .ab-sub-wrapper .menupop > .ab-item {
|
| 761 |
+
padding-right: 30px;
|
| 762 |
+
}
|
| 763 |
+
|
| 764 |
+
#wpadminbar .menupop .menupop > .ab-item:before {
|
| 765 |
+
top: 10px;
|
| 766 |
+
right: 6px;
|
| 767 |
+
}
|
| 768 |
+
|
| 769 |
+
#wpadminbar .ab-top-menu > .menupop > .ab-sub-wrapper .ab-item {
|
| 770 |
+
font-size: 16px;
|
| 771 |
+
padding: 8px 16px;
|
| 772 |
+
}
|
| 773 |
+
|
| 774 |
+
#wpadminbar .ab-top-menu > .menupop > .ab-sub-wrapper a:empty {
|
| 775 |
+
display: none;
|
| 776 |
+
}
|
| 777 |
+
|
| 778 |
+
/* WP logo */
|
| 779 |
+
#wpadminbar #wp-admin-bar-wp-logo > .ab-item {
|
| 780 |
+
padding: 0;
|
| 781 |
+
}
|
| 782 |
+
|
| 783 |
+
#wpadminbar #wp-admin-bar-wp-logo > .ab-item .ab-icon {
|
| 784 |
+
padding: 0;
|
| 785 |
+
width: 52px;
|
| 786 |
+
height: 46px;
|
| 787 |
+
text-align: center;
|
| 788 |
+
vertical-align: top;
|
| 789 |
+
}
|
| 790 |
+
|
| 791 |
+
#wpadminbar #wp-admin-bar-wp-logo > .ab-item .ab-icon:before {
|
| 792 |
+
font: 28px/1 dashicons !important;
|
| 793 |
+
top: -3px;
|
| 794 |
+
}
|
| 795 |
+
|
| 796 |
+
#wpadminbar .ab-icon,
|
| 797 |
+
#wpadminbar .ab-item:before {
|
| 798 |
+
padding: 0;
|
| 799 |
+
}
|
| 800 |
+
|
| 801 |
+
/* My Sites and "Site Title" menu */
|
| 802 |
+
#wpadminbar #wp-admin-bar-my-sites > .ab-item,
|
| 803 |
+
#wpadminbar #wp-admin-bar-site-name > .ab-item,
|
| 804 |
+
#wpadminbar #wp-admin-bar-customize > .ab-item,
|
| 805 |
+
#wpadminbar #wp-admin-bar-edit > .ab-item,
|
| 806 |
+
#wpadminbar #wp-admin-bar-my-account > .ab-item {
|
| 807 |
+
text-indent: 100%;
|
| 808 |
+
white-space: nowrap;
|
| 809 |
+
overflow: hidden;
|
| 810 |
+
width: 52px;
|
| 811 |
+
padding: 0;
|
| 812 |
+
color: #a0a5aa; /* @todo not needed? this text is hidden */
|
| 813 |
+
position: relative;
|
| 814 |
+
}
|
| 815 |
+
|
| 816 |
+
#wpadminbar > #wp-toolbar > #wp-admin-bar-root-default .ab-icon,
|
| 817 |
+
#wpadminbar .ab-icon,
|
| 818 |
+
#wpadminbar .ab-item:before {
|
| 819 |
+
padding: 0;
|
| 820 |
+
margin-right: 0;
|
| 821 |
+
}
|
| 822 |
+
|
| 823 |
+
#wpadminbar #wp-admin-bar-edit > .ab-item:before,
|
| 824 |
+
#wpadminbar #wp-admin-bar-my-sites > .ab-item:before,
|
| 825 |
+
#wpadminbar #wp-admin-bar-site-name > .ab-item:before,
|
| 826 |
+
#wpadminbar #wp-admin-bar-customize > .ab-item:before,
|
| 827 |
+
#wpadminbar #wp-admin-bar-my-account > .ab-item:before {
|
| 828 |
+
display: block;
|
| 829 |
+
text-indent: 0;
|
| 830 |
+
font: normal 32px/1 dashicons;
|
| 831 |
+
speak: none;
|
| 832 |
+
top: 7px;
|
| 833 |
+
width: 52px;
|
| 834 |
+
text-align: center;
|
| 835 |
+
-webkit-font-smoothing: antialiased;
|
| 836 |
+
-moz-osx-font-smoothing: grayscale;
|
| 837 |
+
}
|
| 838 |
+
|
| 839 |
+
#wpadminbar #wp-admin-bar-appearance {
|
| 840 |
+
margin-top: 0;
|
| 841 |
+
}
|
| 842 |
+
|
| 843 |
+
#wpadminbar .quicklinks li .blavatar:before {
|
| 844 |
+
display: none;
|
| 845 |
+
}
|
| 846 |
+
|
| 847 |
+
/* Search */
|
| 848 |
+
#wpadminbar #wp-admin-bar-search {
|
| 849 |
+
display: none;
|
| 850 |
+
}
|
| 851 |
+
|
| 852 |
+
/* New Content */
|
| 853 |
+
#wpadminbar #wp-admin-bar-new-content .ab-icon:before {
|
| 854 |
+
top: 0;
|
| 855 |
+
line-height: 53px;
|
| 856 |
+
height: 46px !important;
|
| 857 |
+
text-align: center;
|
| 858 |
+
width: 52px;
|
| 859 |
+
display: block;
|
| 860 |
+
}
|
| 861 |
+
|
| 862 |
+
/* Updates */
|
| 863 |
+
#wpadminbar #wp-admin-bar-updates {
|
| 864 |
+
text-align: center;
|
| 865 |
+
}
|
| 866 |
+
|
| 867 |
+
#wpadminbar #wp-admin-bar-updates .ab-icon:before {
|
| 868 |
+
top: 3px;
|
| 869 |
+
}
|
| 870 |
+
|
| 871 |
+
/* Comments */
|
| 872 |
+
#wpadminbar #wp-admin-bar-comments .ab-icon {
|
| 873 |
+
margin: 0;
|
| 874 |
+
}
|
| 875 |
+
|
| 876 |
+
#wpadminbar #wp-admin-bar-comments .ab-icon:before {
|
| 877 |
+
display: block;
|
| 878 |
+
font-size: 34px;
|
| 879 |
+
height: 46px;
|
| 880 |
+
line-height: 47px;
|
| 881 |
+
top: 0;
|
| 882 |
+
}
|
| 883 |
+
|
| 884 |
+
/* My Account */
|
| 885 |
+
#wpadminbar #wp-admin-bar-my-account > a {
|
| 886 |
+
position: relative;
|
| 887 |
+
white-space: nowrap;
|
| 888 |
+
text-indent: 150%; /* More than 100% indention is needed since this element has padding */
|
| 889 |
+
width: 28px;
|
| 890 |
+
padding: 0 10px;
|
| 891 |
+
overflow: hidden; /* Prevent link text from forcing horizontal scrolling on mobile */
|
| 892 |
+
}
|
| 893 |
+
|
| 894 |
+
#wpadminbar .quicklinks li#wp-admin-bar-my-account.with-avatar > a img {
|
| 895 |
+
position: absolute;
|
| 896 |
+
top: 13px;
|
| 897 |
+
right: 10px;
|
| 898 |
+
width: 26px;
|
| 899 |
+
height: 26px;
|
| 900 |
+
}
|
| 901 |
+
|
| 902 |
+
#wpadminbar #wp-admin-bar-user-actions.ab-submenu {
|
| 903 |
+
padding: 0;
|
| 904 |
+
}
|
| 905 |
+
|
| 906 |
+
#wpadminbar #wp-admin-bar-user-actions.ab-submenu img.avatar {
|
| 907 |
+
display: none;
|
| 908 |
+
}
|
| 909 |
+
|
| 910 |
+
#wpadminbar #wp-admin-bar-my-account.with-avatar #wp-admin-bar-user-actions > li {
|
| 911 |
+
margin: 0;
|
| 912 |
+
}
|
| 913 |
+
|
| 914 |
+
#wpadminbar #wp-admin-bar-user-info .display-name {
|
| 915 |
+
height: auto;
|
| 916 |
+
font-size: 16px;
|
| 917 |
+
line-height: 24px;
|
| 918 |
+
color: #eee;
|
| 919 |
+
}
|
| 920 |
+
|
| 921 |
+
#wpadminbar #wp-admin-bar-user-info a {
|
| 922 |
+
padding-top: 4px;
|
| 923 |
+
}
|
| 924 |
+
|
| 925 |
+
#wpadminbar #wp-admin-bar-user-info .username {
|
| 926 |
+
line-height: 0.8 !important;
|
| 927 |
+
margin-bottom: -2px;
|
| 928 |
+
}
|
| 929 |
+
|
| 930 |
+
/* Show only default top level items */
|
| 931 |
+
#wp-toolbar > ul > li {
|
| 932 |
+
display: none;
|
| 933 |
+
}
|
| 934 |
+
|
| 935 |
+
#wpadminbar li#wp-admin-bar-menu-toggle,
|
| 936 |
+
#wpadminbar li#wp-admin-bar-wp-logo,
|
| 937 |
+
#wpadminbar li#wp-admin-bar-my-sites,
|
| 938 |
+
#wpadminbar li#wp-admin-bar-updates,
|
| 939 |
+
#wpadminbar li#wp-admin-bar-site-name,
|
| 940 |
+
#wpadminbar li#wp-admin-bar-customize,
|
| 941 |
+
#wpadminbar li#wp-admin-bar-new-content,
|
| 942 |
+
#wpadminbar li#wp-admin-bar-edit,
|
| 943 |
+
#wpadminbar li#wp-admin-bar-comments,
|
| 944 |
+
#wpadminbar li#wp-admin-bar-my-account {
|
| 945 |
+
display: block;
|
| 946 |
+
}
|
| 947 |
+
|
| 948 |
+
/* Allow dropdown list items to appear normally */
|
| 949 |
+
#wpadminbar li:hover ul li,
|
| 950 |
+
#wpadminbar li:focus-within ul li,
|
| 951 |
+
#wpadminbar li:hover ul li:hover ul li {
|
| 952 |
+
display: list-item;
|
| 953 |
+
}
|
| 954 |
+
|
| 955 |
+
/* Override default min-width so dropdown lists aren't stretched
|
| 956 |
+
to 100% viewport width at responsive sizes. */
|
| 957 |
+
#wpadminbar .ab-top-menu > .menupop > .ab-sub-wrapper {
|
| 958 |
+
min-width: -webkit-fit-content;
|
| 959 |
+
min-width: -moz-fit-content;
|
| 960 |
+
min-width: fit-content;
|
| 961 |
+
}
|
| 962 |
+
|
| 963 |
+
#wpadminbar ul#wp-admin-bar-root-default > li {
|
| 964 |
+
margin-right: 0;
|
| 965 |
+
}
|
| 966 |
+
|
| 967 |
+
/* Experimental fix for touch toolbar dropdown positioning */
|
| 968 |
+
#wpadminbar .ab-top-menu,
|
| 969 |
+
#wpadminbar .ab-top-secondary,
|
| 970 |
+
#wpadminbar #wp-admin-bar-wp-logo,
|
| 971 |
+
#wpadminbar #wp-admin-bar-my-sites,
|
| 972 |
+
#wpadminbar #wp-admin-bar-site-name,
|
| 973 |
+
#wpadminbar #wp-admin-bar-updates,
|
| 974 |
+
#wpadminbar #wp-admin-bar-comments,
|
| 975 |
+
#wpadminbar #wp-admin-bar-new-content,
|
| 976 |
+
#wpadminbar #wp-admin-bar-edit,
|
| 977 |
+
#wpadminbar #wp-admin-bar-my-account {
|
| 978 |
+
position: static;
|
| 979 |
+
}
|
| 980 |
+
|
| 981 |
+
#wpadminbar #wp-admin-bar-my-account {
|
| 982 |
+
float: right;
|
| 983 |
+
}
|
| 984 |
+
|
| 985 |
+
.network-admin #wpadminbar ul#wp-admin-bar-top-secondary > li#wp-admin-bar-my-account {
|
| 986 |
+
margin-right: 0;
|
| 987 |
+
}
|
| 988 |
+
|
| 989 |
+
/* Realign arrows on taller responsive submenus */
|
| 990 |
+
|
| 991 |
+
#wpadminbar .ab-top-secondary .menupop .menupop > .ab-item:before {
|
| 992 |
+
top: 10px;
|
| 993 |
+
left: 0;
|
| 994 |
+
}
|
| 995 |
+
}
|
| 996 |
+
|
| 997 |
+
/* Smartphone */
|
| 998 |
+
@media screen and (max-width: 600px) {
|
| 999 |
+
/* Removed: #wpadminbar { position: absolute; } */
|
| 1000 |
+
|
| 1001 |
+
#wp-responsive-overlay {
|
| 1002 |
+
position: fixed;
|
| 1003 |
+
top: 0;
|
| 1004 |
+
left: 0;
|
| 1005 |
+
width: 100%;
|
| 1006 |
+
height: 100%;
|
| 1007 |
+
z-index: 400;
|
| 1008 |
+
}
|
| 1009 |
+
|
| 1010 |
+
#wpadminbar .ab-top-menu > .menupop > .ab-sub-wrapper {
|
| 1011 |
+
width: 100%;
|
| 1012 |
+
left: 0;
|
| 1013 |
+
}
|
| 1014 |
+
|
| 1015 |
+
#wpadminbar .menupop .menupop > .ab-item:before {
|
| 1016 |
+
display: none;
|
| 1017 |
+
}
|
| 1018 |
+
|
| 1019 |
+
#wpadminbar #wp-admin-bar-wp-logo.menupop .ab-sub-wrapper {
|
| 1020 |
+
margin-left: 0;
|
| 1021 |
+
}
|
| 1022 |
+
|
| 1023 |
+
#wpadminbar .ab-top-menu > .menupop li > .ab-sub-wrapper {
|
| 1024 |
+
margin: 0;
|
| 1025 |
+
width: 100%;
|
| 1026 |
+
top: auto;
|
| 1027 |
+
left: auto;
|
| 1028 |
+
position: relative;
|
| 1029 |
+
}
|
| 1030 |
+
|
| 1031 |
+
#wpadminbar .ab-top-menu > .menupop li > .ab-sub-wrapper .ab-item {
|
| 1032 |
+
font-size: 16px;
|
| 1033 |
+
padding: 6px 15px 19px 30px;
|
| 1034 |
+
}
|
| 1035 |
+
|
| 1036 |
+
#wpadminbar li:hover ul li ul li {
|
| 1037 |
+
display: list-item;
|
| 1038 |
+
}
|
| 1039 |
+
|
| 1040 |
+
#wpadminbar li#wp-admin-bar-wp-logo,
|
| 1041 |
+
#wpadminbar li#wp-admin-bar-updates {
|
| 1042 |
+
display: none;
|
| 1043 |
+
}
|
| 1044 |
+
|
| 1045 |
+
/* Make submenus full-width at this size */
|
| 1046 |
+
|
| 1047 |
+
#wpadminbar .ab-top-menu > .menupop li > .ab-sub-wrapper {
|
| 1048 |
+
position: static;
|
| 1049 |
+
box-shadow: none;
|
| 1050 |
+
}
|
| 1051 |
+
}
|
| 1052 |
+
|
| 1053 |
+
/* Very narrow screens */
|
| 1054 |
+
@media screen and (max-width: 400px) {
|
| 1055 |
+
#wpadminbar li#wp-admin-bar-comments {
|
| 1056 |
+
display: none;
|
| 1057 |
+
}
|
| 1058 |
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.column-error_status .dashicons-editor-help {
|
| 2 |
+
color: #767676;
|
| 3 |
+
}
|
| 4 |
+
.column-sources .dashicons,
|
| 5 |
+
.column-sources_with_invalid_output .dashicons {
|
| 6 |
+
margin-right: 5px;
|
| 7 |
+
}
|
| 8 |
+
.column-source .dashicons-admin-plugins,
|
| 9 |
+
.column-sources_with_invalid_output .dashicons-admin-plugins {
|
| 10 |
+
color: #64a2e9;
|
| 11 |
+
}
|
| 12 |
+
.column-source .dashicons-admin-appearance,
|
| 13 |
+
.column-sources_with_invalid_output .dashicons-admin-appearance {
|
| 14 |
+
color: #ebb04f;
|
| 15 |
+
}
|
| 16 |
+
.column-source, .dashicons-wordpress-alt,
|
| 17 |
+
.column-sources_with_invalid_output .dashicons-wordpress-alt {
|
| 18 |
+
color: #92b371;
|
| 19 |
+
}
|
| 20 |
+
.amp-logo-icon {
|
| 21 |
+
background-image: url( '../images/amp-logo-icon.svg' );
|
| 22 |
+
background-color: transparent;
|
| 23 |
+
background-size: 20px 20px;
|
| 24 |
+
height: 20px;
|
| 25 |
+
width: 20px;
|
| 26 |
+
display: inline-block;
|
| 27 |
+
}
|
| 28 |
+
.column-error_status .error-status {
|
| 29 |
+
line-height: 20px;
|
| 30 |
+
display: inline-block;
|
| 31 |
+
position: relative;
|
| 32 |
+
vertical-align: top;
|
| 33 |
+
margin-left: 10px;
|
| 34 |
+
}
|
| 35 |
+
td.column-found_elements_and_attributes {
|
| 36 |
+
color: #970010;
|
| 37 |
+
}
|
| 38 |
+
td.column-found_elements_and_attributes div {
|
| 39 |
+
margin-bottom: 0.6rem;
|
| 40 |
+
}
|
| 41 |
+
.column-error_status .dashicons-flag.new {
|
| 42 |
+
color: #d98501;
|
| 43 |
+
}
|
| 44 |
+
.column-error_status .dashicons-yes.new {
|
| 45 |
+
color: #ff0000;
|
| 46 |
+
}
|
| 47 |
+
.column-error_status .dashicons-warning.rejected {
|
| 48 |
+
color: #68c6ff;
|
| 49 |
+
}
|
| 50 |
+
.column-sources .source,
|
| 51 |
+
.column-sources_with_invalid_output .source {
|
| 52 |
+
margin-bottom: 10px;
|
| 53 |
+
display: block;
|
| 54 |
+
}
|
| 55 |
+
.wrap .wp-heading-inline + .page-title-action {
|
| 56 |
+
margin-left: 1rem;
|
| 57 |
+
}
|
|
@@ -1,11 +1,25 @@
|
|
| 1 |
-
.amp-wp-
|
| 2 |
-
/** Our sizes fallback is 100vw, and we have a padding on the container; the max-width here prevents the element from overflowing. **/
|
| 3 |
-
max-width: 100%;
|
| 4 |
-
margin: 0 auto;
|
| 5 |
-
}
|
| 6 |
-
|
| 7 |
-
.amp-wp-unknown-size img {
|
| 8 |
/** Worst case scenario when we can't figure out dimensions for an image. **/
|
| 9 |
/** Force the image into a box of fixed dimensions and use object-fit to scale. **/
|
| 10 |
object-fit: contain;
|
| 11 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.amp-wp-unknown-size [src] {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
/** Worst case scenario when we can't figure out dimensions for an image. **/
|
| 3 |
/** Force the image into a box of fixed dimensions and use object-fit to scale. **/
|
| 4 |
object-fit: contain;
|
| 5 |
}
|
| 6 |
+
|
| 7 |
+
amp-fit-text blockquote,
|
| 8 |
+
amp-fit-text h1,
|
| 9 |
+
amp-fit-text h2,
|
| 10 |
+
amp-fit-text h3,
|
| 11 |
+
amp-fit-text h4,
|
| 12 |
+
amp-fit-text h5,
|
| 13 |
+
amp-fit-text h6 {
|
| 14 |
+
font-size: inherit;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
/**
|
| 18 |
+
* Override a style rule in Twenty Sixteen and Twenty Seventeen.
|
| 19 |
+
* It set display:none for audio elements.
|
| 20 |
+
* This selector is the same, though it adds body and uses amp-audio instead of audio.
|
| 21 |
+
*/
|
| 22 |
+
body amp-audio:not([controls]) {
|
| 23 |
+
display: inline-block;
|
| 24 |
+
height: auto;
|
| 25 |
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.is-amp-fit-text + .blocks-font-size > .components-font-size-picker__buttons,
|
| 2 |
+
.is-amp-fit-text + .blocks-font-size > .components-font-size-picker__custom-input {
|
| 3 |
+
display: none;
|
| 4 |
+
}
|
|
@@ -64,3 +64,16 @@
|
|
| 64 |
line-height: 280%;
|
| 65 |
}
|
| 66 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
line-height: 280%;
|
| 65 |
}
|
| 66 |
}
|
| 67 |
+
|
| 68 |
+
.amp-block-validation-errors {
|
| 69 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
| 70 |
+
font-size: 13px;
|
| 71 |
+
line-height: 1.5;
|
| 72 |
+
}
|
| 73 |
+
.amp-block-validation-errors .amp-block-validation-errors__summary {
|
| 74 |
+
margin: 0.5em 0;
|
| 75 |
+
padding: 2px;
|
| 76 |
+
}
|
| 77 |
+
.amp-block-validation-errors .amp-block-validation-errors__list {
|
| 78 |
+
padding-left: 2.5em;
|
| 79 |
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#col-left {
|
| 2 |
+
display: none;
|
| 3 |
+
}
|
| 4 |
+
#col-right {
|
| 5 |
+
float: none;
|
| 6 |
+
width: auto;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
/* Move the 'All dates' filter to the right of the new status and type filters */
|
| 10 |
+
#filter-by-date {
|
| 11 |
+
float: none;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
/* Improve column widths */
|
| 15 |
+
td.column-details pre,
|
| 16 |
+
td.column-sources pre {
|
| 17 |
+
overflow: auto;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
th.column-created_date_gmt,
|
| 21 |
+
th.column-error_type {
|
| 22 |
+
width: 15%;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
td.column-error .error-code {
|
| 26 |
+
font-family: Consolas, Monaco, monospace;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
th.column-status {
|
| 30 |
+
width: 15%;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.fixed th.column-posts {
|
| 34 |
+
width: 10%;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
/* Details column */
|
| 38 |
+
.column-details .details-attributes__summary {
|
| 39 |
+
display: flex;
|
| 40 |
+
justify-content: space-between;
|
| 41 |
+
align-items: center;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
details[open] .details-attributes__summary {
|
| 45 |
+
font-weight: 600;
|
| 46 |
+
margin-bottom: 15px;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
.column-details .details-attributes__summary::-webkit-details-marker,
|
| 50 |
+
.column-details .notice details > summary::-webkit-details-marker {
|
| 51 |
+
display: none;
|
| 52 |
+
}
|
| 53 |
+
.details-attributes__summary::after,
|
| 54 |
+
.single-error-detail-summary::after {
|
| 55 |
+
order: 99;
|
| 56 |
+
width: 12px;
|
| 57 |
+
height: 12px;
|
| 58 |
+
background-image: url("../images/down-triangle.svg");
|
| 59 |
+
background-size: cover;
|
| 60 |
+
background-position: center;
|
| 61 |
+
content: "";
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
tr.expanded .details-attributes__summary::after,
|
| 65 |
+
details.single-error-detail[open] .single-error-detail-summary::after {
|
| 66 |
+
transform: rotate(180deg);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
.notice .detailed {
|
| 70 |
+
padding-left: 15px;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
.notice .detailed details {
|
| 74 |
+
padding-bottom: 16px;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.notice .detailed details .detailed {
|
| 78 |
+
padding-left: 32px;
|
| 79 |
+
font-family: Consolas, Monaco, monospace;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.details-attributes__title code,
|
| 83 |
+
.notice .detailed summary code {
|
| 84 |
+
display: inline-block;
|
| 85 |
+
min-width: 240px;
|
| 86 |
+
margin-left: 18px;
|
| 87 |
+
font-weight: 600;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.details-attributes__title code {
|
| 91 |
+
margin-left: 0;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
.details-attributes__list {
|
| 95 |
+
margin-top: 0;
|
| 96 |
+
padding-left: 0;
|
| 97 |
+
list-style: none;
|
| 98 |
+
font-family: Consolas, Monaco, monospace;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
.details-attributes__list li {
|
| 102 |
+
word-break: break-all;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
.details-attributes__attr {
|
| 106 |
+
font-weight: 600;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.column-sources_with_invalid_output details[open] .details-attributes__summary {
|
| 110 |
+
margin-bottom: 5px;
|
| 111 |
+
}
|
| 112 |
+
.column-sources_with_invalid_output details > div {
|
| 113 |
+
padding-left: 25px;
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
/* Error details toggle button */
|
| 117 |
+
.manage-column.column-sources_with_invalid_output .error-details-toggle {
|
| 118 |
+
margin: 0;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.error-details-toggle {
|
| 122 |
+
float: right;
|
| 123 |
+
display: flex;
|
| 124 |
+
flex-direction: column;
|
| 125 |
+
height: 14px;
|
| 126 |
+
padding: 0;
|
| 127 |
+
margin-top: 4px;
|
| 128 |
+
background: none;
|
| 129 |
+
border: none;
|
| 130 |
+
cursor: pointer;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
.error-details-toggle.is-open {
|
| 134 |
+
transform: rotate(180deg);
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
.column-details .error-details-toggle::before,
|
| 138 |
+
.column-details .error-details-toggle::after {
|
| 139 |
+
width: 12px;
|
| 140 |
+
height: 12px;
|
| 141 |
+
background-image: url("../images/down-triangle.svg");
|
| 142 |
+
background-size: cover;
|
| 143 |
+
background-position: center;
|
| 144 |
+
content: "";
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
/* Status text icons */
|
| 148 |
+
.status-text {
|
| 149 |
+
display: flex;
|
| 150 |
+
align-items: center;
|
| 151 |
+
padding-bottom: 0.6rem;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
.status-text::before {
|
| 155 |
+
margin-right: 10px;
|
| 156 |
+
background-size: 20px 20px;
|
| 157 |
+
height: 20px;
|
| 158 |
+
width: 20px;
|
| 159 |
+
content: "";
|
| 160 |
+
min-width: 20px;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
.status-text.sanitized::before {
|
| 164 |
+
background-image: url("../images/amp-logo-icon.svg");
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
.status-text.new::before {
|
| 168 |
+
background-image: url("../images/baseline-error.svg");
|
| 169 |
+
}
|
| 170 |
+
.status-text.new.new-accepted::before, .status-text.new.accepted::before{
|
| 171 |
+
background-image: url("../images/baseline-error-green.svg");
|
| 172 |
+
}
|
| 173 |
+
.status-text.new.new-rejected::before, .status-text.new.rejected::before {
|
| 174 |
+
background-image: url("../images/baseline-error-red.svg");
|
| 175 |
+
}
|
| 176 |
+
.status-text.accepted::before {
|
| 177 |
+
background-image: url("../images/baseline-check-circle-green.svg");
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
.status-text.rejected::before {
|
| 181 |
+
background-image: url("../images/error-rejected.svg");
|
| 182 |
+
}
|
| 183 |
+
.single-error-detail {
|
| 184 |
+
margin: 5px 0 5px 0;
|
| 185 |
+
}
|
| 186 |
+
.single-error-detail-summary:after {
|
| 187 |
+
display: inline-block;
|
| 188 |
+
}
|
| 189 |
+
.single-error-detail-summary strong {
|
| 190 |
+
margin-right: 10px;
|
| 191 |
+
font-size: 15px;
|
| 192 |
+
}
|
| 193 |
+
.single-error-detail ul.secondary-details-array .details-attributes__attr {
|
| 194 |
+
margin-left: 20px;
|
| 195 |
+
}
|
| 196 |
+
.single-error-detail ul.secondary-details-array .details-attributes__value {
|
| 197 |
+
margin-left: 30px;
|
| 198 |
+
}
|
| 199 |
+
.single-error-detail .details-attributes__value {
|
| 200 |
+
margin-left: 10px;
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
body.taxonomy-amp_validation_error .wp-list-table .new th,
|
| 204 |
+
body.taxonomy-amp_validation_error .wp-list-table .new td,
|
| 205 |
+
tr.expanded.new + tr > td:first-of-type,
|
| 206 |
+
body.post-type-amp_validated_url .wp-list-table .new th,
|
| 207 |
+
body.post-type-amp_validated_url .wp-list-table .new td {
|
| 208 |
+
background-color: #fef7f1;
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
body.taxonomy-amp_validation_error .wp-list-table .new th.check-column,
|
| 212 |
+
tr.expanded.new + tr > td:first-of-type,
|
| 213 |
+
body.post-type-amp_validated_url .wp-list-table .new th.check-column {
|
| 214 |
+
border-left: 4px solid #d54e21;
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
body.taxonomy-amp_validation_error .wp-list-table .new th.check-column input {
|
| 218 |
+
margin-left: 4px;
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
.row-actions .amp_validation_error_accept > a {
|
| 222 |
+
color: #006505;
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
.row-actions .amp_validation_error_reject > a {
|
| 226 |
+
color: #a00;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
.notice.accept-reject-error {
|
| 230 |
+
display: flex;
|
| 231 |
+
margin-bottom: 0;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
.notice.accept-reject-error > p {
|
| 235 |
+
display: inline-block;
|
| 236 |
+
font-size: 14px;
|
| 237 |
+
flex-grow: 10;
|
| 238 |
+
margin-right: 20px;
|
| 239 |
+
}
|
| 240 |
+
.notice.accept-reject-error > .button {
|
| 241 |
+
display: inline-block;
|
| 242 |
+
margin: 5px 5px 0 5px;
|
| 243 |
+
padding: 0 26px 2px;
|
| 244 |
+
flex-grow: 1;
|
| 245 |
+
text-align: center;
|
| 246 |
+
}
|
| 247 |
+
.notice.accept-reject-error > .button.accept {
|
| 248 |
+
/* @todo Add green colors */
|
| 249 |
+
}
|
| 250 |
+
.notice.accept-reject-error > .button.reject {
|
| 251 |
+
/* @todo Add red colors */
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
.notice.error-details {
|
| 255 |
+
margin-top: 1px;
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
.wp-heading-inline .status-text {
|
| 259 |
+
display: inline-flex;
|
| 260 |
+
margin-left: 10px;
|
| 261 |
+
vertical-align: middle;
|
| 262 |
+
padding-bottom: 0;
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
.wp-heading-inline code {
|
| 266 |
+
font-size: 1rem;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
/** Details post action. */
|
| 270 |
+
.details button {
|
| 271 |
+
display: inline-block;
|
| 272 |
+
background: none;
|
| 273 |
+
border: none;
|
| 274 |
+
padding: 0;
|
| 275 |
+
text-align: left;
|
| 276 |
+
color: #0073aa;
|
| 277 |
+
cursor: pointer;
|
| 278 |
+
text-decoration: underline;
|
| 279 |
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** Arrow icon on title in error column. */
|
| 2 |
+
.column-error > .single-url-detail-toggle {
|
| 3 |
+
position: relative;
|
| 4 |
+
width: 100%;
|
| 5 |
+
padding: 5px 36px 5px 0;
|
| 6 |
+
background: none;
|
| 7 |
+
border: none;
|
| 8 |
+
text-align: left;
|
| 9 |
+
line-height: 1.682;
|
| 10 |
+
color: #0073aa;
|
| 11 |
+
cursor: pointer;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
.column-error > .single-url-detail-toggle::after {
|
| 15 |
+
position: absolute;
|
| 16 |
+
top: 0;
|
| 17 |
+
right: 0;
|
| 18 |
+
display: flex;
|
| 19 |
+
align-items: center;
|
| 20 |
+
justify-content: center;
|
| 21 |
+
width: 12px;
|
| 22 |
+
height: 18px;
|
| 23 |
+
margin-top: 5px;
|
| 24 |
+
background-image: url("../images/down-triangle.svg");
|
| 25 |
+
background-size: contain;
|
| 26 |
+
background-repeat: no-repeat;
|
| 27 |
+
background-position: center;
|
| 28 |
+
content: "";
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
tr.expanded .single-url-detail-toggle::after {
|
| 32 |
+
transform: rotate(180deg);
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
/** Striped table overrides. */
|
| 36 |
+
table.striped > tbody > tr.odd {
|
| 37 |
+
background: #f9f9f9;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
table.striped > tbody > tr.even {
|
| 41 |
+
background: #fff;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/** Hide original details content. */
|
| 45 |
+
.details-attributes > .detailed {
|
| 46 |
+
display: none;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
/** Details post action. */
|
| 50 |
+
.details button {
|
| 51 |
+
display: inline-block;
|
| 52 |
+
background: none;
|
| 53 |
+
border: none;
|
| 54 |
+
padding: 0;
|
| 55 |
+
text-align: left;
|
| 56 |
+
color: #0073aa;
|
| 57 |
+
cursor: pointer;
|
| 58 |
+
text-decoration: underline;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
/** Details row styles. */
|
| 62 |
+
.details details.details-attributes:hover {
|
| 63 |
+
cursor: pointer;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
.details ul.detailed {
|
| 67 |
+
padding: 0 32px;
|
| 68 |
+
margin-top: 0;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
.details div.detailed {
|
| 72 |
+
padding-left: 30px;
|
| 73 |
+
margin-top: 10px;
|
| 74 |
+
font-family: Consolas, Monaco, monospace;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.details .detailed details {
|
| 78 |
+
padding-bottom: 16px;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
.details .detailed summary code {
|
| 82 |
+
display: inline-block;
|
| 83 |
+
min-width: 240px;
|
| 84 |
+
margin-left: 12px;
|
| 85 |
+
font-weight: 600;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
.column-status select {
|
| 89 |
+
vertical-align: top;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
.column-status img {
|
| 93 |
+
width: 1.5rem;
|
| 94 |
+
margin-top: 0.2rem;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
#number-errors {
|
| 98 |
+
text-align: center;
|
| 99 |
+
background-color: #d3d3d3b8;
|
| 100 |
+
color: #1e8cbecc;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
#url-post-filter {
|
| 104 |
+
float: none;
|
| 105 |
+
display: inline;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
.tablenav.top,
|
| 109 |
+
.tablenav.bottom {
|
| 110 |
+
display: none;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
.amp-validated-url a {
|
| 114 |
+
text-decoration: none;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
.curtime.misc-pub-section {
|
| 118 |
+
margin-top: 0.5rem;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
/* Give enough width to prevent the widest column status, 'New Accepted,' from forcing the <select> below the icon. */
|
| 122 |
+
.wp-list-table th.column-status {
|
| 123 |
+
width: 150px;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
.wp-list-table th.column-sources_with_invalid_output {
|
| 127 |
+
width: 20%;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
.wp-list-table th.column-error {
|
| 131 |
+
width: 25%;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
.wp-list-table th.column-details {
|
| 135 |
+
width: 20%;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
/** Add space between list table and the filter and search box above it. */
|
| 139 |
+
#post-body-content button.action,
|
| 140 |
+
#post-body-content #url-post-filter,
|
| 141 |
+
#post-body-content .search-box {
|
| 142 |
+
margin-bottom: 4px;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
#post-body-content button.reject {
|
| 146 |
+
margin-left: 4px;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
#accept-reject-buttons:not(.hidden) {
|
| 150 |
+
display: inline-block;
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
#vertical-divider {
|
| 154 |
+
display: inline-block;
|
| 155 |
+
vertical-align: middle;
|
| 156 |
+
width: 15px;
|
| 157 |
+
margin-right: 15px;
|
| 158 |
+
height: 30px;
|
| 159 |
+
border-right: 1px solid #a0a5aa;
|
| 160 |
+
}
|
| 161 |
+
.amp-validation-error-status {
|
| 162 |
+
width: auto;
|
| 163 |
+
float: none;
|
| 164 |
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
/* @todo This should be moved to admin-tables.css which is then enqueued on both screens. */
|
| 3 |
+
.tooltip-button {
|
| 4 |
+
margin: 0 6px;
|
| 5 |
+
cursor: pointer;
|
| 6 |
+
color: #767676;
|
| 7 |
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
| 3 |
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
| 4 |
+
viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
|
| 5 |
+
<g id="AMP-Logo-Icon" fill="#0075C2">
|
| 6 |
+
<path d="M13.3,9.1l-4,6.6H8.5l0.7-4.3l-2.2,0h0c-0.2,0-0.4-0.2-0.4-0.4c0-0.1,0.1-0.2,0.1-0.2l4-6.6l0.7,0l-0.7,4.3l2.2,0l0,0
|
| 7 |
+
c0.2,0,0.4,0.2,0.4,0.4C13.4,9,13.3,9.1,13.3,9.1L13.3,9.1z M10,0.5c-5.3,0-9.6,4.3-9.6,9.5c0,5.3,4.3,9.5,9.6,9.5
|
| 8 |
+
c5.3,0,9.6-4.3,9.6-9.5C19.6,4.7,15.3,0.5,10,0.5z"/></g>
|
| 9 |
+
</svg>
|
| 10 |
+
|
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
| 3 |
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
| 4 |
+
viewBox="908.3604125976562 898.2000122070312 183.05340576171875 200.39996337890625" style="enable-background:new 0 0 2000 2000;" xml:space="preserve">
|
| 5 |
+
<style type="text/css">
|
| 6 |
+
.st0{opacity:0.8;fill:none;stroke:url(#SVGID_1_);stroke-width:9.6838;stroke-miterlimit:10;enable-background:new ;}
|
| 7 |
+
.st1{opacity:0.8;fill:none;stroke:url(#SVGID_2_);stroke-width:10.1244;stroke-miterlimit:10;enable-background:new ;}
|
| 8 |
+
.st2{fill:none;stroke:url(#SVGID_3_);stroke-width:2.4095;stroke-miterlimit:10;}
|
| 9 |
+
.st3{fill:url(#SVGID_4_);}
|
| 10 |
+
.st4{fill:#FFFFFF;stroke:url(#SVGID_5_);stroke-width:2.4095;stroke-miterlimit:10;}
|
| 11 |
+
.st5{fill:none;stroke:url(#SVGID_6_);stroke-width:2.4095;stroke-miterlimit:10;}
|
| 12 |
+
.st6{fill:#0DD7FF;fill-opacity:0.7;}
|
| 13 |
+
.st7{opacity:0.7;fill:#0DD7FF;enable-background:new ;}
|
| 14 |
+
.st8{fill:url(#SVGID_7_);fill-opacity:0.75;}
|
| 15 |
+
.st9{fill:none;stroke:url(#SVGID_8_);stroke-width:2.4095;stroke-linecap:round;stroke-miterlimit:10;}
|
| 16 |
+
.st10{fill:none;stroke:url(#SVGID_9_);stroke-width:2.4095;stroke-linecap:round;stroke-miterlimit:10;}
|
| 17 |
+
.st11{fill:#FFFFFF;fill-opacity:0.75;stroke:url(#SVGID_10_);stroke-width:2.4095;stroke-miterlimit:10;}
|
| 18 |
+
.st12{fill:url(#SVGID_11_);fill-opacity:0.75;}
|
| 19 |
+
.st13{fill:none;stroke:url(#SVGID_12_);stroke-width:2.4095;stroke-linecap:round;stroke-miterlimit:10;}
|
| 20 |
+
.st14{fill:none;stroke:url(#SVGID_13_);stroke-width:2.4095;stroke-linecap:round;stroke-miterlimit:10;}
|
| 21 |
+
.st15{fill:#FFFFFF;}
|
| 22 |
+
.st16{fill:#167DD2;}
|
| 23 |
+
.st17{opacity:0.3;fill:#0DD7FF;enable-background:new ;}
|
| 24 |
+
.st18{opacity:0.5;fill:none;stroke:#FFFFFF;stroke-width:2.4095;stroke-linecap:round;stroke-miterlimit:10;}
|
| 25 |
+
</style>
|
| 26 |
+
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-12002.9561" y1="893.2319" x2="-11948.1289" y2="893.2319" gradientTransform="matrix(0.3305 -0.9438 -0.9438 -0.3305 5754.7773 -10044.6777)">
|
| 27 |
+
<stop offset="0" style="stop-color:#0389FF"/>
|
| 28 |
+
<stop offset="0.5" style="stop-color:#0DD7FF"/>
|
| 29 |
+
<stop offset="1" style="stop-color:#FFFFFF"/>
|
| 30 |
+
</linearGradient>
|
| 31 |
+
<line class="st0" x1="954.3" y1="935.3" x2="953.8" y2="989.9"/>
|
| 32 |
+
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="-12020.958" y1="879.0432" x2="-11920.0166" y2="879.0432" gradientTransform="matrix(0.3305 -0.9438 -0.9438 -0.3305 5754.7773 -10044.6777)">
|
| 33 |
+
<stop offset="0" style="stop-color:#0389FF"/>
|
| 34 |
+
<stop offset="0.5" style="stop-color:#0DD7FF"/>
|
| 35 |
+
<stop offset="1" style="stop-color:#FFFFFF"/>
|
| 36 |
+
</linearGradient>
|
| 37 |
+
<line class="st1" x1="969.7" y1="910.9" x2="968.5" y2="1014"/>
|
| 38 |
+
<g>
|
| 39 |
+
|
| 40 |
+
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="1008.2053" y1="1053.8057" x2="1008.2053" y2="1103.8019" gradientTransform="matrix(1 0 0 -1 0 2002)">
|
| 41 |
+
<stop offset="0" style="stop-color:#1C79C4"/>
|
| 42 |
+
<stop offset="0.51" style="stop-color:#0389FF"/>
|
| 43 |
+
<stop offset="1" style="stop-color:#0DD7FF"/>
|
| 44 |
+
</linearGradient>
|
| 45 |
+
<line class="st2" x1="1008.2" y1="948.2" x2="1008.2" y2="900.8"/>
|
| 46 |
+
|
| 47 |
+
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="1008.2053" y1="1053.8057" x2="1008.2053" y2="1103.8019" gradientTransform="matrix(1 0 0 -1 0 2002)">
|
| 48 |
+
<stop offset="0" style="stop-color:#1C79C4"/>
|
| 49 |
+
<stop offset="0.51" style="stop-color:#0389FF"/>
|
| 50 |
+
<stop offset="1" style="stop-color:#0DD7FF"/>
|
| 51 |
+
</linearGradient>
|
| 52 |
+
<polygon class="st3" points="1018.1,908.8 1016.3,910.4 1008.2,901.7 1000.1,910.4 998.4,908.8 1008.2,898.2 "/>
|
| 53 |
+
</g>
|
| 54 |
+
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="941.6317" y1="1014.0682" x2="1040.9495" y2="1014.0682">
|
| 55 |
+
<stop offset="0" style="stop-color:#187CCE"/>
|
| 56 |
+
<stop offset="1" style="stop-color:#0DD5FE"/>
|
| 57 |
+
</linearGradient>
|
| 58 |
+
<polygon class="st4" points="942.8,1098.6 1039.7,1045.5 1039.7,929.6 942.8,982.7 "/>
|
| 59 |
+
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="943.079" y1="1027.4312" x2="1041.1453" y2="1027.4312" gradientTransform="matrix(1 0 0 -1 0 2002)">
|
| 60 |
+
<stop offset="0" style="stop-color:#1C79C4"/>
|
| 61 |
+
<stop offset="0.51" style="stop-color:#0389FF"/>
|
| 62 |
+
<stop offset="1" style="stop-color:#0DD7FF"/>
|
| 63 |
+
</linearGradient>
|
| 64 |
+
<line class="st5" x1="1040.6" y1="948" x2="943.7" y2="1001.1"/>
|
| 65 |
+
<ellipse transform="matrix(0.1104 -0.9939 0.9939 0.1104 -124.5549 1829.4717)" class="st6" cx="959.7" cy="984.3" rx="2.8" ry="2.8"/>
|
| 66 |
+
<ellipse transform="matrix(0.1094 -0.994 0.994 0.1094 -133.3753 1826.4724)" class="st6" cx="952.6" cy="987.7" rx="2.8" ry="2.8"/>
|
| 67 |
+
<ellipse transform="matrix(0.1094 -0.994 0.994 0.1094 -111.5842 1834.7726)" class="st6" cx="968.1" cy="979.7" rx="2.8" ry="2.8"/>
|
| 68 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 23.327 1872.063)" class="st7" cx="1064.6" cy="922.9" rx="3.4" ry="3.5"/>
|
| 69 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 -144.5006 1781.6594)" class="st7" cx="929.9" cy="972.1" rx="3.4" ry="3.5"/>
|
| 70 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 -261.0735 1874.2338)" class="st7" cx="923.7" cy="1084" rx="3.4" ry="3.5"/>
|
| 71 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 -116.1821 1770.166)" class="st7" cx="937.6" cy="950.4" rx="3.4" ry="3.5"/>
|
| 72 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 -177.6883 1787.7156)" class="st7" cx="916.7" cy="993.8" rx="3.4" ry="3.5"/>
|
| 73 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 2.8353 1930.9661)" class="st7" cx="1087.5" cy="963.9" rx="3.4" ry="3.5"/>
|
| 74 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 14.4208 1901.3986)" class="st7" cx="1076.7" cy="942.6" rx="3.4" ry="3.5"/>
|
| 75 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 -255.1249 1856.6938)" class="st7" cx="916.8" cy="1071.8" rx="3.4" ry="3.5"/>
|
| 76 |
+
<ellipse transform="matrix(0.1172 -0.9931 0.9931 0.1172 -141.707 1747.8772)" class="st7" cx="912.3" cy="953.6" rx="3.4" ry="3.5"/>
|
| 77 |
+
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="988.4651" y1="1030.0048" x2="988.4651" y2="980.6591">
|
| 78 |
+
<stop offset="0" style="stop-color:#187CCE"/>
|
| 79 |
+
<stop offset="0" style="stop-color:#187FD0"/>
|
| 80 |
+
<stop offset="1" style="stop-color:#0DD5FE"/>
|
| 81 |
+
</linearGradient>
|
| 82 |
+
<polygon class="st8" points="972.5,1030 1004.4,1013.6 1004.4,980.7 972.5,997 "/>
|
| 83 |
+
<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="976.1646" y1="969.6558" x2="1000.2975" y2="969.6558" gradientTransform="matrix(1 0 0 -1 0 2002)">
|
| 84 |
+
<stop offset="0" style="stop-color:#1C79C4"/>
|
| 85 |
+
<stop offset="0.51" style="stop-color:#0389FF"/>
|
| 86 |
+
<stop offset="1" style="stop-color:#0DD7FF"/>
|
| 87 |
+
</linearGradient>
|
| 88 |
+
<line class="st9" x1="977.4" y1="1038.1" x2="999.1" y2="1026.6"/>
|
| 89 |
+
<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="976.1646" y1="961.2227" x2="1000.2975" y2="961.2227" gradientTransform="matrix(1 0 0 -1 0 2002)">
|
| 90 |
+
<stop offset="0" style="stop-color:#1C79C4"/>
|
| 91 |
+
<stop offset="0.51" style="stop-color:#0389FF"/>
|
| 92 |
+
<stop offset="1" style="stop-color:#0DD7FF"/>
|
| 93 |
+
</linearGradient>
|
| 94 |
+
<line class="st10" x1="977.4" y1="1046.5" x2="999.1" y2="1035"/>
|
| 95 |
+
<g>
|
| 96 |
+
<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="1016.4717" y1="1038.5374" x2="1063.432" y2="1038.5374">
|
| 97 |
+
<stop offset="0" style="stop-color:#187CCE"/>
|
| 98 |
+
<stop offset="1" style="stop-color:#0DD5FE"/>
|
| 99 |
+
</linearGradient>
|
| 100 |
+
<polygon class="st11" points="1062.2,981.4 1017.7,1004.3 1017.7,1095.7 1062.2,1072.8 "/>
|
| 101 |
+
<linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="1039.6508" y1="1046.2155" x2="1039.6508" y2="996.8698">
|
| 102 |
+
<stop offset="0" style="stop-color:#187CCE"/>
|
| 103 |
+
<stop offset="0" style="stop-color:#187FD0"/>
|
| 104 |
+
<stop offset="1" style="stop-color:#0DD5FE"/>
|
| 105 |
+
</linearGradient>
|
| 106 |
+
<polygon class="st12" points="1023.7,1046.2 1055.6,1029.9 1055.6,996.9 1023.7,1013.2 "/>
|
| 107 |
+
|
| 108 |
+
<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="1023.5676" y1="954.687" x2="1056.0122" y2="954.687" gradientTransform="matrix(1 0 0 -1 0 2002)">
|
| 109 |
+
<stop offset="0" style="stop-color:#1C79C4"/>
|
| 110 |
+
<stop offset="0.51" style="stop-color:#0389FF"/>
|
| 111 |
+
<stop offset="1" style="stop-color:#0DD7FF"/>
|
| 112 |
+
</linearGradient>
|
| 113 |
+
<line class="st13" x1="1024.8" y1="1055.3" x2="1054.8" y2="1039.4"/>
|
| 114 |
+
|
| 115 |
+
<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="1023.5676" y1="945.752" x2="1056.0122" y2="945.752" gradientTransform="matrix(1 0 0 -1 0 2002)">
|
| 116 |
+
<stop offset="0" style="stop-color:#1C79C4"/>
|
| 117 |
+
<stop offset="0.51" style="stop-color:#0389FF"/>
|
| 118 |
+
<stop offset="1" style="stop-color:#0DD7FF"/>
|
| 119 |
+
</linearGradient>
|
| 120 |
+
<line class="st14" x1="1024.8" y1="1064.2" x2="1054.8" y2="1048.3"/>
|
| 121 |
+
<path class="st15" d="M1043.8,1018.9l-5,11.6l-0.9,0.3l0.9-6.7l-2.8,0.9l0,0c-0.2,0.1-0.5-0.1-0.5-0.4c0-0.1,0.1-0.4,0.1-0.4
|
| 122 |
+
l5-11.6l0.9-0.3l-0.9,6.8l2.8-0.9l0,0c0.3-0.1,0.5,0.1,0.5,0.4C1043.8,1018.6,1043.8,1018.8,1043.8,1018.9L1043.8,1018.9z"/>
|
| 123 |
+
</g>
|
| 124 |
+
<polygon class="st16" points="968.6,1083 943.7,1097.1 943.7,1002.4 968.6,989 "/>
|
| 125 |
+
<polygon class="st17" points="1013.1,975.4 1032.9,964.4 1032.9,973.6 1013.6,984.7 "/>
|
| 126 |
+
<polygon class="st17" points="1013.1,988.5 1032.9,977.4 1032.9,982.8 1013.6,993.7 "/>
|
| 127 |
+
<path class="st15" d="M956.2,1000c-4.7,2.2-8.6,8.1-8.6,13.1c0,5,3.9,7.4,8.6,5.2c4.7-2.2,8.6-8.1,8.6-13.1
|
| 128 |
+
C964.8,1000.2,960.9,997.8,956.2,1000z M948.4,1012.7c0-1.2,0.2-2.4,0.7-3.7l3.7,9.1C950.2,1018,948.4,1016,948.4,1012.7z
|
| 129 |
+
M956.2,1017.4c-0.8,0.3-1.5,0.6-2.2,0.7l2.3-8.2l2.4,5.8c0,0,0,0.1,0.1,0.1C958,1016.4,957.1,1017,956.2,1017.4z M957.2,1004.8
|
| 130 |
+
c0.5-0.2,0.9-0.5,0.9-0.5c0.4-0.2,0.4-0.9-0.1-0.7c0,0-1.3,0.7-2.1,1.1c-0.8,0.3-2,0.8-2,0.8c-0.4,0.2-0.5,0.9,0,0.7
|
| 131 |
+
c0,0,0.4-0.1,0.8-0.3l1.2,3l-1.7,6.2l-2.8-7.6c0.5-0.2,0.9-0.5,0.9-0.5c0.4-0.2,0.4-0.9-0.1-0.7c0,0-1.3,0.7-2.1,1.1
|
| 132 |
+
c-0.1,0.1-0.3,0.1-0.5,0.2c1.4-2.9,3.8-5.4,6.5-6.7c2-0.9,3.9-1,5.2-0.2c0,0-0.1,0-0.1,0c-0.8,0.3-1.3,1.3-1.3,2.1
|
| 133 |
+
c0,0.7,0.4,1.1,0.8,1.6c0.3,0.4,0.6,1,0.6,2c0,0.7-0.3,1.6-0.6,2.9l-0.8,3.1L957.2,1004.8z M963,1002.1c0.6,0.9,1,2.1,1,3.5
|
| 134 |
+
c0,3-1.5,6.4-3.8,8.9l2.3-8.4c0.4-1.4,0.6-2.4,0.6-3.2C963,1002.6,963,1002.3,963,1002.1z"/>
|
| 135 |
+
<path class="st18" d="M970.6,1021.2"/>
|
| 136 |
+
<line class="st18" x1="948.6" y1="1028.4" x2="963.6" y2="1020.5"/>
|
| 137 |
+
<line class="st18" x1="948.6" y1="1036.3" x2="963.6" y2="1028.4"/>
|
| 138 |
+
<line class="st18" x1="948.6" y1="1044.3" x2="963.6" y2="1036.3"/>
|
| 139 |
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
| 2 |
+
<path d="M0 0h24v24H0z" fill="none"/>
|
| 3 |
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill="#85b649" />
|
| 4 |
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
| 3 |
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
| 4 |
+
viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
|
| 5 |
+
<style type="text/css">
|
| 6 |
+
.st0{fill:none;}
|
| 7 |
+
</style>
|
| 8 |
+
<path class="st0" d="M0,0h20v20H0V0z"/>
|
| 9 |
+
<g id="AMP-Warning" fill="#84b741">
|
| 10 |
+
<path d="M10,1c-5,0-9,4.1-9,9s4.1,9,9,9s9-4.1,9-9S15,1,10,1z M10.9,14.6H9.1v-1.8H11v1.8H10.9z M10.9,10.9H9.1V5.4H11v5.4H10.9z"/>
|
| 11 |
+
</g>
|
| 12 |
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
| 3 |
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
| 4 |
+
viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
|
| 5 |
+
<style type="text/css">
|
| 6 |
+
.st0{fill:none;}
|
| 7 |
+
</style>
|
| 8 |
+
<path class="st0" d="M0,0h20v20H0V0z"/>
|
| 9 |
+
<g id="AMP-Warning" fill="#FF0000">
|
| 10 |
+
<path d="M10,1c-5,0-9,4.1-9,9s4.1,9,9,9s9-4.1,9-9S15,1,10,1z M10.9,14.6H9.1v-1.8H11v1.8H10.9z M10.9,10.9H9.1V5.4H11v5.4H10.9z"/>
|
| 11 |
+
</g>
|
| 12 |
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
| 2 |
+
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
| 3 |
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
| 4 |
+
viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
|
| 5 |
+
<style type="text/css">
|
| 6 |
+
.st0{fill:none;}
|
| 7 |
+
</style>
|
| 8 |
+
<path class="st0" d="M0,0h20v20H0V0z"/>
|
| 9 |
+
<g id="AMP-Warning" fill="#E38000">
|
| 10 |
+
<path d="M10,1c-5,0-9,4.1-9,9s4.1,9,9,9s9-4.1,9-9S15,1,10,1z M10.9,14.6H9.1v-1.8H11v1.8H10.9z M10.9,10.9H9.1V5.4H11v5.4H10.9z"/>
|
| 11 |
+
</g>
|
| 12 |
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<svg height="1024" width="767.5" xmlns="http://www.w3.org/2000/svg">
|
| 2 |
+
<path d="M0 384l383.75 383.75L767.5 384H0z" fill="#0073aa" />
|
| 3 |
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g fill="#FF0E57"><path d="M17 10c0-3.87-3.14-7-7-7-3.87 0-7 3.13-7 7s3.13 7 7 7c3.86 0 7-3.13 7-7zm-6.3 1.48H9.14v-.43c0-.38.08-.7.24-.98s.46-.57.88-.89c.41-.29.68-.53.81-.71.14-.18.2-.39.2-.62 0-.25-.09-.44-.28-.58-.19-.13-.45-.19-.79-.19-.58 0-1.25.19-2 .57l-.64-1.28c.87-.49 1.8-.74 2.77-.74.81 0 1.45.2 1.92.58.48.39.71.91.71 1.55 0 .43-.09.8-.29 1.11-.19.32-.57.67-1.11 1.06-.38.28-.61.49-.71.63-.1.15-.15.34-.15.57v.35zm-1.47 2.74c-.18-.17-.27-.42-.27-.73 0-.33.08-.58.26-.75s.43-.25.77-.25c.32 0 .57.09.75.26s.27.42.27.74c0 .3-.09.55-.27.72-.18.18-.43.27-.75.27-.33 0-.58-.09-.76-.26z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
|
| 1 |
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g fill="#FF0000"><path d="M12.12 10l3.53 3.53-2.12 2.12L10 12.12l-3.54 3.54-2.12-2.12L7.88 10 4.34 6.46l2.12-2.12L10 7.88l3.54-3.53 2.12 2.12z"/></g></svg>
|
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Adds an admin pointer that describes new features in 1.0.
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
/* exported ampAdminPointer */
|
| 6 |
+
/* global ajaxurl, jQuery */
|
| 7 |
+
var ampAdminPointer = ( function( $ ) { // eslint-disable-line no-unused-vars
|
| 8 |
+
'use strict';
|
| 9 |
+
|
| 10 |
+
return {
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* Loads the pointer.
|
| 14 |
+
*
|
| 15 |
+
* @param {Object} data - Module data.
|
| 16 |
+
* @return {void}
|
| 17 |
+
*/
|
| 18 |
+
load: function load( data ) {
|
| 19 |
+
var options = $.extend(
|
| 20 |
+
data.pointer.options,
|
| 21 |
+
{
|
| 22 |
+
/**
|
| 23 |
+
* Makes a POST request to store the pointer ID as dismissed for this user.
|
| 24 |
+
*/
|
| 25 |
+
close: function() {
|
| 26 |
+
$.post( ajaxurl, {
|
| 27 |
+
pointer: data.pointer.pointer_id,
|
| 28 |
+
action: 'dismiss-wp-pointer'
|
| 29 |
+
} );
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
);
|
| 33 |
+
|
| 34 |
+
$( data.pointer.target ).pointer( options ).pointer( 'open' );
|
| 35 |
+
}
|
| 36 |
+
};
|
| 37 |
+
}( jQuery ) );
|
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/******/ (function(modules) { // webpackBootstrap
|
| 2 |
+
/******/ // The module cache
|
| 3 |
+
/******/ var installedModules = {};
|
| 4 |
+
/******/
|
| 5 |
+
/******/ // The require function
|
| 6 |
+
/******/ function __webpack_require__(moduleId) {
|
| 7 |
+
/******/
|
| 8 |
+
/******/ // Check if module is in cache
|
| 9 |
+
/******/ if(installedModules[moduleId]) {
|
| 10 |
+
/******/ return installedModules[moduleId].exports;
|
| 11 |
+
/******/ }
|
| 12 |
+
/******/ // Create a new module (and put it into the cache)
|
| 13 |
+
/******/ var module = installedModules[moduleId] = {
|
| 14 |
+
/******/ i: moduleId,
|
| 15 |
+
/******/ l: false,
|
| 16 |
+
/******/ exports: {}
|
| 17 |
+
/******/ };
|
| 18 |
+
/******/
|
| 19 |
+
/******/ // Execute the module function
|
| 20 |
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
| 21 |
+
/******/
|
| 22 |
+
/******/ // Flag the module as loaded
|
| 23 |
+
/******/ module.l = true;
|
| 24 |
+
/******/
|
| 25 |
+
/******/ // Return the exports of the module
|
| 26 |
+
/******/ return module.exports;
|
| 27 |
+
/******/ }
|
| 28 |
+
/******/
|
| 29 |
+
/******/
|
| 30 |
+
/******/ // expose the modules object (__webpack_modules__)
|
| 31 |
+
/******/ __webpack_require__.m = modules;
|
| 32 |
+
/******/
|
| 33 |
+
/******/ // expose the module cache
|
| 34 |
+
/******/ __webpack_require__.c = installedModules;
|
| 35 |
+
/******/
|
| 36 |
+
/******/ // define getter function for harmony exports
|
| 37 |
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
| 38 |
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
| 39 |
+
/******/ Object.defineProperty(exports, name, {
|
| 40 |
+
/******/ configurable: false,
|
| 41 |
+
/******/ enumerable: true,
|
| 42 |
+
/******/ get: getter
|
| 43 |
+
/******/ });
|
| 44 |
+
/******/ }
|
| 45 |
+
/******/ };
|
| 46 |
+
/******/
|
| 47 |
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
| 48 |
+
/******/ __webpack_require__.n = function(module) {
|
| 49 |
+
/******/ var getter = module && module.__esModule ?
|
| 50 |
+
/******/ function getDefault() { return module['default']; } :
|
| 51 |
+
/******/ function getModuleExports() { return module; };
|
| 52 |
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
| 53 |
+
/******/ return getter;
|
| 54 |
+
/******/ };
|
| 55 |
+
/******/
|
| 56 |
+
/******/ // Object.prototype.hasOwnProperty.call
|
| 57 |
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
| 58 |
+
/******/
|
| 59 |
+
/******/ // __webpack_public_path__
|
| 60 |
+
/******/ __webpack_require__.p = "";
|
| 61 |
+
/******/
|
| 62 |
+
/******/ // Load entry module and return exports
|
| 63 |
+
/******/ return __webpack_require__(__webpack_require__.s = 13);
|
| 64 |
+
/******/ })
|
| 65 |
+
/************************************************************************/
|
| 66 |
+
/******/ ({
|
| 67 |
+
|
| 68 |
+
/***/ 13:
|
| 69 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 70 |
+
|
| 71 |
+
"use strict";
|
| 72 |
+
eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/**\n * WordPress dependencies\n */\nvar __ = wp.i18n.__;\nvar _wp$components = wp.components,\n FormToggle = _wp$components.FormToggle,\n Notice = _wp$components.Notice;\nvar _wp$element = wp.element,\n Fragment = _wp$element.Fragment,\n RawHTML = _wp$element.RawHTML;\nvar _wp$data = wp.data,\n withSelect = _wp$data.withSelect,\n withDispatch = _wp$data.withDispatch;\nvar PluginPostStatusInfo = wp.editPost.PluginPostStatusInfo;\nvar _wp$compose = wp.compose,\n compose = _wp$compose.compose,\n withInstanceId = _wp$compose.withInstanceId;\n\n/**\n * Exported via wp_localize_script().\n */\n\nvar _window$wpAmpEditor = window.wpAmpEditor,\n possibleStati = _window$wpAmpEditor.possibleStati,\n defaultStatus = _window$wpAmpEditor.defaultStatus,\n errorMessages = _window$wpAmpEditor.errorMessages;\n\n/**\n * Adds an 'Enable AMP' toggle to the block editor 'Status & Visibility' section.\n *\n * If there are error(s) that block AMP from being enabled or disabled,\n * this only displays a Notice with the error(s), not a toggle.\n * Error(s) are imported as errorMessages via wp_localize_script().\n *\n * @return {Object} AMPToggle component.\n */\n\nfunction AMPToggle(_ref) {\n\tvar enabledStatus = _ref.enabledStatus,\n\t onAmpChange = _ref.onAmpChange;\n\n\treturn wp.element.createElement(\n\t\tFragment,\n\t\tnull,\n\t\twp.element.createElement(\n\t\t\tPluginPostStatusInfo,\n\t\t\tnull,\n\t\t\t!errorMessages.length && wp.element.createElement(\n\t\t\t\t'label',\n\t\t\t\t{ htmlFor: 'amp-enabled' },\n\t\t\t\t__('Enable AMP', 'amp')\n\t\t\t),\n\t\t\t!errorMessages.length && wp.element.createElement(FormToggle, {\n\t\t\t\tchecked: 'enabled' === enabledStatus,\n\t\t\t\tonChange: function onChange() {\n\t\t\t\t\treturn onAmpChange(enabledStatus);\n\t\t\t\t},\n\t\t\t\tid: 'amp-enabled'\n\t\t\t}),\n\t\t\t!!errorMessages.length && wp.element.createElement(\n\t\t\t\tNotice,\n\t\t\t\t{\n\t\t\t\t\tstatus: 'warning',\n\t\t\t\t\tisDismissible: false\n\t\t\t\t},\n\t\t\t\terrorMessages.map(function (message, index) {\n\t\t\t\t\treturn wp.element.createElement(\n\t\t\t\t\t\tRawHTML,\n\t\t\t\t\t\t{ key: index },\n\t\t\t\t\t\tmessage\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t)\n\t\t)\n\t);\n}\n\n/**\n * The AMP Toggle component, composed with the enabledStatus and a callback for when it's changed.\n *\n * @return {Object} The composed AMP toggle.\n */\nfunction ComposedAMPToggle() {\n\treturn compose([withSelect(function (select) {\n\t\t/**\n * Gets the AMP enabled status.\n *\n * Uses select from the enclosing function to get the meta value.\n * If it doesn't exist, it uses the default value.\n * This applies especially for a new post, where there probably won't be a meta value yet.\n *\n * @return {string} Enabled status, either 'enabled' or 'disabled'.\n */\n\t\tvar getEnabledStatus = function getEnabledStatus() {\n\t\t\tvar meta = select('core/editor').getEditedPostAttribute('meta');\n\t\t\tif (meta && meta.amp_status && possibleStati.includes(meta.amp_status)) {\n\t\t\t\treturn meta.amp_status;\n\t\t\t}\n\t\t\treturn defaultStatus;\n\t\t};\n\n\t\treturn { enabledStatus: getEnabledStatus() };\n\t}), withDispatch(function (dispatch) {\n\t\treturn {\n\t\t\tonAmpChange: function onAmpChange(enabledStatus) {\n\t\t\t\tvar newStatus = 'enabled' === enabledStatus ? 'disabled' : 'enabled';\n\t\t\t\tdispatch('core/editor').editPost({ meta: { amp_status: newStatus } });\n\t\t\t}\n\t\t};\n\t}), withInstanceId])(AMPToggle);\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (wp.plugins.registerPlugin('amp', {\n\ticon: 'hidden',\n\trender: ComposedAMPToggle()\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hc3NldHMvc3JjL2FtcC1ibG9jay1lZGl0b3ItdG9nZ2xlLmpzPzVkMDkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBXb3JkUHJlc3MgZGVwZW5kZW5jaWVzXG4gKi9cbnZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgX3dwJGNvbXBvbmVudHMgPSB3cC5jb21wb25lbnRzLFxuICAgIEZvcm1Ub2dnbGUgPSBfd3AkY29tcG9uZW50cy5Gb3JtVG9nZ2xlLFxuICAgIE5vdGljZSA9IF93cCRjb21wb25lbnRzLk5vdGljZTtcbnZhciBfd3AkZWxlbWVudCA9IHdwLmVsZW1lbnQsXG4gICAgRnJhZ21lbnQgPSBfd3AkZWxlbWVudC5GcmFnbWVudCxcbiAgICBSYXdIVE1MID0gX3dwJGVsZW1lbnQuUmF3SFRNTDtcbnZhciBfd3AkZGF0YSA9IHdwLmRhdGEsXG4gICAgd2l0aFNlbGVjdCA9IF93cCRkYXRhLndpdGhTZWxlY3QsXG4gICAgd2l0aERpc3BhdGNoID0gX3dwJGRhdGEud2l0aERpc3BhdGNoO1xudmFyIFBsdWdpblBvc3RTdGF0dXNJbmZvID0gd3AuZWRpdFBvc3QuUGx1Z2luUG9zdFN0YXR1c0luZm87XG52YXIgX3dwJGNvbXBvc2UgPSB3cC5jb21wb3NlLFxuICAgIGNvbXBvc2UgPSBfd3AkY29tcG9zZS5jb21wb3NlLFxuICAgIHdpdGhJbnN0YW5jZUlkID0gX3dwJGNvbXBvc2Uud2l0aEluc3RhbmNlSWQ7XG5cbi8qKlxuICogRXhwb3J0ZWQgdmlhIHdwX2xvY2FsaXplX3NjcmlwdCgpLlxuICovXG5cbnZhciBfd2luZG93JHdwQW1wRWRpdG9yID0gd2luZG93LndwQW1wRWRpdG9yLFxuICAgIHBvc3NpYmxlU3RhdGkgPSBfd2luZG93JHdwQW1wRWRpdG9yLnBvc3NpYmxlU3RhdGksXG4gICAgZGVmYXVsdFN0YXR1cyA9IF93aW5kb3ckd3BBbXBFZGl0b3IuZGVmYXVsdFN0YXR1cyxcbiAgICBlcnJvck1lc3NhZ2VzID0gX3dpbmRvdyR3cEFtcEVkaXRvci5lcnJvck1lc3NhZ2VzO1xuXG4vKipcbiAqIEFkZHMgYW4gJ0VuYWJsZSBBTVAnIHRvZ2dsZSB0byB0aGUgYmxvY2sgZWRpdG9yICdTdGF0dXMgJiBWaXNpYmlsaXR5JyBzZWN0aW9uLlxuICpcbiAqIElmIHRoZXJlIGFyZSBlcnJvcihzKSB0aGF0IGJsb2NrIEFNUCBmcm9tIGJlaW5nIGVuYWJsZWQgb3IgZGlzYWJsZWQsXG4gKiB0aGlzIG9ubHkgZGlzcGxheXMgYSBOb3RpY2Ugd2l0aCB0aGUgZXJyb3IocyksIG5vdCBhIHRvZ2dsZS5cbiAqIEVycm9yKHMpIGFyZSBpbXBvcnRlZCBhcyBlcnJvck1lc3NhZ2VzIHZpYSB3cF9sb2NhbGl6ZV9zY3JpcHQoKS5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IEFNUFRvZ2dsZSBjb21wb25lbnQuXG4gKi9cblxuZnVuY3Rpb24gQU1QVG9nZ2xlKF9yZWYpIHtcblx0dmFyIGVuYWJsZWRTdGF0dXMgPSBfcmVmLmVuYWJsZWRTdGF0dXMsXG5cdCAgICBvbkFtcENoYW5nZSA9IF9yZWYub25BbXBDaGFuZ2U7XG5cblx0cmV0dXJuIHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRGcmFnbWVudCxcblx0XHRudWxsLFxuXHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFBsdWdpblBvc3RTdGF0dXNJbmZvLFxuXHRcdFx0bnVsbCxcblx0XHRcdCFlcnJvck1lc3NhZ2VzLmxlbmd0aCAmJiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdCdsYWJlbCcsXG5cdFx0XHRcdHsgaHRtbEZvcjogJ2FtcC1lbmFibGVkJyB9LFxuXHRcdFx0XHRfXygnRW5hYmxlIEFNUCcsICdhbXAnKVxuXHRcdFx0KSxcblx0XHRcdCFlcnJvck1lc3NhZ2VzLmxlbmd0aCAmJiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoRm9ybVRvZ2dsZSwge1xuXHRcdFx0XHRjaGVja2VkOiAnZW5hYmxlZCcgPT09IGVuYWJsZWRTdGF0dXMsXG5cdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSgpIHtcblx0XHRcdFx0XHRyZXR1cm4gb25BbXBDaGFuZ2UoZW5hYmxlZFN0YXR1cyk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdGlkOiAnYW1wLWVuYWJsZWQnXG5cdFx0XHR9KSxcblx0XHRcdCEhZXJyb3JNZXNzYWdlcy5sZW5ndGggJiYgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHROb3RpY2UsXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRzdGF0dXM6ICd3YXJuaW5nJyxcblx0XHRcdFx0XHRpc0Rpc21pc3NpYmxlOiBmYWxzZVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRlcnJvck1lc3NhZ2VzLm1hcChmdW5jdGlvbiAobWVzc2FnZSwgaW5kZXgpIHtcblx0XHRcdFx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRcdFx0UmF3SFRNTCxcblx0XHRcdFx0XHRcdHsga2V5OiBpbmRleCB9LFxuXHRcdFx0XHRcdFx0bWVzc2FnZVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0KVxuXHQpO1xufVxuXG4vKipcbiAqIFRoZSBBTVAgVG9nZ2xlIGNvbXBvbmVudCwgY29tcG9zZWQgd2l0aCB0aGUgZW5hYmxlZFN0YXR1cyBhbmQgYSBjYWxsYmFjayBmb3Igd2hlbiBpdCdzIGNoYW5nZWQuXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBUaGUgY29tcG9zZWQgQU1QIHRvZ2dsZS5cbiAqL1xuZnVuY3Rpb24gQ29tcG9zZWRBTVBUb2dnbGUoKSB7XG5cdHJldHVybiBjb21wb3NlKFt3aXRoU2VsZWN0KGZ1bmN0aW9uIChzZWxlY3QpIHtcblx0XHQvKipcbiAgICogR2V0cyB0aGUgQU1QIGVuYWJsZWQgc3RhdHVzLlxuICAgKlxuICAgKiBVc2VzIHNlbGVjdCBmcm9tIHRoZSBlbmNsb3NpbmcgZnVuY3Rpb24gdG8gZ2V0IHRoZSBtZXRhIHZhbHVlLlxuICAgKiBJZiBpdCBkb2Vzbid0IGV4aXN0LCBpdCB1c2VzIHRoZSBkZWZhdWx0IHZhbHVlLlxuICAgKiBUaGlzIGFwcGxpZXMgZXNwZWNpYWxseSBmb3IgYSBuZXcgcG9zdCwgd2hlcmUgdGhlcmUgcHJvYmFibHkgd29uJ3QgYmUgYSBtZXRhIHZhbHVlIHlldC5cbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nfSBFbmFibGVkIHN0YXR1cywgZWl0aGVyICdlbmFibGVkJyBvciAnZGlzYWJsZWQnLlxuICAgKi9cblx0XHR2YXIgZ2V0RW5hYmxlZFN0YXR1cyA9IGZ1bmN0aW9uIGdldEVuYWJsZWRTdGF0dXMoKSB7XG5cdFx0XHR2YXIgbWV0YSA9IHNlbGVjdCgnY29yZS9lZGl0b3InKS5nZXRFZGl0ZWRQb3N0QXR0cmlidXRlKCdtZXRhJyk7XG5cdFx0XHRpZiAobWV0YSAmJiBtZXRhLmFtcF9zdGF0dXMgJiYgcG9zc2libGVTdGF0aS5pbmNsdWRlcyhtZXRhLmFtcF9zdGF0dXMpKSB7XG5cdFx0XHRcdHJldHVybiBtZXRhLmFtcF9zdGF0dXM7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZGVmYXVsdFN0YXR1cztcblx0XHR9O1xuXG5cdFx0cmV0dXJuIHsgZW5hYmxlZFN0YXR1czogZ2V0RW5hYmxlZFN0YXR1cygpIH07XG5cdH0pLCB3aXRoRGlzcGF0Y2goZnVuY3Rpb24gKGRpc3BhdGNoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdG9uQW1wQ2hhbmdlOiBmdW5jdGlvbiBvbkFtcENoYW5nZShlbmFibGVkU3RhdHVzKSB7XG5cdFx0XHRcdHZhciBuZXdTdGF0dXMgPSAnZW5hYmxlZCcgPT09IGVuYWJsZWRTdGF0dXMgPyAnZGlzYWJsZWQnIDogJ2VuYWJsZWQnO1xuXHRcdFx0XHRkaXNwYXRjaCgnY29yZS9lZGl0b3InKS5lZGl0UG9zdCh7IG1ldGE6IHsgYW1wX3N0YXR1czogbmV3U3RhdHVzIH0gfSk7XG5cdFx0XHR9XG5cdFx0fTtcblx0fSksIHdpdGhJbnN0YW5jZUlkXSkoQU1QVG9nZ2xlKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgd3AucGx1Z2lucy5yZWdpc3RlclBsdWdpbignYW1wJywge1xuXHRpY29uOiAnaGlkZGVuJyxcblx0cmVuZGVyOiBDb21wb3NlZEFNUFRvZ2dsZSgpXG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2Fzc2V0cy9zcmMvYW1wLWJsb2NrLWVkaXRvci10b2dnbGUuanNcbi8vIG1vZHVsZSBpZCA9IDEzXG4vLyBtb2R1bGUgY2h1bmtzID0gNCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///13\n");
|
| 73 |
+
|
| 74 |
+
/***/ })
|
| 75 |
+
|
| 76 |
+
/******/ });
|
|
@@ -0,0 +1,540 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Validates blocks for AMP compatibility.
|
| 3 |
+
*
|
| 4 |
+
* This uses the REST API response from saving a page to find validation errors.
|
| 5 |
+
* If one exists for a block, it display it inline with a Notice component.
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/* exported ampBlockValidation */
|
| 9 |
+
/* global wp, _ */
|
| 10 |
+
var ampBlockValidation = ( function() { // eslint-disable-line no-unused-vars
|
| 11 |
+
'use strict';
|
| 12 |
+
|
| 13 |
+
var module = {
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* Data exported from server.
|
| 17 |
+
*
|
| 18 |
+
* @param {Object}
|
| 19 |
+
*/
|
| 20 |
+
data: {
|
| 21 |
+
i18n: {},
|
| 22 |
+
ampValidityRestField: '',
|
| 23 |
+
isSanitizationAutoAccepted: false
|
| 24 |
+
},
|
| 25 |
+
|
| 26 |
+
/**
|
| 27 |
+
* Name of the store.
|
| 28 |
+
*
|
| 29 |
+
* @param {string}
|
| 30 |
+
*/
|
| 31 |
+
storeName: 'amp/blockValidation',
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* Holds the last states which are used for comparisons.
|
| 35 |
+
*
|
| 36 |
+
* @param {Object}
|
| 37 |
+
*/
|
| 38 |
+
lastStates: {
|
| 39 |
+
noticesAreReset: false,
|
| 40 |
+
validationErrors: [],
|
| 41 |
+
blockOrder: [],
|
| 42 |
+
blockValidationErrors: {}
|
| 43 |
+
},
|
| 44 |
+
|
| 45 |
+
/**
|
| 46 |
+
* Boot module.
|
| 47 |
+
*
|
| 48 |
+
* @param {Object} data - Module data.
|
| 49 |
+
* @return {void}
|
| 50 |
+
*/
|
| 51 |
+
boot: function boot( data ) {
|
| 52 |
+
module.data = data;
|
| 53 |
+
|
| 54 |
+
wp.i18n.setLocaleData( module.data.i18n, 'amp' );
|
| 55 |
+
|
| 56 |
+
wp.hooks.addFilter(
|
| 57 |
+
'editor.BlockEdit',
|
| 58 |
+
'amp/add-notice',
|
| 59 |
+
module.conditionallyAddNotice,
|
| 60 |
+
99 // eslint-disable-line
|
| 61 |
+
);
|
| 62 |
+
|
| 63 |
+
module.store = module.registerStore();
|
| 64 |
+
|
| 65 |
+
wp.data.subscribe( module.handleValidationErrorsStateChange );
|
| 66 |
+
},
|
| 67 |
+
|
| 68 |
+
/**
|
| 69 |
+
* Register store.
|
| 70 |
+
*
|
| 71 |
+
* @return {Object} Store.
|
| 72 |
+
*/
|
| 73 |
+
registerStore: function registerStore() {
|
| 74 |
+
return wp.data.registerStore( module.storeName, {
|
| 75 |
+
reducer: function( _state, action ) {
|
| 76 |
+
var state = _state || {
|
| 77 |
+
blockValidationErrorsByClientId: {}
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
switch ( action.type ) {
|
| 81 |
+
case 'UPDATE_BLOCKS_VALIDATION_ERRORS':
|
| 82 |
+
return _.extend( {}, state, {
|
| 83 |
+
blockValidationErrorsByClientId: action.blockValidationErrorsByClientId
|
| 84 |
+
} );
|
| 85 |
+
default:
|
| 86 |
+
return state;
|
| 87 |
+
}
|
| 88 |
+
},
|
| 89 |
+
actions: {
|
| 90 |
+
updateBlocksValidationErrors: function( blockValidationErrorsByClientId ) {
|
| 91 |
+
return {
|
| 92 |
+
type: 'UPDATE_BLOCKS_VALIDATION_ERRORS',
|
| 93 |
+
blockValidationErrorsByClientId: blockValidationErrorsByClientId
|
| 94 |
+
};
|
| 95 |
+
}
|
| 96 |
+
},
|
| 97 |
+
selectors: {
|
| 98 |
+
getBlockValidationErrors: function( state, clientId ) {
|
| 99 |
+
return state.blockValidationErrorsByClientId[ clientId ] || [];
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
} );
|
| 103 |
+
},
|
| 104 |
+
|
| 105 |
+
/**
|
| 106 |
+
* Checks if AMP is enabled for this post.
|
| 107 |
+
*
|
| 108 |
+
* @return {boolean} Returns true when the AMP toggle is on; else, false is returned.
|
| 109 |
+
*/
|
| 110 |
+
isAMPEnabled: function isAMPEnabled() {
|
| 111 |
+
var meta = wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' );
|
| 112 |
+
if ( meta && meta.amp_status && window.wpAmpEditor.possibleStati.includes( meta.amp_status ) ) {
|
| 113 |
+
return 'enabled' === meta.amp_status;
|
| 114 |
+
}
|
| 115 |
+
return window.wpAmpEditor.defaultStatus;
|
| 116 |
+
},
|
| 117 |
+
|
| 118 |
+
/**
|
| 119 |
+
* Checks if the validate errors state change handler should wait before processing.
|
| 120 |
+
*
|
| 121 |
+
* @return {boolean} Whether should wait.
|
| 122 |
+
*/
|
| 123 |
+
waitToHandleStateChange: function waitToHandleStateChange() {
|
| 124 |
+
var currentPost;
|
| 125 |
+
|
| 126 |
+
// @todo Gutenberg currently is not persisting isDirty state if changes are made during save request. Block order mismatch.
|
| 127 |
+
// We can only align block validation errors with blocks in editor when in saved state, since only here will the blocks be aligned with the validation errors.
|
| 128 |
+
if ( wp.data.select( 'core/editor' ).isEditedPostDirty() || ( ! wp.data.select( 'core/editor' ).isEditedPostDirty() && wp.data.select( 'core/editor' ).isEditedPostNew() ) ) {
|
| 129 |
+
return true;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
// Wait for the current post to be set up.
|
| 133 |
+
currentPost = wp.data.select( 'core/editor' ).getCurrentPost();
|
| 134 |
+
if ( ! currentPost.hasOwnProperty( 'id' ) ) {
|
| 135 |
+
return true;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
return false;
|
| 139 |
+
},
|
| 140 |
+
|
| 141 |
+
/**
|
| 142 |
+
* Handle state change regarding validation errors.
|
| 143 |
+
*
|
| 144 |
+
* This is essentially a JS implementation of \AMP_Validation_Manager::print_edit_form_validation_status() in PHP.
|
| 145 |
+
*
|
| 146 |
+
* @return {void}
|
| 147 |
+
*/
|
| 148 |
+
handleValidationErrorsStateChange: function handleValidationErrorsStateChange() {
|
| 149 |
+
var currentPost, validationErrors, blockValidationErrors, noticeOptions, noticeMessage, blockErrorCount, ampValidity, rejectedErrors;
|
| 150 |
+
|
| 151 |
+
if ( ! module.isAMPEnabled() ) {
|
| 152 |
+
if ( ! module.lastStates.noticesAreReset ) {
|
| 153 |
+
module.lastStates.validationErrors = [];
|
| 154 |
+
module.lastStates.noticesAreReset = true;
|
| 155 |
+
module.resetWarningNotice();
|
| 156 |
+
module.resetBlockNotices();
|
| 157 |
+
}
|
| 158 |
+
return;
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
if ( module.waitToHandleStateChange() ) {
|
| 162 |
+
return;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
currentPost = wp.data.select( 'core/editor' ).getCurrentPost();
|
| 166 |
+
ampValidity = currentPost[ module.data.ampValidityRestField ] || {};
|
| 167 |
+
|
| 168 |
+
// Show all validation errors which have not been explicitly acknowledged as accepted.
|
| 169 |
+
validationErrors = _.map(
|
| 170 |
+
_.filter( ampValidity.results, function( result ) {
|
| 171 |
+
// @todo Show VALIDATION_ERROR_ACK_REJECTED_STATUS differently since moderated?
|
| 172 |
+
return (
|
| 173 |
+
0 /* \AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_REJECTED_STATUS */ === result.status ||
|
| 174 |
+
1 /* \AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_ACCEPTED_STATUS */ === result.status ||
|
| 175 |
+
2 /* \AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACK_REJECTED_STATUS */ === result.status // eslint-disable-line no-magic-numbers
|
| 176 |
+
);
|
| 177 |
+
} ),
|
| 178 |
+
function( result ) {
|
| 179 |
+
return result.error;
|
| 180 |
+
}
|
| 181 |
+
);
|
| 182 |
+
|
| 183 |
+
// Short-circuit if there was no change to the validation errors.
|
| 184 |
+
if ( ! module.didValidationErrorsChange( validationErrors ) ) {
|
| 185 |
+
if ( ! validationErrors.length && ! module.lastStates.noticesAreReset ) {
|
| 186 |
+
module.lastStates.noticesAreReset = true;
|
| 187 |
+
module.resetWarningNotice();
|
| 188 |
+
}
|
| 189 |
+
return;
|
| 190 |
+
}
|
| 191 |
+
module.lastStates.validationErrors = validationErrors;
|
| 192 |
+
module.lastStates.noticesAreReset = false;
|
| 193 |
+
|
| 194 |
+
// Remove any existing notice.
|
| 195 |
+
module.resetWarningNotice();
|
| 196 |
+
|
| 197 |
+
noticeMessage = wp.i18n.sprintf(
|
| 198 |
+
wp.i18n._n(
|
| 199 |
+
'There is %s issue from AMP validation which needs review.',
|
| 200 |
+
'There are %s issues from AMP validation which need review.',
|
| 201 |
+
validationErrors.length,
|
| 202 |
+
'amp'
|
| 203 |
+
),
|
| 204 |
+
validationErrors.length
|
| 205 |
+
);
|
| 206 |
+
|
| 207 |
+
try {
|
| 208 |
+
blockValidationErrors = module.getBlocksValidationErrors();
|
| 209 |
+
module.lastStates.blockValidationErrors = blockValidationErrors.byClientId;
|
| 210 |
+
wp.data.dispatch( module.storeName ).updateBlocksValidationErrors( blockValidationErrors.byClientId );
|
| 211 |
+
|
| 212 |
+
blockErrorCount = validationErrors.length - blockValidationErrors.other.length;
|
| 213 |
+
if ( blockErrorCount > 0 ) {
|
| 214 |
+
noticeMessage += ' ' + wp.i18n.sprintf(
|
| 215 |
+
wp.i18n._n(
|
| 216 |
+
'And %s is directly due to content here.',
|
| 217 |
+
'And %s are directly due to content here.',
|
| 218 |
+
blockErrorCount,
|
| 219 |
+
'amp'
|
| 220 |
+
),
|
| 221 |
+
blockErrorCount
|
| 222 |
+
);
|
| 223 |
+
} else {
|
| 224 |
+
noticeMessage += ' ' + wp.i18n.sprintf(
|
| 225 |
+
wp.i18n._n(
|
| 226 |
+
'But it is not directly due to content here.',
|
| 227 |
+
'But none are directly due to content here.',
|
| 228 |
+
validationErrors.length,
|
| 229 |
+
'amp'
|
| 230 |
+
),
|
| 231 |
+
validationErrors.length
|
| 232 |
+
);
|
| 233 |
+
}
|
| 234 |
+
} catch ( e ) {
|
| 235 |
+
// Clear out block validation errors in case the block sand errors cannot be aligned.
|
| 236 |
+
module.resetBlockNotices();
|
| 237 |
+
|
| 238 |
+
noticeMessage += ' ' + wp.i18n._n(
|
| 239 |
+
'It may not be due to content here.',
|
| 240 |
+
'Some may be due to content here.',
|
| 241 |
+
validationErrors.length,
|
| 242 |
+
'amp'
|
| 243 |
+
);
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
rejectedErrors = _.filter( ampValidity.results, function( result ) {
|
| 247 |
+
return (
|
| 248 |
+
0 /* \AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_REJECTED_STATUS */ === result.status ||
|
| 249 |
+
2 /* \AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACK_REJECTED_STATUS */ === result.status // eslint-disable-line no-magic-numbers
|
| 250 |
+
);
|
| 251 |
+
} );
|
| 252 |
+
|
| 253 |
+
noticeMessage += ' ';
|
| 254 |
+
// Auto-acceptance is from either checking 'Automatically accept sanitization...' or from being in Native mode.
|
| 255 |
+
if ( module.data.isSanitizationAutoAccepted ) {
|
| 256 |
+
if ( 0 === rejectedErrors.length ) {
|
| 257 |
+
noticeMessage += wp.i18n.__( 'However, your site is configured to automatically accept sanitization of the offending markup.', 'amp' );
|
| 258 |
+
} else {
|
| 259 |
+
noticeMessage += wp.i18n._n(
|
| 260 |
+
'Your site is configured to automatically accept sanitization errors, but this error could be from when auto-acceptance was not selected, or from manually rejecting an error.',
|
| 261 |
+
'Your site is configured to automatically accept sanitization errors, but these errors could be from when auto-acceptance was not selected, or from manually rejecting an error.',
|
| 262 |
+
validationErrors.length,
|
| 263 |
+
'amp'
|
| 264 |
+
);
|
| 265 |
+
}
|
| 266 |
+
} else {
|
| 267 |
+
noticeMessage += wp.i18n.__( 'Non-accepted validation errors prevent AMP from being served, and the user will be redirected to the non-AMP version.', 'amp' );
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
noticeOptions = {
|
| 271 |
+
id: 'amp-errors-notice'
|
| 272 |
+
};
|
| 273 |
+
if ( ampValidity.review_link ) {
|
| 274 |
+
noticeOptions.actions = [
|
| 275 |
+
{
|
| 276 |
+
label: wp.i18n.__( 'Review issues', 'amp' ),
|
| 277 |
+
url: ampValidity.review_link
|
| 278 |
+
}
|
| 279 |
+
];
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
// Display notice if there were validation errors.
|
| 283 |
+
if ( validationErrors.length > 0 ) {
|
| 284 |
+
wp.data.dispatch( 'core/notices' ).createNotice( 'warning', noticeMessage, noticeOptions );
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
module.validationWarningNoticeId = noticeOptions.id;
|
| 288 |
+
},
|
| 289 |
+
|
| 290 |
+
/**
|
| 291 |
+
* Checks if the validation errors have changed.
|
| 292 |
+
*
|
| 293 |
+
* @param {Object[]} validationErrors A list of validation errors.
|
| 294 |
+
* @return {boolean|*} Returns true when the validation errors change.
|
| 295 |
+
*/
|
| 296 |
+
didValidationErrorsChange: function didValidationErrorsChange( validationErrors ) {
|
| 297 |
+
if ( module.areBlocksOutOfSync() ) {
|
| 298 |
+
module.lastStates.validationErrors = [];
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
return (
|
| 302 |
+
module.lastStates.validationErrors.length !== validationErrors.length
|
| 303 |
+
||
|
| 304 |
+
( validationErrors && ! _.isEqual( module.lastStates.validationErrors, validationErrors ) )
|
| 305 |
+
);
|
| 306 |
+
},
|
| 307 |
+
|
| 308 |
+
/**
|
| 309 |
+
* Checks if the block order is out of sync.
|
| 310 |
+
*
|
| 311 |
+
* Block change on page load and can get out of sync during normal editing and saving processes. This method gives a check to determine if an "out of sync" condition occurred.
|
| 312 |
+
*
|
| 313 |
+
* @return {boolean} Whether out of sync.
|
| 314 |
+
*/
|
| 315 |
+
areBlocksOutOfSync: function areBlocksOutOfSync() {
|
| 316 |
+
var blockOrder = wp.data.select( 'core/editor' ).getBlockOrder();
|
| 317 |
+
if ( module.lastStates.blockOrder.length !== blockOrder.length || ! _.isEqual( module.lastStates.blockOrder, blockOrder ) ) {
|
| 318 |
+
module.lastStates.blockOrder = blockOrder;
|
| 319 |
+
return true;
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
return false;
|
| 323 |
+
},
|
| 324 |
+
|
| 325 |
+
/**
|
| 326 |
+
* Resets the validation warning notice.
|
| 327 |
+
*
|
| 328 |
+
* @return {void}
|
| 329 |
+
*/
|
| 330 |
+
resetWarningNotice: function resetWarningNotice() {
|
| 331 |
+
if ( module.validationWarningNoticeId ) {
|
| 332 |
+
wp.data.dispatch( 'core/notices' ).removeNotice( module.validationWarningNoticeId );
|
| 333 |
+
module.validationWarningNoticeId = null;
|
| 334 |
+
}
|
| 335 |
+
},
|
| 336 |
+
|
| 337 |
+
/**
|
| 338 |
+
* Resets the block level validation errors.
|
| 339 |
+
*
|
| 340 |
+
* @return {void}
|
| 341 |
+
*/
|
| 342 |
+
resetBlockNotices: function resetBlockNotices() {
|
| 343 |
+
wp.data.dispatch( module.storeName ).updateBlocksValidationErrors( {} );
|
| 344 |
+
},
|
| 345 |
+
|
| 346 |
+
/**
|
| 347 |
+
* Get flattened block order.
|
| 348 |
+
*
|
| 349 |
+
* @param {Object[]} blocks - List of blocks which maty have nested blocks inside them.
|
| 350 |
+
* @return {string[]} Block IDs in flattened order.
|
| 351 |
+
*/
|
| 352 |
+
getFlattenedBlockOrder: function getFlattenedBlockOrder( blocks ) {
|
| 353 |
+
var blockOrder = [];
|
| 354 |
+
_.each( blocks, function( block ) {
|
| 355 |
+
blockOrder.push( block.clientId );
|
| 356 |
+
if ( block.innerBlocks.length > 0 ) {
|
| 357 |
+
Array.prototype.push.apply( blockOrder, module.getFlattenedBlockOrder( block.innerBlocks ) );
|
| 358 |
+
}
|
| 359 |
+
} );
|
| 360 |
+
return blockOrder;
|
| 361 |
+
},
|
| 362 |
+
|
| 363 |
+
/**
|
| 364 |
+
* Update blocks' validation errors in the store.
|
| 365 |
+
*
|
| 366 |
+
* @return {Object} Validation errors grouped by block ID other ones.
|
| 367 |
+
*/
|
| 368 |
+
getBlocksValidationErrors: function getBlocksValidationErrors() {
|
| 369 |
+
var acceptedStatus, blockValidationErrorsByClientId, editorSelect, currentPost, blockOrder, validationErrors, otherValidationErrors;
|
| 370 |
+
acceptedStatus = 3; // eslint-disable-line no-magic-numbers
|
| 371 |
+
editorSelect = wp.data.select( 'core/editor' );
|
| 372 |
+
currentPost = editorSelect.getCurrentPost();
|
| 373 |
+
validationErrors = _.map(
|
| 374 |
+
_.filter( currentPost[ module.data.ampValidityRestField ].results, function( result ) {
|
| 375 |
+
return result.term_status !== acceptedStatus; // If not accepted by the user.
|
| 376 |
+
} ),
|
| 377 |
+
function( result ) {
|
| 378 |
+
return result.error;
|
| 379 |
+
}
|
| 380 |
+
);
|
| 381 |
+
blockOrder = module.getFlattenedBlockOrder( editorSelect.getBlocks() );
|
| 382 |
+
|
| 383 |
+
otherValidationErrors = [];
|
| 384 |
+
blockValidationErrorsByClientId = {};
|
| 385 |
+
_.each( blockOrder, function( clientId ) {
|
| 386 |
+
blockValidationErrorsByClientId[ clientId ] = [];
|
| 387 |
+
} );
|
| 388 |
+
|
| 389 |
+
_.each( validationErrors, function( validationError ) {
|
| 390 |
+
var i, source, clientId, block, matched;
|
| 391 |
+
if ( ! validationError.sources ) {
|
| 392 |
+
otherValidationErrors.push( validationError );
|
| 393 |
+
return;
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
// Find the inner-most nested block source only; ignore any nested blocks.
|
| 397 |
+
matched = false;
|
| 398 |
+
for ( i = validationError.sources.length - 1; 0 <= i; i-- ) {
|
| 399 |
+
source = validationError.sources[ i ];
|
| 400 |
+
|
| 401 |
+
// Skip sources that are not for blocks.
|
| 402 |
+
if ( ! source.block_name || _.isUndefined( source.block_content_index ) || currentPost.id !== source.post_id ) {
|
| 403 |
+
continue;
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
// Look up the block ID by index, assuming the blocks of content in the editor are the same as blocks rendered on frontend.
|
| 407 |
+
clientId = blockOrder[ source.block_content_index ];
|
| 408 |
+
if ( _.isUndefined( clientId ) ) {
|
| 409 |
+
throw new Error( 'undefined_block_index' );
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
// Sanity check that block exists for clientId.
|
| 413 |
+
block = editorSelect.getBlock( clientId );
|
| 414 |
+
if ( ! block ) {
|
| 415 |
+
throw new Error( 'block_lookup_failure' );
|
| 416 |
+
}
|
| 417 |
+
|
| 418 |
+
// Check the block type in case a block is dynamically added/removed via the_content filter to cause alignment error.
|
| 419 |
+
if ( block.name !== source.block_name ) {
|
| 420 |
+
throw new Error( 'ordered_block_alignment_mismatch' );
|
| 421 |
+
}
|
| 422 |
+
|
| 423 |
+
blockValidationErrorsByClientId[ clientId ].push( validationError );
|
| 424 |
+
matched = true;
|
| 425 |
+
|
| 426 |
+
// Stop looking for sources, since we aren't looking for parent blocks.
|
| 427 |
+
break;
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
if ( ! matched ) {
|
| 431 |
+
otherValidationErrors.push( validationError );
|
| 432 |
+
}
|
| 433 |
+
} );
|
| 434 |
+
|
| 435 |
+
return {
|
| 436 |
+
byClientId: blockValidationErrorsByClientId,
|
| 437 |
+
other: otherValidationErrors
|
| 438 |
+
};
|
| 439 |
+
},
|
| 440 |
+
|
| 441 |
+
/**
|
| 442 |
+
* Get message for validation error.
|
| 443 |
+
*
|
| 444 |
+
* @param {Object} validationError - Validation error.
|
| 445 |
+
* @param {string} validationError.code - Validation error code.
|
| 446 |
+
* @param {string} [validationError.node_name] - Node name.
|
| 447 |
+
* @param {string} [validationError.message] - Validation error message.
|
| 448 |
+
* @return {wp.element.Component[]|string[]} Validation error message.
|
| 449 |
+
*/
|
| 450 |
+
getValidationErrorMessage: function getValidationErrorMessage( validationError ) {
|
| 451 |
+
if ( validationError.message ) {
|
| 452 |
+
return validationError.message;
|
| 453 |
+
}
|
| 454 |
+
if ( 'invalid_element' === validationError.code && validationError.node_name ) {
|
| 455 |
+
return [
|
| 456 |
+
wp.i18n.__( 'Invalid element: ' ),
|
| 457 |
+
wp.element.createElement( 'code', { key: 'name' }, validationError.node_name )
|
| 458 |
+
];
|
| 459 |
+
} else if ( 'invalid_attribute' === validationError.code && validationError.node_name ) {
|
| 460 |
+
return [
|
| 461 |
+
wp.i18n.__( 'Invalid attribute: ' ),
|
| 462 |
+
wp.element.createElement( 'code', { key: 'name' }, validationError.parent_name ? wp.i18n.sprintf( '%s[%s]', validationError.parent_name, validationError.node_name ) : validationError.node_name )
|
| 463 |
+
];
|
| 464 |
+
}
|
| 465 |
+
return [
|
| 466 |
+
wp.i18n.__( 'Error code: ', 'amp' ),
|
| 467 |
+
wp.element.createElement( 'code', { key: 'name' }, validationError.code || wp.i18n.__( 'unknown' ) )
|
| 468 |
+
];
|
| 469 |
+
},
|
| 470 |
+
|
| 471 |
+
/**
|
| 472 |
+
* Wraps the edit() method of a block, and conditionally adds a Notice.
|
| 473 |
+
*
|
| 474 |
+
* @param {Function} BlockEdit - The original edit() method of the block.
|
| 475 |
+
* @return {Function} The edit() method, conditionally wrapped in a notice for AMP validation error(s).
|
| 476 |
+
*/
|
| 477 |
+
conditionallyAddNotice: function conditionallyAddNotice( BlockEdit ) {
|
| 478 |
+
return function( ownProps ) {
|
| 479 |
+
var validationErrors,
|
| 480 |
+
mergedProps;
|
| 481 |
+
function AmpNoticeBlockEdit( props ) {
|
| 482 |
+
var edit, details;
|
| 483 |
+
edit = wp.element.createElement(
|
| 484 |
+
BlockEdit,
|
| 485 |
+
props
|
| 486 |
+
);
|
| 487 |
+
|
| 488 |
+
if ( 0 === props.ampBlockValidationErrors.length ) {
|
| 489 |
+
return edit;
|
| 490 |
+
}
|
| 491 |
+
|
| 492 |
+
details = wp.element.createElement( 'details', { className: 'amp-block-validation-errors' }, [
|
| 493 |
+
wp.element.createElement( 'summary', { key: 'summary', className: 'amp-block-validation-errors__summary' }, wp.i18n.sprintf(
|
| 494 |
+
wp.i18n._n(
|
| 495 |
+
'There is %s issue from AMP validation.',
|
| 496 |
+
'There are %s issues from AMP validation.',
|
| 497 |
+
props.ampBlockValidationErrors.length,
|
| 498 |
+
'amp'
|
| 499 |
+
),
|
| 500 |
+
props.ampBlockValidationErrors.length
|
| 501 |
+
) ),
|
| 502 |
+
wp.element.createElement(
|
| 503 |
+
'ul',
|
| 504 |
+
{ key: 'list', className: 'amp-block-validation-errors__list' },
|
| 505 |
+
_.map( props.ampBlockValidationErrors, function( error, key ) {
|
| 506 |
+
return wp.element.createElement( 'li', { key: key }, module.getValidationErrorMessage( error ) );
|
| 507 |
+
} )
|
| 508 |
+
)
|
| 509 |
+
] );
|
| 510 |
+
|
| 511 |
+
return wp.element.createElement(
|
| 512 |
+
wp.element.Fragment, {},
|
| 513 |
+
wp.element.createElement(
|
| 514 |
+
wp.components.Notice,
|
| 515 |
+
{
|
| 516 |
+
status: 'warning',
|
| 517 |
+
isDismissible: false
|
| 518 |
+
},
|
| 519 |
+
details
|
| 520 |
+
),
|
| 521 |
+
edit
|
| 522 |
+
);
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
if ( ! module.lastStates.blockValidationErrors[ ownProps.clientId ] ) {
|
| 526 |
+
validationErrors = wp.data.select( module.storeName ).getBlockValidationErrors( ownProps.clientId );
|
| 527 |
+
module.lastStates.blockValidationErrors[ ownProps.clientId ] = validationErrors;
|
| 528 |
+
}
|
| 529 |
+
|
| 530 |
+
mergedProps = _.extend( {}, ownProps, {
|
| 531 |
+
ampBlockValidationErrors: module.lastStates.blockValidationErrors[ ownProps.clientId ]
|
| 532 |
+
} );
|
| 533 |
+
|
| 534 |
+
return AmpNoticeBlockEdit( mergedProps );
|
| 535 |
+
};
|
| 536 |
+
}
|
| 537 |
+
};
|
| 538 |
+
|
| 539 |
+
return module;
|
| 540 |
+
}() );
|
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/******/ (function(modules) { // webpackBootstrap
|
| 2 |
+
/******/ // The module cache
|
| 3 |
+
/******/ var installedModules = {};
|
| 4 |
+
/******/
|
| 5 |
+
/******/ // The require function
|
| 6 |
+
/******/ function __webpack_require__(moduleId) {
|
| 7 |
+
/******/
|
| 8 |
+
/******/ // Check if module is in cache
|
| 9 |
+
/******/ if(installedModules[moduleId]) {
|
| 10 |
+
/******/ return installedModules[moduleId].exports;
|
| 11 |
+
/******/ }
|
| 12 |
+
/******/ // Create a new module (and put it into the cache)
|
| 13 |
+
/******/ var module = installedModules[moduleId] = {
|
| 14 |
+
/******/ i: moduleId,
|
| 15 |
+
/******/ l: false,
|
| 16 |
+
/******/ exports: {}
|
| 17 |
+
/******/ };
|
| 18 |
+
/******/
|
| 19 |
+
/******/ // Execute the module function
|
| 20 |
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
| 21 |
+
/******/
|
| 22 |
+
/******/ // Flag the module as loaded
|
| 23 |
+
/******/ module.l = true;
|
| 24 |
+
/******/
|
| 25 |
+
/******/ // Return the exports of the module
|
| 26 |
+
/******/ return module.exports;
|
| 27 |
+
/******/ }
|
| 28 |
+
/******/
|
| 29 |
+
/******/
|
| 30 |
+
/******/ // expose the modules object (__webpack_modules__)
|
| 31 |
+
/******/ __webpack_require__.m = modules;
|
| 32 |
+
/******/
|
| 33 |
+
/******/ // expose the module cache
|
| 34 |
+
/******/ __webpack_require__.c = installedModules;
|
| 35 |
+
/******/
|
| 36 |
+
/******/ // define getter function for harmony exports
|
| 37 |
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
| 38 |
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
| 39 |
+
/******/ Object.defineProperty(exports, name, {
|
| 40 |
+
/******/ configurable: false,
|
| 41 |
+
/******/ enumerable: true,
|
| 42 |
+
/******/ get: getter
|
| 43 |
+
/******/ });
|
| 44 |
+
/******/ }
|
| 45 |
+
/******/ };
|
| 46 |
+
/******/
|
| 47 |
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
| 48 |
+
/******/ __webpack_require__.n = function(module) {
|
| 49 |
+
/******/ var getter = module && module.__esModule ?
|
| 50 |
+
/******/ function getDefault() { return module['default']; } :
|
| 51 |
+
/******/ function getModuleExports() { return module; };
|
| 52 |
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
| 53 |
+
/******/ return getter;
|
| 54 |
+
/******/ };
|
| 55 |
+
/******/
|
| 56 |
+
/******/ // Object.prototype.hasOwnProperty.call
|
| 57 |
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
| 58 |
+
/******/
|
| 59 |
+
/******/ // __webpack_public_path__
|
| 60 |
+
/******/ __webpack_require__.p = "";
|
| 61 |
+
/******/
|
| 62 |
+
/******/ // Load entry module and return exports
|
| 63 |
+
/******/ return __webpack_require__(__webpack_require__.s = 2);
|
| 64 |
+
/******/ })
|
| 65 |
+
/************************************************************************/
|
| 66 |
+
/******/ ([
|
| 67 |
+
/* 0 */
|
| 68 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 69 |
+
|
| 70 |
+
"use strict";
|
| 71 |
+
eval("/* harmony export (immutable) */ __webpack_exports__[\"b\"] = getMediaPlaceholder;\n/* harmony export (immutable) */ __webpack_exports__[\"a\"] = getLayoutControls;\nvar __ = wp.i18n.__;\nvar _wp$components = wp.components,\n TextControl = _wp$components.TextControl,\n SelectControl = _wp$components.SelectControl,\n Notice = _wp$components.Notice,\n Placeholder = _wp$components.Placeholder;\n\n/**\n * Display media placeholder.\n *\n * @param {string} name Block's name.\n * @param {string|boolean} url URL.\n * @return {XML} Placeholder.\n */\n\nfunction getMediaPlaceholder(name, url) {\n\treturn wp.element.createElement(\n\t\tPlaceholder,\n\t\t{ label: name },\n\t\twp.element.createElement(\n\t\t\t\"p\",\n\t\t\t{ className: \"components-placeholder__error\" },\n\t\t\turl\n\t\t),\n\t\twp.element.createElement(\n\t\t\t\"p\",\n\t\t\t{ className: \"components-placeholder__error\" },\n\t\t\t__('Previews for this are unavailable in the editor, sorry!', 'amp')\n\t\t)\n\t);\n}\n\n/**\n * Layout controls for AMP blocks' attributes: layout, width, height.\n *\n * @param {Object} props Props.\n * @param {Array} ampLayoutOptions Layout options.\n * @return {[XML,*,XML,*,XML]} Controls.\n */\nfunction getLayoutControls(props, ampLayoutOptions) {\n\t// @todo Move getting ampLayoutOptions to utils as well.\n\tvar attributes = props.attributes,\n\t setAttributes = props.setAttributes;\n\tvar ampLayout = attributes.ampLayout,\n\t height = attributes.height,\n\t width = attributes.width;\n\n\tvar showHeightNotice = !height && ('fixed' === ampLayout || 'fixed-height' === ampLayout);\n\tvar showWidthNotice = !width && 'fixed' === ampLayout;\n\n\treturn [wp.element.createElement(SelectControl, {\n\t\tkey: \"ampLayout\",\n\t\tlabel: __('Layout', 'amp'),\n\t\tvalue: ampLayout,\n\t\toptions: ampLayoutOptions,\n\t\tonChange: function onChange(value) {\n\t\t\treturn setAttributes({ ampLayout: value });\n\t\t}\n\t}), showWidthNotice && wp.element.createElement(\n\t\tNotice,\n\t\t{ key: \"showWidthNotice\", status: \"error\", isDismissible: false },\n\t\twp.i18n.sprintf(\n\t\t/* translators: %s is the layout name */\n\t\t__('Width is required for %s layout', 'amp'), ampLayout)\n\t), wp.element.createElement(TextControl, {\n\t\tkey: \"width\",\n\t\ttype: \"number\",\n\t\tlabel: __('Width (px)', 'amp'),\n\t\tvalue: width !== undefined ? width : '',\n\t\tonChange: function onChange(value) {\n\t\t\treturn setAttributes({ width: value });\n\t\t}\n\t}), showHeightNotice && wp.element.createElement(\n\t\tNotice,\n\t\t{ key: \"showHeightNotice\", status: \"error\", isDismissible: false },\n\t\twp.i18n.sprintf(\n\t\t/* translators: %s is the layout name */\n\t\t__('Height is required for %s layout', 'amp'), ampLayout)\n\t), wp.element.createElement(TextControl, {\n\t\tkey: \"height\",\n\t\ttype: \"number\",\n\t\tlabel: __('Height (px)', 'amp'),\n\t\tvalue: height,\n\t\tonChange: function onChange(value) {\n\t\t\treturn setAttributes({ height: value });\n\t\t}\n\t})];\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy91dGlscy5qcz8wOGNiIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgX3dwJGNvbXBvbmVudHMgPSB3cC5jb21wb25lbnRzLFxuICAgIFRleHRDb250cm9sID0gX3dwJGNvbXBvbmVudHMuVGV4dENvbnRyb2wsXG4gICAgU2VsZWN0Q29udHJvbCA9IF93cCRjb21wb25lbnRzLlNlbGVjdENvbnRyb2wsXG4gICAgTm90aWNlID0gX3dwJGNvbXBvbmVudHMuTm90aWNlLFxuICAgIFBsYWNlaG9sZGVyID0gX3dwJGNvbXBvbmVudHMuUGxhY2Vob2xkZXI7XG5cbi8qKlxuICogRGlzcGxheSBtZWRpYSBwbGFjZWhvbGRlci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBCbG9jaydzIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ3xib29sZWFufSB1cmwgVVJMLlxuICogQHJldHVybiB7WE1MfSBQbGFjZWhvbGRlci5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWVkaWFQbGFjZWhvbGRlcihuYW1lLCB1cmwpIHtcblx0cmV0dXJuIHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRQbGFjZWhvbGRlcixcblx0XHR7IGxhYmVsOiBuYW1lIH0sXG5cdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XCJwXCIsXG5cdFx0XHR7IGNsYXNzTmFtZTogXCJjb21wb25lbnRzLXBsYWNlaG9sZGVyX19lcnJvclwiIH0sXG5cdFx0XHR1cmxcblx0XHQpLFxuXHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFwicFwiLFxuXHRcdFx0eyBjbGFzc05hbWU6IFwiY29tcG9uZW50cy1wbGFjZWhvbGRlcl9fZXJyb3JcIiB9LFxuXHRcdFx0X18oJ1ByZXZpZXdzIGZvciB0aGlzIGFyZSB1bmF2YWlsYWJsZSBpbiB0aGUgZWRpdG9yLCBzb3JyeSEnLCAnYW1wJylcblx0XHQpXG5cdCk7XG59XG5cbi8qKlxuICogTGF5b3V0IGNvbnRyb2xzIGZvciBBTVAgYmxvY2tzJyBhdHRyaWJ1dGVzOiBsYXlvdXQsIHdpZHRoLCBoZWlnaHQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHByb3BzIFByb3BzLlxuICogQHBhcmFtIHtBcnJheX0gYW1wTGF5b3V0T3B0aW9ucyBMYXlvdXQgb3B0aW9ucy5cbiAqIEByZXR1cm4ge1tYTUwsKixYTUwsKixYTUxdfSBDb250cm9scy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExheW91dENvbnRyb2xzKHByb3BzLCBhbXBMYXlvdXRPcHRpb25zKSB7XG5cdC8vIEB0b2RvIE1vdmUgZ2V0dGluZyBhbXBMYXlvdXRPcHRpb25zIHRvIHV0aWxzIGFzIHdlbGwuXG5cdHZhciBhdHRyaWJ1dGVzID0gcHJvcHMuYXR0cmlidXRlcyxcblx0ICAgIHNldEF0dHJpYnV0ZXMgPSBwcm9wcy5zZXRBdHRyaWJ1dGVzO1xuXHR2YXIgYW1wTGF5b3V0ID0gYXR0cmlidXRlcy5hbXBMYXlvdXQsXG5cdCAgICBoZWlnaHQgPSBhdHRyaWJ1dGVzLmhlaWdodCxcblx0ICAgIHdpZHRoID0gYXR0cmlidXRlcy53aWR0aDtcblxuXHR2YXIgc2hvd0hlaWdodE5vdGljZSA9ICFoZWlnaHQgJiYgKCdmaXhlZCcgPT09IGFtcExheW91dCB8fCAnZml4ZWQtaGVpZ2h0JyA9PT0gYW1wTGF5b3V0KTtcblx0dmFyIHNob3dXaWR0aE5vdGljZSA9ICF3aWR0aCAmJiAnZml4ZWQnID09PSBhbXBMYXlvdXQ7XG5cblx0cmV0dXJuIFt3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoU2VsZWN0Q29udHJvbCwge1xuXHRcdGtleTogXCJhbXBMYXlvdXRcIixcblx0XHRsYWJlbDogX18oJ0xheW91dCcsICdhbXAnKSxcblx0XHR2YWx1ZTogYW1wTGF5b3V0LFxuXHRcdG9wdGlvbnM6IGFtcExheW91dE9wdGlvbnMsXG5cdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGFtcExheW91dDogdmFsdWUgfSk7XG5cdFx0fVxuXHR9KSwgc2hvd1dpZHRoTm90aWNlICYmIHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHROb3RpY2UsXG5cdFx0eyBrZXk6IFwic2hvd1dpZHRoTm90aWNlXCIsIHN0YXR1czogXCJlcnJvclwiLCBpc0Rpc21pc3NpYmxlOiBmYWxzZSB9LFxuXHRcdHdwLmkxOG4uc3ByaW50Zihcblx0XHQvKiB0cmFuc2xhdG9yczogJXMgaXMgdGhlIGxheW91dCBuYW1lICovXG5cdFx0X18oJ1dpZHRoIGlzIHJlcXVpcmVkIGZvciAlcyBsYXlvdXQnLCAnYW1wJyksIGFtcExheW91dClcblx0KSwgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0a2V5OiBcIndpZHRoXCIsXG5cdFx0dHlwZTogXCJudW1iZXJcIixcblx0XHRsYWJlbDogX18oJ1dpZHRoIChweCknLCAnYW1wJyksXG5cdFx0dmFsdWU6IHdpZHRoICE9PSB1bmRlZmluZWQgPyB3aWR0aCA6ICcnLFxuXHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyB3aWR0aDogdmFsdWUgfSk7XG5cdFx0fVxuXHR9KSwgc2hvd0hlaWdodE5vdGljZSAmJiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0Tm90aWNlLFxuXHRcdHsga2V5OiBcInNob3dIZWlnaHROb3RpY2VcIiwgc3RhdHVzOiBcImVycm9yXCIsIGlzRGlzbWlzc2libGU6IGZhbHNlIH0sXG5cdFx0d3AuaTE4bi5zcHJpbnRmKFxuXHRcdC8qIHRyYW5zbGF0b3JzOiAlcyBpcyB0aGUgbGF5b3V0IG5hbWUgKi9cblx0XHRfXygnSGVpZ2h0IGlzIHJlcXVpcmVkIGZvciAlcyBsYXlvdXQnLCAnYW1wJyksIGFtcExheW91dClcblx0KSwgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0a2V5OiBcImhlaWdodFwiLFxuXHRcdHR5cGU6IFwibnVtYmVyXCIsXG5cdFx0bGFiZWw6IF9fKCdIZWlnaHQgKHB4KScsICdhbXAnKSxcblx0XHR2YWx1ZTogaGVpZ2h0LFxuXHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBoZWlnaHQ6IHZhbHVlIH0pO1xuXHRcdH1cblx0fSldO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vYmxvY2tzL3V0aWxzLmpzXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0\n");
|
| 72 |
+
|
| 73 |
+
/***/ }),
|
| 74 |
+
/* 1 */,
|
| 75 |
+
/* 2 */
|
| 76 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 77 |
+
|
| 78 |
+
"use strict";
|
| 79 |
+
eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__amp_mathml__ = __webpack_require__(3);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__amp_timeago__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__amp_o2_player__ = __webpack_require__(6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__amp_ooyala_player__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__amp_reach_player__ = __webpack_require__(8);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__amp_springboard_player__ = __webpack_require__(9);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__amp_jwplayer__ = __webpack_require__(10);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__amp_brid_player__ = __webpack_require__(11);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__amp_ima_video__ = __webpack_require__(12);\n/**\n * Import blocks.\n */\n\n\n\n\n\n\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy9pbmRleC5qcz84MTkzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSW1wb3J0IGJsb2Nrcy5cbiAqL1xuaW1wb3J0ICcuL2FtcC1tYXRobWwnO1xuaW1wb3J0ICcuL2FtcC10aW1lYWdvJztcbmltcG9ydCAnLi9hbXAtbzItcGxheWVyJztcbmltcG9ydCAnLi9hbXAtb295YWxhLXBsYXllcic7XG5pbXBvcnQgJy4vYW1wLXJlYWNoLXBsYXllcic7XG5pbXBvcnQgJy4vYW1wLXNwcmluZ2JvYXJkLXBsYXllcic7XG5pbXBvcnQgJy4vYW1wLWp3cGxheWVyJztcbmltcG9ydCAnLi9hbXAtYnJpZC1wbGF5ZXInO1xuaW1wb3J0ICcuL2FtcC1pbWEtdmlkZW8nO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vYmxvY2tzL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2\n");
|
| 80 |
+
|
| 81 |
+
/***/ }),
|
| 82 |
+
/* 3 */
|
| 83 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 84 |
+
|
| 85 |
+
"use strict";
|
| 86 |
+
eval("\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar PlainText = wp.editor.PlainText;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-mathml', {\n\ttitle: __('AMP MathML', 'amp'),\n\tcategory: 'common',\n\ticon: 'welcome-learn-more',\n\tkeywords: [__('Mathematical formula', 'amp'), __('Scientific content ', 'amp')],\n\n\tattributes: {\n\t\tdataFormula: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-mathml',\n\t\t\tattribute: 'data-formula'\n\t\t}\n\t},\n\n\tedit: function edit(_ref) {\n\t\tvar attributes = _ref.attributes,\n\t\t setAttributes = _ref.setAttributes;\n\t\tvar dataFormula = attributes.dataFormula;\n\n\n\t\treturn wp.element.createElement(PlainText, {\n\t\t\tkey: 'formula',\n\t\t\tvalue: dataFormula,\n\t\t\tplaceholder: __('Insert formula', 'amp'),\n\t\t\tonChange: function onChange(value) {\n\t\t\t\treturn setAttributes({ dataFormula: value });\n\t\t\t}\n\t\t});\n\t},\n\tsave: function save(_ref2) {\n\t\tvar attributes = _ref2.attributes;\n\n\t\tvar mathmlProps = {\n\t\t\t'data-formula': attributes.dataFormula,\n\t\t\tlayout: 'container'\n\t\t};\n\t\treturn wp.element.createElement('amp-mathml', mathmlProps);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy9hbXAtbWF0aG1sL2luZGV4LmpzP2JhZjIiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIEludGVybmFsIGJsb2NrIGxpYnJhcmllcy5cbiAqL1xudmFyIF9fID0gd3AuaTE4bi5fXztcbnZhciByZWdpc3RlckJsb2NrVHlwZSA9IHdwLmJsb2Nrcy5yZWdpc3RlckJsb2NrVHlwZTtcbnZhciBQbGFpblRleHQgPSB3cC5lZGl0b3IuUGxhaW5UZXh0O1xuXG4vKipcbiAqIFJlZ2lzdGVyIGJsb2NrLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IHJlZ2lzdGVyQmxvY2tUeXBlKCdhbXAvYW1wLW1hdGhtbCcsIHtcblx0dGl0bGU6IF9fKCdBTVAgTWF0aE1MJywgJ2FtcCcpLFxuXHRjYXRlZ29yeTogJ2NvbW1vbicsXG5cdGljb246ICd3ZWxjb21lLWxlYXJuLW1vcmUnLFxuXHRrZXl3b3JkczogW19fKCdNYXRoZW1hdGljYWwgZm9ybXVsYScsICdhbXAnKSwgX18oJ1NjaWVudGlmaWMgY29udGVudCAnLCAnYW1wJyldLFxuXG5cdGF0dHJpYnV0ZXM6IHtcblx0XHRkYXRhRm9ybXVsYToge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLW1hdGhtbCcsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLWZvcm11bGEnXG5cdFx0fVxuXHR9LFxuXG5cdGVkaXQ6IGZ1bmN0aW9uIGVkaXQoX3JlZikge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gX3JlZi5hdHRyaWJ1dGVzLFxuXHRcdCAgICBzZXRBdHRyaWJ1dGVzID0gX3JlZi5zZXRBdHRyaWJ1dGVzO1xuXHRcdHZhciBkYXRhRm9ybXVsYSA9IGF0dHJpYnV0ZXMuZGF0YUZvcm11bGE7XG5cblxuXHRcdHJldHVybiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoUGxhaW5UZXh0LCB7XG5cdFx0XHRrZXk6ICdmb3JtdWxhJyxcblx0XHRcdHZhbHVlOiBkYXRhRm9ybXVsYSxcblx0XHRcdHBsYWNlaG9sZGVyOiBfXygnSW5zZXJ0IGZvcm11bGEnLCAnYW1wJyksXG5cdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhRm9ybXVsYTogdmFsdWUgfSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cdHNhdmU6IGZ1bmN0aW9uIHNhdmUoX3JlZjIpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IF9yZWYyLmF0dHJpYnV0ZXM7XG5cblx0XHR2YXIgbWF0aG1sUHJvcHMgPSB7XG5cdFx0XHQnZGF0YS1mb3JtdWxhJzogYXR0cmlidXRlcy5kYXRhRm9ybXVsYSxcblx0XHRcdGxheW91dDogJ2NvbnRhaW5lcidcblx0XHR9O1xuXHRcdHJldHVybiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoJ2FtcC1tYXRobWwnLCBtYXRobWxQcm9wcyk7XG5cdH1cbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vYmxvY2tzL2FtcC1tYXRobWwvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3\n");
|
| 87 |
+
|
| 88 |
+
/***/ }),
|
| 89 |
+
/* 4 */
|
| 90 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 91 |
+
|
| 92 |
+
"use strict";
|
| 93 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_timeago_js__ = __webpack_require__(5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_timeago_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_timeago_js__);\n/* global moment */\n\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar _wp$editor = wp.editor,\n InspectorControls = _wp$editor.InspectorControls,\n BlockAlignmentToolbar = _wp$editor.BlockAlignmentToolbar,\n BlockControls = _wp$editor.BlockControls;\nvar _wp$components = wp.components,\n DateTimePicker = _wp$components.DateTimePicker,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl;\nvar Fragment = wp.element.Fragment;\n\n\n\n/**\n * Register block.\n */\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-timeago', {\n\ttitle: __('AMP Timeago'),\n\tcategory: 'common',\n\ticon: 'backup',\n\tkeywords: [__('Time difference'), __('Time ago'), __('Date')],\n\n\tattributes: {\n\t\talign: {\n\t\t\ttype: 'string'\n\t\t},\n\t\tcutoff: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-timeago',\n\t\t\tattribute: 'cutoff'\n\t\t},\n\t\tdateTime: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-timeago',\n\t\t\tattribute: 'datetime'\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'fixed-height',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-timeago',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-timeago',\n\t\t\tattribute: 'width'\n\t\t},\n\t\theight: {\n\t\t\tdefault: 20,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-timeago',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tgetEditWrapperProps: function getEditWrapperProps(attributes) {\n\t\tvar align = attributes.align;\n\n\t\tif ('left' === align || 'right' === align || 'center' === align) {\n\t\t\treturn { 'data-align': align };\n\t\t}\n\t},\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar align = attributes.align,\n\t\t cutoff = attributes.cutoff;\n\n\t\tvar timeAgo = void 0;\n\t\tif (attributes.dateTime) {\n\t\t\tif (attributes.cutoff && parseInt(attributes.cutoff) < Math.abs(moment(attributes.dateTime).diff(moment(), 'seconds'))) {\n\t\t\t\ttimeAgo = moment(attributes.dateTime).format('dddd D MMMM HH:mm');\n\t\t\t} else {\n\t\t\t\ttimeAgo = __WEBPACK_IMPORTED_MODULE_1_timeago_js___default()().format(attributes.dateTime);\n\t\t\t}\n\t\t} else {\n\t\t\ttimeAgo = __WEBPACK_IMPORTED_MODULE_1_timeago_js___default()().format(new Date());\n\t\t\tsetAttributes({ dateTime: moment(moment(), moment.ISO_8601, true).format() });\n\t\t}\n\n\t\tvar ampLayoutOptions = [{ value: '', label: __('Responsive', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }, { value: 'fixed-height', label: __('Fixed height', 'amp') }];\n\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('AMP Timeago Settings') },\n\t\t\t\t\twp.element.createElement(DateTimePicker, {\n\t\t\t\t\t\tlocale: 'en',\n\t\t\t\t\t\tcurrentDate: attributes.dateTime || moment(),\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dateTime: moment(value, moment.ISO_8601, true).format() });\n\t\t\t\t\t\t} // eslint-disable-line\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tclassName: 'blocks-amp-timeout__cutoff',\n\t\t\t\t\t\tlabel: __('Cutoff (seconds)'),\n\t\t\t\t\t\tvalue: cutoff !== undefined ? cutoff : '',\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ cutoff: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t),\n\t\t\twp.element.createElement(\n\t\t\t\tBlockControls,\n\t\t\t\t{ key: 'controls' },\n\t\t\t\twp.element.createElement(BlockAlignmentToolbar, {\n\t\t\t\t\tvalue: align,\n\t\t\t\t\tonChange: function onChange(nextAlign) {\n\t\t\t\t\t\tsetAttributes({ align: nextAlign });\n\t\t\t\t\t},\n\t\t\t\t\tcontrols: ['left', 'center', 'right']\n\t\t\t\t})\n\t\t\t),\n\t\t\twp.element.createElement(\n\t\t\t\t'time',\n\t\t\t\t{ key: 'timeago', dateTime: attributes.dateTime },\n\t\t\t\ttimeAgo\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\n\t\tvar timeagoProps = {\n\t\t\tlayout: 'responsive',\n\t\t\tclassName: 'align' + (attributes.align || 'none'),\n\t\t\tdatetime: attributes.dateTime,\n\t\t\tlocale: 'en'\n\t\t};\n\t\tif (attributes.cutoff) {\n\t\t\ttimeagoProps.cutoff = attributes.cutoff;\n\t\t}\n\t\tif (attributes.ampLayout) {\n\t\t\tswitch (attributes.ampLayout) {\n\t\t\t\tcase 'fixed-height':\n\t\t\t\t\tif (attributes.height) {\n\t\t\t\t\t\ttimeagoProps.height = attributes.height;\n\t\t\t\t\t\ttimeagoProps.layout = attributes.ampLayout;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fixed':\n\t\t\t\t\tif (attributes.height && attributes.width) {\n\t\t\t\t\t\ttimeagoProps.height = attributes.height;\n\t\t\t\t\t\ttimeagoProps.width = attributes.width;\n\t\t\t\t\t\ttimeagoProps.layout = attributes.ampLayout;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\t'amp-timeago',\n\t\t\ttimeagoProps,\n\t\t\tmoment(attributes.dateTime).format('dddd D MMMM HH:mm')\n\t\t);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy9hbXAtdGltZWFnby9pbmRleC5qcz9iMThjIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGdsb2JhbCBtb21lbnQgKi9cblxuLyoqXG4gKiBIZWxwZXIgbWV0aG9kcyBmb3IgYmxvY2tzLlxuICovXG5pbXBvcnQgeyBnZXRMYXlvdXRDb250cm9scyB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuLyoqXG4gKiBJbnRlcm5hbCBibG9jayBsaWJyYXJpZXMuXG4gKi9cbnZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7XG52YXIgX3dwJGVkaXRvciA9IHdwLmVkaXRvcixcbiAgICBJbnNwZWN0b3JDb250cm9scyA9IF93cCRlZGl0b3IuSW5zcGVjdG9yQ29udHJvbHMsXG4gICAgQmxvY2tBbGlnbm1lbnRUb29sYmFyID0gX3dwJGVkaXRvci5CbG9ja0FsaWdubWVudFRvb2xiYXIsXG4gICAgQmxvY2tDb250cm9scyA9IF93cCRlZGl0b3IuQmxvY2tDb250cm9scztcbnZhciBfd3AkY29tcG9uZW50cyA9IHdwLmNvbXBvbmVudHMsXG4gICAgRGF0ZVRpbWVQaWNrZXIgPSBfd3AkY29tcG9uZW50cy5EYXRlVGltZVBpY2tlcixcbiAgICBQYW5lbEJvZHkgPSBfd3AkY29tcG9uZW50cy5QYW5lbEJvZHksXG4gICAgVGV4dENvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5UZXh0Q29udHJvbDtcbnZhciBGcmFnbWVudCA9IHdwLmVsZW1lbnQuRnJhZ21lbnQ7XG5cbmltcG9ydCB0aW1lYWdvIGZyb20gJ3RpbWVhZ28uanMnO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGJsb2NrLlxuICovXG5leHBvcnQgZGVmYXVsdCByZWdpc3RlckJsb2NrVHlwZSgnYW1wL2FtcC10aW1lYWdvJywge1xuXHR0aXRsZTogX18oJ0FNUCBUaW1lYWdvJyksXG5cdGNhdGVnb3J5OiAnY29tbW9uJyxcblx0aWNvbjogJ2JhY2t1cCcsXG5cdGtleXdvcmRzOiBbX18oJ1RpbWUgZGlmZmVyZW5jZScpLCBfXygnVGltZSBhZ28nKSwgX18oJ0RhdGUnKV0sXG5cblx0YXR0cmlidXRlczoge1xuXHRcdGFsaWduOiB7XG5cdFx0XHR0eXBlOiAnc3RyaW5nJ1xuXHRcdH0sXG5cdFx0Y3V0b2ZmOiB7XG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtdGltZWFnbycsXG5cdFx0XHRhdHRyaWJ1dGU6ICdjdXRvZmYnXG5cdFx0fSxcblx0XHRkYXRlVGltZToge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXRpbWVhZ28nLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0ZXRpbWUnXG5cdFx0fSxcblx0XHRhbXBMYXlvdXQ6IHtcblx0XHRcdGRlZmF1bHQ6ICdmaXhlZC1oZWlnaHQnLFxuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXRpbWVhZ28nLFxuXHRcdFx0YXR0cmlidXRlOiAnbGF5b3V0J1xuXHRcdH0sXG5cdFx0d2lkdGg6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC10aW1lYWdvJyxcblx0XHRcdGF0dHJpYnV0ZTogJ3dpZHRoJ1xuXHRcdH0sXG5cdFx0aGVpZ2h0OiB7XG5cdFx0XHRkZWZhdWx0OiAyMCxcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC10aW1lYWdvJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2hlaWdodCdcblx0XHR9XG5cdH0sXG5cblx0Z2V0RWRpdFdyYXBwZXJQcm9wczogZnVuY3Rpb24gZ2V0RWRpdFdyYXBwZXJQcm9wcyhhdHRyaWJ1dGVzKSB7XG5cdFx0dmFyIGFsaWduID0gYXR0cmlidXRlcy5hbGlnbjtcblxuXHRcdGlmICgnbGVmdCcgPT09IGFsaWduIHx8ICdyaWdodCcgPT09IGFsaWduIHx8ICdjZW50ZXInID09PSBhbGlnbikge1xuXHRcdFx0cmV0dXJuIHsgJ2RhdGEtYWxpZ24nOiBhbGlnbiB9O1xuXHRcdH1cblx0fSxcblx0ZWRpdDogZnVuY3Rpb24gZWRpdChwcm9wcykge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gcHJvcHMuYXR0cmlidXRlcyxcblx0XHQgICAgc2V0QXR0cmlidXRlcyA9IHByb3BzLnNldEF0dHJpYnV0ZXM7XG5cdFx0dmFyIGFsaWduID0gYXR0cmlidXRlcy5hbGlnbixcblx0XHQgICAgY3V0b2ZmID0gYXR0cmlidXRlcy5jdXRvZmY7XG5cblx0XHR2YXIgdGltZUFnbyA9IHZvaWQgMDtcblx0XHRpZiAoYXR0cmlidXRlcy5kYXRlVGltZSkge1xuXHRcdFx0aWYgKGF0dHJpYnV0ZXMuY3V0b2ZmICYmIHBhcnNlSW50KGF0dHJpYnV0ZXMuY3V0b2ZmKSA8IE1hdGguYWJzKG1vbWVudChhdHRyaWJ1dGVzLmRhdGVUaW1lKS5kaWZmKG1vbWVudCgpLCAnc2Vjb25kcycpKSkge1xuXHRcdFx0XHR0aW1lQWdvID0gbW9tZW50KGF0dHJpYnV0ZXMuZGF0ZVRpbWUpLmZvcm1hdCgnZGRkZCBEIE1NTU0gSEg6bW0nKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRpbWVBZ28gPSB0aW1lYWdvKCkuZm9ybWF0KGF0dHJpYnV0ZXMuZGF0ZVRpbWUpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aW1lQWdvID0gdGltZWFnbygpLmZvcm1hdChuZXcgRGF0ZSgpKTtcblx0XHRcdHNldEF0dHJpYnV0ZXMoeyBkYXRlVGltZTogbW9tZW50KG1vbWVudCgpLCBtb21lbnQuSVNPXzg2MDEsIHRydWUpLmZvcm1hdCgpIH0pO1xuXHRcdH1cblxuXHRcdHZhciBhbXBMYXlvdXRPcHRpb25zID0gW3sgdmFsdWU6ICcnLCBsYWJlbDogX18oJ1Jlc3BvbnNpdmUnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpeGVkJywgbGFiZWw6IF9fKCdGaXhlZCcsICdhbXAnKSB9LCB7IHZhbHVlOiAnZml4ZWQtaGVpZ2h0JywgbGFiZWw6IF9fKCdGaXhlZCBoZWlnaHQnLCAnYW1wJykgfV07XG5cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0RnJhZ21lbnQsXG5cdFx0XHRudWxsLFxuXHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRJbnNwZWN0b3JDb250cm9scyxcblx0XHRcdFx0eyBrZXk6ICdpbnNwZWN0b3InIH0sXG5cdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0XHRQYW5lbEJvZHksXG5cdFx0XHRcdFx0eyB0aXRsZTogX18oJ0FNUCBUaW1lYWdvIFNldHRpbmdzJykgfSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoRGF0ZVRpbWVQaWNrZXIsIHtcblx0XHRcdFx0XHRcdGxvY2FsZTogJ2VuJyxcblx0XHRcdFx0XHRcdGN1cnJlbnREYXRlOiBhdHRyaWJ1dGVzLmRhdGVUaW1lIHx8IG1vbWVudCgpLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0ZVRpbWU6IG1vbWVudCh2YWx1ZSwgbW9tZW50LklTT184NjAxLCB0cnVlKS5mb3JtYXQoKSB9KTtcblx0XHRcdFx0XHRcdH0gLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdGdldExheW91dENvbnRyb2xzKHByb3BzLCBhbXBMYXlvdXRPcHRpb25zKSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdHR5cGU6ICdudW1iZXInLFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lOiAnYmxvY2tzLWFtcC10aW1lb3V0X19jdXRvZmYnLFxuXHRcdFx0XHRcdFx0bGFiZWw6IF9fKCdDdXRvZmYgKHNlY29uZHMpJyksXG5cdFx0XHRcdFx0XHR2YWx1ZTogY3V0b2ZmICE9PSB1bmRlZmluZWQgPyBjdXRvZmYgOiAnJyxcblx0XHRcdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGN1dG9mZjogdmFsdWUgfSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0KVxuXHRcdFx0KSxcblx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0QmxvY2tDb250cm9scyxcblx0XHRcdFx0eyBrZXk6ICdjb250cm9scycgfSxcblx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KEJsb2NrQWxpZ25tZW50VG9vbGJhciwge1xuXHRcdFx0XHRcdHZhbHVlOiBhbGlnbixcblx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UobmV4dEFsaWduKSB7XG5cdFx0XHRcdFx0XHRzZXRBdHRyaWJ1dGVzKHsgYWxpZ246IG5leHRBbGlnbiB9KTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdGNvbnRyb2xzOiBbJ2xlZnQnLCAnY2VudGVyJywgJ3JpZ2h0J11cblx0XHRcdFx0fSlcblx0XHRcdCksXG5cdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdCd0aW1lJyxcblx0XHRcdFx0eyBrZXk6ICd0aW1lYWdvJywgZGF0ZVRpbWU6IGF0dHJpYnV0ZXMuZGF0ZVRpbWUgfSxcblx0XHRcdFx0dGltZUFnb1xuXHRcdFx0KVxuXHRcdCk7XG5cdH0sXG5cdHNhdmU6IGZ1bmN0aW9uIHNhdmUoX3JlZikge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gX3JlZi5hdHRyaWJ1dGVzO1xuXG5cdFx0dmFyIHRpbWVhZ29Qcm9wcyA9IHtcblx0XHRcdGxheW91dDogJ3Jlc3BvbnNpdmUnLFxuXHRcdFx0Y2xhc3NOYW1lOiAnYWxpZ24nICsgKGF0dHJpYnV0ZXMuYWxpZ24gfHwgJ25vbmUnKSxcblx0XHRcdGRhdGV0aW1lOiBhdHRyaWJ1dGVzLmRhdGVUaW1lLFxuXHRcdFx0bG9jYWxlOiAnZW4nXG5cdFx0fTtcblx0XHRpZiAoYXR0cmlidXRlcy5jdXRvZmYpIHtcblx0XHRcdHRpbWVhZ29Qcm9wcy5jdXRvZmYgPSBhdHRyaWJ1dGVzLmN1dG9mZjtcblx0XHR9XG5cdFx0aWYgKGF0dHJpYnV0ZXMuYW1wTGF5b3V0KSB7XG5cdFx0XHRzd2l0Y2ggKGF0dHJpYnV0ZXMuYW1wTGF5b3V0KSB7XG5cdFx0XHRcdGNhc2UgJ2ZpeGVkLWhlaWdodCc6XG5cdFx0XHRcdFx0aWYgKGF0dHJpYnV0ZXMuaGVpZ2h0KSB7XG5cdFx0XHRcdFx0XHR0aW1lYWdvUHJvcHMuaGVpZ2h0ID0gYXR0cmlidXRlcy5oZWlnaHQ7XG5cdFx0XHRcdFx0XHR0aW1lYWdvUHJvcHMubGF5b3V0ID0gYXR0cmlidXRlcy5hbXBMYXlvdXQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdmaXhlZCc6XG5cdFx0XHRcdFx0aWYgKGF0dHJpYnV0ZXMuaGVpZ2h0ICYmIGF0dHJpYnV0ZXMud2lkdGgpIHtcblx0XHRcdFx0XHRcdHRpbWVhZ29Qcm9wcy5oZWlnaHQgPSBhdHRyaWJ1dGVzLmhlaWdodDtcblx0XHRcdFx0XHRcdHRpbWVhZ29Qcm9wcy53aWR0aCA9IGF0dHJpYnV0ZXMud2lkdGg7XG5cdFx0XHRcdFx0XHR0aW1lYWdvUHJvcHMubGF5b3V0ID0gYXR0cmlidXRlcy5hbXBMYXlvdXQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0J2FtcC10aW1lYWdvJyxcblx0XHRcdHRpbWVhZ29Qcm9wcyxcblx0XHRcdG1vbWVudChhdHRyaWJ1dGVzLmRhdGVUaW1lKS5mb3JtYXQoJ2RkZGQgRCBNTU1NIEhIOm1tJylcblx0XHQpO1xuXHR9XG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2Jsb2Nrcy9hbXAtdGltZWFnby9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4\n");
|
| 94 |
+
|
| 95 |
+
/***/ }),
|
| 96 |
+
/* 5 */
|
| 97 |
+
/***/ (function(module, exports) {
|
| 98 |
+
|
| 99 |
+
eval("!function(t,e){\"object\"==typeof module&&module.exports?(module.exports=e(),module.exports.default=module.exports):t.timeago=e()}(\"undefined\"!=typeof window?window:this,function(){function t(t){return t instanceof Date?t:isNaN(t)?/^\\d+$/.test(t)?new Date(e(t)):(t=(t||\"\").trim().replace(/\\.\\d+/,\"\").replace(/-/,\"/\").replace(/-/,\"/\").replace(/(\\d)T(\\d)/,\"$1 $2\").replace(/Z/,\" UTC\").replace(/([\\+\\-]\\d\\d)\\:?(\\d\\d)/,\" $1$2\"),new Date(t)):new Date(e(t))}function e(t){return parseInt(t)}function n(t,n,r){n=l[n]?n:l[r]?r:\"en\";for(var o=0,i=t<0?1:0,a=t=Math.abs(t);t>=p[o]&&o<h;o++)t/=p[o];return t=e(t),o*=2,t>(0===o?9:1)&&(o+=1),l[n](t,o,a)[i].replace(\"%s\",t)}function r(e,n){return((n=n?t(n):new Date)-t(e))/1e3}function o(t){for(var e=1,n=0,r=Math.abs(t);t>=p[n]&&n<h;n++)t/=p[n],e*=p[n];return r%=e,r=r?e-r:e,Math.ceil(r)}function i(t){return a(t,\"data-timeago\")||a(t,\"datetime\")}function a(t,e){return t.getAttribute?t.getAttribute(e):t.attr?t.attr(e):void 0}function u(t,e){return t.setAttribute?t.setAttribute(m,e):t.attr?t.attr(m,e):void 0}function c(t,e){this.nowDate=t,this.defaultLocale=e||\"en\"}function d(t,e){return new c(t,e)}var f=\"second_minute_hour_day_week_month_year\".split(\"_\"),s=\"秒_分钟_小时_天_周_月_年\".split(\"_\"),l={en:function(t,e){if(0===e)return[\"just now\",\"right now\"];var n=f[parseInt(e/2)];return t>1&&(n+=\"s\"),[t+\" \"+n+\" ago\",\"in \"+t+\" \"+n]},zh_CN:function(t,e){if(0===e)return[\"刚刚\",\"片刻后\"];var n=s[parseInt(e/2)];return[t+n+\"前\",t+n+\"后\"]}},p=[60,60,24,7,365/7/12,12],h=6,m=\"data-tid\",w={};return c.prototype.doRender=function(t,e,i){var a,c=r(e,this.nowDate),d=this;t.innerHTML=n(c,i,this.defaultLocale),w[a=setTimeout(function(){d.doRender(t,e,i),delete w[a]},Math.min(1e3*o(c),2147483647))]=0,u(t,a)},c.prototype.format=function(t,e){return n(r(t,this.nowDate),e,this.defaultLocale)},c.prototype.render=function(t,e){void 0===t.length&&(t=[t]);for(var n=0,r=t.length;n<r;n++)this.doRender(t[n],i(t[n]),e)},c.prototype.setLocale=function(t){this.defaultLocale=t},d.register=function(t,e){l[t]=e},d.cancel=function(t){var e;if(t)(e=a(t,m))&&(clearTimeout(e),delete w[e]);else{for(e in w)clearTimeout(e);w={}}},d});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy90aW1lYWdvLmpzL2Rpc3QvdGltZWFnby5taW4uanM/ZjAwZCJdLCJzb3VyY2VzQ29udGVudCI6WyIhZnVuY3Rpb24odCxlKXtcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlJiZtb2R1bGUuZXhwb3J0cz8obW9kdWxlLmV4cG9ydHM9ZSgpLG1vZHVsZS5leHBvcnRzLmRlZmF1bHQ9bW9kdWxlLmV4cG9ydHMpOnQudGltZWFnbz1lKCl9KFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3c/d2luZG93OnRoaXMsZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3JldHVybiB0IGluc3RhbmNlb2YgRGF0ZT90OmlzTmFOKHQpPy9eXFxkKyQvLnRlc3QodCk/bmV3IERhdGUoZSh0KSk6KHQ9KHR8fFwiXCIpLnRyaW0oKS5yZXBsYWNlKC9cXC5cXGQrLyxcIlwiKS5yZXBsYWNlKC8tLyxcIi9cIikucmVwbGFjZSgvLS8sXCIvXCIpLnJlcGxhY2UoLyhcXGQpVChcXGQpLyxcIiQxICQyXCIpLnJlcGxhY2UoL1ovLFwiIFVUQ1wiKS5yZXBsYWNlKC8oW1xcK1xcLV1cXGRcXGQpXFw6PyhcXGRcXGQpLyxcIiAkMSQyXCIpLG5ldyBEYXRlKHQpKTpuZXcgRGF0ZShlKHQpKX1mdW5jdGlvbiBlKHQpe3JldHVybiBwYXJzZUludCh0KX1mdW5jdGlvbiBuKHQsbixyKXtuPWxbbl0/bjpsW3JdP3I6XCJlblwiO2Zvcih2YXIgbz0wLGk9dDwwPzE6MCxhPXQ9TWF0aC5hYnModCk7dD49cFtvXSYmbzxoO28rKyl0Lz1wW29dO3JldHVybiB0PWUodCksbyo9Mix0PigwPT09bz85OjEpJiYobys9MSksbFtuXSh0LG8sYSlbaV0ucmVwbGFjZShcIiVzXCIsdCl9ZnVuY3Rpb24gcihlLG4pe3JldHVybigobj1uP3Qobik6bmV3IERhdGUpLXQoZSkpLzFlM31mdW5jdGlvbiBvKHQpe2Zvcih2YXIgZT0xLG49MCxyPU1hdGguYWJzKHQpO3Q+PXBbbl0mJm48aDtuKyspdC89cFtuXSxlKj1wW25dO3JldHVybiByJT1lLHI9cj9lLXI6ZSxNYXRoLmNlaWwocil9ZnVuY3Rpb24gaSh0KXtyZXR1cm4gYSh0LFwiZGF0YS10aW1lYWdvXCIpfHxhKHQsXCJkYXRldGltZVwiKX1mdW5jdGlvbiBhKHQsZSl7cmV0dXJuIHQuZ2V0QXR0cmlidXRlP3QuZ2V0QXR0cmlidXRlKGUpOnQuYXR0cj90LmF0dHIoZSk6dm9pZCAwfWZ1bmN0aW9uIHUodCxlKXtyZXR1cm4gdC5zZXRBdHRyaWJ1dGU/dC5zZXRBdHRyaWJ1dGUobSxlKTp0LmF0dHI/dC5hdHRyKG0sZSk6dm9pZCAwfWZ1bmN0aW9uIGModCxlKXt0aGlzLm5vd0RhdGU9dCx0aGlzLmRlZmF1bHRMb2NhbGU9ZXx8XCJlblwifWZ1bmN0aW9uIGQodCxlKXtyZXR1cm4gbmV3IGModCxlKX12YXIgZj1cInNlY29uZF9taW51dGVfaG91cl9kYXlfd2Vla19tb250aF95ZWFyXCIuc3BsaXQoXCJfXCIpLHM9XCLnp5Jf5YiG6ZKfX+Wwj+aXtl/lpKlf5ZGoX+aciF/lubRcIi5zcGxpdChcIl9cIiksbD17ZW46ZnVuY3Rpb24odCxlKXtpZigwPT09ZSlyZXR1cm5bXCJqdXN0IG5vd1wiLFwicmlnaHQgbm93XCJdO3ZhciBuPWZbcGFyc2VJbnQoZS8yKV07cmV0dXJuIHQ+MSYmKG4rPVwic1wiKSxbdCtcIiBcIituK1wiIGFnb1wiLFwiaW4gXCIrdCtcIiBcIituXX0semhfQ046ZnVuY3Rpb24odCxlKXtpZigwPT09ZSlyZXR1cm5bXCLliJrliJpcIixcIueJh+WIu+WQjlwiXTt2YXIgbj1zW3BhcnNlSW50KGUvMildO3JldHVyblt0K24rXCLliY1cIix0K24rXCLlkI5cIl19fSxwPVs2MCw2MCwyNCw3LDM2NS83LzEyLDEyXSxoPTYsbT1cImRhdGEtdGlkXCIsdz17fTtyZXR1cm4gYy5wcm90b3R5cGUuZG9SZW5kZXI9ZnVuY3Rpb24odCxlLGkpe3ZhciBhLGM9cihlLHRoaXMubm93RGF0ZSksZD10aGlzO3QuaW5uZXJIVE1MPW4oYyxpLHRoaXMuZGVmYXVsdExvY2FsZSksd1thPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtkLmRvUmVuZGVyKHQsZSxpKSxkZWxldGUgd1thXX0sTWF0aC5taW4oMWUzKm8oYyksMjE0NzQ4MzY0NykpXT0wLHUodCxhKX0sYy5wcm90b3R5cGUuZm9ybWF0PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG4ocih0LHRoaXMubm93RGF0ZSksZSx0aGlzLmRlZmF1bHRMb2NhbGUpfSxjLnByb3RvdHlwZS5yZW5kZXI9ZnVuY3Rpb24odCxlKXt2b2lkIDA9PT10Lmxlbmd0aCYmKHQ9W3RdKTtmb3IodmFyIG49MCxyPXQubGVuZ3RoO248cjtuKyspdGhpcy5kb1JlbmRlcih0W25dLGkodFtuXSksZSl9LGMucHJvdG90eXBlLnNldExvY2FsZT1mdW5jdGlvbih0KXt0aGlzLmRlZmF1bHRMb2NhbGU9dH0sZC5yZWdpc3Rlcj1mdW5jdGlvbih0LGUpe2xbdF09ZX0sZC5jYW5jZWw9ZnVuY3Rpb24odCl7dmFyIGU7aWYodCkoZT1hKHQsbSkpJiYoY2xlYXJUaW1lb3V0KGUpLGRlbGV0ZSB3W2VdKTtlbHNle2ZvcihlIGluIHcpY2xlYXJUaW1lb3V0KGUpO3c9e319fSxkfSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdGltZWFnby5qcy9kaXN0L3RpbWVhZ28ubWluLmpzXG4vLyBtb2R1bGUgaWQgPSA1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5\n");
|
| 100 |
+
|
| 101 |
+
/***/ }),
|
| 102 |
+
/* 6 */
|
| 103 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 104 |
+
|
| 105 |
+
"use strict";
|
| 106 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar InspectorControls = wp.editor.InspectorControls;\nvar Fragment = wp.element.Fragment;\nvar _wp$components = wp.components,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl,\n Placeholder = _wp$components.Placeholder,\n ToggleControl = _wp$components.ToggleControl;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-o2-player', {\n\ttitle: __('AMP O2 Player', 'amp'),\n\tcategory: 'embed',\n\ticon: 'embed-generic',\n\tkeywords: [__('Embed', 'amp'), __('AOL O2Player', 'amp')],\n\n\t// @todo Add other useful macro toggles, e.g. showing relevant content.\n\tattributes: {\n\t\tdataPid: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-o2-player',\n\t\t\tattribute: 'data-pid'\n\t\t},\n\t\tdataVid: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-o2-player',\n\t\t\tattribute: 'data-vid'\n\t\t},\n\t\tdataBcid: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-o2-player',\n\t\t\tattribute: 'data-bcid'\n\t\t},\n\t\tdataBid: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-o2-player',\n\t\t\tattribute: 'data-bid'\n\t\t},\n\t\tautoPlay: {\n\t\t\tdefault: false\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'responsive',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-o2-player',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\tdefault: 600,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-o2-player',\n\t\t\tattribute: 'width'\n\t\t},\n\t\theight: {\n\t\t\tdefault: 400,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-o2-player',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar autoPlay = attributes.autoPlay,\n\t\t dataPid = attributes.dataPid,\n\t\t dataVid = attributes.dataVid,\n\t\t dataBcid = attributes.dataBcid,\n\t\t dataBid = attributes.dataBid;\n\n\t\tvar ampLayoutOptions = [{ value: 'responsive', label: __('Responsive', 'amp') }, { value: 'fixed-height', label: __('Fixed height', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }, { value: 'fill', label: __('Fill', 'amp') }, { value: 'flex-item', label: __('Flex-item', 'amp') }, { value: 'nodisplay', label: __('No Display', 'amp') }];\n\t\tvar url = false;\n\t\tif (dataPid && (dataBcid || dataVid)) {\n\t\t\turl = 'https://delivery.vidible.tv/htmlembed/pid=' + dataPid + '/';\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('O2 Player Settings', 'amp') },\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Player ID (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataPid,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPid: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Buyer Company ID (either buyer or video ID is required)', 'amp'),\n\t\t\t\t\t\tvalue: dataBcid,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataBcid: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Video ID (either buyer or video ID is required)', 'amp'),\n\t\t\t\t\t\tvalue: dataVid,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataVid: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Playlist ID', 'amp'),\n\t\t\t\t\t\tvalue: dataBid,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataBid: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(ToggleControl, {\n\t\t\t\t\t\tlabel: __('Autoplay', 'amp'),\n\t\t\t\t\t\tchecked: autoPlay,\n\t\t\t\t\t\tonChange: function onChange() {\n\t\t\t\t\t\t\treturn setAttributes({ autoPlay: !autoPlay });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions)\n\t\t\t\t)\n\t\t\t),\n\t\t\turl && Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"b\" /* getMediaPlaceholder */])(__('O2 Player', 'amp'), url),\n\t\t\t!url && wp.element.createElement(\n\t\t\t\tPlaceholder,\n\t\t\t\t{ label: __('O2 Player', 'amp') },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\t'p',\n\t\t\t\t\tnull,\n\t\t\t\t\t__('Add required data to use the block.', 'amp')\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\n\t\tvar o2Props = {\n\t\t\tlayout: attributes.ampLayout,\n\t\t\theight: attributes.height,\n\t\t\t'data-pid': attributes.dataPid\n\t\t};\n\t\tif ('fixed-height' !== attributes.ampLayout && attributes.width) {\n\t\t\to2Props.width = attributes.width;\n\t\t}\n\t\tif (!attributes.autoPlay) {\n\t\t\to2Props['data-macros'] = 'm.playback=click';\n\t\t}\n\t\tif (attributes.dataVid) {\n\t\t\to2Props['data-vid'] = attributes.dataVid;\n\t\t} else if (attributes.dataBcid) {\n\t\t\to2Props['data-bcid'] = attributes.dataBcid;\n\t\t}\n\t\tif (attributes.dataBid) {\n\t\t\to2Props['data-bid'] = attributes.dataBid;\n\t\t}\n\t\treturn wp.element.createElement('amp-o2-player', o2Props);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy9hbXAtbzItcGxheWVyL2luZGV4LmpzPzIwMGYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBIZWxwZXIgbWV0aG9kcyBmb3IgYmxvY2tzLlxuICovXG5pbXBvcnQgeyBnZXRMYXlvdXRDb250cm9scywgZ2V0TWVkaWFQbGFjZWhvbGRlciB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuLyoqXG4gKiBJbnRlcm5hbCBibG9jayBsaWJyYXJpZXMuXG4gKi9cbnZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7XG52YXIgSW5zcGVjdG9yQ29udHJvbHMgPSB3cC5lZGl0b3IuSW5zcGVjdG9yQ29udHJvbHM7XG52YXIgRnJhZ21lbnQgPSB3cC5lbGVtZW50LkZyYWdtZW50O1xudmFyIF93cCRjb21wb25lbnRzID0gd3AuY29tcG9uZW50cyxcbiAgICBQYW5lbEJvZHkgPSBfd3AkY29tcG9uZW50cy5QYW5lbEJvZHksXG4gICAgVGV4dENvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5UZXh0Q29udHJvbCxcbiAgICBQbGFjZWhvbGRlciA9IF93cCRjb21wb25lbnRzLlBsYWNlaG9sZGVyLFxuICAgIFRvZ2dsZUNvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5Ub2dnbGVDb250cm9sO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGJsb2NrLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IHJlZ2lzdGVyQmxvY2tUeXBlKCdhbXAvYW1wLW8yLXBsYXllcicsIHtcblx0dGl0bGU6IF9fKCdBTVAgTzIgUGxheWVyJywgJ2FtcCcpLFxuXHRjYXRlZ29yeTogJ2VtYmVkJyxcblx0aWNvbjogJ2VtYmVkLWdlbmVyaWMnLFxuXHRrZXl3b3JkczogW19fKCdFbWJlZCcsICdhbXAnKSwgX18oJ0FPTCBPMlBsYXllcicsICdhbXAnKV0sXG5cblx0Ly8gQHRvZG8gQWRkIG90aGVyIHVzZWZ1bCBtYWNybyB0b2dnbGVzLCBlLmcuIHNob3dpbmcgcmVsZXZhbnQgY29udGVudC5cblx0YXR0cmlidXRlczoge1xuXHRcdGRhdGFQaWQ6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1vMi1wbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1waWQnXG5cdFx0fSxcblx0XHRkYXRhVmlkOiB7XG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtbzItcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtdmlkJ1xuXHRcdH0sXG5cdFx0ZGF0YUJjaWQ6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1vMi1wbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1iY2lkJ1xuXHRcdH0sXG5cdFx0ZGF0YUJpZDoge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLW8yLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLWJpZCdcblx0XHR9LFxuXHRcdGF1dG9QbGF5OiB7XG5cdFx0XHRkZWZhdWx0OiBmYWxzZVxuXHRcdH0sXG5cdFx0YW1wTGF5b3V0OiB7XG5cdFx0XHRkZWZhdWx0OiAncmVzcG9uc2l2ZScsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtbzItcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2xheW91dCdcblx0XHR9LFxuXHRcdHdpZHRoOiB7XG5cdFx0XHRkZWZhdWx0OiA2MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtbzItcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ3dpZHRoJ1xuXHRcdH0sXG5cdFx0aGVpZ2h0OiB7XG5cdFx0XHRkZWZhdWx0OiA0MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtbzItcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2hlaWdodCdcblx0XHR9XG5cdH0sXG5cblx0ZWRpdDogZnVuY3Rpb24gZWRpdChwcm9wcykge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gcHJvcHMuYXR0cmlidXRlcyxcblx0XHQgICAgc2V0QXR0cmlidXRlcyA9IHByb3BzLnNldEF0dHJpYnV0ZXM7XG5cdFx0dmFyIGF1dG9QbGF5ID0gYXR0cmlidXRlcy5hdXRvUGxheSxcblx0XHQgICAgZGF0YVBpZCA9IGF0dHJpYnV0ZXMuZGF0YVBpZCxcblx0XHQgICAgZGF0YVZpZCA9IGF0dHJpYnV0ZXMuZGF0YVZpZCxcblx0XHQgICAgZGF0YUJjaWQgPSBhdHRyaWJ1dGVzLmRhdGFCY2lkLFxuXHRcdCAgICBkYXRhQmlkID0gYXR0cmlidXRlcy5kYXRhQmlkO1xuXG5cdFx0dmFyIGFtcExheW91dE9wdGlvbnMgPSBbeyB2YWx1ZTogJ3Jlc3BvbnNpdmUnLCBsYWJlbDogX18oJ1Jlc3BvbnNpdmUnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpeGVkLWhlaWdodCcsIGxhYmVsOiBfXygnRml4ZWQgaGVpZ2h0JywgJ2FtcCcpIH0sIHsgdmFsdWU6ICdmaXhlZCcsIGxhYmVsOiBfXygnRml4ZWQnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpbGwnLCBsYWJlbDogX18oJ0ZpbGwnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZsZXgtaXRlbScsIGxhYmVsOiBfXygnRmxleC1pdGVtJywgJ2FtcCcpIH0sIHsgdmFsdWU6ICdub2Rpc3BsYXknLCBsYWJlbDogX18oJ05vIERpc3BsYXknLCAnYW1wJykgfV07XG5cdFx0dmFyIHVybCA9IGZhbHNlO1xuXHRcdGlmIChkYXRhUGlkICYmIChkYXRhQmNpZCB8fCBkYXRhVmlkKSkge1xuXHRcdFx0dXJsID0gJ2h0dHBzOi8vZGVsaXZlcnkudmlkaWJsZS50di9odG1sZW1iZWQvcGlkPScgKyBkYXRhUGlkICsgJy8nO1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0RnJhZ21lbnQsXG5cdFx0XHRudWxsLFxuXHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRJbnNwZWN0b3JDb250cm9scyxcblx0XHRcdFx0eyBrZXk6ICdpbnNwZWN0b3InIH0sXG5cdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0XHRQYW5lbEJvZHksXG5cdFx0XHRcdFx0eyB0aXRsZTogX18oJ08yIFBsYXllciBTZXR0aW5ncycsICdhbXAnKSB9LFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUZXh0Q29udHJvbCwge1xuXHRcdFx0XHRcdFx0bGFiZWw6IF9fKCdQbGF5ZXIgSUQgKHJlcXVpcmVkKScsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhUGlkLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YVBpZDogdmFsdWUgfSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ0J1eWVyIENvbXBhbnkgSUQgKGVpdGhlciBidXllciBvciB2aWRlbyBJRCBpcyByZXF1aXJlZCknLCAnYW1wJyksXG5cdFx0XHRcdFx0XHR2YWx1ZTogZGF0YUJjaWQsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhQmNpZDogdmFsdWUgfSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ1ZpZGVvIElEIChlaXRoZXIgYnV5ZXIgb3IgdmlkZW8gSUQgaXMgcmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFWaWQsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhVmlkOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnUGxheWxpc3QgSUQnLCAnYW1wJyksXG5cdFx0XHRcdFx0XHR2YWx1ZTogZGF0YUJpZCxcblx0XHRcdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGRhdGFCaWQ6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUb2dnbGVDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ0F1dG9wbGF5JywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0Y2hlY2tlZDogYXV0b1BsYXksXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UoKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgYXV0b1BsYXk6ICFhdXRvUGxheSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRnZXRMYXlvdXRDb250cm9scyhwcm9wcywgYW1wTGF5b3V0T3B0aW9ucylcblx0XHRcdFx0KVxuXHRcdFx0KSxcblx0XHRcdHVybCAmJiBnZXRNZWRpYVBsYWNlaG9sZGVyKF9fKCdPMiBQbGF5ZXInLCAnYW1wJyksIHVybCksXG5cdFx0XHQhdXJsICYmIHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0UGxhY2Vob2xkZXIsXG5cdFx0XHRcdHsgbGFiZWw6IF9fKCdPMiBQbGF5ZXInLCAnYW1wJykgfSxcblx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRcdCdwJyxcblx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdF9fKCdBZGQgcmVxdWlyZWQgZGF0YSB0byB1c2UgdGhlIGJsb2NrLicsICdhbXAnKVxuXHRcdFx0XHQpXG5cdFx0XHQpXG5cdFx0KTtcblx0fSxcblx0c2F2ZTogZnVuY3Rpb24gc2F2ZShfcmVmKSB7XG5cdFx0dmFyIGF0dHJpYnV0ZXMgPSBfcmVmLmF0dHJpYnV0ZXM7XG5cblx0XHR2YXIgbzJQcm9wcyA9IHtcblx0XHRcdGxheW91dDogYXR0cmlidXRlcy5hbXBMYXlvdXQsXG5cdFx0XHRoZWlnaHQ6IGF0dHJpYnV0ZXMuaGVpZ2h0LFxuXHRcdFx0J2RhdGEtcGlkJzogYXR0cmlidXRlcy5kYXRhUGlkXG5cdFx0fTtcblx0XHRpZiAoJ2ZpeGVkLWhlaWdodCcgIT09IGF0dHJpYnV0ZXMuYW1wTGF5b3V0ICYmIGF0dHJpYnV0ZXMud2lkdGgpIHtcblx0XHRcdG8yUHJvcHMud2lkdGggPSBhdHRyaWJ1dGVzLndpZHRoO1xuXHRcdH1cblx0XHRpZiAoIWF0dHJpYnV0ZXMuYXV0b1BsYXkpIHtcblx0XHRcdG8yUHJvcHNbJ2RhdGEtbWFjcm9zJ10gPSAnbS5wbGF5YmFjaz1jbGljayc7XG5cdFx0fVxuXHRcdGlmIChhdHRyaWJ1dGVzLmRhdGFWaWQpIHtcblx0XHRcdG8yUHJvcHNbJ2RhdGEtdmlkJ10gPSBhdHRyaWJ1dGVzLmRhdGFWaWQ7XG5cdFx0fSBlbHNlIGlmIChhdHRyaWJ1dGVzLmRhdGFCY2lkKSB7XG5cdFx0XHRvMlByb3BzWydkYXRhLWJjaWQnXSA9IGF0dHJpYnV0ZXMuZGF0YUJjaWQ7XG5cdFx0fVxuXHRcdGlmIChhdHRyaWJ1dGVzLmRhdGFCaWQpIHtcblx0XHRcdG8yUHJvcHNbJ2RhdGEtYmlkJ10gPSBhdHRyaWJ1dGVzLmRhdGFCaWQ7XG5cdFx0fVxuXHRcdHJldHVybiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoJ2FtcC1vMi1wbGF5ZXInLCBvMlByb3BzKTtcblx0fVxufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ibG9ja3MvYW1wLW8yLXBsYXllci9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6\n");
|
| 107 |
+
|
| 108 |
+
/***/ }),
|
| 109 |
+
/* 7 */
|
| 110 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 111 |
+
|
| 112 |
+
"use strict";
|
| 113 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar InspectorControls = wp.editor.InspectorControls;\nvar Fragment = wp.element.Fragment;\nvar _wp$components = wp.components,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl,\n SelectControl = _wp$components.SelectControl,\n Placeholder = _wp$components.Placeholder;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-ooyala-player', {\n\ttitle: __('AMP Ooyala Player', 'amp'),\n\tdescription: __('Displays an Ooyala video.', 'amp'),\n\tcategory: 'embed',\n\ticon: 'embed-generic',\n\tkeywords: [__('Embed', 'amp'), __('Ooyala video', 'amp')],\n\n\t// @todo Add data-config attribute?\n\tattributes: {\n\t\tdataEmbedCode: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ooyala-player',\n\t\t\tattribute: 'data-embedcode'\n\t\t},\n\t\tdataPlayerId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ooyala-player',\n\t\t\tattribute: 'data-playerid'\n\t\t},\n\t\tdataPcode: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ooyala-player',\n\t\t\tattribute: 'data-pcode'\n\t\t},\n\t\tdataPlayerVersion: {\n\t\t\tdefault: 'v3',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ooyala-player',\n\t\t\tattribute: 'data-playerversion'\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'responsive',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ooyala-player',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\tdefault: 600,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ooyala-player',\n\t\t\tattribute: 'width'\n\t\t},\n\t\theight: {\n\t\t\tdefault: 400,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ooyala-player',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar dataEmbedCode = attributes.dataEmbedCode,\n\t\t dataPlayerId = attributes.dataPlayerId,\n\t\t dataPcode = attributes.dataPcode,\n\t\t dataPlayerVersion = attributes.dataPlayerVersion;\n\n\t\tvar ampLayoutOptions = [{ value: 'responsive', label: __('Responsive', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }, { value: 'fill', label: __('Fill', 'amp') }, { value: 'flex-item', label: __('Flex-item', 'amp') }];\n\t\tvar url = false;\n\t\tif (dataEmbedCode && dataPlayerId && dataPcode) {\n\t\t\turl = 'http://cf.c.ooyala.com/' + dataEmbedCode;\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('Ooyala settings', 'amp') },\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Video embed code (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataEmbedCode,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataEmbedCode: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Player ID (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataPlayerId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPlayerId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Provider code for the account (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataPcode,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPcode: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(SelectControl, {\n\t\t\t\t\t\tlabel: __('Player version', 'amp'),\n\t\t\t\t\t\tvalue: dataPlayerVersion,\n\t\t\t\t\t\toptions: [{ value: 'v3', label: __('V3', 'amp') }, { value: 'v4', label: __('V4', 'amp') }],\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPlayerVersion: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions)\n\t\t\t\t)\n\t\t\t),\n\t\t\turl && Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"b\" /* getMediaPlaceholder */])(__('Ooyala Player', 'amp'), url),\n\t\t\t!url && wp.element.createElement(\n\t\t\t\tPlaceholder,\n\t\t\t\t{ label: __('Ooyala Player', 'amp') },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\t'p',\n\t\t\t\t\tnull,\n\t\t\t\t\t__('Add required data to use the block.', 'amp')\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\t\tvar dataEmbedCode = attributes.dataEmbedCode,\n\t\t dataPlayerId = attributes.dataPlayerId,\n\t\t dataPcode = attributes.dataPcode,\n\t\t dataPlayerVersion = attributes.dataPlayerVersion,\n\t\t ampLayout = attributes.ampLayout,\n\t\t height = attributes.height,\n\t\t width = attributes.width;\n\n\n\t\tvar ooyalaProps = {\n\t\t\tlayout: ampLayout,\n\t\t\theight: height,\n\t\t\t'data-embedcode': dataEmbedCode,\n\t\t\t'data-playerid': dataPlayerId,\n\t\t\t'data-pcode': dataPcode,\n\t\t\t'data-playerversion': dataPlayerVersion\n\t\t};\n\t\tif ('fixed-height' !== ampLayout && width) {\n\t\t\tooyalaProps.width = width;\n\t\t}\n\t\treturn wp.element.createElement('amp-ooyala-player', ooyalaProps);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy9hbXAtb295YWxhLXBsYXllci9pbmRleC5qcz81NmRlIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSGVscGVyIG1ldGhvZHMgZm9yIGJsb2Nrcy5cbiAqL1xuaW1wb3J0IHsgZ2V0TGF5b3V0Q29udHJvbHMsIGdldE1lZGlhUGxhY2Vob2xkZXIgfSBmcm9tICcuLi91dGlscy5qcyc7XG5cbi8qKlxuICogSW50ZXJuYWwgYmxvY2sgbGlicmFyaWVzLlxuICovXG52YXIgX18gPSB3cC5pMThuLl9fO1xudmFyIHJlZ2lzdGVyQmxvY2tUeXBlID0gd3AuYmxvY2tzLnJlZ2lzdGVyQmxvY2tUeXBlO1xudmFyIEluc3BlY3RvckNvbnRyb2xzID0gd3AuZWRpdG9yLkluc3BlY3RvckNvbnRyb2xzO1xudmFyIEZyYWdtZW50ID0gd3AuZWxlbWVudC5GcmFnbWVudDtcbnZhciBfd3AkY29tcG9uZW50cyA9IHdwLmNvbXBvbmVudHMsXG4gICAgUGFuZWxCb2R5ID0gX3dwJGNvbXBvbmVudHMuUGFuZWxCb2R5LFxuICAgIFRleHRDb250cm9sID0gX3dwJGNvbXBvbmVudHMuVGV4dENvbnRyb2wsXG4gICAgU2VsZWN0Q29udHJvbCA9IF93cCRjb21wb25lbnRzLlNlbGVjdENvbnRyb2wsXG4gICAgUGxhY2Vob2xkZXIgPSBfd3AkY29tcG9uZW50cy5QbGFjZWhvbGRlcjtcblxuLyoqXG4gKiBSZWdpc3RlciBibG9jay5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCByZWdpc3RlckJsb2NrVHlwZSgnYW1wL2FtcC1vb3lhbGEtcGxheWVyJywge1xuXHR0aXRsZTogX18oJ0FNUCBPb3lhbGEgUGxheWVyJywgJ2FtcCcpLFxuXHRkZXNjcmlwdGlvbjogX18oJ0Rpc3BsYXlzIGFuIE9veWFsYSB2aWRlby4nLCAnYW1wJyksXG5cdGNhdGVnb3J5OiAnZW1iZWQnLFxuXHRpY29uOiAnZW1iZWQtZ2VuZXJpYycsXG5cdGtleXdvcmRzOiBbX18oJ0VtYmVkJywgJ2FtcCcpLCBfXygnT295YWxhIHZpZGVvJywgJ2FtcCcpXSxcblxuXHQvLyBAdG9kbyBBZGQgZGF0YS1jb25maWcgYXR0cmlidXRlP1xuXHRhdHRyaWJ1dGVzOiB7XG5cdFx0ZGF0YUVtYmVkQ29kZToge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLW9veWFsYS1wbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1lbWJlZGNvZGUnXG5cdFx0fSxcblx0XHRkYXRhUGxheWVySWQ6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1vb3lhbGEtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtcGxheWVyaWQnXG5cdFx0fSxcblx0XHRkYXRhUGNvZGU6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1vb3lhbGEtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtcGNvZGUnXG5cdFx0fSxcblx0XHRkYXRhUGxheWVyVmVyc2lvbjoge1xuXHRcdFx0ZGVmYXVsdDogJ3YzJyxcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1vb3lhbGEtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtcGxheWVydmVyc2lvbidcblx0XHR9LFxuXHRcdGFtcExheW91dDoge1xuXHRcdFx0ZGVmYXVsdDogJ3Jlc3BvbnNpdmUnLFxuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLW9veWFsYS1wbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnbGF5b3V0J1xuXHRcdH0sXG5cdFx0d2lkdGg6IHtcblx0XHRcdGRlZmF1bHQ6IDYwMCxcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1vb3lhbGEtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ3dpZHRoJ1xuXHRcdH0sXG5cdFx0aGVpZ2h0OiB7XG5cdFx0XHRkZWZhdWx0OiA0MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtb295YWxhLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdoZWlnaHQnXG5cdFx0fVxuXHR9LFxuXG5cdGVkaXQ6IGZ1bmN0aW9uIGVkaXQocHJvcHMpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IHByb3BzLmF0dHJpYnV0ZXMsXG5cdFx0ICAgIHNldEF0dHJpYnV0ZXMgPSBwcm9wcy5zZXRBdHRyaWJ1dGVzO1xuXHRcdHZhciBkYXRhRW1iZWRDb2RlID0gYXR0cmlidXRlcy5kYXRhRW1iZWRDb2RlLFxuXHRcdCAgICBkYXRhUGxheWVySWQgPSBhdHRyaWJ1dGVzLmRhdGFQbGF5ZXJJZCxcblx0XHQgICAgZGF0YVBjb2RlID0gYXR0cmlidXRlcy5kYXRhUGNvZGUsXG5cdFx0ICAgIGRhdGFQbGF5ZXJWZXJzaW9uID0gYXR0cmlidXRlcy5kYXRhUGxheWVyVmVyc2lvbjtcblxuXHRcdHZhciBhbXBMYXlvdXRPcHRpb25zID0gW3sgdmFsdWU6ICdyZXNwb25zaXZlJywgbGFiZWw6IF9fKCdSZXNwb25zaXZlJywgJ2FtcCcpIH0sIHsgdmFsdWU6ICdmaXhlZCcsIGxhYmVsOiBfXygnRml4ZWQnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpbGwnLCBsYWJlbDogX18oJ0ZpbGwnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZsZXgtaXRlbScsIGxhYmVsOiBfXygnRmxleC1pdGVtJywgJ2FtcCcpIH1dO1xuXHRcdHZhciB1cmwgPSBmYWxzZTtcblx0XHRpZiAoZGF0YUVtYmVkQ29kZSAmJiBkYXRhUGxheWVySWQgJiYgZGF0YVBjb2RlKSB7XG5cdFx0XHR1cmwgPSAnaHR0cDovL2NmLmMub295YWxhLmNvbS8nICsgZGF0YUVtYmVkQ29kZTtcblx0XHR9XG5cdFx0cmV0dXJuIHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdEZyYWdtZW50LFxuXHRcdFx0bnVsbCxcblx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0SW5zcGVjdG9yQ29udHJvbHMsXG5cdFx0XHRcdHsga2V5OiAnaW5zcGVjdG9yJyB9LFxuXHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0UGFuZWxCb2R5LFxuXHRcdFx0XHRcdHsgdGl0bGU6IF9fKCdPb3lhbGEgc2V0dGluZ3MnLCAnYW1wJykgfSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnVmlkZW8gZW1iZWQgY29kZSAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFFbWJlZENvZGUsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhRW1iZWRDb2RlOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnUGxheWVyIElEIChyZXF1aXJlZCknLCAnYW1wJyksXG5cdFx0XHRcdFx0XHR2YWx1ZTogZGF0YVBsYXllcklkLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YVBsYXllcklkOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnUHJvdmlkZXIgY29kZSBmb3IgdGhlIGFjY291bnQgKHJlcXVpcmVkKScsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhUGNvZGUsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhUGNvZGU6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChTZWxlY3RDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ1BsYXllciB2ZXJzaW9uJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFQbGF5ZXJWZXJzaW9uLFxuXHRcdFx0XHRcdFx0b3B0aW9uczogW3sgdmFsdWU6ICd2MycsIGxhYmVsOiBfXygnVjMnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ3Y0JywgbGFiZWw6IF9fKCdWNCcsICdhbXAnKSB9XSxcblx0XHRcdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGRhdGFQbGF5ZXJWZXJzaW9uOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRnZXRMYXlvdXRDb250cm9scyhwcm9wcywgYW1wTGF5b3V0T3B0aW9ucylcblx0XHRcdFx0KVxuXHRcdFx0KSxcblx0XHRcdHVybCAmJiBnZXRNZWRpYVBsYWNlaG9sZGVyKF9fKCdPb3lhbGEgUGxheWVyJywgJ2FtcCcpLCB1cmwpLFxuXHRcdFx0IXVybCAmJiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFBsYWNlaG9sZGVyLFxuXHRcdFx0XHR7IGxhYmVsOiBfXygnT295YWxhIFBsYXllcicsICdhbXAnKSB9LFxuXHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0J3AnLFxuXHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0X18oJ0FkZCByZXF1aXJlZCBkYXRhIHRvIHVzZSB0aGUgYmxvY2suJywgJ2FtcCcpXG5cdFx0XHRcdClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXHRzYXZlOiBmdW5jdGlvbiBzYXZlKF9yZWYpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IF9yZWYuYXR0cmlidXRlcztcblx0XHR2YXIgZGF0YUVtYmVkQ29kZSA9IGF0dHJpYnV0ZXMuZGF0YUVtYmVkQ29kZSxcblx0XHQgICAgZGF0YVBsYXllcklkID0gYXR0cmlidXRlcy5kYXRhUGxheWVySWQsXG5cdFx0ICAgIGRhdGFQY29kZSA9IGF0dHJpYnV0ZXMuZGF0YVBjb2RlLFxuXHRcdCAgICBkYXRhUGxheWVyVmVyc2lvbiA9IGF0dHJpYnV0ZXMuZGF0YVBsYXllclZlcnNpb24sXG5cdFx0ICAgIGFtcExheW91dCA9IGF0dHJpYnV0ZXMuYW1wTGF5b3V0LFxuXHRcdCAgICBoZWlnaHQgPSBhdHRyaWJ1dGVzLmhlaWdodCxcblx0XHQgICAgd2lkdGggPSBhdHRyaWJ1dGVzLndpZHRoO1xuXG5cblx0XHR2YXIgb295YWxhUHJvcHMgPSB7XG5cdFx0XHRsYXlvdXQ6IGFtcExheW91dCxcblx0XHRcdGhlaWdodDogaGVpZ2h0LFxuXHRcdFx0J2RhdGEtZW1iZWRjb2RlJzogZGF0YUVtYmVkQ29kZSxcblx0XHRcdCdkYXRhLXBsYXllcmlkJzogZGF0YVBsYXllcklkLFxuXHRcdFx0J2RhdGEtcGNvZGUnOiBkYXRhUGNvZGUsXG5cdFx0XHQnZGF0YS1wbGF5ZXJ2ZXJzaW9uJzogZGF0YVBsYXllclZlcnNpb25cblx0XHR9O1xuXHRcdGlmICgnZml4ZWQtaGVpZ2h0JyAhPT0gYW1wTGF5b3V0ICYmIHdpZHRoKSB7XG5cdFx0XHRvb3lhbGFQcm9wcy53aWR0aCA9IHdpZHRoO1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KCdhbXAtb295YWxhLXBsYXllcicsIG9veWFsYVByb3BzKTtcblx0fVxufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ibG9ja3MvYW1wLW9veWFsYS1wbGF5ZXIvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7\n");
|
| 114 |
+
|
| 115 |
+
/***/ }),
|
| 116 |
+
/* 8 */
|
| 117 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 118 |
+
|
| 119 |
+
"use strict";
|
| 120 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar InspectorControls = wp.editor.InspectorControls;\nvar Fragment = wp.element.Fragment;\nvar _wp$components = wp.components,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl,\n Placeholder = _wp$components.Placeholder;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-reach-player', {\n\ttitle: __('AMP Reach Player', 'amp'),\n\tdescription: __('Displays the Reach Player configured in the Beachfront Reach platform.', 'amp'),\n\tcategory: 'embed',\n\ticon: 'embed-generic',\n\tkeywords: [__('Embed', 'amp'), __('Beachfront Reach video', 'amp')],\n\n\tattributes: {\n\t\tdataEmbedId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-reach-player',\n\t\t\tattribute: 'data-embed-id'\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'fixed-height',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-reach-player',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\tdefault: 600,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-reach-player',\n\t\t\tattribute: 'width'\n\t\t},\n\t\theight: {\n\t\t\tdefault: 400,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-reach-player',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar dataEmbedId = attributes.dataEmbedId;\n\n\t\tvar ampLayoutOptions = [{ value: 'responsive', label: __('Responsive', 'amp') }, { value: 'fixed-height', label: __('Fixed Height', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }, { value: 'fill', label: __('Fill', 'amp') }, { value: 'flex-item', label: __('Flex-item', 'amp') }];\n\t\tvar url = false;\n\t\tif (dataEmbedId) {\n\t\t\turl = 'https://media-cdn.beachfrontreach.com/acct_1/video/';\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('Reach settings', 'amp') },\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('The Reach player embed id (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataEmbedId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataEmbedId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions)\n\t\t\t\t)\n\t\t\t),\n\t\t\turl && Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"b\" /* getMediaPlaceholder */])(__('Reach Player', 'amp'), url),\n\t\t\t!url && wp.element.createElement(\n\t\t\t\tPlaceholder,\n\t\t\t\t{ label: __('Reach Player', 'amp') },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\t'p',\n\t\t\t\t\tnull,\n\t\t\t\t\t__('Add Reach player embed ID to use the block.', 'amp')\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\t\tvar dataEmbedId = attributes.dataEmbedId,\n\t\t ampLayout = attributes.ampLayout,\n\t\t height = attributes.height,\n\t\t width = attributes.width;\n\n\n\t\tvar reachProps = {\n\t\t\tlayout: ampLayout,\n\t\t\theight: height,\n\t\t\t'data-embed-id': dataEmbedId\n\t\t};\n\t\tif ('fixed-height' !== ampLayout && width) {\n\t\t\treachProps.width = width;\n\t\t}\n\t\treturn wp.element.createElement('amp-reach-player', reachProps);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy9hbXAtcmVhY2gtcGxheWVyL2luZGV4LmpzPzIwNmIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBIZWxwZXIgbWV0aG9kcyBmb3IgYmxvY2tzLlxuICovXG5pbXBvcnQgeyBnZXRMYXlvdXRDb250cm9scywgZ2V0TWVkaWFQbGFjZWhvbGRlciB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuLyoqXG4gKiBJbnRlcm5hbCBibG9jayBsaWJyYXJpZXMuXG4gKi9cbnZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7XG52YXIgSW5zcGVjdG9yQ29udHJvbHMgPSB3cC5lZGl0b3IuSW5zcGVjdG9yQ29udHJvbHM7XG52YXIgRnJhZ21lbnQgPSB3cC5lbGVtZW50LkZyYWdtZW50O1xudmFyIF93cCRjb21wb25lbnRzID0gd3AuY29tcG9uZW50cyxcbiAgICBQYW5lbEJvZHkgPSBfd3AkY29tcG9uZW50cy5QYW5lbEJvZHksXG4gICAgVGV4dENvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5UZXh0Q29udHJvbCxcbiAgICBQbGFjZWhvbGRlciA9IF93cCRjb21wb25lbnRzLlBsYWNlaG9sZGVyO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGJsb2NrLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IHJlZ2lzdGVyQmxvY2tUeXBlKCdhbXAvYW1wLXJlYWNoLXBsYXllcicsIHtcblx0dGl0bGU6IF9fKCdBTVAgUmVhY2ggUGxheWVyJywgJ2FtcCcpLFxuXHRkZXNjcmlwdGlvbjogX18oJ0Rpc3BsYXlzIHRoZSBSZWFjaCBQbGF5ZXIgY29uZmlndXJlZCBpbiB0aGUgQmVhY2hmcm9udCBSZWFjaCBwbGF0Zm9ybS4nLCAnYW1wJyksXG5cdGNhdGVnb3J5OiAnZW1iZWQnLFxuXHRpY29uOiAnZW1iZWQtZ2VuZXJpYycsXG5cdGtleXdvcmRzOiBbX18oJ0VtYmVkJywgJ2FtcCcpLCBfXygnQmVhY2hmcm9udCBSZWFjaCB2aWRlbycsICdhbXAnKV0sXG5cblx0YXR0cmlidXRlczoge1xuXHRcdGRhdGFFbWJlZElkOiB7XG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtcmVhY2gtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtZW1iZWQtaWQnXG5cdFx0fSxcblx0XHRhbXBMYXlvdXQ6IHtcblx0XHRcdGRlZmF1bHQ6ICdmaXhlZC1oZWlnaHQnLFxuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXJlYWNoLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdsYXlvdXQnXG5cdFx0fSxcblx0XHR3aWR0aDoge1xuXHRcdFx0ZGVmYXVsdDogNjAwLFxuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXJlYWNoLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICd3aWR0aCdcblx0XHR9LFxuXHRcdGhlaWdodDoge1xuXHRcdFx0ZGVmYXVsdDogNDAwLFxuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXJlYWNoLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdoZWlnaHQnXG5cdFx0fVxuXHR9LFxuXG5cdGVkaXQ6IGZ1bmN0aW9uIGVkaXQocHJvcHMpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IHByb3BzLmF0dHJpYnV0ZXMsXG5cdFx0ICAgIHNldEF0dHJpYnV0ZXMgPSBwcm9wcy5zZXRBdHRyaWJ1dGVzO1xuXHRcdHZhciBkYXRhRW1iZWRJZCA9IGF0dHJpYnV0ZXMuZGF0YUVtYmVkSWQ7XG5cblx0XHR2YXIgYW1wTGF5b3V0T3B0aW9ucyA9IFt7IHZhbHVlOiAncmVzcG9uc2l2ZScsIGxhYmVsOiBfXygnUmVzcG9uc2l2ZScsICdhbXAnKSB9LCB7IHZhbHVlOiAnZml4ZWQtaGVpZ2h0JywgbGFiZWw6IF9fKCdGaXhlZCBIZWlnaHQnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpeGVkJywgbGFiZWw6IF9fKCdGaXhlZCcsICdhbXAnKSB9LCB7IHZhbHVlOiAnZmlsbCcsIGxhYmVsOiBfXygnRmlsbCcsICdhbXAnKSB9LCB7IHZhbHVlOiAnZmxleC1pdGVtJywgbGFiZWw6IF9fKCdGbGV4LWl0ZW0nLCAnYW1wJykgfV07XG5cdFx0dmFyIHVybCA9IGZhbHNlO1xuXHRcdGlmIChkYXRhRW1iZWRJZCkge1xuXHRcdFx0dXJsID0gJ2h0dHBzOi8vbWVkaWEtY2RuLmJlYWNoZnJvbnRyZWFjaC5jb20vYWNjdF8xL3ZpZGVvLyc7XG5cdFx0fVxuXHRcdHJldHVybiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRGcmFnbWVudCxcblx0XHRcdG51bGwsXG5cdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdEluc3BlY3RvckNvbnRyb2xzLFxuXHRcdFx0XHR7IGtleTogJ2luc3BlY3RvcicgfSxcblx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRcdFBhbmVsQm9keSxcblx0XHRcdFx0XHR7IHRpdGxlOiBfXygnUmVhY2ggc2V0dGluZ3MnLCAnYW1wJykgfSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnVGhlIFJlYWNoIHBsYXllciBlbWJlZCBpZCAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFFbWJlZElkLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YUVtYmVkSWQ6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdGdldExheW91dENvbnRyb2xzKHByb3BzLCBhbXBMYXlvdXRPcHRpb25zKVxuXHRcdFx0XHQpXG5cdFx0XHQpLFxuXHRcdFx0dXJsICYmIGdldE1lZGlhUGxhY2Vob2xkZXIoX18oJ1JlYWNoIFBsYXllcicsICdhbXAnKSwgdXJsKSxcblx0XHRcdCF1cmwgJiYgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRQbGFjZWhvbGRlcixcblx0XHRcdFx0eyBsYWJlbDogX18oJ1JlYWNoIFBsYXllcicsICdhbXAnKSB9LFxuXHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0J3AnLFxuXHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0X18oJ0FkZCBSZWFjaCBwbGF5ZXIgZW1iZWQgSUQgdG8gdXNlIHRoZSBibG9jay4nLCAnYW1wJylcblx0XHRcdFx0KVxuXHRcdFx0KVxuXHRcdCk7XG5cdH0sXG5cdHNhdmU6IGZ1bmN0aW9uIHNhdmUoX3JlZikge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gX3JlZi5hdHRyaWJ1dGVzO1xuXHRcdHZhciBkYXRhRW1iZWRJZCA9IGF0dHJpYnV0ZXMuZGF0YUVtYmVkSWQsXG5cdFx0ICAgIGFtcExheW91dCA9IGF0dHJpYnV0ZXMuYW1wTGF5b3V0LFxuXHRcdCAgICBoZWlnaHQgPSBhdHRyaWJ1dGVzLmhlaWdodCxcblx0XHQgICAgd2lkdGggPSBhdHRyaWJ1dGVzLndpZHRoO1xuXG5cblx0XHR2YXIgcmVhY2hQcm9wcyA9IHtcblx0XHRcdGxheW91dDogYW1wTGF5b3V0LFxuXHRcdFx0aGVpZ2h0OiBoZWlnaHQsXG5cdFx0XHQnZGF0YS1lbWJlZC1pZCc6IGRhdGFFbWJlZElkXG5cdFx0fTtcblx0XHRpZiAoJ2ZpeGVkLWhlaWdodCcgIT09IGFtcExheW91dCAmJiB3aWR0aCkge1xuXHRcdFx0cmVhY2hQcm9wcy53aWR0aCA9IHdpZHRoO1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KCdhbXAtcmVhY2gtcGxheWVyJywgcmVhY2hQcm9wcyk7XG5cdH1cbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vYmxvY2tzL2FtcC1yZWFjaC1wbGF5ZXIvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8\n");
|
| 121 |
+
|
| 122 |
+
/***/ }),
|
| 123 |
+
/* 9 */
|
| 124 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 125 |
+
|
| 126 |
+
"use strict";
|
| 127 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar InspectorControls = wp.editor.InspectorControls;\nvar Fragment = wp.element.Fragment;\nvar _wp$components = wp.components,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl,\n SelectControl = _wp$components.SelectControl,\n Placeholder = _wp$components.Placeholder;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-springboard-player', {\n\ttitle: __('AMP Springboard Player', 'amp'),\n\tdescription: __('Displays the Springboard Player used in the Springboard Video Platform', 'amp'),\n\tcategory: 'embed',\n\ticon: 'embed-generic',\n\tkeywords: [__('Embed', 'amp')],\n\n\tattributes: {\n\t\tdataSiteId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'data-site-id'\n\t\t},\n\t\tdataContentId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'data-content-id'\n\t\t},\n\t\tdataPlayerId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'data-player-id'\n\t\t},\n\t\tdataDomain: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'data-domain'\n\t\t},\n\t\tdataMode: {\n\t\t\tdefault: 'video',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'data-mode'\n\t\t},\n\t\tdataItems: {\n\t\t\tdefault: 1,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'data-items'\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'responsive',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\tdefault: 600,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'width'\n\t\t},\n\t\theight: {\n\t\t\tdefault: 400,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-springboard-player',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar dataSiteId = attributes.dataSiteId,\n\t\t dataPlayerId = attributes.dataPlayerId,\n\t\t dataContentId = attributes.dataContentId,\n\t\t dataDomain = attributes.dataDomain,\n\t\t dataMode = attributes.dataMode,\n\t\t dataItems = attributes.dataItems;\n\n\t\tvar ampLayoutOptions = [{ value: 'responsive', label: __('Responsive', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }, { value: 'fill', label: __('Fill', 'amp') }, { value: 'flex-item', label: __('Flex-item', 'amp') }];\n\t\tvar url = false;\n\t\tif (dataSiteId && dataContentId && dataDomain && dataMode && dataItems) {\n\t\t\turl = 'https://cms.springboardplatform.com/embed_iframe/';\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('Springboard Player Settings', 'amp') },\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('SprintBoard site ID (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataSiteId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataSiteId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Player content ID (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataContentId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataContentId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Player ID', 'amp'),\n\t\t\t\t\t\tvalue: dataPlayerId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPlayerId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Springboard partner domain', 'amp'),\n\t\t\t\t\t\tvalue: dataDomain,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataDomain: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(SelectControl, {\n\t\t\t\t\t\tlabel: __('Mode (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataMode,\n\t\t\t\t\t\toptions: [{ value: 'video', label: __('Video', 'amp') }, { value: 'playlist', label: __('Playlist', 'amp') }],\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataMode: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tlabel: __('Number of video is playlist (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataItems,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataItems: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions)\n\t\t\t\t)\n\t\t\t),\n\t\t\turl && Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"b\" /* getMediaPlaceholder */])(__('Springboard Player', 'amp'), url),\n\t\t\t!url && wp.element.createElement(\n\t\t\t\tPlaceholder,\n\t\t\t\t{ label: __('Springboard Player', 'amp') },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\t'p',\n\t\t\t\t\tnull,\n\t\t\t\t\t__('Add required data to use the block.', 'amp')\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\t\tvar dataSiteId = attributes.dataSiteId,\n\t\t dataPlayerId = attributes.dataPlayerId,\n\t\t dataContentId = attributes.dataContentId,\n\t\t dataDomain = attributes.dataDomain,\n\t\t dataMode = attributes.dataMode,\n\t\t dataItems = attributes.dataItems,\n\t\t ampLayout = attributes.ampLayout,\n\t\t height = attributes.height,\n\t\t width = attributes.width;\n\n\t\tvar springboardProps = {\n\t\t\tlayout: ampLayout,\n\t\t\theight: height,\n\t\t\t'data-site-id': dataSiteId,\n\t\t\t'data-mode': dataMode,\n\t\t\t'data-content-id': dataContentId,\n\t\t\t'data-player-id': dataPlayerId,\n\t\t\t'data-domain': dataDomain,\n\t\t\t'data-items': dataItems\n\t\t};\n\t\tif ('fixed-height' !== ampLayout && width) {\n\t\t\tspringboardProps.width = attributes.width;\n\t\t}\n\t\treturn wp.element.createElement('amp-springboard-player', springboardProps);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2Jsb2Nrcy9hbXAtc3ByaW5nYm9hcmQtcGxheWVyL2luZGV4LmpzPzcyYjgiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBIZWxwZXIgbWV0aG9kcyBmb3IgYmxvY2tzLlxuICovXG5pbXBvcnQgeyBnZXRMYXlvdXRDb250cm9scywgZ2V0TWVkaWFQbGFjZWhvbGRlciB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuLyoqXG4gKiBJbnRlcm5hbCBibG9jayBsaWJyYXJpZXMuXG4gKi9cbnZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7XG52YXIgSW5zcGVjdG9yQ29udHJvbHMgPSB3cC5lZGl0b3IuSW5zcGVjdG9yQ29udHJvbHM7XG52YXIgRnJhZ21lbnQgPSB3cC5lbGVtZW50LkZyYWdtZW50O1xudmFyIF93cCRjb21wb25lbnRzID0gd3AuY29tcG9uZW50cyxcbiAgICBQYW5lbEJvZHkgPSBfd3AkY29tcG9uZW50cy5QYW5lbEJvZHksXG4gICAgVGV4dENvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5UZXh0Q29udHJvbCxcbiAgICBTZWxlY3RDb250cm9sID0gX3dwJGNvbXBvbmVudHMuU2VsZWN0Q29udHJvbCxcbiAgICBQbGFjZWhvbGRlciA9IF93cCRjb21wb25lbnRzLlBsYWNlaG9sZGVyO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGJsb2NrLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IHJlZ2lzdGVyQmxvY2tUeXBlKCdhbXAvYW1wLXNwcmluZ2JvYXJkLXBsYXllcicsIHtcblx0dGl0bGU6IF9fKCdBTVAgU3ByaW5nYm9hcmQgUGxheWVyJywgJ2FtcCcpLFxuXHRkZXNjcmlwdGlvbjogX18oJ0Rpc3BsYXlzIHRoZSBTcHJpbmdib2FyZCBQbGF5ZXIgdXNlZCBpbiB0aGUgU3ByaW5nYm9hcmQgVmlkZW8gUGxhdGZvcm0nLCAnYW1wJyksXG5cdGNhdGVnb3J5OiAnZW1iZWQnLFxuXHRpY29uOiAnZW1iZWQtZ2VuZXJpYycsXG5cdGtleXdvcmRzOiBbX18oJ0VtYmVkJywgJ2FtcCcpXSxcblxuXHRhdHRyaWJ1dGVzOiB7XG5cdFx0ZGF0YVNpdGVJZDoge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXNwcmluZ2JvYXJkLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLXNpdGUtaWQnXG5cdFx0fSxcblx0XHRkYXRhQ29udGVudElkOiB7XG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtc3ByaW5nYm9hcmQtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtY29udGVudC1pZCdcblx0XHR9LFxuXHRcdGRhdGFQbGF5ZXJJZDoge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXNwcmluZ2JvYXJkLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLXBsYXllci1pZCdcblx0XHR9LFxuXHRcdGRhdGFEb21haW46IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1zcHJpbmdib2FyZC1wbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1kb21haW4nXG5cdFx0fSxcblx0XHRkYXRhTW9kZToge1xuXHRcdFx0ZGVmYXVsdDogJ3ZpZGVvJyxcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1zcHJpbmdib2FyZC1wbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1tb2RlJ1xuXHRcdH0sXG5cdFx0ZGF0YUl0ZW1zOiB7XG5cdFx0XHRkZWZhdWx0OiAxLFxuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLXNwcmluZ2JvYXJkLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLWl0ZW1zJ1xuXHRcdH0sXG5cdFx0YW1wTGF5b3V0OiB7XG5cdFx0XHRkZWZhdWx0OiAncmVzcG9uc2l2ZScsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtc3ByaW5nYm9hcmQtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2xheW91dCdcblx0XHR9LFxuXHRcdHdpZHRoOiB7XG5cdFx0XHRkZWZhdWx0OiA2MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtc3ByaW5nYm9hcmQtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ3dpZHRoJ1xuXHRcdH0sXG5cdFx0aGVpZ2h0OiB7XG5cdFx0XHRkZWZhdWx0OiA0MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtc3ByaW5nYm9hcmQtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2hlaWdodCdcblx0XHR9XG5cdH0sXG5cblx0ZWRpdDogZnVuY3Rpb24gZWRpdChwcm9wcykge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gcHJvcHMuYXR0cmlidXRlcyxcblx0XHQgICAgc2V0QXR0cmlidXRlcyA9IHByb3BzLnNldEF0dHJpYnV0ZXM7XG5cdFx0dmFyIGRhdGFTaXRlSWQgPSBhdHRyaWJ1dGVzLmRhdGFTaXRlSWQsXG5cdFx0ICAgIGRhdGFQbGF5ZXJJZCA9IGF0dHJpYnV0ZXMuZGF0YVBsYXllcklkLFxuXHRcdCAgICBkYXRhQ29udGVudElkID0gYXR0cmlidXRlcy5kYXRhQ29udGVudElkLFxuXHRcdCAgICBkYXRhRG9tYWluID0gYXR0cmlidXRlcy5kYXRhRG9tYWluLFxuXHRcdCAgICBkYXRhTW9kZSA9IGF0dHJpYnV0ZXMuZGF0YU1vZGUsXG5cdFx0ICAgIGRhdGFJdGVtcyA9IGF0dHJpYnV0ZXMuZGF0YUl0ZW1zO1xuXG5cdFx0dmFyIGFtcExheW91dE9wdGlvbnMgPSBbeyB2YWx1ZTogJ3Jlc3BvbnNpdmUnLCBsYWJlbDogX18oJ1Jlc3BvbnNpdmUnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpeGVkJywgbGFiZWw6IF9fKCdGaXhlZCcsICdhbXAnKSB9LCB7IHZhbHVlOiAnZmlsbCcsIGxhYmVsOiBfXygnRmlsbCcsICdhbXAnKSB9LCB7IHZhbHVlOiAnZmxleC1pdGVtJywgbGFiZWw6IF9fKCdGbGV4LWl0ZW0nLCAnYW1wJykgfV07XG5cdFx0dmFyIHVybCA9IGZhbHNlO1xuXHRcdGlmIChkYXRhU2l0ZUlkICYmIGRhdGFDb250ZW50SWQgJiYgZGF0YURvbWFpbiAmJiBkYXRhTW9kZSAmJiBkYXRhSXRlbXMpIHtcblx0XHRcdHVybCA9ICdodHRwczovL2Ntcy5zcHJpbmdib2FyZHBsYXRmb3JtLmNvbS9lbWJlZF9pZnJhbWUvJztcblx0XHR9XG5cdFx0cmV0dXJuIHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdEZyYWdtZW50LFxuXHRcdFx0bnVsbCxcblx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0SW5zcGVjdG9yQ29udHJvbHMsXG5cdFx0XHRcdHsga2V5OiAnaW5zcGVjdG9yJyB9LFxuXHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0UGFuZWxCb2R5LFxuXHRcdFx0XHRcdHsgdGl0bGU6IF9fKCdTcHJpbmdib2FyZCBQbGF5ZXIgU2V0dGluZ3MnLCAnYW1wJykgfSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnU3ByaW50Qm9hcmQgc2l0ZSBJRCAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFTaXRlSWQsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhU2l0ZUlkOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnUGxheWVyIGNvbnRlbnQgSUQgKHJlcXVpcmVkKScsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhQ29udGVudElkLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YUNvbnRlbnRJZDogdmFsdWUgfSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ1BsYXllciBJRCcsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhUGxheWVySWQsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhUGxheWVySWQ6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUZXh0Q29udHJvbCwge1xuXHRcdFx0XHRcdFx0bGFiZWw6IF9fKCdTcHJpbmdib2FyZCBwYXJ0bmVyIGRvbWFpbicsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhRG9tYWluLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YURvbWFpbjogdmFsdWUgfSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFNlbGVjdENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnTW9kZSAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFNb2RlLFxuXHRcdFx0XHRcdFx0b3B0aW9uczogW3sgdmFsdWU6ICd2aWRlbycsIGxhYmVsOiBfXygnVmlkZW8nLCAnYW1wJykgfSwgeyB2YWx1ZTogJ3BsYXlsaXN0JywgbGFiZWw6IF9fKCdQbGF5bGlzdCcsICdhbXAnKSB9XSxcblx0XHRcdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGRhdGFNb2RlOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdHR5cGU6ICdudW1iZXInLFxuXHRcdFx0XHRcdFx0bGFiZWw6IF9fKCdOdW1iZXIgb2YgdmlkZW8gaXMgcGxheWxpc3QgKHJlcXVpcmVkKScsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhSXRlbXMsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhSXRlbXM6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdGdldExheW91dENvbnRyb2xzKHByb3BzLCBhbXBMYXlvdXRPcHRpb25zKVxuXHRcdFx0XHQpXG5cdFx0XHQpLFxuXHRcdFx0dXJsICYmIGdldE1lZGlhUGxhY2Vob2xkZXIoX18oJ1NwcmluZ2JvYXJkIFBsYXllcicsICdhbXAnKSwgdXJsKSxcblx0XHRcdCF1cmwgJiYgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRQbGFjZWhvbGRlcixcblx0XHRcdFx0eyBsYWJlbDogX18oJ1NwcmluZ2JvYXJkIFBsYXllcicsICdhbXAnKSB9LFxuXHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0J3AnLFxuXHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0X18oJ0FkZCByZXF1aXJlZCBkYXRhIHRvIHVzZSB0aGUgYmxvY2suJywgJ2FtcCcpXG5cdFx0XHRcdClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXHRzYXZlOiBmdW5jdGlvbiBzYXZlKF9yZWYpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IF9yZWYuYXR0cmlidXRlcztcblx0XHR2YXIgZGF0YVNpdGVJZCA9IGF0dHJpYnV0ZXMuZGF0YVNpdGVJZCxcblx0XHQgICAgZGF0YVBsYXllcklkID0gYXR0cmlidXRlcy5kYXRhUGxheWVySWQsXG5cdFx0ICAgIGRhdGFDb250ZW50SWQgPSBhdHRyaWJ1dGVzLmRhdGFDb250ZW50SWQsXG5cdFx0ICAgIGRhdGFEb21haW4gPSBhdHRyaWJ1dGVzLmRhdGFEb21haW4sXG5cdFx0ICAgIGRhdGFNb2RlID0gYXR0cmlidXRlcy5kYXRhTW9kZSxcblx0XHQgICAgZGF0YUl0ZW1zID0gYXR0cmlidXRlcy5kYXRhSXRlbXMsXG5cdFx0ICAgIGFtcExheW91dCA9IGF0dHJpYnV0ZXMuYW1wTGF5b3V0LFxuXHRcdCAgICBoZWlnaHQgPSBhdHRyaWJ1dGVzLmhlaWdodCxcblx0XHQgICAgd2lkdGggPSBhdHRyaWJ1dGVzLndpZHRoO1xuXG5cdFx0dmFyIHNwcmluZ2JvYXJkUHJvcHMgPSB7XG5cdFx0XHRsYXlvdXQ6IGFtcExheW91dCxcblx0XHRcdGhlaWdodDogaGVpZ2h0LFxuXHRcdFx0J2RhdGEtc2l0ZS1pZCc6IGRhdGFTaXRlSWQsXG5cdFx0XHQnZGF0YS1tb2RlJzogZGF0YU1vZGUsXG5cdFx0XHQnZGF0YS1jb250ZW50LWlkJzogZGF0YUNvbnRlbnRJZCxcblx0XHRcdCdkYXRhLXBsYXllci1pZCc6IGRhdGFQbGF5ZXJJZCxcblx0XHRcdCdkYXRhLWRvbWFpbic6IGRhdGFEb21haW4sXG5cdFx0XHQnZGF0YS1pdGVtcyc6IGRhdGFJdGVtc1xuXHRcdH07XG5cdFx0aWYgKCdmaXhlZC1oZWlnaHQnICE9PSBhbXBMYXlvdXQgJiYgd2lkdGgpIHtcblx0XHRcdHNwcmluZ2JvYXJkUHJvcHMud2lkdGggPSBhdHRyaWJ1dGVzLndpZHRoO1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KCdhbXAtc3ByaW5nYm9hcmQtcGxheWVyJywgc3ByaW5nYm9hcmRQcm9wcyk7XG5cdH1cbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vYmxvY2tzL2FtcC1zcHJpbmdib2FyZC1wbGF5ZXIvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9\n");
|
| 128 |
+
|
| 129 |
+
/***/ }),
|
| 130 |
+
/* 10 */
|
| 131 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 132 |
+
|
| 133 |
+
"use strict";
|
| 134 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar InspectorControls = wp.editor.InspectorControls;\nvar Fragment = wp.element.Fragment;\nvar _wp$components = wp.components,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl,\n Placeholder = _wp$components.Placeholder;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-jwplayer', {\n\ttitle: __('AMP JW Player', 'amp'),\n\tdescription: __('Displays a cloud-hosted JW Player.', 'amp'),\n\tcategory: 'embed',\n\ticon: 'embed-generic',\n\tkeywords: [__('Embed', 'amp')],\n\n\tattributes: {\n\t\tdataPlayerId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-jwplayer',\n\t\t\tattribute: 'data-player-id'\n\t\t},\n\t\tdataMediaId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-jwplayer',\n\t\t\tattribute: 'data-media-id'\n\t\t},\n\t\tdataPlaylistId: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-jwplayer',\n\t\t\tattribute: 'data-playlist-id'\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'responsive',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-jwplayer',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\tdefault: 600,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-jwplayer',\n\t\t\tattribute: 'width'\n\t\t},\n\t\theight: {\n\t\t\tdefault: 400,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-jwplayer',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar dataPlayerId = attributes.dataPlayerId,\n\t\t dataMediaId = attributes.dataMediaId,\n\t\t dataPlaylistId = attributes.dataPlaylistId;\n\n\t\tvar ampLayoutOptions = [{ value: 'responsive', label: __('Responsive', 'amp') }, { value: 'fixed-height', label: __('Fixed height', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }, { value: 'fill', label: __('Fill', 'amp') }, { value: 'flex-item', label: __('Flex-item', 'amp') }, { value: 'nodisplay', label: __('No Display', 'amp') }];\n\t\tvar url = false;\n\t\tif (dataPlayerId && (dataMediaId || dataPlaylistId)) {\n\t\t\tif (dataPlaylistId) {\n\t\t\t\turl = 'https://content.jwplatform.com/players/' + dataPlaylistId + '-' + dataPlayerId;\n\t\t\t} else {\n\t\t\t\turl = 'https://content.jwplatform.com/players/' + dataMediaId + '-' + dataPlayerId;\n\t\t\t}\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('JW Player Settings', 'amp') },\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Player ID (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataPlayerId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPlayerId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Media ID (required if playlist ID not set)', 'amp'),\n\t\t\t\t\t\tvalue: dataMediaId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataMediaId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Playlist ID (required if media ID not set)', 'amp'),\n\t\t\t\t\t\tvalue: dataPlaylistId,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPlaylistId: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions)\n\t\t\t\t)\n\t\t\t),\n\t\t\turl && Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"b\" /* getMediaPlaceholder */])(__('JW Player', 'amp'), url),\n\t\t\t!url && wp.element.createElement(\n\t\t\t\tPlaceholder,\n\t\t\t\t{ label: __('JW Player', 'amp') },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\t'p',\n\t\t\t\t\tnull,\n\t\t\t\t\t__('Add required data to use the block.', 'amp')\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\n\t\tvar jwProps = {\n\t\t\tlayout: attributes.ampLayout,\n\t\t\theight: attributes.height,\n\t\t\t'data-player-id': attributes.dataPlayerId\n\t\t};\n\t\tif ('fixed-height' !== attributes.ampLayout && attributes.width) {\n\t\t\tjwProps.width = attributes.width;\n\t\t}\n\t\tif (attributes.dataPlaylistId) {\n\t\t\tjwProps['data-playlist-id'] = attributes.dataPlaylistId;\n\t\t}\n\t\tif (attributes.dataMediaId) {\n\t\t\tjwProps['data-media-id'] = attributes.dataMediaId;\n\t\t}\n\t\treturn wp.element.createElement('amp-jwplayer', jwProps);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ibG9ja3MvYW1wLWp3cGxheWVyL2luZGV4LmpzP2E1ZDAiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBIZWxwZXIgbWV0aG9kcyBmb3IgYmxvY2tzLlxuICovXG5pbXBvcnQgeyBnZXRMYXlvdXRDb250cm9scywgZ2V0TWVkaWFQbGFjZWhvbGRlciB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuLyoqXG4gKiBJbnRlcm5hbCBibG9jayBsaWJyYXJpZXMuXG4gKi9cbnZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7XG52YXIgSW5zcGVjdG9yQ29udHJvbHMgPSB3cC5lZGl0b3IuSW5zcGVjdG9yQ29udHJvbHM7XG52YXIgRnJhZ21lbnQgPSB3cC5lbGVtZW50LkZyYWdtZW50O1xudmFyIF93cCRjb21wb25lbnRzID0gd3AuY29tcG9uZW50cyxcbiAgICBQYW5lbEJvZHkgPSBfd3AkY29tcG9uZW50cy5QYW5lbEJvZHksXG4gICAgVGV4dENvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5UZXh0Q29udHJvbCxcbiAgICBQbGFjZWhvbGRlciA9IF93cCRjb21wb25lbnRzLlBsYWNlaG9sZGVyO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGJsb2NrLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IHJlZ2lzdGVyQmxvY2tUeXBlKCdhbXAvYW1wLWp3cGxheWVyJywge1xuXHR0aXRsZTogX18oJ0FNUCBKVyBQbGF5ZXInLCAnYW1wJyksXG5cdGRlc2NyaXB0aW9uOiBfXygnRGlzcGxheXMgYSBjbG91ZC1ob3N0ZWQgSlcgUGxheWVyLicsICdhbXAnKSxcblx0Y2F0ZWdvcnk6ICdlbWJlZCcsXG5cdGljb246ICdlbWJlZC1nZW5lcmljJyxcblx0a2V5d29yZHM6IFtfXygnRW1iZWQnLCAnYW1wJyldLFxuXG5cdGF0dHJpYnV0ZXM6IHtcblx0XHRkYXRhUGxheWVySWQ6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1qd3BsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLXBsYXllci1pZCdcblx0XHR9LFxuXHRcdGRhdGFNZWRpYUlkOiB7XG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtandwbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1tZWRpYS1pZCdcblx0XHR9LFxuXHRcdGRhdGFQbGF5bGlzdElkOiB7XG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtandwbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1wbGF5bGlzdC1pZCdcblx0XHR9LFxuXHRcdGFtcExheW91dDoge1xuXHRcdFx0ZGVmYXVsdDogJ3Jlc3BvbnNpdmUnLFxuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLWp3cGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2xheW91dCdcblx0XHR9LFxuXHRcdHdpZHRoOiB7XG5cdFx0XHRkZWZhdWx0OiA2MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtandwbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnd2lkdGgnXG5cdFx0fSxcblx0XHRoZWlnaHQ6IHtcblx0XHRcdGRlZmF1bHQ6IDQwMCxcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1qd3BsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdoZWlnaHQnXG5cdFx0fVxuXHR9LFxuXG5cdGVkaXQ6IGZ1bmN0aW9uIGVkaXQocHJvcHMpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IHByb3BzLmF0dHJpYnV0ZXMsXG5cdFx0ICAgIHNldEF0dHJpYnV0ZXMgPSBwcm9wcy5zZXRBdHRyaWJ1dGVzO1xuXHRcdHZhciBkYXRhUGxheWVySWQgPSBhdHRyaWJ1dGVzLmRhdGFQbGF5ZXJJZCxcblx0XHQgICAgZGF0YU1lZGlhSWQgPSBhdHRyaWJ1dGVzLmRhdGFNZWRpYUlkLFxuXHRcdCAgICBkYXRhUGxheWxpc3RJZCA9IGF0dHJpYnV0ZXMuZGF0YVBsYXlsaXN0SWQ7XG5cblx0XHR2YXIgYW1wTGF5b3V0T3B0aW9ucyA9IFt7IHZhbHVlOiAncmVzcG9uc2l2ZScsIGxhYmVsOiBfXygnUmVzcG9uc2l2ZScsICdhbXAnKSB9LCB7IHZhbHVlOiAnZml4ZWQtaGVpZ2h0JywgbGFiZWw6IF9fKCdGaXhlZCBoZWlnaHQnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpeGVkJywgbGFiZWw6IF9fKCdGaXhlZCcsICdhbXAnKSB9LCB7IHZhbHVlOiAnZmlsbCcsIGxhYmVsOiBfXygnRmlsbCcsICdhbXAnKSB9LCB7IHZhbHVlOiAnZmxleC1pdGVtJywgbGFiZWw6IF9fKCdGbGV4LWl0ZW0nLCAnYW1wJykgfSwgeyB2YWx1ZTogJ25vZGlzcGxheScsIGxhYmVsOiBfXygnTm8gRGlzcGxheScsICdhbXAnKSB9XTtcblx0XHR2YXIgdXJsID0gZmFsc2U7XG5cdFx0aWYgKGRhdGFQbGF5ZXJJZCAmJiAoZGF0YU1lZGlhSWQgfHwgZGF0YVBsYXlsaXN0SWQpKSB7XG5cdFx0XHRpZiAoZGF0YVBsYXlsaXN0SWQpIHtcblx0XHRcdFx0dXJsID0gJ2h0dHBzOi8vY29udGVudC5qd3BsYXRmb3JtLmNvbS9wbGF5ZXJzLycgKyBkYXRhUGxheWxpc3RJZCArICctJyArIGRhdGFQbGF5ZXJJZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHVybCA9ICdodHRwczovL2NvbnRlbnQuandwbGF0Zm9ybS5jb20vcGxheWVycy8nICsgZGF0YU1lZGlhSWQgKyAnLScgKyBkYXRhUGxheWVySWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRGcmFnbWVudCxcblx0XHRcdG51bGwsXG5cdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdEluc3BlY3RvckNvbnRyb2xzLFxuXHRcdFx0XHR7IGtleTogJ2luc3BlY3RvcicgfSxcblx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRcdFBhbmVsQm9keSxcblx0XHRcdFx0XHR7IHRpdGxlOiBfXygnSlcgUGxheWVyIFNldHRpbmdzJywgJ2FtcCcpIH0sXG5cdFx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ1BsYXllciBJRCAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFQbGF5ZXJJZCxcblx0XHRcdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGRhdGFQbGF5ZXJJZDogdmFsdWUgfSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ01lZGlhIElEIChyZXF1aXJlZCBpZiBwbGF5bGlzdCBJRCBub3Qgc2V0KScsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhTWVkaWFJZCxcblx0XHRcdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGRhdGFNZWRpYUlkOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnUGxheWxpc3QgSUQgKHJlcXVpcmVkIGlmIG1lZGlhIElEIG5vdCBzZXQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFQbGF5bGlzdElkLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YVBsYXlsaXN0SWQ6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdGdldExheW91dENvbnRyb2xzKHByb3BzLCBhbXBMYXlvdXRPcHRpb25zKVxuXHRcdFx0XHQpXG5cdFx0XHQpLFxuXHRcdFx0dXJsICYmIGdldE1lZGlhUGxhY2Vob2xkZXIoX18oJ0pXIFBsYXllcicsICdhbXAnKSwgdXJsKSxcblx0XHRcdCF1cmwgJiYgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRQbGFjZWhvbGRlcixcblx0XHRcdFx0eyBsYWJlbDogX18oJ0pXIFBsYXllcicsICdhbXAnKSB9LFxuXHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0J3AnLFxuXHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0X18oJ0FkZCByZXF1aXJlZCBkYXRhIHRvIHVzZSB0aGUgYmxvY2suJywgJ2FtcCcpXG5cdFx0XHRcdClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXHRzYXZlOiBmdW5jdGlvbiBzYXZlKF9yZWYpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IF9yZWYuYXR0cmlidXRlcztcblxuXHRcdHZhciBqd1Byb3BzID0ge1xuXHRcdFx0bGF5b3V0OiBhdHRyaWJ1dGVzLmFtcExheW91dCxcblx0XHRcdGhlaWdodDogYXR0cmlidXRlcy5oZWlnaHQsXG5cdFx0XHQnZGF0YS1wbGF5ZXItaWQnOiBhdHRyaWJ1dGVzLmRhdGFQbGF5ZXJJZFxuXHRcdH07XG5cdFx0aWYgKCdmaXhlZC1oZWlnaHQnICE9PSBhdHRyaWJ1dGVzLmFtcExheW91dCAmJiBhdHRyaWJ1dGVzLndpZHRoKSB7XG5cdFx0XHRqd1Byb3BzLndpZHRoID0gYXR0cmlidXRlcy53aWR0aDtcblx0XHR9XG5cdFx0aWYgKGF0dHJpYnV0ZXMuZGF0YVBsYXlsaXN0SWQpIHtcblx0XHRcdGp3UHJvcHNbJ2RhdGEtcGxheWxpc3QtaWQnXSA9IGF0dHJpYnV0ZXMuZGF0YVBsYXlsaXN0SWQ7XG5cdFx0fVxuXHRcdGlmIChhdHRyaWJ1dGVzLmRhdGFNZWRpYUlkKSB7XG5cdFx0XHRqd1Byb3BzWydkYXRhLW1lZGlhLWlkJ10gPSBhdHRyaWJ1dGVzLmRhdGFNZWRpYUlkO1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KCdhbXAtandwbGF5ZXInLCBqd1Byb3BzKTtcblx0fVxufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ibG9ja3MvYW1wLWp3cGxheWVyL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///10\n");
|
| 135 |
+
|
| 136 |
+
/***/ }),
|
| 137 |
+
/* 11 */
|
| 138 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 139 |
+
|
| 140 |
+
"use strict";
|
| 141 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar InspectorControls = wp.editor.InspectorControls;\nvar Fragment = wp.element.Fragment;\nvar _wp$components = wp.components,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl,\n Placeholder = _wp$components.Placeholder,\n ToggleControl = _wp$components.ToggleControl;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-brid-player', {\n\ttitle: __('AMP Brid Player', 'amp'),\n\tdescription: __('Displays the Brid Player used in Brid.tv Video Platform.', 'amp'),\n\tcategory: 'embed',\n\ticon: 'embed-generic',\n\tkeywords: [__('Embed', 'amp')],\n\n\tattributes: {\n\t\tautoPlay: {\n\t\t\ttype: 'boolean'\n\t\t},\n\t\tdataPartner: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-brid-player',\n\t\t\tattribute: 'data-partner'\n\t\t},\n\t\tdataPlayer: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-brid-player',\n\t\t\tattribute: 'data-player'\n\t\t},\n\t\tdataVideo: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-brid-player',\n\t\t\tattribute: 'data-video'\n\t\t},\n\t\tdataPlaylist: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-brid-player',\n\t\t\tattribute: 'data-playlist'\n\t\t},\n\t\tdataOutstream: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-brid-player',\n\t\t\tattribute: 'data-outstream'\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'responsive',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-brid-player',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\ttype: 'number',\n\t\t\tdefault: 600\n\t\t},\n\t\theight: {\n\t\t\tdefault: 400,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-brid-player',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar autoPlay = attributes.autoPlay,\n\t\t dataPartner = attributes.dataPartner,\n\t\t dataPlayer = attributes.dataPlayer,\n\t\t dataVideo = attributes.dataVideo,\n\t\t dataPlaylist = attributes.dataPlaylist,\n\t\t dataOutstream = attributes.dataOutstream;\n\n\t\tvar ampLayoutOptions = [{ value: 'responsive', label: __('Responsive', 'amp') }, { value: 'fixed-height', label: __('Fixed height', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }, { value: 'fill', label: __('Fill', 'amp') }, { value: 'flex-item', label: __('Flex-item', 'amp') }, { value: 'nodisplay', label: __('No Display', 'amp') }];\n\t\tvar url = false;\n\t\tif (dataPartner && dataPlayer && (dataVideo || dataPlaylist || dataOutstream)) {\n\t\t\turl = 'http://cdn.brid.tv/live/partners/' + dataPartner;\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('Brid Player Settings', 'amp') },\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Brid.tv partner ID (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataPartner,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPartner: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Brid.tv player ID (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataPlayer,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPlayer: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Video ID (one of video / playlist / outstream ID is required)', 'amp'),\n\t\t\t\t\t\tvalue: dataVideo,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataVideo: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Outstream unit ID (one of video / playlist / outstream ID is required)', 'amp'),\n\t\t\t\t\t\tvalue: dataOutstream,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataOutstream: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Playlist ID (one of video / playlist / outstream ID is required)', 'amp'),\n\t\t\t\t\t\tvalue: dataPlaylist,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPlaylist: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(ToggleControl, {\n\t\t\t\t\t\tlabel: __('Autoplay', 'amp'),\n\t\t\t\t\t\tchecked: autoPlay,\n\t\t\t\t\t\tonChange: function onChange() {\n\t\t\t\t\t\t\treturn setAttributes({ autoPlay: !autoPlay });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions)\n\t\t\t\t)\n\t\t\t),\n\t\t\turl && Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"b\" /* getMediaPlaceholder */])(__('Brid Player', 'amp'), url),\n\t\t\t!url && wp.element.createElement(\n\t\t\t\tPlaceholder,\n\t\t\t\t{ label: __('Brid Player', 'amp') },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\t'p',\n\t\t\t\t\tnull,\n\t\t\t\t\t__('Add required data to use the block.', 'amp')\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\n\t\tvar bridProps = {\n\t\t\tlayout: attributes.ampLayout,\n\t\t\theight: attributes.height,\n\t\t\t'data-player': attributes.dataPlayer,\n\t\t\t'data-partner': attributes.dataPartner\n\t\t};\n\t\tif ('fixed-height' !== attributes.ampLayout && attributes.width) {\n\t\t\tbridProps.width = attributes.width;\n\t\t}\n\t\tif (attributes.dataPlaylist) {\n\t\t\tbridProps['data-playlist'] = attributes.dataPlaylist;\n\t\t}\n\t\tif (attributes.dataVideo) {\n\t\t\tbridProps['data-video'] = attributes.dataVideo;\n\t\t}\n\t\tif (attributes.dataOutstream) {\n\t\t\tbridProps['data-outstream'] = attributes.dataOutstream;\n\t\t}\n\t\tif (attributes.autoPlay) {\n\t\t\tbridProps.autoplay = attributes.autoPlay;\n\t\t}\n\t\treturn wp.element.createElement('amp-brid-player', bridProps);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ibG9ja3MvYW1wLWJyaWQtcGxheWVyL2luZGV4LmpzPzEyYjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBIZWxwZXIgbWV0aG9kcyBmb3IgYmxvY2tzLlxuICovXG5pbXBvcnQgeyBnZXRMYXlvdXRDb250cm9scywgZ2V0TWVkaWFQbGFjZWhvbGRlciB9IGZyb20gJy4uL3V0aWxzLmpzJztcblxuLyoqXG4gKiBJbnRlcm5hbCBibG9jayBsaWJyYXJpZXMuXG4gKi9cbnZhciBfXyA9IHdwLmkxOG4uX187XG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7XG52YXIgSW5zcGVjdG9yQ29udHJvbHMgPSB3cC5lZGl0b3IuSW5zcGVjdG9yQ29udHJvbHM7XG52YXIgRnJhZ21lbnQgPSB3cC5lbGVtZW50LkZyYWdtZW50O1xudmFyIF93cCRjb21wb25lbnRzID0gd3AuY29tcG9uZW50cyxcbiAgICBQYW5lbEJvZHkgPSBfd3AkY29tcG9uZW50cy5QYW5lbEJvZHksXG4gICAgVGV4dENvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5UZXh0Q29udHJvbCxcbiAgICBQbGFjZWhvbGRlciA9IF93cCRjb21wb25lbnRzLlBsYWNlaG9sZGVyLFxuICAgIFRvZ2dsZUNvbnRyb2wgPSBfd3AkY29tcG9uZW50cy5Ub2dnbGVDb250cm9sO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGJsb2NrLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IHJlZ2lzdGVyQmxvY2tUeXBlKCdhbXAvYW1wLWJyaWQtcGxheWVyJywge1xuXHR0aXRsZTogX18oJ0FNUCBCcmlkIFBsYXllcicsICdhbXAnKSxcblx0ZGVzY3JpcHRpb246IF9fKCdEaXNwbGF5cyB0aGUgQnJpZCBQbGF5ZXIgdXNlZCBpbiBCcmlkLnR2IFZpZGVvIFBsYXRmb3JtLicsICdhbXAnKSxcblx0Y2F0ZWdvcnk6ICdlbWJlZCcsXG5cdGljb246ICdlbWJlZC1nZW5lcmljJyxcblx0a2V5d29yZHM6IFtfXygnRW1iZWQnLCAnYW1wJyldLFxuXG5cdGF0dHJpYnV0ZXM6IHtcblx0XHRhdXRvUGxheToge1xuXHRcdFx0dHlwZTogJ2Jvb2xlYW4nXG5cdFx0fSxcblx0XHRkYXRhUGFydG5lcjoge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLWJyaWQtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtcGFydG5lcidcblx0XHR9LFxuXHRcdGRhdGFQbGF5ZXI6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1icmlkLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLXBsYXllcidcblx0XHR9LFxuXHRcdGRhdGFWaWRlbzoge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLWJyaWQtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtdmlkZW8nXG5cdFx0fSxcblx0XHRkYXRhUGxheWxpc3Q6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1icmlkLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLXBsYXlsaXN0J1xuXHRcdH0sXG5cdFx0ZGF0YU91dHN0cmVhbToge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLWJyaWQtcGxheWVyJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtb3V0c3RyZWFtJ1xuXHRcdH0sXG5cdFx0YW1wTGF5b3V0OiB7XG5cdFx0XHRkZWZhdWx0OiAncmVzcG9uc2l2ZScsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtYnJpZC1wbGF5ZXInLFxuXHRcdFx0YXR0cmlidXRlOiAnbGF5b3V0J1xuXHRcdH0sXG5cdFx0d2lkdGg6IHtcblx0XHRcdHR5cGU6ICdudW1iZXInLFxuXHRcdFx0ZGVmYXVsdDogNjAwXG5cdFx0fSxcblx0XHRoZWlnaHQ6IHtcblx0XHRcdGRlZmF1bHQ6IDQwMCxcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1icmlkLXBsYXllcicsXG5cdFx0XHRhdHRyaWJ1dGU6ICdoZWlnaHQnXG5cdFx0fVxuXHR9LFxuXG5cdGVkaXQ6IGZ1bmN0aW9uIGVkaXQocHJvcHMpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IHByb3BzLmF0dHJpYnV0ZXMsXG5cdFx0ICAgIHNldEF0dHJpYnV0ZXMgPSBwcm9wcy5zZXRBdHRyaWJ1dGVzO1xuXHRcdHZhciBhdXRvUGxheSA9IGF0dHJpYnV0ZXMuYXV0b1BsYXksXG5cdFx0ICAgIGRhdGFQYXJ0bmVyID0gYXR0cmlidXRlcy5kYXRhUGFydG5lcixcblx0XHQgICAgZGF0YVBsYXllciA9IGF0dHJpYnV0ZXMuZGF0YVBsYXllcixcblx0XHQgICAgZGF0YVZpZGVvID0gYXR0cmlidXRlcy5kYXRhVmlkZW8sXG5cdFx0ICAgIGRhdGFQbGF5bGlzdCA9IGF0dHJpYnV0ZXMuZGF0YVBsYXlsaXN0LFxuXHRcdCAgICBkYXRhT3V0c3RyZWFtID0gYXR0cmlidXRlcy5kYXRhT3V0c3RyZWFtO1xuXG5cdFx0dmFyIGFtcExheW91dE9wdGlvbnMgPSBbeyB2YWx1ZTogJ3Jlc3BvbnNpdmUnLCBsYWJlbDogX18oJ1Jlc3BvbnNpdmUnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpeGVkLWhlaWdodCcsIGxhYmVsOiBfXygnRml4ZWQgaGVpZ2h0JywgJ2FtcCcpIH0sIHsgdmFsdWU6ICdmaXhlZCcsIGxhYmVsOiBfXygnRml4ZWQnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpbGwnLCBsYWJlbDogX18oJ0ZpbGwnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZsZXgtaXRlbScsIGxhYmVsOiBfXygnRmxleC1pdGVtJywgJ2FtcCcpIH0sIHsgdmFsdWU6ICdub2Rpc3BsYXknLCBsYWJlbDogX18oJ05vIERpc3BsYXknLCAnYW1wJykgfV07XG5cdFx0dmFyIHVybCA9IGZhbHNlO1xuXHRcdGlmIChkYXRhUGFydG5lciAmJiBkYXRhUGxheWVyICYmIChkYXRhVmlkZW8gfHwgZGF0YVBsYXlsaXN0IHx8IGRhdGFPdXRzdHJlYW0pKSB7XG5cdFx0XHR1cmwgPSAnaHR0cDovL2Nkbi5icmlkLnR2L2xpdmUvcGFydG5lcnMvJyArIGRhdGFQYXJ0bmVyO1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0RnJhZ21lbnQsXG5cdFx0XHRudWxsLFxuXHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRJbnNwZWN0b3JDb250cm9scyxcblx0XHRcdFx0eyBrZXk6ICdpbnNwZWN0b3InIH0sXG5cdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0XHRQYW5lbEJvZHksXG5cdFx0XHRcdFx0eyB0aXRsZTogX18oJ0JyaWQgUGxheWVyIFNldHRpbmdzJywgJ2FtcCcpIH0sXG5cdFx0XHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFRleHRDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ0JyaWQudHYgcGFydG5lciBJRCAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFQYXJ0bmVyLFxuXHRcdFx0XHRcdFx0b25DaGFuZ2U6IGZ1bmN0aW9uIG9uQ2hhbmdlKHZhbHVlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YVBhcnRuZXI6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUZXh0Q29udHJvbCwge1xuXHRcdFx0XHRcdFx0bGFiZWw6IF9fKCdCcmlkLnR2IHBsYXllciBJRCAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFQbGF5ZXIsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhUGxheWVyOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnVmlkZW8gSUQgKG9uZSBvZiB2aWRlbyAvIHBsYXlsaXN0IC8gb3V0c3RyZWFtIElEIGlzIHJlcXVpcmVkKScsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhVmlkZW8sXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhVmlkZW86IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUZXh0Q29udHJvbCwge1xuXHRcdFx0XHRcdFx0bGFiZWw6IF9fKCdPdXRzdHJlYW0gdW5pdCBJRCAob25lIG9mIHZpZGVvIC8gcGxheWxpc3QgLyBvdXRzdHJlYW0gSUQgaXMgcmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFPdXRzdHJlYW0sXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhT3V0c3RyZWFtOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnUGxheWxpc3QgSUQgKG9uZSBvZiB2aWRlbyAvIHBsYXlsaXN0IC8gb3V0c3RyZWFtIElEIGlzIHJlcXVpcmVkKScsICdhbXAnKSxcblx0XHRcdFx0XHRcdHZhbHVlOiBkYXRhUGxheWxpc3QsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhUGxheWxpc3Q6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUb2dnbGVDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ0F1dG9wbGF5JywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0Y2hlY2tlZDogYXV0b1BsYXksXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UoKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgYXV0b1BsYXk6ICFhdXRvUGxheSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRnZXRMYXlvdXRDb250cm9scyhwcm9wcywgYW1wTGF5b3V0T3B0aW9ucylcblx0XHRcdFx0KVxuXHRcdFx0KSxcblx0XHRcdHVybCAmJiBnZXRNZWRpYVBsYWNlaG9sZGVyKF9fKCdCcmlkIFBsYXllcicsICdhbXAnKSwgdXJsKSxcblx0XHRcdCF1cmwgJiYgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRQbGFjZWhvbGRlcixcblx0XHRcdFx0eyBsYWJlbDogX18oJ0JyaWQgUGxheWVyJywgJ2FtcCcpIH0sXG5cdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0XHQncCcsXG5cdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHRfXygnQWRkIHJlcXVpcmVkIGRhdGEgdG8gdXNlIHRoZSBibG9jay4nLCAnYW1wJylcblx0XHRcdFx0KVxuXHRcdFx0KVxuXHRcdCk7XG5cdH0sXG5cdHNhdmU6IGZ1bmN0aW9uIHNhdmUoX3JlZikge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gX3JlZi5hdHRyaWJ1dGVzO1xuXG5cdFx0dmFyIGJyaWRQcm9wcyA9IHtcblx0XHRcdGxheW91dDogYXR0cmlidXRlcy5hbXBMYXlvdXQsXG5cdFx0XHRoZWlnaHQ6IGF0dHJpYnV0ZXMuaGVpZ2h0LFxuXHRcdFx0J2RhdGEtcGxheWVyJzogYXR0cmlidXRlcy5kYXRhUGxheWVyLFxuXHRcdFx0J2RhdGEtcGFydG5lcic6IGF0dHJpYnV0ZXMuZGF0YVBhcnRuZXJcblx0XHR9O1xuXHRcdGlmICgnZml4ZWQtaGVpZ2h0JyAhPT0gYXR0cmlidXRlcy5hbXBMYXlvdXQgJiYgYXR0cmlidXRlcy53aWR0aCkge1xuXHRcdFx0YnJpZFByb3BzLndpZHRoID0gYXR0cmlidXRlcy53aWR0aDtcblx0XHR9XG5cdFx0aWYgKGF0dHJpYnV0ZXMuZGF0YVBsYXlsaXN0KSB7XG5cdFx0XHRicmlkUHJvcHNbJ2RhdGEtcGxheWxpc3QnXSA9IGF0dHJpYnV0ZXMuZGF0YVBsYXlsaXN0O1xuXHRcdH1cblx0XHRpZiAoYXR0cmlidXRlcy5kYXRhVmlkZW8pIHtcblx0XHRcdGJyaWRQcm9wc1snZGF0YS12aWRlbyddID0gYXR0cmlidXRlcy5kYXRhVmlkZW87XG5cdFx0fVxuXHRcdGlmIChhdHRyaWJ1dGVzLmRhdGFPdXRzdHJlYW0pIHtcblx0XHRcdGJyaWRQcm9wc1snZGF0YS1vdXRzdHJlYW0nXSA9IGF0dHJpYnV0ZXMuZGF0YU91dHN0cmVhbTtcblx0XHR9XG5cdFx0aWYgKGF0dHJpYnV0ZXMuYXV0b1BsYXkpIHtcblx0XHRcdGJyaWRQcm9wcy5hdXRvcGxheSA9IGF0dHJpYnV0ZXMuYXV0b1BsYXk7XG5cdFx0fVxuXHRcdHJldHVybiB3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoJ2FtcC1icmlkLXBsYXllcicsIGJyaWRQcm9wcyk7XG5cdH1cbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vYmxvY2tzL2FtcC1icmlkLXBsYXllci9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///11\n");
|
| 142 |
+
|
| 143 |
+
/***/ }),
|
| 144 |
+
/* 12 */
|
| 145 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 146 |
+
|
| 147 |
+
"use strict";
|
| 148 |
+
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);\n/**\n * Helper methods for blocks.\n */\n\n\n/**\n * Internal block libraries.\n */\nvar __ = wp.i18n.__;\nvar registerBlockType = wp.blocks.registerBlockType;\nvar InspectorControls = wp.editor.InspectorControls;\nvar Fragment = wp.element.Fragment;\nvar _wp$components = wp.components,\n PanelBody = _wp$components.PanelBody,\n TextControl = _wp$components.TextControl,\n Placeholder = _wp$components.Placeholder,\n ToggleControl = _wp$components.ToggleControl;\n\n/**\n * Register block.\n */\n\n/* unused harmony default export */ var _unused_webpack_default_export = (registerBlockType('amp/amp-ima-video', {\n\ttitle: __('AMP IMA Video', 'amp'),\n\tdescription: __('Embeds a video player for instream video ads that are integrated with the IMA SDK', 'amp'),\n\tcategory: 'embed',\n\ticon: 'embed-generic',\n\tkeywords: [__('Embed', 'amp')],\n\n\t// @todo Perhaps later add subtitles option and additional source options?\n\tattributes: {\n\t\tdataDelayAdRequest: {\n\t\t\tdefault: false,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ima-video',\n\t\t\tattribute: 'data-delay-ad-request'\n\t\t},\n\t\tdataTag: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ima-video',\n\t\t\tattribute: 'data-tag'\n\t\t},\n\t\tdataSrc: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ima-video',\n\t\t\tattribute: 'data-src'\n\t\t},\n\t\tdataPoster: {\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ima-video',\n\t\t\tattribute: 'data-poster'\n\t\t},\n\t\tampLayout: {\n\t\t\tdefault: 'responsive',\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ima-video',\n\t\t\tattribute: 'layout'\n\t\t},\n\t\twidth: {\n\t\t\tdefault: 600,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ima-video',\n\t\t\tattribute: 'width'\n\t\t},\n\t\theight: {\n\t\t\tdefault: 400,\n\t\t\tsource: 'attribute',\n\t\t\tselector: 'amp-ima-video',\n\t\t\tattribute: 'height'\n\t\t}\n\t},\n\n\tedit: function edit(props) {\n\t\tvar attributes = props.attributes,\n\t\t setAttributes = props.setAttributes;\n\t\tvar dataDelayAdRequest = attributes.dataDelayAdRequest,\n\t\t dataTag = attributes.dataTag,\n\t\t dataSrc = attributes.dataSrc,\n\t\t dataPoster = attributes.dataPoster;\n\n\t\tvar ampLayoutOptions = [{ value: 'responsive', label: __('Responsive', 'amp') }, { value: 'fixed', label: __('Fixed', 'amp') }];\n\t\tvar dataSet = false;\n\t\tif (dataTag && dataSrc) {\n\t\t\tdataSet = true;\n\t\t}\n\t\treturn wp.element.createElement(\n\t\t\tFragment,\n\t\t\tnull,\n\t\t\twp.element.createElement(\n\t\t\t\tInspectorControls,\n\t\t\t\t{ key: 'inspector' },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\tPanelBody,\n\t\t\t\t\t{ title: __('IMA Video Settings', 'amp') },\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Https URL for your VAST ad document (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataTag,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataTag: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Https URL of your video content (required)', 'amp'),\n\t\t\t\t\t\tvalue: dataSrc,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataSrc: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(TextControl, {\n\t\t\t\t\t\tlabel: __('Https URL to preview image', 'amp'),\n\t\t\t\t\t\tvalue: dataPoster,\n\t\t\t\t\t\tonChange: function onChange(value) {\n\t\t\t\t\t\t\treturn setAttributes({ dataPoster: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\twp.element.createElement(ToggleControl, {\n\t\t\t\t\t\tlabel: __('Delay Ad Request', 'amp'),\n\t\t\t\t\t\tchecked: dataDelayAdRequest,\n\t\t\t\t\t\tonChange: function onChange() {\n\t\t\t\t\t\t\treturn setAttributes({ dataDelayAdRequest: !dataDelayAdRequest });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tObject(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"a\" /* getLayoutControls */])(props, ampLayoutOptions)\n\t\t\t\t)\n\t\t\t),\n\t\t\tdataSet && Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__[\"b\" /* getMediaPlaceholder */])(__('IMA Video', 'amp'), dataSrc),\n\t\t\t!dataSet && wp.element.createElement(\n\t\t\t\tPlaceholder,\n\t\t\t\t{ label: __('IMA Video', 'amp') },\n\t\t\t\twp.element.createElement(\n\t\t\t\t\t'p',\n\t\t\t\t\tnull,\n\t\t\t\t\t__('Add required data to use the block.', 'amp')\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t},\n\tsave: function save(_ref) {\n\t\tvar attributes = _ref.attributes;\n\n\t\tvar imaProps = {\n\t\t\tlayout: attributes.ampLayout,\n\t\t\theight: attributes.height,\n\t\t\twidth: attributes.width,\n\t\t\t'data-tag': attributes.dataTag,\n\t\t\t'data-src': attributes.dataSrc\n\t\t};\n\t\tif (attributes.dataPoster) {\n\t\t\timaProps['data-poster'] = attributes.dataPoster;\n\t\t}\n\t\tif (attributes.dataDelayAdRequest) {\n\t\t\timaProps['data-delay-ad-request'] = attributes.dataDelayAdRequest;\n\t\t}\n\t\treturn wp.element.createElement('amp-ima-video', imaProps);\n\t}\n}));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTIuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ibG9ja3MvYW1wLWltYS12aWRlby9pbmRleC5qcz9kYzU1Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSGVscGVyIG1ldGhvZHMgZm9yIGJsb2Nrcy5cbiAqL1xuaW1wb3J0IHsgZ2V0TGF5b3V0Q29udHJvbHMsIGdldE1lZGlhUGxhY2Vob2xkZXIgfSBmcm9tICcuLi91dGlscy5qcyc7XG5cbi8qKlxuICogSW50ZXJuYWwgYmxvY2sgbGlicmFyaWVzLlxuICovXG52YXIgX18gPSB3cC5pMThuLl9fO1xudmFyIHJlZ2lzdGVyQmxvY2tUeXBlID0gd3AuYmxvY2tzLnJlZ2lzdGVyQmxvY2tUeXBlO1xudmFyIEluc3BlY3RvckNvbnRyb2xzID0gd3AuZWRpdG9yLkluc3BlY3RvckNvbnRyb2xzO1xudmFyIEZyYWdtZW50ID0gd3AuZWxlbWVudC5GcmFnbWVudDtcbnZhciBfd3AkY29tcG9uZW50cyA9IHdwLmNvbXBvbmVudHMsXG4gICAgUGFuZWxCb2R5ID0gX3dwJGNvbXBvbmVudHMuUGFuZWxCb2R5LFxuICAgIFRleHRDb250cm9sID0gX3dwJGNvbXBvbmVudHMuVGV4dENvbnRyb2wsXG4gICAgUGxhY2Vob2xkZXIgPSBfd3AkY29tcG9uZW50cy5QbGFjZWhvbGRlcixcbiAgICBUb2dnbGVDb250cm9sID0gX3dwJGNvbXBvbmVudHMuVG9nZ2xlQ29udHJvbDtcblxuLyoqXG4gKiBSZWdpc3RlciBibG9jay5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCByZWdpc3RlckJsb2NrVHlwZSgnYW1wL2FtcC1pbWEtdmlkZW8nLCB7XG5cdHRpdGxlOiBfXygnQU1QIElNQSBWaWRlbycsICdhbXAnKSxcblx0ZGVzY3JpcHRpb246IF9fKCdFbWJlZHMgYSB2aWRlbyBwbGF5ZXIgZm9yIGluc3RyZWFtIHZpZGVvIGFkcyB0aGF0IGFyZSBpbnRlZ3JhdGVkIHdpdGggdGhlIElNQSBTREsnLCAnYW1wJyksXG5cdGNhdGVnb3J5OiAnZW1iZWQnLFxuXHRpY29uOiAnZW1iZWQtZ2VuZXJpYycsXG5cdGtleXdvcmRzOiBbX18oJ0VtYmVkJywgJ2FtcCcpXSxcblxuXHQvLyBAdG9kbyBQZXJoYXBzIGxhdGVyIGFkZCBzdWJ0aXRsZXMgb3B0aW9uIGFuZCBhZGRpdGlvbmFsIHNvdXJjZSBvcHRpb25zP1xuXHRhdHRyaWJ1dGVzOiB7XG5cdFx0ZGF0YURlbGF5QWRSZXF1ZXN0OiB7XG5cdFx0XHRkZWZhdWx0OiBmYWxzZSxcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1pbWEtdmlkZW8nLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1kZWxheS1hZC1yZXF1ZXN0J1xuXHRcdH0sXG5cdFx0ZGF0YVRhZzoge1xuXHRcdFx0c291cmNlOiAnYXR0cmlidXRlJyxcblx0XHRcdHNlbGVjdG9yOiAnYW1wLWltYS12aWRlbycsXG5cdFx0XHRhdHRyaWJ1dGU6ICdkYXRhLXRhZydcblx0XHR9LFxuXHRcdGRhdGFTcmM6IHtcblx0XHRcdHNvdXJjZTogJ2F0dHJpYnV0ZScsXG5cdFx0XHRzZWxlY3RvcjogJ2FtcC1pbWEtdmlkZW8nLFxuXHRcdFx0YXR0cmlidXRlOiAnZGF0YS1zcmMnXG5cdFx0fSxcblx0XHRkYXRhUG9zdGVyOiB7XG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtaW1hLXZpZGVvJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2RhdGEtcG9zdGVyJ1xuXHRcdH0sXG5cdFx0YW1wTGF5b3V0OiB7XG5cdFx0XHRkZWZhdWx0OiAncmVzcG9uc2l2ZScsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtaW1hLXZpZGVvJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2xheW91dCdcblx0XHR9LFxuXHRcdHdpZHRoOiB7XG5cdFx0XHRkZWZhdWx0OiA2MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtaW1hLXZpZGVvJyxcblx0XHRcdGF0dHJpYnV0ZTogJ3dpZHRoJ1xuXHRcdH0sXG5cdFx0aGVpZ2h0OiB7XG5cdFx0XHRkZWZhdWx0OiA0MDAsXG5cdFx0XHRzb3VyY2U6ICdhdHRyaWJ1dGUnLFxuXHRcdFx0c2VsZWN0b3I6ICdhbXAtaW1hLXZpZGVvJyxcblx0XHRcdGF0dHJpYnV0ZTogJ2hlaWdodCdcblx0XHR9XG5cdH0sXG5cblx0ZWRpdDogZnVuY3Rpb24gZWRpdChwcm9wcykge1xuXHRcdHZhciBhdHRyaWJ1dGVzID0gcHJvcHMuYXR0cmlidXRlcyxcblx0XHQgICAgc2V0QXR0cmlidXRlcyA9IHByb3BzLnNldEF0dHJpYnV0ZXM7XG5cdFx0dmFyIGRhdGFEZWxheUFkUmVxdWVzdCA9IGF0dHJpYnV0ZXMuZGF0YURlbGF5QWRSZXF1ZXN0LFxuXHRcdCAgICBkYXRhVGFnID0gYXR0cmlidXRlcy5kYXRhVGFnLFxuXHRcdCAgICBkYXRhU3JjID0gYXR0cmlidXRlcy5kYXRhU3JjLFxuXHRcdCAgICBkYXRhUG9zdGVyID0gYXR0cmlidXRlcy5kYXRhUG9zdGVyO1xuXG5cdFx0dmFyIGFtcExheW91dE9wdGlvbnMgPSBbeyB2YWx1ZTogJ3Jlc3BvbnNpdmUnLCBsYWJlbDogX18oJ1Jlc3BvbnNpdmUnLCAnYW1wJykgfSwgeyB2YWx1ZTogJ2ZpeGVkJywgbGFiZWw6IF9fKCdGaXhlZCcsICdhbXAnKSB9XTtcblx0XHR2YXIgZGF0YVNldCA9IGZhbHNlO1xuXHRcdGlmIChkYXRhVGFnICYmIGRhdGFTcmMpIHtcblx0XHRcdGRhdGFTZXQgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0RnJhZ21lbnQsXG5cdFx0XHRudWxsLFxuXHRcdFx0d3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRJbnNwZWN0b3JDb250cm9scyxcblx0XHRcdFx0eyBrZXk6ICdpbnNwZWN0b3InIH0sXG5cdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChcblx0XHRcdFx0XHRQYW5lbEJvZHksXG5cdFx0XHRcdFx0eyB0aXRsZTogX18oJ0lNQSBWaWRlbyBTZXR0aW5ncycsICdhbXAnKSB9LFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUZXh0Q29udHJvbCwge1xuXHRcdFx0XHRcdFx0bGFiZWw6IF9fKCdIdHRwcyBVUkwgZm9yIHlvdXIgVkFTVCBhZCBkb2N1bWVudCAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFUYWcsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhVGFnOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnSHR0cHMgVVJMIG9mIHlvdXIgdmlkZW8gY29udGVudCAocmVxdWlyZWQpJywgJ2FtcCcpLFxuXHRcdFx0XHRcdFx0dmFsdWU6IGRhdGFTcmMsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UodmFsdWUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNldEF0dHJpYnV0ZXMoeyBkYXRhU3JjOiB2YWx1ZSB9KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoVGV4dENvbnRyb2wsIHtcblx0XHRcdFx0XHRcdGxhYmVsOiBfXygnSHR0cHMgVVJMIHRvIHByZXZpZXcgaW1hZ2UnLCAnYW1wJyksXG5cdFx0XHRcdFx0XHR2YWx1ZTogZGF0YVBvc3Rlcixcblx0XHRcdFx0XHRcdG9uQ2hhbmdlOiBmdW5jdGlvbiBvbkNoYW5nZSh2YWx1ZSkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gc2V0QXR0cmlidXRlcyh7IGRhdGFQb3N0ZXI6IHZhbHVlIH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdHdwLmVsZW1lbnQuY3JlYXRlRWxlbWVudChUb2dnbGVDb250cm9sLCB7XG5cdFx0XHRcdFx0XHRsYWJlbDogX18oJ0RlbGF5IEFkIFJlcXVlc3QnLCAnYW1wJyksXG5cdFx0XHRcdFx0XHRjaGVja2VkOiBkYXRhRGVsYXlBZFJlcXVlc3QsXG5cdFx0XHRcdFx0XHRvbkNoYW5nZTogZnVuY3Rpb24gb25DaGFuZ2UoKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRBdHRyaWJ1dGVzKHsgZGF0YURlbGF5QWRSZXF1ZXN0OiAhZGF0YURlbGF5QWRSZXF1ZXN0IH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdGdldExheW91dENvbnRyb2xzKHByb3BzLCBhbXBMYXlvdXRPcHRpb25zKVxuXHRcdFx0XHQpXG5cdFx0XHQpLFxuXHRcdFx0ZGF0YVNldCAmJiBnZXRNZWRpYVBsYWNlaG9sZGVyKF9fKCdJTUEgVmlkZW8nLCAnYW1wJyksIGRhdGFTcmMpLFxuXHRcdFx0IWRhdGFTZXQgJiYgd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KFxuXHRcdFx0XHRQbGFjZWhvbGRlcixcblx0XHRcdFx0eyBsYWJlbDogX18oJ0lNQSBWaWRlbycsICdhbXAnKSB9LFxuXHRcdFx0XHR3cC5lbGVtZW50LmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0J3AnLFxuXHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0X18oJ0FkZCByZXF1aXJlZCBkYXRhIHRvIHVzZSB0aGUgYmxvY2suJywgJ2FtcCcpXG5cdFx0XHRcdClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXHRzYXZlOiBmdW5jdGlvbiBzYXZlKF9yZWYpIHtcblx0XHR2YXIgYXR0cmlidXRlcyA9IF9yZWYuYXR0cmlidXRlcztcblxuXHRcdHZhciBpbWFQcm9wcyA9IHtcblx0XHRcdGxheW91dDogYXR0cmlidXRlcy5hbXBMYXlvdXQsXG5cdFx0XHRoZWlnaHQ6IGF0dHJpYnV0ZXMuaGVpZ2h0LFxuXHRcdFx0d2lkdGg6IGF0dHJpYnV0ZXMud2lkdGgsXG5cdFx0XHQnZGF0YS10YWcnOiBhdHRyaWJ1dGVzLmRhdGFUYWcsXG5cdFx0XHQnZGF0YS1zcmMnOiBhdHRyaWJ1dGVzLmRhdGFTcmNcblx0XHR9O1xuXHRcdGlmIChhdHRyaWJ1dGVzLmRhdGFQb3N0ZXIpIHtcblx0XHRcdGltYVByb3BzWydkYXRhLXBvc3RlciddID0gYXR0cmlidXRlcy5kYXRhUG9zdGVyO1xuXHRcdH1cblx0XHRpZiAoYXR0cmlidXRlcy5kYXRhRGVsYXlBZFJlcXVlc3QpIHtcblx0XHRcdGltYVByb3BzWydkYXRhLWRlbGF5LWFkLXJlcXVlc3QnXSA9IGF0dHJpYnV0ZXMuZGF0YURlbGF5QWRSZXF1ZXN0O1xuXHRcdH1cblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KCdhbXAtaW1hLXZpZGVvJywgaW1hUHJvcHMpO1xuXHR9XG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2Jsb2Nrcy9hbXAtaW1hLXZpZGVvL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///12\n");
|
| 149 |
+
|
| 150 |
+
/***/ })
|
| 151 |
+
/******/ ]);
|
|
@@ -1,7 +1,7 @@
|
|
| 1 |
/* exported ampCustomizeControls */
|
| 2 |
/* eslint no-magic-numbers: [ "error", { "ignore": [ 0, 1, 250] } ] */
|
| 3 |
|
| 4 |
-
var ampCustomizeControls = ( function( api, $ ) {
|
| 5 |
'use strict';
|
| 6 |
|
| 7 |
var component = {
|
|
@@ -46,7 +46,7 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 46 |
/**
|
| 47 |
* Add state for AMP.
|
| 48 |
*
|
| 49 |
-
* @
|
| 50 |
*/
|
| 51 |
component.addState = function addState() {
|
| 52 |
api.state.add( 'ampEnabled', new api.Value( false ) );
|
|
@@ -84,7 +84,7 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 84 |
urlParser.href = url;
|
| 85 |
urlParser.pathname = urlParser.pathname.replace( regexEndpoint, '' );
|
| 86 |
|
| 87 |
-
if ( urlParser.search.length
|
| 88 |
params = wp.customize.utils.parseQueryString( urlParser.search.substr( 1 ) );
|
| 89 |
delete params[ component.data.queryVar ];
|
| 90 |
urlParser.search = $.param( params );
|
|
@@ -112,7 +112,7 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 112 |
/**
|
| 113 |
* Try to close the tooltip after a given timeout.
|
| 114 |
*
|
| 115 |
-
* @
|
| 116 |
*/
|
| 117 |
component.tryToCloseTooltip = function tryToCloseTooltip() {
|
| 118 |
clearTimeout( component.tooltipTimeoutId );
|
|
@@ -120,7 +120,7 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 120 |
if ( ! component.tooltipVisible.get() ) {
|
| 121 |
return;
|
| 122 |
}
|
| 123 |
-
if ( component.tooltipFocused.get()
|
| 124 |
component.tryToCloseTooltip();
|
| 125 |
} else {
|
| 126 |
component.tooltipVisible.set( false );
|
|
@@ -157,7 +157,7 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 157 |
* Enable AMP and navigate to the given URL.
|
| 158 |
*
|
| 159 |
* @param {string} url - URL.
|
| 160 |
-
* @
|
| 161 |
*/
|
| 162 |
component.enableAndNavigateToUrl = function enableAndNavigateToUrl( url ) {
|
| 163 |
api.state( 'ampEnabled' ).set( true );
|
|
@@ -167,10 +167,11 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 167 |
/**
|
| 168 |
* Update panel notifications.
|
| 169 |
*
|
| 170 |
-
* @
|
| 171 |
*/
|
| 172 |
component.updatePanelNotifications = function updatePanelNotifications() {
|
| 173 |
-
var panel = api.panel( component.data.panelId ),
|
|
|
|
| 174 |
containers = panel.sections().concat( [ panel ] );
|
| 175 |
if ( api.state( 'ampAvailable' ).get() ) {
|
| 176 |
_.each( containers, function( container ) {
|
|
@@ -223,7 +224,6 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 223 |
if ( api.state( 'ampAvailable' ).get() ) {
|
| 224 |
api.state( 'ampEnabled' ).set( panel.expanded.get() );
|
| 225 |
} else if ( ! panel.notifications ) {
|
| 226 |
-
|
| 227 |
/*
|
| 228 |
* This is only done if panel notifications aren't supported.
|
| 229 |
* If they are (as of 4.9) then a notification will be shown
|
|
@@ -270,7 +270,7 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 270 |
}
|
| 271 |
return val;
|
| 272 |
};
|
| 273 |
-
}
|
| 274 |
|
| 275 |
// Listen for ampEnabled state changes.
|
| 276 |
api.state( 'ampEnabled' ).bind( function( enabled ) {
|
|
@@ -302,7 +302,7 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 302 |
tooltip.attr( 'aria-hidden', visible ? 'false' : 'true' );
|
| 303 |
if ( visible ) {
|
| 304 |
$( document ).on( 'click.amp-toggle-outside', function( event ) {
|
| 305 |
-
if ( ! $.contains( ampToggleContainer[0], event.target ) ) {
|
| 306 |
component.tooltipVisible.set( false );
|
| 307 |
}
|
| 308 |
} );
|
|
@@ -347,5 +347,4 @@ var ampCustomizeControls = ( function( api, $ ) {
|
|
| 347 |
};
|
| 348 |
|
| 349 |
return component;
|
| 350 |
-
|
| 351 |
-
} )( wp.customize, jQuery );
|
| 1 |
/* exported ampCustomizeControls */
|
| 2 |
/* eslint no-magic-numbers: [ "error", { "ignore": [ 0, 1, 250] } ] */
|
| 3 |
|
| 4 |
+
var ampCustomizeControls = ( function( api, $ ) { // eslint-disable-line no-unused-vars
|
| 5 |
'use strict';
|
| 6 |
|
| 7 |
var component = {
|
| 46 |
/**
|
| 47 |
* Add state for AMP.
|
| 48 |
*
|
| 49 |
+
* @return {void}
|
| 50 |
*/
|
| 51 |
component.addState = function addState() {
|
| 52 |
api.state.add( 'ampEnabled', new api.Value( false ) );
|
| 84 |
urlParser.href = url;
|
| 85 |
urlParser.pathname = urlParser.pathname.replace( regexEndpoint, '' );
|
| 86 |
|
| 87 |
+
if ( 1 < urlParser.search.length ) {
|
| 88 |
params = wp.customize.utils.parseQueryString( urlParser.search.substr( 1 ) );
|
| 89 |
delete params[ component.data.queryVar ];
|
| 90 |
urlParser.search = $.param( params );
|
| 112 |
/**
|
| 113 |
* Try to close the tooltip after a given timeout.
|
| 114 |
*
|
| 115 |
+
* @return {void}
|
| 116 |
*/
|
| 117 |
component.tryToCloseTooltip = function tryToCloseTooltip() {
|
| 118 |
clearTimeout( component.tooltipTimeoutId );
|
| 120 |
if ( ! component.tooltipVisible.get() ) {
|
| 121 |
return;
|
| 122 |
}
|
| 123 |
+
if ( 0 < component.tooltipFocused.get() ) {
|
| 124 |
component.tryToCloseTooltip();
|
| 125 |
} else {
|
| 126 |
component.tooltipVisible.set( false );
|
| 157 |
* Enable AMP and navigate to the given URL.
|
| 158 |
*
|
| 159 |
* @param {string} url - URL.
|
| 160 |
+
* @return {void}
|
| 161 |
*/
|
| 162 |
component.enableAndNavigateToUrl = function enableAndNavigateToUrl( url ) {
|
| 163 |
api.state( 'ampEnabled' ).set( true );
|
| 167 |
/**
|
| 168 |
* Update panel notifications.
|
| 169 |
*
|
| 170 |
+
* @return {void}
|
| 171 |
*/
|
| 172 |
component.updatePanelNotifications = function updatePanelNotifications() {
|
| 173 |
+
var panel = api.panel( component.data.panelId ),
|
| 174 |
+
containers;
|
| 175 |
containers = panel.sections().concat( [ panel ] );
|
| 176 |
if ( api.state( 'ampAvailable' ).get() ) {
|
| 177 |
_.each( containers, function( container ) {
|
| 224 |
if ( api.state( 'ampAvailable' ).get() ) {
|
| 225 |
api.state( 'ampEnabled' ).set( panel.expanded.get() );
|
| 226 |
} else if ( ! panel.notifications ) {
|
|
|
|
| 227 |
/*
|
| 228 |
* This is only done if panel notifications aren't supported.
|
| 229 |
* If they are (as of 4.9) then a notification will be shown
|
| 270 |
}
|
| 271 |
return val;
|
| 272 |
};
|
| 273 |
+
}( api.previewer.previewUrl.validate ) );
|
| 274 |
|
| 275 |
// Listen for ampEnabled state changes.
|
| 276 |
api.state( 'ampEnabled' ).bind( function( enabled ) {
|
| 302 |
tooltip.attr( 'aria-hidden', visible ? 'false' : 'true' );
|
| 303 |
if ( visible ) {
|
| 304 |
$( document ).on( 'click.amp-toggle-outside', function( event ) {
|
| 305 |
+
if ( ! $.contains( ampToggleContainer[ 0 ], event.target ) ) {
|
| 306 |
component.tooltipVisible.set( false );
|
| 307 |
}
|
| 308 |
} );
|
| 347 |
};
|
| 348 |
|
| 349 |
return component;
|
| 350 |
+
}( wp.customize, jQuery ) );
|
|
|
|
@@ -1,6 +1,6 @@
|
|
| 1 |
/* exported ampCustomizePreview */
|
| 2 |
|
| 3 |
-
var ampCustomizePreview = ( function( api ) {
|
| 4 |
'use strict';
|
| 5 |
|
| 6 |
var component = {};
|
|
@@ -22,5 +22,4 @@ var ampCustomizePreview = ( function( api ) {
|
|
| 22 |
};
|
| 23 |
|
| 24 |
return component;
|
| 25 |
-
|
| 26 |
-
} )( wp.customize );
|
| 1 |
/* exported ampCustomizePreview */
|
| 2 |
|
| 3 |
+
var ampCustomizePreview = ( function( api ) { // eslint-disable-line no-unused-vars
|
| 4 |
'use strict';
|
| 5 |
|
| 6 |
var component = {};
|
| 22 |
};
|
| 23 |
|
| 24 |
return component;
|
| 25 |
+
}( wp.customize ) );
|
|
|
|
@@ -24,10 +24,10 @@
|
|
| 24 |
// AMP background color scheme.
|
| 25 |
wp.customize( 'amp_customizer[color_scheme]', function( value ) {
|
| 26 |
value.bind( function( to ) {
|
| 27 |
-
var colors = amp_customizer_design.color_schemes[ to ];
|
| 28 |
|
| 29 |
if ( ! colors ) {
|
| 30 |
-
console.error( 'Selected color scheme "%s" not registered.', to );
|
| 31 |
return;
|
| 32 |
}
|
| 33 |
|
|
@@ -45,5 +45,4 @@
|
|
| 45 |
$( '.amp-wp-header .amp-site-title, .amp-wp-footer h2' ).text( title );
|
| 46 |
} );
|
| 47 |
} );
|
| 48 |
-
|
| 49 |
-
} )( jQuery );
|
| 24 |
// AMP background color scheme.
|
| 25 |
wp.customize( 'amp_customizer[color_scheme]', function( value ) {
|
| 26 |
value.bind( function( to ) {
|
| 27 |
+
var colors = amp_customizer_design.color_schemes[ to ]; // eslint-disable-line
|
| 28 |
|
| 29 |
if ( ! colors ) {
|
| 30 |
+
console.error( 'Selected color scheme "%s" not registered.', to ); // eslint-disable-line
|
| 31 |
return;
|
| 32 |
}
|
| 33 |
|
| 45 |
$( '.amp-wp-header .amp-site-title, .amp-wp-footer h2' ).text( title );
|
| 46 |
} );
|
| 47 |
} );
|
| 48 |
+
}( jQuery ) );
|
|
|
|
@@ -0,0 +1,852 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* exported ampEditorBlocks */
|
| 2 |
+
/* eslint no-magic-numbers: [ "error", { "ignore": [ 1, -1, 0, 4 ] } ] */
|
| 3 |
+
|
| 4 |
+
var ampEditorBlocks = ( function() { // eslint-disable-line no-unused-vars
|
| 5 |
+
var component, __;
|
| 6 |
+
|
| 7 |
+
__ = wp.i18n.__;
|
| 8 |
+
|
| 9 |
+
component = {
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Holds data.
|
| 13 |
+
*/
|
| 14 |
+
data: {
|
| 15 |
+
ampLayoutOptions: [
|
| 16 |
+
{
|
| 17 |
+
value: 'nodisplay',
|
| 18 |
+
label: __( 'No Display', 'amp' ),
|
| 19 |
+
notAvailable: [
|
| 20 |
+
'core-embed/vimeo',
|
| 21 |
+
'core-embed/dailymotion',
|
| 22 |
+
'core-embed/hulu',
|
| 23 |
+
'core-embed/reddit',
|
| 24 |
+
'core-embed/soundcloud'
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
// Not supported by amp-audio and amp-pixel.
|
| 29 |
+
value: 'fixed',
|
| 30 |
+
label: __( 'Fixed', 'amp' ),
|
| 31 |
+
notAvailable: [
|
| 32 |
+
'core-embed/soundcloud'
|
| 33 |
+
]
|
| 34 |
+
},
|
| 35 |
+
{
|
| 36 |
+
// To ensure your AMP element displays, you must specify a width and height for the containing element.
|
| 37 |
+
value: 'responsive',
|
| 38 |
+
label: __( 'Responsive', 'amp' ),
|
| 39 |
+
notAvailable: [
|
| 40 |
+
'core/audio',
|
| 41 |
+
'core-embed/soundcloud'
|
| 42 |
+
]
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
value: 'fixed-height',
|
| 46 |
+
label: __( 'Fixed height', 'amp' ),
|
| 47 |
+
notAvailable: []
|
| 48 |
+
},
|
| 49 |
+
{
|
| 50 |
+
value: 'fill',
|
| 51 |
+
label: __( 'Fill', 'amp' ),
|
| 52 |
+
notAvailable: [
|
| 53 |
+
'core/audio',
|
| 54 |
+
'core-embed/soundcloud'
|
| 55 |
+
]
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
value: 'flex-item',
|
| 59 |
+
label: __( 'Flex Item', 'amp' ),
|
| 60 |
+
notAvailable: [
|
| 61 |
+
'core/audio',
|
| 62 |
+
'core-embed/soundcloud'
|
| 63 |
+
]
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
// Not supported by video.
|
| 67 |
+
value: 'intrinsic',
|
| 68 |
+
label: __( 'Intrinsic', 'amp' ),
|
| 69 |
+
notAvailable: [
|
| 70 |
+
'core/audio',
|
| 71 |
+
'core-embed/youtube',
|
| 72 |
+
'core-embed/facebook',
|
| 73 |
+
'core-embed/instagram',
|
| 74 |
+
'core-embed/vimeo',
|
| 75 |
+
'core-embed/dailymotion',
|
| 76 |
+
'core-embed/hulu',
|
| 77 |
+
'core-embed/reddit',
|
| 78 |
+
'core-embed/soundcloud'
|
| 79 |
+
]
|
| 80 |
+
}
|
| 81 |
+
],
|
| 82 |
+
defaultWidth: 608, // Max-width in the editor.
|
| 83 |
+
defaultHeight: 400,
|
| 84 |
+
mediaBlocks: [
|
| 85 |
+
'core/image',
|
| 86 |
+
'core/video',
|
| 87 |
+
'core/audio'
|
| 88 |
+
],
|
| 89 |
+
textBlocks: [
|
| 90 |
+
'core/paragraph',
|
| 91 |
+
'core/heading',
|
| 92 |
+
'core/code',
|
| 93 |
+
'core/quote',
|
| 94 |
+
'core/subhead'
|
| 95 |
+
],
|
| 96 |
+
ampSettingsLabel: __( 'AMP Settings' ),
|
| 97 |
+
fontSizes: {
|
| 98 |
+
small: 14,
|
| 99 |
+
larger: 48
|
| 100 |
+
},
|
| 101 |
+
ampPanelLabel: __( 'AMP Settings' )
|
| 102 |
+
},
|
| 103 |
+
hasThemeSupport: true
|
| 104 |
+
};
|
| 105 |
+
|
| 106 |
+
/**
|
| 107 |
+
* Add filters.
|
| 108 |
+
*
|
| 109 |
+
* @param {Object} data Data.
|
| 110 |
+
*/
|
| 111 |
+
component.boot = function boot( data ) {
|
| 112 |
+
if ( data ) {
|
| 113 |
+
_.extend( component.data, data );
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
wp.hooks.addFilter( 'blocks.registerBlockType', 'ampEditorBlocks/addAttributes', component.addAMPAttributes );
|
| 117 |
+
wp.hooks.addFilter( 'blocks.getSaveElement', 'ampEditorBlocks/filterSave', component.filterBlocksSave );
|
| 118 |
+
wp.hooks.addFilter( 'editor.BlockEdit', 'ampEditorBlocks/filterEdit', component.filterBlocksEdit );
|
| 119 |
+
wp.hooks.addFilter( 'blocks.getSaveContent.extraProps', 'ampEditorBlocks/addExtraAttributes', component.addAMPExtraProps );
|
| 120 |
+
};
|
| 121 |
+
|
| 122 |
+
/**
|
| 123 |
+
* Check if layout is available for the block.
|
| 124 |
+
*
|
| 125 |
+
* @param {string} blockName Block name.
|
| 126 |
+
* @param {Object} option Layout option object.
|
| 127 |
+
* @return {boolean} If is available.
|
| 128 |
+
*/
|
| 129 |
+
component.isLayoutAvailable = function isLayoutAvailable( blockName, option ) {
|
| 130 |
+
return -1 === option.notAvailable.indexOf( blockName );
|
| 131 |
+
};
|
| 132 |
+
|
| 133 |
+
/**
|
| 134 |
+
* Get layout options depending on the block.
|
| 135 |
+
*
|
| 136 |
+
* @param {string} blockName Block name.
|
| 137 |
+
* @return {[*]} Options.
|
| 138 |
+
*/
|
| 139 |
+
component.getLayoutOptions = function getLayoutOptions( blockName ) {
|
| 140 |
+
var layoutOptions = [
|
| 141 |
+
{
|
| 142 |
+
value: '',
|
| 143 |
+
label: __( 'Default', 'amp' )
|
| 144 |
+
}
|
| 145 |
+
];
|
| 146 |
+
|
| 147 |
+
_.each( component.data.ampLayoutOptions, function( option ) {
|
| 148 |
+
if ( component.isLayoutAvailable( blockName, option ) ) {
|
| 149 |
+
layoutOptions.push( {
|
| 150 |
+
value: option.value,
|
| 151 |
+
label: option.label
|
| 152 |
+
} );
|
| 153 |
+
}
|
| 154 |
+
} );
|
| 155 |
+
|
| 156 |
+
return layoutOptions;
|
| 157 |
+
};
|
| 158 |
+
|
| 159 |
+
/**
|
| 160 |
+
* Add extra data-amp-layout attribute to save to DB.
|
| 161 |
+
*
|
| 162 |
+
* @param {Object} props Properties.
|
| 163 |
+
* @param {Object} blockType Block type.
|
| 164 |
+
* @param {Object} attributes Attributes.
|
| 165 |
+
* @return {Object} Props.
|
| 166 |
+
*/
|
| 167 |
+
component.addAMPExtraProps = function addAMPExtraProps( props, blockType, attributes ) {
|
| 168 |
+
var ampAttributes = {};
|
| 169 |
+
|
| 170 |
+
// Shortcode props are handled differently.
|
| 171 |
+
if ( 'core/shortcode' === blockType.name ) {
|
| 172 |
+
return props;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
// AMP blocks handle layout and other props on their own.
|
| 176 |
+
if ( 'amp/' === blockType.name.substr( 0, 4 ) ) {
|
| 177 |
+
return props;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
if ( attributes.ampLayout ) {
|
| 181 |
+
ampAttributes[ 'data-amp-layout' ] = attributes.ampLayout;
|
| 182 |
+
}
|
| 183 |
+
if ( attributes.ampNoLoading ) {
|
| 184 |
+
ampAttributes[ 'data-amp-noloading' ] = attributes.ampNoLoading;
|
| 185 |
+
}
|
| 186 |
+
if ( attributes.ampLightbox ) {
|
| 187 |
+
ampAttributes[ 'data-amp-lightbox' ] = attributes.ampLightbox;
|
| 188 |
+
}
|
| 189 |
+
if ( attributes.ampCarousel ) {
|
| 190 |
+
ampAttributes[ 'data-amp-carousel' ] = attributes.ampCarousel;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
return _.extend( ampAttributes, props );
|
| 194 |
+
};
|
| 195 |
+
|
| 196 |
+
/**
|
| 197 |
+
* Add AMP attributes (in this test case just ampLayout) to every core block.
|
| 198 |
+
*
|
| 199 |
+
* @param {Object} settings Settings.
|
| 200 |
+
* @param {string} name Block name.
|
| 201 |
+
* @return {Object} Settings.
|
| 202 |
+
*/
|
| 203 |
+
component.addAMPAttributes = function addAMPAttributes( settings, name ) {
|
| 204 |
+
// AMP Carousel settings.
|
| 205 |
+
if ( 'core/shortcode' === name || 'core/gallery' === name ) {
|
| 206 |
+
if ( ! settings.attributes ) {
|
| 207 |
+
settings.attributes = {};
|
| 208 |
+
}
|
| 209 |
+
settings.attributes.ampCarousel = {
|
| 210 |
+
type: 'boolean'
|
| 211 |
+
};
|
| 212 |
+
settings.attributes.ampLightbox = {
|
| 213 |
+
type: 'boolean'
|
| 214 |
+
};
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
// Add AMP Lightbox settings.
|
| 218 |
+
if ( 'core/image' === name ) {
|
| 219 |
+
if ( ! settings.attributes ) {
|
| 220 |
+
settings.attributes = {};
|
| 221 |
+
}
|
| 222 |
+
settings.attributes.ampLightbox = {
|
| 223 |
+
type: 'boolean'
|
| 224 |
+
};
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
// Fit-text for text blocks.
|
| 228 |
+
if ( -1 !== component.data.textBlocks.indexOf( name ) ) {
|
| 229 |
+
if ( ! settings.attributes ) {
|
| 230 |
+
settings.attributes = {};
|
| 231 |
+
}
|
| 232 |
+
settings.attributes.ampFitText = {
|
| 233 |
+
default: false
|
| 234 |
+
};
|
| 235 |
+
settings.attributes.minFont = {
|
| 236 |
+
default: component.data.fontSizes.small,
|
| 237 |
+
source: 'attribute',
|
| 238 |
+
selector: 'amp-fit-text',
|
| 239 |
+
attribute: 'min-font-size'
|
| 240 |
+
};
|
| 241 |
+
settings.attributes.maxFont = {
|
| 242 |
+
default: component.data.fontSizes.larger,
|
| 243 |
+
source: 'attribute',
|
| 244 |
+
selector: 'amp-fit-text',
|
| 245 |
+
attribute: 'max-font-size'
|
| 246 |
+
};
|
| 247 |
+
settings.attributes.height = {
|
| 248 |
+
default: 50,
|
| 249 |
+
source: 'attribute',
|
| 250 |
+
selector: 'amp-fit-text',
|
| 251 |
+
attribute: 'height'
|
| 252 |
+
};
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
// Layout settings for embeds and media blocks.
|
| 256 |
+
if ( 0 === name.indexOf( 'core-embed' ) || -1 !== component.data.mediaBlocks.indexOf( name ) ) {
|
| 257 |
+
if ( ! settings.attributes ) {
|
| 258 |
+
settings.attributes = {};
|
| 259 |
+
}
|
| 260 |
+
settings.attributes.ampLayout = {
|
| 261 |
+
type: 'string'
|
| 262 |
+
};
|
| 263 |
+
settings.attributes.ampNoLoading = {
|
| 264 |
+
type: 'boolean'
|
| 265 |
+
};
|
| 266 |
+
}
|
| 267 |
+
return settings;
|
| 268 |
+
};
|
| 269 |
+
|
| 270 |
+
/**
|
| 271 |
+
* Filters blocks edit function of all blocks.
|
| 272 |
+
*
|
| 273 |
+
* @param {Function} BlockEdit Edit function.
|
| 274 |
+
* @return {Function} Edit function.
|
| 275 |
+
*/
|
| 276 |
+
component.filterBlocksEdit = function filterBlocksEdit( BlockEdit ) {
|
| 277 |
+
var el = wp.element.createElement;
|
| 278 |
+
|
| 279 |
+
return function( props ) {
|
| 280 |
+
var attributes = props.attributes,
|
| 281 |
+
name = props.name,
|
| 282 |
+
ampLayout,
|
| 283 |
+
inspectorControls;
|
| 284 |
+
|
| 285 |
+
ampLayout = attributes.ampLayout;
|
| 286 |
+
|
| 287 |
+
if ( 'core/shortcode' === name ) {
|
| 288 |
+
// Lets remove amp-carousel from edit view.
|
| 289 |
+
if ( component.hasGalleryShortcodeCarouselAttribute( attributes.text || '' ) ) {
|
| 290 |
+
props.setAttributes( { text: component.removeAmpCarouselFromShortcodeAtts( attributes.text ) } );
|
| 291 |
+
}
|
| 292 |
+
// Lets remove amp-lightbox from edit view.
|
| 293 |
+
if ( component.hasGalleryShortcodeLightboxAttribute( attributes.text || '' ) ) {
|
| 294 |
+
props.setAttributes( { text: component.removeAmpLightboxFromShortcodeAtts( attributes.text ) } );
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
inspectorControls = component.setUpShortcodeInspectorControls( props );
|
| 298 |
+
if ( '' === inspectorControls ) {
|
| 299 |
+
// Return original.
|
| 300 |
+
return [
|
| 301 |
+
el( BlockEdit, _.extend( {
|
| 302 |
+
key: 'original'
|
| 303 |
+
}, props ) )
|
| 304 |
+
];
|
| 305 |
+
}
|
| 306 |
+
} else if ( 'core/gallery' === name ) {
|
| 307 |
+
inspectorControls = component.setUpGalleryInpsectorControls( props );
|
| 308 |
+
} else if ( 'core/image' === name ) {
|
| 309 |
+
inspectorControls = component.setUpImageInpsectorControls( props );
|
| 310 |
+
} else if ( -1 !== component.data.mediaBlocks.indexOf( name ) || 0 === name.indexOf( 'core-embed/' ) ) {
|
| 311 |
+
inspectorControls = component.setUpInspectorControls( props );
|
| 312 |
+
} else if ( -1 !== component.data.textBlocks.indexOf( name ) ) {
|
| 313 |
+
inspectorControls = component.setUpTextBlocksInspectorControls( props );
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
// Return just inspector controls in case of 'nodisplay'.
|
| 317 |
+
if ( ampLayout && 'nodisplay' === ampLayout ) {
|
| 318 |
+
return [
|
| 319 |
+
inspectorControls
|
| 320 |
+
];
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
return [
|
| 324 |
+
el( BlockEdit, _.extend( {
|
| 325 |
+
key: 'original'
|
| 326 |
+
}, props ) ),
|
| 327 |
+
inspectorControls
|
| 328 |
+
];
|
| 329 |
+
};
|
| 330 |
+
};
|
| 331 |
+
|
| 332 |
+
/**
|
| 333 |
+
* Set width and height in case of image block.
|
| 334 |
+
*
|
| 335 |
+
* @param {Object} props Props.
|
| 336 |
+
* @param {string} layout Layout.
|
| 337 |
+
*/
|
| 338 |
+
component.setImageBlockLayoutAttributes = function setImageBlockLayoutAttributes( props, layout ) {
|
| 339 |
+
var attributes = props.attributes;
|
| 340 |
+
switch ( layout ) {
|
| 341 |
+
case 'fixed-height':
|
| 342 |
+
if ( ! attributes.height ) {
|
| 343 |
+
props.setAttributes( { height: component.data.defaultHeight } );
|
| 344 |
+
}
|
| 345 |
+
// Lightbox doesn't work with fixed height, so unset it.
|
| 346 |
+
if ( attributes.ampLightbox ) {
|
| 347 |
+
props.setAttributes( { ampLightbox: false } );
|
| 348 |
+
}
|
| 349 |
+
break;
|
| 350 |
+
|
| 351 |
+
case 'fixed':
|
| 352 |
+
if ( ! attributes.height ) {
|
| 353 |
+
props.setAttributes( { height: component.data.defaultHeight } );
|
| 354 |
+
}
|
| 355 |
+
if ( ! attributes.width ) {
|
| 356 |
+
props.setAttributes( { width: component.data.defaultWidth } );
|
| 357 |
+
}
|
| 358 |
+
break;
|
| 359 |
+
}
|
| 360 |
+
};
|
| 361 |
+
|
| 362 |
+
/**
|
| 363 |
+
* Default setup for inspector controls.
|
| 364 |
+
*
|
| 365 |
+
* @param {Object} props Props.
|
| 366 |
+
* @return {Object|Element|*|{$$typeof, type, key, ref, props, _owner}} Inspector Controls.
|
| 367 |
+
*/
|
| 368 |
+
component.setUpInspectorControls = function setUpInspectorControls( props ) {
|
| 369 |
+
var isSelected = props.isSelected,
|
| 370 |
+
el = wp.element.createElement,
|
| 371 |
+
InspectorControls = wp.editor.InspectorControls,
|
| 372 |
+
PanelBody = wp.components.PanelBody;
|
| 373 |
+
|
| 374 |
+
return isSelected && (
|
| 375 |
+
el( InspectorControls, { key: 'inspector' },
|
| 376 |
+
el( PanelBody, { title: component.data.ampPanelLabel },
|
| 377 |
+
component.getAmpLayoutControl( props ),
|
| 378 |
+
component.getAmpNoloadingToggle( props )
|
| 379 |
+
)
|
| 380 |
+
)
|
| 381 |
+
);
|
| 382 |
+
};
|
| 383 |
+
|
| 384 |
+
/**
|
| 385 |
+
* Get AMP Layout select control.
|
| 386 |
+
*
|
| 387 |
+
* @param {Object} props Props.
|
| 388 |
+
* @return {Object} Element.
|
| 389 |
+
*/
|
| 390 |
+
component.getAmpLayoutControl = function getAmpLayoutControl( props ) {
|
| 391 |
+
var ampLayout = props.attributes.ampLayout,
|
| 392 |
+
el = wp.element.createElement,
|
| 393 |
+
SelectControl = wp.components.SelectControl,
|
| 394 |
+
name = props.name,
|
| 395 |
+
label = __( 'AMP Layout' );
|
| 396 |
+
|
| 397 |
+
if ( 'core/image' === name ) {
|
| 398 |
+
label = __( 'AMP Layout (modifies width/height)' );
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
return el( SelectControl, {
|
| 402 |
+
label: label,
|
| 403 |
+
value: ampLayout,
|
| 404 |
+
options: component.getLayoutOptions( name ),
|
| 405 |
+
onChange: function( value ) {
|
| 406 |
+
props.setAttributes( { ampLayout: value } );
|
| 407 |
+
if ( 'core/image' === props.name ) {
|
| 408 |
+
component.setImageBlockLayoutAttributes( props, value );
|
| 409 |
+
}
|
| 410 |
+
}
|
| 411 |
+
} );
|
| 412 |
+
};
|
| 413 |
+
|
| 414 |
+
/**
|
| 415 |
+
* Get AMP Noloading toggle control.
|
| 416 |
+
*
|
| 417 |
+
* @param {Object} props Props.
|
| 418 |
+
* @return {Object} Element.
|
| 419 |
+
*/
|
| 420 |
+
component.getAmpNoloadingToggle = function getAmpNoloadingToggle( props ) {
|
| 421 |
+
var ampNoLoading = props.attributes.ampNoLoading,
|
| 422 |
+
el = wp.element.createElement,
|
| 423 |
+
ToggleControl = wp.components.ToggleControl,
|
| 424 |
+
label = __( 'AMP Noloading' );
|
| 425 |
+
|
| 426 |
+
return el( ToggleControl, {
|
| 427 |
+
label: label,
|
| 428 |
+
checked: ampNoLoading,
|
| 429 |
+
onChange: function() {
|
| 430 |
+
props.setAttributes( { ampNoLoading: ! ampNoLoading } );
|
| 431 |
+
}
|
| 432 |
+
} );
|
| 433 |
+
};
|
| 434 |
+
|
| 435 |
+
/**
|
| 436 |
+
* Setup inspector controls for text blocks.
|
| 437 |
+
*
|
| 438 |
+
* @todo Consider wrapping the render function to delete the original font size in text settings when ampFitText.
|
| 439 |
+
*
|
| 440 |
+
* @param {Object} props Props.
|
| 441 |
+
* @return {Object|Element|*|{$$typeof, type, key, ref, props, _owner}} Inspector Controls.
|
| 442 |
+
*/
|
| 443 |
+
component.setUpTextBlocksInspectorControls = function setUpInspectorControls( props ) {
|
| 444 |
+
var inspectorPanelBodyArgs,
|
| 445 |
+
ampFitText = props.attributes.ampFitText,
|
| 446 |
+
minFont = props.attributes.minFont,
|
| 447 |
+
maxFont = props.attributes.maxFont,
|
| 448 |
+
height = props.attributes.height,
|
| 449 |
+
isSelected = props.isSelected,
|
| 450 |
+
el = wp.element.createElement,
|
| 451 |
+
InspectorControls = wp.editor.InspectorControls,
|
| 452 |
+
TextControl = wp.components.TextControl,
|
| 453 |
+
FontSizePicker = wp.components.FontSizePicker,
|
| 454 |
+
ToggleControl = wp.components.ToggleControl,
|
| 455 |
+
PanelBody = wp.components.PanelBody,
|
| 456 |
+
label = __( 'Use AMP Fit Text' ),
|
| 457 |
+
FONT_SIZES = [
|
| 458 |
+
{
|
| 459 |
+
name: 'small',
|
| 460 |
+
shortName: __( 'S' ),
|
| 461 |
+
size: 14
|
| 462 |
+
},
|
| 463 |
+
{
|
| 464 |
+
name: 'regular',
|
| 465 |
+
shortName: __( 'M' ),
|
| 466 |
+
size: 16
|
| 467 |
+
},
|
| 468 |
+
{
|
| 469 |
+
name: 'large',
|
| 470 |
+
shortName: __( 'L' ),
|
| 471 |
+
size: 36
|
| 472 |
+
},
|
| 473 |
+
{
|
| 474 |
+
name: 'larger',
|
| 475 |
+
shortName: __( 'XL' ),
|
| 476 |
+
size: 48
|
| 477 |
+
}
|
| 478 |
+
];
|
| 479 |
+
|
| 480 |
+
if ( ! isSelected ) {
|
| 481 |
+
return null;
|
| 482 |
+
}
|
| 483 |
+
|
| 484 |
+
inspectorPanelBodyArgs = [
|
| 485 |
+
PanelBody,
|
| 486 |
+
{ title: component.data.ampSettingsLabel, className: ampFitText ? 'is-amp-fit-text' : '' },
|
| 487 |
+
el( ToggleControl, {
|
| 488 |
+
label: label,
|
| 489 |
+
checked: ampFitText,
|
| 490 |
+
onChange: function() {
|
| 491 |
+
props.setAttributes( { ampFitText: ! ampFitText } );
|
| 492 |
+
}
|
| 493 |
+
} )
|
| 494 |
+
];
|
| 495 |
+
|
| 496 |
+
if ( ampFitText ) {
|
| 497 |
+
inspectorPanelBodyArgs.push.apply( inspectorPanelBodyArgs, [
|
| 498 |
+
el( TextControl, {
|
| 499 |
+
label: __( 'Height' ),
|
| 500 |
+
value: height,
|
| 501 |
+
min: 1,
|
| 502 |
+
onChange: function( nextHeight ) {
|
| 503 |
+
props.setAttributes( { height: nextHeight } );
|
| 504 |
+
}
|
| 505 |
+
} ),
|
| 506 |
+
parseInt( maxFont ) > parseInt( height ) && el(
|
| 507 |
+
wp.components.Notice,
|
| 508 |
+
{
|
| 509 |
+
status: 'error',
|
| 510 |
+
isDismissible: false
|
| 511 |
+
},
|
| 512 |
+
__( 'The height must be greater than the max font size.' )
|
| 513 |
+
),
|
| 514 |
+
el( PanelBody, { title: __( 'Minimum font size' ) },
|
| 515 |
+
el( FontSizePicker, {
|
| 516 |
+
fallbackFontSize: 14,
|
| 517 |
+
value: minFont,
|
| 518 |
+
fontSizes: FONT_SIZES,
|
| 519 |
+
onChange: function( nextMinFont ) {
|
| 520 |
+
if ( ! nextMinFont ) {
|
| 521 |
+
nextMinFont = component.data.fontSizes.small; // @todo Supplying fallbackFontSize should be done automatically by the component?
|
| 522 |
+
}
|
| 523 |
+
if ( parseInt( nextMinFont ) <= parseInt( maxFont ) ) {
|
| 524 |
+
props.setAttributes( { minFont: nextMinFont } );
|
| 525 |
+
}
|
| 526 |
+
}
|
| 527 |
+
} )
|
| 528 |
+
),
|
| 529 |
+
parseInt( minFont ) > parseInt( maxFont ) && el(
|
| 530 |
+
wp.components.Notice,
|
| 531 |
+
{
|
| 532 |
+
status: 'error',
|
| 533 |
+
isDismissible: false
|
| 534 |
+
},
|
| 535 |
+
__( 'The min font size must less than the max font size.' )
|
| 536 |
+
),
|
| 537 |
+
el( PanelBody, { title: __( 'Maximum font size' ) },
|
| 538 |
+
el( FontSizePicker, {
|
| 539 |
+
value: maxFont,
|
| 540 |
+
fallbackFontSize: 48,
|
| 541 |
+
fontSizes: FONT_SIZES,
|
| 542 |
+
onChange: function( nextMaxFont ) {
|
| 543 |
+
if ( ! nextMaxFont ) {
|
| 544 |
+
nextMaxFont = component.data.fontSizes.larger; // @todo Supplying fallbackFontSize should be done automatically by the component?
|
| 545 |
+
}
|
| 546 |
+
props.setAttributes( {
|
| 547 |
+
maxFont: nextMaxFont,
|
| 548 |
+
height: Math.max( nextMaxFont, height )
|
| 549 |
+
} );
|
| 550 |
+
}
|
| 551 |
+
} )
|
| 552 |
+
)
|
| 553 |
+
] );
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
return (
|
| 557 |
+
el( InspectorControls, { key: 'inspector' },
|
| 558 |
+
el.apply( null, inspectorPanelBodyArgs )
|
| 559 |
+
)
|
| 560 |
+
);
|
| 561 |
+
};
|
| 562 |
+
|
| 563 |
+
/**
|
| 564 |
+
* Set up inspector controls for shortcode block.
|
| 565 |
+
* Adds ampCarousel attribute in case of gallery shortcode.
|
| 566 |
+
*
|
| 567 |
+
* @param {Object} props Props.
|
| 568 |
+
* @return {Object} Inspector controls.
|
| 569 |
+
*/
|
| 570 |
+
component.setUpShortcodeInspectorControls = function setUpShortcodeInspectorControls( props ) {
|
| 571 |
+
var isSelected = props.isSelected,
|
| 572 |
+
el = wp.element.createElement,
|
| 573 |
+
InspectorControls = wp.editor.InspectorControls,
|
| 574 |
+
PanelBody = wp.components.PanelBody;
|
| 575 |
+
|
| 576 |
+
if ( component.isGalleryShortcode( props.attributes ) ) {
|
| 577 |
+
return isSelected && (
|
| 578 |
+
el( InspectorControls, { key: 'inspector' },
|
| 579 |
+
el( PanelBody, { title: component.data.ampPanelLabel },
|
| 580 |
+
component.data.hasThemeSupport && component.getAmpCarouselToggle( props ),
|
| 581 |
+
component.getAmpLightboxToggle( props )
|
| 582 |
+
)
|
| 583 |
+
)
|
| 584 |
+
);
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
return '';
|
| 588 |
+
};
|
| 589 |
+
|
| 590 |
+
/**
|
| 591 |
+
* Get AMP Lightbox toggle control.
|
| 592 |
+
*
|
| 593 |
+
* @param {Object} props Props.
|
| 594 |
+
* @return {Object} Element.
|
| 595 |
+
*/
|
| 596 |
+
component.getAmpLightboxToggle = function getAmpLightboxToggle( props ) {
|
| 597 |
+
var ampLightbox = props.attributes.ampLightbox,
|
| 598 |
+
el = wp.element.createElement,
|
| 599 |
+
ToggleControl = wp.components.ToggleControl,
|
| 600 |
+
label = __( 'Add lightbox effect' );
|
| 601 |
+
|
| 602 |
+
return el( ToggleControl, {
|
| 603 |
+
label: label,
|
| 604 |
+
checked: ampLightbox,
|
| 605 |
+
onChange: function( nextValue ) {
|
| 606 |
+
props.setAttributes( { ampLightbox: ! ampLightbox } );
|
| 607 |
+
if ( nextValue ) {
|
| 608 |
+
// Lightbox doesn't work with fixed height, so change.
|
| 609 |
+
if ( 'fixed-height' === props.attributes.ampLayout ) {
|
| 610 |
+
props.setAttributes( { ampLayout: 'fixed' } );
|
| 611 |
+
}
|
| 612 |
+
// In case of lightbox set linking images to 'none'.
|
| 613 |
+
if ( props.attributes.linkTo && 'none' !== props.attributes.linkTo ) {
|
| 614 |
+
props.setAttributes( { linkTo: 'none' } );
|
| 615 |
+
}
|
| 616 |
+
}
|
| 617 |
+
}
|
| 618 |
+
} );
|
| 619 |
+
};
|
| 620 |
+
|
| 621 |
+
/**
|
| 622 |
+
* Get AMP Carousel toggle control.
|
| 623 |
+
*
|
| 624 |
+
* @param {Object} props Props.
|
| 625 |
+
* @return {Object} Element.
|
| 626 |
+
*/
|
| 627 |
+
component.getAmpCarouselToggle = function getAmpCarouselToggle( props ) {
|
| 628 |
+
var ampCarousel = props.attributes.ampCarousel,
|
| 629 |
+
el = wp.element.createElement,
|
| 630 |
+
ToggleControl = wp.components.ToggleControl,
|
| 631 |
+
label = __( 'Display as AMP carousel' );
|
| 632 |
+
|
| 633 |
+
return el( ToggleControl, {
|
| 634 |
+
label: label,
|
| 635 |
+
checked: ampCarousel,
|
| 636 |
+
onChange: function() {
|
| 637 |
+
props.setAttributes( { ampCarousel: ! ampCarousel } );
|
| 638 |
+
}
|
| 639 |
+
} );
|
| 640 |
+
};
|
| 641 |
+
|
| 642 |
+
/**
|
| 643 |
+
* Set up inspector controls for Image block.
|
| 644 |
+
*
|
| 645 |
+
* @param {Object} props Props.
|
| 646 |
+
* @return {Object} Inspector Controls.
|
| 647 |
+
*/
|
| 648 |
+
component.setUpImageInpsectorControls = function setUpImageInpsectorControls( props ) {
|
| 649 |
+
var isSelected = props.isSelected,
|
| 650 |
+
el = wp.element.createElement,
|
| 651 |
+
InspectorControls = wp.editor.InspectorControls,
|
| 652 |
+
PanelBody = wp.components.PanelBody;
|
| 653 |
+
|
| 654 |
+
return isSelected && (
|
| 655 |
+
el( InspectorControls, { key: 'inspector' },
|
| 656 |
+
el( PanelBody, { title: component.data.ampPanelLabel },
|
| 657 |
+
component.getAmpLayoutControl( props ),
|
| 658 |
+
component.getAmpNoloadingToggle( props ),
|
| 659 |
+
component.getAmpLightboxToggle( props )
|
| 660 |
+
)
|
| 661 |
+
)
|
| 662 |
+
);
|
| 663 |
+
};
|
| 664 |
+
|
| 665 |
+
/**
|
| 666 |
+
* Set up inspector controls for Gallery block.
|
| 667 |
+
* Adds ampCarousel attribute for displaying the output as amp-carousel.
|
| 668 |
+
*
|
| 669 |
+
* @param {Object} props Props.
|
| 670 |
+
* @return {Object} Inspector controls.
|
| 671 |
+
*/
|
| 672 |
+
component.setUpGalleryInpsectorControls = function setUpGalleryInpsectorControls( props ) {
|
| 673 |
+
var isSelected = props.isSelected,
|
| 674 |
+
el = wp.element.createElement,
|
| 675 |
+
InspectorControls = wp.editor.InspectorControls,
|
| 676 |
+
PanelBody = wp.components.PanelBody;
|
| 677 |
+
|
| 678 |
+
return isSelected && (
|
| 679 |
+
el( InspectorControls, { key: 'inspector' },
|
| 680 |
+
el( PanelBody, { title: component.data.ampPanelLabel },
|
| 681 |
+
component.data.hasThemeSupport && component.getAmpCarouselToggle( props ),
|
| 682 |
+
component.getAmpLightboxToggle( props )
|
| 683 |
+
)
|
| 684 |
+
)
|
| 685 |
+
);
|
| 686 |
+
};
|
| 687 |
+
|
| 688 |
+
/**
|
| 689 |
+
* Filters blocks' save function.
|
| 690 |
+
*
|
| 691 |
+
* @param {Object} element Element.
|
| 692 |
+
* @param {string} blockType Block type.
|
| 693 |
+
* @param {Object} attributes Attributes.
|
| 694 |
+
* @return {Object} Output element.
|
| 695 |
+
*/
|
| 696 |
+
component.filterBlocksSave = function filterBlocksSave( element, blockType, attributes ) {
|
| 697 |
+
var text = attributes.text || '',
|
| 698 |
+
fitTextProps = {
|
| 699 |
+
layout: 'fixed-height',
|
| 700 |
+
children: element
|
| 701 |
+
};
|
| 702 |
+
|
| 703 |
+
if ( 'core/shortcode' === blockType.name && component.isGalleryShortcode( attributes ) ) {
|
| 704 |
+
if ( ! attributes.ampLightbox ) {
|
| 705 |
+
if ( component.hasGalleryShortcodeLightboxAttribute( attributes.text || '' ) ) {
|
| 706 |
+
text = component.removeAmpLightboxFromShortcodeAtts( attributes.text );
|
| 707 |
+
}
|
| 708 |
+
}
|
| 709 |
+
if ( attributes.ampCarousel ) {
|
| 710 |
+
// If the text contains amp-carousel or amp-lightbox, lets remove it.
|
| 711 |
+
if ( component.hasGalleryShortcodeCarouselAttribute( text ) ) {
|
| 712 |
+
text = component.removeAmpCarouselFromShortcodeAtts( text );
|
| 713 |
+
}
|
| 714 |
+
|
| 715 |
+
// If lightbox is not set, we can return here.
|
| 716 |
+
if ( ! attributes.ampLightbox ) {
|
| 717 |
+
if ( attributes.text !== text ) {
|
| 718 |
+
return wp.element.createElement(
|
| 719 |
+
wp.element.RawHTML,
|
| 720 |
+
{},
|
| 721 |
+
text
|
| 722 |
+
);
|
| 723 |
+
}
|
| 724 |
+
|
| 725 |
+
// Else lets return original.
|
| 726 |
+
return element;
|
| 727 |
+
}
|
| 728 |
+
} else if ( ! component.hasGalleryShortcodeCarouselAttribute( attributes.text || '' ) ) {
|
| 729 |
+
// Add amp-carousel=false attribute to the shortcode.
|
| 730 |
+
text = attributes.text.replace( '[gallery', '[gallery amp-carousel=false' );
|
| 731 |
+
} else {
|
| 732 |
+
text = attributes.text;
|
| 733 |
+
}
|
| 734 |
+
|
| 735 |
+
if ( attributes.ampLightbox && ! component.hasGalleryShortcodeLightboxAttribute( text ) ) {
|
| 736 |
+
text = text.replace( '[gallery', '[gallery amp-lightbox=true' );
|
| 737 |
+
}
|
| 738 |
+
|
| 739 |
+
if ( attributes.text !== text ) {
|
| 740 |
+
return wp.element.createElement(
|
| 741 |
+
wp.element.RawHTML,
|
| 742 |
+
{},
|
| 743 |
+
text
|
| 744 |
+
);
|
| 745 |
+
}
|
| 746 |
+
} else if ( -1 !== component.data.textBlocks.indexOf( blockType.name ) && attributes.ampFitText ) {
|
| 747 |
+
if ( attributes.minFont ) {
|
| 748 |
+
fitTextProps[ 'min-font-size' ] = attributes.minFont;
|
| 749 |
+
}
|
| 750 |
+
if ( attributes.maxFont ) {
|
| 751 |
+
fitTextProps[ 'max-font-size' ] = attributes.maxFont;
|
| 752 |
+
}
|
| 753 |
+
if ( attributes.height ) {
|
| 754 |
+
fitTextProps.height = attributes.height;
|
| 755 |
+
}
|
| 756 |
+
return wp.element.createElement( 'amp-fit-text', fitTextProps );
|
| 757 |
+
}
|
| 758 |
+
return element;
|
| 759 |
+
};
|
| 760 |
+
|
| 761 |
+
/**
|
| 762 |
+
* Check if AMP Lightbox is set.
|
| 763 |
+
*
|
| 764 |
+
* @param {Object} attributes Attributes.
|
| 765 |
+
* @return {boolean} If is set.
|
| 766 |
+
*/
|
| 767 |
+
component.hasAmpLightboxSet = function hasAmpLightboxSet( attributes ) {
|
| 768 |
+
return attributes.ampLightbox && false !== attributes.ampLightbox;
|
| 769 |
+
};
|
| 770 |
+
|
| 771 |
+
/**
|
| 772 |
+
* Check if AMP Carousel is set.
|
| 773 |
+
*
|
| 774 |
+
* @param {Object} attributes Attributes.
|
| 775 |
+
* @return {boolean} If is set.
|
| 776 |
+
*/
|
| 777 |
+
component.hasAmpCarouselSet = function hasAmpCarouselSet( attributes ) {
|
| 778 |
+
return attributes.ampCarousel && false !== attributes.ampCarousel;
|
| 779 |
+
};
|
| 780 |
+
|
| 781 |
+
/**
|
| 782 |
+
* Check if AMP NoLoading is set.
|
| 783 |
+
*
|
| 784 |
+
* @param {Object} attributes Attributes.
|
| 785 |
+
* @return {boolean} If is set.
|
| 786 |
+
*/
|
| 787 |
+
component.hasAmpNoLoadingSet = function hasAmpNoLoadingSet( attributes ) {
|
| 788 |
+
return attributes.ampNoLoading && false !== attributes.ampNoLoading;
|
| 789 |
+
};
|
| 790 |
+
|
| 791 |
+
/**
|
| 792 |
+
* Check if AMP Layout is set.
|
| 793 |
+
*
|
| 794 |
+
* @param {Object} attributes Attributes.
|
| 795 |
+
* @return {boolean} If AMP Layout is set.
|
| 796 |
+
*/
|
| 797 |
+
component.hasAmpLayoutSet = function hasAmpLayoutSet( attributes ) {
|
| 798 |
+
return attributes.ampLayout && attributes.ampLayout.length;
|
| 799 |
+
};
|
| 800 |
+
|
| 801 |
+
/**
|
| 802 |
+
* Removes amp-carousel=false from attributes.
|
| 803 |
+
*
|
| 804 |
+
* @param {string} shortcode Shortcode text.
|
| 805 |
+
* @return {string} Modified shortcode.
|
| 806 |
+
*/
|
| 807 |
+
component.removeAmpCarouselFromShortcodeAtts = function removeAmpCarouselFromShortcodeAtts( shortcode ) {
|
| 808 |
+
return shortcode.replace( ' amp-carousel=false', '' );
|
| 809 |
+
};
|
| 810 |
+
|
| 811 |
+
/**
|
| 812 |
+
* Removes amp-lightbox=true from attributes.
|
| 813 |
+
*
|
| 814 |
+
* @param {string} shortcode Shortcode text.
|
| 815 |
+
* @return {string} Modified shortcode.
|
| 816 |
+
*/
|
| 817 |
+
component.removeAmpLightboxFromShortcodeAtts = function removeAmpLightboxFromShortcodeAtts( shortcode ) {
|
| 818 |
+
return shortcode.replace( ' amp-lightbox=true', '' );
|
| 819 |
+
};
|
| 820 |
+
|
| 821 |
+
/**
|
| 822 |
+
* Check if shortcode includes amp-carousel attribute.
|
| 823 |
+
*
|
| 824 |
+
* @param {string} text Shortcode.
|
| 825 |
+
* @return {boolean} If has amp-carousel.
|
| 826 |
+
*/
|
| 827 |
+
component.hasGalleryShortcodeCarouselAttribute = function hasGalleryShortcodeCarouselAttribute( text ) {
|
| 828 |
+
return -1 !== text.indexOf( 'amp-carousel=false' );
|
| 829 |
+
};
|
| 830 |
+
|
| 831 |
+
/**
|
| 832 |
+
* Check if shortcode includes amp-lightbox attribute.
|
| 833 |
+
*
|
| 834 |
+
* @param {string} text Shortcode.
|
| 835 |
+
* @return {boolean} If has amp-lightbox.
|
| 836 |
+
*/
|
| 837 |
+
component.hasGalleryShortcodeLightboxAttribute = function hasGalleryShortcodeLightboxAttribute( text ) {
|
| 838 |
+
return -1 !== text.indexOf( 'amp-lightbox=true' );
|
| 839 |
+
};
|
| 840 |
+
|
| 841 |
+
/**
|
| 842 |
+
* Check if shortcode is gallery shortcode.
|
| 843 |
+
*
|
| 844 |
+
* @param {Object} attributes Attributes.
|
| 845 |
+
* @return {boolean} If is gallery shortcode.
|
| 846 |
+
*/
|
| 847 |
+
component.isGalleryShortcode = function isGalleryShortcode( attributes ) {
|
| 848 |
+
return attributes.text && -1 !== attributes.text.indexOf( 'gallery' );
|
| 849 |
+
};
|
| 850 |
+
|
| 851 |
+
return component;
|
| 852 |
+
}() );
|
|
@@ -7,7 +7,7 @@
|
|
| 7 |
*
|
| 8 |
* @since 0.6
|
| 9 |
*/
|
| 10 |
-
var ampPostMetaBox = ( function( $ ) {
|
| 11 |
'use strict';
|
| 12 |
|
| 13 |
var component = {
|
|
@@ -104,8 +104,8 @@ var ampPostMetaBox = ( function( $ ) {
|
|
| 104 |
.clone()
|
| 105 |
.insertAfter( previewBtn )
|
| 106 |
.prop( {
|
| 107 |
-
|
| 108 |
-
|
| 109 |
} )
|
| 110 |
.text( component.data.l10n.ampPreviewBtnLabel )
|
| 111 |
.parent()
|
|
@@ -126,9 +126,9 @@ var ampPostMetaBox = ( function( $ ) {
|
|
| 126 |
// Flag the AMP preview referer.
|
| 127 |
$input = $( '<input>' )
|
| 128 |
.prop( {
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
} )
|
| 133 |
.insertAfter( component.ampPreviewBtnSelector );
|
| 134 |
|
|
@@ -176,4 +176,4 @@ var ampPostMetaBox = ( function( $ ) {
|
|
| 176 |
};
|
| 177 |
|
| 178 |
return component;
|
| 179 |
-
}
|
| 7 |
*
|
| 8 |
* @since 0.6
|
| 9 |
*/
|
| 10 |
+
var ampPostMetaBox = ( function( $ ) { // eslint-disable-line no-unused-vars
|
| 11 |
'use strict';
|
| 12 |
|
| 13 |
var component = {
|
| 104 |
.clone()
|
| 105 |
.insertAfter( previewBtn )
|
| 106 |
.prop( {
|
| 107 |
+
href: component.data.previewLink,
|
| 108 |
+
id: component.ampPreviewBtnSelector.replace( '#', '' )
|
| 109 |
} )
|
| 110 |
.text( component.data.l10n.ampPreviewBtnLabel )
|
| 111 |
.parent()
|
| 126 |
// Flag the AMP preview referer.
|
| 127 |
$input = $( '<input>' )
|
| 128 |
.prop( {
|
| 129 |
+
type: 'hidden',
|
| 130 |
+
name: 'amp-preview',
|
| 131 |
+
value: 'do-preview'
|
| 132 |
} )
|
| 133 |
.insertAfter( component.ampPreviewBtnSelector );
|
| 134 |
|
| 176 |
};
|
| 177 |
|
| 178 |
return component;
|
| 179 |
+
}( window.jQuery ) );
|
|
@@ -0,0 +1,409 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* exported ampValidatedUrlPostEditScreen */
|
| 2 |
+
|
| 3 |
+
const ampValidatedUrlPostEditScreen = ( function() { // eslint-disable-line no-unused-vars
|
| 4 |
+
let component = {
|
| 5 |
+
data: {
|
| 6 |
+
l10n: {
|
| 7 |
+
unsaved_changes: '',
|
| 8 |
+
showing_number_errors: '',
|
| 9 |
+
page_heading: '',
|
| 10 |
+
show_all: '',
|
| 11 |
+
amp_enabled: false
|
| 12 |
+
}
|
| 13 |
+
}
|
| 14 |
+
};
|
| 15 |
+
|
| 16 |
+
/**
|
| 17 |
+
* The id for the 'Showing x of y errors' notice.
|
| 18 |
+
*
|
| 19 |
+
* @var {string}
|
| 20 |
+
*/
|
| 21 |
+
component.idNumberErrors = 'number-errors';
|
| 22 |
+
|
| 23 |
+
/**
|
| 24 |
+
* The id for the 'Show all' button.
|
| 25 |
+
*
|
| 26 |
+
* @var {string}
|
| 27 |
+
*/
|
| 28 |
+
component.showAllId = 'show-all-errors';
|
| 29 |
+
|
| 30 |
+
/**
|
| 31 |
+
* Boot.
|
| 32 |
+
*
|
| 33 |
+
* @param {Object} data Data.
|
| 34 |
+
* @param {Object} data.l10n Translations.
|
| 35 |
+
*/
|
| 36 |
+
component.boot = function boot( data ) {
|
| 37 |
+
Object.assign( component.data, data );
|
| 38 |
+
component.handleShowAll();
|
| 39 |
+
component.handleFiltering();
|
| 40 |
+
component.handleSearching();
|
| 41 |
+
component.handleStatusChange();
|
| 42 |
+
component.handleBulkActions();
|
| 43 |
+
component.changeHeading();
|
| 44 |
+
component.watchForUnsavedChanges();
|
| 45 |
+
component.showAMPIconIfEnabled();
|
| 46 |
+
};
|
| 47 |
+
|
| 48 |
+
/**
|
| 49 |
+
* Add prompt when leaving page due to unsaved changes.
|
| 50 |
+
*/
|
| 51 |
+
component.addBeforeUnloadPrompt = function addBeforeUnloadPrompt() {
|
| 52 |
+
if ( component.beforeUnloadPromptAdded ) {
|
| 53 |
+
return;
|
| 54 |
+
}
|
| 55 |
+
window.addEventListener( 'beforeunload', component.onBeforeUnload );
|
| 56 |
+
|
| 57 |
+
// Remove prompt when clicking trash or update.
|
| 58 |
+
document.querySelector( '#major-publishing-actions' ).addEventListener( 'click', function() {
|
| 59 |
+
window.removeEventListener( 'beforeunload', component.onBeforeUnload );
|
| 60 |
+
} );
|
| 61 |
+
|
| 62 |
+
component.beforeUnloadPromptAdded = true;
|
| 63 |
+
};
|
| 64 |
+
|
| 65 |
+
/**
|
| 66 |
+
* Watch for unsaved changes.
|
| 67 |
+
*
|
| 68 |
+
* Add an beforeunload warning when attempting to leave the page when there are unsaved changes,
|
| 69 |
+
* unless the user is pressing the trash link or update button.
|
| 70 |
+
*/
|
| 71 |
+
component.watchForUnsavedChanges = function watchForUnsavedChanges() {
|
| 72 |
+
const onChange = function( event ) {
|
| 73 |
+
if ( event.target.matches( 'select' ) ) {
|
| 74 |
+
document.getElementById( 'post' ).removeEventListener( 'change', onChange );
|
| 75 |
+
component.addBeforeUnloadPrompt();
|
| 76 |
+
}
|
| 77 |
+
};
|
| 78 |
+
document.getElementById( 'post' ).addEventListener( 'change', onChange );
|
| 79 |
+
};
|
| 80 |
+
|
| 81 |
+
/**
|
| 82 |
+
* Show message at beforeunload.
|
| 83 |
+
*
|
| 84 |
+
* @param {Event} event - The beforeunload event.
|
| 85 |
+
* @return {string} Message.
|
| 86 |
+
*/
|
| 87 |
+
component.onBeforeUnload = function onBeforeUnload( event ) {
|
| 88 |
+
event.preventDefault();
|
| 89 |
+
event.returnValue = component.data.l10n.unsaved_changes;
|
| 90 |
+
return component.data.l10n.unsaved_changes;
|
| 91 |
+
};
|
| 92 |
+
|
| 93 |
+
/**
|
| 94 |
+
* Updates the <tr> with 'Showing x of y validation errors' at the top of the list table with the current count.
|
| 95 |
+
* If this does not exist yet, it creates the element.
|
| 96 |
+
*
|
| 97 |
+
* @param {number} numberErrorsDisplaying - The number of errors displaying.
|
| 98 |
+
* @param {number} totalErrors - The total number of errors, displaying or not.
|
| 99 |
+
*/
|
| 100 |
+
component.updateShowingErrorsRow = function updateShowingErrorsRow( numberErrorsDisplaying, totalErrors ) {
|
| 101 |
+
const showAllButton = document.getElementById( component.showAllId );
|
| 102 |
+
let thead, th,
|
| 103 |
+
tr = document.getElementById( component.idNumberErrors );
|
| 104 |
+
const theadQuery = document.getElementsByTagName( 'thead' );
|
| 105 |
+
|
| 106 |
+
// Only create the <tr> if it does not exist yet.
|
| 107 |
+
if ( theadQuery[ 0 ] && ! tr ) {
|
| 108 |
+
thead = theadQuery[ 0 ];
|
| 109 |
+
tr = document.createElement( 'tr' );
|
| 110 |
+
th = document.createElement( 'th' );
|
| 111 |
+
th.setAttribute( 'id', component.idNumberErrors );
|
| 112 |
+
th.setAttribute( 'colspan', '6' );
|
| 113 |
+
tr.appendChild( th );
|
| 114 |
+
thead.appendChild( tr );
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// If all of the errors are displaying, hide the 'Show all' button and the count notice.
|
| 118 |
+
if ( showAllButton && numberErrorsDisplaying === totalErrors ) {
|
| 119 |
+
showAllButton.classList.add( 'hidden' );
|
| 120 |
+
tr.classList.add( 'hidden' );
|
| 121 |
+
} else if ( null !== numberErrorsDisplaying ) {
|
| 122 |
+
// Update the number of errors displaying and create a 'Show all' button if it does not exist yet.
|
| 123 |
+
document.getElementById( component.idNumberErrors ).innerText = component.data.l10n.showing_number_errors.replace( '%', numberErrorsDisplaying );
|
| 124 |
+
document.getElementById( component.idNumberErrors ).classList.remove( 'hidden' );
|
| 125 |
+
component.conditionallyCreateShowAllButton();
|
| 126 |
+
if ( document.getElementById( component.showAllId ) ) {
|
| 127 |
+
document.getElementById( component.showAllId ).classList.remove( 'hidden' );
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
};
|
| 131 |
+
|
| 132 |
+
/**
|
| 133 |
+
* Conditionally creates and appends a 'Show all' button.
|
| 134 |
+
*/
|
| 135 |
+
component.conditionallyCreateShowAllButton = function conditionallyCreateShowAllButton() {
|
| 136 |
+
const buttonContainer = document.getElementById( 'url-post-filter' );
|
| 137 |
+
let showAllButton = document.getElementById( component.showAllId );
|
| 138 |
+
|
| 139 |
+
// There is no 'Show all' <button> yet, but there is a container element for it, create the <button>
|
| 140 |
+
if ( ! showAllButton && buttonContainer ) {
|
| 141 |
+
showAllButton = document.createElement( 'button' );
|
| 142 |
+
showAllButton.id = component.showAllId;
|
| 143 |
+
showAllButton.classList.add( 'button' );
|
| 144 |
+
showAllButton.innerText = component.data.l10n.show_all;
|
| 145 |
+
buttonContainer.appendChild( showAllButton );
|
| 146 |
+
}
|
| 147 |
+
};
|
| 148 |
+
|
| 149 |
+
/**
|
| 150 |
+
* On clicking the 'Show all' <button>, this displays all of the validation errors.
|
| 151 |
+
* Then, it hides this 'Show all' <button> and the notice for the number of errors showing.
|
| 152 |
+
*/
|
| 153 |
+
component.handleShowAll = function handleShowAll() {
|
| 154 |
+
const onClick = function( event ) {
|
| 155 |
+
const validationErrors = document.querySelectorAll( '[data-error-type]' );
|
| 156 |
+
if ( ! event.target.matches( '#' + component.showAllId ) ) {
|
| 157 |
+
return;
|
| 158 |
+
}
|
| 159 |
+
event.preventDefault();
|
| 160 |
+
|
| 161 |
+
// Iterate through all of the errors, and remove the 'hidden' class.
|
| 162 |
+
validationErrors.forEach( function( element ) {
|
| 163 |
+
element.parentElement.parentElement.classList.remove( 'hidden' );
|
| 164 |
+
} );
|
| 165 |
+
|
| 166 |
+
/*
|
| 167 |
+
* Update the notice to indicate that all of the errors are displaying.
|
| 168 |
+
* Like 'Showing 5 of 5 validation errors'.
|
| 169 |
+
*/
|
| 170 |
+
component.updateShowingErrorsRow( validationErrors.length, validationErrors.length );
|
| 171 |
+
|
| 172 |
+
// Hide this 'Show all' button.
|
| 173 |
+
event.target.classList.add( 'hidden' );
|
| 174 |
+
|
| 175 |
+
// Change the value of the error type <select> element to 'All Error Types'.
|
| 176 |
+
document.getElementById( 'amp_validation_error_type' ).selectedIndex = 0;
|
| 177 |
+
};
|
| 178 |
+
|
| 179 |
+
document.getElementById( 'url-post-filter' ).addEventListener( 'click', onClick );
|
| 180 |
+
};
|
| 181 |
+
|
| 182 |
+
/**
|
| 183 |
+
* Handles filtering by error type, triggered by clicking 'Apply Filter'.
|
| 184 |
+
*
|
| 185 |
+
* Gets the value of the error type <select> element.
|
| 186 |
+
* And hides all <tr> elements that do not have the same type of this value.
|
| 187 |
+
* If 'All Error Types' is selected, this displays all errors.
|
| 188 |
+
*/
|
| 189 |
+
component.handleFiltering = function handleFiltering() {
|
| 190 |
+
const onChange = function( event ) {
|
| 191 |
+
const showAllButton = document.getElementById( component.showAllId );
|
| 192 |
+
if ( ! event.target.matches( 'select' ) ) {
|
| 193 |
+
return;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
event.preventDefault();
|
| 197 |
+
|
| 198 |
+
const isAllErrorTypesSelected = ( '-1' === event.target.value );
|
| 199 |
+
const errorTypeQuery = document.querySelectorAll( '[data-error-type]' );
|
| 200 |
+
|
| 201 |
+
// If the user has chosen 'All Error Types' from the <select>, hide the 'Show all' button.
|
| 202 |
+
if ( isAllErrorTypesSelected && showAllButton ) {
|
| 203 |
+
showAllButton.classList.add( 'hidden' );
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
/*
|
| 207 |
+
* Iterate through all of the <tr> elements in the list table.
|
| 208 |
+
* If the error type does not match the value (selected error type), hide them.
|
| 209 |
+
*/
|
| 210 |
+
let numberErrorsDisplaying = 0;
|
| 211 |
+
errorTypeQuery.forEach( function( element ) {
|
| 212 |
+
const errorType = element.getAttribute( 'data-error-type' );
|
| 213 |
+
|
| 214 |
+
// If 'All Error Types' was selected, this should display all errors.
|
| 215 |
+
if ( isAllErrorTypesSelected || ! event.target.value || event.target.value === errorType ) {
|
| 216 |
+
element.parentElement.parentElement.classList.remove( 'hidden' );
|
| 217 |
+
numberErrorsDisplaying++;
|
| 218 |
+
} else {
|
| 219 |
+
element.parentElement.parentElement.classList.add( 'hidden' );
|
| 220 |
+
}
|
| 221 |
+
} );
|
| 222 |
+
|
| 223 |
+
component.updateShowingErrorsRow( numberErrorsDisplaying, errorTypeQuery.length );
|
| 224 |
+
};
|
| 225 |
+
|
| 226 |
+
document.getElementById( 'amp_validation_error_type' ).addEventListener( 'change', onChange );
|
| 227 |
+
};
|
| 228 |
+
|
| 229 |
+
/**
|
| 230 |
+
* Handles searching for errors via the <input> and the 'Search Errors' <button>.
|
| 231 |
+
*/
|
| 232 |
+
component.handleSearching = function handleSearching() {
|
| 233 |
+
const onClick = function( event ) {
|
| 234 |
+
event.preventDefault();
|
| 235 |
+
if ( ! event.target.matches( 'input' ) ) {
|
| 236 |
+
return;
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
const searchQuery = document.getElementById( 'invalid-url-search-search-input' ).value;
|
| 240 |
+
const detailsQuery = document.querySelectorAll( 'tbody .column-details' );
|
| 241 |
+
|
| 242 |
+
/*
|
| 243 |
+
* Iterate through the 'Details' column of each row.
|
| 244 |
+
* If the search query is not present, hide the row.
|
| 245 |
+
*/
|
| 246 |
+
let numberErrorsDisplaying = 0;
|
| 247 |
+
detailsQuery.forEach( function( element ) {
|
| 248 |
+
let isSearchQueryPresent = false;
|
| 249 |
+
|
| 250 |
+
element.querySelectorAll( '.detailed' ).forEach( function( detailed ) {
|
| 251 |
+
if ( -1 !== detailed.innerText.indexOf( searchQuery ) ) {
|
| 252 |
+
isSearchQueryPresent = true;
|
| 253 |
+
}
|
| 254 |
+
} );
|
| 255 |
+
|
| 256 |
+
if ( isSearchQueryPresent ) {
|
| 257 |
+
element.parentElement.classList.remove( 'hidden' );
|
| 258 |
+
numberErrorsDisplaying++;
|
| 259 |
+
} else {
|
| 260 |
+
element.parentElement.classList.add( 'hidden' );
|
| 261 |
+
}
|
| 262 |
+
} );
|
| 263 |
+
|
| 264 |
+
component.updateShowingErrorsRow( numberErrorsDisplaying, detailsQuery.length );
|
| 265 |
+
};
|
| 266 |
+
|
| 267 |
+
document.getElementById( 'search-submit' ).addEventListener( 'click', onClick );
|
| 268 |
+
};
|
| 269 |
+
|
| 270 |
+
/**
|
| 271 |
+
* Update icon for select element.
|
| 272 |
+
*
|
| 273 |
+
* @param {HTMLSelectElement} select Select element.
|
| 274 |
+
*/
|
| 275 |
+
component.updateSelectIcon = function updateSelectIcon( select ) {
|
| 276 |
+
const newOption = select.options[ select.selectedIndex ];
|
| 277 |
+
if ( newOption ) {
|
| 278 |
+
const iconSrc = newOption.getAttribute( 'data-status-icon' );
|
| 279 |
+
select.parentNode.querySelector( 'img' ).setAttribute( 'src', iconSrc );
|
| 280 |
+
}
|
| 281 |
+
};
|
| 282 |
+
|
| 283 |
+
/**
|
| 284 |
+
* Handles a change in the error status, like from 'New' to 'Accepted'.
|
| 285 |
+
*
|
| 286 |
+
* Gets the data-status-icon value from the newly-selected <option>.
|
| 287 |
+
* And sets this as the src of the status icon <img>.
|
| 288 |
+
*/
|
| 289 |
+
component.handleStatusChange = function handleStatusChange() {
|
| 290 |
+
const setRowStatusClass = function( { row, select } ) {
|
| 291 |
+
const acceptedValue = 3;
|
| 292 |
+
const rejectedValue = 2;
|
| 293 |
+
const status = parseInt( select.options[ select.selectedIndex ].value );
|
| 294 |
+
|
| 295 |
+
row.classList.toggle( 'new', isNaN( status ) );
|
| 296 |
+
row.classList.toggle( 'accepted', acceptedValue === status );
|
| 297 |
+
row.classList.toggle( 'rejected', rejectedValue === status );
|
| 298 |
+
};
|
| 299 |
+
|
| 300 |
+
const onChange = function( { event, row, select } ) {
|
| 301 |
+
if ( event.target.matches( 'select' ) ) {
|
| 302 |
+
component.updateSelectIcon( event.target );
|
| 303 |
+
setRowStatusClass( { row, select } );
|
| 304 |
+
}
|
| 305 |
+
};
|
| 306 |
+
|
| 307 |
+
document.querySelectorAll( 'tr[id^="tag-"]' ).forEach( function( row ) {
|
| 308 |
+
const select = row.querySelector( '.amp-validation-error-status' );
|
| 309 |
+
|
| 310 |
+
if ( select ) {
|
| 311 |
+
setRowStatusClass( { row, select } );
|
| 312 |
+
select.addEventListener( 'change', function( event ) {
|
| 313 |
+
onChange( { event, row, select } );
|
| 314 |
+
} );
|
| 315 |
+
}
|
| 316 |
+
} );
|
| 317 |
+
};
|
| 318 |
+
|
| 319 |
+
/**
|
| 320 |
+
* On checking a bulk action checkbox, this ensures that the 'Accept' and 'Reject' buttons are present. Handle clicking on buttons.
|
| 321 |
+
*
|
| 322 |
+
* They're hidden until one of these boxes is checked.
|
| 323 |
+
* Also, on unchecking the last checked box, this hides these buttons.
|
| 324 |
+
*/
|
| 325 |
+
component.handleBulkActions = function handleBulkActions() {
|
| 326 |
+
const acceptButton = document.querySelector( 'button.action.accept' );
|
| 327 |
+
const rejectButton = document.querySelector( 'button.action.reject' );
|
| 328 |
+
const acceptAndRejectContainer = document.getElementById( 'accept-reject-buttons' );
|
| 329 |
+
|
| 330 |
+
const onChange = function( event ) {
|
| 331 |
+
let areThereCheckedBoxes;
|
| 332 |
+
|
| 333 |
+
if ( ! event.target.matches( '[type=checkbox]' ) ) {
|
| 334 |
+
return;
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
if ( event.target.checked ) {
|
| 338 |
+
// This checkbox was checked, so ensure the buttons display.
|
| 339 |
+
acceptAndRejectContainer.classList.remove( 'hidden' );
|
| 340 |
+
} else {
|
| 341 |
+
/*
|
| 342 |
+
* This checkbox was unchecked.
|
| 343 |
+
* So find if there are any other checkboxes that are checked.
|
| 344 |
+
* If not, hide the 'Accept' and 'Reject' buttons.
|
| 345 |
+
*/
|
| 346 |
+
areThereCheckedBoxes = false;
|
| 347 |
+
document.querySelectorAll( '.check-column [type=checkbox]' ).forEach( function( element ) {
|
| 348 |
+
if ( element.checked ) {
|
| 349 |
+
areThereCheckedBoxes = true;
|
| 350 |
+
}
|
| 351 |
+
} );
|
| 352 |
+
if ( ! areThereCheckedBoxes ) {
|
| 353 |
+
acceptAndRejectContainer.classList.add( 'hidden' );
|
| 354 |
+
}
|
| 355 |
+
}
|
| 356 |
+
};
|
| 357 |
+
|
| 358 |
+
document.querySelectorAll( '.check-column [type=checkbox]' ).forEach( function( element ) {
|
| 359 |
+
element.addEventListener( 'change', onChange );
|
| 360 |
+
} );
|
| 361 |
+
|
| 362 |
+
// Handle click on accept button.
|
| 363 |
+
acceptButton.addEventListener( 'click', function() {
|
| 364 |
+
Array.prototype.forEach.call( document.querySelectorAll( 'select.amp-validation-error-status' ), function( select ) {
|
| 365 |
+
if ( select.closest( 'tr' ).querySelector( '.check-column input[type=checkbox]' ).checked ) {
|
| 366 |
+
select.value = '3';
|
| 367 |
+
component.updateSelectIcon( select );
|
| 368 |
+
component.addBeforeUnloadPrompt();
|
| 369 |
+
}
|
| 370 |
+
} );
|
| 371 |
+
} );
|
| 372 |
+
|
| 373 |
+
// Handle click on reject button.
|
| 374 |
+
rejectButton.addEventListener( 'click', function() {
|
| 375 |
+
Array.prototype.forEach.call( document.querySelectorAll( 'select.amp-validation-error-status' ), function( select ) {
|
| 376 |
+
if ( select.closest( 'tr' ).querySelector( '.check-column input[type=checkbox]' ).checked ) {
|
| 377 |
+
select.value = '2';
|
| 378 |
+
component.updateSelectIcon( select );
|
| 379 |
+
component.addBeforeUnloadPrompt();
|
| 380 |
+
}
|
| 381 |
+
} );
|
| 382 |
+
} );
|
| 383 |
+
};
|
| 384 |
+
|
| 385 |
+
/**
|
| 386 |
+
* Changes the page heading and document title, as this doesn't look to be possible with a PHP filter.
|
| 387 |
+
*/
|
| 388 |
+
component.changeHeading = function changeHeading() {
|
| 389 |
+
const headingQuery = document.getElementsByClassName( 'wp-heading-inline' );
|
| 390 |
+
if ( headingQuery[ 0 ] && component.data.l10n.page_heading ) {
|
| 391 |
+
headingQuery[ 0 ].innerText = component.data.l10n.page_heading;
|
| 392 |
+
document.title = component.data.l10n.page_heading + document.title;
|
| 393 |
+
}
|
| 394 |
+
};
|
| 395 |
+
|
| 396 |
+
/**
|
| 397 |
+
* Adds the AMP icon to the page heading if AMP is enabled on this URL.
|
| 398 |
+
*/
|
| 399 |
+
component.showAMPIconIfEnabled = function() {
|
| 400 |
+
const heading = document.querySelector( 'h1.wp-heading-inline' );
|
| 401 |
+
if ( heading && true === component.data.l10n.amp_enabled ) {
|
| 402 |
+
const ampIcon = document.createElement( 'span' );
|
| 403 |
+
ampIcon.classList.add( 'status-text', 'sanitized' );
|
| 404 |
+
heading.appendChild( ampIcon );
|
| 405 |
+
}
|
| 406 |
+
};
|
| 407 |
+
|
| 408 |
+
return component;
|
| 409 |
+
}() );
|
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* exported ampValidatedUrlsIndex */
|
| 2 |
+
|
| 3 |
+
const ampValidatedUrlsIndex = ( function() { // eslint-disable-line no-unused-vars
|
| 4 |
+
let component = {
|
| 5 |
+
classes: {}
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* The class for the new status
|
| 10 |
+
*
|
| 11 |
+
* @type {string}
|
| 12 |
+
*/
|
| 13 |
+
component.classes.new = 'new';
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* Boot.
|
| 17 |
+
*/
|
| 18 |
+
component.boot = function boot() {
|
| 19 |
+
component.highlightRowsWithNewStatus();
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* Highlight rows with new status.
|
| 24 |
+
*/
|
| 25 |
+
component.highlightRowsWithNewStatus = function highlightRowsWithNewStatus() {
|
| 26 |
+
document.querySelectorAll( 'tr[id^="post-"]' ).forEach( function( row ) {
|
| 27 |
+
if ( row.querySelector( 'span.status-text.' + component.classes.new ) ) {
|
| 28 |
+
row.classList.add( 'new' );
|
| 29 |
+
}
|
| 30 |
+
} );
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
return component;
|
| 34 |
+
}() );
|
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/******/ (function(modules) { // webpackBootstrap
|
| 2 |
+
/******/ // The module cache
|
| 3 |
+
/******/ var installedModules = {};
|
| 4 |
+
/******/
|
| 5 |
+
/******/ // The require function
|
| 6 |
+
/******/ function __webpack_require__(moduleId) {
|
| 7 |
+
/******/
|
| 8 |
+
/******/ // Check if module is in cache
|
| 9 |
+
/******/ if(installedModules[moduleId]) {
|
| 10 |
+
/******/ return installedModules[moduleId].exports;
|
| 11 |
+
/******/ }
|
| 12 |
+
/******/ // Create a new module (and put it into the cache)
|
| 13 |
+
/******/ var module = installedModules[moduleId] = {
|
| 14 |
+
/******/ i: moduleId,
|
| 15 |
+
/******/ l: false,
|
| 16 |
+
/******/ exports: {}
|
| 17 |
+
/******/ };
|
| 18 |
+
/******/
|
| 19 |
+
/******/ // Execute the module function
|
| 20 |
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
| 21 |
+
/******/
|
| 22 |
+
/******/ // Flag the module as loaded
|
| 23 |
+
/******/ module.l = true;
|
| 24 |
+
/******/
|
| 25 |
+
/******/ // Return the exports of the module
|
| 26 |
+
/******/ return module.exports;
|
| 27 |
+
/******/ }
|
| 28 |
+
/******/
|
| 29 |
+
/******/
|
| 30 |
+
/******/ // expose the modules object (__webpack_modules__)
|
| 31 |
+
/******/ __webpack_require__.m = modules;
|
| 32 |
+
/******/
|
| 33 |
+
/******/ // expose the module cache
|
| 34 |
+
/******/ __webpack_require__.c = installedModules;
|
| 35 |
+
/******/
|
| 36 |
+
/******/ // define getter function for harmony exports
|
| 37 |
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
| 38 |
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
| 39 |
+
/******/ Object.defineProperty(exports, name, {
|
| 40 |
+
/******/ configurable: false,
|
| 41 |
+
/******/ enumerable: true,
|
| 42 |
+
/******/ get: getter
|
| 43 |
+
/******/ });
|
| 44 |
+
/******/ }
|
| 45 |
+
/******/ };
|
| 46 |
+
/******/
|
| 47 |
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
| 48 |
+
/******/ __webpack_require__.n = function(module) {
|
| 49 |
+
/******/ var getter = module && module.__esModule ?
|
| 50 |
+
/******/ function getDefault() { return module['default']; } :
|
| 51 |
+
/******/ function getModuleExports() { return module; };
|
| 52 |
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
| 53 |
+
/******/ return getter;
|
| 54 |
+
/******/ };
|
| 55 |
+
/******/
|
| 56 |
+
/******/ // Object.prototype.hasOwnProperty.call
|
| 57 |
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
| 58 |
+
/******/
|
| 59 |
+
/******/ // __webpack_public_path__
|
| 60 |
+
/******/ __webpack_require__.p = "";
|
| 61 |
+
/******/
|
| 62 |
+
/******/ // Load entry module and return exports
|
| 63 |
+
/******/ return __webpack_require__(__webpack_require__.s = 14);
|
| 64 |
+
/******/ })
|
| 65 |
+
/************************************************************************/
|
| 66 |
+
/******/ ({
|
| 67 |
+
|
| 68 |
+
/***/ 1:
|
| 69 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 70 |
+
|
| 71 |
+
"use strict";
|
| 72 |
+
eval("/**\n * Specify a function to execute when the DOM is fully loaded.\n *\n * @param {Function} callback A function to execute after the DOM is ready.\n *\n * @return {void}\n */\nvar domReady = function domReady(callback) {\n if (document.readyState === 'complete' || // DOMContentLoaded + Images/Styles/etc loaded, so we call directly.\n document.readyState === 'interactive' // DOMContentLoaded fires at this point, so we call directly.\n ) {\n return callback();\n } // DOMContentLoaded has not fired yet, delay callback until then.\n\n\n document.addEventListener('DOMContentLoaded', callback);\n};\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (domReady);\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9Ad29yZHByZXNzL2RvbS1yZWFkeS9idWlsZC1tb2R1bGUvaW5kZXguanM/YTc2MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNwZWNpZnkgYSBmdW5jdGlvbiB0byBleGVjdXRlIHdoZW4gdGhlIERPTSBpcyBmdWxseSBsb2FkZWQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQSBmdW5jdGlvbiB0byBleGVjdXRlIGFmdGVyIHRoZSBET00gaXMgcmVhZHkuXG4gKlxuICogQHJldHVybiB7dm9pZH1cbiAqL1xudmFyIGRvbVJlYWR5ID0gZnVuY3Rpb24gZG9tUmVhZHkoY2FsbGJhY2spIHtcbiAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScgfHwgLy8gRE9NQ29udGVudExvYWRlZCArIEltYWdlcy9TdHlsZXMvZXRjIGxvYWRlZCwgc28gd2UgY2FsbCBkaXJlY3RseS5cbiAgZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2ludGVyYWN0aXZlJyAvLyBET01Db250ZW50TG9hZGVkIGZpcmVzIGF0IHRoaXMgcG9pbnQsIHNvIHdlIGNhbGwgZGlyZWN0bHkuXG4gICkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfSAvLyBET01Db250ZW50TG9hZGVkIGhhcyBub3QgZmlyZWQgeWV0LCBkZWxheSBjYWxsYmFjayB1bnRpbCB0aGVuLlxuXG5cbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGRvbVJlYWR5O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvQHdvcmRwcmVzcy9kb20tcmVhZHkvYnVpbGQtbW9kdWxlL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMSAyIDMiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1\n");
|
| 73 |
+
|
| 74 |
+
/***/ }),
|
| 75 |
+
|
| 76 |
+
/***/ 14:
|
| 77 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 78 |
+
|
| 79 |
+
"use strict";
|
| 80 |
+
eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__wordpress_dom_ready__ = __webpack_require__(1);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_amp_validation_i18n__ = __webpack_require__(15);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_amp_validation_i18n___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_amp_validation_i18n__);\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\n/**\n * WordPress dependencies\n */\n\n\n/**\n * Localized data\n */\n\n\nvar OPEN_CLASS = 'is-open';\n\n/**\n * Adds detail toggle buttons to the header and footer rows of the validation error \"details\" column.\n * The buttons are added via JS because there's no easy way to append them to the heading of a sortable\n * table column via backend code.\n *\n * @param {string} containerSelector Selector for elements that will have the button added.\n * @param {string} ariaLabel Screen reader label for the button.\n * @return {Array} Array of added buttons.\n */\nfunction addToggleButtons(containerSelector, ariaLabel) {\n\tvar addButton = function addButton(container) {\n\t\tvar button = document.createElement('button');\n\t\tbutton.setAttribute('aria-label', ariaLabel);\n\t\tbutton.setAttribute('type', 'button');\n\t\tbutton.setAttribute('class', 'error-details-toggle');\n\t\tcontainer.appendChild(button);\n\n\t\treturn button;\n\t};\n\n\treturn [].concat(_toConsumableArray(document.querySelectorAll(containerSelector))).map(function (container) {\n\t\treturn addButton(container);\n\t});\n}\n\nfunction addToggleAllListener(_ref) {\n\tvar btn = _ref.btn,\n\t _ref$toggleAllButtonS = _ref.toggleAllButtonSelector,\n\t toggleAllButtonSelector = _ref$toggleAllButtonS === undefined ? null : _ref$toggleAllButtonS,\n\t targetDetailsSelector = _ref.targetDetailsSelector;\n\n\tvar open = false;\n\n\tvar targetDetails = [].concat(_toConsumableArray(document.querySelectorAll(targetDetailsSelector)));\n\n\tvar toggleAllButtons = [];\n\tif (toggleAllButtonSelector) {\n\t\ttoggleAllButtons = [].concat(_toConsumableArray(document.querySelectorAll(toggleAllButtonSelector)));\n\t}\n\n\tvar onButtonClick = function onButtonClick() {\n\t\topen = !open;\n\t\ttoggleAllButtons.forEach(function (toggleAllButton) {\n\t\t\ttoggleAllButton.classList.toggle(OPEN_CLASS);\n\t\t});\n\n\t\ttargetDetails.forEach(function (detail) {\n\t\t\tif (open) {\n\t\t\t\tdetail.setAttribute('open', true);\n\t\t\t} else {\n\t\t\t\tdetail.removeAttribute('open');\n\t\t\t}\n\t\t});\n\t};\n\n\tbtn.addEventListener('click', onButtonClick);\n}\n\n/**\n * Adds classes to the rows for the amp_validation_error term list table.\n *\n * This is needed because \\WP_Terms_List_Table::single_row() does not allow for additional\n * attributes to be added to the <tr> element.\n */\nfunction addTermListTableRowClasses() {\n\tvar rows = [].concat(_toConsumableArray(document.querySelectorAll('#the-list tr')));\n\trows.forEach(function (row) {\n\t\tvar statusText = row.querySelector('.column-status > .status-text');\n\t\tif (statusText) {\n\t\t\trow.classList.toggle('new', statusText.classList.contains('new'));\n\t\t\trow.classList.toggle('accepted', statusText.classList.contains('accepted'));\n\t\t\trow.classList.toggle('rejected', statusText.classList.contains('rejected'));\n\t\t}\n\t});\n}\n\nObject(__WEBPACK_IMPORTED_MODULE_0__wordpress_dom_ready__[\"a\" /* default */])(function () {\n\taddToggleButtons('th.column-details.manage-column', __WEBPACK_IMPORTED_MODULE_1_amp_validation_i18n__[\"detailToggleBtnAriaLabel\"]).forEach(function (btn) {\n\t\taddToggleAllListener({\n\t\t\tbtn: btn,\n\t\t\ttoggleAllButtonSelector: '.column-details button.error-details-toggle',\n\t\t\ttargetDetailsSelector: '.column-details details'\n\t\t});\n\t});\n\n\taddToggleButtons('th.manage-column.column-sources_with_invalid_output', __WEBPACK_IMPORTED_MODULE_1_amp_validation_i18n__[\"sourcesToggleBtnAriaLabel\"]).forEach(function (btn) {\n\t\taddToggleAllListener({\n\t\t\tbtn: btn,\n\t\t\ttoggleAllButtonSelector: '.column-sources_with_invalid_output button.error-details-toggle',\n\t\t\ttargetDetailsSelector: 'details.source'\n\t\t});\n\t});\n\n\taddTermListTableRowClasses();\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hc3NldHMvc3JjL2FtcC12YWxpZGF0aW9uLWRldGFpbC10b2dnbGUuanM/YmUxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9IGVsc2UgeyByZXR1cm4gQXJyYXkuZnJvbShhcnIpOyB9IH1cblxuLyoqXG4gKiBXb3JkUHJlc3MgZGVwZW5kZW5jaWVzXG4gKi9cbmltcG9ydCBkb21SZWFkeSBmcm9tICdAd29yZHByZXNzL2RvbS1yZWFkeSc7XG5cbi8qKlxuICogTG9jYWxpemVkIGRhdGFcbiAqL1xuaW1wb3J0IHsgZGV0YWlsVG9nZ2xlQnRuQXJpYUxhYmVsLCBzb3VyY2VzVG9nZ2xlQnRuQXJpYUxhYmVsIH0gZnJvbSAnYW1wLXZhbGlkYXRpb24taTE4bic7XG5cbnZhciBPUEVOX0NMQVNTID0gJ2lzLW9wZW4nO1xuXG4vKipcbiAqIEFkZHMgZGV0YWlsIHRvZ2dsZSBidXR0b25zIHRvIHRoZSBoZWFkZXIgYW5kIGZvb3RlciByb3dzIG9mIHRoZSB2YWxpZGF0aW9uIGVycm9yIFwiZGV0YWlsc1wiIGNvbHVtbi5cbiAqIFRoZSBidXR0b25zIGFyZSBhZGRlZCB2aWEgSlMgYmVjYXVzZSB0aGVyZSdzIG5vIGVhc3kgd2F5IHRvIGFwcGVuZCB0aGVtIHRvIHRoZSBoZWFkaW5nIG9mIGEgc29ydGFibGVcbiAqIHRhYmxlIGNvbHVtbiB2aWEgYmFja2VuZCBjb2RlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250YWluZXJTZWxlY3RvciBTZWxlY3RvciBmb3IgZWxlbWVudHMgdGhhdCB3aWxsIGhhdmUgdGhlIGJ1dHRvbiBhZGRlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmlhTGFiZWwgU2NyZWVuIHJlYWRlciBsYWJlbCBmb3IgdGhlIGJ1dHRvbi5cbiAqIEByZXR1cm4ge0FycmF5fSBBcnJheSBvZiBhZGRlZCBidXR0b25zLlxuICovXG5mdW5jdGlvbiBhZGRUb2dnbGVCdXR0b25zKGNvbnRhaW5lclNlbGVjdG9yLCBhcmlhTGFiZWwpIHtcblx0dmFyIGFkZEJ1dHRvbiA9IGZ1bmN0aW9uIGFkZEJ1dHRvbihjb250YWluZXIpIHtcblx0XHR2YXIgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG5cdFx0YnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsIGFyaWFMYWJlbCk7XG5cdFx0YnV0dG9uLnNldEF0dHJpYnV0ZSgndHlwZScsICdidXR0b24nKTtcblx0XHRidXR0b24uc2V0QXR0cmlidXRlKCdjbGFzcycsICdlcnJvci1kZXRhaWxzLXRvZ2dsZScpO1xuXHRcdGNvbnRhaW5lci5hcHBlbmRDaGlsZChidXR0b24pO1xuXG5cdFx0cmV0dXJuIGJ1dHRvbjtcblx0fTtcblxuXHRyZXR1cm4gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGNvbnRhaW5lclNlbGVjdG9yKSkpLm1hcChmdW5jdGlvbiAoY29udGFpbmVyKSB7XG5cdFx0cmV0dXJuIGFkZEJ1dHRvbihjb250YWluZXIpO1xuXHR9KTtcbn1cblxuZnVuY3Rpb24gYWRkVG9nZ2xlQWxsTGlzdGVuZXIoX3JlZikge1xuXHR2YXIgYnRuID0gX3JlZi5idG4sXG5cdCAgICBfcmVmJHRvZ2dsZUFsbEJ1dHRvblMgPSBfcmVmLnRvZ2dsZUFsbEJ1dHRvblNlbGVjdG9yLFxuXHQgICAgdG9nZ2xlQWxsQnV0dG9uU2VsZWN0b3IgPSBfcmVmJHRvZ2dsZUFsbEJ1dHRvblMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBfcmVmJHRvZ2dsZUFsbEJ1dHRvblMsXG5cdCAgICB0YXJnZXREZXRhaWxzU2VsZWN0b3IgPSBfcmVmLnRhcmdldERldGFpbHNTZWxlY3RvcjtcblxuXHR2YXIgb3BlbiA9IGZhbHNlO1xuXG5cdHZhciB0YXJnZXREZXRhaWxzID0gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHRhcmdldERldGFpbHNTZWxlY3RvcikpKTtcblxuXHR2YXIgdG9nZ2xlQWxsQnV0dG9ucyA9IFtdO1xuXHRpZiAodG9nZ2xlQWxsQnV0dG9uU2VsZWN0b3IpIHtcblx0XHR0b2dnbGVBbGxCdXR0b25zID0gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHRvZ2dsZUFsbEJ1dHRvblNlbGVjdG9yKSkpO1xuXHR9XG5cblx0dmFyIG9uQnV0dG9uQ2xpY2sgPSBmdW5jdGlvbiBvbkJ1dHRvbkNsaWNrKCkge1xuXHRcdG9wZW4gPSAhb3Blbjtcblx0XHR0b2dnbGVBbGxCdXR0b25zLmZvckVhY2goZnVuY3Rpb24gKHRvZ2dsZUFsbEJ1dHRvbikge1xuXHRcdFx0dG9nZ2xlQWxsQnV0dG9uLmNsYXNzTGlzdC50b2dnbGUoT1BFTl9DTEFTUyk7XG5cdFx0fSk7XG5cblx0XHR0YXJnZXREZXRhaWxzLmZvckVhY2goZnVuY3Rpb24gKGRldGFpbCkge1xuXHRcdFx0aWYgKG9wZW4pIHtcblx0XHRcdFx0ZGV0YWlsLnNldEF0dHJpYnV0ZSgnb3BlbicsIHRydWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGV0YWlsLnJlbW92ZUF0dHJpYnV0ZSgnb3BlbicpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9O1xuXG5cdGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIG9uQnV0dG9uQ2xpY2spO1xufVxuXG4vKipcbiAqIEFkZHMgY2xhc3NlcyB0byB0aGUgcm93cyBmb3IgdGhlIGFtcF92YWxpZGF0aW9uX2Vycm9yIHRlcm0gbGlzdCB0YWJsZS5cbiAqXG4gKiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIFxcV1BfVGVybXNfTGlzdF9UYWJsZTo6c2luZ2xlX3JvdygpIGRvZXMgbm90IGFsbG93IGZvciBhZGRpdGlvbmFsXG4gKiBhdHRyaWJ1dGVzIHRvIGJlIGFkZGVkIHRvIHRoZSA8dHI+IGVsZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGFkZFRlcm1MaXN0VGFibGVSb3dDbGFzc2VzKCkge1xuXHR2YXIgcm93cyA9IFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3RoZS1saXN0IHRyJykpKTtcblx0cm93cy5mb3JFYWNoKGZ1bmN0aW9uIChyb3cpIHtcblx0XHR2YXIgc3RhdHVzVGV4dCA9IHJvdy5xdWVyeVNlbGVjdG9yKCcuY29sdW1uLXN0YXR1cyA+IC5zdGF0dXMtdGV4dCcpO1xuXHRcdGlmIChzdGF0dXNUZXh0KSB7XG5cdFx0XHRyb3cuY2xhc3NMaXN0LnRvZ2dsZSgnbmV3Jywgc3RhdHVzVGV4dC5jbGFzc0xpc3QuY29udGFpbnMoJ25ldycpKTtcblx0XHRcdHJvdy5jbGFzc0xpc3QudG9nZ2xlKCdhY2NlcHRlZCcsIHN0YXR1c1RleHQuY2xhc3NMaXN0LmNvbnRhaW5zKCdhY2NlcHRlZCcpKTtcblx0XHRcdHJvdy5jbGFzc0xpc3QudG9nZ2xlKCdyZWplY3RlZCcsIHN0YXR1c1RleHQuY2xhc3NMaXN0LmNvbnRhaW5zKCdyZWplY3RlZCcpKTtcblx0XHR9XG5cdH0pO1xufVxuXG5kb21SZWFkeShmdW5jdGlvbiAoKSB7XG5cdGFkZFRvZ2dsZUJ1dHRvbnMoJ3RoLmNvbHVtbi1kZXRhaWxzLm1hbmFnZS1jb2x1bW4nLCBkZXRhaWxUb2dnbGVCdG5BcmlhTGFiZWwpLmZvckVhY2goZnVuY3Rpb24gKGJ0bikge1xuXHRcdGFkZFRvZ2dsZUFsbExpc3RlbmVyKHtcblx0XHRcdGJ0bjogYnRuLFxuXHRcdFx0dG9nZ2xlQWxsQnV0dG9uU2VsZWN0b3I6ICcuY29sdW1uLWRldGFpbHMgYnV0dG9uLmVycm9yLWRldGFpbHMtdG9nZ2xlJyxcblx0XHRcdHRhcmdldERldGFpbHNTZWxlY3RvcjogJy5jb2x1bW4tZGV0YWlscyBkZXRhaWxzJ1xuXHRcdH0pO1xuXHR9KTtcblxuXHRhZGRUb2dnbGVCdXR0b25zKCd0aC5tYW5hZ2UtY29sdW1uLmNvbHVtbi1zb3VyY2VzX3dpdGhfaW52YWxpZF9vdXRwdXQnLCBzb3VyY2VzVG9nZ2xlQnRuQXJpYUxhYmVsKS5mb3JFYWNoKGZ1bmN0aW9uIChidG4pIHtcblx0XHRhZGRUb2dnbGVBbGxMaXN0ZW5lcih7XG5cdFx0XHRidG46IGJ0bixcblx0XHRcdHRvZ2dsZUFsbEJ1dHRvblNlbGVjdG9yOiAnLmNvbHVtbi1zb3VyY2VzX3dpdGhfaW52YWxpZF9vdXRwdXQgYnV0dG9uLmVycm9yLWRldGFpbHMtdG9nZ2xlJyxcblx0XHRcdHRhcmdldERldGFpbHNTZWxlY3RvcjogJ2RldGFpbHMuc291cmNlJ1xuXHRcdH0pO1xuXHR9KTtcblxuXHRhZGRUZXJtTGlzdFRhYmxlUm93Q2xhc3NlcygpO1xufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9hc3NldHMvc3JjL2FtcC12YWxpZGF0aW9uLWRldGFpbC10b2dnbGUuanNcbi8vIG1vZHVsZSBpZCA9IDE0XG4vLyBtb2R1bGUgY2h1bmtzID0gMSJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///14\n");
|
| 81 |
+
|
| 82 |
+
/***/ }),
|
| 83 |
+
|
| 84 |
+
/***/ 15:
|
| 85 |
+
/***/ (function(module, exports) {
|
| 86 |
+
|
| 87 |
+
module.exports = ampValidationI18n;
|
| 88 |
+
|
| 89 |
+
/***/ })
|
| 90 |
+
|
| 91 |
+
/******/ });
|
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/******/ (function(modules) { // webpackBootstrap
|
| 2 |
+
/******/ // The module cache
|
| 3 |
+
/******/ var installedModules = {};
|
| 4 |
+
/******/
|
| 5 |
+
/******/ // The require function
|
| 6 |
+
/******/ function __webpack_require__(moduleId) {
|
| 7 |
+
/******/
|
| 8 |
+
/******/ // Check if module is in cache
|
| 9 |
+
/******/ if(installedModules[moduleId]) {
|
| 10 |
+
/******/ return installedModules[moduleId].exports;
|
| 11 |
+
/******/ }
|
| 12 |
+
/******/ // Create a new module (and put it into the cache)
|
| 13 |
+
/******/ var module = installedModules[moduleId] = {
|
| 14 |
+
/******/ i: moduleId,
|
| 15 |
+
/******/ l: false,
|
| 16 |
+
/******/ exports: {}
|
| 17 |
+
/******/ };
|
| 18 |
+
/******/
|
| 19 |
+
/******/ // Execute the module function
|
| 20 |
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
| 21 |
+
/******/
|
| 22 |
+
/******/ // Flag the module as loaded
|
| 23 |
+
/******/ module.l = true;
|
| 24 |
+
/******/
|
| 25 |
+
/******/ // Return the exports of the module
|
| 26 |
+
/******/ return module.exports;
|
| 27 |
+
/******/ }
|
| 28 |
+
/******/
|
| 29 |
+
/******/
|
| 30 |
+
/******/ // expose the modules object (__webpack_modules__)
|
| 31 |
+
/******/ __webpack_require__.m = modules;
|
| 32 |
+
/******/
|
| 33 |
+
/******/ // expose the module cache
|
| 34 |
+
/******/ __webpack_require__.c = installedModules;
|
| 35 |
+
/******/
|
| 36 |
+
/******/ // define getter function for harmony exports
|
| 37 |
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
| 38 |
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
| 39 |
+
/******/ Object.defineProperty(exports, name, {
|
| 40 |
+
/******/ configurable: false,
|
| 41 |
+
/******/ enumerable: true,
|
| 42 |
+
/******/ get: getter
|
| 43 |
+
/******/ });
|
| 44 |
+
/******/ }
|
| 45 |
+
/******/ };
|
| 46 |
+
/******/
|
| 47 |
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
| 48 |
+
/******/ __webpack_require__.n = function(module) {
|
| 49 |
+
/******/ var getter = module && module.__esModule ?
|
| 50 |
+
/******/ function getDefault() { return module['default']; } :
|
| 51 |
+
/******/ function getModuleExports() { return module; };
|
| 52 |
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
| 53 |
+
/******/ return getter;
|
| 54 |
+
/******/ };
|
| 55 |
+
/******/
|
| 56 |
+
/******/ // Object.prototype.hasOwnProperty.call
|
| 57 |
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
| 58 |
+
/******/
|
| 59 |
+
/******/ // __webpack_public_path__
|
| 60 |
+
/******/ __webpack_require__.p = "";
|
| 61 |
+
/******/
|
| 62 |
+
/******/ // Load entry module and return exports
|
| 63 |
+
/******/ return __webpack_require__(__webpack_require__.s = 17);
|
| 64 |
+
/******/ })
|
| 65 |
+
/************************************************************************/
|
| 66 |
+
/******/ ({
|
| 67 |
+
|
| 68 |
+
/***/ 1:
|
| 69 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 70 |
+
|
| 71 |
+
"use strict";
|
| 72 |
+
eval("/**\n * Specify a function to execute when the DOM is fully loaded.\n *\n * @param {Function} callback A function to execute after the DOM is ready.\n *\n * @return {void}\n */\nvar domReady = function domReady(callback) {\n if (document.readyState === 'complete' || // DOMContentLoaded + Images/Styles/etc loaded, so we call directly.\n document.readyState === 'interactive' // DOMContentLoaded fires at this point, so we call directly.\n ) {\n return callback();\n } // DOMContentLoaded has not fired yet, delay callback until then.\n\n\n document.addEventListener('DOMContentLoaded', callback);\n};\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (domReady);\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9Ad29yZHByZXNzL2RvbS1yZWFkeS9idWlsZC1tb2R1bGUvaW5kZXguanM/YTc2MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNwZWNpZnkgYSBmdW5jdGlvbiB0byBleGVjdXRlIHdoZW4gdGhlIERPTSBpcyBmdWxseSBsb2FkZWQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQSBmdW5jdGlvbiB0byBleGVjdXRlIGFmdGVyIHRoZSBET00gaXMgcmVhZHkuXG4gKlxuICogQHJldHVybiB7dm9pZH1cbiAqL1xudmFyIGRvbVJlYWR5ID0gZnVuY3Rpb24gZG9tUmVhZHkoY2FsbGJhY2spIHtcbiAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScgfHwgLy8gRE9NQ29udGVudExvYWRlZCArIEltYWdlcy9TdHlsZXMvZXRjIGxvYWRlZCwgc28gd2UgY2FsbCBkaXJlY3RseS5cbiAgZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2ludGVyYWN0aXZlJyAvLyBET01Db250ZW50TG9hZGVkIGZpcmVzIGF0IHRoaXMgcG9pbnQsIHNvIHdlIGNhbGwgZGlyZWN0bHkuXG4gICkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfSAvLyBET01Db250ZW50TG9hZGVkIGhhcyBub3QgZmlyZWQgeWV0LCBkZWxheSBjYWxsYmFjayB1bnRpbCB0aGVuLlxuXG5cbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGRvbVJlYWR5O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvQHdvcmRwcmVzcy9kb20tcmVhZHkvYnVpbGQtbW9kdWxlL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMSAyIDMiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1\n");
|
| 73 |
+
|
| 74 |
+
/***/ }),
|
| 75 |
+
|
| 76 |
+
/***/ 17:
|
| 77 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 78 |
+
|
| 79 |
+
"use strict";
|
| 80 |
+
eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__wordpress_dom_ready__ = __webpack_require__(1);\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * WordPress dependencies\n */\n\n\n/**\n * Toggles the contents of a details element as an additional table tr.\n */\n\nvar RowToggler = function () {\n\tfunction RowToggler(tr, index) {\n\t\t_classCallCheck(this, RowToggler);\n\n\t\tthis.tr = tr;\n\t\tthis.index = index;\n\n\t\t// Since we're adding additional rows, we need to override default .striped tables styles.\n\t\tthis.tr.classList.add(this.index % 2 ? 'odd' : 'even'); // eslint-disable-line no-magic-numbers\n\n\t\tthis.toggle = this.toggle.bind(this);\n\t}\n\n\t/**\n * Sets up the new tr and adds an event listener to toggle details.\n */\n\n\n\t_createClass(RowToggler, [{\n\t\tkey: 'init',\n\t\tvalue: function init() {\n\t\t\tvar _this = this;\n\n\t\t\tthis.details = this.tr.querySelector('.column-details details');\n\t\t\tif (this.details) {\n\t\t\t\tthis.createNewTr();\n\t\t\t\tvar togglers = [].concat(_toConsumableArray(this.tr.querySelectorAll('.single-url-detail-toggle')), [this.details.querySelector('summary')]);\n\n\t\t\t\ttogglers.forEach(function (el) {\n\t\t\t\t\tel.addEventListener('click', function () {\n\t\t\t\t\t\t_this.toggle(el);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n * Creates the details table row from the original row's <details> element content, minus the summary.\n */\n\n\t}, {\n\t\tkey: 'createNewTr',\n\t\tvalue: function createNewTr() {\n\t\t\tthis.newTr = document.createElement('tr');\n\t\t\tthis.newTr.classList.add('details');\n\t\t\tthis.newTr.classList.add(this.index % 2 ? 'odd' : 'even'); // eslint-disable-line no-magic-numbers\n\n\t\t\tvar newCell = document.createElement('td');\n\t\t\tnewCell.setAttribute('colspan', this.getRowColspan());\n\n\t\t\tvar _iteratorNormalCompletion = true;\n\t\t\tvar _didIteratorError = false;\n\t\t\tvar _iteratorError = undefined;\n\n\t\t\ttry {\n\t\t\t\tfor (var _iterator = this.details.childNodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n\t\t\t\t\tvar childNode = _step.value;\n\n\t\t\t\t\tif ('SUMMARY' !== childNode.tagName) {\n\t\t\t\t\t\tnewCell.appendChild(childNode.cloneNode(true));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t_didIteratorError = true;\n\t\t\t\t_iteratorError = err;\n\t\t\t} finally {\n\t\t\t\ttry {\n\t\t\t\t\tif (!_iteratorNormalCompletion && _iterator.return) {\n\t\t\t\t\t\t_iterator.return();\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tif (_didIteratorError) {\n\t\t\t\t\t\tthrow _iteratorError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.newTr.appendChild(newCell);\n\t\t}\n\n\t\t/**\n * Gets the number of cells within the original row.\n *\n * @return {number} The number of cells.\n */\n\n\t}, {\n\t\tkey: 'getRowColspan',\n\t\tvalue: function getRowColspan() {\n\t\t\treturn [].concat(_toConsumableArray(this.tr.childNodes)).filter(function (childNode) {\n\t\t\t\treturn ['TD', 'TH'].includes(childNode.tagName);\n\t\t\t}).length;\n\t\t}\n\n\t\t/**\n * Toggles the additional row.\n *\n * @param {Object} target The click event target.\n */\n\n\t}, {\n\t\tkey: 'toggle',\n\t\tvalue: function toggle(target) {\n\t\t\tif (this.tr.classList.contains('expanded')) {\n\t\t\t\tthis.onClose(target);\n\t\t\t} else {\n\t\t\t\tthis.onOpen(target);\n\t\t\t}\n\t\t}\n\n\t\t/**\n * Adds the additional row.\n *\n * @param {Object} target The click event target.\n */\n\n\t}, {\n\t\tkey: 'onOpen',\n\t\tvalue: function onOpen(target) {\n\t\t\tthis.tr.parentNode.insertBefore(this.newTr, this.tr.nextSibling);\n\t\t\tthis.tr.classList.add('expanded');\n\n\t\t\tif ('SUMMARY' !== target.tagName) {\n\t\t\t\t// This browser will do this if the summary was clicked.\n\t\t\t\tthis.details.setAttribute('open', true);\n\t\t\t}\n\t\t}\n\n\t\t/**\n * Removes the additional row.\n *\n * @param {Object} target The click event target.\n */\n\n\t}, {\n\t\tkey: 'onClose',\n\t\tvalue: function onClose(target) {\n\t\t\tthis.tr.parentNode.removeChild(this.newTr);\n\t\t\tthis.tr.classList.remove('expanded');\n\n\t\t\tif ('SUMMARY' !== target.tagName) {\n\t\t\t\tthis.details.removeAttribute('open');\n\t\t\t}\n\t\t}\n\t}]);\n\n\treturn RowToggler;\n}();\n\n/**\n * Sets up expandable details for errors when viewing a single URL error list.\n */\n\n\nvar ErrorRows = function () {\n\tfunction ErrorRows() {\n\t\t_classCallCheck(this, ErrorRows);\n\n\t\tthis.rows = [].concat(_toConsumableArray(document.querySelectorAll('.wp-list-table tr[id^=\"tag-\"]'))).map(function (tr, index) {\n\t\t\tvar rowHandler = new RowToggler(tr, index);\n\t\t\trowHandler.init();\n\t\t\treturn rowHandler;\n\t\t}).filter(function (row) {\n\t\t\treturn row.details;\n\t\t});\n\t}\n\n\t_createClass(ErrorRows, [{\n\t\tkey: 'init',\n\t\tvalue: function init() {\n\t\t\tthis.addToggleAllListener();\n\t\t}\n\n\t\t/**\n * Handle 'toggle all' buttons on the page.\n */\n\n\t}, {\n\t\tkey: 'addToggleAllListener',\n\t\tvalue: function addToggleAllListener() {\n\t\t\tvar _this2 = this;\n\n\t\t\tvar open = false;\n\t\t\tvar toggleButtons = [].concat(_toConsumableArray(document.querySelectorAll('.column-details button.error-details-toggle')));\n\n\t\t\tvar onButtonClick = function onButtonClick(target) {\n\t\t\t\topen = !open;\n\t\t\t\t_this2.rows.forEach(function (row) {\n\t\t\t\t\tif (open) {\n\t\t\t\t\t\trow.onOpen(target);\n\t\t\t\t\t} else {\n\t\t\t\t\t\trow.onClose(target);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t};\n\n\t\t\twindow.addEventListener('click', function (event) {\n\t\t\t\tif (toggleButtons.includes(event.target)) {\n\t\t\t\t\tonButtonClick(event.target);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}]);\n\n\treturn ErrorRows;\n}();\n\nObject(__WEBPACK_IMPORTED_MODULE_0__wordpress_dom_ready__[\"a\" /* default */])(function () {\n\tnew ErrorRows().init();\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hc3NldHMvc3JjL2FtcC12YWxpZGF0aW9uLXNpbmdsZS1lcnJvci11cmwtZGV0YWlscy5qcz80OTI0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbmZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IEFycmF5KGFyci5sZW5ndGgpOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH0gZWxzZSB7IHJldHVybiBBcnJheS5mcm9tKGFycik7IH0gfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG4vKipcbiAqIFdvcmRQcmVzcyBkZXBlbmRlbmNpZXNcbiAqL1xuaW1wb3J0IGRvbVJlYWR5IGZyb20gJ0B3b3JkcHJlc3MvZG9tLXJlYWR5JztcblxuLyoqXG4gKiBUb2dnbGVzIHRoZSBjb250ZW50cyBvZiBhIGRldGFpbHMgZWxlbWVudCBhcyBhbiBhZGRpdGlvbmFsIHRhYmxlIHRyLlxuICovXG5cbnZhciBSb3dUb2dnbGVyID0gZnVuY3Rpb24gKCkge1xuXHRmdW5jdGlvbiBSb3dUb2dnbGVyKHRyLCBpbmRleCkge1xuXHRcdF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSb3dUb2dnbGVyKTtcblxuXHRcdHRoaXMudHIgPSB0cjtcblx0XHR0aGlzLmluZGV4ID0gaW5kZXg7XG5cblx0XHQvLyBTaW5jZSB3ZSdyZSBhZGRpbmcgYWRkaXRpb25hbCByb3dzLCB3ZSBuZWVkIHRvIG92ZXJyaWRlIGRlZmF1bHQgLnN0cmlwZWQgdGFibGVzIHN0eWxlcy5cblx0XHR0aGlzLnRyLmNsYXNzTGlzdC5hZGQodGhpcy5pbmRleCAlIDIgPyAnb2RkJyA6ICdldmVuJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbWFnaWMtbnVtYmVyc1xuXG5cdFx0dGhpcy50b2dnbGUgPSB0aGlzLnRvZ2dsZS5iaW5kKHRoaXMpO1xuXHR9XG5cblx0LyoqXG4gICogU2V0cyB1cCB0aGUgbmV3IHRyIGFuZCBhZGRzIGFuIGV2ZW50IGxpc3RlbmVyIHRvIHRvZ2dsZSBkZXRhaWxzLlxuICAqL1xuXG5cblx0X2NyZWF0ZUNsYXNzKFJvd1RvZ2dsZXIsIFt7XG5cdFx0a2V5OiAnaW5pdCcsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGluaXQoKSB7XG5cdFx0XHR2YXIgX3RoaXMgPSB0aGlzO1xuXG5cdFx0XHR0aGlzLmRldGFpbHMgPSB0aGlzLnRyLnF1ZXJ5U2VsZWN0b3IoJy5jb2x1bW4tZGV0YWlscyBkZXRhaWxzJyk7XG5cdFx0XHRpZiAodGhpcy5kZXRhaWxzKSB7XG5cdFx0XHRcdHRoaXMuY3JlYXRlTmV3VHIoKTtcblx0XHRcdFx0dmFyIHRvZ2dsZXJzID0gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheSh0aGlzLnRyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zaW5nbGUtdXJsLWRldGFpbC10b2dnbGUnKSksIFt0aGlzLmRldGFpbHMucXVlcnlTZWxlY3Rvcignc3VtbWFyeScpXSk7XG5cblx0XHRcdFx0dG9nZ2xlcnMuZm9yRWFjaChmdW5jdGlvbiAoZWwpIHtcblx0XHRcdFx0XHRlbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdF90aGlzLnRvZ2dsZShlbCk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBDcmVhdGVzIHRoZSBkZXRhaWxzIHRhYmxlIHJvdyBmcm9tIHRoZSBvcmlnaW5hbCByb3cncyA8ZGV0YWlscz4gZWxlbWVudCBjb250ZW50LCBtaW51cyB0aGUgc3VtbWFyeS5cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2NyZWF0ZU5ld1RyJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gY3JlYXRlTmV3VHIoKSB7XG5cdFx0XHR0aGlzLm5ld1RyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndHInKTtcblx0XHRcdHRoaXMubmV3VHIuY2xhc3NMaXN0LmFkZCgnZGV0YWlscycpO1xuXHRcdFx0dGhpcy5uZXdUci5jbGFzc0xpc3QuYWRkKHRoaXMuaW5kZXggJSAyID8gJ29kZCcgOiAnZXZlbicpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW1hZ2ljLW51bWJlcnNcblxuXHRcdFx0dmFyIG5ld0NlbGwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZCcpO1xuXHRcdFx0bmV3Q2VsbC5zZXRBdHRyaWJ1dGUoJ2NvbHNwYW4nLCB0aGlzLmdldFJvd0NvbHNwYW4oKSk7XG5cblx0XHRcdHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZTtcblx0XHRcdHZhciBfZGlkSXRlcmF0b3JFcnJvciA9IGZhbHNlO1xuXHRcdFx0dmFyIF9pdGVyYXRvckVycm9yID0gdW5kZWZpbmVkO1xuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRmb3IgKHZhciBfaXRlcmF0b3IgPSB0aGlzLmRldGFpbHMuY2hpbGROb2Rlc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSAoX3N0ZXAgPSBfaXRlcmF0b3IubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWUpIHtcblx0XHRcdFx0XHR2YXIgY2hpbGROb2RlID0gX3N0ZXAudmFsdWU7XG5cblx0XHRcdFx0XHRpZiAoJ1NVTU1BUlknICE9PSBjaGlsZE5vZGUudGFnTmFtZSkge1xuXHRcdFx0XHRcdFx0bmV3Q2VsbC5hcHBlbmRDaGlsZChjaGlsZE5vZGUuY2xvbmVOb2RlKHRydWUpKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0XHRfZGlkSXRlcmF0b3JFcnJvciA9IHRydWU7XG5cdFx0XHRcdF9pdGVyYXRvckVycm9yID0gZXJyO1xuXHRcdFx0fSBmaW5hbGx5IHtcblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gJiYgX2l0ZXJhdG9yLnJldHVybikge1xuXHRcdFx0XHRcdFx0X2l0ZXJhdG9yLnJldHVybigpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBmaW5hbGx5IHtcblx0XHRcdFx0XHRpZiAoX2RpZEl0ZXJhdG9yRXJyb3IpIHtcblx0XHRcdFx0XHRcdHRocm93IF9pdGVyYXRvckVycm9yO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLm5ld1RyLmFwcGVuZENoaWxkKG5ld0NlbGwpO1xuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgY2VsbHMgd2l0aGluIHRoZSBvcmlnaW5hbCByb3cuXG4gICAqXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBjZWxscy5cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2dldFJvd0NvbHNwYW4nLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiBnZXRSb3dDb2xzcGFuKCkge1xuXHRcdFx0cmV0dXJuIFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkodGhpcy50ci5jaGlsZE5vZGVzKSkuZmlsdGVyKGZ1bmN0aW9uIChjaGlsZE5vZGUpIHtcblx0XHRcdFx0cmV0dXJuIFsnVEQnLCAnVEgnXS5pbmNsdWRlcyhjaGlsZE5vZGUudGFnTmFtZSk7XG5cdFx0XHR9KS5sZW5ndGg7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIFRvZ2dsZXMgdGhlIGFkZGl0aW9uYWwgcm93LlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0IFRoZSBjbGljayBldmVudCB0YXJnZXQuXG4gICAqL1xuXG5cdH0sIHtcblx0XHRrZXk6ICd0b2dnbGUnLFxuXHRcdHZhbHVlOiBmdW5jdGlvbiB0b2dnbGUodGFyZ2V0KSB7XG5cdFx0XHRpZiAodGhpcy50ci5jbGFzc0xpc3QuY29udGFpbnMoJ2V4cGFuZGVkJykpIHtcblx0XHRcdFx0dGhpcy5vbkNsb3NlKHRhcmdldCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLm9uT3Blbih0YXJnZXQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBBZGRzIHRoZSBhZGRpdGlvbmFsIHJvdy5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUaGUgY2xpY2sgZXZlbnQgdGFyZ2V0LlxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnb25PcGVuJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gb25PcGVuKHRhcmdldCkge1xuXHRcdFx0dGhpcy50ci5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLm5ld1RyLCB0aGlzLnRyLm5leHRTaWJsaW5nKTtcblx0XHRcdHRoaXMudHIuY2xhc3NMaXN0LmFkZCgnZXhwYW5kZWQnKTtcblxuXHRcdFx0aWYgKCdTVU1NQVJZJyAhPT0gdGFyZ2V0LnRhZ05hbWUpIHtcblx0XHRcdFx0Ly8gVGhpcyBicm93c2VyIHdpbGwgZG8gdGhpcyBpZiB0aGUgc3VtbWFyeSB3YXMgY2xpY2tlZC5cblx0XHRcdFx0dGhpcy5kZXRhaWxzLnNldEF0dHJpYnV0ZSgnb3BlbicsIHRydWUpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuICAgKiBSZW1vdmVzIHRoZSBhZGRpdGlvbmFsIHJvdy5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUaGUgY2xpY2sgZXZlbnQgdGFyZ2V0LlxuICAgKi9cblxuXHR9LCB7XG5cdFx0a2V5OiAnb25DbG9zZScsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIG9uQ2xvc2UodGFyZ2V0KSB7XG5cdFx0XHR0aGlzLnRyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5uZXdUcik7XG5cdFx0XHR0aGlzLnRyLmNsYXNzTGlzdC5yZW1vdmUoJ2V4cGFuZGVkJyk7XG5cblx0XHRcdGlmICgnU1VNTUFSWScgIT09IHRhcmdldC50YWdOYW1lKSB7XG5cdFx0XHRcdHRoaXMuZGV0YWlscy5yZW1vdmVBdHRyaWJ1dGUoJ29wZW4nKTtcblx0XHRcdH1cblx0XHR9XG5cdH1dKTtcblxuXHRyZXR1cm4gUm93VG9nZ2xlcjtcbn0oKTtcblxuLyoqXG4gKiBTZXRzIHVwIGV4cGFuZGFibGUgZGV0YWlscyBmb3IgZXJyb3JzIHdoZW4gdmlld2luZyBhIHNpbmdsZSBVUkwgZXJyb3IgbGlzdC5cbiAqL1xuXG5cbnZhciBFcnJvclJvd3MgPSBmdW5jdGlvbiAoKSB7XG5cdGZ1bmN0aW9uIEVycm9yUm93cygpIHtcblx0XHRfY2xhc3NDYWxsQ2hlY2sodGhpcywgRXJyb3JSb3dzKTtcblxuXHRcdHRoaXMucm93cyA9IFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLndwLWxpc3QtdGFibGUgdHJbaWRePVwidGFnLVwiXScpKSkubWFwKGZ1bmN0aW9uICh0ciwgaW5kZXgpIHtcblx0XHRcdHZhciByb3dIYW5kbGVyID0gbmV3IFJvd1RvZ2dsZXIodHIsIGluZGV4KTtcblx0XHRcdHJvd0hhbmRsZXIuaW5pdCgpO1xuXHRcdFx0cmV0dXJuIHJvd0hhbmRsZXI7XG5cdFx0fSkuZmlsdGVyKGZ1bmN0aW9uIChyb3cpIHtcblx0XHRcdHJldHVybiByb3cuZGV0YWlscztcblx0XHR9KTtcblx0fVxuXG5cdF9jcmVhdGVDbGFzcyhFcnJvclJvd3MsIFt7XG5cdFx0a2V5OiAnaW5pdCcsXG5cdFx0dmFsdWU6IGZ1bmN0aW9uIGluaXQoKSB7XG5cdFx0XHR0aGlzLmFkZFRvZ2dsZUFsbExpc3RlbmVyKCk7XG5cdFx0fVxuXG5cdFx0LyoqXG4gICAqIEhhbmRsZSAndG9nZ2xlIGFsbCcgYnV0dG9ucyBvbiB0aGUgcGFnZS5cbiAgICovXG5cblx0fSwge1xuXHRcdGtleTogJ2FkZFRvZ2dsZUFsbExpc3RlbmVyJyxcblx0XHR2YWx1ZTogZnVuY3Rpb24gYWRkVG9nZ2xlQWxsTGlzdGVuZXIoKSB7XG5cdFx0XHR2YXIgX3RoaXMyID0gdGhpcztcblxuXHRcdFx0dmFyIG9wZW4gPSBmYWxzZTtcblx0XHRcdHZhciB0b2dnbGVCdXR0b25zID0gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuY29sdW1uLWRldGFpbHMgYnV0dG9uLmVycm9yLWRldGFpbHMtdG9nZ2xlJykpKTtcblxuXHRcdFx0dmFyIG9uQnV0dG9uQ2xpY2sgPSBmdW5jdGlvbiBvbkJ1dHRvbkNsaWNrKHRhcmdldCkge1xuXHRcdFx0XHRvcGVuID0gIW9wZW47XG5cdFx0XHRcdF90aGlzMi5yb3dzLmZvckVhY2goZnVuY3Rpb24gKHJvdykge1xuXHRcdFx0XHRcdGlmIChvcGVuKSB7XG5cdFx0XHRcdFx0XHRyb3cub25PcGVuKHRhcmdldCk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHJvdy5vbkNsb3NlKHRhcmdldCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH07XG5cblx0XHRcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uIChldmVudCkge1xuXHRcdFx0XHRpZiAodG9nZ2xlQnV0dG9ucy5pbmNsdWRlcyhldmVudC50YXJnZXQpKSB7XG5cdFx0XHRcdFx0b25CdXR0b25DbGljayhldmVudC50YXJnZXQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1dKTtcblxuXHRyZXR1cm4gRXJyb3JSb3dzO1xufSgpO1xuXG5kb21SZWFkeShmdW5jdGlvbiAoKSB7XG5cdG5ldyBFcnJvclJvd3MoKS5pbml0KCk7XG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2Fzc2V0cy9zcmMvYW1wLXZhbGlkYXRpb24tc2luZ2xlLWVycm9yLXVybC1kZXRhaWxzLmpzXG4vLyBtb2R1bGUgaWQgPSAxN1xuLy8gbW9kdWxlIGNodW5rcyA9IDMiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///17\n");
|
| 81 |
+
|
| 82 |
+
/***/ })
|
| 83 |
+
|
| 84 |
+
/******/ });
|
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/******/ (function(modules) { // webpackBootstrap
|
| 2 |
+
/******/ // The module cache
|
| 3 |
+
/******/ var installedModules = {};
|
| 4 |
+
/******/
|
| 5 |
+
/******/ // The require function
|
| 6 |
+
/******/ function __webpack_require__(moduleId) {
|
| 7 |
+
/******/
|
| 8 |
+
/******/ // Check if module is in cache
|
| 9 |
+
/******/ if(installedModules[moduleId]) {
|
| 10 |
+
/******/ return installedModules[moduleId].exports;
|
| 11 |
+
/******/ }
|
| 12 |
+
/******/ // Create a new module (and put it into the cache)
|
| 13 |
+
/******/ var module = installedModules[moduleId] = {
|
| 14 |
+
/******/ i: moduleId,
|
| 15 |
+
/******/ l: false,
|
| 16 |
+
/******/ exports: {}
|
| 17 |
+
/******/ };
|
| 18 |
+
/******/
|
| 19 |
+
/******/ // Execute the module function
|
| 20 |
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
| 21 |
+
/******/
|
| 22 |
+
/******/ // Flag the module as loaded
|
| 23 |
+
/******/ module.l = true;
|
| 24 |
+
/******/
|
| 25 |
+
/******/ // Return the exports of the module
|
| 26 |
+
/******/ return module.exports;
|
| 27 |
+
/******/ }
|
| 28 |
+
/******/
|
| 29 |
+
/******/
|
| 30 |
+
/******/ // expose the modules object (__webpack_modules__)
|
| 31 |
+
/******/ __webpack_require__.m = modules;
|
| 32 |
+
/******/
|
| 33 |
+
/******/ // expose the module cache
|
| 34 |
+
/******/ __webpack_require__.c = installedModules;
|
| 35 |
+
/******/
|
| 36 |
+
/******/ // define getter function for harmony exports
|
| 37 |
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
| 38 |
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
| 39 |
+
/******/ Object.defineProperty(exports, name, {
|
| 40 |
+
/******/ configurable: false,
|
| 41 |
+
/******/ enumerable: true,
|
| 42 |
+
/******/ get: getter
|
| 43 |
+
/******/ });
|
| 44 |
+
/******/ }
|
| 45 |
+
/******/ };
|
| 46 |
+
/******/
|
| 47 |
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
| 48 |
+
/******/ __webpack_require__.n = function(module) {
|
| 49 |
+
/******/ var getter = module && module.__esModule ?
|
| 50 |
+
/******/ function getDefault() { return module['default']; } :
|
| 51 |
+
/******/ function getModuleExports() { return module; };
|
| 52 |
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
| 53 |
+
/******/ return getter;
|
| 54 |
+
/******/ };
|
| 55 |
+
/******/
|
| 56 |
+
/******/ // Object.prototype.hasOwnProperty.call
|
| 57 |
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
| 58 |
+
/******/
|
| 59 |
+
/******/ // __webpack_public_path__
|
| 60 |
+
/******/ __webpack_require__.p = "";
|
| 61 |
+
/******/
|
| 62 |
+
/******/ // Load entry module and return exports
|
| 63 |
+
/******/ return __webpack_require__(__webpack_require__.s = 16);
|
| 64 |
+
/******/ })
|
| 65 |
+
/************************************************************************/
|
| 66 |
+
/******/ ({
|
| 67 |
+
|
| 68 |
+
/***/ 1:
|
| 69 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 70 |
+
|
| 71 |
+
"use strict";
|
| 72 |
+
eval("/**\n * Specify a function to execute when the DOM is fully loaded.\n *\n * @param {Function} callback A function to execute after the DOM is ready.\n *\n * @return {void}\n */\nvar domReady = function domReady(callback) {\n if (document.readyState === 'complete' || // DOMContentLoaded + Images/Styles/etc loaded, so we call directly.\n document.readyState === 'interactive' // DOMContentLoaded fires at this point, so we call directly.\n ) {\n return callback();\n } // DOMContentLoaded has not fired yet, delay callback until then.\n\n\n document.addEventListener('DOMContentLoaded', callback);\n};\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (domReady);\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9Ad29yZHByZXNzL2RvbS1yZWFkeS9idWlsZC1tb2R1bGUvaW5kZXguanM/YTc2MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNwZWNpZnkgYSBmdW5jdGlvbiB0byBleGVjdXRlIHdoZW4gdGhlIERPTSBpcyBmdWxseSBsb2FkZWQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQSBmdW5jdGlvbiB0byBleGVjdXRlIGFmdGVyIHRoZSBET00gaXMgcmVhZHkuXG4gKlxuICogQHJldHVybiB7dm9pZH1cbiAqL1xudmFyIGRvbVJlYWR5ID0gZnVuY3Rpb24gZG9tUmVhZHkoY2FsbGJhY2spIHtcbiAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScgfHwgLy8gRE9NQ29udGVudExvYWRlZCArIEltYWdlcy9TdHlsZXMvZXRjIGxvYWRlZCwgc28gd2UgY2FsbCBkaXJlY3RseS5cbiAgZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2ludGVyYWN0aXZlJyAvLyBET01Db250ZW50TG9hZGVkIGZpcmVzIGF0IHRoaXMgcG9pbnQsIHNvIHdlIGNhbGwgZGlyZWN0bHkuXG4gICkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfSAvLyBET01Db250ZW50TG9hZGVkIGhhcyBub3QgZmlyZWQgeWV0LCBkZWxheSBjYWxsYmFjayB1bnRpbCB0aGVuLlxuXG5cbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGRvbVJlYWR5O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvQHdvcmRwcmVzcy9kb20tcmVhZHkvYnVpbGQtbW9kdWxlL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMSAyIDMiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1\n");
|
| 73 |
+
|
| 74 |
+
/***/ }),
|
| 75 |
+
|
| 76 |
+
/***/ 16:
|
| 77 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
| 78 |
+
|
| 79 |
+
"use strict";
|
| 80 |
+
eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__wordpress_dom_ready__ = __webpack_require__(1);\n/**\n * WordPress dependencies\n */\n\n\n// WIP Pointer function\nfunction sourcesPointer() {\n\tjQuery(document).on('click', '.tooltip-button', function () {\n\t\tjQuery(this).pointer({\n\t\t\tcontent: jQuery(this).next('.tooltip').attr('data-content'),\n\t\t\tposition: {\n\t\t\t\tedge: 'left',\n\t\t\t\talign: 'center'\n\t\t\t},\n\t\t\tpointerClass: 'wp-pointer wp-pointer--tooltip'\n\t\t}).pointer('open');\n\t});\n}\n\nObject(__WEBPACK_IMPORTED_MODULE_0__wordpress_dom_ready__[\"a\" /* default */])(function () {\n\tsourcesPointer();\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTYuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hc3NldHMvc3JjL2FtcC12YWxpZGF0aW9uLXRvb2x0aXBzLmpzPzAxYTMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBXb3JkUHJlc3MgZGVwZW5kZW5jaWVzXG4gKi9cbmltcG9ydCBkb21SZWFkeSBmcm9tICdAd29yZHByZXNzL2RvbS1yZWFkeSc7XG5cbi8vIFdJUCBQb2ludGVyIGZ1bmN0aW9uXG5mdW5jdGlvbiBzb3VyY2VzUG9pbnRlcigpIHtcblx0alF1ZXJ5KGRvY3VtZW50KS5vbignY2xpY2snLCAnLnRvb2x0aXAtYnV0dG9uJywgZnVuY3Rpb24gKCkge1xuXHRcdGpRdWVyeSh0aGlzKS5wb2ludGVyKHtcblx0XHRcdGNvbnRlbnQ6IGpRdWVyeSh0aGlzKS5uZXh0KCcudG9vbHRpcCcpLmF0dHIoJ2RhdGEtY29udGVudCcpLFxuXHRcdFx0cG9zaXRpb246IHtcblx0XHRcdFx0ZWRnZTogJ2xlZnQnLFxuXHRcdFx0XHRhbGlnbjogJ2NlbnRlcidcblx0XHRcdH0sXG5cdFx0XHRwb2ludGVyQ2xhc3M6ICd3cC1wb2ludGVyIHdwLXBvaW50ZXItLXRvb2x0aXAnXG5cdFx0fSkucG9pbnRlcignb3BlbicpO1xuXHR9KTtcbn1cblxuZG9tUmVhZHkoZnVuY3Rpb24gKCkge1xuXHRzb3VyY2VzUG9pbnRlcigpO1xufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9hc3NldHMvc3JjL2FtcC12YWxpZGF0aW9uLXRvb2x0aXBzLmpzXG4vLyBtb2R1bGUgaWQgPSAxNlxuLy8gbW9kdWxlIGNodW5rcyA9IDIiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///16\n");
|
| 81 |
+
|
| 82 |
+
/***/ })
|
| 83 |
+
|
| 84 |
+
/******/ });
|
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* WordPress dependencies
|
| 3 |
+
*/
|
| 4 |
+
const { __ } = wp.i18n;
|
| 5 |
+
const { FormToggle, Notice } = wp.components;
|
| 6 |
+
const { Fragment, RawHTML } = wp.element;
|
| 7 |
+
const { withSelect, withDispatch } = wp.data;
|
| 8 |
+
const { PluginPostStatusInfo } = wp.editPost;
|
| 9 |
+
const { compose, withInstanceId } = wp.compose;
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Exported via wp_localize_script().
|
| 13 |
+
*/
|
| 14 |
+
const { possibleStati, defaultStatus, errorMessages } = window.wpAmpEditor;
|
| 15 |
+
|
| 16 |
+
/**
|
| 17 |
+
* Adds an 'Enable AMP' toggle to the block editor 'Status & Visibility' section.
|
| 18 |
+
*
|
| 19 |
+
* If there are error(s) that block AMP from being enabled or disabled,
|
| 20 |
+
* this only displays a Notice with the error(s), not a toggle.
|
| 21 |
+
* Error(s) are imported as errorMessages via wp_localize_script().
|
| 22 |
+
*
|
| 23 |
+
* @return {Object} AMPToggle component.
|
| 24 |
+
*/
|
| 25 |
+
function AMPToggle( { enabledStatus, onAmpChange } ) {
|
| 26 |
+
return (
|
| 27 |
+
<Fragment>
|
| 28 |
+
<PluginPostStatusInfo>
|
| 29 |
+
{ ! errorMessages.length && <label htmlFor='amp-enabled'>{ __( 'Enable AMP', 'amp' ) }</label> }
|
| 30 |
+
{
|
| 31 |
+
! errorMessages.length &&
|
| 32 |
+
(
|
| 33 |
+
<FormToggle
|
| 34 |
+
checked={ 'enabled' === enabledStatus }
|
| 35 |
+
onChange={ () => onAmpChange( enabledStatus ) }
|
| 36 |
+
id='amp-enabled'
|
| 37 |
+
/>
|
| 38 |
+
)
|
| 39 |
+
}
|
| 40 |
+
{
|
| 41 |
+
!! errorMessages.length &&
|
| 42 |
+
(
|
| 43 |
+
<Notice
|
| 44 |
+
status='warning'
|
| 45 |
+
isDismissible={ false }
|
| 46 |
+
>
|
| 47 |
+
{
|
| 48 |
+
errorMessages.map(
|
| 49 |
+
( message, index ) => <RawHTML key={ index }>{ message }</RawHTML>
|
| 50 |
+
)
|
| 51 |
+
}
|
| 52 |
+
</Notice>
|
| 53 |
+
)
|
| 54 |
+
}
|
| 55 |
+
</PluginPostStatusInfo>
|
| 56 |
+
</Fragment>
|
| 57 |
+
);
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
/**
|
| 61 |
+
* The AMP Toggle component, composed with the enabledStatus and a callback for when it's changed.
|
| 62 |
+
*
|
| 63 |
+
* @return {Object} The composed AMP toggle.
|
| 64 |
+
*/
|
| 65 |
+
function ComposedAMPToggle() {
|
| 66 |
+
return compose( [
|
| 67 |
+
withSelect( ( select ) => {
|
| 68 |
+
/**
|
| 69 |
+
* Gets the AMP enabled status.
|
| 70 |
+
*
|
| 71 |
+
* Uses select from the enclosing function to get the meta value.
|
| 72 |
+
* If it doesn't exist, it uses the default value.
|
| 73 |
+
* This applies especially for a new post, where there probably won't be a meta value yet.
|
| 74 |
+
*
|
| 75 |
+
* @return {string} Enabled status, either 'enabled' or 'disabled'.
|
| 76 |
+
*/
|
| 77 |
+
const getEnabledStatus = () => {
|
| 78 |
+
const meta = select( 'core/editor' ).getEditedPostAttribute( 'meta' );
|
| 79 |
+
if ( meta && meta.amp_status && possibleStati.includes( meta.amp_status ) ) {
|
| 80 |
+
return meta.amp_status;
|
| 81 |
+
}
|
| 82 |
+
return defaultStatus;
|
| 83 |
+
};
|
| 84 |
+
|
| 85 |
+
return { enabledStatus: getEnabledStatus() };
|
| 86 |
+
} ),
|
| 87 |
+
withDispatch( ( dispatch ) => ( {
|
| 88 |
+
onAmpChange: ( enabledStatus ) => {
|
| 89 |
+
const newStatus = 'enabled' === enabledStatus ? 'disabled' : 'enabled';
|
| 90 |
+
dispatch( 'core/editor' ).editPost( { meta: { amp_status: newStatus } } );
|
| 91 |
+
}
|
| 92 |
+
} ) ),
|
| 93 |
+
withInstanceId
|
| 94 |
+
] )( AMPToggle );
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
export default wp.plugins.registerPlugin( 'amp', {
|
| 98 |
+
icon: 'hidden',
|
| 99 |
+
render: ComposedAMPToggle()
|
| 100 |
+
} );
|
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* WordPress dependencies
|
| 3 |
+
*/
|
| 4 |
+
import domReady from '@wordpress/dom-ready';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Localized data
|
| 8 |
+
*/
|
| 9 |
+
import { detailToggleBtnAriaLabel, sourcesToggleBtnAriaLabel } from 'amp-validation-i18n';
|
| 10 |
+
|
| 11 |
+
const OPEN_CLASS = 'is-open';
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Adds detail toggle buttons to the header and footer rows of the validation error "details" column.
|
| 15 |
+
* The buttons are added via JS because there's no easy way to append them to the heading of a sortable
|
| 16 |
+
* table column via backend code.
|
| 17 |
+
*
|
| 18 |
+
* @param {string} containerSelector Selector for elements that will have the button added.
|
| 19 |
+
* @param {string} ariaLabel Screen reader label for the button.
|
| 20 |
+
* @return {Array} Array of added buttons.
|
| 21 |
+
*/
|
| 22 |
+
function addToggleButtons( containerSelector, ariaLabel ) {
|
| 23 |
+
const addButton = ( container ) => {
|
| 24 |
+
const button = document.createElement( 'button' );
|
| 25 |
+
button.setAttribute( 'aria-label', ariaLabel );
|
| 26 |
+
button.setAttribute( 'type', 'button' );
|
| 27 |
+
button.setAttribute( 'class', 'error-details-toggle' );
|
| 28 |
+
container.appendChild( button );
|
| 29 |
+
|
| 30 |
+
return button;
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
return [ ...document.querySelectorAll( containerSelector ) ].map( container => addButton( container ) );
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
function addToggleAllListener( { btn, toggleAllButtonSelector = null, targetDetailsSelector } ) {
|
| 37 |
+
let open = false;
|
| 38 |
+
|
| 39 |
+
const targetDetails = [ ...document.querySelectorAll( targetDetailsSelector ) ];
|
| 40 |
+
|
| 41 |
+
let toggleAllButtons = [];
|
| 42 |
+
if ( toggleAllButtonSelector ) {
|
| 43 |
+
toggleAllButtons = [ ...document.querySelectorAll( toggleAllButtonSelector ) ];
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
const onButtonClick = () => {
|
| 47 |
+
open = ! open;
|
| 48 |
+
toggleAllButtons.forEach( toggleAllButton => {
|
| 49 |
+
toggleAllButton.classList.toggle( OPEN_CLASS );
|
| 50 |
+
} );
|
| 51 |
+
|
| 52 |
+
targetDetails.forEach( detail => {
|
| 53 |
+
if ( open ) {
|
| 54 |
+
detail.setAttribute( 'open', true );
|
| 55 |
+
} else {
|
| 56 |
+
detail.removeAttribute( 'open' );
|
| 57 |
+
}
|
| 58 |
+
} );
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
btn.addEventListener( 'click', onButtonClick );
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
/**
|
| 65 |
+
* Adds classes to the rows for the amp_validation_error term list table.
|
| 66 |
+
*
|
| 67 |
+
* This is needed because \WP_Terms_List_Table::single_row() does not allow for additional
|
| 68 |
+
* attributes to be added to the <tr> element.
|
| 69 |
+
*/
|
| 70 |
+
function addTermListTableRowClasses() {
|
| 71 |
+
const rows = [ ...document.querySelectorAll( '#the-list tr' ) ];
|
| 72 |
+
rows.forEach( ( row ) => {
|
| 73 |
+
const statusText = row.querySelector( '.column-status > .status-text' );
|
| 74 |
+
if ( statusText ) {
|
| 75 |
+
row.classList.toggle( 'new', statusText.classList.contains( 'new' ) );
|
| 76 |
+
row.classList.toggle( 'accepted', statusText.classList.contains( 'accepted' ) );
|
| 77 |
+
row.classList.toggle( 'rejected', statusText.classList.contains( 'rejected' ) );
|
| 78 |
+
}
|
| 79 |
+
} );
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
domReady( () => {
|
| 83 |
+
addToggleButtons( 'th.column-details.manage-column', detailToggleBtnAriaLabel )
|
| 84 |
+
.forEach( ( btn ) => {
|
| 85 |
+
addToggleAllListener( {
|
| 86 |
+
btn,
|
| 87 |
+
toggleAllButtonSelector: '.column-details button.error-details-toggle',
|
| 88 |
+
targetDetailsSelector: '.column-details details'
|
| 89 |
+
} );
|
| 90 |
+
} );
|
| 91 |
+
|
| 92 |
+
addToggleButtons( 'th.manage-column.column-sources_with_invalid_output', sourcesToggleBtnAriaLabel )
|
| 93 |
+
.forEach( ( btn ) => {
|
| 94 |
+
addToggleAllListener( {
|
| 95 |
+
btn,
|
| 96 |
+
toggleAllButtonSelector: '.column-sources_with_invalid_output button.error-details-toggle',
|
| 97 |
+
targetDetailsSelector: 'details.source'
|
| 98 |
+
} );
|
| 99 |
+
} );
|
| 100 |
+
|
| 101 |
+
addTermListTableRowClasses();
|
| 102 |
+
} );
|
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* WordPress dependencies
|
| 3 |
+
*/
|
| 4 |
+
import domReady from '@wordpress/dom-ready';
|
| 5 |
+
|
| 6 |
+
/**
|
| 7 |
+
* Toggles the contents of a details element as an additional table tr.
|
| 8 |
+
*/
|
| 9 |
+
class RowToggler {
|
| 10 |
+
constructor( tr, index ) {
|
| 11 |
+
this.tr = tr;
|
| 12 |
+
this.index = index;
|
| 13 |
+
|
| 14 |
+
// Since we're adding additional rows, we need to override default .striped tables styles.
|
| 15 |
+
this.tr.classList.add( this.index % 2 ? 'odd' : 'even' ); // eslint-disable-line no-magic-numbers
|
| 16 |
+
|
| 17 |
+
this.toggle = this.toggle.bind( this );
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Sets up the new tr and adds an event listener to toggle details.
|
| 22 |
+
*/
|
| 23 |
+
init() {
|
| 24 |
+
this.details = this.tr.querySelector( '.column-details details' );
|
| 25 |
+
if ( this.details ) {
|
| 26 |
+
this.createNewTr();
|
| 27 |
+
const togglers = [
|
| 28 |
+
...this.tr.querySelectorAll( '.single-url-detail-toggle' ),
|
| 29 |
+
this.details.querySelector( 'summary' )
|
| 30 |
+
];
|
| 31 |
+
|
| 32 |
+
togglers.forEach( el => {
|
| 33 |
+
el.addEventListener( 'click', () => {
|
| 34 |
+
this.toggle( el );
|
| 35 |
+
} );
|
| 36 |
+
} );
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
/**
|
| 41 |
+
* Creates the details table row from the original row's <details> element content, minus the summary.
|
| 42 |
+
*/
|
| 43 |
+
createNewTr() {
|
| 44 |
+
this.newTr = document.createElement( 'tr' );
|
| 45 |
+
this.newTr.classList.add( 'details' );
|
| 46 |
+
this.newTr.classList.add( this.index % 2 ? 'odd' : 'even' ); // eslint-disable-line no-magic-numbers
|
| 47 |
+
|
| 48 |
+
const newCell = document.createElement( 'td' );
|
| 49 |
+
newCell.setAttribute( 'colspan', this.getRowColspan() );
|
| 50 |
+
|
| 51 |
+
for ( const childNode of this.details.childNodes ) {
|
| 52 |
+
if ( 'SUMMARY' !== childNode.tagName ) {
|
| 53 |
+
newCell.appendChild( childNode.cloneNode( true ) );
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
this.newTr.appendChild( newCell );
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
/**
|
| 61 |
+
* Gets the number of cells within the original row.
|
| 62 |
+
*
|
| 63 |
+
* @return {number} The number of cells.
|
| 64 |
+
*/
|
| 65 |
+
getRowColspan() {
|
| 66 |
+
return [ ...this.tr.childNodes ]
|
| 67 |
+
.filter( childNode => [ 'TD', 'TH' ].includes( childNode.tagName ) )
|
| 68 |
+
.length;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
/**
|
| 72 |
+
* Toggles the additional row.
|
| 73 |
+
*
|
| 74 |
+
* @param {Object} target The click event target.
|
| 75 |
+
*/
|
| 76 |
+
toggle( target ) {
|
| 77 |
+
if ( this.tr.classList.contains( 'expanded' ) ) {
|
| 78 |
+
this.onClose( target );
|
| 79 |
+
} else {
|
| 80 |
+
this.onOpen( target );
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
/**
|
| 85 |
+
* Adds the additional row.
|
| 86 |
+
*
|
| 87 |
+
* @param {Object} target The click event target.
|
| 88 |
+
*/
|
| 89 |
+
onOpen( target ) {
|
| 90 |
+
this.tr.parentNode.insertBefore( this.newTr, this.tr.nextSibling );
|
| 91 |
+
this.tr.classList.add( 'expanded' );
|
| 92 |
+
|
| 93 |
+
if ( 'SUMMARY' !== target.tagName ) { // This browser will do this if the summary was clicked.
|
| 94 |
+
this.details.setAttribute( 'open', true );
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
/**
|
| 99 |
+
* Removes the additional row.
|
| 100 |
+
*
|
| 101 |
+
* @param {Object} target The click event target.
|
| 102 |
+
*/
|
| 103 |
+
onClose( target ) {
|
| 104 |
+
this.tr.parentNode.removeChild( this.newTr );
|
| 105 |
+
this.tr.classList.remove( 'expanded' );
|
| 106 |
+
|
| 107 |
+
if ( 'SUMMARY' !== target.tagName ) {
|
| 108 |
+
this.details.removeAttribute( 'open' );
|
| 109 |
+
}
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
/**
|
| 114 |
+
* Sets up expandable details for errors when viewing a single URL error list.
|
| 115 |
+
*/
|
| 116 |
+
class ErrorRows {
|
| 117 |
+
constructor() {
|
| 118 |
+
this.rows = [ ...document.querySelectorAll( '.wp-list-table tr[id^="tag-"]' ) ]
|
| 119 |
+
.map( ( tr, index ) => {
|
| 120 |
+
const rowHandler = new RowToggler( tr, index );
|
| 121 |
+
rowHandler.init();
|
| 122 |
+
return rowHandler;
|
| 123 |
+
} )
|
| 124 |
+
.filter( row => row.details );
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
init() {
|
| 128 |
+
this.addToggleAllListener();
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/**
|
| 132 |
+
* Handle 'toggle all' buttons on the page.
|
| 133 |
+
*/
|
| 134 |
+
addToggleAllListener() {
|
| 135 |
+
let open = false;
|
| 136 |
+
const toggleButtons = [ ...document.querySelectorAll( '.column-details button.error-details-toggle' ) ];
|
| 137 |
+
|
| 138 |
+
const onButtonClick = ( target ) => {
|
| 139 |
+
open = ! open;
|
| 140 |
+
this.rows.forEach( row => {
|
| 141 |
+
if ( open ) {
|
| 142 |
+
row.onOpen( target );
|
| 143 |
+
} else {
|
| 144 |
+
row.onClose( target );
|
| 145 |
+
}
|
| 146 |
+
} );
|
| 147 |
+
};
|
| 148 |
+
|
| 149 |
+
window.addEventListener( 'click', event => {
|
| 150 |
+
if ( toggleButtons.includes( event.target ) ) {
|
| 151 |
+
onButtonClick( event.target );
|
| 152 |
+
}
|
| 153 |
+
} );
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
domReady( () => {
|
| 158 |
+
new ErrorRows().init();
|
| 159 |
+
} );
|
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* WordPress dependencies
|
| 3 |
+
*/
|
| 4 |
+
import domReady from '@wordpress/dom-ready';
|
| 5 |
+
|
| 6 |
+
// WIP Pointer function
|
| 7 |
+
function sourcesPointer() {
|
| 8 |
+
jQuery( document ).on( 'click', '.tooltip-button', function() {
|
| 9 |
+
jQuery( this ).pointer( {
|
| 10 |
+
content: jQuery( this ).next( '.tooltip' ).attr( 'data-content' ),
|
| 11 |
+
position: {
|
| 12 |
+
edge: 'left',
|
| 13 |
+
align: 'center'
|
| 14 |
+
},
|
| 15 |
+
pointerClass: 'wp-pointer wp-pointer--tooltip'
|
| 16 |
+
} ).pointer( 'open' );
|
| 17 |
+
} );
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
domReady( () => {
|
| 21 |
+
sourcesPointer();
|
| 22 |
+
} );
|
|
@@ -3,7 +3,8 @@
|
|
| 3 |
<?php
|
| 4 |
echo esc_html(
|
| 5 |
sprintf(
|
| 6 |
-
|
|
|
|
| 7 |
human_time_diff( $this->get( 'post_publish_timestamp' ), current_time( 'timestamp' ) )
|
| 8 |
)
|
| 9 |
);
|
| 3 |
<?php
|
| 4 |
echo esc_html(
|
| 5 |
sprintf(
|
| 6 |
+
/* translators: %s: the human-readable time difference. */
|
| 7 |
+
__( '%s ago', 'amp' ),
|
| 8 |
human_time_diff( $this->get( 'post_publish_timestamp' ), current_time( 'timestamp' ) )
|
| 9 |
)
|
| 10 |
);
|
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Admin pointer class.
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
* @since 1.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* AMP_Admin_Pointer class.
|
| 11 |
+
*
|
| 12 |
+
* Outputs an admin pointer to show the new features of v1.0.
|
| 13 |
+
* Based on https://code.tutsplus.com/articles/integrating-with-wordpress-ui-admin-pointers--wp-26853
|
| 14 |
+
*
|
| 15 |
+
* @since 1.0
|
| 16 |
+
*/
|
| 17 |
+
class AMP_Admin_Pointer {
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* The ID of the template mode admin pointer.
|
| 21 |
+
*
|
| 22 |
+
* @var string
|
| 23 |
+
*/
|
| 24 |
+
const TEMPLATE_POINTER_ID = 'amp_template_mode_pointer_10';
|
| 25 |
+
|
| 26 |
+
/**
|
| 27 |
+
* The slug of the script.
|
| 28 |
+
*
|
| 29 |
+
* @var string
|
| 30 |
+
*/
|
| 31 |
+
const SCRIPT_SLUG = 'amp-admin-pointer';
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* The slug of the tooltip script.
|
| 35 |
+
*
|
| 36 |
+
* @var string
|
| 37 |
+
*/
|
| 38 |
+
const TOOLTIP_SLUG = 'amp-validation-tooltips';
|
| 39 |
+
|
| 40 |
+
/**
|
| 41 |
+
* Initializes the class.
|
| 42 |
+
*
|
| 43 |
+
* @since 1.0
|
| 44 |
+
*/
|
| 45 |
+
public function init() {
|
| 46 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_pointer' ) );
|
| 47 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'register_tooltips' ) );
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
/**
|
| 51 |
+
* Enqueues the pointer assets.
|
| 52 |
+
*
|
| 53 |
+
* If the pointer has not been dismissed, enqueues the style and script.
|
| 54 |
+
* And outputs the pointer data for the script.
|
| 55 |
+
*
|
| 56 |
+
* @since 1.0
|
| 57 |
+
*/
|
| 58 |
+
public function enqueue_pointer() {
|
| 59 |
+
if ( $this->is_pointer_dismissed() ) {
|
| 60 |
+
return;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
wp_enqueue_style( 'wp-pointer' );
|
| 64 |
+
|
| 65 |
+
wp_enqueue_script(
|
| 66 |
+
self::SCRIPT_SLUG,
|
| 67 |
+
amp_get_asset_url( 'js/' . self::SCRIPT_SLUG . '.js' ),
|
| 68 |
+
array( 'jquery', 'wp-pointer' ),
|
| 69 |
+
AMP__VERSION,
|
| 70 |
+
true
|
| 71 |
+
);
|
| 72 |
+
|
| 73 |
+
wp_add_inline_script(
|
| 74 |
+
self::SCRIPT_SLUG,
|
| 75 |
+
sprintf( 'ampAdminPointer.load( %s );', wp_json_encode( $this->get_pointer_data() ) )
|
| 76 |
+
);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
/**
|
| 80 |
+
* Registers style and script for tooltips.
|
| 81 |
+
*
|
| 82 |
+
* @since 1.0
|
| 83 |
+
*/
|
| 84 |
+
public function register_tooltips() {
|
| 85 |
+
wp_register_style(
|
| 86 |
+
self::TOOLTIP_SLUG,
|
| 87 |
+
amp_get_asset_url( 'css/' . self::TOOLTIP_SLUG . '.css' ),
|
| 88 |
+
array( 'wp-pointer' ),
|
| 89 |
+
AMP__VERSION
|
| 90 |
+
);
|
| 91 |
+
|
| 92 |
+
wp_register_script(
|
| 93 |
+
self::TOOLTIP_SLUG,
|
| 94 |
+
amp_get_asset_url( 'js/' . self::TOOLTIP_SLUG . '-compiled.js' ),
|
| 95 |
+
array( 'jquery', 'wp-pointer' ),
|
| 96 |
+
AMP__VERSION,
|
| 97 |
+
true
|
| 98 |
+
);
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
/**
|
| 102 |
+
* Whether the AMP admin pointer has been dismissed.
|
| 103 |
+
*
|
| 104 |
+
* @since 1.0
|
| 105 |
+
* @return boolean Is dismissed.
|
| 106 |
+
*/
|
| 107 |
+
protected function is_pointer_dismissed() {
|
| 108 |
+
$dismissed = get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true );
|
| 109 |
+
if ( empty( $dismissed ) ) {
|
| 110 |
+
return false;
|
| 111 |
+
}
|
| 112 |
+
$dismissed = explode( ',', strval( $dismissed ) );
|
| 113 |
+
|
| 114 |
+
return in_array( self::TEMPLATE_POINTER_ID, $dismissed, true );
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
/**
|
| 118 |
+
* Gets the pointer data to pass to the script.
|
| 119 |
+
*
|
| 120 |
+
* @since 1.0
|
| 121 |
+
* @return array Pointer data.
|
| 122 |
+
*/
|
| 123 |
+
public function get_pointer_data() {
|
| 124 |
+
return array(
|
| 125 |
+
'pointer' => array(
|
| 126 |
+
'pointer_id' => self::TEMPLATE_POINTER_ID,
|
| 127 |
+
'target' => '#toplevel_page_amp-options',
|
| 128 |
+
'options' => array(
|
| 129 |
+
'content' => sprintf(
|
| 130 |
+
'<h3>%s</h3><p><strong>%s</strong></p><p>%s</p>',
|
| 131 |
+
__( 'AMP', 'amp' ),
|
| 132 |
+
__( 'New AMP Template Modes', 'amp' ),
|
| 133 |
+
__( 'You can now reuse your theme\'s templates and styles in AMP responses, in both “Paired” and “Native” modes.', 'amp' )
|
| 134 |
+
),
|
| 135 |
+
'position' => array(
|
| 136 |
+
'edge' => 'left',
|
| 137 |
+
'align' => 'middle',
|
| 138 |
+
),
|
| 139 |
+
),
|
| 140 |
+
),
|
| 141 |
+
);
|
| 142 |
+
}
|
| 143 |
+
}
|
|
@@ -124,30 +124,32 @@ class AMP_Template_Customizer {
|
|
| 124 |
* @since 0.6
|
| 125 |
*/
|
| 126 |
public function add_customizer_scripts() {
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
|
|
|
| 134 |
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
|
|
|
| 151 |
|
| 152 |
/**
|
| 153 |
* Fires when plugins should register settings for AMP.
|
|
@@ -164,8 +166,10 @@ class AMP_Template_Customizer {
|
|
| 164 |
* Enqueues scripts used in both the AMP and non-AMP Customizer preview.
|
| 165 |
*
|
| 166 |
* @since 0.6
|
|
|
|
| 167 |
*/
|
| 168 |
public function enqueue_preview_scripts() {
|
|
|
|
| 169 |
|
| 170 |
// Bail if user can't customize anyway.
|
| 171 |
if ( ! current_user_can( 'customize' ) ) {
|
|
@@ -180,9 +184,24 @@ class AMP_Template_Customizer {
|
|
| 180 |
true
|
| 181 |
);
|
| 182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
wp_add_inline_script( 'amp-customize-preview', sprintf( 'ampCustomizePreview.boot( %s );',
|
| 184 |
wp_json_encode( array(
|
| 185 |
-
'available' =>
|
| 186 |
'enabled' => is_amp_endpoint(),
|
| 187 |
) )
|
| 188 |
) );
|
| 124 |
* @since 0.6
|
| 125 |
*/
|
| 126 |
public function add_customizer_scripts() {
|
| 127 |
+
if ( ! amp_is_canonical() ) {
|
| 128 |
+
wp_enqueue_script(
|
| 129 |
+
'amp-customize-controls',
|
| 130 |
+
amp_get_asset_url( 'js/amp-customize-controls.js' ),
|
| 131 |
+
array( 'jquery', 'customize-controls' ),
|
| 132 |
+
AMP__VERSION,
|
| 133 |
+
true
|
| 134 |
+
);
|
| 135 |
|
| 136 |
+
wp_add_inline_script( 'amp-customize-controls', sprintf( 'ampCustomizeControls.boot( %s );',
|
| 137 |
+
wp_json_encode( array(
|
| 138 |
+
'queryVar' => amp_get_slug(),
|
| 139 |
+
'panelId' => self::PANEL_ID,
|
| 140 |
+
'ampUrl' => amp_admin_get_preview_permalink(),
|
| 141 |
+
'l10n' => array(
|
| 142 |
+
'unavailableMessage' => __( 'AMP is not available for the page currently being previewed.', 'amp' ),
|
| 143 |
+
'unavailableLinkText' => __( 'Navigate to an AMP compatible page', 'amp' ),
|
| 144 |
+
),
|
| 145 |
+
) )
|
| 146 |
+
) );
|
| 147 |
|
| 148 |
+
wp_enqueue_style(
|
| 149 |
+
'amp-customizer',
|
| 150 |
+
amp_get_asset_url( 'css/amp-customizer.css' )
|
| 151 |
+
);
|
| 152 |
+
}
|
| 153 |
|
| 154 |
/**
|
| 155 |
* Fires when plugins should register settings for AMP.
|
| 166 |
* Enqueues scripts used in both the AMP and non-AMP Customizer preview.
|
| 167 |
*
|
| 168 |
* @since 0.6
|
| 169 |
+
* @global WP_Query $wp_query
|
| 170 |
*/
|
| 171 |
public function enqueue_preview_scripts() {
|
| 172 |
+
global $wp_query;
|
| 173 |
|
| 174 |
// Bail if user can't customize anyway.
|
| 175 |
if ( ! current_user_can( 'customize' ) ) {
|
| 184 |
true
|
| 185 |
);
|
| 186 |
|
| 187 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 188 |
+
$availability = AMP_Theme_Support::get_template_availability();
|
| 189 |
+
$available = $availability['supported'];
|
| 190 |
+
} elseif ( is_singular() || $wp_query->is_posts_page ) {
|
| 191 |
+
/**
|
| 192 |
+
* Queried object.
|
| 193 |
+
*
|
| 194 |
+
* @var WP_Post $queried_object
|
| 195 |
+
*/
|
| 196 |
+
$queried_object = get_queried_object();
|
| 197 |
+
$available = post_supports_amp( $queried_object );
|
| 198 |
+
} else {
|
| 199 |
+
$available = false;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
wp_add_inline_script( 'amp-customize-preview', sprintf( 'ampCustomizePreview.boot( %s );',
|
| 203 |
wp_json_encode( array(
|
| 204 |
+
'available' => $available,
|
| 205 |
'enabled' => is_amp_endpoint(),
|
| 206 |
) )
|
| 207 |
) );
|
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* AMP Editor Blocks extending.
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
* @since 1.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Class AMP_Editor_Blocks
|
| 11 |
+
*/
|
| 12 |
+
class AMP_Editor_Blocks {
|
| 13 |
+
|
| 14 |
+
/**
|
| 15 |
+
* List of AMP scripts that need to be printed when AMP components are used in non-AMP document context ("dirty AMP").
|
| 16 |
+
*
|
| 17 |
+
* @var array
|
| 18 |
+
*/
|
| 19 |
+
public $content_required_amp_scripts = array();
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* AMP components that have blocks.
|
| 23 |
+
*
|
| 24 |
+
* @var array
|
| 25 |
+
*/
|
| 26 |
+
public $amp_blocks = array(
|
| 27 |
+
'amp-mathml',
|
| 28 |
+
'amp-timeago',
|
| 29 |
+
'amp-o2-player',
|
| 30 |
+
'amp-ooyala-player',
|
| 31 |
+
'amp-reach-player',
|
| 32 |
+
'amp-springboard-player',
|
| 33 |
+
'amp-jwplayer',
|
| 34 |
+
'amp-brid-player',
|
| 35 |
+
'amp-ima-video',
|
| 36 |
+
'amp-fit-text',
|
| 37 |
+
);
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* Init.
|
| 41 |
+
*/
|
| 42 |
+
public function init() {
|
| 43 |
+
if ( function_exists( 'register_block_type' ) ) {
|
| 44 |
+
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
|
| 45 |
+
add_filter( 'wp_kses_allowed_html', array( $this, 'whitelist_block_atts_in_wp_kses_allowed_html' ), 10, 2 );
|
| 46 |
+
|
| 47 |
+
/*
|
| 48 |
+
* Dirty AMP is required when a site is in native mode but not all templates are being served
|
| 49 |
+
* as AMP. In particular, if a single post is using AMP-specific Gutenberg Blocks which make
|
| 50 |
+
* use of AMP components, and the singular template is served as AMP but the blog page is not,
|
| 51 |
+
* then the non-AMP blog page need to load the AMP runtime scripts so that the AMP components
|
| 52 |
+
* in the posts displayed there will be rendered properly. This is only relevant on native AMP
|
| 53 |
+
* sites because the AMP Gutenberg blocks are only made available in that mode; they are not
|
| 54 |
+
* presented in the Gutenberg inserter in paired mode. In general, using AMP components in
|
| 55 |
+
* non-AMP documents is still not officially supported, so it's occurrence is being minimized
|
| 56 |
+
* as much as possible. For more, see <https://github.com/ampproject/amp-wp/issues/1192>.
|
| 57 |
+
*/
|
| 58 |
+
if ( amp_is_canonical() ) {
|
| 59 |
+
add_filter( 'the_content', array( $this, 'tally_content_requiring_amp_scripts' ) );
|
| 60 |
+
add_action( 'wp_print_footer_scripts', array( $this, 'print_dirty_amp_scripts' ) );
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
/**
|
| 66 |
+
* Whitelist elements and attributes used for AMP.
|
| 67 |
+
*
|
| 68 |
+
* This prevents AMP markup from being deleted in
|
| 69 |
+
*
|
| 70 |
+
* @param array $tags Array of allowed post tags.
|
| 71 |
+
* @param string $context Context.
|
| 72 |
+
* @return mixed Modified array.
|
| 73 |
+
*/
|
| 74 |
+
public function whitelist_block_atts_in_wp_kses_allowed_html( $tags, $context ) {
|
| 75 |
+
if ( 'post' !== $context ) {
|
| 76 |
+
return $tags;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
foreach ( $tags as &$tag ) {
|
| 80 |
+
$tag['data-amp-layout'] = true;
|
| 81 |
+
$tag['data-amp-noloading'] = true;
|
| 82 |
+
$tag['data-amp-lightbox'] = true;
|
| 83 |
+
$tag['data-close-button-aria-label'] = true;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
foreach ( $this->amp_blocks as $amp_block ) {
|
| 87 |
+
if ( ! isset( $tags[ $amp_block ] ) ) {
|
| 88 |
+
$tags[ $amp_block ] = array();
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
// @todo The global attributes included here should be matched up with what is actually used by each block.
|
| 92 |
+
$tags[ $amp_block ] = array_merge(
|
| 93 |
+
array_fill_keys(
|
| 94 |
+
array(
|
| 95 |
+
'layout',
|
| 96 |
+
'width',
|
| 97 |
+
'height',
|
| 98 |
+
'class',
|
| 99 |
+
),
|
| 100 |
+
true
|
| 101 |
+
),
|
| 102 |
+
$tags[ $amp_block ]
|
| 103 |
+
);
|
| 104 |
+
|
| 105 |
+
$amp_tag_specs = AMP_Allowed_Tags_Generated::get_allowed_tag( $amp_block );
|
| 106 |
+
foreach ( $amp_tag_specs as $amp_tag_spec ) {
|
| 107 |
+
if ( ! isset( $amp_tag_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] ) ) {
|
| 108 |
+
continue;
|
| 109 |
+
}
|
| 110 |
+
$tags[ $amp_block ] = array_merge(
|
| 111 |
+
$tags[ $amp_block ],
|
| 112 |
+
array_fill_keys( array_keys( $amp_tag_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] ), true )
|
| 113 |
+
);
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
return $tags;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
/**
|
| 121 |
+
* Enqueue filters for extending core blocks attributes.
|
| 122 |
+
* Has to be loaded before registering the blocks in registerCoreBlocks.
|
| 123 |
+
*/
|
| 124 |
+
public function enqueue_block_editor_assets() {
|
| 125 |
+
|
| 126 |
+
// Enqueue script and style for AMP-specific blocks.
|
| 127 |
+
if ( amp_is_canonical() ) {
|
| 128 |
+
wp_enqueue_style(
|
| 129 |
+
'amp-editor-blocks-style',
|
| 130 |
+
amp_get_asset_url( 'css/amp-editor-blocks.css' ),
|
| 131 |
+
array(),
|
| 132 |
+
AMP__VERSION
|
| 133 |
+
);
|
| 134 |
+
|
| 135 |
+
wp_enqueue_script(
|
| 136 |
+
'amp-editor-blocks-build',
|
| 137 |
+
amp_get_asset_url( 'js/amp-blocks-compiled.js' ),
|
| 138 |
+
array( 'wp-editor', 'wp-blocks', 'lodash', 'wp-i18n', 'wp-element', 'wp-components' ),
|
| 139 |
+
AMP__VERSION
|
| 140 |
+
);
|
| 141 |
+
|
| 142 |
+
if ( function_exists( 'wp_set_script_translations' ) ) {
|
| 143 |
+
wp_set_script_translations( 'amp-editor-blocks-build', 'amp' );
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
wp_enqueue_script(
|
| 148 |
+
'amp-editor-blocks',
|
| 149 |
+
amp_get_asset_url( 'js/amp-editor-blocks.js' ),
|
| 150 |
+
array( 'underscore', 'wp-hooks', 'wp-i18n', 'wp-components' ),
|
| 151 |
+
AMP__VERSION,
|
| 152 |
+
true
|
| 153 |
+
);
|
| 154 |
+
|
| 155 |
+
wp_add_inline_script(
|
| 156 |
+
'amp-editor-blocks',
|
| 157 |
+
sprintf( 'ampEditorBlocks.boot( %s );', wp_json_encode( array(
|
| 158 |
+
'hasThemeSupport' => current_theme_supports( AMP_Theme_Support::SLUG ),
|
| 159 |
+
) ) )
|
| 160 |
+
);
|
| 161 |
+
|
| 162 |
+
if ( function_exists( 'wp_set_script_translations' ) ) {
|
| 163 |
+
wp_set_script_translations( 'amp-editor-blocks', 'amp' );
|
| 164 |
+
} elseif ( function_exists( 'wp_get_jed_locale_data' ) || function_exists( 'gutenberg_get_jed_locale_data' ) ) {
|
| 165 |
+
$locale_data = function_exists( 'wp_get_jed_locale_data' ) ? wp_get_jed_locale_data( 'amp' ) : gutenberg_get_jed_locale_data( 'amp' );
|
| 166 |
+
wp_add_inline_script(
|
| 167 |
+
'wp-i18n',
|
| 168 |
+
'wp.i18n.setLocaleData( ' . wp_json_encode( $locale_data ) . ', "amp" );',
|
| 169 |
+
'after'
|
| 170 |
+
);
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
/**
|
| 175 |
+
* Tally the AMP component scripts that are needed in a dirty AMP document.
|
| 176 |
+
*
|
| 177 |
+
* @param string $content Content.
|
| 178 |
+
* @return string Content (unmodified).
|
| 179 |
+
*/
|
| 180 |
+
public function tally_content_requiring_amp_scripts( $content ) {
|
| 181 |
+
if ( ! is_amp_endpoint() ) {
|
| 182 |
+
$pattern = sprintf( '/<(%s)\b.*?>/s', join( '|', $this->amp_blocks ) );
|
| 183 |
+
if ( preg_match_all( $pattern, $content, $matches ) ) {
|
| 184 |
+
$this->content_required_amp_scripts = array_merge(
|
| 185 |
+
$this->content_required_amp_scripts,
|
| 186 |
+
$matches[1]
|
| 187 |
+
);
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
return $content;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
/**
|
| 194 |
+
* Print AMP scripts required for AMP components used in a non-AMP document (dirty AMP).
|
| 195 |
+
*/
|
| 196 |
+
public function print_dirty_amp_scripts() {
|
| 197 |
+
if ( ! is_amp_endpoint() && ! empty( $this->content_required_amp_scripts ) ) {
|
| 198 |
+
wp_scripts()->do_items( $this->content_required_amp_scripts );
|
| 199 |
+
}
|
| 200 |
+
}
|
| 201 |
+
}
|
|
@@ -21,6 +21,14 @@ class AMP_Post_Meta_Box {
|
|
| 21 |
*/
|
| 22 |
const ASSETS_HANDLE = 'amp-post-meta-box';
|
| 23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
/**
|
| 25 |
* The enabled status post meta value.
|
| 26 |
*
|
|
@@ -84,6 +92,7 @@ class AMP_Post_Meta_Box {
|
|
| 84 |
) );
|
| 85 |
|
| 86 |
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
|
|
|
| 87 |
add_action( 'post_submitbox_misc_actions', array( $this, 'render_status' ) );
|
| 88 |
add_action( 'save_post', array( $this, 'save_amp_status' ) );
|
| 89 |
add_filter( 'preview_post_link', array( $this, 'preview_post_link' ) );
|
|
@@ -143,12 +152,20 @@ class AMP_Post_Meta_Box {
|
|
| 143 |
array( 'jquery' ),
|
| 144 |
AMP__VERSION
|
| 145 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
wp_add_inline_script( self::ASSETS_HANDLE, sprintf( 'ampPostMetaBox.boot( %s );',
|
| 147 |
wp_json_encode( array(
|
| 148 |
'previewLink' => esc_url_raw( add_query_arg( amp_get_slug(), '', get_preview_post_link( $post ) ) ),
|
| 149 |
'canonical' => amp_is_canonical(),
|
| 150 |
-
'enabled' =>
|
| 151 |
-
'canSupport' => count(
|
| 152 |
'statusInputName' => self::STATUS_INPUT_NAME,
|
| 153 |
'l10n' => array(
|
| 154 |
'ampPreviewBtnLabel' => __( 'Preview changes in AMP (opens in new window)', 'amp' ),
|
|
@@ -157,6 +174,49 @@ class AMP_Post_Meta_Box {
|
|
| 157 |
) );
|
| 158 |
}
|
| 159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
/**
|
| 161 |
* Render AMP status.
|
| 162 |
*
|
|
@@ -170,23 +230,102 @@ class AMP_Post_Meta_Box {
|
|
| 170 |
is_post_type_viewable( $post->post_type )
|
| 171 |
&&
|
| 172 |
current_user_can( 'edit_post', $post->ID )
|
| 173 |
-
&&
|
| 174 |
-
! amp_is_canonical()
|
| 175 |
);
|
| 176 |
|
| 177 |
if ( true !== $verify ) {
|
| 178 |
return;
|
| 179 |
}
|
| 180 |
|
| 181 |
-
$
|
| 182 |
-
$status
|
|
|
|
|
|
|
|
|
|
| 183 |
$labels = array(
|
| 184 |
'enabled' => __( 'Enabled', 'amp' ),
|
| 185 |
'disabled' => __( 'Disabled', 'amp' ),
|
| 186 |
);
|
| 187 |
|
| 188 |
// The preceding variables are used inside the following amp-status.php template.
|
| 189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
}
|
| 191 |
|
| 192 |
/**
|
| 21 |
*/
|
| 22 |
const ASSETS_HANDLE = 'amp-post-meta-box';
|
| 23 |
|
| 24 |
+
/**
|
| 25 |
+
* Block asset handle.
|
| 26 |
+
*
|
| 27 |
+
* @since 1.0
|
| 28 |
+
* @var string
|
| 29 |
+
*/
|
| 30 |
+
const BLOCK_ASSET_HANDLE = 'amp-block-editor-toggle-compiled';
|
| 31 |
+
|
| 32 |
/**
|
| 33 |
* The enabled status post meta value.
|
| 34 |
*
|
| 92 |
) );
|
| 93 |
|
| 94 |
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
| 95 |
+
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_assets' ) );
|
| 96 |
add_action( 'post_submitbox_misc_actions', array( $this, 'render_status' ) );
|
| 97 |
add_action( 'save_post', array( $this, 'save_amp_status' ) );
|
| 98 |
add_filter( 'preview_post_link', array( $this, 'preview_post_link' ) );
|
| 152 |
array( 'jquery' ),
|
| 153 |
AMP__VERSION
|
| 154 |
);
|
| 155 |
+
|
| 156 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 157 |
+
$availability = AMP_Theme_Support::get_template_availability( $post );
|
| 158 |
+
$support_errors = $availability['errors'];
|
| 159 |
+
} else {
|
| 160 |
+
$support_errors = AMP_Post_Type_Support::get_support_errors( $post );
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
wp_add_inline_script( self::ASSETS_HANDLE, sprintf( 'ampPostMetaBox.boot( %s );',
|
| 164 |
wp_json_encode( array(
|
| 165 |
'previewLink' => esc_url_raw( add_query_arg( amp_get_slug(), '', get_preview_post_link( $post ) ) ),
|
| 166 |
'canonical' => amp_is_canonical(),
|
| 167 |
+
'enabled' => empty( $support_errors ),
|
| 168 |
+
'canSupport' => 0 === count( array_diff( $support_errors, array( 'post-status-disabled' ) ) ),
|
| 169 |
'statusInputName' => self::STATUS_INPUT_NAME,
|
| 170 |
'l10n' => array(
|
| 171 |
'ampPreviewBtnLabel' => __( 'Preview changes in AMP (opens in new window)', 'amp' ),
|
| 174 |
) );
|
| 175 |
}
|
| 176 |
|
| 177 |
+
/**
|
| 178 |
+
* Enqueues block assets.
|
| 179 |
+
*
|
| 180 |
+
* @since 1.0
|
| 181 |
+
*/
|
| 182 |
+
public function enqueue_block_assets() {
|
| 183 |
+
$post = get_post();
|
| 184 |
+
if ( ! is_post_type_viewable( $post->post_type ) ) {
|
| 185 |
+
return;
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
wp_enqueue_script(
|
| 189 |
+
self::BLOCK_ASSET_HANDLE,
|
| 190 |
+
amp_get_asset_url( 'js/' . self::BLOCK_ASSET_HANDLE . '.js' ),
|
| 191 |
+
array( 'wp-hooks', 'wp-i18n', 'wp-components' ),
|
| 192 |
+
AMP__VERSION,
|
| 193 |
+
true
|
| 194 |
+
);
|
| 195 |
+
|
| 196 |
+
$status_and_errors = $this->get_status_and_errors( $post );
|
| 197 |
+
$enabled_status = $status_and_errors['status'];
|
| 198 |
+
$error_messages = $this->get_error_messages( $status_and_errors['status'], $status_and_errors['errors'] );
|
| 199 |
+
$script_data = array(
|
| 200 |
+
'possibleStati' => array( self::ENABLED_STATUS, self::DISABLED_STATUS ),
|
| 201 |
+
'defaultStatus' => $enabled_status,
|
| 202 |
+
'errorMessages' => $error_messages,
|
| 203 |
+
);
|
| 204 |
+
|
| 205 |
+
if ( function_exists( 'wp_set_script_translations' ) ) {
|
| 206 |
+
wp_set_script_translations( self::BLOCK_ASSET_HANDLE, 'amp' );
|
| 207 |
+
} elseif ( function_exists( 'wp_get_jed_locale_data' ) ) {
|
| 208 |
+
$script_data['i18n'] = wp_get_jed_locale_data( 'amp' );
|
| 209 |
+
} elseif ( function_exists( 'gutenberg_get_jed_locale_data' ) ) {
|
| 210 |
+
$script_data['i18n'] = gutenberg_get_jed_locale_data( 'amp' );
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
wp_add_inline_script(
|
| 214 |
+
self::BLOCK_ASSET_HANDLE,
|
| 215 |
+
sprintf( 'var wpAmpEditor = %s;', wp_json_encode( $script_data ) ),
|
| 216 |
+
'before'
|
| 217 |
+
);
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
/**
|
| 221 |
* Render AMP status.
|
| 222 |
*
|
| 230 |
is_post_type_viewable( $post->post_type )
|
| 231 |
&&
|
| 232 |
current_user_can( 'edit_post', $post->ID )
|
|
|
|
|
|
|
| 233 |
);
|
| 234 |
|
| 235 |
if ( true !== $verify ) {
|
| 236 |
return;
|
| 237 |
}
|
| 238 |
|
| 239 |
+
$status_and_errors = $this->get_status_and_errors( $post );
|
| 240 |
+
$status = $status_and_errors['status'];
|
| 241 |
+
$errors = $status_and_errors['errors'];
|
| 242 |
+
$error_messages = $this->get_error_messages( $status, $errors );
|
| 243 |
+
|
| 244 |
$labels = array(
|
| 245 |
'enabled' => __( 'Enabled', 'amp' ),
|
| 246 |
'disabled' => __( 'Disabled', 'amp' ),
|
| 247 |
);
|
| 248 |
|
| 249 |
// The preceding variables are used inside the following amp-status.php template.
|
| 250 |
+
include AMP__DIR__ . '/templates/admin/amp-status.php';
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
/**
|
| 254 |
+
* Gets the AMP enabled status and errors.
|
| 255 |
+
*
|
| 256 |
+
* @since 1.0
|
| 257 |
+
* @param WP_Post $post The post to check.
|
| 258 |
+
* @return array {
|
| 259 |
+
* The status and errors.
|
| 260 |
+
*
|
| 261 |
+
* @type string $status The AMP enabled status.
|
| 262 |
+
* @type string[] $errors AMP errors.
|
| 263 |
+
* }
|
| 264 |
+
*/
|
| 265 |
+
public function get_status_and_errors( $post ) {
|
| 266 |
+
/*
|
| 267 |
+
* When theme support is present then theme templates can be served in AMP and we check first if the template is available.
|
| 268 |
+
* Checking for template availability will include a check for get_support_errors. Otherwise, if theme support is not present
|
| 269 |
+
* then we just check get_support_errors.
|
| 270 |
+
*/
|
| 271 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 272 |
+
$availability = AMP_Theme_Support::get_template_availability( $post );
|
| 273 |
+
$status = $availability['supported'] ? self::ENABLED_STATUS : self::DISABLED_STATUS;
|
| 274 |
+
$errors = array_diff( $availability['errors'], array( 'post-status-disabled' ) ); // Subtract the status which the metabox will allow to be toggled.
|
| 275 |
+
if ( true === $availability['immutable'] ) {
|
| 276 |
+
$errors[] = 'status_immutable';
|
| 277 |
+
}
|
| 278 |
+
} else {
|
| 279 |
+
$errors = AMP_Post_Type_Support::get_support_errors( $post );
|
| 280 |
+
$status = empty( $errors ) ? self::ENABLED_STATUS : self::DISABLED_STATUS;
|
| 281 |
+
$errors = array_diff( $errors, array( 'post-status-disabled' ) ); // Subtract the status which the metabox will allow to be toggled.
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
return compact( 'status', 'errors' );
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
/**
|
| 288 |
+
* Gets the AMP enabled error message(s).
|
| 289 |
+
*
|
| 290 |
+
* @since 1.0
|
| 291 |
+
* @param string $status The AMP enabled status.
|
| 292 |
+
* @param array $errors The AMP enabled errors.
|
| 293 |
+
* @return array $error_messages The error messages, as an array of strings.
|
| 294 |
+
*/
|
| 295 |
+
public function get_error_messages( $status, $errors ) {
|
| 296 |
+
$error_messages = array();
|
| 297 |
+
if ( in_array( 'status_immutable', $errors, true ) ) {
|
| 298 |
+
if ( self::ENABLED_STATUS === $status ) {
|
| 299 |
+
$error_messages[] = __( 'Your site does not allow AMP to be disabled.', 'amp' );
|
| 300 |
+
} else {
|
| 301 |
+
$error_messages[] = __( 'Your site does not allow AMP to be enabled.', 'amp' );
|
| 302 |
+
}
|
| 303 |
+
}
|
| 304 |
+
if ( in_array( 'template_unsupported', $errors, true ) || in_array( 'no_matching_template', $errors, true ) ) {
|
| 305 |
+
$error_messages[] = sprintf(
|
| 306 |
+
/* translators: %s is a link to the AMP settings screen */
|
| 307 |
+
__( 'There are no <a href="%s">supported templates</a> to display this in AMP.', 'amp' ),
|
| 308 |
+
esc_url( admin_url( 'admin.php?page=' . AMP_Options_Manager::OPTION_NAME ) )
|
| 309 |
+
);
|
| 310 |
+
}
|
| 311 |
+
if ( in_array( 'password-protected', $errors, true ) ) {
|
| 312 |
+
$error_messages[] = __( 'AMP cannot be enabled on password protected posts.', 'amp' );
|
| 313 |
+
}
|
| 314 |
+
if ( in_array( 'post-type-support', $errors, true ) ) {
|
| 315 |
+
$error_messages[] = sprintf(
|
| 316 |
+
/* translators: %s is a link to the AMP settings screen */
|
| 317 |
+
__( 'AMP cannot be enabled because this <a href="%s">post type does not support it</a>.', 'amp' ),
|
| 318 |
+
esc_url( admin_url( 'admin.php?page=' . AMP_Options_Manager::OPTION_NAME ) )
|
| 319 |
+
);
|
| 320 |
+
}
|
| 321 |
+
if ( in_array( 'skip-post', $errors, true ) ) {
|
| 322 |
+
$error_messages[] = __( 'A plugin or theme has disabled AMP support.', 'amp' );
|
| 323 |
+
}
|
| 324 |
+
if ( count( array_diff( $errors, array( 'status_immutable', 'page-on-front', 'page-for-posts', 'password-protected', 'post-type-support', 'skip-post', 'template_unsupported', 'no_matching_template' ) ) ) > 0 ) {
|
| 325 |
+
$error_messages[] = __( 'Unavailable for an unknown reason.', 'amp' );
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
return $error_messages;
|
| 329 |
}
|
| 330 |
|
| 331 |
/**
|
|
@@ -38,7 +38,7 @@ function amp_init_customizer() {
|
|
| 38 |
/**
|
| 39 |
* Get permalink for the first AMP-eligible post.
|
| 40 |
*
|
| 41 |
-
* @return string|null
|
| 42 |
*/
|
| 43 |
function amp_admin_get_preview_permalink() {
|
| 44 |
/**
|
|
@@ -48,16 +48,34 @@ function amp_admin_get_preview_permalink() {
|
|
| 48 |
*/
|
| 49 |
$post_type = (string) apply_filters( 'amp_customizer_post_type', 'post' );
|
| 50 |
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
return null;
|
| 53 |
}
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
$post_ids = get_posts( array(
|
| 56 |
-
'
|
| 57 |
-
'
|
| 58 |
-
'
|
| 59 |
-
'
|
| 60 |
-
'
|
|
|
|
|
|
|
|
|
|
| 61 |
) );
|
| 62 |
|
| 63 |
if ( empty( $post_ids ) ) {
|
|
@@ -73,6 +91,11 @@ function amp_admin_get_preview_permalink() {
|
|
| 73 |
* Registers a submenu page to access the AMP template editor panel in the Customizer.
|
| 74 |
*/
|
| 75 |
function amp_add_customizer_link() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
$menu_slug = add_query_arg( array(
|
| 77 |
'autofocus[panel]' => AMP_Template_Customizer::PANEL_ID,
|
| 78 |
'url' => rawurlencode( amp_admin_get_preview_permalink() ),
|
|
@@ -153,3 +176,21 @@ function amp_post_meta_box() {
|
|
| 153 |
$post_meta_box = new AMP_Post_Meta_Box();
|
| 154 |
$post_meta_box->init();
|
| 155 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
/**
|
| 39 |
* Get permalink for the first AMP-eligible post.
|
| 40 |
*
|
| 41 |
+
* @return string|null URL on success, null if none found.
|
| 42 |
*/
|
| 43 |
function amp_admin_get_preview_permalink() {
|
| 44 |
/**
|
| 48 |
*/
|
| 49 |
$post_type = (string) apply_filters( 'amp_customizer_post_type', 'post' );
|
| 50 |
|
| 51 |
+
// Make sure the desired post type is actually supported, and if so, prefer it.
|
| 52 |
+
$supported_post_types = get_post_types_by_support( AMP_Post_Type_Support::SLUG );
|
| 53 |
+
if ( in_array( $post_type, $supported_post_types, true ) ) {
|
| 54 |
+
$supported_post_types = array_unique( array_merge( array( $post_type ), $supported_post_types ) );
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
// Bail if there are no supported post types.
|
| 58 |
+
if ( empty( $supported_post_types ) ) {
|
| 59 |
return null;
|
| 60 |
}
|
| 61 |
|
| 62 |
+
// If theme support is present, then bail if the singular template is not supported.
|
| 63 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 64 |
+
$supported_templates = AMP_Theme_Support::get_supportable_templates();
|
| 65 |
+
if ( empty( $supported_templates['is_singular']['supported'] ) ) {
|
| 66 |
+
return null;
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
$post_ids = get_posts( array(
|
| 71 |
+
'no_found_rows' => true,
|
| 72 |
+
'suppress_filters' => false,
|
| 73 |
+
'post_status' => 'publish',
|
| 74 |
+
'post_password' => '',
|
| 75 |
+
'post_type' => $supported_post_types,
|
| 76 |
+
'posts_per_page' => 1,
|
| 77 |
+
'fields' => 'ids',
|
| 78 |
+
// @todo This should eventually do a meta_query to make sure there are none that have AMP_Post_Meta_Box::STATUS_POST_META_KEY = DISABLED_STATUS.
|
| 79 |
) );
|
| 80 |
|
| 81 |
if ( empty( $post_ids ) ) {
|
| 91 |
* Registers a submenu page to access the AMP template editor panel in the Customizer.
|
| 92 |
*/
|
| 93 |
function amp_add_customizer_link() {
|
| 94 |
+
/** This filter is documented in includes/settings/class-amp-customizer-design-settings.php */
|
| 95 |
+
if ( ! apply_filters( 'amp_customizer_is_enabled', true ) || current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 96 |
+
return;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
$menu_slug = add_query_arg( array(
|
| 100 |
'autofocus[panel]' => AMP_Template_Customizer::PANEL_ID,
|
| 101 |
'url' => rawurlencode( amp_admin_get_preview_permalink() ),
|
| 176 |
$post_meta_box = new AMP_Post_Meta_Box();
|
| 177 |
$post_meta_box->init();
|
| 178 |
}
|
| 179 |
+
|
| 180 |
+
/**
|
| 181 |
+
* Bootstrap AMP Editor core blocks.
|
| 182 |
+
*/
|
| 183 |
+
function amp_editor_core_blocks() {
|
| 184 |
+
$editor_blocks = new AMP_Editor_Blocks();
|
| 185 |
+
$editor_blocks->init();
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
/**
|
| 189 |
+
* Bootstrap the AMP admin pointer class.
|
| 190 |
+
*
|
| 191 |
+
* @since 1.0
|
| 192 |
+
*/
|
| 193 |
+
function amp_admin_pointer() {
|
| 194 |
+
$admin_pointer = new AMP_Admin_Pointer();
|
| 195 |
+
$admin_pointer->init();
|
| 196 |
+
}
|
|
@@ -2,39 +2,22 @@
|
|
| 2 |
/**
|
| 3 |
* Callbacks for adding AMP-related things to the main theme.
|
| 4 |
*
|
|
|
|
| 5 |
* @package AMP
|
| 6 |
*/
|
| 7 |
|
| 8 |
-
|
| 9 |
|
| 10 |
/**
|
| 11 |
* Add amphtml link to frontend.
|
| 12 |
*
|
| 13 |
-
* @
|
| 14 |
*
|
| 15 |
* @since 0.2
|
|
|
|
|
|
|
| 16 |
*/
|
| 17 |
function amp_frontend_add_canonical() {
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
* Filters whether to show the amphtml link on the frontend.
|
| 21 |
-
*
|
| 22 |
-
* @todo This filter's name is incorrect. It's not about adding a canonical link but adding the amphtml link.
|
| 23 |
-
* @since 0.2
|
| 24 |
-
*/
|
| 25 |
-
if ( false === apply_filters( 'amp_frontend_show_canonical', true ) ) {
|
| 26 |
-
return;
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
$amp_url = null;
|
| 30 |
-
if ( is_singular() ) {
|
| 31 |
-
$amp_url = amp_get_permalink( get_queried_object_id() );
|
| 32 |
-
} elseif ( isset( $_SERVER['REQUEST_URI'] ) ) {
|
| 33 |
-
$host_url = preg_replace( '#(^https?://[^/]+)/.*#', '$1', home_url( '/' ) );
|
| 34 |
-
$self_url = esc_url_raw( $host_url . wp_unslash( $_SERVER['REQUEST_URI'] ) );
|
| 35 |
-
$amp_url = add_query_arg( amp_get_slug(), '', $self_url );
|
| 36 |
-
}
|
| 37 |
-
if ( $amp_url ) {
|
| 38 |
-
printf( '<link rel="amphtml" href="%s">', esc_url( $amp_url ) );
|
| 39 |
-
}
|
| 40 |
}
|
| 2 |
/**
|
| 3 |
* Callbacks for adding AMP-related things to the main theme.
|
| 4 |
*
|
| 5 |
+
* @deprecated Function in this file has been moved to amp-helper-functions.php.
|
| 6 |
* @package AMP
|
| 7 |
*/
|
| 8 |
|
| 9 |
+
_deprecated_file( __FILE__, '1.0', null, esc_html__( 'Use amp_add_amphtml_link() function which is already included from amp-helper-functions.php', 'amp' ) );
|
| 10 |
|
| 11 |
/**
|
| 12 |
* Add amphtml link to frontend.
|
| 13 |
*
|
| 14 |
+
* @deprecated
|
| 15 |
*
|
| 16 |
* @since 0.2
|
| 17 |
+
* @since 1.0 Deprecated
|
| 18 |
+
* @see amp_add_amphtml_link()
|
| 19 |
*/
|
| 20 |
function amp_frontend_add_canonical() {
|
| 21 |
+
_deprecated_function( __FUNCTION__, '1.0', 'amp_add_amphtml_link' );
|
| 22 |
+
amp_add_amphtml_link();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
}
|
|
@@ -13,6 +13,7 @@
|
|
| 13 |
* may be deprecated in the future. Normally the slug should be just 'amp'.
|
| 14 |
*
|
| 15 |
* @since 0.7
|
|
|
|
| 16 |
* @return string Slug used for query var, endpoint, and post type support.
|
| 17 |
*/
|
| 18 |
function amp_get_slug() {
|
|
@@ -26,6 +27,7 @@ function amp_get_slug() {
|
|
| 26 |
* Warning: This filter may become deprecated.
|
| 27 |
*
|
| 28 |
* @since 0.3.2
|
|
|
|
| 29 |
* @param string $query_var The AMP query variable.
|
| 30 |
*/
|
| 31 |
$query_var = apply_filters( 'amp_query_var', 'amp' );
|
|
@@ -35,23 +37,52 @@ function amp_get_slug() {
|
|
| 35 |
return $query_var;
|
| 36 |
}
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
/**
|
| 39 |
* Retrieves the full AMP-specific permalink for the given post ID.
|
| 40 |
*
|
| 41 |
* @since 0.1
|
| 42 |
*
|
| 43 |
* @param int $post_id Post ID.
|
| 44 |
-
*
|
| 45 |
* @return string AMP permalink.
|
| 46 |
*/
|
| 47 |
function amp_get_permalink( $post_id ) {
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
/**
|
| 50 |
* Filters the AMP permalink to short-circuit normal generation.
|
| 51 |
*
|
| 52 |
* Returning a non-false value in this filter will cause the `get_permalink()` to get called and the `amp_get_permalink` filter to not apply.
|
| 53 |
*
|
| 54 |
* @since 0.4
|
|
|
|
| 55 |
*
|
| 56 |
* @param false $url Short-circuited URL.
|
| 57 |
* @param int $post_id Post ID.
|
|
@@ -62,15 +93,34 @@ function amp_get_permalink( $post_id ) {
|
|
| 62 |
return $pre_url;
|
| 63 |
}
|
| 64 |
|
|
|
|
|
|
|
| 65 |
if ( amp_is_canonical() ) {
|
| 66 |
-
$amp_url =
|
| 67 |
} else {
|
| 68 |
-
$parsed_url
|
| 69 |
-
$structure
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
} else {
|
| 73 |
-
$amp_url =
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
}
|
| 75 |
}
|
| 76 |
|
|
@@ -78,6 +128,7 @@ function amp_get_permalink( $post_id ) {
|
|
| 78 |
* Filters AMP permalink.
|
| 79 |
*
|
| 80 |
* @since 0.2
|
|
|
|
| 81 |
*
|
| 82 |
* @param false $amp_url AMP URL.
|
| 83 |
* @param int $post_id Post ID.
|
|
@@ -105,85 +156,135 @@ function amp_remove_endpoint( $url ) {
|
|
| 105 |
}
|
| 106 |
|
| 107 |
/**
|
| 108 |
-
*
|
| 109 |
-
*
|
| 110 |
-
* @since 0.1
|
| 111 |
-
* @since 0.6 Returns false when post has meta to disable AMP.
|
| 112 |
-
* @see AMP_Post_Type_Support::get_support_errors()
|
| 113 |
*
|
| 114 |
-
*
|
| 115 |
*
|
| 116 |
-
* @
|
| 117 |
*/
|
| 118 |
-
function
|
| 119 |
-
|
| 120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
}
|
| 122 |
|
| 123 |
-
$
|
| 124 |
|
| 125 |
-
|
| 126 |
-
if (
|
| 127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
}
|
| 129 |
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
'
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
|
|
|
|
|
|
| 153 |
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
*
|
| 157 |
-
* @since 0.6
|
| 158 |
-
*
|
| 159 |
-
* @param string $status Status.
|
| 160 |
-
* @param WP_Post $post Post.
|
| 161 |
-
*/
|
| 162 |
-
return apply_filters( 'amp_post_status_default_enabled', $enabled, $post );
|
| 163 |
}
|
| 164 |
}
|
| 165 |
|
| 166 |
/**
|
| 167 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
*
|
| 169 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
*
|
| 171 |
* @return bool Whether it is the AMP endpoint.
|
| 172 |
*/
|
| 173 |
function is_amp_endpoint() {
|
| 174 |
-
|
|
|
|
|
|
|
| 175 |
return false;
|
| 176 |
}
|
| 177 |
|
| 178 |
-
|
| 179 |
-
return true;
|
| 180 |
-
}
|
| 181 |
|
| 182 |
-
if (
|
| 183 |
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( "is_amp_endpoint() was called before the 'parse_query' hook was called. This function will always return 'false' before the 'parse_query' hook is called.", 'amp' ) ), '0.4.2' );
|
| 184 |
}
|
| 185 |
|
| 186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
}
|
| 188 |
|
| 189 |
/**
|
|
@@ -209,6 +310,23 @@ function amp_get_boilerplate_code() {
|
|
| 209 |
. '<noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>';
|
| 210 |
}
|
| 211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
/**
|
| 213 |
* Register default scripts for AMP components.
|
| 214 |
*
|
|
@@ -242,23 +360,19 @@ function amp_register_default_scripts( $wp_scripts ) {
|
|
| 242 |
|
| 243 |
// Get all AMP components as defined in the spec.
|
| 244 |
$extensions = array();
|
| 245 |
-
foreach ( AMP_Allowed_Tags_Generated::
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
$rule_spec[ AMP_Rule_Spec::TAG_SPEC ]['requires_extension']
|
| 251 |
-
);
|
| 252 |
-
}
|
| 253 |
}
|
| 254 |
}
|
| 255 |
-
$extensions = array_unique( $extensions );
|
| 256 |
|
| 257 |
-
foreach ( $extensions as $extension ) {
|
| 258 |
$src = sprintf(
|
| 259 |
'https://cdn.ampproject.org/v0/%s-%s.js',
|
| 260 |
$extension,
|
| 261 |
-
|
| 262 |
);
|
| 263 |
|
| 264 |
$wp_scripts->add(
|
|
@@ -377,6 +491,49 @@ function amp_filter_script_loader_tag( $tag, $handle ) {
|
|
| 377 |
return $tag;
|
| 378 |
}
|
| 379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
/**
|
| 381 |
* Retrieve analytics data added in backend.
|
| 382 |
*
|
|
@@ -435,7 +592,7 @@ function amp_print_analytics( $analytics ) {
|
|
| 435 |
// Can enter multiple configs within backend.
|
| 436 |
foreach ( $analytics_entries as $id => $analytics_entry ) {
|
| 437 |
if ( ! isset( $analytics_entry['type'], $analytics_entry['attributes'], $analytics_entry['config_data'] ) ) {
|
| 438 |
-
/* translators:
|
| 439 |
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'Analytics entry for %1$s is missing one of the following keys: `type`, `attributes`, or `config_data` (array keys: %2$s)', 'amp' ), esc_html( $id ), esc_html( implode( ', ', array_keys( $analytics_entry ) ) ) ), '0.3.2' );
|
| 440 |
continue;
|
| 441 |
}
|
|
@@ -462,7 +619,7 @@ function amp_print_analytics( $analytics ) {
|
|
| 462 |
* @return array Embed handlers.
|
| 463 |
*/
|
| 464 |
function amp_get_content_embed_handlers( $post = null ) {
|
| 465 |
-
if ( current_theme_supports(
|
| 466 |
_deprecated_argument( __FUNCTION__, '0.7', esc_html__( 'The $post argument is deprecated when theme supports AMP.', 'amp' ) );
|
| 467 |
$post = null;
|
| 468 |
}
|
|
@@ -478,6 +635,7 @@ function amp_get_content_embed_handlers( $post = null ) {
|
|
| 478 |
*/
|
| 479 |
return apply_filters( 'amp_content_embed_handlers',
|
| 480 |
array(
|
|
|
|
| 481 |
'AMP_Twitter_Embed_Handler' => array(),
|
| 482 |
'AMP_YouTube_Embed_Handler' => array(),
|
| 483 |
'AMP_DailyMotion_Embed_Handler' => array(),
|
|
@@ -493,6 +651,9 @@ function amp_get_content_embed_handlers( $post = null ) {
|
|
| 493 |
'AMP_Reddit_Embed_Handler' => array(),
|
| 494 |
'AMP_Tumblr_Embed_Handler' => array(),
|
| 495 |
'AMP_Gallery_Embed_Handler' => array(),
|
|
|
|
|
|
|
|
|
|
| 496 |
'WPCOM_AMP_Polldaddy_Embed' => array(),
|
| 497 |
),
|
| 498 |
$post
|
|
@@ -509,7 +670,7 @@ function amp_get_content_embed_handlers( $post = null ) {
|
|
| 509 |
* @return array Embed handlers.
|
| 510 |
*/
|
| 511 |
function amp_get_content_sanitizers( $post = null ) {
|
| 512 |
-
if ( current_theme_supports(
|
| 513 |
_deprecated_argument( __FUNCTION__, '0.7', esc_html__( 'The $post argument is deprecated when theme supports AMP.', 'amp' ) );
|
| 514 |
$post = null;
|
| 515 |
}
|
|
@@ -525,15 +686,26 @@ function amp_get_content_sanitizers( $post = null ) {
|
|
| 525 |
*/
|
| 526 |
$sanitizers = apply_filters( 'amp_content_sanitizers',
|
| 527 |
array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 528 |
'AMP_Img_Sanitizer' => array(),
|
| 529 |
'AMP_Form_Sanitizer' => array(),
|
| 530 |
'AMP_Comments_Sanitizer' => array(),
|
| 531 |
'AMP_Video_Sanitizer' => array(),
|
|
|
|
| 532 |
'AMP_Audio_Sanitizer' => array(),
|
| 533 |
'AMP_Playbuzz_Sanitizer' => array(),
|
|
|
|
| 534 |
'AMP_Iframe_Sanitizer' => array(
|
| 535 |
'add_placeholder' => true,
|
| 536 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 537 |
'AMP_Style_Sanitizer' => array(),
|
| 538 |
'AMP_Tag_And_Attribute_Sanitizer' => array(), // Note: This whitelist sanitizer must come at the end to clean up any remaining issues the other sanitizers didn't catch.
|
| 539 |
),
|
|
@@ -627,23 +799,66 @@ function amp_get_schemaorg_metadata() {
|
|
| 627 |
),
|
| 628 |
);
|
| 629 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 630 |
/**
|
| 631 |
-
* Filters the
|
| 632 |
*
|
| 633 |
-
*
|
|
|
|
| 634 |
*
|
| 635 |
* @since 0.3
|
| 636 |
-
* @todo Why is the size set to 32px?
|
| 637 |
*
|
| 638 |
-
* @param string $
|
| 639 |
*/
|
| 640 |
-
$
|
| 641 |
-
if ( $
|
| 642 |
-
$
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
);
|
| 648 |
}
|
| 649 |
|
|
@@ -715,3 +930,17 @@ function amp_print_schemaorg_metadata() {
|
|
| 715 |
<script type="application/ld+json"><?php echo wp_json_encode( $metadata ); ?></script>
|
| 716 |
<?php
|
| 717 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
* may be deprecated in the future. Normally the slug should be just 'amp'.
|
| 14 |
*
|
| 15 |
* @since 0.7
|
| 16 |
+
*
|
| 17 |
* @return string Slug used for query var, endpoint, and post type support.
|
| 18 |
*/
|
| 19 |
function amp_get_slug() {
|
| 27 |
* Warning: This filter may become deprecated.
|
| 28 |
*
|
| 29 |
* @since 0.3.2
|
| 30 |
+
*
|
| 31 |
* @param string $query_var The AMP query variable.
|
| 32 |
*/
|
| 33 |
$query_var = apply_filters( 'amp_query_var', 'amp' );
|
| 37 |
return $query_var;
|
| 38 |
}
|
| 39 |
|
| 40 |
+
/**
|
| 41 |
+
* Get the URL for the current request.
|
| 42 |
+
*
|
| 43 |
+
* This is essentially the REQUEST_URI prefixed by the scheme and host for the home URL.
|
| 44 |
+
* This is needed in particular due to subdirectory installs.
|
| 45 |
+
*
|
| 46 |
+
* @since 1.0
|
| 47 |
+
*
|
| 48 |
+
* @return string Current URL.
|
| 49 |
+
*/
|
| 50 |
+
function amp_get_current_url() {
|
| 51 |
+
$url = preg_replace( '#(^https?://[^/]+)/.*#', '$1', home_url( '/' ) );
|
| 52 |
+
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
|
| 53 |
+
$url = esc_url_raw( $url . wp_unslash( $_SERVER['REQUEST_URI'] ) );
|
| 54 |
+
} else {
|
| 55 |
+
$url .= '/';
|
| 56 |
+
}
|
| 57 |
+
return $url;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
/**
|
| 61 |
* Retrieves the full AMP-specific permalink for the given post ID.
|
| 62 |
*
|
| 63 |
* @since 0.1
|
| 64 |
*
|
| 65 |
* @param int $post_id Post ID.
|
|
|
|
| 66 |
* @return string AMP permalink.
|
| 67 |
*/
|
| 68 |
function amp_get_permalink( $post_id ) {
|
| 69 |
|
| 70 |
+
// When theme support is present, the plain query var should always be used.
|
| 71 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 72 |
+
$permalink = get_permalink( $post_id );
|
| 73 |
+
if ( ! amp_is_canonical() ) {
|
| 74 |
+
$permalink = add_query_arg( amp_get_slug(), '', $permalink );
|
| 75 |
+
}
|
| 76 |
+
return $permalink;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
/**
|
| 80 |
* Filters the AMP permalink to short-circuit normal generation.
|
| 81 |
*
|
| 82 |
* Returning a non-false value in this filter will cause the `get_permalink()` to get called and the `amp_get_permalink` filter to not apply.
|
| 83 |
*
|
| 84 |
* @since 0.4
|
| 85 |
+
* @since 1.0 This filter does not apply when 'amp' theme support is present.
|
| 86 |
*
|
| 87 |
* @param false $url Short-circuited URL.
|
| 88 |
* @param int $post_id Post ID.
|
| 93 |
return $pre_url;
|
| 94 |
}
|
| 95 |
|
| 96 |
+
$permalink = get_permalink( $post_id );
|
| 97 |
+
|
| 98 |
if ( amp_is_canonical() ) {
|
| 99 |
+
$amp_url = $permalink;
|
| 100 |
} else {
|
| 101 |
+
$parsed_url = wp_parse_url( get_permalink( $post_id ) );
|
| 102 |
+
$structure = get_option( 'permalink_structure' );
|
| 103 |
+
$use_query_var = (
|
| 104 |
+
// If pretty permalinks aren't available, then query var must be used.
|
| 105 |
+
empty( $structure )
|
| 106 |
+
||
|
| 107 |
+
// If there are existing query vars, then always use the amp query var as well.
|
| 108 |
+
! empty( $parsed_url['query'] )
|
| 109 |
+
||
|
| 110 |
+
// If the post type is hierarchical then the /amp/ endpoint isn't available.
|
| 111 |
+
is_post_type_hierarchical( get_post_type( $post_id ) )
|
| 112 |
+
||
|
| 113 |
+
// Attachment pages don't accept the /amp/ endpoint.
|
| 114 |
+
'attachment' === get_post_type( $post_id )
|
| 115 |
+
);
|
| 116 |
+
if ( $use_query_var ) {
|
| 117 |
+
$amp_url = add_query_arg( amp_get_slug(), '', $permalink );
|
| 118 |
} else {
|
| 119 |
+
$amp_url = preg_replace( '/#.*/', '', $permalink );
|
| 120 |
+
$amp_url = trailingslashit( $amp_url ) . user_trailingslashit( amp_get_slug(), 'single_amp' );
|
| 121 |
+
if ( ! empty( $parsed_url['fragment'] ) ) {
|
| 122 |
+
$amp_url .= '#' . $parsed_url['fragment'];
|
| 123 |
+
}
|
| 124 |
}
|
| 125 |
}
|
| 126 |
|
| 128 |
* Filters AMP permalink.
|
| 129 |
*
|
| 130 |
* @since 0.2
|
| 131 |
+
* @since 1.0 This filter does not apply when 'amp' theme support is present.
|
| 132 |
*
|
| 133 |
* @param false $amp_url AMP URL.
|
| 134 |
* @param int $post_id Post ID.
|
| 156 |
}
|
| 157 |
|
| 158 |
/**
|
| 159 |
+
* Add amphtml link.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
*
|
| 161 |
+
* If there are known validation errors for the current URL then do not output anything.
|
| 162 |
*
|
| 163 |
+
* @since 1.0
|
| 164 |
*/
|
| 165 |
+
function amp_add_amphtml_link() {
|
| 166 |
+
|
| 167 |
+
/**
|
| 168 |
+
* Filters whether to show the amphtml link on the frontend.
|
| 169 |
+
*
|
| 170 |
+
* @todo This filter's name is incorrect. It's not about adding a canonical link but adding the amphtml link.
|
| 171 |
+
* @since 0.2
|
| 172 |
+
*/
|
| 173 |
+
if ( false === apply_filters( 'amp_frontend_show_canonical', true ) ) {
|
| 174 |
+
return;
|
| 175 |
}
|
| 176 |
|
| 177 |
+
$current_url = amp_get_current_url();
|
| 178 |
|
| 179 |
+
$amp_url = null;
|
| 180 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 181 |
+
if ( AMP_Theme_Support::is_paired_available() ) {
|
| 182 |
+
$amp_url = add_query_arg( amp_get_slug(), '', $current_url );
|
| 183 |
+
}
|
| 184 |
+
} else {
|
| 185 |
+
if ( is_singular() ) {
|
| 186 |
+
$amp_url = amp_get_permalink( get_queried_object_id() );
|
| 187 |
+
} else {
|
| 188 |
+
$amp_url = add_query_arg( amp_get_slug(), '', $current_url );
|
| 189 |
+
}
|
| 190 |
}
|
| 191 |
|
| 192 |
+
if ( ! $amp_url ) {
|
| 193 |
+
printf( '<!-- %s -->', esc_html__( 'There is no amphtml version available for this URL.', 'amp' ) );
|
| 194 |
+
return;
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
// Check to see if there are known unaccepted validation errors for this URL.
|
| 198 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 199 |
+
$validation_errors = AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( $current_url, array( 'ignore_accepted' => true ) );
|
| 200 |
+
$error_count = count( $validation_errors );
|
| 201 |
+
if ( $error_count > 0 ) {
|
| 202 |
+
echo "<!--\n";
|
| 203 |
+
echo esc_html( sprintf(
|
| 204 |
+
/* translators: %s is error count */
|
| 205 |
+
_n(
|
| 206 |
+
'There is %s validation error that is blocking the amphtml version from being available.',
|
| 207 |
+
'There are %s validation errors that are blocking the amphtml version from being available.',
|
| 208 |
+
$error_count,
|
| 209 |
+
'amp'
|
| 210 |
+
),
|
| 211 |
+
number_format_i18n( $error_count )
|
| 212 |
+
) );
|
| 213 |
+
echo "\n-->";
|
| 214 |
+
return;
|
| 215 |
+
}
|
| 216 |
+
}
|
| 217 |
|
| 218 |
+
if ( $amp_url ) {
|
| 219 |
+
printf( '<link rel="amphtml" href="%s">', esc_url( $amp_url ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
}
|
| 221 |
}
|
| 222 |
|
| 223 |
/**
|
| 224 |
+
* Determine whether a given post supports AMP.
|
| 225 |
+
*
|
| 226 |
+
* @since 0.1
|
| 227 |
+
* @since 0.6 Returns false when post has meta to disable AMP.
|
| 228 |
+
* @see AMP_Post_Type_Support::get_support_errors()
|
| 229 |
+
*
|
| 230 |
+
* @param WP_Post $post Post.
|
| 231 |
+
* @return bool Whether the post supports AMP.
|
| 232 |
+
*/
|
| 233 |
+
function post_supports_amp( $post ) {
|
| 234 |
+
return 0 === count( AMP_Post_Type_Support::get_support_errors( $post ) );
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
/**
|
| 238 |
+
* Determine whether the current response being served as AMP.
|
| 239 |
*
|
| 240 |
+
* This function cannot be called before the parse_query action because it needs to be able
|
| 241 |
+
* to determine the queried object is able to be served as AMP. If 'amp' theme support is not
|
| 242 |
+
* present, this function returns true just if the query var is present. If theme support is
|
| 243 |
+
* present, then it returns true in paired mode if an AMP template is available and the query
|
| 244 |
+
* var is present, or else in native mode if just the template is available.
|
| 245 |
*
|
| 246 |
* @return bool Whether it is the AMP endpoint.
|
| 247 |
*/
|
| 248 |
function is_amp_endpoint() {
|
| 249 |
+
global $pagenow;
|
| 250 |
+
|
| 251 |
+
if ( is_admin() || is_feed() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || in_array( $pagenow, array( 'wp-login.php', 'wp-signup.php', 'wp-activate.php' ), true ) ) {
|
| 252 |
return false;
|
| 253 |
}
|
| 254 |
|
| 255 |
+
$did_parse_query = did_action( 'parse_query' );
|
|
|
|
|
|
|
| 256 |
|
| 257 |
+
if ( ! $did_parse_query ) {
|
| 258 |
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( "is_amp_endpoint() was called before the 'parse_query' hook was called. This function will always return 'false' before the 'parse_query' hook is called.", 'amp' ) ), '0.4.2' );
|
| 259 |
}
|
| 260 |
|
| 261 |
+
$has_amp_query_var = (
|
| 262 |
+
isset( $_GET[ amp_get_slug() ] ) // WPCS: CSRF OK.
|
| 263 |
+
||
|
| 264 |
+
false !== get_query_var( amp_get_slug(), false )
|
| 265 |
+
);
|
| 266 |
+
|
| 267 |
+
if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 268 |
+
return $has_amp_query_var;
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
// When there is no query var and AMP is not canonical/native, then this is definitely not an AMP endpoint.
|
| 272 |
+
if ( ! $has_amp_query_var && ! amp_is_canonical() ) {
|
| 273 |
+
return false;
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
/*
|
| 277 |
+
* If this is a URL for validation, and validation is forced for all URLs, return true.
|
| 278 |
+
* Normally, this would be false if the user has deselected a template,
|
| 279 |
+
* like by unchecking 'Categories' in 'AMP Settings' > 'Supported Templates'.
|
| 280 |
+
* But there's a flag for the WP-CLI command that sets this query var to validate all URLs.
|
| 281 |
+
*/
|
| 282 |
+
if ( AMP_Validation_Manager::is_theme_support_forced() ) {
|
| 283 |
+
return true;
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
$availability = AMP_Theme_Support::get_template_availability();
|
| 287 |
+
return amp_is_canonical() ? $availability['supported'] : ( $has_amp_query_var && $availability['supported'] );
|
| 288 |
}
|
| 289 |
|
| 290 |
/**
|
| 310 |
. '<noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>';
|
| 311 |
}
|
| 312 |
|
| 313 |
+
/**
|
| 314 |
+
* Add generator metadata.
|
| 315 |
+
*
|
| 316 |
+
* @since 6.0
|
| 317 |
+
* @since 1.0 Add template mode.
|
| 318 |
+
*/
|
| 319 |
+
function amp_add_generator_metadata() {
|
| 320 |
+
if ( amp_is_canonical() ) {
|
| 321 |
+
$mode = 'native';
|
| 322 |
+
} elseif ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 323 |
+
$mode = 'paired';
|
| 324 |
+
} else {
|
| 325 |
+
$mode = 'classic';
|
| 326 |
+
}
|
| 327 |
+
printf( '<meta name="generator" content="%s">', esc_attr( sprintf( 'AMP Plugin v%s; mode=%s', AMP__VERSION, $mode ) ) );
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
/**
|
| 331 |
* Register default scripts for AMP components.
|
| 332 |
*
|
| 360 |
|
| 361 |
// Get all AMP components as defined in the spec.
|
| 362 |
$extensions = array();
|
| 363 |
+
foreach ( AMP_Allowed_Tags_Generated::get_allowed_tag( 'script' ) as $script_spec ) {
|
| 364 |
+
if ( isset( $script_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec']['name'], $script_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec']['version'] ) ) {
|
| 365 |
+
$versions = $script_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec']['version'];
|
| 366 |
+
array_pop( $versions );
|
| 367 |
+
$extensions[ $script_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec']['name'] ] = array_pop( $versions );
|
|
|
|
|
|
|
|
|
|
| 368 |
}
|
| 369 |
}
|
|
|
|
| 370 |
|
| 371 |
+
foreach ( $extensions as $extension => $version ) {
|
| 372 |
$src = sprintf(
|
| 373 |
'https://cdn.ampproject.org/v0/%s-%s.js',
|
| 374 |
$extension,
|
| 375 |
+
$version
|
| 376 |
);
|
| 377 |
|
| 378 |
$wp_scripts->add(
|
| 491 |
return $tag;
|
| 492 |
}
|
| 493 |
|
| 494 |
+
/**
|
| 495 |
+
* Explicitly opt-in to CORS mode by adding the crossorigin attribute to font stylesheet links.
|
| 496 |
+
*
|
| 497 |
+
* This explicitly triggers a CORS request, and gets back a non-opaque response, ensuring that a service
|
| 498 |
+
* worker caching the external stylesheet will not inflate the storage quota. This must be done in AMP
|
| 499 |
+
* and non-AMP alike because in paired mode the service worker could cache the font stylesheets in a
|
| 500 |
+
* non-AMP document without CORS (crossorigin="anonymous") in which case the service worker could then
|
| 501 |
+
* fail to serve the cached font resources in an AMP document with the warning:
|
| 502 |
+
*
|
| 503 |
+
* > The FetchEvent resulted in a network error response: an "opaque" response was used for a request whose type is not no-cors
|
| 504 |
+
*
|
| 505 |
+
* @since 1.0
|
| 506 |
+
* @link https://developers.google.com/web/tools/workbox/guides/storage-quota#beware_of_opaque_responses
|
| 507 |
+
* @link https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests#cross-origin_requests_and_opaque_responses
|
| 508 |
+
* @todo This should be proposed for WordPress core.
|
| 509 |
+
*
|
| 510 |
+
* @param string $tag Link tag HTML.
|
| 511 |
+
* @param string $handle Dependency handle.
|
| 512 |
+
* @param string $href Link URL.
|
| 513 |
+
* @return string Link tag HTML.
|
| 514 |
+
*/
|
| 515 |
+
function amp_filter_font_style_loader_tag_with_crossorigin_anonymous( $tag, $handle, $href ) {
|
| 516 |
+
static $allowed_font_src_regex = null;
|
| 517 |
+
unset( $handle );
|
| 518 |
+
if ( ! $allowed_font_src_regex ) {
|
| 519 |
+
$spec_name = 'link rel=stylesheet for fonts'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
|
| 520 |
+
foreach ( AMP_Allowed_Tags_Generated::get_allowed_tag( 'link' ) as $spec_rule ) {
|
| 521 |
+
if ( isset( $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] ) && $spec_name === $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] ) {
|
| 522 |
+
$allowed_font_src_regex = '@^(' . $spec_rule[ AMP_Rule_Spec::ATTR_SPEC_LIST ]['href']['value_regex'] . ')$@';
|
| 523 |
+
break;
|
| 524 |
+
}
|
| 525 |
+
}
|
| 526 |
+
}
|
| 527 |
+
|
| 528 |
+
$href = preg_replace( '#^(http:)?(?=//)#', 'https:', $href );
|
| 529 |
+
|
| 530 |
+
if ( preg_match( $allowed_font_src_regex, $href ) && false === strpos( $tag, 'crossorigin=' ) ) {
|
| 531 |
+
$tag = preg_replace( '/(?<=<link\s)/', 'crossorigin="anonymous" ', $tag );
|
| 532 |
+
}
|
| 533 |
+
|
| 534 |
+
return $tag;
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
/**
|
| 538 |
* Retrieve analytics data added in backend.
|
| 539 |
*
|
| 592 |
// Can enter multiple configs within backend.
|
| 593 |
foreach ( $analytics_entries as $id => $analytics_entry ) {
|
| 594 |
if ( ! isset( $analytics_entry['type'], $analytics_entry['attributes'], $analytics_entry['config_data'] ) ) {
|
| 595 |
+
/* translators: 1: the analytics entry ID, 2: comma-separated list of the actual entry keys. */
|
| 596 |
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'Analytics entry for %1$s is missing one of the following keys: `type`, `attributes`, or `config_data` (array keys: %2$s)', 'amp' ), esc_html( $id ), esc_html( implode( ', ', array_keys( $analytics_entry ) ) ) ), '0.3.2' );
|
| 597 |
continue;
|
| 598 |
}
|
| 619 |
* @return array Embed handlers.
|
| 620 |
*/
|
| 621 |
function amp_get_content_embed_handlers( $post = null ) {
|
| 622 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) && $post ) {
|
| 623 |
_deprecated_argument( __FUNCTION__, '0.7', esc_html__( 'The $post argument is deprecated when theme supports AMP.', 'amp' ) );
|
| 624 |
$post = null;
|
| 625 |
}
|
| 635 |
*/
|
| 636 |
return apply_filters( 'amp_content_embed_handlers',
|
| 637 |
array(
|
| 638 |
+
'AMP_Core_Block_Handler' => array(),
|
| 639 |
'AMP_Twitter_Embed_Handler' => array(),
|
| 640 |
'AMP_YouTube_Embed_Handler' => array(),
|
| 641 |
'AMP_DailyMotion_Embed_Handler' => array(),
|
| 651 |
'AMP_Reddit_Embed_Handler' => array(),
|
| 652 |
'AMP_Tumblr_Embed_Handler' => array(),
|
| 653 |
'AMP_Gallery_Embed_Handler' => array(),
|
| 654 |
+
'AMP_Gfycat_Embed_Handler' => array(),
|
| 655 |
+
'AMP_Hulu_Embed_Handler' => array(),
|
| 656 |
+
'AMP_Imgur_Embed_Handler' => array(),
|
| 657 |
'WPCOM_AMP_Polldaddy_Embed' => array(),
|
| 658 |
),
|
| 659 |
$post
|
| 670 |
* @return array Embed handlers.
|
| 671 |
*/
|
| 672 |
function amp_get_content_sanitizers( $post = null ) {
|
| 673 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) && $post ) {
|
| 674 |
_deprecated_argument( __FUNCTION__, '0.7', esc_html__( 'The $post argument is deprecated when theme supports AMP.', 'amp' ) );
|
| 675 |
$post = null;
|
| 676 |
}
|
| 686 |
*/
|
| 687 |
$sanitizers = apply_filters( 'amp_content_sanitizers',
|
| 688 |
array(
|
| 689 |
+
'AMP_Core_Theme_Sanitizer' => array(
|
| 690 |
+
'template' => get_template(),
|
| 691 |
+
'stylesheet' => get_stylesheet(),
|
| 692 |
+
),
|
| 693 |
'AMP_Img_Sanitizer' => array(),
|
| 694 |
'AMP_Form_Sanitizer' => array(),
|
| 695 |
'AMP_Comments_Sanitizer' => array(),
|
| 696 |
'AMP_Video_Sanitizer' => array(),
|
| 697 |
+
'AMP_O2_Player_Sanitizer' => array(),
|
| 698 |
'AMP_Audio_Sanitizer' => array(),
|
| 699 |
'AMP_Playbuzz_Sanitizer' => array(),
|
| 700 |
+
'AMP_Embed_Sanitizer' => array(),
|
| 701 |
'AMP_Iframe_Sanitizer' => array(
|
| 702 |
'add_placeholder' => true,
|
| 703 |
),
|
| 704 |
+
'AMP_Gallery_Block_Sanitizer' => array( // Note: Gallery block sanitizer must come after image sanitizers since itś logic is using the already sanitized images.
|
| 705 |
+
'carousel_required' => ! current_theme_supports( AMP_Theme_Support::SLUG ), // For back-compat.
|
| 706 |
+
),
|
| 707 |
+
'AMP_Block_Sanitizer' => array(), // Note: Block sanitizer must come after embed / media sanitizers since it's logic is using the already sanitized content.
|
| 708 |
+
'AMP_Script_Sanitizer' => array(),
|
| 709 |
'AMP_Style_Sanitizer' => array(),
|
| 710 |
'AMP_Tag_And_Attribute_Sanitizer' => array(), // Note: This whitelist sanitizer must come at the end to clean up any remaining issues the other sanitizers didn't catch.
|
| 711 |
),
|
| 799 |
),
|
| 800 |
);
|
| 801 |
|
| 802 |
+
/*
|
| 803 |
+
* "The logo should be a rectangle, not a square. The logo should fit in a 60x600px rectangle.,
|
| 804 |
+
* and either be exactly 60px high (preferred), or exactly 600px wide. For example, 450x45px
|
| 805 |
+
* would not be acceptable, even though it fits in the 600x60px rectangle."
|
| 806 |
+
* See <https://developers.google.com/search/docs/data-types/article#logo-guidelines>.
|
| 807 |
+
*/
|
| 808 |
+
$max_logo_width = 600;
|
| 809 |
+
$max_logo_height = 60;
|
| 810 |
+
$custom_logo_id = get_theme_mod( 'custom_logo' );
|
| 811 |
+
$schema_img = array();
|
| 812 |
+
|
| 813 |
+
if ( has_custom_logo() && $custom_logo_id ) {
|
| 814 |
+
$custom_logo_img = wp_get_attachment_image_src( $custom_logo_id, array( $max_logo_width, $max_logo_height ), false );
|
| 815 |
+
if ( $custom_logo_img ) {
|
| 816 |
+
// @todo Warning: The width/height returned may not actually be physically the $max_logo_width and $max_logo_height for the image returned.
|
| 817 |
+
$schema_img = array(
|
| 818 |
+
'url' => $custom_logo_img[0],
|
| 819 |
+
'width' => $custom_logo_img[1],
|
| 820 |
+
'height' => $custom_logo_img[2],
|
| 821 |
+
);
|
| 822 |
+
}
|
| 823 |
+
}
|
| 824 |
+
|
| 825 |
+
// Try Site Icon, though it is not ideal because "The logo should be a rectangle, not a square." per <https://developers.google.com/search/docs/data-types/article#logo-guidelines>.
|
| 826 |
+
if ( empty( $schema_img['url'] ) ) {
|
| 827 |
+
/*
|
| 828 |
+
* Note that AMP_Post_Template::SITE_ICON_SIZE is used and not $max_logo_height because 32px is the largest
|
| 829 |
+
* size that is defined in \WP_Site_Icon::$site_icon_sizes which is less than 60px. It may be a good idea
|
| 830 |
+
* to add a site_icon_image_sizes filter which appends 60 to the list of sizes, but this will only help
|
| 831 |
+
* when adding a new site icon and it would be irrelevant when a custom logo is present, per above.
|
| 832 |
+
*/
|
| 833 |
+
$schema_img = array(
|
| 834 |
+
'url' => get_site_icon_url( AMP_Post_Template::SITE_ICON_SIZE ),
|
| 835 |
+
'width' => AMP_Post_Template::SITE_ICON_SIZE,
|
| 836 |
+
'height' => AMP_Post_Template::SITE_ICON_SIZE,
|
| 837 |
+
);
|
| 838 |
+
}
|
| 839 |
+
|
| 840 |
/**
|
| 841 |
+
* Filters the publisher logo URL in the schema.org data.
|
| 842 |
*
|
| 843 |
+
* Previously, this only filtered the Site Icon, as that was the only possible schema.org publisher logo.
|
| 844 |
+
* But the Custom Logo is now the preferred publisher logo, if it exists and its dimensions aren't too big.
|
| 845 |
*
|
| 846 |
* @since 0.3
|
|
|
|
| 847 |
*
|
| 848 |
+
* @param string $schema_img_url URL of the publisher logo, either the Custom Logo or the Site Icon.
|
| 849 |
*/
|
| 850 |
+
$filtered_schema_img_url = apply_filters( 'amp_site_icon_url', $schema_img['url'] );
|
| 851 |
+
if ( $filtered_schema_img_url !== $schema_img['url'] ) {
|
| 852 |
+
$schema_img['url'] = $filtered_schema_img_url;
|
| 853 |
+
unset( $schema_img['width'], $schema_img['height'] ); // Clear width/height since now unknown, and not required.
|
| 854 |
+
}
|
| 855 |
+
|
| 856 |
+
if ( ! empty( $schema_img['url'] ) ) {
|
| 857 |
+
$metadata['publisher']['logo'] = array_merge(
|
| 858 |
+
array(
|
| 859 |
+
'@type' => 'ImageObject',
|
| 860 |
+
),
|
| 861 |
+
$schema_img
|
| 862 |
);
|
| 863 |
}
|
| 864 |
|
| 930 |
<script type="application/ld+json"><?php echo wp_json_encode( $metadata ); ?></script>
|
| 931 |
<?php
|
| 932 |
}
|
| 933 |
+
|
| 934 |
+
/**
|
| 935 |
+
* Filters content and keeps only allowable HTML elements by amp-mustache.
|
| 936 |
+
*
|
| 937 |
+
* @see wp_kses()
|
| 938 |
+
* @since 1.0
|
| 939 |
+
*
|
| 940 |
+
* @param string $markup Markup to sanitize.
|
| 941 |
+
* @return string HTML markup with tags allowed by amp-mustache.
|
| 942 |
+
*/
|
| 943 |
+
function amp_wp_kses_mustache( $markup ) {
|
| 944 |
+
$amp_mustache_allowed_html_tags = array( 'strong', 'b', 'em', 'i', 'u', 's', 'small', 'mark', 'del', 'ins', 'sup', 'sub' );
|
| 945 |
+
return wp_kses( $markup, array_fill_keys( $amp_mustache_allowed_html_tags, array() ) );
|
| 946 |
+
}
|
|
@@ -2,6 +2,7 @@
|
|
| 2 |
/**
|
| 3 |
* Callbacks for adding content to an AMP template.
|
| 4 |
*
|
|
|
|
| 5 |
* @package AMP
|
| 6 |
*/
|
| 7 |
|
|
@@ -98,6 +99,12 @@ function amp_post_template_add_schemaorg_metadata() {
|
|
| 98 |
* @param AMP_Post_Template $amp_template Template.
|
| 99 |
*/
|
| 100 |
function amp_post_template_add_styles( $amp_template ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
$styles = $amp_template->get( 'post_amp_styles' );
|
| 102 |
if ( ! empty( $styles ) ) {
|
| 103 |
echo '/* Inline styles */' . PHP_EOL; // WPCS: XSS OK.
|
|
@@ -130,12 +137,3 @@ function amp_post_template_add_analytics_data() {
|
|
| 130 |
$analytics = amp_add_custom_analytics();
|
| 131 |
amp_print_analytics( $analytics );
|
| 132 |
}
|
| 133 |
-
|
| 134 |
-
/**
|
| 135 |
-
* Add generator metadata.
|
| 136 |
-
*
|
| 137 |
-
* @since 6.0
|
| 138 |
-
*/
|
| 139 |
-
function amp_add_generator_metadata() {
|
| 140 |
-
printf( '<meta name="generator" content="%s" />', esc_attr( 'AMP Plugin v' . AMP__VERSION ) );
|
| 141 |
-
}
|
| 2 |
/**
|
| 3 |
* Callbacks for adding content to an AMP template.
|
| 4 |
*
|
| 5 |
+
* @todo Rename this file from amp-post-template-actions.php to amp-post-template-functions.php.
|
| 6 |
* @package AMP
|
| 7 |
*/
|
| 8 |
|
| 99 |
* @param AMP_Post_Template $amp_template Template.
|
| 100 |
*/
|
| 101 |
function amp_post_template_add_styles( $amp_template ) {
|
| 102 |
+
$stylesheets = $amp_template->get( 'post_amp_stylesheets' );
|
| 103 |
+
if ( ! empty( $stylesheets ) ) {
|
| 104 |
+
echo '/* Inline stylesheets */' . PHP_EOL; // WPCS: XSS OK.
|
| 105 |
+
echo implode( '', $stylesheets ); // WPCS: XSS OK.
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
$styles = $amp_template->get( 'post_amp_styles' );
|
| 109 |
if ( ! empty( $styles ) ) {
|
| 110 |
echo '/* Inline styles */' . PHP_EOL; // WPCS: XSS OK.
|
| 137 |
$analytics = amp_add_custom_analytics();
|
| 138 |
amp_print_analytics( $analytics );
|
| 139 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -29,15 +29,22 @@ class AMP_Autoloader {
|
|
| 29 |
* @var string[]
|
| 30 |
*/
|
| 31 |
private static $_classmap = array(
|
|
|
|
| 32 |
'AMP_Theme_Support' => 'includes/class-amp-theme-support',
|
|
|
|
| 33 |
'AMP_Comment_Walker' => 'includes/class-amp-comment-walker',
|
| 34 |
'AMP_Template_Customizer' => 'includes/admin/class-amp-customizer',
|
| 35 |
'AMP_Post_Meta_Box' => 'includes/admin/class-amp-post-meta-box',
|
|
|
|
| 36 |
'AMP_Post_Type_Support' => 'includes/class-amp-post-type-support',
|
| 37 |
'AMP_Base_Embed_Handler' => 'includes/embeds/class-amp-base-embed-handler',
|
| 38 |
'AMP_DailyMotion_Embed_Handler' => 'includes/embeds/class-amp-dailymotion-embed',
|
| 39 |
'AMP_Facebook_Embed_Handler' => 'includes/embeds/class-amp-facebook-embed',
|
| 40 |
'AMP_Gallery_Embed_Handler' => 'includes/embeds/class-amp-gallery-embed',
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
'AMP_Instagram_Embed_Handler' => 'includes/embeds/class-amp-instagram-embed',
|
| 42 |
'AMP_Issuu_Embed_Handler' => 'includes/embeds/class-amp-issuu-embed-handler',
|
| 43 |
'AMP_Meetup_Embed_Handler' => 'includes/embeds/class-amp-meetup-embed-handler',
|
|
@@ -50,14 +57,14 @@ class AMP_Autoloader {
|
|
| 50 |
'AMP_Vimeo_Embed_Handler' => 'includes/embeds/class-amp-vimeo-embed',
|
| 51 |
'AMP_Vine_Embed_Handler' => 'includes/embeds/class-amp-vine-embed',
|
| 52 |
'AMP_YouTube_Embed_Handler' => 'includes/embeds/class-amp-youtube-embed',
|
| 53 |
-
'FastImage' => '
|
| 54 |
-
'WillWashburn\Stream\Exception\StreamBufferTooSmallException' => '
|
| 55 |
-
'WillWashburn\Stream\StreamableInterface' => '
|
| 56 |
-
'WillWashburn\Stream\Stream' => '
|
| 57 |
-
'FasterImage\Exception\InvalidImageException' => '
|
| 58 |
-
'FasterImage\ExifParser' => '
|
| 59 |
-
'FasterImage\ImageParser' => '
|
| 60 |
-
'FasterImage\FasterImage' => '
|
| 61 |
'AMP_Analytics_Options_Submenu' => 'includes/options/class-amp-analytics-options-submenu',
|
| 62 |
'AMP_Options_Menu' => 'includes/options/class-amp-options-menu',
|
| 63 |
'AMP_Options_Manager' => 'includes/options/class-amp-options-manager',
|
|
@@ -68,14 +75,20 @@ class AMP_Autoloader {
|
|
| 68 |
'AMP_Audio_Sanitizer' => 'includes/sanitizers/class-amp-audio-sanitizer',
|
| 69 |
'AMP_Base_Sanitizer' => 'includes/sanitizers/class-amp-base-sanitizer',
|
| 70 |
'AMP_Blacklist_Sanitizer' => 'includes/sanitizers/class-amp-blacklist-sanitizer',
|
|
|
|
|
|
|
| 71 |
'AMP_Iframe_Sanitizer' => 'includes/sanitizers/class-amp-iframe-sanitizer',
|
| 72 |
'AMP_Img_Sanitizer' => 'includes/sanitizers/class-amp-img-sanitizer',
|
| 73 |
'AMP_Comments_Sanitizer' => 'includes/sanitizers/class-amp-comments-sanitizer',
|
| 74 |
'AMP_Form_Sanitizer' => 'includes/sanitizers/class-amp-form-sanitizer',
|
|
|
|
| 75 |
'AMP_Playbuzz_Sanitizer' => 'includes/sanitizers/class-amp-playbuzz-sanitizer',
|
| 76 |
'AMP_Style_Sanitizer' => 'includes/sanitizers/class-amp-style-sanitizer',
|
|
|
|
|
|
|
| 77 |
'AMP_Tag_And_Attribute_Sanitizer' => 'includes/sanitizers/class-amp-tag-and-attribute-sanitizer',
|
| 78 |
'AMP_Video_Sanitizer' => 'includes/sanitizers/class-amp-video-sanitizer',
|
|
|
|
| 79 |
'AMP_Customizer_Design_Settings' => 'includes/settings/class-amp-customizer-design-settings',
|
| 80 |
'AMP_Customizer_Settings' => 'includes/settings/class-amp-customizer-settings',
|
| 81 |
'AMP_Content' => 'includes/templates/class-amp-content',
|
|
@@ -84,13 +97,14 @@ class AMP_Autoloader {
|
|
| 84 |
'AMP_DOM_Utils' => 'includes/utils/class-amp-dom-utils',
|
| 85 |
'AMP_HTML_Utils' => 'includes/utils/class-amp-html-utils',
|
| 86 |
'AMP_Image_Dimension_Extractor' => 'includes/utils/class-amp-image-dimension-extractor',
|
| 87 |
-
'
|
|
|
|
|
|
|
|
|
|
| 88 |
'AMP_String_Utils' => 'includes/utils/class-amp-string-utils',
|
| 89 |
'AMP_WP_Utils' => 'includes/utils/class-amp-wp-utils',
|
| 90 |
'AMP_Widget_Archives' => 'includes/widgets/class-amp-widget-archives',
|
| 91 |
'AMP_Widget_Categories' => 'includes/widgets/class-amp-widget-categories',
|
| 92 |
-
'AMP_Widget_Media_Video' => 'includes/widgets/class-amp-widget-media-video',
|
| 93 |
-
'AMP_Widget_Recent_Comments' => 'includes/widgets/class-amp-widget-recent-comments',
|
| 94 |
'AMP_Widget_Text' => 'includes/widgets/class-amp-widget-text',
|
| 95 |
'WPCOM_AMP_Polldaddy_Embed' => 'wpcom/class-amp-polldaddy-embed',
|
| 96 |
'AMP_Test_Stub_Sanitizer' => 'tests/stubs',
|
|
@@ -129,6 +143,10 @@ class AMP_Autoloader {
|
|
| 129 |
* Called at the end of this file; calling a second time has no effect.
|
| 130 |
*/
|
| 131 |
public static function register() {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
if ( ! self::$is_registered ) {
|
| 133 |
spl_autoload_register( array( __CLASS__, 'autoload' ) );
|
| 134 |
self::$is_registered = true;
|
| 29 |
* @var string[]
|
| 30 |
*/
|
| 31 |
private static $_classmap = array(
|
| 32 |
+
'AMP_Editor_Blocks' => 'includes/admin/class-amp-editor-blocks',
|
| 33 |
'AMP_Theme_Support' => 'includes/class-amp-theme-support',
|
| 34 |
+
'AMP_HTTP' => 'includes/class-amp-http',
|
| 35 |
'AMP_Comment_Walker' => 'includes/class-amp-comment-walker',
|
| 36 |
'AMP_Template_Customizer' => 'includes/admin/class-amp-customizer',
|
| 37 |
'AMP_Post_Meta_Box' => 'includes/admin/class-amp-post-meta-box',
|
| 38 |
+
'AMP_Admin_Pointer' => 'includes/admin/class-amp-admin-pointer',
|
| 39 |
'AMP_Post_Type_Support' => 'includes/class-amp-post-type-support',
|
| 40 |
'AMP_Base_Embed_Handler' => 'includes/embeds/class-amp-base-embed-handler',
|
| 41 |
'AMP_DailyMotion_Embed_Handler' => 'includes/embeds/class-amp-dailymotion-embed',
|
| 42 |
'AMP_Facebook_Embed_Handler' => 'includes/embeds/class-amp-facebook-embed',
|
| 43 |
'AMP_Gallery_Embed_Handler' => 'includes/embeds/class-amp-gallery-embed',
|
| 44 |
+
'AMP_Gfycat_Embed_Handler' => 'includes/embeds/class-amp-gfycat-embed-handler',
|
| 45 |
+
'AMP_Hulu_Embed_Handler' => 'includes/embeds/class-amp-hulu-embed-handler',
|
| 46 |
+
'AMP_Imgur_Embed_Handler' => 'includes/embeds/class-amp-imgur-embed-handler',
|
| 47 |
+
'AMP_Core_Block_Handler' => 'includes/embeds/class-amp-core-block-handler',
|
| 48 |
'AMP_Instagram_Embed_Handler' => 'includes/embeds/class-amp-instagram-embed',
|
| 49 |
'AMP_Issuu_Embed_Handler' => 'includes/embeds/class-amp-issuu-embed-handler',
|
| 50 |
'AMP_Meetup_Embed_Handler' => 'includes/embeds/class-amp-meetup-embed-handler',
|
| 57 |
'AMP_Vimeo_Embed_Handler' => 'includes/embeds/class-amp-vimeo-embed',
|
| 58 |
'AMP_Vine_Embed_Handler' => 'includes/embeds/class-amp-vine-embed',
|
| 59 |
'AMP_YouTube_Embed_Handler' => 'includes/embeds/class-amp-youtube-embed',
|
| 60 |
+
'FastImage' => 'third_party/fastimage/class-fastimage',
|
| 61 |
+
'WillWashburn\Stream\Exception\StreamBufferTooSmallException' => 'third_party/fasterimage/Stream/Exception/StreamBufferTooSmallException',
|
| 62 |
+
'WillWashburn\Stream\StreamableInterface' => 'third_party/fasterimage/Stream/StreamableInterface',
|
| 63 |
+
'WillWashburn\Stream\Stream' => 'third_party/fasterimage/Stream/Stream',
|
| 64 |
+
'FasterImage\Exception\InvalidImageException' => 'third_party/fasterimage/Exception/InvalidImageException',
|
| 65 |
+
'FasterImage\ExifParser' => 'third_party/fasterimage/ExifParser',
|
| 66 |
+
'FasterImage\ImageParser' => 'third_party/fasterimage/ImageParser',
|
| 67 |
+
'FasterImage\FasterImage' => 'third_party/fasterimage/FasterImage',
|
| 68 |
'AMP_Analytics_Options_Submenu' => 'includes/options/class-amp-analytics-options-submenu',
|
| 69 |
'AMP_Options_Menu' => 'includes/options/class-amp-options-menu',
|
| 70 |
'AMP_Options_Manager' => 'includes/options/class-amp-options-manager',
|
| 75 |
'AMP_Audio_Sanitizer' => 'includes/sanitizers/class-amp-audio-sanitizer',
|
| 76 |
'AMP_Base_Sanitizer' => 'includes/sanitizers/class-amp-base-sanitizer',
|
| 77 |
'AMP_Blacklist_Sanitizer' => 'includes/sanitizers/class-amp-blacklist-sanitizer',
|
| 78 |
+
'AMP_Block_Sanitizer' => 'includes/sanitizers/class-amp-block-sanitizer',
|
| 79 |
+
'AMP_Gallery_Block_Sanitizer' => 'includes/sanitizers/class-amp-gallery-block-sanitizer',
|
| 80 |
'AMP_Iframe_Sanitizer' => 'includes/sanitizers/class-amp-iframe-sanitizer',
|
| 81 |
'AMP_Img_Sanitizer' => 'includes/sanitizers/class-amp-img-sanitizer',
|
| 82 |
'AMP_Comments_Sanitizer' => 'includes/sanitizers/class-amp-comments-sanitizer',
|
| 83 |
'AMP_Form_Sanitizer' => 'includes/sanitizers/class-amp-form-sanitizer',
|
| 84 |
+
'AMP_O2_Player_Sanitizer' => 'includes/sanitizers/class-amp-o2-player-sanitizer',
|
| 85 |
'AMP_Playbuzz_Sanitizer' => 'includes/sanitizers/class-amp-playbuzz-sanitizer',
|
| 86 |
'AMP_Style_Sanitizer' => 'includes/sanitizers/class-amp-style-sanitizer',
|
| 87 |
+
'AMP_Script_Sanitizer' => 'includes/sanitizers/class-amp-script-sanitizer',
|
| 88 |
+
'AMP_Embed_Sanitizer' => 'includes/sanitizers/class-amp-embed-sanitizer',
|
| 89 |
'AMP_Tag_And_Attribute_Sanitizer' => 'includes/sanitizers/class-amp-tag-and-attribute-sanitizer',
|
| 90 |
'AMP_Video_Sanitizer' => 'includes/sanitizers/class-amp-video-sanitizer',
|
| 91 |
+
'AMP_Core_Theme_Sanitizer' => 'includes/sanitizers/class-amp-core-theme-sanitizer',
|
| 92 |
'AMP_Customizer_Design_Settings' => 'includes/settings/class-amp-customizer-design-settings',
|
| 93 |
'AMP_Customizer_Settings' => 'includes/settings/class-amp-customizer-settings',
|
| 94 |
'AMP_Content' => 'includes/templates/class-amp-content',
|
| 97 |
'AMP_DOM_Utils' => 'includes/utils/class-amp-dom-utils',
|
| 98 |
'AMP_HTML_Utils' => 'includes/utils/class-amp-html-utils',
|
| 99 |
'AMP_Image_Dimension_Extractor' => 'includes/utils/class-amp-image-dimension-extractor',
|
| 100 |
+
'AMP_Validation_Manager' => 'includes/validation/class-amp-validation-manager',
|
| 101 |
+
'AMP_Validated_URL_Post_Type' => 'includes/validation/class-amp-validated-url-post-type',
|
| 102 |
+
'AMP_Validation_Error_Taxonomy' => 'includes/validation/class-amp-validation-error-taxonomy',
|
| 103 |
+
'AMP_CLI' => 'includes/class-amp-cli',
|
| 104 |
'AMP_String_Utils' => 'includes/utils/class-amp-string-utils',
|
| 105 |
'AMP_WP_Utils' => 'includes/utils/class-amp-wp-utils',
|
| 106 |
'AMP_Widget_Archives' => 'includes/widgets/class-amp-widget-archives',
|
| 107 |
'AMP_Widget_Categories' => 'includes/widgets/class-amp-widget-categories',
|
|
|
|
|
|
|
| 108 |
'AMP_Widget_Text' => 'includes/widgets/class-amp-widget-text',
|
| 109 |
'WPCOM_AMP_Polldaddy_Embed' => 'wpcom/class-amp-polldaddy-embed',
|
| 110 |
'AMP_Test_Stub_Sanitizer' => 'tests/stubs',
|
| 143 |
* Called at the end of this file; calling a second time has no effect.
|
| 144 |
*/
|
| 145 |
public static function register() {
|
| 146 |
+
if ( file_exists( AMP__DIR__ . '/vendor/autoload.php' ) ) {
|
| 147 |
+
require_once AMP__DIR__ . '/vendor/autoload.php';
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
if ( ! self::$is_registered ) {
|
| 151 |
spl_autoload_register( array( __CLASS__, 'autoload' ) );
|
| 152 |
self::$is_registered = true;
|
|
@@ -0,0 +1,680 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_CLI
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Class AMP_CLI
|
| 10 |
+
*
|
| 11 |
+
* Registers and implements a WP-CLI command to crawl the entire site for AMP validity.
|
| 12 |
+
* To use this, run: wp amp validate-site.
|
| 13 |
+
*
|
| 14 |
+
* @since 1.0
|
| 15 |
+
*/
|
| 16 |
+
class AMP_CLI {
|
| 17 |
+
|
| 18 |
+
/**
|
| 19 |
+
* The WP-CLI flag to force validation.
|
| 20 |
+
*
|
| 21 |
+
* By default, the WP-CLI command does not validate templates that the user has opted-out of.
|
| 22 |
+
* For example, by unchecking 'Categories' in 'AMP Settings' > 'Supported Templates'.
|
| 23 |
+
* But with this flag, validation will ignore these options.
|
| 24 |
+
*
|
| 25 |
+
* @var string
|
| 26 |
+
*/
|
| 27 |
+
const FLAG_NAME_FORCE_VALIDATION = 'force';
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* The WP-CLI argument to validate based on certain conditionals
|
| 31 |
+
*
|
| 32 |
+
* For example, --include=is_tag,is_author
|
| 33 |
+
* Normally, this script will validate all of the templates that don't have AMP disabled.
|
| 34 |
+
* But this allows validating only specific templates.
|
| 35 |
+
*
|
| 36 |
+
* @var string
|
| 37 |
+
*/
|
| 38 |
+
const INCLUDE_ARGUMENT = 'include';
|
| 39 |
+
|
| 40 |
+
/**
|
| 41 |
+
* The WP-CLI argument for the maximum URLs to validate for each type.
|
| 42 |
+
*
|
| 43 |
+
* If this is passed in the command,
|
| 44 |
+
* it overrides the value of self::$maximum_urls_to_validate_for_each_type.
|
| 45 |
+
*
|
| 46 |
+
* @var string
|
| 47 |
+
*/
|
| 48 |
+
const LIMIT_URLS_ARGUMENT = 'limit';
|
| 49 |
+
|
| 50 |
+
/**
|
| 51 |
+
* The WP CLI progress bar.
|
| 52 |
+
*
|
| 53 |
+
* @see https://make.wordpress.org/cli/handbook/internal-api/wp-cli-utils-make-progress-bar/
|
| 54 |
+
* @var \cli\progress\Bar|\WP_CLI\NoOp
|
| 55 |
+
*/
|
| 56 |
+
public static $wp_cli_progress;
|
| 57 |
+
|
| 58 |
+
/**
|
| 59 |
+
* The total number of validation errors, regardless of whether they were accepted.
|
| 60 |
+
*
|
| 61 |
+
* @var int
|
| 62 |
+
*/
|
| 63 |
+
public static $total_errors = 0;
|
| 64 |
+
|
| 65 |
+
/**
|
| 66 |
+
* The total number of unaccepted validation errors.
|
| 67 |
+
*
|
| 68 |
+
* If an error has been accepted in the /wp-admin validation UI,
|
| 69 |
+
* it won't count toward this.
|
| 70 |
+
*
|
| 71 |
+
* @var int
|
| 72 |
+
*/
|
| 73 |
+
public static $unaccepted_errors = 0;
|
| 74 |
+
|
| 75 |
+
/**
|
| 76 |
+
* The number of URLs crawled, regardless of whether they have validation errors.
|
| 77 |
+
*
|
| 78 |
+
* @var int
|
| 79 |
+
*/
|
| 80 |
+
public static $number_crawled = 0;
|
| 81 |
+
|
| 82 |
+
/**
|
| 83 |
+
* Whether to force crawling of URLs.
|
| 84 |
+
*
|
| 85 |
+
* By default, this script only crawls URLs that support AMP,
|
| 86 |
+
* where the user has not opted-out of AMP for the URL.
|
| 87 |
+
* For example, by un-checking 'Posts' in 'AMP Settings' > 'Supported Templates'.
|
| 88 |
+
* Or un-checking 'Enable AMP' in the post's editor.
|
| 89 |
+
*
|
| 90 |
+
* @var int
|
| 91 |
+
*/
|
| 92 |
+
public static $force_crawl_urls = false;
|
| 93 |
+
|
| 94 |
+
/**
|
| 95 |
+
* A whitelist of conditionals to use for validation.
|
| 96 |
+
*
|
| 97 |
+
* Usually, this script will validate all of the templates that don't have AMP disabled.
|
| 98 |
+
* But this allows validating based on only these conditionals.
|
| 99 |
+
* This is set if the WP-CLI command has an --include argument.
|
| 100 |
+
*
|
| 101 |
+
* @var array
|
| 102 |
+
*/
|
| 103 |
+
public static $include_conditionals = array();
|
| 104 |
+
|
| 105 |
+
/**
|
| 106 |
+
* The maximum number of URLs to validate for each type.
|
| 107 |
+
*
|
| 108 |
+
* Templates are each a separate type, like those for is_category() and is_tag().
|
| 109 |
+
* Also, each post type is a separate type.
|
| 110 |
+
* This value is overridden if the WP-CLI command has an --limit argument, like --limit=10.
|
| 111 |
+
*
|
| 112 |
+
* @var int
|
| 113 |
+
*/
|
| 114 |
+
public static $limit_type_validate_count;
|
| 115 |
+
|
| 116 |
+
/**
|
| 117 |
+
* The validation counts by type, like template or post type.
|
| 118 |
+
*
|
| 119 |
+
* @var array[][] {
|
| 120 |
+
* Validity by type.
|
| 121 |
+
*
|
| 122 |
+
* @type int $valid The number of valid URLs for this type.
|
| 123 |
+
* @type int $total The total number of URLs for this type, valid or invalid.
|
| 124 |
+
* }
|
| 125 |
+
*/
|
| 126 |
+
public static $validity_by_type = array();
|
| 127 |
+
|
| 128 |
+
/**
|
| 129 |
+
* Crawl the entire site to get AMP validation results.
|
| 130 |
+
*
|
| 131 |
+
* ## OPTIONS
|
| 132 |
+
*
|
| 133 |
+
* [--limit=<count>]
|
| 134 |
+
* : The maximum number of URLs to validate for each template and content type.
|
| 135 |
+
* ---
|
| 136 |
+
* default: 100
|
| 137 |
+
* ---
|
| 138 |
+
*
|
| 139 |
+
* [--include=<templates>]
|
| 140 |
+
* : Only validates a URL if one of the conditionals is true.
|
| 141 |
+
*
|
| 142 |
+
* [--force]
|
| 143 |
+
* : Force validation of URLs even if their associated templates or object types do not have AMP enabled.
|
| 144 |
+
*
|
| 145 |
+
* ## EXAMPLES
|
| 146 |
+
*
|
| 147 |
+
* wp amp validate-site --include=is_author,is_tag
|
| 148 |
+
*
|
| 149 |
+
* @subcommand validate-site
|
| 150 |
+
* @param array $args Positional args.
|
| 151 |
+
* @param array $assoc_args Associative args.
|
| 152 |
+
* @throws Exception If an error happens.
|
| 153 |
+
*/
|
| 154 |
+
public function validate_site( $args, $assoc_args ) {
|
| 155 |
+
unset( $args );
|
| 156 |
+
self::$include_conditionals = array();
|
| 157 |
+
self::$force_crawl_urls = false;
|
| 158 |
+
self::$limit_type_validate_count = (int) $assoc_args[ self::LIMIT_URLS_ARGUMENT ];
|
| 159 |
+
|
| 160 |
+
/*
|
| 161 |
+
* Handle the argument and flag passed to the command: --include and --force.
|
| 162 |
+
* If the self::INCLUDE_ARGUMENT is present, force crawling or URLs.
|
| 163 |
+
* The WP-CLI command should indicate which templates are crawled, not the /wp-admin options.
|
| 164 |
+
*/
|
| 165 |
+
if ( ! empty( $assoc_args[ self::INCLUDE_ARGUMENT ] ) ) {
|
| 166 |
+
self::$include_conditionals = explode( ',', $assoc_args[ self::INCLUDE_ARGUMENT ] );
|
| 167 |
+
self::$force_crawl_urls = true;
|
| 168 |
+
} elseif ( isset( $assoc_args[ self::FLAG_NAME_FORCE_VALIDATION ] ) ) {
|
| 169 |
+
self::$force_crawl_urls = true;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) {
|
| 173 |
+
if ( self::$force_crawl_urls ) {
|
| 174 |
+
/*
|
| 175 |
+
* There is no theme support added programmatically or via options.
|
| 176 |
+
* So make sure that theme support is present so that AMP_Validation_Manager::validate_url()
|
| 177 |
+
* will use a canonical URL as the basis for obtaining validation results.
|
| 178 |
+
*/
|
| 179 |
+
add_theme_support( AMP_Theme_Support::SLUG );
|
| 180 |
+
} else {
|
| 181 |
+
WP_CLI::error(
|
| 182 |
+
sprintf(
|
| 183 |
+
/* translators: %s is the flag to force validation */
|
| 184 |
+
__( 'The current template mode is Classic, which does not allow crawling the site. Please pass the --%s flag in order to force crawling for validation.', 'amp' ),
|
| 185 |
+
self::FLAG_NAME_FORCE_VALIDATION
|
| 186 |
+
)
|
| 187 |
+
);
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
$number_urls_to_crawl = self::count_urls_to_validate();
|
| 192 |
+
if ( ! $number_urls_to_crawl ) {
|
| 193 |
+
if ( ! empty( self::$include_conditionals ) ) {
|
| 194 |
+
WP_CLI::error(
|
| 195 |
+
sprintf(
|
| 196 |
+
/* translators: %s is the command line argument to include certain templates */
|
| 197 |
+
__( 'The templates passed via the --%s argument did not match any URLs. You might try passing different templates to it.', 'amp' ),
|
| 198 |
+
self::INCLUDE_ARGUMENT
|
| 199 |
+
)
|
| 200 |
+
);
|
| 201 |
+
} else {
|
| 202 |
+
WP_CLI::error(
|
| 203 |
+
sprintf(
|
| 204 |
+
/* translators: %s is the command line argument to force validation */
|
| 205 |
+
__( 'All of your templates might be unchecked in AMP Settings > Supported Templates. You might pass --%s to this command.', 'amp' ),
|
| 206 |
+
self::FLAG_NAME_FORCE_VALIDATION
|
| 207 |
+
)
|
| 208 |
+
);
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
WP_CLI::log( __( 'Crawling the site for AMP validity.', 'amp' ) );
|
| 213 |
+
|
| 214 |
+
self::$wp_cli_progress = WP_CLI\Utils\make_progress_bar(
|
| 215 |
+
/* translators: %d is the number of URLs */
|
| 216 |
+
sprintf( __( 'Validating %d URLs...', 'amp' ), $number_urls_to_crawl ),
|
| 217 |
+
$number_urls_to_crawl
|
| 218 |
+
);
|
| 219 |
+
self::crawl_site();
|
| 220 |
+
self::$wp_cli_progress->finish();
|
| 221 |
+
|
| 222 |
+
$key_template_type = __( 'Template or content type', 'amp' );
|
| 223 |
+
$key_url_count = __( 'URL Count', 'amp' );
|
| 224 |
+
$key_validity_rate = __( 'Validity Rate', 'amp' );
|
| 225 |
+
|
| 226 |
+
$table_validation_by_type = array();
|
| 227 |
+
foreach ( self::$validity_by_type as $type_name => $validity ) {
|
| 228 |
+
$table_validation_by_type[] = array(
|
| 229 |
+
$key_template_type => $type_name,
|
| 230 |
+
$key_url_count => $validity['total'],
|
| 231 |
+
$key_validity_rate => sprintf( '%d%%', 100.0 * ( $validity['valid'] / $validity['total'] ) ),
|
| 232 |
+
);
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
if ( empty( $table_validation_by_type ) ) {
|
| 236 |
+
WP_CLI::error( __( 'No validation results were obtained from the URLs.', 'amp' ) );
|
| 237 |
+
return;
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
WP_CLI::success(
|
| 241 |
+
sprintf(
|
| 242 |
+
/* translators: $1%d is the number of URls crawled, $2%d is the number of validation issues, $3%d is the number of unaccepted issues, $4%s is the list of validation by type, $5%s is the link for more details */
|
| 243 |
+
__( '%3$d crawled URLs have unaccepted issue(s) out of %2$d total with AMP validation issue(s); %1$d URLs were crawled.', 'amp' ),
|
| 244 |
+
self::$number_crawled,
|
| 245 |
+
self::$total_errors,
|
| 246 |
+
self::$unaccepted_errors
|
| 247 |
+
)
|
| 248 |
+
);
|
| 249 |
+
|
| 250 |
+
// Output a table of validity by template/content type.
|
| 251 |
+
WP_CLI\Utils\format_items(
|
| 252 |
+
'table',
|
| 253 |
+
$table_validation_by_type,
|
| 254 |
+
array( $key_template_type, $key_url_count, $key_validity_rate )
|
| 255 |
+
);
|
| 256 |
+
|
| 257 |
+
$url_more_details = add_query_arg(
|
| 258 |
+
'post_type',
|
| 259 |
+
AMP_Validated_URL_Post_Type::POST_TYPE_SLUG,
|
| 260 |
+
admin_url( 'edit.php' )
|
| 261 |
+
);
|
| 262 |
+
/* translators: %s is the URL to the admin */
|
| 263 |
+
WP_CLI::line( sprintf( __( 'For more details, please see: %s', 'amp' ), $url_more_details ) );
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
/**
|
| 267 |
+
* Reset all validation data on a site.
|
| 268 |
+
*
|
| 269 |
+
* This deletes all amp_validated_url posts and all amp_validation_error terms.
|
| 270 |
+
*
|
| 271 |
+
* ## OPTIONS
|
| 272 |
+
*
|
| 273 |
+
* [--yes]
|
| 274 |
+
* : Proceed to empty the site validation data without a confirmation prompt.
|
| 275 |
+
*
|
| 276 |
+
* ## EXAMPLES
|
| 277 |
+
*
|
| 278 |
+
* wp amp reset-site-validation --yes
|
| 279 |
+
*
|
| 280 |
+
* @subcommand reset-site-validation
|
| 281 |
+
* @param array $args Positional args. Unused.
|
| 282 |
+
* @param array $assoc_args Associative args.
|
| 283 |
+
* @throws Exception If an error happens.
|
| 284 |
+
*/
|
| 285 |
+
public function reset_site_validation( $args, $assoc_args ) {
|
| 286 |
+
unset( $args );
|
| 287 |
+
global $wpdb;
|
| 288 |
+
WP_CLI::confirm( 'Are you sure you want to empty all amp_validated_url posts and amp_validation_error taxonomy terms?', $assoc_args );
|
| 289 |
+
|
| 290 |
+
// Delete all posts.
|
| 291 |
+
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = %s", AMP_Validated_URL_Post_Type::POST_TYPE_SLUG ) );
|
| 292 |
+
$query = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = %s", AMP_Validated_URL_Post_Type::POST_TYPE_SLUG );
|
| 293 |
+
$posts = new WP_CLI\Iterators\Query( $query, 10000 );
|
| 294 |
+
|
| 295 |
+
$progress = WP_CLI\Utils\make_progress_bar(
|
| 296 |
+
/* translators: %d is the number of posts */
|
| 297 |
+
sprintf( __( 'Deleting %d amp_validated_url posts...', 'amp' ), $count ),
|
| 298 |
+
$count
|
| 299 |
+
);
|
| 300 |
+
while ( $posts->valid() ) {
|
| 301 |
+
$post_id = $posts->current()->ID;
|
| 302 |
+
$posts->next();
|
| 303 |
+
wp_delete_post( $post_id, true );
|
| 304 |
+
$progress->tick();
|
| 305 |
+
}
|
| 306 |
+
$progress->finish();
|
| 307 |
+
|
| 308 |
+
// Delete all terms. Note that many terms should get deleted when their post counts go to zero above.
|
| 309 |
+
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( * ) FROM $wpdb->term_taxonomy WHERE taxonomy = %s", AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG ) );
|
| 310 |
+
$query = $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE taxonomy = %s", AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG );
|
| 311 |
+
$terms = new WP_CLI\Iterators\Query( $query, 10000 );
|
| 312 |
+
|
| 313 |
+
$progress = WP_CLI\Utils\make_progress_bar(
|
| 314 |
+
/* translators: %d is the number of terms */
|
| 315 |
+
sprintf( __( 'Deleting %d amp_taxonomy_error terms...', 'amp' ), $count ),
|
| 316 |
+
$count
|
| 317 |
+
);
|
| 318 |
+
while ( $terms->valid() ) {
|
| 319 |
+
$term_id = $terms->current()->term_id;
|
| 320 |
+
$terms->next();
|
| 321 |
+
wp_delete_term( $term_id, AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG );
|
| 322 |
+
$progress->tick();
|
| 323 |
+
}
|
| 324 |
+
$progress->finish();
|
| 325 |
+
|
| 326 |
+
WP_CLI::success( 'All AMP validation data has been removed.' );
|
| 327 |
+
}
|
| 328 |
+
|
| 329 |
+
/**
|
| 330 |
+
* Gets the total number of URLs to validate.
|
| 331 |
+
*
|
| 332 |
+
* By default, this only counts AMP-enabled posts and terms.
|
| 333 |
+
* But if $force_crawl_urls is true, it counts all of them, regardless of their AMP status.
|
| 334 |
+
* It also uses self::$maximum_urls_to_validate_for_each_type,
|
| 335 |
+
* which can be overridden with a command line argument.
|
| 336 |
+
*
|
| 337 |
+
* @return int The number of URLs to validate.
|
| 338 |
+
*/
|
| 339 |
+
public static function count_urls_to_validate() {
|
| 340 |
+
/*
|
| 341 |
+
* If the homepage is set to 'Your latest posts,' start the $total_count at 1.
|
| 342 |
+
* Otherwise, it will probably be counted in the query for pages below.
|
| 343 |
+
*/
|
| 344 |
+
$total_count = 'posts' === get_option( 'show_on_front' ) && self::is_template_supported( 'is_home' ) ? 1 : 0;
|
| 345 |
+
|
| 346 |
+
$amp_enabled_taxonomies = array_filter(
|
| 347 |
+
get_taxonomies( array( 'public' => true ) ),
|
| 348 |
+
array( 'AMP_CLI', 'does_taxonomy_support_amp' )
|
| 349 |
+
);
|
| 350 |
+
|
| 351 |
+
// Count all public taxonomy terms.
|
| 352 |
+
foreach ( $amp_enabled_taxonomies as $taxonomy ) {
|
| 353 |
+
$term_query = new WP_Term_Query( array(
|
| 354 |
+
'taxonomy' => $taxonomy,
|
| 355 |
+
'fields' => 'ids',
|
| 356 |
+
'number' => self::$limit_type_validate_count,
|
| 357 |
+
) );
|
| 358 |
+
|
| 359 |
+
// If $term_query->terms is an empty array, passing it to count() will throw an error.
|
| 360 |
+
$total_count += ! empty( $term_query->terms ) ? count( $term_query->terms ) : 0;
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
// Count posts by type, like post, page, attachment, etc.
|
| 364 |
+
$public_post_types = get_post_types( array( 'public' => true ), 'names' );
|
| 365 |
+
foreach ( $public_post_types as $post_type ) {
|
| 366 |
+
$posts = self::get_posts_that_support_amp( self::get_posts_by_type( $post_type ) );
|
| 367 |
+
$total_count += ! empty( $posts ) ? count( $posts ) : 0;
|
| 368 |
+
}
|
| 369 |
+
|
| 370 |
+
// Count author pages, like https://example.com/author/admin/.
|
| 371 |
+
$total_count += count( self::get_author_page_urls() );
|
| 372 |
+
|
| 373 |
+
// Count a single example date page, like https://example.com/?year=2019.
|
| 374 |
+
if ( self::get_date_page() ) {
|
| 375 |
+
$total_count++;
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
// Count a single example search page, like https://example.com/?s=example.
|
| 379 |
+
if ( self::get_search_page() ) {
|
| 380 |
+
$total_count++;
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
return $total_count;
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
/**
|
| 387 |
+
* Gets the posts IDs that support AMP.
|
| 388 |
+
*
|
| 389 |
+
* By default, this only gets the post IDs if they support AMP.
|
| 390 |
+
* This means that 'Posts' isn't deselected in 'AMP Settings' > 'Supported Templates'.
|
| 391 |
+
* And 'Enable AMP' isn't unchecked in the post's editor.
|
| 392 |
+
* But if $force_crawl_urls is true, this simply returns all of the IDs.
|
| 393 |
+
*
|
| 394 |
+
* @param array $ids THe post IDs to check for AMP support.
|
| 395 |
+
* @return array The post IDs that support AMP, or an empty array.
|
| 396 |
+
*/
|
| 397 |
+
public static function get_posts_that_support_amp( $ids ) {
|
| 398 |
+
if ( ! self::is_template_supported( 'is_singular' ) ) {
|
| 399 |
+
return array();
|
| 400 |
+
}
|
| 401 |
+
|
| 402 |
+
if ( self::$force_crawl_urls ) {
|
| 403 |
+
return $ids;
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
return array_filter(
|
| 407 |
+
$ids,
|
| 408 |
+
function( $id ) {
|
| 409 |
+
return post_supports_amp( $id );
|
| 410 |
+
}
|
| 411 |
+
);
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
/**
|
| 415 |
+
* Gets whether the taxonomy supports AMP.
|
| 416 |
+
*
|
| 417 |
+
* This only gets the term IDs if they support AMP.
|
| 418 |
+
* If their taxonomy is unchecked in 'AMP Settings' > 'Supported Templates,' this does not return them.
|
| 419 |
+
* For example, if 'Categories' is unchecked.
|
| 420 |
+
* This can be overridden by passing the self::FLAG_NAME_FORCE_VALIDATION argument to the WP-CLI command.
|
| 421 |
+
*
|
| 422 |
+
* @param string $taxonomy The taxonomy.
|
| 423 |
+
* @return boolean Whether the taxonomy supports AMP.
|
| 424 |
+
*/
|
| 425 |
+
public static function does_taxonomy_support_amp( $taxonomy ) {
|
| 426 |
+
if ( 'post_tag' === $taxonomy ) {
|
| 427 |
+
$taxonomy = 'tag';
|
| 428 |
+
}
|
| 429 |
+
$taxonomy_key = 'is_' . $taxonomy;
|
| 430 |
+
$custom_taxonomy_key = sprintf( 'is_tax[%s]', $taxonomy );
|
| 431 |
+
return self::is_template_supported( $taxonomy_key ) || self::is_template_supported( $custom_taxonomy_key );
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
/**
|
| 435 |
+
* Gets whether the template is supported.
|
| 436 |
+
*
|
| 437 |
+
* If the user has passed an include argument to the WP-CLI command, use that to find if this template supports AMP.
|
| 438 |
+
* For example, wp amp validate-site --include=is_tag,is_category
|
| 439 |
+
* would return true only if is_tag() or is_category().
|
| 440 |
+
* But passing the self::FLAG_NAME_FORCE_VALIDATION argument to the WP-CLI command overrides this.
|
| 441 |
+
*
|
| 442 |
+
* @param string $template The template to check.
|
| 443 |
+
* @return bool Whether the template is supported.
|
| 444 |
+
*/
|
| 445 |
+
public static function is_template_supported( $template ) {
|
| 446 |
+
// If the --include argument is present in the WP-CLI command, this template conditional must be present in it.
|
| 447 |
+
if ( ! empty( self::$include_conditionals ) ) {
|
| 448 |
+
return in_array( $template, self::$include_conditionals, true );
|
| 449 |
+
}
|
| 450 |
+
if ( self::$force_crawl_urls ) {
|
| 451 |
+
return true;
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
$supportable_templates = AMP_Theme_Support::get_supportable_templates();
|
| 455 |
+
|
| 456 |
+
// Check whether this taxonomy's template is supported, including in the 'AMP Settings' > 'Supported Templates' UI.
|
| 457 |
+
return ! empty( $supportable_templates[ $template ]['supported'] );
|
| 458 |
+
}
|
| 459 |
+
|
| 460 |
+
/**
|
| 461 |
+
* Gets the IDs of public, published posts.
|
| 462 |
+
*
|
| 463 |
+
* @param string $post_type The post type.
|
| 464 |
+
* @param int|null $offset The offset of the query (optional).
|
| 465 |
+
* @param int|null $number The number of posts to query for (optional).
|
| 466 |
+
* @return int[] $post_ids The post IDs in an array.
|
| 467 |
+
*/
|
| 468 |
+
public static function get_posts_by_type( $post_type, $offset = null, $number = null ) {
|
| 469 |
+
$args = array(
|
| 470 |
+
'post_type' => $post_type,
|
| 471 |
+
'posts_per_page' => is_int( $number ) ? $number : self::$limit_type_validate_count,
|
| 472 |
+
'post_status' => 'publish',
|
| 473 |
+
'orderby' => 'ID',
|
| 474 |
+
'order' => 'DESC',
|
| 475 |
+
'fields' => 'ids',
|
| 476 |
+
);
|
| 477 |
+
if ( is_int( $offset ) ) {
|
| 478 |
+
$args['offset'] = $offset;
|
| 479 |
+
}
|
| 480 |
+
|
| 481 |
+
// Attachment posts usually have the post_status of 'inherit,' so they can use the status of the post they're attached to.
|
| 482 |
+
if ( 'attachment' === $post_type ) {
|
| 483 |
+
$args['post_status'] = 'inherit';
|
| 484 |
+
}
|
| 485 |
+
$query = new WP_Query( $args );
|
| 486 |
+
|
| 487 |
+
return $query->posts;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
/**
|
| 491 |
+
* Gets the front-end links for taxonomy terms.
|
| 492 |
+
* For example, https://example.org/?cat=2
|
| 493 |
+
*
|
| 494 |
+
* @param string $taxonomy The name of the taxonomy, like 'category' or 'post_tag'.
|
| 495 |
+
* @param int|string $offset The number at which to offset the query (optional).
|
| 496 |
+
* @param int $number The maximum amount of links to get (optional).
|
| 497 |
+
* @return string[] The term links, as an array of strings.
|
| 498 |
+
*/
|
| 499 |
+
public static function get_taxonomy_links( $taxonomy, $offset = '', $number = 1 ) {
|
| 500 |
+
return array_map(
|
| 501 |
+
'get_term_link',
|
| 502 |
+
get_terms(
|
| 503 |
+
array_merge(
|
| 504 |
+
compact( 'taxonomy', 'offset', 'number' ),
|
| 505 |
+
array(
|
| 506 |
+
'orderby' => 'id',
|
| 507 |
+
)
|
| 508 |
+
)
|
| 509 |
+
)
|
| 510 |
+
);
|
| 511 |
+
}
|
| 512 |
+
|
| 513 |
+
/**
|
| 514 |
+
* Gets the author page URLs, like https://example.com/author/admin/.
|
| 515 |
+
*
|
| 516 |
+
* Accepts an $offset parameter, for the query of authors.
|
| 517 |
+
* 0 is the first author in the query, and 1 is the second.
|
| 518 |
+
*
|
| 519 |
+
* @param int|string $offset The offset for the URL to query for, should be an int if passing an argument.
|
| 520 |
+
* @param int|string $number The total number to query for, should be an int if passing an argument.
|
| 521 |
+
* @return array The author page URLs, or an empty array.
|
| 522 |
+
*/
|
| 523 |
+
public static function get_author_page_urls( $offset = '', $number = '' ) {
|
| 524 |
+
$author_page_urls = array();
|
| 525 |
+
if ( ! self::is_template_supported( 'is_author' ) ) {
|
| 526 |
+
return $author_page_urls;
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
$number = ! empty( $number ) ? $number : self::$limit_type_validate_count;
|
| 530 |
+
foreach ( get_users( compact( 'offset', 'number' ) ) as $author ) {
|
| 531 |
+
$author_page_urls[] = get_author_posts_url( $author->ID, $author->user_nicename );
|
| 532 |
+
}
|
| 533 |
+
|
| 534 |
+
return $author_page_urls;
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
/**
|
| 538 |
+
* Gets a single search page URL, like https://example.com/?s=example.
|
| 539 |
+
*
|
| 540 |
+
* @return string|null An example search page, or null.
|
| 541 |
+
*/
|
| 542 |
+
public static function get_search_page() {
|
| 543 |
+
if ( ! self::is_template_supported( 'is_search' ) ) {
|
| 544 |
+
return null;
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
return add_query_arg( 's', 'example', home_url( '/' ) );
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
/**
|
| 551 |
+
* Gets a single date page URL, like https://example.com/?year=2018.
|
| 552 |
+
*
|
| 553 |
+
* @return string|null An example search page, or null.
|
| 554 |
+
*/
|
| 555 |
+
public static function get_date_page() {
|
| 556 |
+
if ( ! self::is_template_supported( 'is_date' ) ) {
|
| 557 |
+
return null;
|
| 558 |
+
}
|
| 559 |
+
|
| 560 |
+
return add_query_arg( 'year', date( 'Y' ), home_url( '/' ) );
|
| 561 |
+
}
|
| 562 |
+
|
| 563 |
+
/**
|
| 564 |
+
* Validates the URLs of the entire site.
|
| 565 |
+
*
|
| 566 |
+
* Includes the URLs of public, published posts, public taxonomies, and other templates.
|
| 567 |
+
* This validates one of each type at a time,
|
| 568 |
+
* and iterates until it reaches the maximum number of URLs for each type.
|
| 569 |
+
*/
|
| 570 |
+
public static function crawl_site() {
|
| 571 |
+
/*
|
| 572 |
+
* If 'Your homepage displays' is set to 'Your latest posts', validate the homepage.
|
| 573 |
+
* It will not be part of the page validation below.
|
| 574 |
+
*/
|
| 575 |
+
if ( 'posts' === get_option( 'show_on_front' ) && self::is_template_supported( 'is_home' ) ) {
|
| 576 |
+
self::validate_and_store_url( home_url( '/' ), 'home' );
|
| 577 |
+
}
|
| 578 |
+
|
| 579 |
+
$amp_enabled_taxonomies = array_filter(
|
| 580 |
+
get_taxonomies( array( 'public' => true ) ),
|
| 581 |
+
array( 'AMP_CLI', 'does_taxonomy_support_amp' )
|
| 582 |
+
);
|
| 583 |
+
$public_post_types = get_post_types( array( 'public' => true ), 'names' );
|
| 584 |
+
|
| 585 |
+
// Validate one URL of each template/content type, then another URL of each type on the next iteration.
|
| 586 |
+
for ( $i = 0; $i < self::$limit_type_validate_count; $i++ ) {
|
| 587 |
+
// Validate all public, published posts.
|
| 588 |
+
foreach ( $public_post_types as $post_type ) {
|
| 589 |
+
$post_ids = self::get_posts_that_support_amp( self::get_posts_by_type( $post_type, $i, 1 ) );
|
| 590 |
+
if ( ! empty( $post_ids[0] ) ) {
|
| 591 |
+
self::validate_and_store_url( get_permalink( $post_ids[0] ), $post_type );
|
| 592 |
+
}
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
foreach ( $amp_enabled_taxonomies as $taxonomy ) {
|
| 596 |
+
$taxonomy_links = self::get_taxonomy_links( $taxonomy, $i, 1 );
|
| 597 |
+
$link = reset( $taxonomy_links );
|
| 598 |
+
if ( ! empty( $link ) ) {
|
| 599 |
+
self::validate_and_store_url( $link, $taxonomy );
|
| 600 |
+
}
|
| 601 |
+
}
|
| 602 |
+
|
| 603 |
+
$author_page_urls = self::get_author_page_urls( $i, 1 );
|
| 604 |
+
if ( ! empty( $author_page_urls[0] ) ) {
|
| 605 |
+
self::validate_and_store_url( $author_page_urls[0], 'author' );
|
| 606 |
+
}
|
| 607 |
+
}
|
| 608 |
+
|
| 609 |
+
// Only validate 1 date and 1 search page.
|
| 610 |
+
$url = self::get_date_page();
|
| 611 |
+
if ( $url ) {
|
| 612 |
+
self::validate_and_store_url( $url, 'date' );
|
| 613 |
+
}
|
| 614 |
+
$url = self::get_search_page();
|
| 615 |
+
if ( $url ) {
|
| 616 |
+
self::validate_and_store_url( $url, 'search' );
|
| 617 |
+
}
|
| 618 |
+
}
|
| 619 |
+
|
| 620 |
+
/**
|
| 621 |
+
* Validates the URL, stores the results, and increments the counts.
|
| 622 |
+
*
|
| 623 |
+
* @param string $url The URL to validate.
|
| 624 |
+
* @param string $type The type of template, post, or taxonomy.
|
| 625 |
+
*/
|
| 626 |
+
public static function validate_and_store_url( $url, $type ) {
|
| 627 |
+
$validity = AMP_Validation_Manager::validate_url( $url );
|
| 628 |
+
|
| 629 |
+
/*
|
| 630 |
+
* If the request to validate this returns a WP_Error, return.
|
| 631 |
+
* One cause of an error is if the validation request results in a 404 response code.
|
| 632 |
+
*/
|
| 633 |
+
if ( is_wp_error( $validity ) ) {
|
| 634 |
+
/* translators: %1$s is error code, %2$s is error message, and %3$s is the actual URL. */
|
| 635 |
+
WP_CLI::warning( sprintf( __( 'Validate URL error (%1$s): %2$s URL: %3$s', 'amp' ), $validity->get_error_code(), $validity->get_error_message(), $url ) );
|
| 636 |
+
return;
|
| 637 |
+
}
|
| 638 |
+
if ( self::$wp_cli_progress ) {
|
| 639 |
+
self::$wp_cli_progress->tick();
|
| 640 |
+
}
|
| 641 |
+
|
| 642 |
+
$validation_errors = wp_list_pluck( $validity['results'], 'error' );
|
| 643 |
+
AMP_Validated_URL_Post_Type::store_validation_errors(
|
| 644 |
+
$validation_errors,
|
| 645 |
+
$validity['url'],
|
| 646 |
+
wp_array_slice_assoc( $validity, array( 'queried_object' ) )
|
| 647 |
+
);
|
| 648 |
+
$unaccepted_error_count = count( array_filter(
|
| 649 |
+
$validation_errors,
|
| 650 |
+
function( $error ) {
|
| 651 |
+
$validation_status = AMP_Validation_Error_Taxonomy::get_validation_error_sanitization( $error );
|
| 652 |
+
return (
|
| 653 |
+
AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACK_ACCEPTED_STATUS !== $validation_status['term_status']
|
| 654 |
+
&&
|
| 655 |
+
AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_ACCEPTED_STATUS !== $validation_status['term_status']
|
| 656 |
+
);
|
| 657 |
+
}
|
| 658 |
+
) );
|
| 659 |
+
|
| 660 |
+
if ( count( $validation_errors ) > 0 ) {
|
| 661 |
+
self::$total_errors++;
|
| 662 |
+
}
|
| 663 |
+
if ( $unaccepted_error_count > 0 ) {
|
| 664 |
+
self::$unaccepted_errors++;
|
| 665 |
+
}
|
| 666 |
+
|
| 667 |
+
self::$number_crawled++;
|
| 668 |
+
|
| 669 |
+
if ( ! isset( self::$validity_by_type[ $type ] ) ) {
|
| 670 |
+
self::$validity_by_type[ $type ] = array(
|
| 671 |
+
'valid' => 0,
|
| 672 |
+
'total' => 0,
|
| 673 |
+
);
|
| 674 |
+
}
|
| 675 |
+
self::$validity_by_type[ $type ]['total']++;
|
| 676 |
+
if ( 0 === $unaccepted_error_count ) {
|
| 677 |
+
self::$validity_by_type[ $type ]['valid']++;
|
| 678 |
+
}
|
| 679 |
+
}
|
| 680 |
+
}
|
|
@@ -0,0 +1,441 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_HTTP
|
| 4 |
+
*
|
| 5 |
+
* @since 1.0
|
| 6 |
+
* @package AMP
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Class AMP_HTTP
|
| 11 |
+
*/
|
| 12 |
+
class AMP_HTTP {
|
| 13 |
+
|
| 14 |
+
/**
|
| 15 |
+
* Headers sent (or attempted to be sent).
|
| 16 |
+
*
|
| 17 |
+
* @since 1.0
|
| 18 |
+
* @see AMP_HTTP::send_header()
|
| 19 |
+
* @var array[]
|
| 20 |
+
*/
|
| 21 |
+
public static $headers_sent = array();
|
| 22 |
+
|
| 23 |
+
/**
|
| 24 |
+
* AMP-specific query vars that were purged.
|
| 25 |
+
*
|
| 26 |
+
* @since 0.7
|
| 27 |
+
* @since 1.0 Moved to AMP_HTTP class.
|
| 28 |
+
* @see AMP_HTTP::purge_amp_query_vars()
|
| 29 |
+
* @var string[]
|
| 30 |
+
*/
|
| 31 |
+
public static $purged_amp_query_vars = array();
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* Send an HTTP response header.
|
| 35 |
+
*
|
| 36 |
+
* This largely exists to facilitate unit testing but it also provides a better interface for sending headers.
|
| 37 |
+
*
|
| 38 |
+
* @since 0.7.0
|
| 39 |
+
* @since 1.0 Moved to AMP_HTTP class.
|
| 40 |
+
*
|
| 41 |
+
* @param string $name Header name.
|
| 42 |
+
* @param string $value Header value.
|
| 43 |
+
* @param array $args {
|
| 44 |
+
* Args to header().
|
| 45 |
+
*
|
| 46 |
+
* @type bool $replace Whether to replace a header previously sent. Default true.
|
| 47 |
+
* @type int $status_code Status code to send with the sent header.
|
| 48 |
+
* }
|
| 49 |
+
* @return bool Whether the header was sent.
|
| 50 |
+
*/
|
| 51 |
+
public static function send_header( $name, $value, $args = array() ) {
|
| 52 |
+
$args = array_merge(
|
| 53 |
+
array(
|
| 54 |
+
'replace' => true,
|
| 55 |
+
'status_code' => null,
|
| 56 |
+
),
|
| 57 |
+
$args
|
| 58 |
+
);
|
| 59 |
+
|
| 60 |
+
self::$headers_sent[] = array_merge( compact( 'name', 'value' ), $args );
|
| 61 |
+
if ( headers_sent() ) {
|
| 62 |
+
return false;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
header(
|
| 66 |
+
sprintf( '%s: %s', $name, $value ),
|
| 67 |
+
$args['replace'],
|
| 68 |
+
$args['status_code']
|
| 69 |
+
);
|
| 70 |
+
return true;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
/**
|
| 74 |
+
* Send Server-Timing header.
|
| 75 |
+
*
|
| 76 |
+
* If WP_DEBUG is not enabled and an admin user (who can manage_options) is not logged-in, the Server-Header will not be sent.
|
| 77 |
+
*
|
| 78 |
+
* @since 1.0
|
| 79 |
+
*
|
| 80 |
+
* @param string $name Name.
|
| 81 |
+
* @param float $duration Duration. If negative, will be added to microtime( true ). Optional.
|
| 82 |
+
* @param string $description Description. Optional.
|
| 83 |
+
* @return bool Return value of send_header call. If WP_DEBUG is not enabled or admin user (who can manage_options) is not logged-in, this will always return false.
|
| 84 |
+
*/
|
| 85 |
+
public static function send_server_timing( $name, $duration = null, $description = null ) {
|
| 86 |
+
if ( ! WP_DEBUG && ! current_user_can( 'manage_options' ) ) {
|
| 87 |
+
return false;
|
| 88 |
+
}
|
| 89 |
+
$value = $name;
|
| 90 |
+
if ( isset( $description ) ) {
|
| 91 |
+
$value .= sprintf( ';desc="%s"', str_replace( array( '\\', '"' ), '', substr( $description, 0, 100 ) ) );
|
| 92 |
+
}
|
| 93 |
+
if ( isset( $duration ) ) {
|
| 94 |
+
if ( $duration < 0 ) {
|
| 95 |
+
$duration = microtime( true ) + $duration;
|
| 96 |
+
}
|
| 97 |
+
$value .= sprintf( ';dur=%f', $duration * 1000 );
|
| 98 |
+
}
|
| 99 |
+
return self::send_header( 'Server-Timing', $value, array( 'replace' => false ) );
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
/**
|
| 103 |
+
* Remove query vars that come in requests such as for amp-live-list.
|
| 104 |
+
*
|
| 105 |
+
* WordPress should generally not respond differently to requests when these parameters
|
| 106 |
+
* are present. In some cases, when a query param such as __amp_source_origin is present
|
| 107 |
+
* then it would normally get included into pagination links generated by get_pagenum_link().
|
| 108 |
+
* The whitelist sanitizer empties out links that contain this string as it matches the
|
| 109 |
+
* blacklisted_value_regex. So by preemptively scrubbing any reference to these query vars
|
| 110 |
+
* we can ensure that WordPress won't end up referencing them in any way.
|
| 111 |
+
*
|
| 112 |
+
* @since 0.7
|
| 113 |
+
* @since 1.0 Moved to AMP_HTTP class.
|
| 114 |
+
*/
|
| 115 |
+
public static function purge_amp_query_vars() {
|
| 116 |
+
$query_vars = array(
|
| 117 |
+
'__amp_source_origin',
|
| 118 |
+
'_wp_amp_action_xhr_converted',
|
| 119 |
+
'amp_latest_update_time',
|
| 120 |
+
'amp_last_check_time',
|
| 121 |
+
);
|
| 122 |
+
|
| 123 |
+
// Scrub input vars.
|
| 124 |
+
foreach ( $query_vars as $query_var ) {
|
| 125 |
+
if ( ! isset( $_GET[ $query_var ] ) ) { // phpcs:ignore
|
| 126 |
+
continue;
|
| 127 |
+
}
|
| 128 |
+
self::$purged_amp_query_vars[ $query_var ] = wp_unslash( $_GET[ $query_var ] ); // phpcs:ignore
|
| 129 |
+
unset( $_REQUEST[ $query_var ], $_GET[ $query_var ] );
|
| 130 |
+
$scrubbed = true;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
if ( isset( $scrubbed ) ) {
|
| 134 |
+
$build_query = function ( $query ) use ( $query_vars ) {
|
| 135 |
+
$pattern = '/^(' . join( '|', $query_vars ) . ')(?==|$)/';
|
| 136 |
+
$pairs = array();
|
| 137 |
+
foreach ( explode( '&', $query ) as $pair ) {
|
| 138 |
+
if ( ! preg_match( $pattern, $pair ) ) {
|
| 139 |
+
$pairs[] = $pair;
|
| 140 |
+
}
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
return join( '&', $pairs );
|
| 144 |
+
};
|
| 145 |
+
|
| 146 |
+
// Scrub QUERY_STRING.
|
| 147 |
+
if ( ! empty( $_SERVER['QUERY_STRING'] ) ) {
|
| 148 |
+
$_SERVER['QUERY_STRING'] = $build_query( $_SERVER['QUERY_STRING'] );
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
// Scrub REQUEST_URI.
|
| 152 |
+
if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
|
| 153 |
+
list( $path, $query ) = explode( '?', $_SERVER['REQUEST_URI'], 2 );
|
| 154 |
+
|
| 155 |
+
$pairs = $build_query( $query );
|
| 156 |
+
$_SERVER['REQUEST_URI'] = $path;
|
| 157 |
+
if ( ! empty( $pairs ) ) {
|
| 158 |
+
$_SERVER['REQUEST_URI'] .= "?{$pairs}";
|
| 159 |
+
}
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
/**
|
| 165 |
+
* Filter the allowed redirect hosts to include AMP caches.
|
| 166 |
+
*
|
| 167 |
+
* @since 1.0
|
| 168 |
+
*
|
| 169 |
+
* @param array $allowed_hosts Allowed hosts.
|
| 170 |
+
* @return array Allowed redirect hosts.
|
| 171 |
+
*/
|
| 172 |
+
public static function filter_allowed_redirect_hosts( $allowed_hosts ) {
|
| 173 |
+
return array_merge( $allowed_hosts, self::get_amp_cache_hosts() );
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
/**
|
| 177 |
+
* Get list of AMP cache hosts (that is, CORS origins).
|
| 178 |
+
*
|
| 179 |
+
* @since 1.0
|
| 180 |
+
* @link https://www.ampproject.org/docs/fundamentals/amp-cors-requests#1)-allow-requests-for-specific-cors-origins
|
| 181 |
+
*
|
| 182 |
+
* @return array AMP cache hosts.
|
| 183 |
+
*/
|
| 184 |
+
public static function get_amp_cache_hosts() {
|
| 185 |
+
$hosts = array();
|
| 186 |
+
|
| 187 |
+
// Google AMP Cache (legacy).
|
| 188 |
+
$hosts[] = 'cdn.ampproject.org';
|
| 189 |
+
|
| 190 |
+
// From the publisher’s own origins.
|
| 191 |
+
$domains = array_unique( array(
|
| 192 |
+
wp_parse_url( site_url(), PHP_URL_HOST ),
|
| 193 |
+
wp_parse_url( home_url(), PHP_URL_HOST ),
|
| 194 |
+
) );
|
| 195 |
+
|
| 196 |
+
/*
|
| 197 |
+
* From AMP docs:
|
| 198 |
+
* "When possible, the Google AMP Cache will create a subdomain for each AMP document's domain by first converting it
|
| 199 |
+
* from IDN (punycode) to UTF-8. The caches replaces every - (dash) with -- (2 dashes) and replace every . (dot) with
|
| 200 |
+
* - (dash). For example, pub.com will map to pub-com.cdn.ampproject.org."
|
| 201 |
+
*/
|
| 202 |
+
foreach ( $domains as $domain ) {
|
| 203 |
+
if ( function_exists( 'idn_to_utf8' ) ) {
|
| 204 |
+
if ( version_compare( PHP_VERSION, '5.4', '>=' ) && defined( 'INTL_IDNA_VARIANT_UTS46' ) ) {
|
| 205 |
+
$domain = idn_to_utf8( $domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46 ); // phpcs:ignore PHPCompatibility.PHP.NewFunctionParameters.idn_to_utf8_variantFound, PHPCompatibility.PHP.NewConstants.intl_idna_variant_uts46Found
|
| 206 |
+
} else {
|
| 207 |
+
$domain = idn_to_utf8( $domain );
|
| 208 |
+
}
|
| 209 |
+
}
|
| 210 |
+
$subdomain = str_replace( '-', '--', $domain );
|
| 211 |
+
$subdomain = str_replace( '.', '-', $subdomain );
|
| 212 |
+
|
| 213 |
+
// Google AMP Cache subdomain.
|
| 214 |
+
$hosts[] = sprintf( '%s.cdn.ampproject.org', $subdomain );
|
| 215 |
+
|
| 216 |
+
// Cloudflare AMP Cache.
|
| 217 |
+
$hosts[] = sprintf( '%s.amp.cloudflare.com', $subdomain );
|
| 218 |
+
|
| 219 |
+
// Bing AMP Cache.
|
| 220 |
+
$hosts[] = sprintf( '%s.bing-amp.com', $subdomain );
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
return $hosts;
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
/**
|
| 227 |
+
* Send cors headers.
|
| 228 |
+
*
|
| 229 |
+
* From the AMP docs:
|
| 230 |
+
* Restrict requests to source origins
|
| 231 |
+
* In all fetch requests, the AMP Runtime passes the "__amp_source_origin" query parameter, which contains
|
| 232 |
+
* the value of the source origin (for example, "https://publisher1.com").
|
| 233 |
+
*
|
| 234 |
+
* To restrict requests to only source origins, check that the value of the "__amp_source_origin" parameter
|
| 235 |
+
* is within a set of the Publisher's own origins.
|
| 236 |
+
*
|
| 237 |
+
* Access-Control-Allow-Origin: <origin>
|
| 238 |
+
* This header is a W3 CORS Spec requirement, where origin refers to the requesting origin that was allowed
|
| 239 |
+
* via the CORS Origin request header (for example, "https://<publisher's subdomain>.cdn.ampproject.org").
|
| 240 |
+
*
|
| 241 |
+
* Although the W3 CORS spec allows the value of * to be returned in the response, for improved security, you should:
|
| 242 |
+
*
|
| 243 |
+
* - If the Origin header is present, validate and echo the value of the Origin header.
|
| 244 |
+
* - If the Origin header isn't present, validate and echo the value of the "__amp_source_origin".
|
| 245 |
+
*
|
| 246 |
+
* (Otherwise, no Access-Control-Allow-Origin header is sent.)
|
| 247 |
+
*
|
| 248 |
+
* AMP-Access-Control-Allow-Source-Origin: <source-origin>
|
| 249 |
+
* This header allows the specified source-origin to read the authorization response. The source-origin is
|
| 250 |
+
* the value specified and verified in the "__amp_source_origin" URL parameter (for example, "https://publisher1.com").
|
| 251 |
+
*
|
| 252 |
+
* Access-Control-Expose-Headers: AMP-Access-Control-Allow-Source-Origin
|
| 253 |
+
* This header simply allows the CORS response to contain the AMP-Access-Control-Allow-Source-Origin header.
|
| 254 |
+
*
|
| 255 |
+
* @link https://www.ampproject.org/docs/fundamentals/amp-cors-requests
|
| 256 |
+
* @since 1.0
|
| 257 |
+
*/
|
| 258 |
+
public static function send_cors_headers() {
|
| 259 |
+
$origin = null;
|
| 260 |
+
$source_origin = null;
|
| 261 |
+
if ( isset( $_SERVER['HTTP_ORIGIN'] ) ) {
|
| 262 |
+
$origin = wp_validate_redirect( wp_sanitize_redirect( esc_url_raw( wp_unslash( $_SERVER['HTTP_ORIGIN'] ) ) ) );
|
| 263 |
+
}
|
| 264 |
+
if ( isset( self::$purged_amp_query_vars['__amp_source_origin'] ) ) {
|
| 265 |
+
$source_origin = wp_validate_redirect( wp_sanitize_redirect( esc_url_raw( self::$purged_amp_query_vars['__amp_source_origin'] ) ) );
|
| 266 |
+
}
|
| 267 |
+
if ( ! $origin ) {
|
| 268 |
+
$origin = $source_origin;
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
if ( $origin ) {
|
| 272 |
+
self::send_header( 'Access-Control-Allow-Origin', $origin, array( 'replace' => false ) );
|
| 273 |
+
self::send_header( 'Access-Control-Allow-Credentials', 'true' );
|
| 274 |
+
self::send_header( 'Vary', 'Origin', array( 'replace' => false ) );
|
| 275 |
+
}
|
| 276 |
+
if ( $source_origin ) {
|
| 277 |
+
self::send_header( 'AMP-Access-Control-Allow-Source-Origin', $source_origin );
|
| 278 |
+
self::send_header( 'Access-Control-Expose-Headers', 'AMP-Access-Control-Allow-Source-Origin', array( 'replace' => false ) );
|
| 279 |
+
}
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
/**
|
| 283 |
+
* Hook into a POST form submissions, such as the comment form or some other form submission.
|
| 284 |
+
*
|
| 285 |
+
* @since 0.7.0
|
| 286 |
+
* @since 1.0 Moved to AMP_HTTP class. Extracted some logic to send_cors_headers method.
|
| 287 |
+
*/
|
| 288 |
+
public static function handle_xhr_request() {
|
| 289 |
+
$is_amp_xhr = (
|
| 290 |
+
! empty( self::$purged_amp_query_vars['_wp_amp_action_xhr_converted'] )
|
| 291 |
+
&&
|
| 292 |
+
( ! empty( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] )
|
| 293 |
+
);
|
| 294 |
+
if ( ! $is_amp_xhr ) {
|
| 295 |
+
return;
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
// Intercept POST requests which redirect.
|
| 299 |
+
add_filter( 'wp_redirect', array( __CLASS__, 'intercept_post_request_redirect' ), PHP_INT_MAX );
|
| 300 |
+
|
| 301 |
+
// Add special handling for redirecting after comment submission.
|
| 302 |
+
add_filter( 'comment_post_redirect', array( __CLASS__, 'filter_comment_post_redirect' ), PHP_INT_MAX, 2 );
|
| 303 |
+
|
| 304 |
+
// Add die handler for AMP error display, most likely due to problem with comment.
|
| 305 |
+
add_filter( 'wp_die_handler', function () {
|
| 306 |
+
return array( __CLASS__, 'handle_wp_die' );
|
| 307 |
+
} );
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
/**
|
| 311 |
+
* Intercept the response to a POST request.
|
| 312 |
+
*
|
| 313 |
+
* @since 0.7.0
|
| 314 |
+
* @since 1.0 Moved to AMP_HTTP class.
|
| 315 |
+
* @see wp_redirect()
|
| 316 |
+
*
|
| 317 |
+
* @param string $location The location to redirect to.
|
| 318 |
+
*/
|
| 319 |
+
public static function intercept_post_request_redirect( $location ) {
|
| 320 |
+
|
| 321 |
+
// Make sure relative redirects get made absolute.
|
| 322 |
+
$parsed_location = array_merge(
|
| 323 |
+
array(
|
| 324 |
+
'scheme' => 'https',
|
| 325 |
+
'host' => wp_parse_url( home_url(), PHP_URL_HOST ),
|
| 326 |
+
'path' => isset( $_SERVER['REQUEST_URI'] ) ? strtok( wp_unslash( $_SERVER['REQUEST_URI'] ), '?' ) : '/',
|
| 327 |
+
),
|
| 328 |
+
wp_parse_url( $location )
|
| 329 |
+
);
|
| 330 |
+
|
| 331 |
+
$absolute_location = '';
|
| 332 |
+
if ( 'https' === $parsed_location['scheme'] ) {
|
| 333 |
+
$absolute_location .= $parsed_location['scheme'] . ':';
|
| 334 |
+
}
|
| 335 |
+
$absolute_location .= '//' . $parsed_location['host'];
|
| 336 |
+
if ( isset( $parsed_location['port'] ) ) {
|
| 337 |
+
$absolute_location .= ':' . $parsed_location['port'];
|
| 338 |
+
}
|
| 339 |
+
$absolute_location .= $parsed_location['path'];
|
| 340 |
+
if ( isset( $parsed_location['query'] ) ) {
|
| 341 |
+
$absolute_location .= '?' . $parsed_location['query'];
|
| 342 |
+
}
|
| 343 |
+
if ( isset( $parsed_location['fragment'] ) ) {
|
| 344 |
+
$absolute_location .= '#' . $parsed_location['fragment'];
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
self::send_header( 'AMP-Redirect-To', $absolute_location );
|
| 348 |
+
self::send_header( 'Access-Control-Expose-Headers', 'AMP-Redirect-To', array( 'replace' => false ) );
|
| 349 |
+
|
| 350 |
+
wp_send_json_success();
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
/**
|
| 354 |
+
* New error handler for AMP form submission.
|
| 355 |
+
*
|
| 356 |
+
* @since 0.7.0
|
| 357 |
+
* @since 1.0 Moved to AMP_HTTP class.
|
| 358 |
+
* @see wp_die()
|
| 359 |
+
*
|
| 360 |
+
* @param WP_Error|string $error The error to handle.
|
| 361 |
+
* @param string|int $title Optional. Error title. If `$message` is a `WP_Error` object,
|
| 362 |
+
* error data with the key 'title' may be used to specify the title.
|
| 363 |
+
* If `$title` is an integer, then it is treated as the response
|
| 364 |
+
* code. Default empty.
|
| 365 |
+
* @param string|array|int $args {
|
| 366 |
+
* Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
|
| 367 |
+
* as the response code. Default empty array.
|
| 368 |
+
*
|
| 369 |
+
* @type int $response The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
|
| 370 |
+
* }
|
| 371 |
+
*/
|
| 372 |
+
public static function handle_wp_die( $error, $title = '', $args = array() ) {
|
| 373 |
+
if ( is_int( $title ) ) {
|
| 374 |
+
$status_code = $title;
|
| 375 |
+
} elseif ( is_int( $args ) ) {
|
| 376 |
+
$status_code = $args;
|
| 377 |
+
} elseif ( is_array( $args ) && isset( $args['response'] ) ) {
|
| 378 |
+
$status_code = $args['response'];
|
| 379 |
+
} else {
|
| 380 |
+
$status_code = 500;
|
| 381 |
+
}
|
| 382 |
+
status_header( $status_code );
|
| 383 |
+
|
| 384 |
+
if ( is_wp_error( $error ) ) {
|
| 385 |
+
$error = $error->get_error_message();
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
// Message will be shown in template defined by AMP_Theme_Support::amend_comment_form().
|
| 389 |
+
wp_send_json( array(
|
| 390 |
+
'error' => amp_wp_kses_mustache( $error ),
|
| 391 |
+
) );
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
/**
|
| 395 |
+
* Handle comment_post_redirect to ensure page reload is done when comments_live_list is not supported, while sending back a success message when it is.
|
| 396 |
+
*
|
| 397 |
+
* @since 0.7.0
|
| 398 |
+
* @since 1.0 Moved to AMP_HTTP class.
|
| 399 |
+
*
|
| 400 |
+
* @param string $url Comment permalink to redirect to.
|
| 401 |
+
* @param WP_Comment $comment Posted comment.
|
| 402 |
+
*
|
| 403 |
+
* @return string|null URL if redirect to be done; otherwise function will exist.
|
| 404 |
+
*/
|
| 405 |
+
public static function filter_comment_post_redirect( $url, $comment ) {
|
| 406 |
+
$theme_support = AMP_Theme_Support::get_theme_support_args();
|
| 407 |
+
|
| 408 |
+
// Cause a page refresh if amp-live-list is not implemented for comments via add_theme_support( AMP_Theme_Support::SLUG, array( 'comments_live_list' => true ) ).
|
| 409 |
+
if ( empty( $theme_support['comments_live_list'] ) ) {
|
| 410 |
+
/*
|
| 411 |
+
* Add the comment ID to the URL to force AMP to refresh the page.
|
| 412 |
+
* This is ideally a temporary workaround to deal with https://github.com/ampproject/amphtml/issues/14170
|
| 413 |
+
*/
|
| 414 |
+
$url = add_query_arg( 'comment', $comment->comment_ID, $url );
|
| 415 |
+
|
| 416 |
+
// Pass URL along to wp_redirect().
|
| 417 |
+
return $url;
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
// Create a success message to display to the user.
|
| 421 |
+
if ( '1' === (string) $comment->comment_approved ) {
|
| 422 |
+
$message = __( 'Your comment has been posted.', 'amp' );
|
| 423 |
+
} else {
|
| 424 |
+
$message = __( 'Your comment is awaiting moderation.', 'default' ); // Note core string re-use.
|
| 425 |
+
}
|
| 426 |
+
|
| 427 |
+
/**
|
| 428 |
+
* Filters the message when comment submitted success message when
|
| 429 |
+
*
|
| 430 |
+
* @since 0.7
|
| 431 |
+
*/
|
| 432 |
+
$message = apply_filters( 'amp_comment_posted_message', $message, $comment );
|
| 433 |
+
|
| 434 |
+
// Message will be shown in template defined by AMP_Theme_Support::amend_comment_form().
|
| 435 |
+
wp_send_json( array(
|
| 436 |
+
'message' => amp_wp_kses_mustache( $message ),
|
| 437 |
+
) );
|
| 438 |
+
|
| 439 |
+
return null;
|
| 440 |
+
}
|
| 441 |
+
}
|
|
@@ -11,12 +11,21 @@
|
|
| 11 |
*/
|
| 12 |
class AMP_Post_Type_Support {
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
/**
|
| 15 |
* Get post types that plugin supports out of the box (which cannot be disabled).
|
| 16 |
*
|
|
|
|
| 17 |
* @return string[] Post types.
|
| 18 |
*/
|
| 19 |
public static function get_builtin_supported_post_types() {
|
|
|
|
| 20 |
return array_filter( array( 'post' ), 'post_type_exists' );
|
| 21 |
}
|
| 22 |
|
|
@@ -27,17 +36,12 @@ class AMP_Post_Type_Support {
|
|
| 27 |
* @return string[] Post types eligible for AMP.
|
| 28 |
*/
|
| 29 |
public static function get_eligible_post_types() {
|
| 30 |
-
return
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
'_builtin' => false,
|
| 37 |
-
),
|
| 38 |
-
'names'
|
| 39 |
-
) )
|
| 40 |
-
);
|
| 41 |
}
|
| 42 |
|
| 43 |
/**
|
|
@@ -49,12 +53,13 @@ class AMP_Post_Type_Support {
|
|
| 49 |
* @since 0.6
|
| 50 |
*/
|
| 51 |
public static function add_post_type_support() {
|
| 52 |
-
|
| 53 |
-
self::
|
| 54 |
-
|
| 55 |
-
|
|
|
|
| 56 |
foreach ( $post_types as $post_type ) {
|
| 57 |
-
add_post_type_support( $post_type,
|
| 58 |
}
|
| 59 |
}
|
| 60 |
|
|
@@ -72,8 +77,7 @@ class AMP_Post_Type_Support {
|
|
| 72 |
}
|
| 73 |
$errors = array();
|
| 74 |
|
| 75 |
-
|
| 76 |
-
if ( isset( $post->post_type ) && ! post_type_supports( $post->post_type, amp_get_slug() ) ) {
|
| 77 |
$errors[] = 'post-type-support';
|
| 78 |
}
|
| 79 |
|
|
@@ -94,6 +98,48 @@ class AMP_Post_Type_Support {
|
|
| 94 |
$errors[] = 'skip-post';
|
| 95 |
}
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
return $errors;
|
| 98 |
}
|
| 99 |
}
|
| 11 |
*/
|
| 12 |
class AMP_Post_Type_Support {
|
| 13 |
|
| 14 |
+
/**
|
| 15 |
+
* Post type support slug.
|
| 16 |
+
*
|
| 17 |
+
* @var string
|
| 18 |
+
*/
|
| 19 |
+
const SLUG = 'amp';
|
| 20 |
+
|
| 21 |
/**
|
| 22 |
* Get post types that plugin supports out of the box (which cannot be disabled).
|
| 23 |
*
|
| 24 |
+
* @deprecated
|
| 25 |
* @return string[] Post types.
|
| 26 |
*/
|
| 27 |
public static function get_builtin_supported_post_types() {
|
| 28 |
+
_deprecated_function( __METHOD__, '1.0' );
|
| 29 |
return array_filter( array( 'post' ), 'post_type_exists' );
|
| 30 |
}
|
| 31 |
|
| 36 |
* @return string[] Post types eligible for AMP.
|
| 37 |
*/
|
| 38 |
public static function get_eligible_post_types() {
|
| 39 |
+
return array_values( get_post_types(
|
| 40 |
+
array(
|
| 41 |
+
'public' => true,
|
| 42 |
+
),
|
| 43 |
+
'names'
|
| 44 |
+
) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
}
|
| 46 |
|
| 47 |
/**
|
| 53 |
* @since 0.6
|
| 54 |
*/
|
| 55 |
public static function add_post_type_support() {
|
| 56 |
+
if ( current_theme_supports( AMP_Theme_Support::SLUG ) && AMP_Options_Manager::get_option( 'all_templates_supported' ) ) {
|
| 57 |
+
$post_types = self::get_eligible_post_types();
|
| 58 |
+
} else {
|
| 59 |
+
$post_types = AMP_Options_Manager::get_option( 'supported_post_types', array() );
|
| 60 |
+
}
|
| 61 |
foreach ( $post_types as $post_type ) {
|
| 62 |
+
add_post_type_support( $post_type, self::SLUG );
|
| 63 |
}
|
| 64 |
}
|
| 65 |
|
| 77 |
}
|
| 78 |
$errors = array();
|
| 79 |
|
| 80 |
+
if ( ! post_type_supports( $post->post_type, self::SLUG ) ) {
|
|
|
|
| 81 |
$errors[] = 'post-type-support';
|
| 82 |
}
|
| 83 |
|
| 98 |
$errors[] = 'skip-post';
|
| 99 |
}
|
| 100 |
|
| 101 |
+
$status = get_post_meta( $post->ID, AMP_Post_Meta_Box::STATUS_POST_META_KEY, true );
|
| 102 |
+
if ( $status ) {
|
| 103 |
+
if ( AMP_Post_Meta_Box::DISABLED_STATUS === $status ) {
|
| 104 |
+
$errors[] = 'post-status-disabled';
|
| 105 |
+
}
|
| 106 |
+
} else {
|
| 107 |
+
/*
|
| 108 |
+
* Disabled by default for custom page templates, page on front and page for posts, unless 'amp' theme
|
| 109 |
+
* support is present (in which case AMP_Theme_Support::get_template_availability() determines availability).
|
| 110 |
+
*/
|
| 111 |
+
$enabled = (
|
| 112 |
+
current_theme_supports( AMP_Theme_Support::SLUG )
|
| 113 |
+
||
|
| 114 |
+
(
|
| 115 |
+
! (bool) get_page_template_slug( $post )
|
| 116 |
+
&&
|
| 117 |
+
! (
|
| 118 |
+
'page' === $post->post_type
|
| 119 |
+
&&
|
| 120 |
+
'page' === get_option( 'show_on_front' )
|
| 121 |
+
&&
|
| 122 |
+
in_array( (int) $post->ID, array(
|
| 123 |
+
(int) get_option( 'page_on_front' ),
|
| 124 |
+
(int) get_option( 'page_for_posts' ),
|
| 125 |
+
), true )
|
| 126 |
+
)
|
| 127 |
+
)
|
| 128 |
+
);
|
| 129 |
+
|
| 130 |
+
/**
|
| 131 |
+
* Filters whether default AMP status should be enabled or not.
|
| 132 |
+
*
|
| 133 |
+
* @since 0.6
|
| 134 |
+
*
|
| 135 |
+
* @param string $status Status.
|
| 136 |
+
* @param WP_Post $post Post.
|
| 137 |
+
*/
|
| 138 |
+
$enabled = apply_filters( 'amp_post_status_default_enabled', $enabled, $post );
|
| 139 |
+
if ( ! $enabled ) {
|
| 140 |
+
$errors[] = 'post-status-disabled';
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
return $errors;
|
| 144 |
}
|
| 145 |
}
|
|
@@ -13,11 +13,46 @@
|
|
| 13 |
class AMP_Theme_Support {
|
| 14 |
|
| 15 |
/**
|
| 16 |
-
*
|
| 17 |
*
|
| 18 |
* @var string
|
| 19 |
*/
|
| 20 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
/**
|
| 23 |
* Sanitizer classes.
|
|
@@ -59,57 +94,44 @@ class AMP_Theme_Support {
|
|
| 59 |
);
|
| 60 |
|
| 61 |
/**
|
| 62 |
-
*
|
| 63 |
*
|
| 64 |
-
* @since 0
|
| 65 |
-
* @
|
| 66 |
-
* @var string[]
|
| 67 |
*/
|
| 68 |
-
public static $
|
| 69 |
|
| 70 |
/**
|
| 71 |
-
*
|
| 72 |
*
|
| 73 |
* @since 0.7
|
| 74 |
-
* @
|
| 75 |
-
* @var array[]
|
| 76 |
*/
|
| 77 |
-
|
| 78 |
|
| 79 |
/**
|
| 80 |
-
*
|
| 81 |
*
|
| 82 |
-
* @since 0
|
| 83 |
* @var bool
|
| 84 |
*/
|
| 85 |
-
protected static $
|
| 86 |
|
| 87 |
/**
|
| 88 |
* Initialize.
|
|
|
|
|
|
|
| 89 |
*/
|
| 90 |
public static function init() {
|
| 91 |
-
|
|
|
|
| 92 |
return;
|
| 93 |
}
|
| 94 |
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
self::purge_amp_query_vars();
|
| 98 |
-
self::handle_xhr_request();
|
| 99 |
|
| 100 |
require_once AMP__DIR__ . '/includes/amp-post-template-actions.php';
|
| 101 |
|
| 102 |
-
// Validate theme support usage.
|
| 103 |
-
$support = get_theme_support( 'amp' );
|
| 104 |
-
if ( WP_DEBUG && is_array( $support ) ) {
|
| 105 |
-
$args = array_shift( $support );
|
| 106 |
-
if ( ! is_array( $args ) ) {
|
| 107 |
-
trigger_error( esc_html__( 'Expected AMP theme support arg to be array.', 'amp' ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
|
| 108 |
-
} elseif ( count( array_diff( array_keys( $args ), array( 'template_dir', 'available_callback', 'comments_live_list' ) ) ) !== 0 ) {
|
| 109 |
-
trigger_error( esc_html__( 'Expected AMP theme support to only have template_dir and/or available_callback.', 'amp' ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
|
| 110 |
-
}
|
| 111 |
-
}
|
| 112 |
-
|
| 113 |
add_action( 'widgets_init', array( __CLASS__, 'register_widgets' ) );
|
| 114 |
|
| 115 |
/*
|
|
@@ -120,6 +142,82 @@ class AMP_Theme_Support {
|
|
| 120 |
add_action( 'wp', array( __CLASS__, 'finish_init' ), PHP_INT_MAX );
|
| 121 |
}
|
| 122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
/**
|
| 124 |
* Finish initialization once query vars are set.
|
| 125 |
*
|
|
@@ -127,71 +225,133 @@ class AMP_Theme_Support {
|
|
| 127 |
*/
|
| 128 |
public static function finish_init() {
|
| 129 |
if ( ! is_amp_endpoint() ) {
|
| 130 |
-
|
| 131 |
-
if
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
add_action( 'wp_head', 'amp_frontend_add_canonical' );
|
| 135 |
-
}
|
| 136 |
}
|
|
|
|
|
|
|
| 137 |
return;
|
| 138 |
}
|
| 139 |
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
|
|
|
| 144 |
}
|
| 145 |
|
| 146 |
self::add_hooks();
|
| 147 |
self::$sanitizer_classes = amp_get_content_sanitizers();
|
|
|
|
| 148 |
self::$embed_handlers = self::register_content_embed_handlers();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
}
|
| 150 |
|
| 151 |
/**
|
| 152 |
-
*
|
| 153 |
*
|
| 154 |
-
* @since 0
|
|
|
|
|
|
|
|
|
|
| 155 |
*/
|
| 156 |
-
public static function
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
}
|
|
|
|
|
|
|
|
|
|
| 162 |
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
exit;
|
| 167 |
}
|
|
|
|
|
|
|
| 168 |
}
|
| 169 |
|
| 170 |
/**
|
| 171 |
* Determines whether paired mode is available.
|
| 172 |
*
|
| 173 |
* When 'amp' theme support has not been added or canonical mode is enabled, then this returns false.
|
| 174 |
-
* Returns true when there is a template_dir defined in theme support, and if a defined available_callback
|
| 175 |
-
* returns true.
|
| 176 |
*
|
|
|
|
|
|
|
|
|
|
| 177 |
* @return bool Whether available.
|
| 178 |
*/
|
| 179 |
public static function is_paired_available() {
|
| 180 |
-
|
| 181 |
-
if ( empty( $support ) || amp_is_canonical() ) {
|
| 182 |
return false;
|
| 183 |
}
|
| 184 |
|
| 185 |
-
if (
|
| 186 |
return false;
|
| 187 |
}
|
| 188 |
|
| 189 |
-
$
|
| 190 |
-
|
| 191 |
-
if ( isset( $args['available_callback'] ) && is_callable( $args['available_callback'] ) ) {
|
| 192 |
-
return call_user_func( $args['available_callback'] );
|
| 193 |
-
}
|
| 194 |
-
return true;
|
| 195 |
}
|
| 196 |
|
| 197 |
/**
|
|
@@ -207,354 +367,476 @@ class AMP_Theme_Support {
|
|
| 207 |
}
|
| 208 |
|
| 209 |
/**
|
| 210 |
-
* Register
|
| 211 |
*/
|
| 212 |
-
public static function
|
| 213 |
foreach ( self::$template_types as $template_type ) {
|
| 214 |
-
add_filter( "{$template_type}_template_hierarchy", array( __CLASS__, '
|
| 215 |
}
|
| 216 |
-
add_filter( 'template_include', array( __CLASS__, 'filter_paired_template_include' ), 100 );
|
| 217 |
}
|
| 218 |
|
| 219 |
/**
|
| 220 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
*/
|
| 222 |
-
public static function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
|
|
|
| 229 |
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
return
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
}
|
| 237 |
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
* install is not on utf-8 and we may need to do a encoding conversion.
|
| 246 |
-
*/
|
| 247 |
-
add_action( 'wp_print_styles', array( __CLASS__, 'print_amp_styles' ), 0 ); // Print boilerplate before theme and plugin stylesheets.
|
| 248 |
-
add_action( 'wp_head', 'amp_add_generator_metadata', 20 );
|
| 249 |
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
|
| 254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
|
|
|
|
|
|
| 261 |
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
*/
|
| 266 |
-
$priority = defined( 'PHP_INT_MIN' ) ? PHP_INT_MIN : ~PHP_INT_MAX; // phpcs:ignore PHPCompatibility.PHP.NewConstants.php_int_minFound
|
| 267 |
-
add_action( 'template_redirect', array( __CLASS__, 'start_output_buffering' ), $priority );
|
| 268 |
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
|
|
|
|
|
|
| 282 |
|
| 283 |
-
|
| 284 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
*
|
| 289 |
-
* WordPress should generally not respond differently to requests when these parameters
|
| 290 |
-
* are present. In some cases, when a query param such as __amp_source_origin is present
|
| 291 |
-
* then it would normally get included into pagination links generated by get_pagenum_link().
|
| 292 |
-
* The whitelist sanitizer empties out links that contain this string as it matches the
|
| 293 |
-
* blacklisted_value_regex. So by preemptively scrubbing any reference to these query vars
|
| 294 |
-
* we can ensure that WordPress won't end up referencing them in any way.
|
| 295 |
-
*
|
| 296 |
-
* @since 0.7
|
| 297 |
-
*/
|
| 298 |
-
public static function purge_amp_query_vars() {
|
| 299 |
-
$query_vars = array(
|
| 300 |
-
'__amp_source_origin',
|
| 301 |
-
'_wp_amp_action_xhr_converted',
|
| 302 |
-
'amp_latest_update_time',
|
| 303 |
-
'amp_last_check_time',
|
| 304 |
-
);
|
| 305 |
|
| 306 |
-
//
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 310 |
}
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
$
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
if ( ! preg_match( $pattern, $pair ) ) {
|
| 322 |
-
$pairs[] = $pair;
|
| 323 |
-
}
|
| 324 |
}
|
| 325 |
-
|
| 326 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 327 |
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 331 |
}
|
|
|
|
|
|
|
| 332 |
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
|
|
|
| 336 |
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
}
|
| 343 |
}
|
|
|
|
|
|
|
| 344 |
}
|
| 345 |
|
| 346 |
/**
|
| 347 |
-
*
|
| 348 |
-
*
|
| 349 |
-
* This largely exists to facilitate unit testing but it also provides a better interface for sending headers.
|
| 350 |
-
*
|
| 351 |
-
* @since 0.7.0
|
| 352 |
-
*
|
| 353 |
-
* @param string $name Header name.
|
| 354 |
-
* @param string $value Header value.
|
| 355 |
-
* @param array $args {
|
| 356 |
-
* Args to header().
|
| 357 |
*
|
| 358 |
-
*
|
| 359 |
-
* @type int $status_code Status code to send with the sent header.
|
| 360 |
-
* }
|
| 361 |
-
* @return bool Whether the header was sent.
|
| 362 |
*/
|
| 363 |
-
public static function
|
| 364 |
-
$
|
| 365 |
-
array(
|
| 366 |
-
'
|
| 367 |
-
'
|
| 368 |
),
|
| 369 |
-
$args
|
| 370 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 375 |
}
|
| 376 |
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
);
|
| 382 |
-
return true;
|
| 383 |
-
}
|
| 384 |
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 397 |
);
|
| 398 |
-
|
| 399 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
}
|
| 401 |
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 406 |
}
|
| 407 |
|
| 408 |
-
|
| 409 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 410 |
|
| 411 |
-
|
| 412 |
-
|
|
|
|
|
|
|
|
|
|
| 413 |
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
return array( __CLASS__, 'handle_wp_die' );
|
| 417 |
-
} );
|
| 418 |
|
| 419 |
-
|
|
|
|
| 420 |
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
}
|
| 433 |
|
| 434 |
/**
|
| 435 |
-
*
|
| 436 |
-
*
|
| 437 |
-
* @since 0.7.0
|
| 438 |
-
*
|
| 439 |
-
* @param string $url Comment permalink to redirect to.
|
| 440 |
-
* @param WP_Comment $comment Posted comment.
|
| 441 |
-
* @return string URL.
|
| 442 |
*/
|
| 443 |
-
public static function
|
| 444 |
-
$theme_support = get_theme_support( 'amp' );
|
| 445 |
|
| 446 |
-
//
|
| 447 |
-
|
| 448 |
-
/*
|
| 449 |
-
* Add the comment ID to the URL to force AMP to refresh the page.
|
| 450 |
-
* This is ideally a temporary workaround to deal with https://github.com/ampproject/amphtml/issues/14170
|
| 451 |
-
*/
|
| 452 |
-
$url = add_query_arg( 'comment', $comment->comment_ID, $url );
|
| 453 |
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
|
|
|
|
|
|
| 457 |
|
| 458 |
-
//
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
|
|
|
|
|
|
| 464 |
|
| 465 |
-
|
| 466 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 467 |
*
|
| 468 |
-
*
|
| 469 |
*/
|
| 470 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 471 |
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
) );
|
| 476 |
-
}
|
| 477 |
|
| 478 |
-
|
| 479 |
-
* New error handler for AMP form submission.
|
| 480 |
-
*
|
| 481 |
-
* @since 0.7.0
|
| 482 |
-
* @see wp_die()
|
| 483 |
-
*
|
| 484 |
-
* @param WP_Error|string $error The error to handle.
|
| 485 |
-
* @param string|int $title Optional. Error title. If `$message` is a `WP_Error` object,
|
| 486 |
-
* error data with the key 'title' may be used to specify the title.
|
| 487 |
-
* If `$title` is an integer, then it is treated as the response
|
| 488 |
-
* code. Default empty.
|
| 489 |
-
* @param string|array|int $args {
|
| 490 |
-
* Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
|
| 491 |
-
* as the response code. Default empty array.
|
| 492 |
-
*
|
| 493 |
-
* @type int $response The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
|
| 494 |
-
* }
|
| 495 |
-
*/
|
| 496 |
-
public static function handle_wp_die( $error, $title = '', $args = array() ) {
|
| 497 |
-
if ( is_int( $title ) ) {
|
| 498 |
-
$status_code = $title;
|
| 499 |
-
} elseif ( is_int( $args ) ) {
|
| 500 |
-
$status_code = $args;
|
| 501 |
-
} elseif ( is_array( $args ) && isset( $args['response'] ) ) {
|
| 502 |
-
$status_code = $args['response'];
|
| 503 |
-
} else {
|
| 504 |
-
$status_code = 500;
|
| 505 |
-
}
|
| 506 |
-
status_header( $status_code );
|
| 507 |
|
| 508 |
-
|
| 509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 510 |
}
|
| 511 |
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
/**
|
| 519 |
-
* Intercept the response to a POST request.
|
| 520 |
-
*
|
| 521 |
-
* @since 0.7.0
|
| 522 |
-
* @see wp_redirect()
|
| 523 |
-
*
|
| 524 |
-
* @param string $location The location to redirect to.
|
| 525 |
-
*/
|
| 526 |
-
public static function intercept_post_request_redirect( $location ) {
|
| 527 |
-
|
| 528 |
-
// Make sure relative redirects get made absolute.
|
| 529 |
-
$parsed_location = array_merge(
|
| 530 |
-
array(
|
| 531 |
-
'scheme' => 'https',
|
| 532 |
-
'host' => wp_parse_url( home_url(), PHP_URL_HOST ),
|
| 533 |
-
'path' => isset( $_SERVER['REQUEST_URI'] ) ? strtok( wp_unslash( $_SERVER['REQUEST_URI'] ), '?' ) : '/',
|
| 534 |
-
),
|
| 535 |
-
wp_parse_url( $location )
|
| 536 |
-
);
|
| 537 |
-
|
| 538 |
-
$absolute_location = '';
|
| 539 |
-
if ( 'https' === $parsed_location['scheme'] ) {
|
| 540 |
-
$absolute_location .= $parsed_location['scheme'] . ':';
|
| 541 |
-
}
|
| 542 |
-
$absolute_location .= '//' . $parsed_location['host'];
|
| 543 |
-
if ( isset( $parsed_location['port'] ) ) {
|
| 544 |
-
$absolute_location .= ':' . $parsed_location['port'];
|
| 545 |
-
}
|
| 546 |
-
$absolute_location .= $parsed_location['path'];
|
| 547 |
-
if ( isset( $parsed_location['query'] ) ) {
|
| 548 |
-
$absolute_location .= '?' . $parsed_location['query'];
|
| 549 |
-
}
|
| 550 |
-
if ( isset( $parsed_location['fragment'] ) ) {
|
| 551 |
-
$absolute_location .= '#' . $parsed_location['fragment'];
|
| 552 |
-
}
|
| 553 |
|
| 554 |
-
|
| 555 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 556 |
|
| 557 |
-
|
| 558 |
}
|
| 559 |
|
| 560 |
/**
|
|
@@ -658,41 +940,22 @@ class AMP_Theme_Support {
|
|
| 658 |
/**
|
| 659 |
* Prepends template hierarchy with template_dir for AMP paired mode templates.
|
| 660 |
*
|
| 661 |
-
* @see get_query_template()
|
| 662 |
-
*
|
| 663 |
* @param array $templates Template hierarchy.
|
| 664 |
-
* @
|
| 665 |
*/
|
| 666 |
-
public static function
|
| 667 |
-
$
|
| 668 |
-
$args = array_shift( $support );
|
| 669 |
if ( isset( $args['template_dir'] ) ) {
|
| 670 |
$amp_templates = array();
|
| 671 |
foreach ( $templates as $template ) {
|
| 672 |
-
$amp_templates[] = $args['template_dir'] . '/' . $template;
|
|
|
|
| 673 |
}
|
| 674 |
$templates = $amp_templates;
|
| 675 |
}
|
| 676 |
return $templates;
|
| 677 |
}
|
| 678 |
|
| 679 |
-
/**
|
| 680 |
-
* Redirect to the non-canonical URL when the template to include is empty.
|
| 681 |
-
*
|
| 682 |
-
* This is a failsafe in case an index.php is not located in the AMP template_dir,
|
| 683 |
-
* and the available_callback fails to omit a given request from being available in AMP.
|
| 684 |
-
*
|
| 685 |
-
* @param string $template Template to include.
|
| 686 |
-
* @return string Template to include.
|
| 687 |
-
*/
|
| 688 |
-
public static function filter_paired_template_include( $template ) {
|
| 689 |
-
if ( empty( $template ) || ! self::is_paired_available() ) {
|
| 690 |
-
wp_safe_redirect( self::get_current_canonical_url(), 302 ); // Temporary redirect because support may come later.
|
| 691 |
-
exit;
|
| 692 |
-
}
|
| 693 |
-
return $template;
|
| 694 |
-
}
|
| 695 |
-
|
| 696 |
/**
|
| 697 |
* Get canonical URL for current request.
|
| 698 |
*
|
|
@@ -858,43 +1121,117 @@ class AMP_Theme_Support {
|
|
| 858 |
}
|
| 859 |
|
| 860 |
/**
|
| 861 |
-
*
|
|
|
|
|
|
|
| 862 |
*/
|
| 863 |
-
public static function
|
| 864 |
-
|
| 865 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 866 |
}
|
| 867 |
|
| 868 |
/**
|
| 869 |
-
* Ensure markup required by AMP
|
| 870 |
*
|
| 871 |
-
* Ensure meta[charset], meta[name=viewport], and link[rel=canonical]
|
| 872 |
-
* may have removed an illegal meta[http-equiv] or meta[name=viewport].
|
| 873 |
-
* canonical URL by default
|
| 874 |
*
|
| 875 |
* @since 0.7
|
|
|
|
|
|
|
| 876 |
* @todo All of this might be better placed inside of a sanitizer.
|
| 877 |
*
|
| 878 |
-
* @param DOMDocument $dom
|
|
|
|
| 879 |
*/
|
| 880 |
-
public static function ensure_required_markup( DOMDocument $dom ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 881 |
$head = $dom->getElementsByTagName( 'head' )->item( 0 );
|
| 882 |
if ( ! $head ) {
|
| 883 |
$head = $dom->createElement( 'head' );
|
| 884 |
$dom->documentElement->insertBefore( $head, $dom->documentElement->firstChild );
|
| 885 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 886 |
$meta_charset = null;
|
| 887 |
$meta_viewport = null;
|
|
|
|
| 888 |
foreach ( $head->getElementsByTagName( 'meta' ) as $meta ) {
|
| 889 |
-
|
| 890 |
-
* Meta.
|
| 891 |
-
*
|
| 892 |
-
* @var DOMElement $meta
|
| 893 |
-
*/
|
| 894 |
-
if ( $meta->hasAttribute( 'charset' ) && 'utf-8' === strtolower( $meta->getAttribute( 'charset' ) ) ) { // @todo Also look for meta[http-equiv="Content-Type"]?
|
| 895 |
$meta_charset = $meta;
|
| 896 |
} elseif ( 'viewport' === $meta->getAttribute( 'name' ) ) {
|
| 897 |
$meta_viewport = $meta;
|
|
|
|
|
|
|
| 898 |
}
|
| 899 |
}
|
| 900 |
if ( ! $meta_charset ) {
|
|
@@ -902,43 +1239,166 @@ class AMP_Theme_Support {
|
|
| 902 |
$meta_charset = AMP_DOM_Utils::create_node( $dom, 'meta', array(
|
| 903 |
'charset' => 'utf-8',
|
| 904 |
) );
|
| 905 |
-
|
|
|
|
| 906 |
}
|
|
|
|
|
|
|
| 907 |
if ( ! $meta_viewport ) {
|
| 908 |
$meta_viewport = AMP_DOM_Utils::create_node( $dom, 'meta', array(
|
| 909 |
'name' => 'viewport',
|
| 910 |
-
'content' => 'width=device-width
|
| 911 |
) );
|
| 912 |
-
|
| 913 |
-
|
| 914 |
-
// Prevent schema.org duplicates.
|
| 915 |
-
$has_schema_org_metadata = false;
|
| 916 |
-
foreach ( $head->getElementsByTagName( 'script' ) as $script ) {
|
| 917 |
-
if ( 'application/ld+json' === $script->getAttribute( 'type' ) && false !== strpos( $script->nodeValue, 'schema.org' ) ) {
|
| 918 |
-
$has_schema_org_metadata = true;
|
| 919 |
-
break;
|
| 920 |
-
}
|
| 921 |
}
|
| 922 |
-
|
| 923 |
-
|
| 924 |
-
|
| 925 |
-
|
|
|
|
|
|
|
|
|
|
| 926 |
}
|
| 927 |
-
|
| 928 |
-
$
|
| 929 |
-
|
| 930 |
-
|
| 931 |
-
|
| 932 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 933 |
}
|
|
|
|
| 934 |
}
|
| 935 |
-
|
| 936 |
-
|
| 937 |
-
|
| 938 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 939 |
) );
|
| 940 |
-
$head->appendChild( $rel_canonical );
|
| 941 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 942 |
}
|
| 943 |
|
| 944 |
/**
|
|
@@ -971,7 +1431,7 @@ class AMP_Theme_Support {
|
|
| 971 |
public static function start_output_buffering() {
|
| 972 |
/*
|
| 973 |
* Disable the New Relic Browser agent on AMP responses.
|
| 974 |
-
* This prevents
|
| 975 |
* https://docs.newrelic.com/docs/browser/new-relic-browser/troubleshooting/google-amp-validator-fails-due-3rd-party-script
|
| 976 |
* Sites with New Relic will need to specially configure New Relic for AMP:
|
| 977 |
* https://docs.newrelic.com/docs/browser/new-relic-browser/installation/monitor-amp-pages-new-relic-browser
|
|
@@ -1042,16 +1502,18 @@ class AMP_Theme_Support {
|
|
| 1042 |
* @since 0.7
|
| 1043 |
*
|
| 1044 |
* @param string $response HTML document response. By default it expects a complete document.
|
| 1045 |
-
* @param array $args
|
| 1046 |
-
* Args to send to the preprocessor/sanitizer.
|
| 1047 |
-
*
|
| 1048 |
-
* @type callable $remove_invalid_callback Function to call whenever a node is removed due to being invalid.
|
| 1049 |
-
* }
|
| 1050 |
* @return string AMP document response.
|
| 1051 |
* @global int $content_width
|
| 1052 |
*/
|
| 1053 |
public static function prepare_response( $response, $args = array() ) {
|
| 1054 |
global $content_width;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1055 |
|
| 1056 |
/*
|
| 1057 |
* Check if the response starts with HTML markup.
|
|
@@ -1062,7 +1524,11 @@ class AMP_Theme_Support {
|
|
| 1062 |
return $response;
|
| 1063 |
}
|
| 1064 |
|
| 1065 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1066 |
|
| 1067 |
$args = array_merge(
|
| 1068 |
array(
|
|
@@ -1070,11 +1536,129 @@ class AMP_Theme_Support {
|
|
| 1070 |
'use_document_element' => true,
|
| 1071 |
'allow_dirty_styles' => self::is_customize_preview_iframe(), // Dirty styles only needed when editing (e.g. for edit shortcodes).
|
| 1072 |
'allow_dirty_scripts' => is_customize_preview(), // Scripts are always needed to inject changeset UUID.
|
| 1073 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1074 |
),
|
| 1075 |
$args
|
| 1076 |
);
|
| 1077 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1078 |
/*
|
| 1079 |
* Make sure that <meta charset> is present in output prior to parsing.
|
| 1080 |
* Note that the meta charset is supposed to appear within the first 1024 bytes.
|
|
@@ -1088,65 +1672,246 @@ class AMP_Theme_Support {
|
|
| 1088 |
1
|
| 1089 |
);
|
| 1090 |
}
|
| 1091 |
-
$dom = AMP_DOM_Utils::get_dom( $response );
|
| 1092 |
-
|
| 1093 |
-
$xpath = new DOMXPath( $dom );
|
| 1094 |
|
|
|
|
| 1095 |
$head = $dom->getElementsByTagName( 'head' )->item( 0 );
|
| 1096 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1097 |
if ( isset( $head ) ) {
|
| 1098 |
-
|
| 1099 |
foreach ( $xpath->query( '//body//script[ @custom-element or @custom-template ]' ) as $script ) {
|
| 1100 |
-
$head->appendChild( $script );
|
| 1101 |
}
|
| 1102 |
}
|
| 1103 |
|
| 1104 |
-
// Ensure the mandatory amp attribute is present on the html element
|
| 1105 |
if ( ! $dom->documentElement->hasAttribute( 'amp' ) && ! $dom->documentElement->hasAttribute( '⚡️' ) ) {
|
| 1106 |
$dom->documentElement->setAttribute( 'amp', '' );
|
| 1107 |
}
|
| 1108 |
|
|
|
|
|
|
|
| 1109 |
$assets = AMP_Content_Sanitizer::sanitize_document( $dom, self::$sanitizer_classes, $args );
|
| 1110 |
|
| 1111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1112 |
|
| 1113 |
// @todo If 'utf-8' is not the blog charset, then we'll need to do some character encoding conversation or "entityification".
|
| 1114 |
if ( 'utf-8' !== strtolower( get_bloginfo( 'charset' ) ) ) {
|
| 1115 |
-
/* translators: %s
|
| 1116 |
trigger_error( esc_html( sprintf( __( 'The database has the %s encoding when it needs to be utf-8 to work with AMP.', 'amp' ), get_bloginfo( 'charset' ) ) ), E_USER_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
|
| 1117 |
}
|
| 1118 |
|
| 1119 |
-
|
| 1120 |
-
|
| 1121 |
-
|
| 1122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1123 |
}
|
| 1124 |
|
| 1125 |
$response = "<!DOCTYPE html>\n";
|
| 1126 |
$response .= AMP_DOM_Utils::get_content_from_dom_node( $dom, $dom->documentElement );
|
| 1127 |
|
| 1128 |
-
|
| 1129 |
-
|
| 1130 |
-
$
|
| 1131 |
-
|
| 1132 |
-
|
| 1133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1134 |
}
|
| 1135 |
|
| 1136 |
-
|
| 1137 |
-
|
| 1138 |
-
|
| 1139 |
-
|
| 1140 |
-
|
| 1141 |
-
$script_tags,
|
| 1142 |
-
$response,
|
| 1143 |
-
1
|
| 1144 |
-
);
|
| 1145 |
}
|
| 1146 |
|
| 1147 |
return $response;
|
| 1148 |
}
|
| 1149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1150 |
/**
|
| 1151 |
* Adds 'data-amp-layout' to the allowed <img> attributes for wp_kses().
|
| 1152 |
*
|
|
@@ -1176,4 +1941,74 @@ class AMP_Theme_Support {
|
|
| 1176 |
// Enqueue default styles expected by sanitizer.
|
| 1177 |
wp_enqueue_style( 'amp-default', amp_get_asset_url( 'css/amp-default.css' ), array(), AMP__VERSION );
|
| 1178 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1179 |
}
|
| 13 |
class AMP_Theme_Support {
|
| 14 |
|
| 15 |
/**
|
| 16 |
+
* Theme support slug.
|
| 17 |
*
|
| 18 |
* @var string
|
| 19 |
*/
|
| 20 |
+
const SLUG = 'amp';
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* Response cache group name.
|
| 24 |
+
*
|
| 25 |
+
* @var string
|
| 26 |
+
*/
|
| 27 |
+
const RESPONSE_CACHE_GROUP = 'amp-response';
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* Post-processor cache effectiveness group name.
|
| 31 |
+
*
|
| 32 |
+
* @var string
|
| 33 |
+
*/
|
| 34 |
+
const POST_PROCESSOR_CACHE_EFFECTIVENESS_GROUP = 'post_processor_cache_effectiveness_group';
|
| 35 |
+
|
| 36 |
+
/**
|
| 37 |
+
* Post-processor cache effectiveness key name.
|
| 38 |
+
*
|
| 39 |
+
* @var string
|
| 40 |
+
*/
|
| 41 |
+
const POST_PROCESSOR_CACHE_EFFECTIVENESS_KEY = 'post_processor_cache_effectiveness';
|
| 42 |
+
|
| 43 |
+
/**
|
| 44 |
+
* Cache miss threshold for determining when to disable post-processor cache.
|
| 45 |
+
*
|
| 46 |
+
* @var int
|
| 47 |
+
*/
|
| 48 |
+
const CACHE_MISS_THRESHOLD = 20;
|
| 49 |
+
|
| 50 |
+
/**
|
| 51 |
+
* Cache miss URL option name.
|
| 52 |
+
*
|
| 53 |
+
* @var string
|
| 54 |
+
*/
|
| 55 |
+
const CACHE_MISS_URL_OPTION = 'amp_cache_miss_url';
|
| 56 |
|
| 57 |
/**
|
| 58 |
* Sanitizer classes.
|
| 94 |
);
|
| 95 |
|
| 96 |
/**
|
| 97 |
+
* Start time when init was called.
|
| 98 |
*
|
| 99 |
+
* @since 1.0
|
| 100 |
+
* @var float
|
|
|
|
| 101 |
*/
|
| 102 |
+
public static $init_start_time;
|
| 103 |
|
| 104 |
/**
|
| 105 |
+
* Whether output buffering has started.
|
| 106 |
*
|
| 107 |
* @since 0.7
|
| 108 |
+
* @var bool
|
|
|
|
| 109 |
*/
|
| 110 |
+
protected static $is_output_buffering = false;
|
| 111 |
|
| 112 |
/**
|
| 113 |
+
* Theme support options that were added via option.
|
| 114 |
*
|
| 115 |
+
* @since 1.0
|
| 116 |
* @var bool
|
| 117 |
*/
|
| 118 |
+
protected static $support_added_via_option = false;
|
| 119 |
|
| 120 |
/**
|
| 121 |
* Initialize.
|
| 122 |
+
*
|
| 123 |
+
* @since 0.7
|
| 124 |
*/
|
| 125 |
public static function init() {
|
| 126 |
+
self::read_theme_support();
|
| 127 |
+
if ( ! current_theme_supports( self::SLUG ) ) {
|
| 128 |
return;
|
| 129 |
}
|
| 130 |
|
| 131 |
+
self::$init_start_time = microtime( true );
|
|
|
|
|
|
|
|
|
|
| 132 |
|
| 133 |
require_once AMP__DIR__ . '/includes/amp-post-template-actions.php';
|
| 134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
add_action( 'widgets_init', array( __CLASS__, 'register_widgets' ) );
|
| 136 |
|
| 137 |
/*
|
| 142 |
add_action( 'wp', array( __CLASS__, 'finish_init' ), PHP_INT_MAX );
|
| 143 |
}
|
| 144 |
|
| 145 |
+
/**
|
| 146 |
+
* Determine whether theme support was added via admin option.
|
| 147 |
+
*
|
| 148 |
+
* @since 1.0
|
| 149 |
+
* @see AMP_Theme_Support::read_theme_support()
|
| 150 |
+
*
|
| 151 |
+
* @return bool Support added via option.
|
| 152 |
+
*/
|
| 153 |
+
public static function is_support_added_via_option() {
|
| 154 |
+
return self::$support_added_via_option;
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
/**
|
| 158 |
+
* Check theme support args or add theme support if option is set in the admin.
|
| 159 |
+
*
|
| 160 |
+
* The DB option is only considered if the theme does not already explicitly support AMP.
|
| 161 |
+
*
|
| 162 |
+
* @see AMP_Theme_Support::is_support_added_via_option()
|
| 163 |
+
* @see AMP_Post_Type_Support::add_post_type_support() For where post type support is added, since it is irrespective of theme support.
|
| 164 |
+
*/
|
| 165 |
+
public static function read_theme_support() {
|
| 166 |
+
$theme_support_option = AMP_Options_Manager::get_option( 'theme_support' );
|
| 167 |
+
if ( current_theme_supports( self::SLUG ) ) {
|
| 168 |
+
$args = self::get_theme_support_args();
|
| 169 |
+
|
| 170 |
+
// Validate theme support usage.
|
| 171 |
+
$keys = array( 'template_dir', 'comments_live_list', 'paired', 'templates_supported', 'available_callback' );
|
| 172 |
+
|
| 173 |
+
if ( count( array_diff( array_keys( $args ), $keys ) ) !== 0 ) {
|
| 174 |
+
_doing_it_wrong( 'add_theme_support', esc_html( sprintf( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
|
| 175 |
+
/* translators: 1: comma-separated list of expected keys, 2: comma-separated list of actual keys */
|
| 176 |
+
__( 'Expected AMP theme support to keys (%1$s) but saw (%2$s)', 'amp' ),
|
| 177 |
+
join( ', ', $keys ),
|
| 178 |
+
join( ', ', array_keys( $args ) )
|
| 179 |
+
) ), '1.0' );
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
if ( isset( $args['available_callback'] ) ) {
|
| 183 |
+
_doing_it_wrong( 'add_theme_support', esc_html__( 'The available_callback is deprecated when adding amp theme support in favor of declaratively setting the supported_templates.', 'amp' ), '1.0' );
|
| 184 |
+
}
|
| 185 |
+
self::$support_added_via_option = false;
|
| 186 |
+
} elseif ( 'disabled' !== $theme_support_option ) {
|
| 187 |
+
add_theme_support( self::SLUG, array(
|
| 188 |
+
'paired' => ( 'paired' === $theme_support_option ),
|
| 189 |
+
) );
|
| 190 |
+
self::$support_added_via_option = true;
|
| 191 |
+
} elseif ( AMP_Validation_Manager::is_theme_support_forced() ) {
|
| 192 |
+
add_theme_support( self::SLUG );
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
/**
|
| 197 |
+
* Get the theme support args.
|
| 198 |
+
*
|
| 199 |
+
* This avoids having to repeatedly call `get_theme_support()`, check the args, shift an item off the array, and so on.
|
| 200 |
+
*
|
| 201 |
+
* @since 1.0
|
| 202 |
+
*
|
| 203 |
+
* @return array|false Theme support args, or false if theme support is not present.
|
| 204 |
+
*/
|
| 205 |
+
public static function get_theme_support_args() {
|
| 206 |
+
if ( ! current_theme_supports( self::SLUG ) ) {
|
| 207 |
+
return false;
|
| 208 |
+
}
|
| 209 |
+
$support = get_theme_support( self::SLUG );
|
| 210 |
+
if ( true === $support ) {
|
| 211 |
+
return array(
|
| 212 |
+
'paired' => false,
|
| 213 |
+
);
|
| 214 |
+
}
|
| 215 |
+
if ( ! isset( $support[0] ) || ! is_array( $support[0] ) ) {
|
| 216 |
+
return array();
|
| 217 |
+
}
|
| 218 |
+
return $support[0];
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
/**
|
| 222 |
* Finish initialization once query vars are set.
|
| 223 |
*
|
| 225 |
*/
|
| 226 |
public static function finish_init() {
|
| 227 |
if ( ! is_amp_endpoint() ) {
|
| 228 |
+
|
| 229 |
+
// Redirect to AMP-less variable if AMP is not available for this URL and yet the query var is present.
|
| 230 |
+
if ( isset( $_GET[ amp_get_slug() ] ) ) { // WPCS: csrf ok.
|
| 231 |
+
self::redirect_ampless_url();
|
|
|
|
|
|
|
| 232 |
}
|
| 233 |
+
|
| 234 |
+
amp_add_frontend_actions();
|
| 235 |
return;
|
| 236 |
}
|
| 237 |
|
| 238 |
+
self::ensure_proper_amp_location();
|
| 239 |
+
|
| 240 |
+
$theme_support = self::get_theme_support_args();
|
| 241 |
+
if ( ! empty( $theme_support['template_dir'] ) ) {
|
| 242 |
+
self::add_amp_template_filters();
|
| 243 |
}
|
| 244 |
|
| 245 |
self::add_hooks();
|
| 246 |
self::$sanitizer_classes = amp_get_content_sanitizers();
|
| 247 |
+
self::$sanitizer_classes = AMP_Validation_Manager::filter_sanitizer_args( self::$sanitizer_classes );
|
| 248 |
self::$embed_handlers = self::register_content_embed_handlers();
|
| 249 |
+
self::$sanitizer_classes['AMP_Embed_Sanitizer']['embed_handlers'] = self::$embed_handlers;
|
| 250 |
+
|
| 251 |
+
foreach ( self::$sanitizer_classes as $sanitizer_class => $args ) {
|
| 252 |
+
if ( method_exists( $sanitizer_class, 'add_buffering_hooks' ) ) {
|
| 253 |
+
call_user_func( array( $sanitizer_class, 'add_buffering_hooks' ), $args );
|
| 254 |
+
}
|
| 255 |
+
}
|
| 256 |
}
|
| 257 |
|
| 258 |
/**
|
| 259 |
+
* Ensure that the current AMP location is correct.
|
| 260 |
*
|
| 261 |
+
* @since 1.0
|
| 262 |
+
*
|
| 263 |
+
* @param bool $exit Whether to exit after redirecting.
|
| 264 |
+
* @return bool Whether redirection was done. Naturally this is irrelevant if $exit is true.
|
| 265 |
*/
|
| 266 |
+
public static function ensure_proper_amp_location( $exit = true ) {
|
| 267 |
+
$has_query_var = false !== get_query_var( amp_get_slug(), false ); // May come from URL param or endpoint slug.
|
| 268 |
+
$has_url_param = isset( $_GET[ amp_get_slug() ] ); // WPCS: CSRF OK.
|
| 269 |
+
|
| 270 |
+
if ( amp_is_canonical() ) {
|
| 271 |
+
/*
|
| 272 |
+
* When AMP native/canonical, then when there is an /amp/ endpoint or ?amp URL param,
|
| 273 |
+
* then a redirect needs to be done to the URL without any AMP indicator in the URL.
|
| 274 |
+
*/
|
| 275 |
+
if ( $has_query_var || $has_url_param ) {
|
| 276 |
+
return self::redirect_ampless_url( $exit );
|
| 277 |
+
}
|
| 278 |
+
} else {
|
| 279 |
+
/*
|
| 280 |
+
* When in AMP paired mode *with* theme support, then the proper AMP URL has the 'amp' URL param
|
| 281 |
+
* and not the /amp/ endpoint. The URL param is now the exclusive way to mark AMP in paired mode
|
| 282 |
+
* when amp theme support present. This is important for plugins to be able to reliably call
|
| 283 |
+
* is_amp_endpoint() before the parse_query action.
|
| 284 |
+
*/
|
| 285 |
+
if ( $has_query_var && ! $has_url_param ) {
|
| 286 |
+
$old_url = amp_get_current_url();
|
| 287 |
+
$new_url = add_query_arg( amp_get_slug(), '', amp_remove_endpoint( $old_url ) );
|
| 288 |
+
if ( $old_url !== $new_url ) {
|
| 289 |
+
wp_safe_redirect( $new_url, 302 );
|
| 290 |
+
// @codeCoverageIgnoreStart
|
| 291 |
+
if ( $exit ) {
|
| 292 |
+
exit;
|
| 293 |
+
}
|
| 294 |
+
return true;
|
| 295 |
+
// @codeCoverageIgnoreEnd
|
| 296 |
+
}
|
| 297 |
}
|
| 298 |
+
}
|
| 299 |
+
return false;
|
| 300 |
+
}
|
| 301 |
|
| 302 |
+
/**
|
| 303 |
+
* Redirect to non-AMP version of the current URL, such as because AMP is canonical or there are unaccepted validation errors.
|
| 304 |
+
*
|
| 305 |
+
* If the current URL is already AMP-less then do nothing.
|
| 306 |
+
*
|
| 307 |
+
* @since 0.7
|
| 308 |
+
* @since 1.0 Added $exit param.
|
| 309 |
+
* @since 1.0 Renamed from redirect_canonical_amp().
|
| 310 |
+
*
|
| 311 |
+
* @param bool $exit Whether to exit after redirecting.
|
| 312 |
+
* @return bool Whether redirection was done. Naturally this is irrelevant if $exit is true.
|
| 313 |
+
*/
|
| 314 |
+
public static function redirect_ampless_url( $exit = true ) {
|
| 315 |
+
$current_url = amp_get_current_url();
|
| 316 |
+
$ampless_url = amp_remove_endpoint( $current_url );
|
| 317 |
+
if ( $ampless_url === $current_url ) {
|
| 318 |
+
return false;
|
| 319 |
+
}
|
| 320 |
|
| 321 |
+
/*
|
| 322 |
+
* Temporary redirect because AMP URL may return when blocking validation errors
|
| 323 |
+
* occur or when a non-canonical AMP theme is used.
|
| 324 |
+
*/
|
| 325 |
+
wp_safe_redirect( $ampless_url, 302 );
|
| 326 |
+
// @codeCoverageIgnoreStart
|
| 327 |
+
if ( $exit ) {
|
| 328 |
exit;
|
| 329 |
}
|
| 330 |
+
return true;
|
| 331 |
+
// @codeCoverageIgnoreEnd
|
| 332 |
}
|
| 333 |
|
| 334 |
/**
|
| 335 |
* Determines whether paired mode is available.
|
| 336 |
*
|
| 337 |
* When 'amp' theme support has not been added or canonical mode is enabled, then this returns false.
|
|
|
|
|
|
|
| 338 |
*
|
| 339 |
+
* @since 0.7
|
| 340 |
+
*
|
| 341 |
+
* @see amp_is_canonical()
|
| 342 |
* @return bool Whether available.
|
| 343 |
*/
|
| 344 |
public static function is_paired_available() {
|
| 345 |
+
if ( ! current_theme_supports( self::SLUG ) ) {
|
|
|
|
| 346 |
return false;
|
| 347 |
}
|
| 348 |
|
| 349 |
+
if ( amp_is_canonical() ) {
|
| 350 |
return false;
|
| 351 |
}
|
| 352 |
|
| 353 |
+
$availability = self::get_template_availability();
|
| 354 |
+
return $availability['supported'];
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
}
|
| 356 |
|
| 357 |
/**
|
| 367 |
}
|
| 368 |
|
| 369 |
/**
|
| 370 |
+
* Register filters for loading AMP-specific templates.
|
| 371 |
*/
|
| 372 |
+
public static function add_amp_template_filters() {
|
| 373 |
foreach ( self::$template_types as $template_type ) {
|
| 374 |
+
add_filter( "{$template_type}_template_hierarchy", array( __CLASS__, 'filter_amp_template_hierarchy' ) );
|
| 375 |
}
|
|
|
|
| 376 |
}
|
| 377 |
|
| 378 |
/**
|
| 379 |
+
* Determine template availability of AMP for the given query.
|
| 380 |
+
*
|
| 381 |
+
* This is not intended to return whether AMP is available for a _specific_ post. For that, use `post_supports_amp()`.
|
| 382 |
+
*
|
| 383 |
+
* @since 1.0
|
| 384 |
+
* @global WP_Query $wp_query
|
| 385 |
+
* @see post_supports_amp()
|
| 386 |
+
*
|
| 387 |
+
* @param WP_Query|WP_Post|null $query Query or queried post. If null then the global query will be used.
|
| 388 |
+
* @return array {
|
| 389 |
+
* Template availability.
|
| 390 |
+
*
|
| 391 |
+
* @type bool $supported Whether the template is supported in AMP.
|
| 392 |
+
* @type bool|null $immutable Whether the supported status is known to be unchangeable.
|
| 393 |
+
* @type string|null $template The ID of the matched template (conditional), such as 'is_singular', or null if nothing was matched.
|
| 394 |
+
* @type string[] $errors List of the errors or reasons for why the template is not available.
|
| 395 |
+
* }
|
| 396 |
*/
|
| 397 |
+
public static function get_template_availability( $query = null ) {
|
| 398 |
+
global $wp_query;
|
| 399 |
+
if ( ! $query ) {
|
| 400 |
+
$query = $wp_query;
|
| 401 |
+
} elseif ( $query instanceof WP_Post ) {
|
| 402 |
+
$post = $query;
|
| 403 |
+
$query = new WP_Query();
|
| 404 |
+
if ( 'page' === $post->post_type ) {
|
| 405 |
+
$query->set( 'page_id', $post->ID );
|
| 406 |
+
} else {
|
| 407 |
+
$query->set( 'p', $post->ID );
|
| 408 |
+
}
|
| 409 |
+
$query->queried_object = $post;
|
| 410 |
+
$query->queried_object_id = $post->ID;
|
| 411 |
+
$query->parse_query_vars();
|
| 412 |
+
}
|
| 413 |
|
| 414 |
+
$default_response = array(
|
| 415 |
+
'errors' => array(),
|
| 416 |
+
'supported' => false,
|
| 417 |
+
'immutable' => null,
|
| 418 |
+
'template' => null,
|
| 419 |
+
);
|
| 420 |
|
| 421 |
+
if ( ! ( $query instanceof WP_Query ) ) {
|
| 422 |
+
_doing_it_wrong( __METHOD__, esc_html__( 'No WP_Query available.', 'amp' ), '1.0' );
|
| 423 |
+
return array_merge(
|
| 424 |
+
$default_response,
|
| 425 |
+
array( 'errors' => array( 'no_query_available' ) )
|
| 426 |
+
);
|
| 427 |
+
}
|
| 428 |
|
| 429 |
+
$theme_support_args = self::get_theme_support_args();
|
| 430 |
+
if ( false === $theme_support_args ) {
|
| 431 |
+
return array_merge(
|
| 432 |
+
$default_response,
|
| 433 |
+
array( 'errors' => array( 'no_theme_support' ) )
|
| 434 |
+
);
|
| 435 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
|
| 437 |
+
// Support available_callback from 0.7, though it is deprecated.
|
| 438 |
+
if ( isset( $theme_support_args['available_callback'] ) && is_callable( $theme_support_args['available_callback'] ) ) {
|
| 439 |
+
/**
|
| 440 |
+
* Queried object.
|
| 441 |
+
*
|
| 442 |
+
* @var WP_Post $queried_object
|
| 443 |
+
*/
|
| 444 |
+
$queried_object = $query->get_queried_object();
|
| 445 |
+
if ( ( is_singular() || $query->is_posts_page ) && ! post_supports_amp( $queried_object ) ) {
|
| 446 |
+
return array_merge(
|
| 447 |
+
$default_response,
|
| 448 |
+
array(
|
| 449 |
+
'errors' => array( 'no-post-support' ),
|
| 450 |
+
'supported' => false,
|
| 451 |
+
'immutable' => true,
|
| 452 |
+
)
|
| 453 |
+
);
|
| 454 |
+
}
|
| 455 |
|
| 456 |
+
$response = array_merge(
|
| 457 |
+
$default_response,
|
| 458 |
+
array(
|
| 459 |
+
'supported' => call_user_func( $theme_support_args['available_callback'] ),
|
| 460 |
+
'immutable' => true,
|
| 461 |
+
)
|
| 462 |
+
);
|
| 463 |
+
if ( ! $response['supported'] ) {
|
| 464 |
+
$response['errors'][] = 'available_callback';
|
| 465 |
+
}
|
| 466 |
+
return $response;
|
| 467 |
+
}
|
| 468 |
|
| 469 |
+
$all_templates_supported_by_theme_support = false;
|
| 470 |
+
if ( isset( $theme_support_args['templates_supported'] ) ) {
|
| 471 |
+
$all_templates_supported_by_theme_support = 'all' === $theme_support_args['templates_supported'];
|
| 472 |
+
}
|
| 473 |
+
$all_templates_supported = (
|
| 474 |
+
$all_templates_supported_by_theme_support || AMP_Options_Manager::get_option( 'all_templates_supported' )
|
| 475 |
+
);
|
| 476 |
|
| 477 |
+
// Make sure global $wp_query is set in case of conditionals that unfortunately look at global scope.
|
| 478 |
+
$prev_query = $wp_query;
|
| 479 |
+
$wp_query = $query; // WPCS: override ok.
|
|
|
|
|
|
|
|
|
|
| 480 |
|
| 481 |
+
$matching_templates = array();
|
| 482 |
+
$supportable_templates = self::get_supportable_templates();
|
| 483 |
+
foreach ( $supportable_templates as $id => $supportable_template ) {
|
| 484 |
+
if ( empty( $supportable_template['callback'] ) ) {
|
| 485 |
+
$callback = $id;
|
| 486 |
+
} else {
|
| 487 |
+
$callback = $supportable_template['callback'];
|
| 488 |
+
}
|
| 489 |
|
| 490 |
+
// If the callback is a method on the query, then call the method on the query itself.
|
| 491 |
+
if ( is_string( $callback ) && 'is_' === substr( $callback, 0, 3 ) && method_exists( $query, $callback ) ) {
|
| 492 |
+
$is_match = call_user_func( array( $query, $callback ) );
|
| 493 |
+
} elseif ( is_callable( $callback ) ) {
|
| 494 |
+
$is_match = call_user_func( $callback, $query );
|
| 495 |
+
} else {
|
| 496 |
+
/* translators: %s: the supportable template ID. */
|
| 497 |
+
_doing_it_wrong( __FUNCTION__, esc_html( sprintf( __( 'Supportable template "%s" does not have a callable callback.', 'amp' ), $id ) ), '1.0' );
|
| 498 |
+
$is_match = false;
|
| 499 |
+
}
|
| 500 |
|
| 501 |
+
if ( $is_match ) {
|
| 502 |
+
$matching_templates[ $id ] = array(
|
| 503 |
+
'template' => $id,
|
| 504 |
+
'supported' => ! empty( $supportable_template['supported'] ),
|
| 505 |
+
'immutable' => ! empty( $supportable_template['immutable'] ),
|
| 506 |
+
);
|
| 507 |
+
}
|
| 508 |
+
}
|
| 509 |
|
| 510 |
+
// Restore previous $wp_query (if any).
|
| 511 |
+
$wp_query = $prev_query; // WPCS: override ok.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 512 |
|
| 513 |
+
// Make sure children override their parents.
|
| 514 |
+
$matching_template_ids = array_keys( $matching_templates );
|
| 515 |
+
foreach ( array_diff( array_keys( $supportable_templates ), $matching_template_ids ) as $template_id ) {
|
| 516 |
+
unset( $supportable_templates[ $template_id ] );
|
| 517 |
+
}
|
| 518 |
+
foreach ( $matching_template_ids as $id ) {
|
| 519 |
+
$has_children = false;
|
| 520 |
+
foreach ( $supportable_templates as $other_id => $supportable_template ) {
|
| 521 |
+
if ( $other_id === $id ) {
|
| 522 |
+
continue;
|
| 523 |
+
}
|
| 524 |
+
if ( isset( $supportable_template['parent'] ) && $id === $supportable_template['parent'] ) {
|
| 525 |
+
$has_children = true;
|
| 526 |
+
break;
|
| 527 |
+
}
|
| 528 |
}
|
| 529 |
+
|
| 530 |
+
// Delete all matching parent templates since the child will override them.
|
| 531 |
+
if ( ! $has_children ) {
|
| 532 |
+
$supportable_template = $supportable_templates[ $id ];
|
| 533 |
+
while ( ! empty( $supportable_template['parent'] ) ) {
|
| 534 |
+
$parent = $supportable_template['parent'];
|
| 535 |
+
$supportable_template = $supportable_templates[ $parent ];
|
| 536 |
+
|
| 537 |
+
// Let the child supported status override the parent's supported status.
|
| 538 |
+
unset( $matching_templates[ $parent ] );
|
|
|
|
|
|
|
|
|
|
| 539 |
}
|
| 540 |
+
}
|
| 541 |
+
}
|
| 542 |
+
|
| 543 |
+
// The is_home() condition is the default so discard it if there are other matching templates.
|
| 544 |
+
if ( count( $matching_templates ) > 1 && isset( $matching_templates['is_home'] ) ) {
|
| 545 |
+
unset( $matching_templates['is_home'] );
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
/*
|
| 549 |
+
* If there are more than one matching templates, then something is probably not right.
|
| 550 |
+
* Template conditions need to be set up properly to prevent this from happening.
|
| 551 |
+
*/
|
| 552 |
+
if ( count( $matching_templates ) > 1 ) {
|
| 553 |
+
_doing_it_wrong( __METHOD__, esc_html__( 'Did not expect there to be more than one matching template. Did you filter amp_supportable_templates to not honor the template hierarchy?', 'amp' ), '1.0' );
|
| 554 |
+
}
|
| 555 |
|
| 556 |
+
$matching_template = array_shift( $matching_templates );
|
| 557 |
+
|
| 558 |
+
// If there aren't any matching templates left that are supported, then we consider it to not be available.
|
| 559 |
+
if ( ! $matching_template ) {
|
| 560 |
+
if ( $all_templates_supported ) {
|
| 561 |
+
return array_merge(
|
| 562 |
+
$default_response,
|
| 563 |
+
array(
|
| 564 |
+
'supported' => true,
|
| 565 |
+
)
|
| 566 |
+
);
|
| 567 |
+
} else {
|
| 568 |
+
return array_merge(
|
| 569 |
+
$default_response,
|
| 570 |
+
array( 'errors' => array( 'no_matching_template' ) )
|
| 571 |
+
);
|
| 572 |
}
|
| 573 |
+
}
|
| 574 |
+
$matching_template = array_merge( $default_response, $matching_template );
|
| 575 |
|
| 576 |
+
// If there aren't any matching templates left that are supported, then we consider it to not be available.
|
| 577 |
+
if ( empty( $matching_template['supported'] ) ) {
|
| 578 |
+
$matching_template['errors'][] = 'template_unsupported';
|
| 579 |
+
}
|
| 580 |
|
| 581 |
+
// For singular queries, post_supports_amp() is given the final say.
|
| 582 |
+
if ( $query->is_singular() || $query->is_posts_page ) {
|
| 583 |
+
/**
|
| 584 |
+
* Queried object.
|
| 585 |
+
*
|
| 586 |
+
* @var WP_Post $queried_object
|
| 587 |
+
*/
|
| 588 |
+
$queried_object = $query->get_queried_object();
|
| 589 |
+
$support_errors = AMP_Post_Type_Support::get_support_errors( $queried_object );
|
| 590 |
+
if ( ! empty( $support_errors ) ) {
|
| 591 |
+
$matching_template['errors'] = array_merge( $matching_template['errors'], $support_errors );
|
| 592 |
+
$matching_template['supported'] = false;
|
| 593 |
}
|
| 594 |
}
|
| 595 |
+
|
| 596 |
+
return $matching_template;
|
| 597 |
}
|
| 598 |
|
| 599 |
/**
|
| 600 |
+
* Get the templates which can be supported.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
*
|
| 602 |
+
* @return array Supportable templates.
|
|
|
|
|
|
|
|
|
|
| 603 |
*/
|
| 604 |
+
public static function get_supportable_templates() {
|
| 605 |
+
$templates = array(
|
| 606 |
+
'is_singular' => array(
|
| 607 |
+
'label' => __( 'Singular', 'amp' ),
|
| 608 |
+
'description' => __( 'Required for the above content types.', 'amp' ),
|
| 609 |
),
|
|
|
|
| 610 |
);
|
| 611 |
+
if ( 'page' === get_option( 'show_on_front' ) ) {
|
| 612 |
+
$templates['is_front_page'] = array(
|
| 613 |
+
'label' => __( 'Homepage', 'amp' ),
|
| 614 |
+
'parent' => 'is_singular',
|
| 615 |
+
);
|
| 616 |
+
if ( AMP_Post_Meta_Box::DISABLED_STATUS === get_post_meta( get_option( 'page_on_front' ), AMP_Post_Meta_Box::STATUS_POST_META_KEY, true ) ) {
|
| 617 |
+
/* translators: %s: the URL to the edit post screen. */
|
| 618 |
+
$templates['is_front_page']['description'] = sprintf( __( 'Currently disabled at the <a href="%s" target="_blank">page level</a>.', 'amp' ), esc_url( get_edit_post_link( get_option( 'page_on_front' ) ) ) );
|
| 619 |
+
}
|
| 620 |
|
| 621 |
+
// In other words, same as is_posts_page, *but* it not is_singular.
|
| 622 |
+
$templates['is_home'] = array(
|
| 623 |
+
'label' => __( 'Blog', 'amp' ),
|
| 624 |
+
);
|
| 625 |
+
if ( AMP_Post_Meta_Box::DISABLED_STATUS === get_post_meta( get_option( 'page_for_posts' ), AMP_Post_Meta_Box::STATUS_POST_META_KEY, true ) ) {
|
| 626 |
+
/* translators: %s: the URL to the edit post screen. */
|
| 627 |
+
$templates['is_home']['description'] = sprintf( __( 'Currently disabled at the <a href="%s" target="_blank">page level</a>.', 'amp' ), esc_url( get_edit_post_link( get_option( 'page_for_posts' ) ) ) );
|
| 628 |
+
}
|
| 629 |
+
} else {
|
| 630 |
+
$templates['is_home'] = array(
|
| 631 |
+
'label' => __( 'Homepage', 'amp' ),
|
| 632 |
+
);
|
| 633 |
}
|
| 634 |
|
| 635 |
+
$templates = array_merge(
|
| 636 |
+
$templates,
|
| 637 |
+
array(
|
| 638 |
+
'is_archive' => array(
|
| 639 |
+
'label' => __( 'Archives', 'amp' ),
|
| 640 |
+
),
|
| 641 |
+
'is_author' => array(
|
| 642 |
+
'label' => __( 'Author', 'amp' ),
|
| 643 |
+
'parent' => 'is_archive',
|
| 644 |
+
),
|
| 645 |
+
'is_date' => array(
|
| 646 |
+
'label' => __( 'Date', 'amp' ),
|
| 647 |
+
'parent' => 'is_archive',
|
| 648 |
+
),
|
| 649 |
+
'is_search' => array(
|
| 650 |
+
'label' => __( 'Search', 'amp' ),
|
| 651 |
+
),
|
| 652 |
+
'is_404' => array(
|
| 653 |
+
'label' => __( 'Not Found (404)', 'amp' ),
|
| 654 |
+
),
|
| 655 |
+
)
|
| 656 |
);
|
|
|
|
|
|
|
| 657 |
|
| 658 |
+
if ( taxonomy_exists( 'category' ) ) {
|
| 659 |
+
$templates['is_category'] = array(
|
| 660 |
+
'label' => get_taxonomy( 'category' )->labels->name,
|
| 661 |
+
'parent' => 'is_archive',
|
| 662 |
+
);
|
| 663 |
+
}
|
| 664 |
+
if ( taxonomy_exists( 'post_tag' ) ) {
|
| 665 |
+
$templates['is_tag'] = array(
|
| 666 |
+
'label' => get_taxonomy( 'post_tag' )->labels->name,
|
| 667 |
+
'parent' => 'is_archive',
|
| 668 |
+
);
|
| 669 |
+
}
|
| 670 |
+
|
| 671 |
+
$taxonomy_args = array(
|
| 672 |
+
'_builtin' => false,
|
| 673 |
+
'publicly_queryable' => true,
|
| 674 |
);
|
| 675 |
+
foreach ( get_taxonomies( $taxonomy_args, 'objects' ) as $taxonomy ) {
|
| 676 |
+
$templates[ sprintf( 'is_tax[%s]', $taxonomy->name ) ] = array(
|
| 677 |
+
'label' => $taxonomy->labels->name,
|
| 678 |
+
'parent' => 'is_archive',
|
| 679 |
+
'callback' => function ( WP_Query $query ) use ( $taxonomy ) {
|
| 680 |
+
return $query->is_tax( $taxonomy->name );
|
| 681 |
+
},
|
| 682 |
+
);
|
| 683 |
}
|
| 684 |
|
| 685 |
+
$post_type_args = array(
|
| 686 |
+
'has_archive' => true,
|
| 687 |
+
'publicly_queryable' => true,
|
| 688 |
+
);
|
| 689 |
+
foreach ( get_post_types( $post_type_args, 'objects' ) as $post_type ) {
|
| 690 |
+
$templates[ sprintf( 'is_post_type_archive[%s]', $post_type->name ) ] = array(
|
| 691 |
+
'label' => $post_type->labels->archives,
|
| 692 |
+
'parent' => 'is_archive',
|
| 693 |
+
'callback' => function ( WP_Query $query ) use ( $post_type ) {
|
| 694 |
+
return $query->is_post_type_archive( $post_type->name );
|
| 695 |
+
},
|
| 696 |
+
);
|
| 697 |
}
|
| 698 |
|
| 699 |
+
/**
|
| 700 |
+
* Filters list of supportable templates.
|
| 701 |
+
*
|
| 702 |
+
* A theme or plugin can force a given template to be supported or not by preemptively
|
| 703 |
+
* setting the 'supported' flag for a given template. Otherwise, if the flag is undefined
|
| 704 |
+
* then the user will be able to toggle it themselves in the admin. Each array item should
|
| 705 |
+
* have a key that corresponds to a template conditional function. If the key is such a
|
| 706 |
+
* function, then the key is used to evaluate whether the given template entry is a match.
|
| 707 |
+
* Otherwise, a supportable template item can include a callback value which is used instead.
|
| 708 |
+
* Each item needs a 'label' value. Additionally, if the supportable template is a subset of
|
| 709 |
+
* another condition (e.g. is_singular > is_single) then this relationship needs to be
|
| 710 |
+
* indicated via the 'parent' value.
|
| 711 |
+
*
|
| 712 |
+
* @since 1.0
|
| 713 |
+
*
|
| 714 |
+
* @param array $templates Supportable templates.
|
| 715 |
+
*/
|
| 716 |
+
$templates = apply_filters( 'amp_supportable_templates', $templates );
|
| 717 |
|
| 718 |
+
$theme_support_args = self::get_theme_support_args();
|
| 719 |
+
$theme_supported_templates = array();
|
| 720 |
+
if ( isset( $theme_support_args['templates_supported'] ) ) {
|
| 721 |
+
$theme_supported_templates = $theme_support_args['templates_supported'];
|
| 722 |
+
}
|
| 723 |
|
| 724 |
+
$supported_templates = AMP_Options_Manager::get_option( 'supported_templates' );
|
| 725 |
+
foreach ( $templates as $id => &$template ) {
|
|
|
|
|
|
|
| 726 |
|
| 727 |
+
// Capture user-elected support from options. This allows us to preserve the original user selection through programmatic overrides.
|
| 728 |
+
$template['user_supported'] = in_array( $id, $supported_templates, true );
|
| 729 |
|
| 730 |
+
// Consider supported templates from theme support args.
|
| 731 |
+
if ( ! isset( $template['supported'] ) ) {
|
| 732 |
+
if ( 'all' === $theme_supported_templates ) {
|
| 733 |
+
$template['supported'] = true;
|
| 734 |
+
} elseif ( is_array( $theme_supported_templates ) && isset( $theme_supported_templates[ $id ] ) ) {
|
| 735 |
+
$template['supported'] = $theme_supported_templates[ $id ];
|
| 736 |
+
}
|
| 737 |
+
}
|
| 738 |
+
|
| 739 |
+
// Make supported state immutable if it was programmatically set.
|
| 740 |
+
$template['immutable'] = isset( $template['supported'] );
|
| 741 |
+
|
| 742 |
+
// Set supported state from user preference.
|
| 743 |
+
if ( ! $template['immutable'] ) {
|
| 744 |
+
$template['supported'] = AMP_Options_Manager::get_option( 'all_templates_supported' ) || $template['user_supported'];
|
| 745 |
+
}
|
| 746 |
+
}
|
| 747 |
+
|
| 748 |
+
return $templates;
|
| 749 |
}
|
| 750 |
|
| 751 |
/**
|
| 752 |
+
* Register hooks.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 753 |
*/
|
| 754 |
+
public static function add_hooks() {
|
|
|
|
| 755 |
|
| 756 |
+
// Let the AMP plugin manage service worker streaming in the PWA plugin.
|
| 757 |
+
remove_action( 'template_redirect', 'WP_Service_Worker_Navigation_Routing_Component::start_output_buffering_stream_fragment', PHP_INT_MAX );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 758 |
|
| 759 |
+
// Remove core actions which are invalid AMP.
|
| 760 |
+
remove_action( 'wp_head', 'wp_post_preview_js', 1 );
|
| 761 |
+
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
|
| 762 |
+
remove_action( 'wp_print_styles', 'print_emoji_styles' );
|
| 763 |
+
remove_action( 'wp_head', 'wp_oembed_add_host_js' );
|
| 764 |
|
| 765 |
+
// @todo The wp_mediaelement_fallback() should still run to be injected inside of the audio/video generated by wp_audio_shortcode()/wp_video_shortcode() respectively.
|
| 766 |
+
// Prevent MediaElement.js scripts/styles from being enqueued.
|
| 767 |
+
add_filter( 'wp_video_shortcode_library', function() {
|
| 768 |
+
return 'amp';
|
| 769 |
+
} );
|
| 770 |
+
add_filter( 'wp_audio_shortcode_library', function() {
|
| 771 |
+
return 'amp';
|
| 772 |
+
} );
|
| 773 |
|
| 774 |
+
// Don't show loading indicator on custom logo since it makes most sense for larger images.
|
| 775 |
+
add_filter( 'get_custom_logo', function( $html ) {
|
| 776 |
+
return preg_replace( '/(?<=<img\s)/', ' noloading ', $html );
|
| 777 |
+
}, 1 );
|
| 778 |
+
|
| 779 |
+
/*
|
| 780 |
+
* "AMP HTML documents MUST contain the AMP boilerplate code (head > style[amp-boilerplate] and noscript > style[amp-boilerplate])
|
| 781 |
+
* in their head tag." {@link https://www.ampproject.org/docs/fundamentals/spec#required-markup AMP Required markup}
|
| 782 |
+
*
|
| 783 |
+
* After "Specify the <link> tag for your favicon.", then
|
| 784 |
+
* "Specify any custom styles by using the <style amp-custom> tag."
|
| 785 |
+
*
|
| 786 |
+
* Note that the boilerplate is added at the very end because:
|
| 787 |
+
* "Finally, specify the AMP boilerplate code. By putting the boilerplate code last, it prevents custom styles from accidentally
|
| 788 |
+
* overriding the boilerplate css rules." {@link https://docs.google.com/document/d/169XUxtSSEJb16NfkrCr9y5lqhUR7vxXEAsNxBzg07fM/edit AMP Hosting Guide}
|
| 789 |
*
|
| 790 |
+
* Other required markup is added in the ensure_required_markup method, including meta charset, meta viewport, and rel=canonical link.
|
| 791 |
*/
|
| 792 |
+
add_action( 'wp_head', function() {
|
| 793 |
+
echo '<style amp-custom></style>';
|
| 794 |
+
}, 0 );
|
| 795 |
+
add_action( 'wp_head', function() {
|
| 796 |
+
echo amp_get_boilerplate_code(); // WPCS: xss ok.
|
| 797 |
+
}, PHP_INT_MAX );
|
| 798 |
|
| 799 |
+
add_action( 'wp_head', 'amp_add_generator_metadata', 20 );
|
| 800 |
+
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
|
| 801 |
+
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'dequeue_customize_preview_scripts' ), 1000 );
|
| 802 |
+
add_filter( 'customize_partial_render', array( __CLASS__, 'filter_customize_partial_render' ) );
|
|
|
|
| 803 |
|
| 804 |
+
add_action( 'wp_footer', 'amp_print_analytics' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 805 |
|
| 806 |
+
/*
|
| 807 |
+
* Disable admin bar because admin-bar.css (28K) and Dashicons (48K) alone
|
| 808 |
+
* combine to surpass the 50K limit imposed for the amp-custom style.
|
| 809 |
+
*/
|
| 810 |
+
if ( AMP_Options_Manager::get_option( 'disable_admin_bar' ) ) {
|
| 811 |
+
add_filter( 'show_admin_bar', '__return_false', 100 );
|
| 812 |
+
} else {
|
| 813 |
+
add_action( 'admin_bar_init', array( __CLASS__, 'init_admin_bar' ) );
|
| 814 |
}
|
| 815 |
|
| 816 |
+
/*
|
| 817 |
+
* Start output buffering at very low priority for sake of plugins and themes that use template_redirect
|
| 818 |
+
* instead of template_include.
|
| 819 |
+
*/
|
| 820 |
+
$priority = defined( 'PHP_INT_MIN' ) ? PHP_INT_MIN : ~PHP_INT_MAX; // phpcs:ignore PHPCompatibility.PHP.NewConstants.php_int_minFound
|
| 821 |
+
add_action( 'template_redirect', array( __CLASS__, 'start_output_buffering' ), $priority );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 822 |
|
| 823 |
+
// Commenting hooks.
|
| 824 |
+
add_filter( 'wp_list_comments_args', array( __CLASS__, 'set_comments_walker' ), PHP_INT_MAX );
|
| 825 |
+
add_filter( 'comment_form_defaults', array( __CLASS__, 'filter_comment_form_defaults' ) );
|
| 826 |
+
add_filter( 'comment_reply_link', array( __CLASS__, 'filter_comment_reply_link' ), 10, 4 );
|
| 827 |
+
add_filter( 'cancel_comment_reply_link', array( __CLASS__, 'filter_cancel_comment_reply_link' ), 10, 3 );
|
| 828 |
+
add_action( 'comment_form', array( __CLASS__, 'amend_comment_form' ), 100 );
|
| 829 |
+
remove_action( 'comment_form', 'wp_comment_form_unfiltered_html_nonce' );
|
| 830 |
+
add_filter( 'wp_kses_allowed_html', array( __CLASS__, 'whitelist_layout_in_wp_kses_allowed_html' ), 10 );
|
| 831 |
+
add_filter( 'get_header_image_tag', array( __CLASS__, 'amend_header_image_with_video_header' ), PHP_INT_MAX );
|
| 832 |
+
add_action( 'wp_print_footer_scripts', function() {
|
| 833 |
+
wp_dequeue_script( 'wp-custom-header' );
|
| 834 |
+
}, 0 );
|
| 835 |
+
add_action( 'wp_enqueue_scripts', function() {
|
| 836 |
+
wp_dequeue_script( 'comment-reply' ); // Handled largely by AMP_Comments_Sanitizer and *reply* methods in this class.
|
| 837 |
+
} );
|
| 838 |
|
| 839 |
+
// @todo Add character conversion.
|
| 840 |
}
|
| 841 |
|
| 842 |
/**
|
| 940 |
/**
|
| 941 |
* Prepends template hierarchy with template_dir for AMP paired mode templates.
|
| 942 |
*
|
|
|
|
|
|
|
| 943 |
* @param array $templates Template hierarchy.
|
| 944 |
+
* @return array Templates.
|
| 945 |
*/
|
| 946 |
+
public static function filter_amp_template_hierarchy( $templates ) {
|
| 947 |
+
$args = self::get_theme_support_args();
|
|
|
|
| 948 |
if ( isset( $args['template_dir'] ) ) {
|
| 949 |
$amp_templates = array();
|
| 950 |
foreach ( $templates as $template ) {
|
| 951 |
+
$amp_templates[] = $args['template_dir'] . '/' . $template; // Let template_dir have precedence.
|
| 952 |
+
$amp_templates[] = $template;
|
| 953 |
}
|
| 954 |
$templates = $amp_templates;
|
| 955 |
}
|
| 956 |
return $templates;
|
| 957 |
}
|
| 958 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 959 |
/**
|
| 960 |
* Get canonical URL for current request.
|
| 961 |
*
|
| 1121 |
}
|
| 1122 |
|
| 1123 |
/**
|
| 1124 |
+
* Configure the admin bar for AMP.
|
| 1125 |
+
*
|
| 1126 |
+
* @since 1.0
|
| 1127 |
*/
|
| 1128 |
+
public static function init_admin_bar() {
|
| 1129 |
+
|
| 1130 |
+
// Replace admin-bar.css in core with forked version which makes use of :focus-within among other change for AMP-compat.
|
| 1131 |
+
wp_styles()->registered['admin-bar']->src = amp_get_asset_url( 'css/admin-bar.css' );
|
| 1132 |
+
wp_styles()->registered['admin-bar']->ver = AMP__VERSION;
|
| 1133 |
+
|
| 1134 |
+
// Remove script which is almost entirely made obsolete by :focus-inside in the forked admin-bar.css.
|
| 1135 |
+
wp_dequeue_script( 'admin-bar' );
|
| 1136 |
+
|
| 1137 |
+
// Remove customize support script since not valid AMP.
|
| 1138 |
+
add_action( 'admin_bar_menu', function() {
|
| 1139 |
+
remove_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' );
|
| 1140 |
+
}, 41 );
|
| 1141 |
+
|
| 1142 |
+
// Emulate customize support script in PHP, to assume Customizer.
|
| 1143 |
+
add_filter( 'body_class', function( $body_classes ) {
|
| 1144 |
+
return array_merge(
|
| 1145 |
+
array_diff(
|
| 1146 |
+
$body_classes,
|
| 1147 |
+
array( 'no-customize-support' )
|
| 1148 |
+
),
|
| 1149 |
+
array( 'customize-support' )
|
| 1150 |
+
);
|
| 1151 |
+
} );
|
| 1152 |
}
|
| 1153 |
|
| 1154 |
/**
|
| 1155 |
+
* Ensure the markup exists as required by AMP and elements are in the optimal loading order.
|
| 1156 |
*
|
| 1157 |
+
* Ensure meta[charset], meta[name=viewport], and link[rel=canonical] exist, as the whitelist sanitizer
|
| 1158 |
+
* may have removed an illegal meta[http-equiv] or meta[name=viewport]. For a singular post, core only outputs a
|
| 1159 |
+
* canonical URL by default. Adds the preload links.
|
| 1160 |
*
|
| 1161 |
* @since 0.7
|
| 1162 |
+
* @link https://www.ampproject.org/docs/reference/spec#required-markup
|
| 1163 |
+
* @link https://docs.google.com/document/d/169XUxtSSEJb16NfkrCr9y5lqhUR7vxXEAsNxBzg07fM/edit#heading=h.2ha259c3ffos
|
| 1164 |
* @todo All of this might be better placed inside of a sanitizer.
|
| 1165 |
*
|
| 1166 |
+
* @param DOMDocument $dom Document.
|
| 1167 |
+
* @param string[] $script_handles AMP script handles for components identified during output buffering.
|
| 1168 |
*/
|
| 1169 |
+
public static function ensure_required_markup( DOMDocument $dom, $script_handles = array() ) {
|
| 1170 |
+
/**
|
| 1171 |
+
* Elements.
|
| 1172 |
+
*
|
| 1173 |
+
* @var DOMElement $meta
|
| 1174 |
+
* @var DOMElement $script
|
| 1175 |
+
* @var DOMElement $link
|
| 1176 |
+
*/
|
| 1177 |
+
|
| 1178 |
+
$xpath = new DOMXPath( $dom );
|
| 1179 |
+
|
| 1180 |
+
// Make sure the HEAD element is in the doc.
|
| 1181 |
$head = $dom->getElementsByTagName( 'head' )->item( 0 );
|
| 1182 |
if ( ! $head ) {
|
| 1183 |
$head = $dom->createElement( 'head' );
|
| 1184 |
$dom->documentElement->insertBefore( $head, $dom->documentElement->firstChild );
|
| 1185 |
}
|
| 1186 |
+
|
| 1187 |
+
// Ensure there is a schema.org script in the document.
|
| 1188 |
+
// @todo Consider applying the amp_schemaorg_metadata filter on the contents when a script is already present.
|
| 1189 |
+
$schema_org_meta_script = $xpath->query( '//script[ @type = "application/ld+json" ][ contains( ./text(), "schema.org" ) ]' )->item( 0 );
|
| 1190 |
+
if ( ! $schema_org_meta_script ) {
|
| 1191 |
+
$script = $dom->createElement( 'script' );
|
| 1192 |
+
$script->setAttribute( 'type', 'application/ld+json' );
|
| 1193 |
+
$script->appendChild( $dom->createTextNode( wp_json_encode( amp_get_schemaorg_metadata() ) ) );
|
| 1194 |
+
$head->appendChild( $script );
|
| 1195 |
+
}
|
| 1196 |
+
|
| 1197 |
+
// Ensure rel=canonical link.
|
| 1198 |
+
$links = array();
|
| 1199 |
+
$link_elements = $head->getElementsByTagName( 'link' );
|
| 1200 |
+
$rel_canonical = null;
|
| 1201 |
+
foreach ( $link_elements as $link ) {
|
| 1202 |
+
if ( $link->hasAttribute( 'rel' ) ) {
|
| 1203 |
+
$links[ $link->getAttribute( 'rel' ) ][] = $link;
|
| 1204 |
+
}
|
| 1205 |
+
}
|
| 1206 |
+
if ( empty( $links['canonical'] ) ) {
|
| 1207 |
+
$rel_canonical = AMP_DOM_Utils::create_node( $dom, 'link', array(
|
| 1208 |
+
'rel' => 'canonical',
|
| 1209 |
+
'href' => self::get_current_canonical_url(),
|
| 1210 |
+
) );
|
| 1211 |
+
$head->appendChild( $rel_canonical );
|
| 1212 |
+
}
|
| 1213 |
+
|
| 1214 |
+
/*
|
| 1215 |
+
* Ensure meta charset and meta viewport are present.
|
| 1216 |
+
*
|
| 1217 |
+
* "AMP is already quite restrictive about which markup is allowed in the <head> section. However,
|
| 1218 |
+
* there are a few basic optimizations that you can apply. The key is to structure the <head> section
|
| 1219 |
+
* in a way so that all render-blocking scripts and custom fonts load as fast as possible."
|
| 1220 |
+
*
|
| 1221 |
+
* "The first tag should be the meta charset tag, followed by any remaining meta tags."
|
| 1222 |
+
*
|
| 1223 |
+
* {@link https://docs.google.com/document/d/169XUxtSSEJb16NfkrCr9y5lqhUR7vxXEAsNxBzg07fM/edit#heading=h.2ha259c3ffos Optimize the AMP Runtime loading}
|
| 1224 |
+
*/
|
| 1225 |
$meta_charset = null;
|
| 1226 |
$meta_viewport = null;
|
| 1227 |
+
$meta_elements = array();
|
| 1228 |
foreach ( $head->getElementsByTagName( 'meta' ) as $meta ) {
|
| 1229 |
+
if ( $meta->hasAttribute( 'charset' ) ) { // There will not be a meta[http-equiv] because the sanitizer removed it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1230 |
$meta_charset = $meta;
|
| 1231 |
} elseif ( 'viewport' === $meta->getAttribute( 'name' ) ) {
|
| 1232 |
$meta_viewport = $meta;
|
| 1233 |
+
} else {
|
| 1234 |
+
$meta_elements[] = $meta;
|
| 1235 |
}
|
| 1236 |
}
|
| 1237 |
if ( ! $meta_charset ) {
|
| 1239 |
$meta_charset = AMP_DOM_Utils::create_node( $dom, 'meta', array(
|
| 1240 |
'charset' => 'utf-8',
|
| 1241 |
) );
|
| 1242 |
+
} else {
|
| 1243 |
+
$head->removeChild( $meta_charset ); // So we can move it.
|
| 1244 |
}
|
| 1245 |
+
$head->insertBefore( $meta_charset, $head->firstChild );
|
| 1246 |
+
|
| 1247 |
if ( ! $meta_viewport ) {
|
| 1248 |
$meta_viewport = AMP_DOM_Utils::create_node( $dom, 'meta', array(
|
| 1249 |
'name' => 'viewport',
|
| 1250 |
+
'content' => 'width=device-width',
|
| 1251 |
) );
|
| 1252 |
+
} else {
|
| 1253 |
+
$head->removeChild( $meta_viewport ); // So we can move it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1254 |
}
|
| 1255 |
+
$head->insertBefore( $meta_viewport, $meta_charset->nextSibling );
|
| 1256 |
+
|
| 1257 |
+
$previous_node = $meta_viewport;
|
| 1258 |
+
foreach ( $meta_elements as $meta_element ) {
|
| 1259 |
+
$meta_element->parentNode->removeChild( $meta_element );
|
| 1260 |
+
$head->insertBefore( $meta_element, $previous_node->nextSibling );
|
| 1261 |
+
$previous_node = $meta_element;
|
| 1262 |
}
|
| 1263 |
+
|
| 1264 |
+
$title = $head->getElementsByTagName( 'title' )->item( 0 );
|
| 1265 |
+
if ( $title ) {
|
| 1266 |
+
$title->parentNode->removeChild( $title ); // So we can move it.
|
| 1267 |
+
$head->insertBefore( $title, $previous_node->nextSibling );
|
| 1268 |
+
$previous_node = $title;
|
| 1269 |
+
}
|
| 1270 |
+
|
| 1271 |
+
// @see https://github.com/ampproject/amphtml/blob/2fd30ca984bceac05905bd5b17f9e0010629d719/src/render-delaying-services.js#L39-L43 AMPHTML Render Delaying Services SERVICES definition.
|
| 1272 |
+
$render_delaying_extensions = array(
|
| 1273 |
+
'amp-experiment',
|
| 1274 |
+
'amp-dynamic-css-classes',
|
| 1275 |
+
'amp-story',
|
| 1276 |
+
);
|
| 1277 |
+
|
| 1278 |
+
// Obtain the existing AMP scripts.
|
| 1279 |
+
$amp_scripts = array();
|
| 1280 |
+
$ordered_scripts = array();
|
| 1281 |
+
$head_scripts = array();
|
| 1282 |
+
$runtime_src = wp_scripts()->registered['amp-runtime']->src;
|
| 1283 |
+
foreach ( $head->getElementsByTagName( 'script' ) as $script ) { // Note that prepare_response() already moved body scripts to head.
|
| 1284 |
+
$head_scripts[] = $script;
|
| 1285 |
+
}
|
| 1286 |
+
foreach ( $head_scripts as $script ) {
|
| 1287 |
+
$src = $script->getAttribute( 'src' );
|
| 1288 |
+
if ( ! $src || 'https://cdn.ampproject.org/' !== substr( $src, 0, 27 ) ) {
|
| 1289 |
+
continue;
|
| 1290 |
+
}
|
| 1291 |
+
if ( $runtime_src === $src ) {
|
| 1292 |
+
$amp_scripts['amp-runtime'] = $script;
|
| 1293 |
+
} elseif ( $script->hasAttribute( 'custom-element' ) ) {
|
| 1294 |
+
$amp_scripts[ $script->getAttribute( 'custom-element' ) ] = $script;
|
| 1295 |
+
} elseif ( $script->hasAttribute( 'custom-template' ) ) {
|
| 1296 |
+
$amp_scripts[ $script->getAttribute( 'custom-template' ) ] = $script;
|
| 1297 |
+
} else {
|
| 1298 |
+
continue;
|
| 1299 |
}
|
| 1300 |
+
$script->parentNode->removeChild( $script ); // So we can move it.
|
| 1301 |
}
|
| 1302 |
+
|
| 1303 |
+
// Create scripts for any components discovered from output buffering.
|
| 1304 |
+
foreach ( array_diff( $script_handles, array_keys( $amp_scripts ) ) as $missing_script_handle ) {
|
| 1305 |
+
if ( ! wp_script_is( $missing_script_handle, 'registered' ) ) {
|
| 1306 |
+
continue;
|
| 1307 |
+
}
|
| 1308 |
+
$attrs = array(
|
| 1309 |
+
'src' => wp_scripts()->registered[ $missing_script_handle ]->src,
|
| 1310 |
+
'async' => '',
|
| 1311 |
+
);
|
| 1312 |
+
if ( 'amp-mustache' === $missing_script_handle ) {
|
| 1313 |
+
$attrs['custom-template'] = $missing_script_handle;
|
| 1314 |
+
} else {
|
| 1315 |
+
$attrs['custom-element'] = $missing_script_handle;
|
| 1316 |
+
}
|
| 1317 |
+
|
| 1318 |
+
$amp_scripts[ $missing_script_handle ] = AMP_DOM_Utils::create_node( $dom, 'script', $attrs );
|
| 1319 |
+
}
|
| 1320 |
+
|
| 1321 |
+
/* phpcs:ignore Squiz.PHP.CommentedOutCode.Found
|
| 1322 |
+
*
|
| 1323 |
+
* "Next, preload the AMP runtime v0.js <script> tag with <link as=script href=https://cdn.ampproject.org/v0.js rel=preload>.
|
| 1324 |
+
* The AMP runtime should start downloading as soon as possible because the AMP boilerplate hides the document via body { visibility:hidden }
|
| 1325 |
+
* until the AMP runtime has loaded. Preloading the AMP runtime tells the browser to download the script with a higher priority."
|
| 1326 |
+
* {@link https://docs.google.com/document/d/169XUxtSSEJb16NfkrCr9y5lqhUR7vxXEAsNxBzg07fM/edit#heading=h.2ha259c3ffos Optimize the AMP Runtime loading}
|
| 1327 |
+
*/
|
| 1328 |
+
$prioritized_preloads = array();
|
| 1329 |
+
if ( ! isset( $links['preload'] ) ) {
|
| 1330 |
+
$links['preload'] = array();
|
| 1331 |
+
}
|
| 1332 |
+
|
| 1333 |
+
$prioritized_preloads[] = AMP_DOM_Utils::create_node( $dom, 'link', array(
|
| 1334 |
+
'rel' => 'preload',
|
| 1335 |
+
'as' => 'script',
|
| 1336 |
+
'href' => $runtime_src,
|
| 1337 |
+
) );
|
| 1338 |
+
|
| 1339 |
+
$amp_script_handles = array_keys( $amp_scripts );
|
| 1340 |
+
foreach ( array_intersect( $render_delaying_extensions, $amp_script_handles ) as $script_handle ) {
|
| 1341 |
+
if ( ! in_array( $script_handle, $render_delaying_extensions, true ) ) {
|
| 1342 |
+
continue;
|
| 1343 |
+
}
|
| 1344 |
+
$prioritized_preloads[] = AMP_DOM_Utils::create_node( $dom, 'link', array(
|
| 1345 |
+
'rel' => 'preload',
|
| 1346 |
+
'as' => 'script',
|
| 1347 |
+
'href' => $amp_scripts[ $script_handle ]->getAttribute( 'src' ),
|
| 1348 |
) );
|
|
|
|
| 1349 |
}
|
| 1350 |
+
$links['preload'] = array_merge( $prioritized_preloads, $links['preload'] );
|
| 1351 |
+
|
| 1352 |
+
$link_relations = array( 'preconnect', 'dns-prefetch', 'preload', 'prerender', 'prefetch' );
|
| 1353 |
+
foreach ( $link_relations as $rel ) {
|
| 1354 |
+
if ( ! isset( $links[ $rel ] ) ) {
|
| 1355 |
+
continue;
|
| 1356 |
+
}
|
| 1357 |
+
foreach ( $links[ $rel ] as $link ) {
|
| 1358 |
+
if ( $link->parentNode ) {
|
| 1359 |
+
$link->parentNode->removeChild( $link ); // So we can move it.
|
| 1360 |
+
}
|
| 1361 |
+
$head->insertBefore( $link, $previous_node->nextSibling );
|
| 1362 |
+
$previous_node = $link;
|
| 1363 |
+
}
|
| 1364 |
+
}
|
| 1365 |
+
|
| 1366 |
+
/*
|
| 1367 |
+
* "Specify the <script> tags for render-delaying extensions (e.g., amp-experiment, amp-dynamic-css-classes, and amp-story)."
|
| 1368 |
+
* "Specify the <script> tags for remaining extensions (e.g., amp-bind, ...). These extensions are not render-delaying and therefore
|
| 1369 |
+
* should not be preloaded because they might take away important bandwidth for the initial render."
|
| 1370 |
+
* {@link https://docs.google.com/document/d/169XUxtSSEJb16NfkrCr9y5lqhUR7vxXEAsNxBzg07fM/edit AMP Hosting Guide}
|
| 1371 |
+
*/
|
| 1372 |
+
if ( isset( $amp_scripts['amp-runtime'] ) ) {
|
| 1373 |
+
$ordered_scripts['amp-runtime'] = $amp_scripts['amp-runtime'];
|
| 1374 |
+
}
|
| 1375 |
+
foreach ( $render_delaying_extensions as $extension ) {
|
| 1376 |
+
if ( isset( $amp_scripts[ $extension ] ) ) {
|
| 1377 |
+
$ordered_scripts[ $extension ] = $amp_scripts[ $extension ];
|
| 1378 |
+
unset( $amp_scripts[ $extension ] );
|
| 1379 |
+
}
|
| 1380 |
+
}
|
| 1381 |
+
|
| 1382 |
+
$ordered_scripts = array_merge( $ordered_scripts, $amp_scripts );
|
| 1383 |
+
foreach ( $ordered_scripts as $ordered_script ) {
|
| 1384 |
+
$head->insertBefore( $ordered_script, $previous_node->nextSibling );
|
| 1385 |
+
$previous_node = $ordered_script;
|
| 1386 |
+
}
|
| 1387 |
+
|
| 1388 |
+
/*
|
| 1389 |
+
* "Specify the <link> tag for your favicon."
|
| 1390 |
+
* {@link https://docs.google.com/document/d/169XUxtSSEJb16NfkrCr9y5lqhUR7vxXEAsNxBzg07fM/edit AMP Hosting Guide}
|
| 1391 |
+
*/
|
| 1392 |
+
if ( isset( $links['icon'] ) ) {
|
| 1393 |
+
foreach ( $links['icon'] as $link ) {
|
| 1394 |
+
$link->parentNode->removeChild( $link ); // So we can move it.
|
| 1395 |
+
$head->insertBefore( $link, $previous_node->nextSibling );
|
| 1396 |
+
$previous_node = $link;
|
| 1397 |
+
}
|
| 1398 |
+
}
|
| 1399 |
+
|
| 1400 |
+
// Note the style[amp-custom] and style[amp-boilerplate] are output in the add_hooks() method.
|
| 1401 |
+
unset( $previous_node );
|
| 1402 |
}
|
| 1403 |
|
| 1404 |
/**
|
| 1431 |
public static function start_output_buffering() {
|
| 1432 |
/*
|
| 1433 |
* Disable the New Relic Browser agent on AMP responses.
|
| 1434 |
+
* This prevents the New Relic from causing invalid AMP responses due the NREUM script it injects after the meta charset:
|
| 1435 |
* https://docs.newrelic.com/docs/browser/new-relic-browser/troubleshooting/google-amp-validator-fails-due-3rd-party-script
|
| 1436 |
* Sites with New Relic will need to specially configure New Relic for AMP:
|
| 1437 |
* https://docs.newrelic.com/docs/browser/new-relic-browser/installation/monitor-amp-pages-new-relic-browser
|
| 1502 |
* @since 0.7
|
| 1503 |
*
|
| 1504 |
* @param string $response HTML document response. By default it expects a complete document.
|
| 1505 |
+
* @param array $args Args to send to the preprocessor/sanitizer.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1506 |
* @return string AMP document response.
|
| 1507 |
* @global int $content_width
|
| 1508 |
*/
|
| 1509 |
public static function prepare_response( $response, $args = array() ) {
|
| 1510 |
global $content_width;
|
| 1511 |
+
$prepare_response_start = microtime( true );
|
| 1512 |
+
|
| 1513 |
+
if ( isset( $args['validation_error_callback'] ) ) {
|
| 1514 |
+
_doing_it_wrong( __METHOD__, 'Do not supply validation_error_callback arg.', '1.0' );
|
| 1515 |
+
unset( $args['validation_error_callback'] );
|
| 1516 |
+
}
|
| 1517 |
|
| 1518 |
/*
|
| 1519 |
* Check if the response starts with HTML markup.
|
| 1524 |
return $response;
|
| 1525 |
}
|
| 1526 |
|
| 1527 |
+
// Dependencies on the PWA plugin for service worker streaming.
|
| 1528 |
+
$stream_fragment = null;
|
| 1529 |
+
if ( class_exists( 'WP_Service_Worker_Navigation_Routing_Component' ) && current_theme_supports( WP_Service_Worker_Navigation_Routing_Component::STREAM_THEME_SUPPORT ) ) {
|
| 1530 |
+
$stream_fragment = WP_Service_Worker_Navigation_Routing_Component::get_stream_fragment_query_var();
|
| 1531 |
+
}
|
| 1532 |
|
| 1533 |
$args = array_merge(
|
| 1534 |
array(
|
| 1536 |
'use_document_element' => true,
|
| 1537 |
'allow_dirty_styles' => self::is_customize_preview_iframe(), // Dirty styles only needed when editing (e.g. for edit shortcodes).
|
| 1538 |
'allow_dirty_scripts' => is_customize_preview(), // Scripts are always needed to inject changeset UUID.
|
| 1539 |
+
'enable_response_caching' => (
|
| 1540 |
+
! ( defined( 'WP_DEBUG' ) && WP_DEBUG )
|
| 1541 |
+
&&
|
| 1542 |
+
! AMP_Validation_Manager::should_validate_response()
|
| 1543 |
+
&&
|
| 1544 |
+
! is_customize_preview()
|
| 1545 |
+
),
|
| 1546 |
+
'user_can_validate' => AMP_Validation_Manager::has_cap(),
|
| 1547 |
+
'stream_fragment' => $stream_fragment,
|
| 1548 |
),
|
| 1549 |
$args
|
| 1550 |
);
|
| 1551 |
|
| 1552 |
+
$current_url = amp_get_current_url();
|
| 1553 |
+
$ampless_url = amp_remove_endpoint( $current_url );
|
| 1554 |
+
|
| 1555 |
+
// When response caching is enabled, determine if it should be turned off for cache misses.
|
| 1556 |
+
$caches_for_url = null;
|
| 1557 |
+
if ( true === $args['enable_response_caching'] ) {
|
| 1558 |
+
list( $disable_response_caching, $caches_for_url ) = self::check_for_cache_misses();
|
| 1559 |
+
$args['enable_response_caching'] = ! $disable_response_caching;
|
| 1560 |
+
}
|
| 1561 |
+
|
| 1562 |
+
/*
|
| 1563 |
+
* Set response cache hash, the data values dictates whether a new hash key should be generated or not.
|
| 1564 |
+
* This is also used as the ETag.
|
| 1565 |
+
*/
|
| 1566 |
+
$response_cache_key = md5( wp_json_encode( array(
|
| 1567 |
+
$args,
|
| 1568 |
+
$response,
|
| 1569 |
+
self::$sanitizer_classes,
|
| 1570 |
+
self::$embed_handlers,
|
| 1571 |
+
AMP__VERSION,
|
| 1572 |
+
) ) );
|
| 1573 |
+
|
| 1574 |
+
/*
|
| 1575 |
+
* Per rfc7232:
|
| 1576 |
+
* "The server generating a 304 response MUST generate any of the
|
| 1577 |
+
* following header fields that would have been sent in a 200 (OK)
|
| 1578 |
+
* response to the same request: Cache-Control, Content-Location, Date,
|
| 1579 |
+
* ETag, Expires, and Vary." The only one of these headers which would
|
| 1580 |
+
* not have been set yet during the WordPress template generation is
|
| 1581 |
+
* the ETag. The AMP plugin sends a Vary header at amp_init.
|
| 1582 |
+
*/
|
| 1583 |
+
AMP_HTTP::send_header( 'ETag', $response_cache_key );
|
| 1584 |
+
|
| 1585 |
+
// Handle responses that are cached by the browser.
|
| 1586 |
+
if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) && $_SERVER['HTTP_IF_NONE_MATCH'] === $response_cache_key ) {
|
| 1587 |
+
status_header( 304 );
|
| 1588 |
+
return '';
|
| 1589 |
+
}
|
| 1590 |
+
|
| 1591 |
+
// Return cache if enabled and found.
|
| 1592 |
+
$cache_response = null;
|
| 1593 |
+
if ( true === $args['enable_response_caching'] ) {
|
| 1594 |
+
$response_cache = wp_cache_get( $response_cache_key, self::RESPONSE_CACHE_GROUP );
|
| 1595 |
+
|
| 1596 |
+
// Make sure that all of the validation errors should be sanitized in the same way; if not, then the cached body should be discarded.
|
| 1597 |
+
$blocking_error_count = 0;
|
| 1598 |
+
if ( isset( $response_cache['validation_results'] ) ) {
|
| 1599 |
+
foreach ( $response_cache['validation_results'] as $validation_result ) {
|
| 1600 |
+
if ( ! $validation_result['sanitized'] ) {
|
| 1601 |
+
$blocking_error_count++;
|
| 1602 |
+
}
|
| 1603 |
+
$should_sanitize = AMP_Validation_Error_Taxonomy::is_validation_error_sanitized( $validation_result['error'] );
|
| 1604 |
+
if ( $should_sanitize !== $validation_result['sanitized'] ) {
|
| 1605 |
+
unset( $response_cache['body'] );
|
| 1606 |
+
break;
|
| 1607 |
+
}
|
| 1608 |
+
}
|
| 1609 |
+
}
|
| 1610 |
+
|
| 1611 |
+
// Short-circuit response with cached body.
|
| 1612 |
+
if ( isset( $response_cache['body'] ) ) {
|
| 1613 |
+
|
| 1614 |
+
// Re-send the headers that were sent before when the response was first cached.
|
| 1615 |
+
if ( isset( $response_cache['headers'] ) ) {
|
| 1616 |
+
foreach ( $response_cache['headers'] as $header ) {
|
| 1617 |
+
if ( in_array( $header, AMP_HTTP::$headers_sent, true ) ) {
|
| 1618 |
+
continue; // Skip sending headers that were already sent prior to post-processing.
|
| 1619 |
+
}
|
| 1620 |
+
AMP_HTTP::send_header( $header['name'], $header['value'], wp_array_slice_assoc( $header, array( 'replace', 'status_code' ) ) );
|
| 1621 |
+
}
|
| 1622 |
+
}
|
| 1623 |
+
|
| 1624 |
+
AMP_HTTP::send_server_timing( 'amp_processor_cache_hit', -$prepare_response_start );
|
| 1625 |
+
|
| 1626 |
+
// Redirect to non-AMP version.
|
| 1627 |
+
if ( ! amp_is_canonical() && $blocking_error_count > 0 ) {
|
| 1628 |
+
if ( AMP_Validation_Manager::has_cap() ) {
|
| 1629 |
+
$ampless_url = add_query_arg( AMP_Validation_Manager::VALIDATION_ERRORS_QUERY_VAR, $blocking_error_count, $ampless_url );
|
| 1630 |
+
}
|
| 1631 |
+
wp_safe_redirect( $ampless_url );
|
| 1632 |
+
}
|
| 1633 |
+
return $response_cache['body'];
|
| 1634 |
+
}
|
| 1635 |
+
|
| 1636 |
+
$cache_response = function( $body, $validation_results ) use ( $response_cache_key, $caches_for_url ) {
|
| 1637 |
+
$caches_for_url[] = $response_cache_key;
|
| 1638 |
+
wp_cache_set(
|
| 1639 |
+
AMP_Theme_Support::POST_PROCESSOR_CACHE_EFFECTIVENESS_KEY,
|
| 1640 |
+
$caches_for_url,
|
| 1641 |
+
AMP_Theme_Support::POST_PROCESSOR_CACHE_EFFECTIVENESS_GROUP,
|
| 1642 |
+
600 // 10 minute cache.
|
| 1643 |
+
);
|
| 1644 |
+
|
| 1645 |
+
return wp_cache_set(
|
| 1646 |
+
$response_cache_key,
|
| 1647 |
+
array(
|
| 1648 |
+
'headers' => AMP_HTTP::$headers_sent,
|
| 1649 |
+
'body' => $body,
|
| 1650 |
+
'validation_results' => $validation_results,
|
| 1651 |
+
),
|
| 1652 |
+
AMP_Theme_Support::RESPONSE_CACHE_GROUP,
|
| 1653 |
+
MONTH_IN_SECONDS
|
| 1654 |
+
);
|
| 1655 |
+
};
|
| 1656 |
+
}
|
| 1657 |
+
|
| 1658 |
+
AMP_HTTP::send_server_timing( 'amp_output_buffer', -self::$init_start_time, 'AMP Output Buffer' );
|
| 1659 |
+
|
| 1660 |
+
$dom_parse_start = microtime( true );
|
| 1661 |
+
|
| 1662 |
/*
|
| 1663 |
* Make sure that <meta charset> is present in output prior to parsing.
|
| 1664 |
* Note that the meta charset is supposed to appear within the first 1024 bytes.
|
| 1672 |
1
|
| 1673 |
);
|
| 1674 |
}
|
|
|
|
|
|
|
|
|
|
| 1675 |
|
| 1676 |
+
$dom = AMP_DOM_Utils::get_dom( $response );
|
| 1677 |
$head = $dom->getElementsByTagName( 'head' )->item( 0 );
|
| 1678 |
|
| 1679 |
+
// Remove scripts that are being added for PWA service worker streaming for restoration later.
|
| 1680 |
+
$stream_combine_script_define_element = null;
|
| 1681 |
+
$stream_combine_script_define_placeholder = null;
|
| 1682 |
+
$stream_combine_script_invoke_element = null;
|
| 1683 |
+
$stream_combine_script_invoke_placeholder = null;
|
| 1684 |
+
if ( 'header' === $stream_fragment ) {
|
| 1685 |
+
$stream_combine_script_define_element = $dom->getElementById( WP_Service_Worker_Navigation_Routing_Component::STREAM_COMBINE_DEFINE_SCRIPT_ID );
|
| 1686 |
+
if ( $stream_combine_script_define_element ) {
|
| 1687 |
+
$stream_combine_script_define_placeholder = $dom->createComment( WP_Service_Worker_Navigation_Routing_Component::STREAM_COMBINE_DEFINE_SCRIPT_ID );
|
| 1688 |
+
$stream_combine_script_define_element->parentNode->replaceChild( $stream_combine_script_define_placeholder, $stream_combine_script_define_element );
|
| 1689 |
+
}
|
| 1690 |
+
} elseif ( 'body' === $stream_fragment ) {
|
| 1691 |
+
$stream_combine_script_invoke_placeholder = $dom->getElementById( WP_Service_Worker_Navigation_Routing_Component::STREAM_FRAGMENT_BOUNDARY_ELEMENT_ID );
|
| 1692 |
+
}
|
| 1693 |
+
|
| 1694 |
+
// Move anything after </html>, such as Query Monitor output added at shutdown, to be moved before </body>.
|
| 1695 |
+
$body = $dom->getElementsByTagName( 'body' )->item( 0 );
|
| 1696 |
+
if ( $body ) {
|
| 1697 |
+
while ( $dom->documentElement->nextSibling ) {
|
| 1698 |
+
// Trailing elements after </html> will get wrapped in additional <html> elements.
|
| 1699 |
+
if ( 'html' === $dom->documentElement->nextSibling->nodeName ) {
|
| 1700 |
+
while ( $dom->documentElement->nextSibling->firstChild ) {
|
| 1701 |
+
$body->appendChild( $dom->documentElement->nextSibling->firstChild );
|
| 1702 |
+
}
|
| 1703 |
+
$dom->removeChild( $dom->documentElement->nextSibling );
|
| 1704 |
+
} else {
|
| 1705 |
+
$body->appendChild( $dom->documentElement->nextSibling );
|
| 1706 |
+
}
|
| 1707 |
+
}
|
| 1708 |
+
}
|
| 1709 |
+
|
| 1710 |
+
// Make sure scripts from the body get moved to the head.
|
| 1711 |
if ( isset( $head ) ) {
|
| 1712 |
+
$xpath = new DOMXPath( $dom );
|
| 1713 |
foreach ( $xpath->query( '//body//script[ @custom-element or @custom-template ]' ) as $script ) {
|
| 1714 |
+
$head->appendChild( $script->parentNode->removeChild( $script ) );
|
| 1715 |
}
|
| 1716 |
}
|
| 1717 |
|
| 1718 |
+
// Ensure the mandatory amp attribute is present on the html element.
|
| 1719 |
if ( ! $dom->documentElement->hasAttribute( 'amp' ) && ! $dom->documentElement->hasAttribute( '⚡️' ) ) {
|
| 1720 |
$dom->documentElement->setAttribute( 'amp', '' );
|
| 1721 |
}
|
| 1722 |
|
| 1723 |
+
AMP_HTTP::send_server_timing( 'amp_dom_parse', -$dom_parse_start, 'AMP DOM Parse' );
|
| 1724 |
+
|
| 1725 |
$assets = AMP_Content_Sanitizer::sanitize_document( $dom, self::$sanitizer_classes, $args );
|
| 1726 |
|
| 1727 |
+
// Determine what the validation errors are.
|
| 1728 |
+
$blocking_error_count = 0;
|
| 1729 |
+
$validation_results = array();
|
| 1730 |
+
foreach ( AMP_Validation_Manager::$validation_results as $validation_result ) {
|
| 1731 |
+
if ( ! $validation_result['sanitized'] ) {
|
| 1732 |
+
$blocking_error_count++;
|
| 1733 |
+
}
|
| 1734 |
+
unset( $validation_result['error']['sources'] );
|
| 1735 |
+
$validation_results[] = $validation_result;
|
| 1736 |
+
}
|
| 1737 |
+
|
| 1738 |
+
$dom_serialize_start = microtime( true );
|
| 1739 |
+
|
| 1740 |
+
// Gather all component scripts that are used in the document and then render any not already printed.
|
| 1741 |
+
$amp_scripts = $assets['scripts'];
|
| 1742 |
+
foreach ( self::$embed_handlers as $embed_handler ) {
|
| 1743 |
+
$amp_scripts = array_merge(
|
| 1744 |
+
$amp_scripts,
|
| 1745 |
+
$embed_handler->get_scripts()
|
| 1746 |
+
);
|
| 1747 |
+
}
|
| 1748 |
+
foreach ( $amp_scripts as $handle => $src ) {
|
| 1749 |
+
/*
|
| 1750 |
+
* Make sure the src is up-to-date. This allows for embed handlers to override the
|
| 1751 |
+
* default extension version by defining a different URL.
|
| 1752 |
+
*/
|
| 1753 |
+
if ( is_string( $src ) && wp_script_is( $handle, 'registered' ) ) {
|
| 1754 |
+
wp_scripts()->registered[ $handle ]->src = $src;
|
| 1755 |
+
}
|
| 1756 |
+
}
|
| 1757 |
+
|
| 1758 |
+
self::ensure_required_markup( $dom, array_keys( $amp_scripts ) );
|
| 1759 |
+
|
| 1760 |
+
if ( $blocking_error_count > 0 && ! AMP_Validation_Manager::should_validate_response() ) {
|
| 1761 |
+
/*
|
| 1762 |
+
* In native AMP, strip html@amp attribute to prevent GSC from complaining about a validation error
|
| 1763 |
+
* already surfaced inside of WordPress. This is intended to not serve dirty AMP, but rather a
|
| 1764 |
+
* non-AMP document (intentionally not valid AMP) that contains the AMP runtime and AMP components.
|
| 1765 |
+
*/
|
| 1766 |
+
if ( amp_is_canonical() ) {
|
| 1767 |
+
$dom->documentElement->removeAttribute( 'amp' );
|
| 1768 |
+
$dom->documentElement->removeAttribute( '⚡️' );
|
| 1769 |
+
|
| 1770 |
+
/*
|
| 1771 |
+
* Make sure that document.write() is disabled to prevent dynamically-added content (such as added
|
| 1772 |
+
* via amp-live-list) from wiping out the page by introducing any scripts that call this function.
|
| 1773 |
+
*/
|
| 1774 |
+
if ( $head ) {
|
| 1775 |
+
$script = $dom->createElement( 'script' );
|
| 1776 |
+
$script->appendChild( $dom->createTextNode( 'document.addEventListener( "DOMContentLoaded", function() { document.write = function( text ) { throw new Error( "[AMP-WP] Prevented document.write() call with: " + text ); }; } );' ) );
|
| 1777 |
+
$head->appendChild( $script );
|
| 1778 |
+
}
|
| 1779 |
+
} elseif ( ! self::is_customize_preview_iframe() ) {
|
| 1780 |
+
$response = esc_html__( 'Redirecting to non-AMP version.', 'amp' );
|
| 1781 |
+
|
| 1782 |
+
if ( $cache_response ) {
|
| 1783 |
+
$cache_response( $response, $validation_results );
|
| 1784 |
+
}
|
| 1785 |
+
|
| 1786 |
+
/*
|
| 1787 |
+
* Temporary redirect because AMP URL may return when blocking validation errors
|
| 1788 |
+
* occur or when a non-canonical AMP theme is used.
|
| 1789 |
+
*/
|
| 1790 |
+
if ( AMP_Validation_Manager::has_cap() ) {
|
| 1791 |
+
$ampless_url = add_query_arg( AMP_Validation_Manager::VALIDATION_ERRORS_QUERY_VAR, $blocking_error_count, $ampless_url );
|
| 1792 |
+
}
|
| 1793 |
+
wp_safe_redirect( $ampless_url, 302 );
|
| 1794 |
+
return $response;
|
| 1795 |
+
}
|
| 1796 |
+
}
|
| 1797 |
|
| 1798 |
// @todo If 'utf-8' is not the blog charset, then we'll need to do some character encoding conversation or "entityification".
|
| 1799 |
if ( 'utf-8' !== strtolower( get_bloginfo( 'charset' ) ) ) {
|
| 1800 |
+
/* translators: %s: the charset of the current site. */
|
| 1801 |
trigger_error( esc_html( sprintf( __( 'The database has the %s encoding when it needs to be utf-8 to work with AMP.', 'amp' ), get_bloginfo( 'charset' ) ) ), E_USER_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
|
| 1802 |
}
|
| 1803 |
|
| 1804 |
+
AMP_Validation_Manager::finalize_validation( $dom, array(
|
| 1805 |
+
'remove_source_comments' => ! isset( $_GET['amp_preserve_source_comments'] ), // WPCS: CSRF.
|
| 1806 |
+
) );
|
| 1807 |
+
|
| 1808 |
+
// For service worker streaming, restore the script that was removed above and obtain the script that should be added to the body fragment.
|
| 1809 |
+
$truncate_after_comment = null;
|
| 1810 |
+
$truncate_before_comment = null;
|
| 1811 |
+
if ( $stream_fragment ) {
|
| 1812 |
+
if ( $stream_combine_script_define_placeholder && $stream_combine_script_define_element ) {
|
| 1813 |
+
$stream_combine_script_define_placeholder->parentNode->replaceChild( $stream_combine_script_define_element, $stream_combine_script_define_placeholder );
|
| 1814 |
+
$truncate_after_comment = $dom->createComment( 'AMP_TRUNCATE_RESPONSE_FOR_STREAM_HEADER' );
|
| 1815 |
+
$stream_combine_script_define_element->parentNode->insertBefore( $truncate_after_comment, $stream_combine_script_define_element->nextSibling );
|
| 1816 |
+
}
|
| 1817 |
+
if ( $stream_combine_script_invoke_placeholder ) {
|
| 1818 |
+
$stream_combine_script_invoke_element = WP_Service_Worker_Navigation_Routing_Component::get_header_combine_invoke_script( $dom, false );
|
| 1819 |
+
$stream_combine_script_invoke_placeholder->parentNode->replaceChild( $stream_combine_script_invoke_element, $stream_combine_script_invoke_placeholder );
|
| 1820 |
+
$truncate_before_comment = $dom->createComment( 'AMP_TRUNCATE_RESPONSE_FOR_STREAM_BODY' );
|
| 1821 |
+
$stream_combine_script_invoke_element->parentNode->insertBefore( $truncate_before_comment, $stream_combine_script_invoke_element );
|
| 1822 |
+
}
|
| 1823 |
}
|
| 1824 |
|
| 1825 |
$response = "<!DOCTYPE html>\n";
|
| 1826 |
$response .= AMP_DOM_Utils::get_content_from_dom_node( $dom, $dom->documentElement );
|
| 1827 |
|
| 1828 |
+
// For service worker streaming, make sure that the header response doesn't contain closing tags, and that the body fragment starts with the required script tag.
|
| 1829 |
+
if ( $truncate_after_comment ) {
|
| 1830 |
+
$search = sprintf( '<!--%s-->', $truncate_after_comment->nodeValue );
|
| 1831 |
+
$position = strpos( $response, $search );
|
| 1832 |
+
if ( false !== $position ) {
|
| 1833 |
+
$response = substr( $response, 0, $position );
|
| 1834 |
+
}
|
| 1835 |
+
}
|
| 1836 |
+
if ( $truncate_before_comment ) {
|
| 1837 |
+
$search = sprintf( '<!--%s-->', $truncate_before_comment->nodeValue );
|
| 1838 |
+
$position = strpos( $response, $search );
|
| 1839 |
+
if ( false !== $position ) {
|
| 1840 |
+
$response = substr( $response, $position + strlen( $search ) );
|
| 1841 |
+
}
|
| 1842 |
}
|
| 1843 |
|
| 1844 |
+
AMP_HTTP::send_server_timing( 'amp_dom_serialize', -$dom_serialize_start, 'AMP DOM Serialize' );
|
| 1845 |
+
|
| 1846 |
+
// Cache response if enabled.
|
| 1847 |
+
if ( $cache_response ) {
|
| 1848 |
+
$cache_response( $response, $validation_results );
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1849 |
}
|
| 1850 |
|
| 1851 |
return $response;
|
| 1852 |
}
|
| 1853 |
|
| 1854 |
+
/**
|
| 1855 |
+
* Check for cache misses. When found, store in an option to retain the URL.
|
| 1856 |
+
*
|
| 1857 |
+
* @since 1.0
|
| 1858 |
+
*
|
| 1859 |
+
* @return array {
|
| 1860 |
+
* State.
|
| 1861 |
+
*
|
| 1862 |
+
* @type bool Flag indicating if the threshold has been exceeded.
|
| 1863 |
+
* @type string[] Collection of URLs.
|
| 1864 |
+
* }
|
| 1865 |
+
*/
|
| 1866 |
+
private static function check_for_cache_misses() {
|
| 1867 |
+
// If the cache miss threshold is exceeded, return true.
|
| 1868 |
+
if ( self::exceeded_cache_miss_threshold() ) {
|
| 1869 |
+
return array( true, null );
|
| 1870 |
+
}
|
| 1871 |
+
|
| 1872 |
+
// Get the cache miss URLs.
|
| 1873 |
+
$cache_miss_urls = wp_cache_get( self::POST_PROCESSOR_CACHE_EFFECTIVENESS_KEY, self::POST_PROCESSOR_CACHE_EFFECTIVENESS_GROUP );
|
| 1874 |
+
$cache_miss_urls = is_array( $cache_miss_urls ) ? $cache_miss_urls : array();
|
| 1875 |
+
|
| 1876 |
+
$exceeded_threshold = (
|
| 1877 |
+
! empty( $cache_miss_urls )
|
| 1878 |
+
&&
|
| 1879 |
+
count( $cache_miss_urls ) >= self::CACHE_MISS_THRESHOLD
|
| 1880 |
+
);
|
| 1881 |
+
|
| 1882 |
+
if ( ! $exceeded_threshold ) {
|
| 1883 |
+
return array( $exceeded_threshold, $cache_miss_urls );
|
| 1884 |
+
}
|
| 1885 |
+
|
| 1886 |
+
// When the threshold is exceeded, store the URL for cache miss and turn off response caching.
|
| 1887 |
+
update_option( self::CACHE_MISS_URL_OPTION, amp_get_current_url() );
|
| 1888 |
+
AMP_Options_Manager::update_option( 'enable_response_caching', false );
|
| 1889 |
+
return array( true, null );
|
| 1890 |
+
}
|
| 1891 |
+
|
| 1892 |
+
/**
|
| 1893 |
+
* Reset the cache miss URL option.
|
| 1894 |
+
*
|
| 1895 |
+
* @since 1.0
|
| 1896 |
+
*/
|
| 1897 |
+
public static function reset_cache_miss_url_option() {
|
| 1898 |
+
if ( get_option( self::CACHE_MISS_URL_OPTION ) ) {
|
| 1899 |
+
delete_option( self::CACHE_MISS_URL_OPTION );
|
| 1900 |
+
}
|
| 1901 |
+
}
|
| 1902 |
+
|
| 1903 |
+
/**
|
| 1904 |
+
* Checks if cache miss threshold has been exceeded.
|
| 1905 |
+
*
|
| 1906 |
+
* @since 1.0
|
| 1907 |
+
*
|
| 1908 |
+
* @return bool
|
| 1909 |
+
*/
|
| 1910 |
+
public static function exceeded_cache_miss_threshold() {
|
| 1911 |
+
$url = get_option( self::CACHE_MISS_URL_OPTION, false );
|
| 1912 |
+
return ! empty( $url );
|
| 1913 |
+
}
|
| 1914 |
+
|
| 1915 |
/**
|
| 1916 |
* Adds 'data-amp-layout' to the allowed <img> attributes for wp_kses().
|
| 1917 |
*
|
| 1941 |
// Enqueue default styles expected by sanitizer.
|
| 1942 |
wp_enqueue_style( 'amp-default', amp_get_asset_url( 'css/amp-default.css' ), array(), AMP__VERSION );
|
| 1943 |
}
|
| 1944 |
+
|
| 1945 |
+
/**
|
| 1946 |
+
* Conditionally replace the header image markup with a header video or image.
|
| 1947 |
+
*
|
| 1948 |
+
* This is JS-driven in Core themes like Twenty Sixteen and Twenty Seventeen.
|
| 1949 |
+
* So in order for the header video to display, this replaces the markup of the header image.
|
| 1950 |
+
*
|
| 1951 |
+
* @since 1.0
|
| 1952 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L54
|
| 1953 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/d002fde80e5e3a083e5f950313163f566561517f/src/wp-includes/js/wp-custom-header.js#L78
|
| 1954 |
+
*
|
| 1955 |
+
* @param string $image_markup The image markup to filter.
|
| 1956 |
+
* @return string $html Filtered markup.
|
| 1957 |
+
*/
|
| 1958 |
+
public static function amend_header_image_with_video_header( $image_markup ) {
|
| 1959 |
+
|
| 1960 |
+
// If there is no video, just pass the image through.
|
| 1961 |
+
if ( ! has_header_video() || ! is_header_video_active() ) {
|
| 1962 |
+
return $image_markup;
|
| 1963 |
+
};
|
| 1964 |
+
|
| 1965 |
+
$video_settings = get_header_video_settings();
|
| 1966 |
+
$parsed_url = wp_parse_url( $video_settings['videoUrl'] );
|
| 1967 |
+
$query = isset( $parsed_url['query'] ) ? wp_parse_args( $parsed_url['query'] ) : array();
|
| 1968 |
+
$video_attributes = array(
|
| 1969 |
+
'media' => '(min-width: ' . $video_settings['minWidth'] . 'px)',
|
| 1970 |
+
'width' => $video_settings['width'],
|
| 1971 |
+
'height' => $video_settings['height'],
|
| 1972 |
+
'layout' => 'responsive',
|
| 1973 |
+
'autoplay' => '',
|
| 1974 |
+
'id' => 'wp-custom-header-video',
|
| 1975 |
+
);
|
| 1976 |
+
|
| 1977 |
+
$youtube_id = null;
|
| 1978 |
+
if ( isset( $parsed_url['host'] ) && preg_match( '/(^|\.)(youtube\.com|youtu\.be)$/', $parsed_url['host'] ) ) {
|
| 1979 |
+
if ( 'youtu.be' === $parsed_url['host'] && ! empty( $parsed_url['path'] ) ) {
|
| 1980 |
+
$youtube_id = trim( $parsed_url['path'], '/' );
|
| 1981 |
+
} elseif ( isset( $query['v'] ) ) {
|
| 1982 |
+
$youtube_id = $query['v'];
|
| 1983 |
+
}
|
| 1984 |
+
}
|
| 1985 |
+
|
| 1986 |
+
// If the video URL is for YouTube, return an <amp-youtube> element.
|
| 1987 |
+
if ( ! empty( $youtube_id ) ) {
|
| 1988 |
+
$video_markup = AMP_HTML_Utils::build_tag(
|
| 1989 |
+
'amp-youtube',
|
| 1990 |
+
array_merge(
|
| 1991 |
+
$video_attributes,
|
| 1992 |
+
array(
|
| 1993 |
+
'data-videoid' => $youtube_id,
|
| 1994 |
+
'data-param-rel' => '0', // Don't show related videos.
|
| 1995 |
+
'data-param-showinfo' => '0', // Don't show video title at the top.
|
| 1996 |
+
'data-param-controls' => '0', // Don't show video controls.
|
| 1997 |
+
)
|
| 1998 |
+
)
|
| 1999 |
+
);
|
| 2000 |
+
} else {
|
| 2001 |
+
$video_markup = AMP_HTML_Utils::build_tag(
|
| 2002 |
+
'amp-video',
|
| 2003 |
+
array_merge(
|
| 2004 |
+
$video_attributes,
|
| 2005 |
+
array(
|
| 2006 |
+
'src' => $video_settings['videoUrl'],
|
| 2007 |
+
)
|
| 2008 |
+
)
|
| 2009 |
+
);
|
| 2010 |
+
}
|
| 2011 |
+
|
| 2012 |
+
return $image_markup . $video_markup;
|
| 2013 |
+
}
|
| 2014 |
}
|
|
@@ -1,6 +1,6 @@
|
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
-
*
|
| 4 |
*
|
| 5 |
* @package AMP
|
| 6 |
*/
|
|
@@ -8,9 +8,7 @@
|
|
| 8 |
/**
|
| 9 |
* Load classes for FasterImage.
|
| 10 |
*
|
| 11 |
-
* This is obsolete now that there is an autoloader.
|
| 12 |
-
*
|
| 13 |
-
* @deprecated
|
| 14 |
*/
|
| 15 |
function amp_load_fasterimage_classes() {
|
| 16 |
_deprecated_function( __FUNCTION__, '0.6' );
|
|
@@ -19,9 +17,12 @@ function amp_load_fasterimage_classes() {
|
|
| 19 |
/**
|
| 20 |
* Get FasterImage client for user agent.
|
| 21 |
*
|
|
|
|
|
|
|
| 22 |
* @param string $user_agent User Agent.
|
| 23 |
* @return \FasterImage\FasterImage Instance.
|
| 24 |
*/
|
| 25 |
function amp_get_fasterimage_client( $user_agent ) {
|
|
|
|
| 26 |
return new FasterImage\FasterImage( $user_agent );
|
| 27 |
}
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
+
* Deprecated functions.
|
| 4 |
*
|
| 5 |
* @package AMP
|
| 6 |
*/
|
| 8 |
/**
|
| 9 |
* Load classes for FasterImage.
|
| 10 |
*
|
| 11 |
+
* @deprecated This is obsolete now that there is an autoloader.
|
|
|
|
|
|
|
| 12 |
*/
|
| 13 |
function amp_load_fasterimage_classes() {
|
| 14 |
_deprecated_function( __FUNCTION__, '0.6' );
|
| 17 |
/**
|
| 18 |
* Get FasterImage client for user agent.
|
| 19 |
*
|
| 20 |
+
* @deprecated This function is no longer used in favor of just instantiating the class.
|
| 21 |
+
*
|
| 22 |
* @param string $user_agent User Agent.
|
| 23 |
* @return \FasterImage\FasterImage Instance.
|
| 24 |
*/
|
| 25 |
function amp_get_fasterimage_client( $user_agent ) {
|
| 26 |
+
_deprecated_function( __FUNCTION__, '1.0' );
|
| 27 |
return new FasterImage\FasterImage( $user_agent );
|
| 28 |
}
|
|
@@ -11,18 +11,52 @@
|
|
| 11 |
* Class AMP_Base_Embed_Handler
|
| 12 |
*/
|
| 13 |
abstract class AMP_Base_Embed_Handler {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
protected $DEFAULT_WIDTH = 600;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
protected $DEFAULT_HEIGHT = 480;
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
protected $args = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
protected $did_convert_elements = false;
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
| 22 |
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
$this->args = wp_parse_args( $args, array(
|
| 25 |
-
'width'
|
| 26 |
'height' => $this->DEFAULT_HEIGHT,
|
| 27 |
) );
|
| 28 |
}
|
| 11 |
* Class AMP_Base_Embed_Handler
|
| 12 |
*/
|
| 13 |
abstract class AMP_Base_Embed_Handler {
|
| 14 |
+
/**
|
| 15 |
+
* Default width.
|
| 16 |
+
*
|
| 17 |
+
* @var int
|
| 18 |
+
*/
|
| 19 |
protected $DEFAULT_WIDTH = 600;
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* Default height.
|
| 23 |
+
*
|
| 24 |
+
* @var int
|
| 25 |
+
*/
|
| 26 |
protected $DEFAULT_HEIGHT = 480;
|
| 27 |
|
| 28 |
+
/**
|
| 29 |
+
* Default arguments.
|
| 30 |
+
*
|
| 31 |
+
* @var array
|
| 32 |
+
*/
|
| 33 |
protected $args = array();
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* Whether or not conversion was completed.
|
| 37 |
+
*
|
| 38 |
+
* @var boolean
|
| 39 |
+
*/
|
| 40 |
protected $did_convert_elements = false;
|
| 41 |
|
| 42 |
+
/**
|
| 43 |
+
* Register embed.
|
| 44 |
+
*/
|
| 45 |
+
abstract public function register_embed();
|
| 46 |
|
| 47 |
+
/**
|
| 48 |
+
* Unregister embed.
|
| 49 |
+
*/
|
| 50 |
+
abstract public function unregister_embed();
|
| 51 |
+
|
| 52 |
+
/**
|
| 53 |
+
* AMP_Base_Embed_Handler constructor.
|
| 54 |
+
*
|
| 55 |
+
* @param array $args Height and width for embed.
|
| 56 |
+
*/
|
| 57 |
+
public function __construct( $args = array() ) {
|
| 58 |
$this->args = wp_parse_args( $args, array(
|
| 59 |
+
'width' => $this->DEFAULT_WIDTH,
|
| 60 |
'height' => $this->DEFAULT_HEIGHT,
|
| 61 |
) );
|
| 62 |
}
|
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Core_Block_Handler
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Class AMP_Core_Block_Handler
|
| 10 |
+
*
|
| 11 |
+
* @since 1.0
|
| 12 |
+
*/
|
| 13 |
+
class AMP_Core_Block_Handler extends AMP_Base_Embed_Handler {
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* Original block callback.
|
| 17 |
+
*
|
| 18 |
+
* @var array
|
| 19 |
+
*/
|
| 20 |
+
public $original_categories_callback;
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* Block name.
|
| 24 |
+
*
|
| 25 |
+
* @var string
|
| 26 |
+
*/
|
| 27 |
+
public $block_name = 'core/categories';
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
+
* Register embed.
|
| 31 |
+
*/
|
| 32 |
+
public function register_embed() {
|
| 33 |
+
if ( class_exists( 'WP_Block_Type_Registry' ) ) {
|
| 34 |
+
$registry = WP_Block_Type_Registry::get_instance();
|
| 35 |
+
$block = $registry->get_registered( $this->block_name );
|
| 36 |
+
|
| 37 |
+
if ( $block ) {
|
| 38 |
+
$this->original_categories_callback = $block->render_callback;
|
| 39 |
+
$block->render_callback = array( $this, 'render' );
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Unregister embed.
|
| 46 |
+
*/
|
| 47 |
+
public function unregister_embed() {
|
| 48 |
+
if ( class_exists( 'WP_Block_Type_Registry' ) ) {
|
| 49 |
+
$registry = WP_Block_Type_Registry::get_instance();
|
| 50 |
+
$block = $registry->get_registered( $this->block_name );
|
| 51 |
+
|
| 52 |
+
if ( $block && ! empty( $this->original_categories_callback ) ) {
|
| 53 |
+
$block->render_callback = $this->original_categories_callback;
|
| 54 |
+
$this->original_categories_callback = null;
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
/**
|
| 60 |
+
* Render Gutenberg block. This is essentially the same method as the original.
|
| 61 |
+
* Difference is excluding the disallowed JS script, adding <form> tags, and using on:change for <select>.
|
| 62 |
+
*
|
| 63 |
+
* @param array $attributes Attributes.
|
| 64 |
+
* @return string Rendered.
|
| 65 |
+
*/
|
| 66 |
+
public function render( $attributes ) {
|
| 67 |
+
static $block_id = 0;
|
| 68 |
+
$block_id++;
|
| 69 |
+
|
| 70 |
+
$align = 'center';
|
| 71 |
+
if ( isset( $attributes['align'] ) && in_array( $attributes['align'], array( 'left', 'right', 'full' ), true ) ) {
|
| 72 |
+
$align = $attributes['align'];
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
$args = array(
|
| 76 |
+
'echo' => false,
|
| 77 |
+
'hierarchical' => ! empty( $attributes['showHierarchy'] ),
|
| 78 |
+
'orderby' => 'name',
|
| 79 |
+
'show_count' => ! empty( $attributes['showPostCounts'] ),
|
| 80 |
+
'title_li' => '',
|
| 81 |
+
);
|
| 82 |
+
|
| 83 |
+
if ( ! empty( $attributes['displayAsDropdown'] ) ) {
|
| 84 |
+
$id = 'wp-block-categories-dropdown-' . $block_id;
|
| 85 |
+
$form_id = $id . '-form';
|
| 86 |
+
$args['id'] = $id;
|
| 87 |
+
$args['show_option_none'] = __( 'Select Category', 'amp' );
|
| 88 |
+
$wrapper_markup = '<div class="%1$s">%2$s</div>';
|
| 89 |
+
$items_markup = wp_dropdown_categories( $args );
|
| 90 |
+
$type = 'dropdown';
|
| 91 |
+
|
| 92 |
+
$items_markup = preg_replace(
|
| 93 |
+
'/(?<=<select\b)/',
|
| 94 |
+
sprintf( ' on="change:%s.submit"', esc_attr( $form_id ) ),
|
| 95 |
+
$items_markup,
|
| 96 |
+
1
|
| 97 |
+
);
|
| 98 |
+
} else {
|
| 99 |
+
$wrapper_markup = '<div class="%1$s"><ul>%2$s</ul></div>';
|
| 100 |
+
$items_markup = wp_list_categories( $args );
|
| 101 |
+
$type = 'list';
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
$class = "wp-block-categories wp-block-categories-{$type} align{$align}";
|
| 105 |
+
|
| 106 |
+
$block_content = sprintf(
|
| 107 |
+
$wrapper_markup,
|
| 108 |
+
esc_attr( $class ),
|
| 109 |
+
$items_markup
|
| 110 |
+
);
|
| 111 |
+
|
| 112 |
+
if ( ! empty( $attributes['displayAsDropdown'] ) ) {
|
| 113 |
+
$block_content = sprintf( '<form action="%s" method="get" target="_top" id="%s">%s</form>', esc_url( home_url() ), esc_attr( $form_id ), $block_content );
|
| 114 |
+
}
|
| 115 |
+
return $block_content;
|
| 116 |
+
}
|
| 117 |
+
}
|
|
@@ -13,31 +13,59 @@
|
|
| 13 |
class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler {
|
| 14 |
|
| 15 |
const URL_PATTERN = '#https?:\/\/(www\.)?dailymotion\.com\/video\/.*#i';
|
| 16 |
-
const RATIO
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
protected $DEFAULT_WIDTH = 600;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
protected $DEFAULT_HEIGHT = 338;
|
| 20 |
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
parent::__construct( $args );
|
| 23 |
|
| 24 |
if ( isset( $this->args['content_max_width'] ) ) {
|
| 25 |
-
$max_width
|
| 26 |
-
$this->args['width']
|
| 27 |
$this->args['height'] = round( $max_width * self::RATIO );
|
| 28 |
}
|
| 29 |
}
|
| 30 |
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
| 32 |
wp_embed_register_handler( 'amp-dailymotion', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 33 |
add_shortcode( 'dailymotion', array( $this, 'shortcode' ) );
|
| 34 |
}
|
| 35 |
|
|
|
|
|
|
|
|
|
|
| 36 |
public function unregister_embed() {
|
| 37 |
wp_embed_unregister_handler( 'amp-dailymotion', -1 );
|
| 38 |
remove_shortcode( 'dailymotion' );
|
| 39 |
}
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
public function shortcode( $attr ) {
|
| 42 |
$video_id = false;
|
| 43 |
|
|
@@ -53,25 +81,53 @@ class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 53 |
return '';
|
| 54 |
}
|
| 55 |
|
| 56 |
-
return $this->render(
|
| 57 |
-
|
| 58 |
-
|
|
|
|
|
|
|
| 59 |
}
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 62 |
$video_id = $this->get_video_id_from_url( $url );
|
| 63 |
-
return $this->render(
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
| 66 |
}
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
public function render( $args ) {
|
| 69 |
-
$args = wp_parse_args(
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
| 72 |
|
| 73 |
if ( empty( $args['video_id'] ) ) {
|
| 74 |
-
return AMP_HTML_Utils::build_tag(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
}
|
| 76 |
|
| 77 |
$this->did_convert_elements = true;
|
|
@@ -80,18 +136,24 @@ class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 80 |
'amp-dailymotion',
|
| 81 |
array(
|
| 82 |
'data-videoid' => $args['video_id'],
|
| 83 |
-
'layout'
|
| 84 |
-
'width'
|
| 85 |
-
'height'
|
| 86 |
)
|
| 87 |
);
|
| 88 |
}
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
private function get_video_id_from_url( $url ) {
|
| 91 |
-
$parsed_url =
|
| 92 |
parse_str( $parsed_url['path'], $path );
|
| 93 |
-
$tok
|
| 94 |
-
$tok
|
| 95 |
$video_id = $tok[0];
|
| 96 |
|
| 97 |
return $video_id;
|
| 13 |
class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler {
|
| 14 |
|
| 15 |
const URL_PATTERN = '#https?:\/\/(www\.)?dailymotion\.com\/video\/.*#i';
|
| 16 |
+
const RATIO = 0.5625;
|
| 17 |
|
| 18 |
+
/**
|
| 19 |
+
* Default width.
|
| 20 |
+
*
|
| 21 |
+
* @var int
|
| 22 |
+
*/
|
| 23 |
protected $DEFAULT_WIDTH = 600;
|
| 24 |
+
|
| 25 |
+
/**
|
| 26 |
+
* Default height.
|
| 27 |
+
*
|
| 28 |
+
* @var int
|
| 29 |
+
*/
|
| 30 |
protected $DEFAULT_HEIGHT = 338;
|
| 31 |
|
| 32 |
+
/**
|
| 33 |
+
* AMP_DailyMotion_Embed_Handler constructor.
|
| 34 |
+
*
|
| 35 |
+
* @param array $args Height, width and maximum width for embed.
|
| 36 |
+
*/
|
| 37 |
+
public function __construct( $args = array() ) {
|
| 38 |
parent::__construct( $args );
|
| 39 |
|
| 40 |
if ( isset( $this->args['content_max_width'] ) ) {
|
| 41 |
+
$max_width = $this->args['content_max_width'];
|
| 42 |
+
$this->args['width'] = $max_width;
|
| 43 |
$this->args['height'] = round( $max_width * self::RATIO );
|
| 44 |
}
|
| 45 |
}
|
| 46 |
|
| 47 |
+
/**
|
| 48 |
+
* Register embed.
|
| 49 |
+
*/
|
| 50 |
+
public function register_embed() {
|
| 51 |
wp_embed_register_handler( 'amp-dailymotion', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 52 |
add_shortcode( 'dailymotion', array( $this, 'shortcode' ) );
|
| 53 |
}
|
| 54 |
|
| 55 |
+
/**
|
| 56 |
+
* Unregister embed.
|
| 57 |
+
*/
|
| 58 |
public function unregister_embed() {
|
| 59 |
wp_embed_unregister_handler( 'amp-dailymotion', -1 );
|
| 60 |
remove_shortcode( 'dailymotion' );
|
| 61 |
}
|
| 62 |
|
| 63 |
+
/**
|
| 64 |
+
* Gets AMP-compliant markup for the Dailymotion shortcode.
|
| 65 |
+
*
|
| 66 |
+
* @param array $attr The Dailymotion attributes.
|
| 67 |
+
* @return string Dailymotion shortcode markup.
|
| 68 |
+
*/
|
| 69 |
public function shortcode( $attr ) {
|
| 70 |
$video_id = false;
|
| 71 |
|
| 81 |
return '';
|
| 82 |
}
|
| 83 |
|
| 84 |
+
return $this->render(
|
| 85 |
+
array(
|
| 86 |
+
'video_id' => $video_id,
|
| 87 |
+
)
|
| 88 |
+
);
|
| 89 |
}
|
| 90 |
|
| 91 |
+
/**
|
| 92 |
+
* Render oEmbed.
|
| 93 |
+
*
|
| 94 |
+
* @see \WP_Embed::shortcode()
|
| 95 |
+
*
|
| 96 |
+
* @param array $matches URL pattern matches.
|
| 97 |
+
* @param array $attr Shortcode attribues.
|
| 98 |
+
* @param string $url URL.
|
| 99 |
+
* @param string $rawattr Unmodified shortcode attributes.
|
| 100 |
+
* @return string Rendered oEmbed.
|
| 101 |
+
*/
|
| 102 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 103 |
$video_id = $this->get_video_id_from_url( $url );
|
| 104 |
+
return $this->render(
|
| 105 |
+
array(
|
| 106 |
+
'video_id' => $video_id,
|
| 107 |
+
)
|
| 108 |
+
);
|
| 109 |
}
|
| 110 |
|
| 111 |
+
/**
|
| 112 |
+
* Render.
|
| 113 |
+
*
|
| 114 |
+
* @param array $args Args.
|
| 115 |
+
* @return string Rendered.
|
| 116 |
+
*/
|
| 117 |
public function render( $args ) {
|
| 118 |
+
$args = wp_parse_args(
|
| 119 |
+
$args, array(
|
| 120 |
+
'video_id' => false,
|
| 121 |
+
)
|
| 122 |
+
);
|
| 123 |
|
| 124 |
if ( empty( $args['video_id'] ) ) {
|
| 125 |
+
return AMP_HTML_Utils::build_tag(
|
| 126 |
+
'a', array(
|
| 127 |
+
'href' => esc_url( $args['url'] ),
|
| 128 |
+
'class' => 'amp-wp-embed-fallback',
|
| 129 |
+
), esc_html( $args['url'] )
|
| 130 |
+
);
|
| 131 |
}
|
| 132 |
|
| 133 |
$this->did_convert_elements = true;
|
| 136 |
'amp-dailymotion',
|
| 137 |
array(
|
| 138 |
'data-videoid' => $args['video_id'],
|
| 139 |
+
'layout' => 'responsive',
|
| 140 |
+
'width' => $this->args['width'],
|
| 141 |
+
'height' => $this->args['height'],
|
| 142 |
)
|
| 143 |
);
|
| 144 |
}
|
| 145 |
|
| 146 |
+
/**
|
| 147 |
+
* Determine the video ID from the URL.
|
| 148 |
+
*
|
| 149 |
+
* @param string $url URL.
|
| 150 |
+
* @return integer Video ID.
|
| 151 |
+
*/
|
| 152 |
private function get_video_id_from_url( $url ) {
|
| 153 |
+
$parsed_url = wp_parse_url( $url );
|
| 154 |
parse_str( $parsed_url['path'], $path );
|
| 155 |
+
$tok = explode( '/', $parsed_url['path'] );
|
| 156 |
+
$tok = explode( '_', $tok[2] );
|
| 157 |
$video_id = $tok[0];
|
| 158 |
|
| 159 |
return $video_id;
|
|
@@ -14,12 +14,26 @@ class AMP_Facebook_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 14 |
protected $DEFAULT_WIDTH = 600;
|
| 15 |
protected $DEFAULT_HEIGHT = 400;
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
public function register_embed() {
|
| 18 |
-
wp_embed_register_handler(
|
| 19 |
}
|
| 20 |
|
| 21 |
public function unregister_embed() {
|
| 22 |
-
wp_embed_unregister_handler(
|
| 23 |
}
|
| 24 |
|
| 25 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
|
@@ -38,13 +52,86 @@ class AMP_Facebook_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 38 |
$this->did_convert_elements = true;
|
| 39 |
|
| 40 |
return AMP_HTML_Utils::build_tag(
|
| 41 |
-
|
| 42 |
array(
|
| 43 |
'data-href' => $args['url'],
|
| 44 |
-
'layout'
|
| 45 |
-
'width'
|
| 46 |
-
'height'
|
| 47 |
)
|
| 48 |
);
|
| 49 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
}
|
| 14 |
protected $DEFAULT_WIDTH = 600;
|
| 15 |
protected $DEFAULT_HEIGHT = 400;
|
| 16 |
|
| 17 |
+
/**
|
| 18 |
+
* Tag.
|
| 19 |
+
*
|
| 20 |
+
* @var string embed HTML blockquote tag to identify and replace with AMP version.
|
| 21 |
+
*/
|
| 22 |
+
protected $sanitize_tag = 'div';
|
| 23 |
+
|
| 24 |
+
/**
|
| 25 |
+
* Tag.
|
| 26 |
+
*
|
| 27 |
+
* @var string AMP amp-facebook tag
|
| 28 |
+
*/
|
| 29 |
+
private $amp_tag = 'amp-facebook';
|
| 30 |
+
|
| 31 |
public function register_embed() {
|
| 32 |
+
wp_embed_register_handler( $this->amp_tag, self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 33 |
}
|
| 34 |
|
| 35 |
public function unregister_embed() {
|
| 36 |
+
wp_embed_unregister_handler( $this->amp_tag, -1 );
|
| 37 |
}
|
| 38 |
|
| 39 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 52 |
$this->did_convert_elements = true;
|
| 53 |
|
| 54 |
return AMP_HTML_Utils::build_tag(
|
| 55 |
+
$this->amp_tag,
|
| 56 |
array(
|
| 57 |
'data-href' => $args['url'],
|
| 58 |
+
'layout' => 'responsive',
|
| 59 |
+
'width' => $this->args['width'],
|
| 60 |
+
'height' => $this->args['height'],
|
| 61 |
)
|
| 62 |
);
|
| 63 |
}
|
| 64 |
+
|
| 65 |
+
/**
|
| 66 |
+
* Sanitized <div class="fb-video" data-href=> tags to <amp-facebook>.
|
| 67 |
+
*
|
| 68 |
+
* @param DOMDocument $dom DOM.
|
| 69 |
+
*/
|
| 70 |
+
public function sanitize_raw_embeds( $dom ) {
|
| 71 |
+
/**
|
| 72 |
+
* Node list.
|
| 73 |
+
*
|
| 74 |
+
* @var DOMNodeList $node
|
| 75 |
+
*/
|
| 76 |
+
$nodes = $dom->getElementsByTagName( $this->sanitize_tag );
|
| 77 |
+
$num_nodes = $nodes->length;
|
| 78 |
+
|
| 79 |
+
if ( 0 === $num_nodes ) {
|
| 80 |
+
return;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 84 |
+
$node = $nodes->item( $i );
|
| 85 |
+
if ( ! $node instanceof DOMElement ) {
|
| 86 |
+
continue;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
$embed_type = $this->get_embed_type( $node );
|
| 90 |
+
|
| 91 |
+
if ( null !== $embed_type ) {
|
| 92 |
+
$this->create_amp_facebook_and_replace_node( $dom, $node, $embed_type );
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
/**
|
| 98 |
+
* Get embed type.
|
| 99 |
+
*
|
| 100 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 101 |
+
* @return string|null Embed type or null if not detected.
|
| 102 |
+
*/
|
| 103 |
+
private function get_embed_type( $node ) {
|
| 104 |
+
$class_attr = $node->getAttribute( 'class' );
|
| 105 |
+
if ( null !== $class_attr && $node->hasAttribute( 'data-href' ) ) {
|
| 106 |
+
if ( false !== strpos( $class_attr, 'fb-post' ) ) {
|
| 107 |
+
return 'post';
|
| 108 |
+
} elseif ( false !== strpos( $class_attr, 'fb-video' ) ) {
|
| 109 |
+
return 'video';
|
| 110 |
+
}
|
| 111 |
+
return false !== strpos( $class_attr, 'fb-video' ) ? 'video' : 'post';
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
return null;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
/**
|
| 118 |
+
* Create amp-facebook and replace node.
|
| 119 |
+
*
|
| 120 |
+
* @param DOMDocument $dom The HTML Document.
|
| 121 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 122 |
+
* @param string $embed_type Embed type.
|
| 123 |
+
*/
|
| 124 |
+
private function create_amp_facebook_and_replace_node( $dom, $node, $embed_type ) {
|
| 125 |
+
$amp_facebook_node = AMP_DOM_Utils::create_node( $dom, $this->amp_tag, array(
|
| 126 |
+
'data-href' => $node->getAttribute( 'data-href' ),
|
| 127 |
+
'data-embed-as' => $embed_type,
|
| 128 |
+
'layout' => 'responsive',
|
| 129 |
+
'width' => $this->DEFAULT_WIDTH,
|
| 130 |
+
'height' => $this->DEFAULT_HEIGHT,
|
| 131 |
+
) );
|
| 132 |
+
|
| 133 |
+
$node->parentNode->replaceChild( $amp_facebook_node, $node );
|
| 134 |
+
|
| 135 |
+
$this->did_convert_elements = true;
|
| 136 |
+
}
|
| 137 |
}
|
|
@@ -16,7 +16,8 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 16 |
* Register embed.
|
| 17 |
*/
|
| 18 |
public function register_embed() {
|
| 19 |
-
add_filter( 'post_gallery', array( $this, '
|
|
|
|
| 20 |
}
|
| 21 |
|
| 22 |
/**
|
|
@@ -51,6 +52,10 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 51 |
'link' => 'none',
|
| 52 |
), $attr, 'gallery' );
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
$id = intval( $atts['id'] );
|
| 55 |
|
| 56 |
if ( ! empty( $atts['include'] ) ) {
|
|
@@ -99,10 +104,12 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 99 |
}
|
| 100 |
|
| 101 |
$href = null;
|
| 102 |
-
if (
|
| 103 |
-
$
|
| 104 |
-
|
| 105 |
-
|
|
|
|
|
|
|
| 106 |
}
|
| 107 |
|
| 108 |
$urls[] = array(
|
|
@@ -113,13 +120,28 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 113 |
);
|
| 114 |
}
|
| 115 |
|
| 116 |
-
|
| 117 |
'images' => $urls,
|
| 118 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
}
|
| 120 |
|
| 121 |
/**
|
| 122 |
-
* Override the output of gallery_shortcode().
|
| 123 |
*
|
| 124 |
* The 'Gallery' widget also uses this function.
|
| 125 |
* This ensures that it outputs an <amp-carousel>.
|
|
@@ -128,7 +150,27 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 128 |
* @param array $attributes Shortcode attributes.
|
| 129 |
* @return string $html Markup for the gallery.
|
| 130 |
*/
|
| 131 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
return $this->shortcode( $attributes );
|
| 133 |
}
|
| 134 |
|
|
@@ -151,14 +193,21 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 151 |
|
| 152 |
$images = array();
|
| 153 |
foreach ( $args['images'] as $props ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
$image = AMP_HTML_Utils::build_tag(
|
| 155 |
'amp-img',
|
| 156 |
-
|
| 157 |
-
'src' => $props['url'],
|
| 158 |
-
'width' => $props['width'],
|
| 159 |
-
'height' => $props['height'],
|
| 160 |
-
'layout' => 'responsive',
|
| 161 |
-
)
|
| 162 |
);
|
| 163 |
|
| 164 |
if ( ! empty( $props['href'] ) ) {
|
|
@@ -185,4 +234,25 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 185 |
implode( PHP_EOL, $images )
|
| 186 |
);
|
| 187 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
}
|
| 16 |
* Register embed.
|
| 17 |
*/
|
| 18 |
public function register_embed() {
|
| 19 |
+
add_filter( 'post_gallery', array( $this, 'maybe_override_gallery' ), 10, 2 );
|
| 20 |
+
add_action( 'wp_print_styles', array( $this, 'print_styles' ) );
|
| 21 |
}
|
| 22 |
|
| 23 |
/**
|
| 52 |
'link' => 'none',
|
| 53 |
), $attr, 'gallery' );
|
| 54 |
|
| 55 |
+
if ( ! empty( $attr['amp-lightbox'] ) ) {
|
| 56 |
+
$atts['lightbox'] = filter_var( $attr['amp-lightbox'], FILTER_VALIDATE_BOOLEAN );
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
$id = intval( $atts['id'] );
|
| 60 |
|
| 61 |
if ( ! empty( $atts['include'] ) ) {
|
| 104 |
}
|
| 105 |
|
| 106 |
$href = null;
|
| 107 |
+
if ( empty( $atts['lightbox'] ) ) {
|
| 108 |
+
if ( ! empty( $atts['link'] ) && 'file' === $atts['link'] ) {
|
| 109 |
+
$href = $url;
|
| 110 |
+
} elseif ( ! empty( $atts['link'] ) && 'post' === $atts['link'] ) {
|
| 111 |
+
$href = get_attachment_link( $attachment_id );
|
| 112 |
+
}
|
| 113 |
}
|
| 114 |
|
| 115 |
$urls[] = array(
|
| 120 |
);
|
| 121 |
}
|
| 122 |
|
| 123 |
+
$args = array(
|
| 124 |
'images' => $urls,
|
| 125 |
+
);
|
| 126 |
+
if ( ! empty( $atts['lightbox'] ) ) {
|
| 127 |
+
$args['lightbox'] = true;
|
| 128 |
+
$lightbox_tag = AMP_HTML_Utils::build_tag(
|
| 129 |
+
'amp-image-lightbox',
|
| 130 |
+
array(
|
| 131 |
+
'id' => AMP_Base_Sanitizer::AMP_IMAGE_LIGHTBOX_ID,
|
| 132 |
+
'layout' => 'nodisplay',
|
| 133 |
+
'data-close-button-aria-label' => __( 'Close', 'amp' ),
|
| 134 |
+
)
|
| 135 |
+
);
|
| 136 |
+
/* We need to add lightbox tag, too. @todo Could there be a better alternative for this? */
|
| 137 |
+
return $this->render( $args ) . $lightbox_tag;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
return $this->render( $args );
|
| 141 |
}
|
| 142 |
|
| 143 |
/**
|
| 144 |
+
* Override the output of gallery_shortcode() if amp-carousel is not false.
|
| 145 |
*
|
| 146 |
* The 'Gallery' widget also uses this function.
|
| 147 |
* This ensures that it outputs an <amp-carousel>.
|
| 150 |
* @param array $attributes Shortcode attributes.
|
| 151 |
* @return string $html Markup for the gallery.
|
| 152 |
*/
|
| 153 |
+
public function maybe_override_gallery( $html, $attributes ) {
|
| 154 |
+
$is_lightbox = isset( $attributes['amp-lightbox'] ) && true === filter_var( $attributes['amp-lightbox'], FILTER_VALIDATE_BOOLEAN );
|
| 155 |
+
if ( isset( $attributes['amp-carousel'] ) && false === filter_var( $attributes['amp-carousel'], FILTER_VALIDATE_BOOLEAN ) ) {
|
| 156 |
+
if ( true === $is_lightbox ) {
|
| 157 |
+
remove_filter( 'post_gallery', array( $this, 'maybe_override_gallery' ), 10 );
|
| 158 |
+
$attributes['link'] = 'none';
|
| 159 |
+
$html = '<ul class="amp-lightbox">' . gallery_shortcode( $attributes ) . '</ul>';
|
| 160 |
+
add_filter( 'post_gallery', array( $this, 'maybe_override_gallery' ), 10, 2 );
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
return $html;
|
| 164 |
+
} elseif ( isset( $attributes['size'] ) && 'thumbnail' === $attributes['size'] ) {
|
| 165 |
+
/*
|
| 166 |
+
* If the 'gallery' shortcode has a 'size' attribute of 'thumbnail', prevent outputting an <amp-carousel>.
|
| 167 |
+
* That will often get thumbnail images around 150 x 150,
|
| 168 |
+
* while the <amp-carousel> usually has a width of 600 and a height of 480.
|
| 169 |
+
* That often means very low-resolution images.
|
| 170 |
+
* So fall back to the normal 'gallery' shortcode callback, gallery_shortcode().
|
| 171 |
+
*/
|
| 172 |
+
return '';
|
| 173 |
+
}
|
| 174 |
return $this->shortcode( $attributes );
|
| 175 |
}
|
| 176 |
|
| 193 |
|
| 194 |
$images = array();
|
| 195 |
foreach ( $args['images'] as $props ) {
|
| 196 |
+
$image_atts = array(
|
| 197 |
+
'src' => $props['url'],
|
| 198 |
+
'width' => $props['width'],
|
| 199 |
+
'height' => $props['height'],
|
| 200 |
+
'layout' => 'responsive',
|
| 201 |
+
);
|
| 202 |
+
if ( ! empty( $args['lightbox'] ) ) {
|
| 203 |
+
$image_atts['lightbox'] = '';
|
| 204 |
+
$image_atts['on'] = 'tap:' . AMP_Img_Sanitizer::AMP_IMAGE_LIGHTBOX_ID;
|
| 205 |
+
$image_atts['role'] = 'button';
|
| 206 |
+
$image_atts['tabindex'] = 0;
|
| 207 |
+
}
|
| 208 |
$image = AMP_HTML_Utils::build_tag(
|
| 209 |
'amp-img',
|
| 210 |
+
$image_atts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
);
|
| 212 |
|
| 213 |
if ( ! empty( $props['href'] ) ) {
|
| 234 |
implode( PHP_EOL, $images )
|
| 235 |
);
|
| 236 |
}
|
| 237 |
+
|
| 238 |
+
/**
|
| 239 |
+
* Prints the Gallery block styling.
|
| 240 |
+
*
|
| 241 |
+
* It would be better to print this in AMP_Gallery_Block_Sanitizer,
|
| 242 |
+
* but by the time that runs, it's too late.
|
| 243 |
+
* This rule is copied exactly from block-library/style.css, but the selector here has amp-img >.
|
| 244 |
+
* The image sanitizer normally converts the <img> from that original stylesheet <amp-img>,
|
| 245 |
+
* but that doesn't have the same effect as applying it to the <img>.
|
| 246 |
+
*
|
| 247 |
+
* @return void
|
| 248 |
+
*/
|
| 249 |
+
public function print_styles() {
|
| 250 |
+
?>
|
| 251 |
+
<style>
|
| 252 |
+
.wp-block-gallery.is-cropped .blocks-gallery-item amp-img > img {
|
| 253 |
+
object-fit: cover;
|
| 254 |
+
}
|
| 255 |
+
</style>
|
| 256 |
+
<?php
|
| 257 |
+
}
|
| 258 |
}
|
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Gfycat_Embed_Handler
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
* @since 1.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Class AMP_Gfycat_Embed_Handler
|
| 11 |
+
*/
|
| 12 |
+
class AMP_Gfycat_Embed_Handler extends AMP_Base_Embed_Handler {
|
| 13 |
+
/**
|
| 14 |
+
* Regex matched to produce output amp-gfycat.
|
| 15 |
+
*
|
| 16 |
+
* @var string
|
| 17 |
+
*/
|
| 18 |
+
const URL_PATTERN = '#https?://(www\.)?gfycat\.com/.*#i';
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Register embed.
|
| 22 |
+
*/
|
| 23 |
+
public function register_embed() {
|
| 24 |
+
add_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10, 3 );
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
/**
|
| 28 |
+
* Unregister embed.
|
| 29 |
+
*/
|
| 30 |
+
public function unregister_embed() {
|
| 31 |
+
remove_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10 );
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/**
|
| 35 |
+
* Filter oEmbed HTML for Gfycat to prepare it for AMP.
|
| 36 |
+
*
|
| 37 |
+
* @param mixed $return The shortcode callback function to call.
|
| 38 |
+
* @param string $url The attempted embed URL.
|
| 39 |
+
* @param array $attr An array of shortcode attributes.
|
| 40 |
+
* @return string Embed.
|
| 41 |
+
*/
|
| 42 |
+
public function filter_embed_oembed_html( $return, $url, $attr ) {
|
| 43 |
+
$parsed_url = wp_parse_url( $url );
|
| 44 |
+
if ( false !== strpos( $parsed_url['host'], 'gfycat.com' ) ) {
|
| 45 |
+
if ( preg_match( '/width=["\']?(\d+)/', $return, $matches ) ) {
|
| 46 |
+
$attr['width'] = $matches[1];
|
| 47 |
+
}
|
| 48 |
+
if ( preg_match( '/height=["\']?(\d+)/', $return, $matches ) ) {
|
| 49 |
+
$attr['height'] = $matches[1];
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
if ( empty( $attr['height'] ) ) {
|
| 53 |
+
return $return;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
$attributes = wp_array_slice_assoc( $attr, array( 'width', 'height' ) );
|
| 57 |
+
|
| 58 |
+
if ( empty( $attr['width'] ) ) {
|
| 59 |
+
$attributes['layout'] = 'fixed-height';
|
| 60 |
+
$attributes['width'] = 'auto';
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
$pieces = explode( '/detail/', $parsed_url['path'] );
|
| 64 |
+
if ( ! isset( $pieces[1] ) ) {
|
| 65 |
+
if ( ! preg_match( '/\/([A-Za-z0-9]+)/', $parsed_url['path'], $matches ) ) {
|
| 66 |
+
return $return;
|
| 67 |
+
}
|
| 68 |
+
$attributes['data-gfyid'] = $matches[1];
|
| 69 |
+
} else {
|
| 70 |
+
$attributes['data-gfyid'] = $pieces[1];
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
$return = AMP_HTML_Utils::build_tag(
|
| 74 |
+
'amp-gfycat',
|
| 75 |
+
$attributes
|
| 76 |
+
);
|
| 77 |
+
}
|
| 78 |
+
return $return;
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
|
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Hulu_Embed_Handler
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
* @since 1.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Class AMP_Hulu_Embed_Handler
|
| 11 |
+
*/
|
| 12 |
+
class AMP_Hulu_Embed_Handler extends AMP_Base_Embed_Handler {
|
| 13 |
+
/**
|
| 14 |
+
* Regex matched to produce output amp-hulu.
|
| 15 |
+
*
|
| 16 |
+
* @var string
|
| 17 |
+
*/
|
| 18 |
+
const URL_PATTERN = '#https?://(www\.)?hulu\.com/.*#i';
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Default height.
|
| 22 |
+
*
|
| 23 |
+
* @var int
|
| 24 |
+
*/
|
| 25 |
+
protected $DEFAULT_HEIGHT = 600;
|
| 26 |
+
|
| 27 |
+
/**
|
| 28 |
+
* Register embed.
|
| 29 |
+
*/
|
| 30 |
+
public function register_embed() {
|
| 31 |
+
add_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10, 3 );
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/**
|
| 35 |
+
* Unregister embed.
|
| 36 |
+
*/
|
| 37 |
+
public function unregister_embed() {
|
| 38 |
+
remove_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10 );
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
/**
|
| 42 |
+
* Filter oEmbed HTML for Hulu to prepare it for AMP.
|
| 43 |
+
*
|
| 44 |
+
* @param mixed $return The shortcode callback function to call.
|
| 45 |
+
* @param string $url The attempted embed URL.
|
| 46 |
+
* @param array $attr An array of shortcode attributes.
|
| 47 |
+
* @return string Embed.
|
| 48 |
+
*/
|
| 49 |
+
public function filter_embed_oembed_html( $return, $url, $attr ) {
|
| 50 |
+
$parsed_url = wp_parse_url( $url );
|
| 51 |
+
if ( false !== strpos( $parsed_url['host'], 'hulu.com' ) ) {
|
| 52 |
+
if ( preg_match( '/width=["\']?(\d+)/', $return, $matches ) ) {
|
| 53 |
+
$attr['width'] = $matches[1];
|
| 54 |
+
}
|
| 55 |
+
if ( preg_match( '/height=["\']?(\d+)/', $return, $matches ) ) {
|
| 56 |
+
$attr['height'] = $matches[1];
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
if ( empty( $attr['height'] ) ) {
|
| 60 |
+
return $return;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
$attributes = wp_array_slice_assoc( $attr, array( 'width', 'height' ) );
|
| 64 |
+
|
| 65 |
+
if ( empty( $attr['width'] ) ) {
|
| 66 |
+
$attributes['layout'] = 'fixed-height';
|
| 67 |
+
$attributes['width'] = 'auto';
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
$pieces = explode( '/watch/', $parsed_url['path'] );
|
| 71 |
+
if ( ! isset( $pieces[1] ) ) {
|
| 72 |
+
if ( ! preg_match( '/\/([A-Za-z0-9]+)/', $parsed_url['path'], $matches ) ) {
|
| 73 |
+
return $return;
|
| 74 |
+
}
|
| 75 |
+
$attributes['data-eid'] = $matches[1];
|
| 76 |
+
} else {
|
| 77 |
+
$attributes['data-eid'] = $pieces[1];
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
$return = AMP_HTML_Utils::build_tag(
|
| 81 |
+
'amp-hulu',
|
| 82 |
+
$attributes
|
| 83 |
+
);
|
| 84 |
+
}
|
| 85 |
+
return $return;
|
| 86 |
+
}
|
| 87 |
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Imgur_Embed_Handler
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
* @since 1.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Class AMP_Imgur_Embed_Handler
|
| 11 |
+
*/
|
| 12 |
+
class AMP_Imgur_Embed_Handler extends AMP_Base_Embed_Handler {
|
| 13 |
+
/**
|
| 14 |
+
* Regex matched to produce output amp-imgur.
|
| 15 |
+
*
|
| 16 |
+
* @var string
|
| 17 |
+
*/
|
| 18 |
+
const URL_PATTERN = '#https?://(www\.)?imgur\.com/.*#i';
|
| 19 |
+
|
| 20 |
+
/**
|
| 21 |
+
* Register embed.
|
| 22 |
+
*/
|
| 23 |
+
public function register_embed() {
|
| 24 |
+
if ( version_compare( strtok( get_bloginfo( 'version' ), '-' ), '4.9', '<' ) ) {
|
| 25 |
+
|
| 26 |
+
// Before 4.9 the embedding Imgur is not working properly, register embed for that case.
|
| 27 |
+
wp_embed_register_handler( 'amp-imgur', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 28 |
+
} else {
|
| 29 |
+
add_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10, 3 );
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* Unregister embed.
|
| 35 |
+
*/
|
| 36 |
+
public function unregister_embed() {
|
| 37 |
+
if ( version_compare( strtok( get_bloginfo( 'version' ), '-' ), '4.9', '<' ) ) {
|
| 38 |
+
wp_embed_unregister_handler( 'amp-imgur', -1 );
|
| 39 |
+
} else {
|
| 40 |
+
remove_filter( 'embed_oembed_html', array( $this, 'filter_embed_oembed_html' ), 10 );
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/**
|
| 45 |
+
* Oembed.
|
| 46 |
+
*
|
| 47 |
+
* @param array $matches Matches.
|
| 48 |
+
* @param array $attr Attributes.
|
| 49 |
+
* @param string $url URL.
|
| 50 |
+
* @param array $rawattr Raw attributes.
|
| 51 |
+
* @return string Embed.
|
| 52 |
+
*/
|
| 53 |
+
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 54 |
+
return $this->render( array( 'url' => $url ) );
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
/**
|
| 58 |
+
* Render embed.
|
| 59 |
+
*
|
| 60 |
+
* @param array $args Args.
|
| 61 |
+
* @return string Embed.
|
| 62 |
+
*/
|
| 63 |
+
public function render( $args ) {
|
| 64 |
+
$args = wp_parse_args( $args, array(
|
| 65 |
+
'url' => false,
|
| 66 |
+
) );
|
| 67 |
+
|
| 68 |
+
if ( empty( $args['url'] ) ) {
|
| 69 |
+
return '';
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
$this->did_convert_elements = true;
|
| 73 |
+
|
| 74 |
+
$id = $this->get_imgur_id_from_url( $args['url'] );
|
| 75 |
+
if ( false === $id ) {
|
| 76 |
+
return '';
|
| 77 |
+
}
|
| 78 |
+
return AMP_HTML_Utils::build_tag(
|
| 79 |
+
'amp-imgur',
|
| 80 |
+
array(
|
| 81 |
+
'width' => $this->args['width'],
|
| 82 |
+
'height' => $this->args['height'],
|
| 83 |
+
'data-imgur-id' => $id,
|
| 84 |
+
)
|
| 85 |
+
);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
/**
|
| 89 |
+
* Filter oEmbed HTML for Imgur to prepare it for AMP.
|
| 90 |
+
*
|
| 91 |
+
* @param mixed $return The shortcode callback function to call.
|
| 92 |
+
* @param string $url The attempted embed URL.
|
| 93 |
+
* @param array $attr An array of shortcode attributes.
|
| 94 |
+
* @return string Embed.
|
| 95 |
+
*/
|
| 96 |
+
public function filter_embed_oembed_html( $return, $url, $attr ) {
|
| 97 |
+
$parsed_url = wp_parse_url( $url );
|
| 98 |
+
if ( false !== strpos( $parsed_url['host'], 'imgur.com' ) ) {
|
| 99 |
+
if ( preg_match( '/width=["\']?(\d+)/', $return, $matches ) ) {
|
| 100 |
+
$attr['width'] = $matches[1];
|
| 101 |
+
}
|
| 102 |
+
if ( preg_match( '/height=["\']?(\d+)/', $return, $matches ) ) {
|
| 103 |
+
$attr['height'] = $matches[1];
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
if ( empty( $attr['height'] ) ) {
|
| 107 |
+
return $return;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
$attributes = wp_array_slice_assoc( $attr, array( 'width', 'height' ) );
|
| 111 |
+
|
| 112 |
+
if ( empty( $attr['width'] ) ) {
|
| 113 |
+
$attributes['layout'] = 'fixed-height';
|
| 114 |
+
$attributes['width'] = 'auto';
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
$attributes['data-imgur-id'] = $this->get_imgur_id_from_url( $url );
|
| 118 |
+
if ( false === $attributes['data-imgur-id'] ) {
|
| 119 |
+
return $return;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
$return = AMP_HTML_Utils::build_tag(
|
| 123 |
+
'amp-imgur',
|
| 124 |
+
$attributes
|
| 125 |
+
);
|
| 126 |
+
}
|
| 127 |
+
return $return;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
/**
|
| 131 |
+
* Get Imgur ID from URL.
|
| 132 |
+
*
|
| 133 |
+
* @param string $url URL.
|
| 134 |
+
* @return bool|string ID / false.
|
| 135 |
+
*/
|
| 136 |
+
protected function get_imgur_id_from_url( $url ) {
|
| 137 |
+
$parsed_url = wp_parse_url( $url );
|
| 138 |
+
$pieces = explode( '/gallery/', $parsed_url['path'] );
|
| 139 |
+
if ( ! isset( $pieces[1] ) ) {
|
| 140 |
+
if ( ! preg_match( '/\/([A-Za-z0-9]+)/', $parsed_url['path'], $matches ) ) {
|
| 141 |
+
return false;
|
| 142 |
+
}
|
| 143 |
+
return $matches[1];
|
| 144 |
+
} else {
|
| 145 |
+
return $pieces[1];
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
}
|
|
@@ -17,13 +17,27 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 17 |
protected $DEFAULT_WIDTH = 600;
|
| 18 |
protected $DEFAULT_HEIGHT = 600;
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
public function register_embed() {
|
| 21 |
-
wp_embed_register_handler(
|
| 22 |
add_shortcode( 'instagram', array( $this, 'shortcode' ) );
|
| 23 |
}
|
| 24 |
|
| 25 |
public function unregister_embed() {
|
| 26 |
-
wp_embed_unregister_handler(
|
| 27 |
remove_shortcode( 'instagram' );
|
| 28 |
}
|
| 29 |
|
|
@@ -53,7 +67,7 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 53 |
|
| 54 |
public function render( $args ) {
|
| 55 |
$args = wp_parse_args( $args, array(
|
| 56 |
-
'url'
|
| 57 |
'instagram_id' => false,
|
| 58 |
) );
|
| 59 |
|
|
@@ -64,16 +78,23 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 64 |
$this->did_convert_elements = true;
|
| 65 |
|
| 66 |
return AMP_HTML_Utils::build_tag(
|
| 67 |
-
|
| 68 |
array(
|
| 69 |
'data-shortcode' => $args['instagram_id'],
|
| 70 |
-
'
|
| 71 |
-
'
|
| 72 |
-
'
|
|
|
|
| 73 |
)
|
| 74 |
);
|
| 75 |
}
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
private function get_instagram_id_from_url( $url ) {
|
| 78 |
$found = preg_match( self::URL_PATTERN, $url, $matches );
|
| 79 |
|
|
@@ -83,4 +104,98 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 83 |
|
| 84 |
return end( $matches );
|
| 85 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
}
|
| 17 |
protected $DEFAULT_WIDTH = 600;
|
| 18 |
protected $DEFAULT_HEIGHT = 600;
|
| 19 |
|
| 20 |
+
/**
|
| 21 |
+
* Tag.
|
| 22 |
+
*
|
| 23 |
+
* @var string embed HTML blockquote tag to identify and replace with AMP version.
|
| 24 |
+
*/
|
| 25 |
+
protected $sanitize_tag = 'blockquote';
|
| 26 |
+
|
| 27 |
+
/**
|
| 28 |
+
* Tag.
|
| 29 |
+
*
|
| 30 |
+
* @var string AMP amp-facebook tag
|
| 31 |
+
*/
|
| 32 |
+
private $amp_tag = 'amp-instagram';
|
| 33 |
+
|
| 34 |
public function register_embed() {
|
| 35 |
+
wp_embed_register_handler( $this->amp_tag, self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 36 |
add_shortcode( 'instagram', array( $this, 'shortcode' ) );
|
| 37 |
}
|
| 38 |
|
| 39 |
public function unregister_embed() {
|
| 40 |
+
wp_embed_unregister_handler( $this->amp_tag, -1 );
|
| 41 |
remove_shortcode( 'instagram' );
|
| 42 |
}
|
| 43 |
|
| 67 |
|
| 68 |
public function render( $args ) {
|
| 69 |
$args = wp_parse_args( $args, array(
|
| 70 |
+
'url' => false,
|
| 71 |
'instagram_id' => false,
|
| 72 |
) );
|
| 73 |
|
| 78 |
$this->did_convert_elements = true;
|
| 79 |
|
| 80 |
return AMP_HTML_Utils::build_tag(
|
| 81 |
+
$this->amp_tag,
|
| 82 |
array(
|
| 83 |
'data-shortcode' => $args['instagram_id'],
|
| 84 |
+
'data-captioned' => '',
|
| 85 |
+
'layout' => 'responsive',
|
| 86 |
+
'width' => $this->args['width'],
|
| 87 |
+
'height' => $this->args['height'],
|
| 88 |
)
|
| 89 |
);
|
| 90 |
}
|
| 91 |
|
| 92 |
+
/**
|
| 93 |
+
* Get Instagram ID from URL.
|
| 94 |
+
*
|
| 95 |
+
* @param string $url URL.
|
| 96 |
+
* @return string|false The ID parsed from the URL or false if not found.
|
| 97 |
+
*/
|
| 98 |
private function get_instagram_id_from_url( $url ) {
|
| 99 |
$found = preg_match( self::URL_PATTERN, $url, $matches );
|
| 100 |
|
| 104 |
|
| 105 |
return end( $matches );
|
| 106 |
}
|
| 107 |
+
|
| 108 |
+
/**
|
| 109 |
+
* Sanitized <blockquote class="instagram-media"> tags to <amp-instagram>
|
| 110 |
+
*
|
| 111 |
+
* @param DOMDocument $dom DOM.
|
| 112 |
+
*/
|
| 113 |
+
public function sanitize_raw_embeds( $dom ) {
|
| 114 |
+
/**
|
| 115 |
+
* Node list.
|
| 116 |
+
*
|
| 117 |
+
* @var DOMNodeList $node
|
| 118 |
+
*/
|
| 119 |
+
$nodes = $dom->getElementsByTagName( $this->sanitize_tag );
|
| 120 |
+
$num_nodes = $nodes->length;
|
| 121 |
+
|
| 122 |
+
if ( 0 === $num_nodes ) {
|
| 123 |
+
return;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 127 |
+
$node = $nodes->item( $i );
|
| 128 |
+
if ( ! $node instanceof DOMElement ) {
|
| 129 |
+
continue;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
if ( $node->hasAttribute( 'data-instgrm-permalink' ) ) {
|
| 133 |
+
$this->create_amp_instagram_and_replace_node( $dom, $node );
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
/**
|
| 139 |
+
* Make final modifications to DOMNode
|
| 140 |
+
*
|
| 141 |
+
* @param DOMDocument $dom The HTML Document.
|
| 142 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 143 |
+
*/
|
| 144 |
+
private function create_amp_instagram_and_replace_node( $dom, $node ) {
|
| 145 |
+
$instagram_id = $this->get_instagram_id_from_url( $node->getAttribute( 'data-instgrm-permalink' ) );
|
| 146 |
+
|
| 147 |
+
$node_args = array(
|
| 148 |
+
'data-shortcode' => $instagram_id,
|
| 149 |
+
'layout' => 'responsive',
|
| 150 |
+
'width' => $this->DEFAULT_WIDTH,
|
| 151 |
+
'height' => $this->DEFAULT_HEIGHT,
|
| 152 |
+
);
|
| 153 |
+
|
| 154 |
+
if ( true === $node->hasAttribute( 'data-instgrm-captioned' ) ) {
|
| 155 |
+
$node_args['data-captioned'] = '';
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
$new_node = AMP_DOM_Utils::create_node( $dom, $this->amp_tag, $node_args );
|
| 159 |
+
|
| 160 |
+
$this->sanitize_embed_script( $node );
|
| 161 |
+
|
| 162 |
+
$node->parentNode->replaceChild( $new_node, $node );
|
| 163 |
+
|
| 164 |
+
$this->did_convert_elements = true;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
/**
|
| 168 |
+
* Removes Instagram's embed <script> tag.
|
| 169 |
+
*
|
| 170 |
+
* @param DOMElement $node The DOMNode to whose sibling is the instagram script.
|
| 171 |
+
*/
|
| 172 |
+
private function sanitize_embed_script( $node ) {
|
| 173 |
+
$next_element_sibling = $node->nextSibling;
|
| 174 |
+
while ( $next_element_sibling && ! ( $next_element_sibling instanceof DOMElement ) ) {
|
| 175 |
+
$next_element_sibling = $next_element_sibling->nextSibling;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
$script_src = 'instagram.com/embed.js';
|
| 179 |
+
|
| 180 |
+
// Handle case where script is wrapped in paragraph by wpautop.
|
| 181 |
+
if ( $next_element_sibling instanceof DOMElement && 'p' === $next_element_sibling->nodeName ) {
|
| 182 |
+
$children = $next_element_sibling->getElementsByTagName( '*' );
|
| 183 |
+
if ( 1 === $children->length && 'script' === $children->item( 0 )->nodeName && false !== strpos( $children->item( 0 )->getAttribute( 'src' ), $script_src ) ) {
|
| 184 |
+
$next_element_sibling->parentNode->removeChild( $next_element_sibling );
|
| 185 |
+
return;
|
| 186 |
+
}
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
// Handle case where script is immediately following.
|
| 190 |
+
$is_embed_script = (
|
| 191 |
+
$next_element_sibling
|
| 192 |
+
&&
|
| 193 |
+
'script' === strtolower( $next_element_sibling->nodeName )
|
| 194 |
+
&&
|
| 195 |
+
false !== strpos( $next_element_sibling->getAttribute( 'src' ), $script_src )
|
| 196 |
+
);
|
| 197 |
+
if ( $is_embed_script ) {
|
| 198 |
+
$next_element_sibling->parentNode->removeChild( $next_element_sibling );
|
| 199 |
+
}
|
| 200 |
+
}
|
| 201 |
}
|
|
@@ -178,7 +178,7 @@ class AMP_SoundCloud_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 178 |
* @return string Track ID or empty string if none matched.
|
| 179 |
*/
|
| 180 |
private function get_track_id_from_url( $url ) {
|
| 181 |
-
$parsed_url =
|
| 182 |
if ( ! preg_match( '#tracks/(?P<track_id>[^/]+)#', $parsed_url['path'], $matches ) ) {
|
| 183 |
return '';
|
| 184 |
}
|
| 178 |
* @return string Track ID or empty string if none matched.
|
| 179 |
*/
|
| 180 |
private function get_track_id_from_url( $url ) {
|
| 181 |
+
$parsed_url = wp_parse_url( $url );
|
| 182 |
if ( ! preg_match( '#tracks/(?P<track_id>[^/]+)#', $parsed_url['path'], $matches ) ) {
|
| 183 |
return '';
|
| 184 |
}
|
|
@@ -11,19 +11,64 @@
|
|
| 11 |
* Much of this class is borrowed from Jetpack embeds
|
| 12 |
*/
|
| 13 |
class AMP_Twitter_Embed_Handler extends AMP_Base_Embed_Handler {
|
| 14 |
-
const URL_PATTERN = '#http(s|):\/\/twitter\.com(\/\#\!\/|\/)([a-zA-Z0-9_]{1,20})\/status(es)*\/(\d+)#i';
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
public function register_embed() {
|
| 17 |
-
add_shortcode( 'tweet', array( $this, 'shortcode' ) );
|
| 18 |
wp_embed_register_handler( 'amp-twitter', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
|
|
|
| 19 |
}
|
| 20 |
|
|
|
|
|
|
|
|
|
|
| 21 |
public function unregister_embed() {
|
| 22 |
-
remove_shortcode( 'tweet' );
|
| 23 |
wp_embed_unregister_handler( 'amp-twitter', -1 );
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
$attr = wp_parse_args( $attr, array(
|
| 28 |
'tweet' => false,
|
| 29 |
) );
|
|
@@ -37,8 +82,8 @@ class AMP_Twitter_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 37 |
$id = $attr['tweet'];
|
| 38 |
} else {
|
| 39 |
preg_match( self::URL_PATTERN, $attr['tweet'], $matches );
|
| 40 |
-
if ( isset( $matches[
|
| 41 |
-
$id = $matches[
|
| 42 |
}
|
| 43 |
|
| 44 |
if ( empty( $id ) ) {
|
|
@@ -49,21 +94,29 @@ class AMP_Twitter_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 49 |
$this->did_convert_elements = true;
|
| 50 |
|
| 51 |
return AMP_HTML_Utils::build_tag(
|
| 52 |
-
|
| 53 |
array(
|
| 54 |
'data-tweetid' => $id,
|
| 55 |
-
'layout'
|
| 56 |
-
'width'
|
| 57 |
-
'height'
|
| 58 |
)
|
| 59 |
);
|
| 60 |
}
|
| 61 |
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
$id = false;
|
| 64 |
|
| 65 |
-
if ( isset( $matches[
|
| 66 |
-
$id = $matches[
|
| 67 |
}
|
| 68 |
|
| 69 |
if ( ! $id ) {
|
|
@@ -72,4 +125,182 @@ class AMP_Twitter_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 72 |
|
| 73 |
return $this->shortcode( array( 'tweet' => $id ) );
|
| 74 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
}
|
| 11 |
* Much of this class is borrowed from Jetpack embeds
|
| 12 |
*/
|
| 13 |
class AMP_Twitter_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
|
|
| 14 |
|
| 15 |
+
/**
|
| 16 |
+
* URL pattern for a Tweet URL.
|
| 17 |
+
*
|
| 18 |
+
* @since 0.2
|
| 19 |
+
* @var string
|
| 20 |
+
*/
|
| 21 |
+
const URL_PATTERN = '#https?:\/\/twitter\.com(?:\/\#\!\/|\/)(?P<username>[a-zA-Z0-9_]{1,20})\/status(?:es)?\/(?P<tweet>\d+)#i';
|
| 22 |
+
|
| 23 |
+
/**
|
| 24 |
+
* URL pattern for a Twitter timeline.
|
| 25 |
+
*
|
| 26 |
+
* @since 1.0
|
| 27 |
+
* @var string
|
| 28 |
+
*/
|
| 29 |
+
const URL_PATTERN_TIMELINE = '#https?:\/\/twitter\.com(?:\/\#\!\/|\/)(?P<username>[a-zA-Z0-9_]{1,20})(?:$|\/(?P<type>likes|lists)(\/(?P<id>[a-zA-Z0-9_-]+))?)#i';
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* Tag.
|
| 33 |
+
*
|
| 34 |
+
* @var string embed HTML blockquote tag to identify and replace with AMP version.
|
| 35 |
+
*/
|
| 36 |
+
protected $sanitize_tag = 'blockquote';
|
| 37 |
+
|
| 38 |
+
/**
|
| 39 |
+
* Tag.
|
| 40 |
+
*
|
| 41 |
+
* @var string AMP amp-facebook tag
|
| 42 |
+
*/
|
| 43 |
+
private $amp_tag = 'amp-twitter';
|
| 44 |
+
|
| 45 |
+
/**
|
| 46 |
+
* Register embed.
|
| 47 |
+
*/
|
| 48 |
public function register_embed() {
|
| 49 |
+
add_shortcode( 'tweet', array( $this, 'shortcode' ) ); // Note: This is a Jetpack shortcode.
|
| 50 |
wp_embed_register_handler( 'amp-twitter', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 51 |
+
wp_embed_register_handler( 'amp-twitter-timeline', self::URL_PATTERN_TIMELINE, array( $this, 'oembed_timeline' ), -1 );
|
| 52 |
}
|
| 53 |
|
| 54 |
+
/**
|
| 55 |
+
* Unregister embed.
|
| 56 |
+
*/
|
| 57 |
public function unregister_embed() {
|
| 58 |
+
remove_shortcode( 'tweet' ); // Note: This is a Jetpack shortcode.
|
| 59 |
wp_embed_unregister_handler( 'amp-twitter', -1 );
|
| 60 |
+
wp_embed_unregister_handler( 'amp-twitter-timeline', -1 );
|
| 61 |
}
|
| 62 |
|
| 63 |
+
/**
|
| 64 |
+
* Gets AMP-compliant markup for the Twitter shortcode.
|
| 65 |
+
*
|
| 66 |
+
* Note that this shortcode is is defined in Jetpack.
|
| 67 |
+
*
|
| 68 |
+
* @param array $attr The Twitter attributes.
|
| 69 |
+
* @return string Twitter shortcode markup.
|
| 70 |
+
*/
|
| 71 |
+
public function shortcode( $attr ) {
|
| 72 |
$attr = wp_parse_args( $attr, array(
|
| 73 |
'tweet' => false,
|
| 74 |
) );
|
| 82 |
$id = $attr['tweet'];
|
| 83 |
} else {
|
| 84 |
preg_match( self::URL_PATTERN, $attr['tweet'], $matches );
|
| 85 |
+
if ( isset( $matches['tweet'] ) && is_numeric( $matches['tweet'] ) ) {
|
| 86 |
+
$id = $matches['tweet'];
|
| 87 |
}
|
| 88 |
|
| 89 |
if ( empty( $id ) ) {
|
| 94 |
$this->did_convert_elements = true;
|
| 95 |
|
| 96 |
return AMP_HTML_Utils::build_tag(
|
| 97 |
+
$this->amp_tag,
|
| 98 |
array(
|
| 99 |
'data-tweetid' => $id,
|
| 100 |
+
'layout' => 'responsive',
|
| 101 |
+
'width' => $this->args['width'],
|
| 102 |
+
'height' => $this->args['height'],
|
| 103 |
)
|
| 104 |
);
|
| 105 |
}
|
| 106 |
|
| 107 |
+
/**
|
| 108 |
+
* Render oEmbed.
|
| 109 |
+
*
|
| 110 |
+
* @see \WP_Embed::shortcode()
|
| 111 |
+
*
|
| 112 |
+
* @param array $matches URL pattern matches.
|
| 113 |
+
* @return string Rendered oEmbed.
|
| 114 |
+
*/
|
| 115 |
+
public function oembed( $matches ) {
|
| 116 |
$id = false;
|
| 117 |
|
| 118 |
+
if ( isset( $matches['tweet'] ) && is_numeric( $matches['tweet'] ) ) {
|
| 119 |
+
$id = $matches['tweet'];
|
| 120 |
}
|
| 121 |
|
| 122 |
if ( ! $id ) {
|
| 125 |
|
| 126 |
return $this->shortcode( array( 'tweet' => $id ) );
|
| 127 |
}
|
| 128 |
+
|
| 129 |
+
/**
|
| 130 |
+
* Render oEmbed for a timeline.
|
| 131 |
+
*
|
| 132 |
+
* @since 1.0
|
| 133 |
+
*
|
| 134 |
+
* @param array $matches URL pattern matches.
|
| 135 |
+
* @return string Rendered oEmbed.
|
| 136 |
+
*/
|
| 137 |
+
public function oembed_timeline( $matches ) {
|
| 138 |
+
if ( ! isset( $matches['username'] ) ) {
|
| 139 |
+
return '';
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
$attributes = array(
|
| 143 |
+
'data-timeline-source-type' => 'profile',
|
| 144 |
+
'data-timeline-screen-name' => $matches['username'],
|
| 145 |
+
);
|
| 146 |
+
|
| 147 |
+
if ( isset( $matches['type'] ) ) {
|
| 148 |
+
switch ( $matches['type'] ) {
|
| 149 |
+
case 'likes':
|
| 150 |
+
$attributes['data-timeline-source-type'] = 'likes';
|
| 151 |
+
break;
|
| 152 |
+
case 'lists':
|
| 153 |
+
if ( ! isset( $matches['id'] ) ) {
|
| 154 |
+
return '';
|
| 155 |
+
}
|
| 156 |
+
$attributes['data-timeline-source-type'] = 'list';
|
| 157 |
+
$attributes['data-timeline-slug'] = $matches['id'];
|
| 158 |
+
$attributes['data-timeline-owner-screen-name'] = $attributes['data-timeline-screen-name'];
|
| 159 |
+
unset( $attributes['data-timeline-screen-name'] );
|
| 160 |
+
break;
|
| 161 |
+
default:
|
| 162 |
+
return '';
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
$attributes['layout'] = 'responsive';
|
| 167 |
+
$attributes['width'] = $this->args['width'];
|
| 168 |
+
$attributes['height'] = $this->args['height'];
|
| 169 |
+
|
| 170 |
+
$this->did_convert_elements = true;
|
| 171 |
+
|
| 172 |
+
return AMP_HTML_Utils::build_tag( $this->amp_tag, $attributes );
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
/**
|
| 176 |
+
* Sanitized <blockquote class="twitter-tweet"> tags to <amp-twitter>.
|
| 177 |
+
*
|
| 178 |
+
* @param DOMDocument $dom DOM.
|
| 179 |
+
*/
|
| 180 |
+
public function sanitize_raw_embeds( $dom ) {
|
| 181 |
+
/**
|
| 182 |
+
* Node list.
|
| 183 |
+
*
|
| 184 |
+
* @var DOMNodeList $node
|
| 185 |
+
*/
|
| 186 |
+
$nodes = $dom->getElementsByTagName( $this->sanitize_tag );
|
| 187 |
+
$num_nodes = $nodes->length;
|
| 188 |
+
|
| 189 |
+
if ( 0 === $num_nodes ) {
|
| 190 |
+
return;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 194 |
+
$node = $nodes->item( $i );
|
| 195 |
+
if ( ! $node instanceof DOMElement ) {
|
| 196 |
+
continue;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
if ( $this->is_tweet_raw_embed( $node ) ) {
|
| 200 |
+
$this->create_amp_twitter_and_replace_node( $dom, $node );
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
/**
|
| 206 |
+
* Checks whether it's a twitter blockquote or not
|
| 207 |
+
*
|
| 208 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 209 |
+
* @return bool Whether node is for raw embed.
|
| 210 |
+
*/
|
| 211 |
+
private function is_tweet_raw_embed( $node ) {
|
| 212 |
+
$class_attr = $node->getAttribute( 'class' );
|
| 213 |
+
|
| 214 |
+
return null !== $class_attr && false !== strpos( $class_attr, 'twitter-tweet' );
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
/**
|
| 218 |
+
* Make final modifications to DOMNode
|
| 219 |
+
*
|
| 220 |
+
* @param DOMDocument $dom The HTML Document.
|
| 221 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 222 |
+
*/
|
| 223 |
+
private function create_amp_twitter_and_replace_node( $dom, $node ) {
|
| 224 |
+
$tweet_id = $this->get_tweet_id( $node );
|
| 225 |
+
if ( ! $tweet_id ) {
|
| 226 |
+
return;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
$new_node = AMP_DOM_Utils::create_node( $dom, $this->amp_tag, array(
|
| 230 |
+
'width' => $this->DEFAULT_WIDTH,
|
| 231 |
+
'height' => $this->DEFAULT_HEIGHT,
|
| 232 |
+
'layout' => 'responsive',
|
| 233 |
+
'data-tweetid' => $tweet_id,
|
| 234 |
+
) );
|
| 235 |
+
|
| 236 |
+
$this->sanitize_embed_script( $node );
|
| 237 |
+
|
| 238 |
+
$node->parentNode->replaceChild( $new_node, $node );
|
| 239 |
+
|
| 240 |
+
$this->did_convert_elements = true;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
/**
|
| 244 |
+
* Extracts Tweet id.
|
| 245 |
+
*
|
| 246 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 247 |
+
* @return string Tweet ID.
|
| 248 |
+
*/
|
| 249 |
+
private function get_tweet_id( $node ) {
|
| 250 |
+
/**
|
| 251 |
+
* DOMNode
|
| 252 |
+
*
|
| 253 |
+
* @var DOMNodeList $anchors
|
| 254 |
+
*/
|
| 255 |
+
$anchors = $node->getElementsByTagName( 'a' );
|
| 256 |
+
|
| 257 |
+
/**
|
| 258 |
+
* Anchor.
|
| 259 |
+
*
|
| 260 |
+
* @type DOMElement $anchor
|
| 261 |
+
*/
|
| 262 |
+
foreach ( $anchors as $anchor ) {
|
| 263 |
+
$found = preg_match( self::URL_PATTERN, $anchor->getAttribute( 'href' ), $matches );
|
| 264 |
+
if ( $found ) {
|
| 265 |
+
return $matches['tweet'];
|
| 266 |
+
}
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
return null;
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
/**
|
| 273 |
+
* Removes Twitter's embed <script> tag.
|
| 274 |
+
*
|
| 275 |
+
* @param DOMElement $node The DOMNode to whose sibling is the instagram script.
|
| 276 |
+
*/
|
| 277 |
+
private function sanitize_embed_script( $node ) {
|
| 278 |
+
$next_element_sibling = $node->nextSibling;
|
| 279 |
+
while ( $next_element_sibling && ! ( $next_element_sibling instanceof DOMElement ) ) {
|
| 280 |
+
$next_element_sibling = $next_element_sibling->nextSibling;
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
$script_src = 'platform.twitter.com/widgets.js';
|
| 284 |
+
|
| 285 |
+
// Handle case where script is wrapped in paragraph by wpautop.
|
| 286 |
+
if ( $next_element_sibling instanceof DOMElement && 'p' === $next_element_sibling->nodeName ) {
|
| 287 |
+
$children = $next_element_sibling->getElementsByTagName( '*' );
|
| 288 |
+
if ( 1 === $children->length && 'script' === $children->item( 0 )->nodeName && false !== strpos( $children->item( 0 )->getAttribute( 'src' ), $script_src ) ) {
|
| 289 |
+
$next_element_sibling->parentNode->removeChild( $next_element_sibling );
|
| 290 |
+
return;
|
| 291 |
+
}
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
// Handle case where script is immediately following.
|
| 295 |
+
$is_embed_script = (
|
| 296 |
+
$next_element_sibling
|
| 297 |
+
&&
|
| 298 |
+
'script' === strtolower( $next_element_sibling->nodeName )
|
| 299 |
+
&&
|
| 300 |
+
false !== strpos( $next_element_sibling->getAttribute( 'src' ), $script_src )
|
| 301 |
+
);
|
| 302 |
+
if ( $is_embed_script ) {
|
| 303 |
+
$next_element_sibling->parentNode->removeChild( $next_element_sibling );
|
| 304 |
+
}
|
| 305 |
+
}
|
| 306 |
}
|
|
@@ -16,39 +16,67 @@ class AMP_Vimeo_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 16 |
|
| 17 |
const RATIO = 0.5625;
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
protected $DEFAULT_WIDTH = 600;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
protected $DEFAULT_HEIGHT = 338;
|
| 21 |
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
parent::__construct( $args );
|
| 24 |
|
| 25 |
if ( isset( $this->args['content_max_width'] ) ) {
|
| 26 |
-
$max_width
|
| 27 |
-
$this->args['width']
|
| 28 |
$this->args['height'] = round( $max_width * self::RATIO );
|
| 29 |
}
|
| 30 |
}
|
| 31 |
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
| 33 |
wp_embed_register_handler( 'amp-vimeo', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 34 |
add_shortcode( 'vimeo', array( $this, 'shortcode' ) );
|
| 35 |
add_filter( 'wp_video_shortcode_override', array( $this, 'video_override' ), 10, 2 );
|
| 36 |
}
|
| 37 |
|
|
|
|
|
|
|
|
|
|
| 38 |
public function unregister_embed() {
|
| 39 |
wp_embed_unregister_handler( 'amp-vimeo', -1 );
|
| 40 |
remove_shortcode( 'vimeo' );
|
| 41 |
}
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
public function shortcode( $attr ) {
|
| 44 |
$video_id = false;
|
| 45 |
|
| 46 |
if ( isset( $attr['id'] ) ) {
|
| 47 |
$video_id = $attr['id'];
|
| 48 |
} elseif ( isset( $attr['url'] ) ) {
|
| 49 |
-
$video_id = $this->get_video_id_from_url($attr['url']);
|
| 50 |
-
}elseif ( isset( $attr[0] ) ) {
|
| 51 |
-
$video_id = $this->get_video_id_from_url($attr[0]);
|
| 52 |
} elseif ( function_exists( 'shortcode_new_to_old_params' ) ) {
|
| 53 |
$video_id = shortcode_new_to_old_params( $attr );
|
| 54 |
}
|
|
@@ -57,27 +85,55 @@ class AMP_Vimeo_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 57 |
return '';
|
| 58 |
}
|
| 59 |
|
| 60 |
-
return $this->render(
|
| 61 |
-
|
| 62 |
-
|
|
|
|
|
|
|
| 63 |
}
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 66 |
$video_id = $this->get_video_id_from_url( $url );
|
| 67 |
|
| 68 |
-
return $this->render(
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
| 72 |
}
|
| 73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
public function render( $args ) {
|
| 75 |
-
$args = wp_parse_args(
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
| 78 |
|
| 79 |
if ( empty( $args['video_id'] ) ) {
|
| 80 |
-
return AMP_HTML_Utils::build_tag(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
}
|
| 82 |
|
| 83 |
$this->did_convert_elements = true;
|
|
@@ -86,24 +142,27 @@ class AMP_Vimeo_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 86 |
'amp-vimeo',
|
| 87 |
array(
|
| 88 |
'data-videoid' => $args['video_id'],
|
| 89 |
-
'layout'
|
| 90 |
-
'width'
|
| 91 |
-
'height'
|
| 92 |
)
|
| 93 |
);
|
| 94 |
}
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
|
|
|
|
|
|
|
|
|
| 99 |
private function get_video_id_from_url( $url ) {
|
| 100 |
-
$parsed_url =
|
| 101 |
parse_str( $parsed_url['path'], $path );
|
| 102 |
|
| 103 |
-
$video_id =
|
| 104 |
if ( $path ) {
|
| 105 |
-
$tok
|
| 106 |
-
$video_id = end($tok);
|
| 107 |
}
|
| 108 |
|
| 109 |
return $video_id;
|
| 16 |
|
| 17 |
const RATIO = 0.5625;
|
| 18 |
|
| 19 |
+
/**
|
| 20 |
+
* Default width.
|
| 21 |
+
*
|
| 22 |
+
* @var int
|
| 23 |
+
*/
|
| 24 |
protected $DEFAULT_WIDTH = 600;
|
| 25 |
+
|
| 26 |
+
/**
|
| 27 |
+
* Default height.
|
| 28 |
+
*
|
| 29 |
+
* @var int
|
| 30 |
+
*/
|
| 31 |
protected $DEFAULT_HEIGHT = 338;
|
| 32 |
|
| 33 |
+
/**
|
| 34 |
+
* AMP_Vimeo_Embed_Handler constructor.
|
| 35 |
+
*
|
| 36 |
+
* @param array $args Height, width and maximum width for embed.
|
| 37 |
+
*/
|
| 38 |
+
public function __construct( $args = array() ) {
|
| 39 |
parent::__construct( $args );
|
| 40 |
|
| 41 |
if ( isset( $this->args['content_max_width'] ) ) {
|
| 42 |
+
$max_width = $this->args['content_max_width'];
|
| 43 |
+
$this->args['width'] = $max_width;
|
| 44 |
$this->args['height'] = round( $max_width * self::RATIO );
|
| 45 |
}
|
| 46 |
}
|
| 47 |
|
| 48 |
+
/**
|
| 49 |
+
* Register embed.
|
| 50 |
+
*/
|
| 51 |
+
public function register_embed() {
|
| 52 |
wp_embed_register_handler( 'amp-vimeo', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 53 |
add_shortcode( 'vimeo', array( $this, 'shortcode' ) );
|
| 54 |
add_filter( 'wp_video_shortcode_override', array( $this, 'video_override' ), 10, 2 );
|
| 55 |
}
|
| 56 |
|
| 57 |
+
/**
|
| 58 |
+
* Unregister embed.
|
| 59 |
+
*/
|
| 60 |
public function unregister_embed() {
|
| 61 |
wp_embed_unregister_handler( 'amp-vimeo', -1 );
|
| 62 |
remove_shortcode( 'vimeo' );
|
| 63 |
}
|
| 64 |
|
| 65 |
+
/**
|
| 66 |
+
* Gets AMP-compliant markup for the Vimeo shortcode.
|
| 67 |
+
*
|
| 68 |
+
* @param array $attr The Vimeo attributes.
|
| 69 |
+
* @return string Vimeo shortcode markup.
|
| 70 |
+
*/
|
| 71 |
public function shortcode( $attr ) {
|
| 72 |
$video_id = false;
|
| 73 |
|
| 74 |
if ( isset( $attr['id'] ) ) {
|
| 75 |
$video_id = $attr['id'];
|
| 76 |
} elseif ( isset( $attr['url'] ) ) {
|
| 77 |
+
$video_id = $this->get_video_id_from_url( $attr['url'] );
|
| 78 |
+
} elseif ( isset( $attr[0] ) ) {
|
| 79 |
+
$video_id = $this->get_video_id_from_url( $attr[0] );
|
| 80 |
} elseif ( function_exists( 'shortcode_new_to_old_params' ) ) {
|
| 81 |
$video_id = shortcode_new_to_old_params( $attr );
|
| 82 |
}
|
| 85 |
return '';
|
| 86 |
}
|
| 87 |
|
| 88 |
+
return $this->render(
|
| 89 |
+
array(
|
| 90 |
+
'video_id' => $video_id,
|
| 91 |
+
)
|
| 92 |
+
);
|
| 93 |
}
|
| 94 |
|
| 95 |
+
/**
|
| 96 |
+
* Render oEmbed.
|
| 97 |
+
*
|
| 98 |
+
* @see \WP_Embed::shortcode()
|
| 99 |
+
*
|
| 100 |
+
* @param array $matches URL pattern matches.
|
| 101 |
+
* @param array $attr Shortcode attribues.
|
| 102 |
+
* @param string $url URL.
|
| 103 |
+
* @param string $rawattr Unmodified shortcode attributes.
|
| 104 |
+
* @return string Rendered oEmbed.
|
| 105 |
+
*/
|
| 106 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 107 |
$video_id = $this->get_video_id_from_url( $url );
|
| 108 |
|
| 109 |
+
return $this->render(
|
| 110 |
+
array(
|
| 111 |
+
'url' => $url,
|
| 112 |
+
'video_id' => $video_id,
|
| 113 |
+
)
|
| 114 |
+
);
|
| 115 |
}
|
| 116 |
|
| 117 |
+
/**
|
| 118 |
+
* Render.
|
| 119 |
+
*
|
| 120 |
+
* @param array $args Args.
|
| 121 |
+
* @return string Rendered.
|
| 122 |
+
*/
|
| 123 |
public function render( $args ) {
|
| 124 |
+
$args = wp_parse_args(
|
| 125 |
+
$args, array(
|
| 126 |
+
'video_id' => false,
|
| 127 |
+
)
|
| 128 |
+
);
|
| 129 |
|
| 130 |
if ( empty( $args['video_id'] ) ) {
|
| 131 |
+
return AMP_HTML_Utils::build_tag(
|
| 132 |
+
'a', array(
|
| 133 |
+
'href' => esc_url( $args['url'] ),
|
| 134 |
+
'class' => 'amp-wp-embed-fallback',
|
| 135 |
+
), esc_html( $args['url'] )
|
| 136 |
+
);
|
| 137 |
}
|
| 138 |
|
| 139 |
$this->did_convert_elements = true;
|
| 142 |
'amp-vimeo',
|
| 143 |
array(
|
| 144 |
'data-videoid' => $args['video_id'],
|
| 145 |
+
'layout' => 'responsive',
|
| 146 |
+
'width' => $this->args['width'],
|
| 147 |
+
'height' => $this->args['height'],
|
| 148 |
)
|
| 149 |
);
|
| 150 |
}
|
| 151 |
|
| 152 |
+
/**
|
| 153 |
+
* Determine the video ID from the URL.
|
| 154 |
+
*
|
| 155 |
+
* @param string $url URL.
|
| 156 |
+
* @return integer Video ID.
|
| 157 |
+
*/
|
| 158 |
private function get_video_id_from_url( $url ) {
|
| 159 |
+
$parsed_url = wp_parse_url( $url );
|
| 160 |
parse_str( $parsed_url['path'], $path );
|
| 161 |
|
| 162 |
+
$video_id = '';
|
| 163 |
if ( $path ) {
|
| 164 |
+
$tok = explode( '/', $parsed_url['path'] );
|
| 165 |
+
$video_id = end( $tok );
|
| 166 |
}
|
| 167 |
|
| 168 |
return $video_id;
|
|
@@ -14,37 +14,65 @@ class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 14 |
const SHORT_URL_HOST = 'youtu.be';
|
| 15 |
// Only handling single videos. Playlists are handled elsewhere.
|
| 16 |
const URL_PATTERN = '#https?://(?:www\.)?(?:youtube.com/(?:v/|e/|embed/|watch[/\#?])|youtu\.be/).*#i';
|
| 17 |
-
const RATIO
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
protected $DEFAULT_WIDTH = 600;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
protected $DEFAULT_HEIGHT = 338;
|
| 21 |
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
parent::__construct( $args );
|
| 24 |
|
| 25 |
if ( isset( $this->args['content_max_width'] ) ) {
|
| 26 |
-
$max_width
|
| 27 |
$this->args['width'] = $max_width;
|
| 28 |
$this->args['height'] = round( $max_width * self::RATIO );
|
| 29 |
}
|
| 30 |
}
|
| 31 |
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
| 33 |
wp_embed_register_handler( 'amp-youtube', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 34 |
add_shortcode( 'youtube', array( $this, 'shortcode' ) );
|
| 35 |
add_filter( 'wp_video_shortcode_override', array( $this, 'video_override' ), 10, 2 );
|
| 36 |
}
|
| 37 |
|
|
|
|
|
|
|
|
|
|
| 38 |
public function unregister_embed() {
|
| 39 |
wp_embed_unregister_handler( 'amp-youtube', -1 );
|
| 40 |
remove_shortcode( 'youtube' );
|
| 41 |
}
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
public function shortcode( $attr ) {
|
| 44 |
-
$url
|
| 45 |
$video_id = false;
|
| 46 |
if ( isset( $attr[0] ) ) {
|
| 47 |
-
$url = ltrim( $attr[0]
|
| 48 |
} elseif ( function_exists( 'shortcode_new_to_old_params' ) ) {
|
| 49 |
$url = shortcode_new_to_old_params( $attr );
|
| 50 |
}
|
|
@@ -55,23 +83,49 @@ class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 55 |
|
| 56 |
$video_id = $this->get_video_id_from_url( $url );
|
| 57 |
|
| 58 |
-
return $this->render(
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
| 62 |
}
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 65 |
return $this->shortcode( array( $url ) );
|
| 66 |
}
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
public function render( $args ) {
|
| 69 |
-
$args = wp_parse_args(
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
| 72 |
|
| 73 |
if ( empty( $args['video_id'] ) ) {
|
| 74 |
-
return AMP_HTML_Utils::build_tag(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
}
|
| 76 |
|
| 77 |
$this->did_convert_elements = true;
|
|
@@ -80,25 +134,31 @@ class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 80 |
'amp-youtube',
|
| 81 |
array(
|
| 82 |
'data-videoid' => $args['video_id'],
|
| 83 |
-
'layout'
|
| 84 |
-
'width'
|
| 85 |
-
'height'
|
| 86 |
)
|
| 87 |
);
|
| 88 |
}
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
private function get_video_id_from_url( $url ) {
|
| 91 |
-
$video_id
|
| 92 |
-
$parsed_url =
|
| 93 |
|
| 94 |
if ( self::SHORT_URL_HOST === substr( $parsed_url['host'], -strlen( self::SHORT_URL_HOST ) ) ) {
|
| 95 |
-
|
| 96 |
$parts = explode( '/', $parsed_url['path'] );
|
| 97 |
if ( ! empty( $parts ) ) {
|
| 98 |
$video_id = $parts[1];
|
| 99 |
}
|
| 100 |
} else {
|
| 101 |
-
|
| 102 |
parse_str( $parsed_url['query'], $query_args );
|
| 103 |
|
| 104 |
if ( isset( $query_args['v'] ) ) {
|
|
@@ -107,7 +167,7 @@ class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 107 |
}
|
| 108 |
|
| 109 |
if ( empty( $video_id ) ) {
|
| 110 |
-
|
| 111 |
$parts = explode( '/', $parsed_url['path'] );
|
| 112 |
|
| 113 |
if ( in_array( $parts[1], array( 'v', 'e', 'embed' ), true ) ) {
|
|
@@ -118,8 +178,14 @@ class AMP_YouTube_Embed_Handler extends AMP_Base_Embed_Handler {
|
|
| 118 |
return $video_id;
|
| 119 |
}
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
private function sanitize_v_arg( $value ) {
|
| 122 |
-
// Deal with broken params like `?v=123?rel=0
|
| 123 |
if ( false !== strpos( $value, '?' ) ) {
|
| 124 |
$value = strtok( $value, '?' );
|
| 125 |
}
|
| 14 |
const SHORT_URL_HOST = 'youtu.be';
|
| 15 |
// Only handling single videos. Playlists are handled elsewhere.
|
| 16 |
const URL_PATTERN = '#https?://(?:www\.)?(?:youtube.com/(?:v/|e/|embed/|watch[/\#?])|youtu\.be/).*#i';
|
| 17 |
+
const RATIO = 0.5625;
|
| 18 |
|
| 19 |
+
/**
|
| 20 |
+
* Default width.
|
| 21 |
+
*
|
| 22 |
+
* @var int
|
| 23 |
+
*/
|
| 24 |
protected $DEFAULT_WIDTH = 600;
|
| 25 |
+
|
| 26 |
+
/**
|
| 27 |
+
* Default height.
|
| 28 |
+
*
|
| 29 |
+
* @var int
|
| 30 |
+
*/
|
| 31 |
protected $DEFAULT_HEIGHT = 338;
|
| 32 |
|
| 33 |
+
/**
|
| 34 |
+
* AMP_YouTube_Embed_Handler constructor.
|
| 35 |
+
*
|
| 36 |
+
* @param array $args Height, width and maximum width for embed.
|
| 37 |
+
*/
|
| 38 |
+
public function __construct( $args = array() ) {
|
| 39 |
parent::__construct( $args );
|
| 40 |
|
| 41 |
if ( isset( $this->args['content_max_width'] ) ) {
|
| 42 |
+
$max_width = $this->args['content_max_width'];
|
| 43 |
$this->args['width'] = $max_width;
|
| 44 |
$this->args['height'] = round( $max_width * self::RATIO );
|
| 45 |
}
|
| 46 |
}
|
| 47 |
|
| 48 |
+
/**
|
| 49 |
+
* Register embed.
|
| 50 |
+
*/
|
| 51 |
+
public function register_embed() {
|
| 52 |
wp_embed_register_handler( 'amp-youtube', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
|
| 53 |
add_shortcode( 'youtube', array( $this, 'shortcode' ) );
|
| 54 |
add_filter( 'wp_video_shortcode_override', array( $this, 'video_override' ), 10, 2 );
|
| 55 |
}
|
| 56 |
|
| 57 |
+
/**
|
| 58 |
+
* Unregister embed.
|
| 59 |
+
*/
|
| 60 |
public function unregister_embed() {
|
| 61 |
wp_embed_unregister_handler( 'amp-youtube', -1 );
|
| 62 |
remove_shortcode( 'youtube' );
|
| 63 |
}
|
| 64 |
|
| 65 |
+
/**
|
| 66 |
+
* Gets AMP-compliant markup for the YouTube shortcode.
|
| 67 |
+
*
|
| 68 |
+
* @param array $attr The YouTube attributes.
|
| 69 |
+
* @return string YouTube shortcode markup.
|
| 70 |
+
*/
|
| 71 |
public function shortcode( $attr ) {
|
| 72 |
+
$url = false;
|
| 73 |
$video_id = false;
|
| 74 |
if ( isset( $attr[0] ) ) {
|
| 75 |
+
$url = ltrim( $attr[0], '=' );
|
| 76 |
} elseif ( function_exists( 'shortcode_new_to_old_params' ) ) {
|
| 77 |
$url = shortcode_new_to_old_params( $attr );
|
| 78 |
}
|
| 83 |
|
| 84 |
$video_id = $this->get_video_id_from_url( $url );
|
| 85 |
|
| 86 |
+
return $this->render(
|
| 87 |
+
array(
|
| 88 |
+
'url' => $url,
|
| 89 |
+
'video_id' => $video_id,
|
| 90 |
+
)
|
| 91 |
+
);
|
| 92 |
}
|
| 93 |
|
| 94 |
+
/**
|
| 95 |
+
* Render oEmbed.
|
| 96 |
+
*
|
| 97 |
+
* @see \WP_Embed::shortcode()
|
| 98 |
+
*
|
| 99 |
+
* @param array $matches URL pattern matches.
|
| 100 |
+
* @param array $attr Shortcode attribues.
|
| 101 |
+
* @param string $url URL.
|
| 102 |
+
* @param string $rawattr Unmodified shortcode attributes.
|
| 103 |
+
* @return string Rendered oEmbed.
|
| 104 |
+
*/
|
| 105 |
public function oembed( $matches, $attr, $url, $rawattr ) {
|
| 106 |
return $this->shortcode( array( $url ) );
|
| 107 |
}
|
| 108 |
|
| 109 |
+
/**
|
| 110 |
+
* Render.
|
| 111 |
+
*
|
| 112 |
+
* @param array $args Args.
|
| 113 |
+
* @return string Rendered.
|
| 114 |
+
*/
|
| 115 |
public function render( $args ) {
|
| 116 |
+
$args = wp_parse_args(
|
| 117 |
+
$args, array(
|
| 118 |
+
'video_id' => false,
|
| 119 |
+
)
|
| 120 |
+
);
|
| 121 |
|
| 122 |
if ( empty( $args['video_id'] ) ) {
|
| 123 |
+
return AMP_HTML_Utils::build_tag(
|
| 124 |
+
'a', array(
|
| 125 |
+
'href' => esc_url( $args['url'] ),
|
| 126 |
+
'class' => 'amp-wp-embed-fallback',
|
| 127 |
+
), esc_html( $args['url'] )
|
| 128 |
+
);
|
| 129 |
}
|
| 130 |
|
| 131 |
$this->did_convert_elements = true;
|
| 134 |
'amp-youtube',
|
| 135 |
array(
|
| 136 |
'data-videoid' => $args['video_id'],
|
| 137 |
+
'layout' => 'responsive',
|
| 138 |
+
'width' => $this->args['width'],
|
| 139 |
+
'height' => $this->args['height'],
|
| 140 |
)
|
| 141 |
);
|
| 142 |
}
|
| 143 |
|
| 144 |
+
/**
|
| 145 |
+
* Determine the video ID from the URL.
|
| 146 |
+
*
|
| 147 |
+
* @param string $url URL.
|
| 148 |
+
* @return integer Video ID.
|
| 149 |
+
*/
|
| 150 |
private function get_video_id_from_url( $url ) {
|
| 151 |
+
$video_id = false;
|
| 152 |
+
$parsed_url = wp_parse_url( $url );
|
| 153 |
|
| 154 |
if ( self::SHORT_URL_HOST === substr( $parsed_url['host'], -strlen( self::SHORT_URL_HOST ) ) ) {
|
| 155 |
+
/* youtu.be/{id} */
|
| 156 |
$parts = explode( '/', $parsed_url['path'] );
|
| 157 |
if ( ! empty( $parts ) ) {
|
| 158 |
$video_id = $parts[1];
|
| 159 |
}
|
| 160 |
} else {
|
| 161 |
+
/* The query looks like ?v={id} or ?list={id} */
|
| 162 |
parse_str( $parsed_url['query'], $query_args );
|
| 163 |
|
| 164 |
if ( isset( $query_args['v'] ) ) {
|
| 167 |
}
|
| 168 |
|
| 169 |
if ( empty( $video_id ) ) {
|
| 170 |
+
/* The path looks like /(v|e|embed)/{id} */
|
| 171 |
$parts = explode( '/', $parsed_url['path'] );
|
| 172 |
|
| 173 |
if ( in_array( $parts[1], array( 'v', 'e', 'embed' ), true ) ) {
|
| 178 |
return $video_id;
|
| 179 |
}
|
| 180 |
|
| 181 |
+
/**
|
| 182 |
+
* Sanitize the v= argument in the URL.
|
| 183 |
+
*
|
| 184 |
+
* @param string $value query parameters.
|
| 185 |
+
* @return string First set of query parameters.
|
| 186 |
+
*/
|
| 187 |
private function sanitize_v_arg( $value ) {
|
| 188 |
+
// Deal with broken params like `?v=123?rel=0`.
|
| 189 |
if ( false !== strpos( $value, '?' ) ) {
|
| 190 |
$value = strtok( $value, '?' );
|
| 191 |
}
|
|
@@ -16,8 +16,8 @@ class AMP_Analytics_Options_Submenu {
|
|
| 16 |
|
| 17 |
public function __construct( $parent_menu_slug ) {
|
| 18 |
$this->parent_menu_slug = $parent_menu_slug;
|
| 19 |
-
$this->menu_slug
|
| 20 |
-
$this->menu_page
|
| 21 |
}
|
| 22 |
|
| 23 |
public function init() {
|
| 16 |
|
| 17 |
public function __construct( $parent_menu_slug ) {
|
| 18 |
$this->parent_menu_slug = $parent_menu_slug;
|
| 19 |
+
$this->menu_slug = 'amp-analytics-options';
|
| 20 |
+
$this->menu_page = new AMP_Analytics_Options_Submenu_Page();
|
| 21 |
}
|
| 22 |
|
| 23 |
public function init() {
|
|
@@ -17,6 +17,24 @@ class AMP_Options_Manager {
|
|
| 17 |
*/
|
| 18 |
const OPTION_NAME = 'amp-options';
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
/**
|
| 21 |
* Register settings.
|
| 22 |
*/
|
|
@@ -31,6 +49,9 @@ class AMP_Options_Manager {
|
|
| 31 |
);
|
| 32 |
|
| 33 |
add_action( 'update_option_' . self::OPTION_NAME, array( __CLASS__, 'maybe_flush_rewrite_rules' ), 10, 2 );
|
|
|
|
|
|
|
|
|
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
|
@@ -57,7 +78,12 @@ class AMP_Options_Manager {
|
|
| 57 |
* @return array Options.
|
| 58 |
*/
|
| 59 |
public static function get_options() {
|
| 60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
}
|
| 62 |
|
| 63 |
/**
|
|
@@ -85,19 +111,34 @@ class AMP_Options_Manager {
|
|
| 85 |
* @return array Options.
|
| 86 |
*/
|
| 87 |
public static function validate_options( $new_options ) {
|
| 88 |
-
$
|
| 89 |
-
'supported_post_types' => array(),
|
| 90 |
-
'analytics' => array(),
|
| 91 |
-
);
|
| 92 |
|
| 93 |
-
|
| 94 |
-
$
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
// Validate post type support.
|
|
|
|
| 99 |
if ( isset( $new_options['supported_post_types'] ) ) {
|
| 100 |
-
$options['supported_post_types'] = array();
|
| 101 |
foreach ( $new_options['supported_post_types'] as $post_type ) {
|
| 102 |
if ( ! post_type_exists( $post_type ) ) {
|
| 103 |
add_settings_error( self::OPTION_NAME, 'unknown_post_type', __( 'Unrecognized post type.', 'amp' ) );
|
|
@@ -107,6 +148,22 @@ class AMP_Options_Manager {
|
|
| 107 |
}
|
| 108 |
}
|
| 109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
// Validate analytics.
|
| 111 |
if ( isset( $new_options['analytics'] ) ) {
|
| 112 |
foreach ( $new_options['analytics'] as $id => $data ) {
|
|
@@ -124,7 +181,7 @@ class AMP_Options_Manager {
|
|
| 124 |
continue;
|
| 125 |
}
|
| 126 |
|
| 127 |
-
$entry_vendor_type =
|
| 128 |
$entry_config = trim( $data['config'] );
|
| 129 |
|
| 130 |
if ( ! empty( $data['id'] ) && '__new__' !== $data['id'] ) {
|
|
@@ -152,10 +209,22 @@ class AMP_Options_Manager {
|
|
| 152 |
}
|
| 153 |
}
|
| 154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
return $options;
|
| 156 |
}
|
| 157 |
|
| 158 |
-
|
| 159 |
/**
|
| 160 |
* Check for errors with updating the supported post types.
|
| 161 |
*
|
|
@@ -163,15 +232,20 @@ class AMP_Options_Manager {
|
|
| 163 |
* @see add_settings_error()
|
| 164 |
*/
|
| 165 |
public static function check_supported_post_type_update_errors() {
|
| 166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
$supported_types = self::get_option( 'supported_post_types', array() );
|
| 168 |
foreach ( AMP_Post_Type_Support::get_eligible_post_types() as $name ) {
|
| 169 |
$post_type = get_post_type_object( $name );
|
| 170 |
-
if ( empty( $post_type )
|
| 171 |
continue;
|
| 172 |
}
|
| 173 |
|
| 174 |
-
$post_type_supported = post_type_supports( $post_type->name,
|
| 175 |
$is_support_elected = in_array( $post_type->name, $supported_types, true );
|
| 176 |
|
| 177 |
$error = null;
|
|
@@ -259,4 +333,285 @@ class AMP_Options_Manager {
|
|
| 259 |
_deprecated_function( __METHOD__, '0.6', __CLASS__ . '::update_option' );
|
| 260 |
return self::update_option( 'analytics', wp_unslash( $data ) );
|
| 261 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
}
|
| 17 |
*/
|
| 18 |
const OPTION_NAME = 'amp-options';
|
| 19 |
|
| 20 |
+
/**
|
| 21 |
+
* Default option values.
|
| 22 |
+
*
|
| 23 |
+
* @var array
|
| 24 |
+
*/
|
| 25 |
+
protected static $defaults = array(
|
| 26 |
+
'theme_support' => 'disabled',
|
| 27 |
+
'supported_post_types' => array( 'post' ),
|
| 28 |
+
'analytics' => array(),
|
| 29 |
+
'auto_accept_sanitization' => true,
|
| 30 |
+
'accept_tree_shaking' => true,
|
| 31 |
+
'disable_admin_bar' => false,
|
| 32 |
+
'all_templates_supported' => true,
|
| 33 |
+
'supported_templates' => array( 'is_singular' ),
|
| 34 |
+
'enable_response_caching' => true,
|
| 35 |
+
'version' => AMP__VERSION,
|
| 36 |
+
);
|
| 37 |
+
|
| 38 |
/**
|
| 39 |
* Register settings.
|
| 40 |
*/
|
| 49 |
);
|
| 50 |
|
| 51 |
add_action( 'update_option_' . self::OPTION_NAME, array( __CLASS__, 'maybe_flush_rewrite_rules' ), 10, 2 );
|
| 52 |
+
add_action( 'admin_notices', array( __CLASS__, 'render_welcome_notice' ) );
|
| 53 |
+
add_action( 'admin_notices', array( __CLASS__, 'persistent_object_caching_notice' ) );
|
| 54 |
+
add_action( 'admin_notices', array( __CLASS__, 'render_cache_miss_notice' ) );
|
| 55 |
}
|
| 56 |
|
| 57 |
/**
|
| 78 |
* @return array Options.
|
| 79 |
*/
|
| 80 |
public static function get_options() {
|
| 81 |
+
$options = get_option( self::OPTION_NAME, array() );
|
| 82 |
+
if ( empty( $options ) ) {
|
| 83 |
+
$options = array();
|
| 84 |
+
}
|
| 85 |
+
self::$defaults['enable_response_caching'] = wp_using_ext_object_cache();
|
| 86 |
+
return array_merge( self::$defaults, $options );
|
| 87 |
}
|
| 88 |
|
| 89 |
/**
|
| 111 |
* @return array Options.
|
| 112 |
*/
|
| 113 |
public static function validate_options( $new_options ) {
|
| 114 |
+
$options = self::get_options();
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
| 117 |
+
return $options;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
// Theme support.
|
| 121 |
+
$recognized_theme_supports = array(
|
| 122 |
+
'disabled',
|
| 123 |
+
'paired',
|
| 124 |
+
'native',
|
| 125 |
);
|
| 126 |
+
if ( isset( $new_options['theme_support'] ) && in_array( $new_options['theme_support'], $recognized_theme_supports, true ) ) {
|
| 127 |
+
$options['theme_support'] = $new_options['theme_support'];
|
| 128 |
+
|
| 129 |
+
// If this option was changed, display a notice with the new template mode.
|
| 130 |
+
if ( self::get_option( 'theme_support' ) !== $new_options['theme_support'] ) {
|
| 131 |
+
add_action( 'update_option_' . self::OPTION_NAME, array( __CLASS__, 'handle_updated_theme_support_option' ) );
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
$options['auto_accept_sanitization'] = ! empty( $new_options['auto_accept_sanitization'] );
|
| 136 |
+
$options['accept_tree_shaking'] = ! empty( $new_options['accept_tree_shaking'] );
|
| 137 |
+
$options['disable_admin_bar'] = ! empty( $new_options['disable_admin_bar'] );
|
| 138 |
|
| 139 |
// Validate post type support.
|
| 140 |
+
$options['supported_post_types'] = array();
|
| 141 |
if ( isset( $new_options['supported_post_types'] ) ) {
|
|
|
|
| 142 |
foreach ( $new_options['supported_post_types'] as $post_type ) {
|
| 143 |
if ( ! post_type_exists( $post_type ) ) {
|
| 144 |
add_settings_error( self::OPTION_NAME, 'unknown_post_type', __( 'Unrecognized post type.', 'amp' ) );
|
| 148 |
}
|
| 149 |
}
|
| 150 |
|
| 151 |
+
$theme_support_args = AMP_Theme_Support::get_theme_support_args();
|
| 152 |
+
|
| 153 |
+
$is_template_support_required = ( isset( $theme_support_args['templates_supported'] ) && 'all' === $theme_support_args['templates_supported'] );
|
| 154 |
+
if ( ! $is_template_support_required && ! isset( $theme_support_args['available_callback'] ) ) {
|
| 155 |
+
$options['all_templates_supported'] = ! empty( $new_options['all_templates_supported'] );
|
| 156 |
+
|
| 157 |
+
// Validate supported templates.
|
| 158 |
+
$options['supported_templates'] = array();
|
| 159 |
+
if ( isset( $new_options['supported_templates'] ) ) {
|
| 160 |
+
$options['supported_templates'] = array_intersect(
|
| 161 |
+
$new_options['supported_templates'],
|
| 162 |
+
array_keys( AMP_Theme_Support::get_supportable_templates() )
|
| 163 |
+
);
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
// Validate analytics.
|
| 168 |
if ( isset( $new_options['analytics'] ) ) {
|
| 169 |
foreach ( $new_options['analytics'] as $id => $data ) {
|
| 181 |
continue;
|
| 182 |
}
|
| 183 |
|
| 184 |
+
$entry_vendor_type = preg_replace( '/[^a-zA-Z0-9_\-]/', '', $data['type'] );
|
| 185 |
$entry_config = trim( $data['config'] );
|
| 186 |
|
| 187 |
if ( ! empty( $data['id'] ) && '__new__' !== $data['id'] ) {
|
| 209 |
}
|
| 210 |
}
|
| 211 |
|
| 212 |
+
// Store the current version with the options so we know the format.
|
| 213 |
+
$options['version'] = AMP__VERSION;
|
| 214 |
+
|
| 215 |
+
// Handle the caching option.
|
| 216 |
+
$options['enable_response_caching'] = (
|
| 217 |
+
wp_using_ext_object_cache()
|
| 218 |
+
&&
|
| 219 |
+
! empty( $new_options['enable_response_caching'] )
|
| 220 |
+
);
|
| 221 |
+
if ( $options['enable_response_caching'] ) {
|
| 222 |
+
AMP_Theme_Support::reset_cache_miss_url_option();
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
return $options;
|
| 226 |
}
|
| 227 |
|
|
|
|
| 228 |
/**
|
| 229 |
* Check for errors with updating the supported post types.
|
| 230 |
*
|
| 232 |
* @see add_settings_error()
|
| 233 |
*/
|
| 234 |
public static function check_supported_post_type_update_errors() {
|
| 235 |
+
|
| 236 |
+
// If all templates are supported then skip check since all post types are also supported. This option only applies with native/paired theme support.
|
| 237 |
+
if ( self::get_option( 'all_templates_supported', false ) && 'disabled' !== self::get_option( 'theme_support' ) ) {
|
| 238 |
+
return;
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
$supported_types = self::get_option( 'supported_post_types', array() );
|
| 242 |
foreach ( AMP_Post_Type_Support::get_eligible_post_types() as $name ) {
|
| 243 |
$post_type = get_post_type_object( $name );
|
| 244 |
+
if ( empty( $post_type ) ) {
|
| 245 |
continue;
|
| 246 |
}
|
| 247 |
|
| 248 |
+
$post_type_supported = post_type_supports( $post_type->name, AMP_Post_Type_Support::SLUG );
|
| 249 |
$is_support_elected = in_array( $post_type->name, $supported_types, true );
|
| 250 |
|
| 251 |
$error = null;
|
| 333 |
_deprecated_function( __METHOD__, '0.6', __CLASS__ . '::update_option' );
|
| 334 |
return self::update_option( 'analytics', wp_unslash( $data ) );
|
| 335 |
}
|
| 336 |
+
|
| 337 |
+
/**
|
| 338 |
+
* Renders the welcome notice on the 'AMP Settings' page.
|
| 339 |
+
*
|
| 340 |
+
* Uses the user meta values for the dismissed WP pointers.
|
| 341 |
+
* So once the user dismisses this notice, it will never appear again.
|
| 342 |
+
*/
|
| 343 |
+
public static function render_welcome_notice() {
|
| 344 |
+
if ( 'toplevel_page_' . self::OPTION_NAME !== get_current_screen()->id ) {
|
| 345 |
+
return;
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
$notice_id = 'amp-welcome-notice-1';
|
| 349 |
+
$dismissed = get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true );
|
| 350 |
+
if ( in_array( $notice_id, explode( ',', strval( $dismissed ) ), true ) ) {
|
| 351 |
+
return;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
?>
|
| 355 |
+
<div class="amp-welcome-notice notice notice-info is-dismissible" id="<?php echo esc_attr( $notice_id ); ?>">
|
| 356 |
+
<div class="notice-dismiss"></div>
|
| 357 |
+
<div class="amp-welcome-icon-holder">
|
| 358 |
+
<img class="amp-welcome-icon" src="<?php echo esc_url( amp_get_asset_url( 'images/amp-welcome-icon.svg' ) ); ?>" alt="<?php esc_html_e( 'Illustration of WordPress running AMP plugin.', 'amp' ); ?>" />
|
| 359 |
+
</div>
|
| 360 |
+
<h1><?php esc_html_e( 'Welcome to AMP for WordPress', 'amp' ); ?></h1>
|
| 361 |
+
<h3><?php esc_html_e( 'Bring the speed and features of the open source AMP project to your site, complete with the tools to support content authoring and website development.', 'amp' ); ?></h3>
|
| 362 |
+
<h3><?php esc_html_e( 'From granular controls that help you create AMP content, to Core Gutenberg support, to a sanitizer that only shows visitors error-free pages, to a full error workflow for developers, this release enables rich, performant experiences for your WordPress site.', 'amp' ); ?></h3>
|
| 363 |
+
<a href="https://www.ampproject.org/docs/getting_started/" target="_blank" class="button button-primary"><?php esc_html_e( 'Learn More', 'amp' ); ?></a>
|
| 364 |
+
</div>
|
| 365 |
+
|
| 366 |
+
<script>
|
| 367 |
+
jQuery( function( $ ) {
|
| 368 |
+
// On dismissing the notice, make a POST request to store this notice with the dismissed WP pointers so it doesn't display again.
|
| 369 |
+
$( <?php echo wp_json_encode( "#$notice_id" ); ?> ).on( 'click', '.notice-dismiss', function() {
|
| 370 |
+
$.post( ajaxurl, {
|
| 371 |
+
pointer: <?php echo wp_json_encode( $notice_id ); ?>,
|
| 372 |
+
action: 'dismiss-wp-pointer'
|
| 373 |
+
} );
|
| 374 |
+
} );
|
| 375 |
+
} );
|
| 376 |
+
</script>
|
| 377 |
+
<style type="text/css">
|
| 378 |
+
.amp-welcome-notice {
|
| 379 |
+
padding: 38px;
|
| 380 |
+
}
|
| 381 |
+
.amp-welcome-icon-holder {
|
| 382 |
+
width: 200px;
|
| 383 |
+
height: 200px;
|
| 384 |
+
float: left;
|
| 385 |
+
margin: 0 38px 38px 0;
|
| 386 |
+
}
|
| 387 |
+
.amp-welcome-icon {
|
| 388 |
+
width: 100%;
|
| 389 |
+
height: 100%;
|
| 390 |
+
display: block;
|
| 391 |
+
}
|
| 392 |
+
.amp-welcome-notice h1 {
|
| 393 |
+
font-weight: bold;
|
| 394 |
+
}
|
| 395 |
+
.amp-welcome-notice h3 {
|
| 396 |
+
font-size: 16px;
|
| 397 |
+
font-weight: 500;
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
</style>
|
| 401 |
+
<?php
|
| 402 |
+
}
|
| 403 |
+
|
| 404 |
+
/**
|
| 405 |
+
* Outputs an admin notice if persistent object cache is not present.
|
| 406 |
+
*
|
| 407 |
+
* @return void
|
| 408 |
+
*/
|
| 409 |
+
public static function persistent_object_caching_notice() {
|
| 410 |
+
if ( ! wp_using_ext_object_cache() && 'toplevel_page_' . self::OPTION_NAME === get_current_screen()->id ) {
|
| 411 |
+
printf(
|
| 412 |
+
'<div class="notice notice-warning"><p>%s <a href="%s">%s</a></p></div>',
|
| 413 |
+
esc_html__( 'The AMP plugin performs at its best when persistent object cache is enabled.', 'amp' ),
|
| 414 |
+
esc_url( 'https://codex.wordpress.org/Class_Reference/WP_Object_Cache#Persistent_Caching' ),
|
| 415 |
+
esc_html__( 'More details', 'amp' )
|
| 416 |
+
);
|
| 417 |
+
}
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
/**
|
| 421 |
+
* Render the cache miss admin notice.
|
| 422 |
+
*
|
| 423 |
+
* @return void
|
| 424 |
+
*/
|
| 425 |
+
public static function render_cache_miss_notice() {
|
| 426 |
+
if ( 'toplevel_page_' . self::OPTION_NAME !== get_current_screen()->id ) {
|
| 427 |
+
return;
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
if ( ! self::show_response_cache_disabled_notice() ) {
|
| 431 |
+
return;
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
printf(
|
| 435 |
+
'<div class="notice notice-warning is-dismissible"><p>%s <a href="%s">%s</a></p></div>',
|
| 436 |
+
esc_html__( "The AMP plugin's post-processor cache disabled due to the detection of highly-variable content.", 'amp' ),
|
| 437 |
+
esc_url( 'https://github.com/ampproject/amp-wp/wiki/Post-Processor-Cache' ),
|
| 438 |
+
esc_html__( 'More details', 'amp' )
|
| 439 |
+
);
|
| 440 |
+
}
|
| 441 |
+
|
| 442 |
+
/**
|
| 443 |
+
* Show the response cache disabled notice.
|
| 444 |
+
*
|
| 445 |
+
* @since 1.0
|
| 446 |
+
*
|
| 447 |
+
* @return bool
|
| 448 |
+
*/
|
| 449 |
+
public static function show_response_cache_disabled_notice() {
|
| 450 |
+
return (
|
| 451 |
+
wp_using_ext_object_cache()
|
| 452 |
+
&&
|
| 453 |
+
! self::get_option( 'enable_response_caching' )
|
| 454 |
+
&&
|
| 455 |
+
AMP_Theme_Support::exceeded_cache_miss_threshold()
|
| 456 |
+
);
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
/**
|
| 460 |
+
* Adds a message for an update of the theme support setting.
|
| 461 |
+
*/
|
| 462 |
+
public static function handle_updated_theme_support_option() {
|
| 463 |
+
$template_mode = self::get_option( 'theme_support' );
|
| 464 |
+
|
| 465 |
+
// Make sure post type support has been added for sake of amp_admin_get_preview_permalink().
|
| 466 |
+
foreach ( AMP_Post_Type_Support::get_eligible_post_types() as $post_type ) {
|
| 467 |
+
remove_post_type_support( $post_type, AMP_Post_Type_Support::SLUG );
|
| 468 |
+
}
|
| 469 |
+
AMP_Post_Type_Support::add_post_type_support();
|
| 470 |
+
|
| 471 |
+
// Ensure theme support flags are set properly according to the new mode so that proper AMP URL can be generated.
|
| 472 |
+
$has_theme_support = ( 'native' === $template_mode || 'paired' === $template_mode );
|
| 473 |
+
if ( $has_theme_support ) {
|
| 474 |
+
$theme_support = current_theme_supports( AMP_Theme_Support::SLUG );
|
| 475 |
+
if ( ! is_array( $theme_support ) ) {
|
| 476 |
+
$theme_support = array();
|
| 477 |
+
}
|
| 478 |
+
$theme_support['paired'] = 'paired' === $template_mode;
|
| 479 |
+
add_theme_support( AMP_Theme_Support::SLUG, $theme_support );
|
| 480 |
+
} else {
|
| 481 |
+
remove_theme_support( AMP_Theme_Support::SLUG ); // So that the amp_get_permalink() will work for classic URL.
|
| 482 |
+
}
|
| 483 |
+
|
| 484 |
+
$url = amp_admin_get_preview_permalink();
|
| 485 |
+
|
| 486 |
+
$notice_type = 'updated';
|
| 487 |
+
$review_messages = array();
|
| 488 |
+
if ( $url && $has_theme_support ) {
|
| 489 |
+
$validation = AMP_Validation_Manager::validate_url( $url );
|
| 490 |
+
|
| 491 |
+
if ( is_wp_error( $validation ) ) {
|
| 492 |
+
$review_messages[] = esc_html( sprintf(
|
| 493 |
+
/* translators: %1$s is the error message, %2$s is the error code */
|
| 494 |
+
__( 'However, there was an error when checking the AMP validity for your site.', 'amp' ),
|
| 495 |
+
$validation->get_error_message(),
|
| 496 |
+
$validation->get_error_code()
|
| 497 |
+
) );
|
| 498 |
+
|
| 499 |
+
$error_message = $validation->get_error_message();
|
| 500 |
+
if ( $error_message ) {
|
| 501 |
+
$review_messages[] = $error_message;
|
| 502 |
+
} else {
|
| 503 |
+
/* translators: %s is the error code */
|
| 504 |
+
$review_messages[] = esc_html( sprintf( __( 'Error code: %s.', 'amp' ), $validation->get_error_code() ) );
|
| 505 |
+
}
|
| 506 |
+
$notice_type = 'error';
|
| 507 |
+
} elseif ( is_array( $validation ) ) {
|
| 508 |
+
$new_errors = 0;
|
| 509 |
+
$rejected_errors = 0;
|
| 510 |
+
|
| 511 |
+
$errors = wp_list_pluck( $validation['results'], 'error' );
|
| 512 |
+
foreach ( $errors as $error ) {
|
| 513 |
+
$sanitization = AMP_Validation_Error_Taxonomy::get_validation_error_sanitization( $error );
|
| 514 |
+
$is_new_rejected = AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_REJECTED_STATUS === $sanitization['status'];
|
| 515 |
+
if ( $is_new_rejected || AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_ACCEPTED_STATUS === $sanitization['status'] ) {
|
| 516 |
+
$new_errors++;
|
| 517 |
+
}
|
| 518 |
+
if ( $is_new_rejected || AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACK_REJECTED_STATUS === $sanitization['status'] ) {
|
| 519 |
+
$rejected_errors++;
|
| 520 |
+
}
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
$invalid_url_post_id = AMP_Validated_URL_Post_Type::store_validation_errors( $errors, $url );
|
| 524 |
+
$invalid_url_screen_url = ! is_wp_error( $invalid_url_post_id ) ? get_edit_post_link( $invalid_url_post_id, 'raw' ) : null;
|
| 525 |
+
|
| 526 |
+
if ( $rejected_errors > 0 ) {
|
| 527 |
+
$notice_type = 'error';
|
| 528 |
+
|
| 529 |
+
$message = wp_kses_post(
|
| 530 |
+
sprintf(
|
| 531 |
+
/* translators: %s is count of rejected errors */
|
| 532 |
+
_n(
|
| 533 |
+
'However, AMP is not yet available due to %s validation error (for one URL at least).',
|
| 534 |
+
'However, AMP is not yet available due to %s validation errors (for one URL at least).',
|
| 535 |
+
number_format_i18n( $rejected_errors ),
|
| 536 |
+
'amp'
|
| 537 |
+
),
|
| 538 |
+
$rejected_errors,
|
| 539 |
+
esc_url( $invalid_url_screen_url )
|
| 540 |
+
)
|
| 541 |
+
);
|
| 542 |
+
|
| 543 |
+
if ( $invalid_url_screen_url ) {
|
| 544 |
+
$message .= ' ' . wp_kses_post(
|
| 545 |
+
sprintf(
|
| 546 |
+
/* translators: %s is URL to review issues */
|
| 547 |
+
_n(
|
| 548 |
+
'<a href="%s">Review Issue</a>.',
|
| 549 |
+
'<a href="%s">Review Issues</a>.',
|
| 550 |
+
$rejected_errors,
|
| 551 |
+
'amp'
|
| 552 |
+
),
|
| 553 |
+
esc_url( $invalid_url_screen_url )
|
| 554 |
+
)
|
| 555 |
+
);
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
$review_messages[] = $message;
|
| 559 |
+
} else {
|
| 560 |
+
$message = wp_kses_post(
|
| 561 |
+
sprintf(
|
| 562 |
+
/* translators: %s is an AMP URL */
|
| 563 |
+
__( 'View an <a href="%s">AMP version of your site</a>.', 'amp' ),
|
| 564 |
+
esc_url( $url )
|
| 565 |
+
)
|
| 566 |
+
);
|
| 567 |
+
|
| 568 |
+
if ( $new_errors > 0 && $invalid_url_screen_url ) {
|
| 569 |
+
$message .= ' ' . wp_kses_post(
|
| 570 |
+
sprintf(
|
| 571 |
+
/* translators: %1$s is URL to review issues, %2$s is count of new errors */
|
| 572 |
+
_n(
|
| 573 |
+
'Please also <a href="%1$s">review %2$s issue</a> which may need to be fixed (for one URL at least).',
|
| 574 |
+
'Please also <a href="%1$s">review %2$s issues</a> which may need to be fixed (for one URL at least).',
|
| 575 |
+
$new_errors,
|
| 576 |
+
'amp'
|
| 577 |
+
),
|
| 578 |
+
esc_url( $invalid_url_screen_url ),
|
| 579 |
+
number_format_i18n( $new_errors )
|
| 580 |
+
)
|
| 581 |
+
);
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
$review_messages[] = $message;
|
| 585 |
+
}
|
| 586 |
+
}
|
| 587 |
+
}
|
| 588 |
+
|
| 589 |
+
switch ( $template_mode ) {
|
| 590 |
+
case 'native':
|
| 591 |
+
$message = esc_html__( 'Native mode activated!', 'amp' );
|
| 592 |
+
if ( $review_messages ) {
|
| 593 |
+
$message .= ' ' . join( ' ', $review_messages );
|
| 594 |
+
}
|
| 595 |
+
break;
|
| 596 |
+
case 'paired':
|
| 597 |
+
$message = esc_html__( 'Paired mode activated!', 'amp' );
|
| 598 |
+
if ( $review_messages ) {
|
| 599 |
+
$message .= ' ' . join( ' ', $review_messages );
|
| 600 |
+
}
|
| 601 |
+
break;
|
| 602 |
+
case 'disabled':
|
| 603 |
+
$message = wp_kses_post(
|
| 604 |
+
sprintf(
|
| 605 |
+
/* translators: %s is an AMP URL */
|
| 606 |
+
__( 'Classic mode activated! View the <a href="%s">AMP version of a recent post</a>. It is recommended that you upgrade to Native or Paired mode.', 'amp' ),
|
| 607 |
+
esc_url( $url )
|
| 608 |
+
)
|
| 609 |
+
);
|
| 610 |
+
break;
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
if ( isset( $message ) ) {
|
| 614 |
+
add_settings_error( self::OPTION_NAME, 'template_mode_updated', $message, $notice_type );
|
| 615 |
+
}
|
| 616 |
+
}
|
| 617 |
}
|
|
@@ -23,6 +23,28 @@ class AMP_Options_Menu {
|
|
| 23 |
public function init() {
|
| 24 |
add_action( 'admin_post_amp_analytics_options', 'AMP_Options_Manager::handle_analytics_submit' );
|
| 25 |
add_action( 'admin_menu', array( $this, 'add_menu_items' ), 9 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
}
|
| 27 |
|
| 28 |
/**
|
|
@@ -33,7 +55,7 @@ class AMP_Options_Menu {
|
|
| 33 |
add_menu_page(
|
| 34 |
__( 'AMP Options', 'amp' ),
|
| 35 |
__( 'AMP', 'amp' ),
|
| 36 |
-
'
|
| 37 |
AMP_Options_Manager::OPTION_NAME,
|
| 38 |
array( $this, 'render_screen' ),
|
| 39 |
self::ICON_BASE64_SVG
|
|
@@ -43,24 +65,63 @@ class AMP_Options_Menu {
|
|
| 43 |
AMP_Options_Manager::OPTION_NAME,
|
| 44 |
__( 'AMP Settings', 'amp' ),
|
| 45 |
__( 'General', 'amp' ),
|
| 46 |
-
'
|
| 47 |
AMP_Options_Manager::OPTION_NAME
|
| 48 |
);
|
| 49 |
|
| 50 |
add_settings_section(
|
| 51 |
-
'
|
| 52 |
false,
|
| 53 |
'__return_false',
|
| 54 |
AMP_Options_Manager::OPTION_NAME
|
| 55 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
add_settings_field(
|
| 57 |
-
'
|
| 58 |
-
__( '
|
| 59 |
-
array( $this, '
|
| 60 |
AMP_Options_Manager::OPTION_NAME,
|
| 61 |
-
'
|
|
|
|
|
|
|
|
|
|
| 62 |
);
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
$submenus = array(
|
| 65 |
new AMP_Analytics_Options_Submenu( AMP_Options_Manager::OPTION_NAME ),
|
| 66 |
);
|
|
@@ -71,50 +132,435 @@ class AMP_Options_Menu {
|
|
| 71 |
}
|
| 72 |
}
|
| 73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
/**
|
| 75 |
* Post types support section renderer.
|
| 76 |
*
|
| 77 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
*/
|
| 79 |
-
public function
|
| 80 |
-
$
|
| 81 |
-
$element_name = AMP_Options_Manager::OPTION_NAME . '[supported_post_types][]';
|
| 82 |
?>
|
| 83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
<?php foreach ( array_map( 'get_post_type_object', AMP_Post_Type_Support::get_eligible_post_types() ) as $post_type ) : ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
<?php
|
| 86 |
-
|
| 87 |
-
$is_builtin = amp_is_canonical() || in_array( $post_type->name, $builtin_support, true );
|
| 88 |
?>
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
</label>
|
| 103 |
-
<br>
|
| 104 |
-
<?php endforeach; ?>
|
| 105 |
-
<p class="description">
|
| 106 |
-
<?php
|
| 107 |
-
if ( ! amp_is_canonical() ) :
|
| 108 |
-
esc_html_e( 'Enable/disable AMP post type(s) support', 'amp' );
|
| 109 |
-
else :
|
| 110 |
-
esc_html_e( 'Canonical AMP is enabled in your theme, so all post types will render.', 'amp' );
|
| 111 |
-
endif;
|
| 112 |
-
?>
|
| 113 |
</p>
|
|
|
|
| 114 |
</fieldset>
|
| 115 |
<?php
|
| 116 |
}
|
| 117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
/**
|
| 119 |
* Display Settings.
|
| 120 |
*
|
|
@@ -125,14 +571,19 @@ class AMP_Options_Menu {
|
|
| 125 |
AMP_Options_Manager::check_supported_post_type_update_errors();
|
| 126 |
}
|
| 127 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
<div class="wrap">
|
| 129 |
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
| 130 |
<?php settings_errors(); ?>
|
| 131 |
-
<form action="options.php" method="post">
|
| 132 |
<?php
|
| 133 |
settings_fields( AMP_Options_Manager::OPTION_NAME );
|
| 134 |
do_settings_sections( AMP_Options_Manager::OPTION_NAME );
|
| 135 |
-
if (
|
| 136 |
submit_button();
|
| 137 |
}
|
| 138 |
?>
|
| 23 |
public function init() {
|
| 24 |
add_action( 'admin_post_amp_analytics_options', 'AMP_Options_Manager::handle_analytics_submit' );
|
| 25 |
add_action( 'admin_menu', array( $this, 'add_menu_items' ), 9 );
|
| 26 |
+
|
| 27 |
+
$plugin_file = preg_replace( '#.+/(?=.+?/.+?)#', '', AMP__FILE__ );
|
| 28 |
+
add_filter( "plugin_action_links_{$plugin_file}", array( $this, 'add_plugin_action_links' ) );
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* Add plugin action links.
|
| 33 |
+
*
|
| 34 |
+
* @param array $links Links.
|
| 35 |
+
* @return array Modified links.
|
| 36 |
+
*/
|
| 37 |
+
public function add_plugin_action_links( $links ) {
|
| 38 |
+
return array_merge(
|
| 39 |
+
array(
|
| 40 |
+
'settings' => sprintf(
|
| 41 |
+
'<a href="%1$s">%2$s</a>',
|
| 42 |
+
esc_url( add_query_arg( 'page', AMP_Options_Manager::OPTION_NAME, admin_url( 'admin.php' ) ) ),
|
| 43 |
+
__( 'Settings', 'amp' )
|
| 44 |
+
),
|
| 45 |
+
),
|
| 46 |
+
$links
|
| 47 |
+
);
|
| 48 |
}
|
| 49 |
|
| 50 |
/**
|
| 55 |
add_menu_page(
|
| 56 |
__( 'AMP Options', 'amp' ),
|
| 57 |
__( 'AMP', 'amp' ),
|
| 58 |
+
'edit_posts',
|
| 59 |
AMP_Options_Manager::OPTION_NAME,
|
| 60 |
array( $this, 'render_screen' ),
|
| 61 |
self::ICON_BASE64_SVG
|
| 65 |
AMP_Options_Manager::OPTION_NAME,
|
| 66 |
__( 'AMP Settings', 'amp' ),
|
| 67 |
__( 'General', 'amp' ),
|
| 68 |
+
'edit_posts',
|
| 69 |
AMP_Options_Manager::OPTION_NAME
|
| 70 |
);
|
| 71 |
|
| 72 |
add_settings_section(
|
| 73 |
+
'general',
|
| 74 |
false,
|
| 75 |
'__return_false',
|
| 76 |
AMP_Options_Manager::OPTION_NAME
|
| 77 |
);
|
| 78 |
+
|
| 79 |
+
add_settings_field(
|
| 80 |
+
'theme_support',
|
| 81 |
+
__( 'Template Mode', 'amp' ),
|
| 82 |
+
array( $this, 'render_theme_support' ),
|
| 83 |
+
AMP_Options_Manager::OPTION_NAME,
|
| 84 |
+
'general',
|
| 85 |
+
array(
|
| 86 |
+
'class' => 'theme_support',
|
| 87 |
+
)
|
| 88 |
+
);
|
| 89 |
+
|
| 90 |
+
add_settings_field(
|
| 91 |
+
'validation',
|
| 92 |
+
__( 'Validation Handling', 'amp' ),
|
| 93 |
+
array( $this, 'render_validation_handling' ),
|
| 94 |
+
AMP_Options_Manager::OPTION_NAME,
|
| 95 |
+
'general',
|
| 96 |
+
array(
|
| 97 |
+
'class' => 'amp-validation-field',
|
| 98 |
+
)
|
| 99 |
+
);
|
| 100 |
+
|
| 101 |
add_settings_field(
|
| 102 |
+
'supported_templates',
|
| 103 |
+
__( 'Supported Templates', 'amp' ),
|
| 104 |
+
array( $this, 'render_supported_templates' ),
|
| 105 |
AMP_Options_Manager::OPTION_NAME,
|
| 106 |
+
'general',
|
| 107 |
+
array(
|
| 108 |
+
'class' => 'amp-template-support-field',
|
| 109 |
+
)
|
| 110 |
);
|
| 111 |
|
| 112 |
+
if ( wp_using_ext_object_cache() ) {
|
| 113 |
+
add_settings_field(
|
| 114 |
+
'caching',
|
| 115 |
+
__( 'Caching', 'amp' ),
|
| 116 |
+
array( $this, 'render_caching' ),
|
| 117 |
+
AMP_Options_Manager::OPTION_NAME,
|
| 118 |
+
'general',
|
| 119 |
+
array(
|
| 120 |
+
'class' => 'amp-caching-field',
|
| 121 |
+
)
|
| 122 |
+
);
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
$submenus = array(
|
| 126 |
new AMP_Analytics_Options_Submenu( AMP_Options_Manager::OPTION_NAME ),
|
| 127 |
);
|
| 132 |
}
|
| 133 |
}
|
| 134 |
|
| 135 |
+
/**
|
| 136 |
+
* Render theme support.
|
| 137 |
+
*
|
| 138 |
+
* @since 1.0
|
| 139 |
+
*/
|
| 140 |
+
public function render_theme_support() {
|
| 141 |
+
$theme_support = AMP_Options_Manager::get_option( 'theme_support' );
|
| 142 |
+
$native_description = __( 'Reuses active theme\'s templates to display AMP responses but does not use separate URLs for AMP. This means your site is <b>AMP-first</b> and your canonical URLs are AMP.', 'amp' );
|
| 143 |
+
$paired_description = __( 'Reuses active theme\'s templates to display AMP responses, but uses separate URLs for AMP. Each canonical URL may have a corresponding AMP URL, if the content is fully AMP valid.', 'amp' );
|
| 144 |
+
|
| 145 |
+
$builtin_support = in_array( get_template(), AMP_Core_Theme_Sanitizer::get_supported_themes(), true );
|
| 146 |
+
?>
|
| 147 |
+
<?php if ( current_theme_supports( AMP_Theme_Support::SLUG ) && ! AMP_Theme_Support::is_support_added_via_option() ) : ?>
|
| 148 |
+
<div class="notice notice-info notice-alt inline">
|
| 149 |
+
<p><?php esc_html_e( 'Your active theme has built-in AMP support.', 'amp' ); ?></p>
|
| 150 |
+
</div>
|
| 151 |
+
<p>
|
| 152 |
+
<?php if ( amp_is_canonical() ) : ?>
|
| 153 |
+
<strong><?php esc_html_e( 'Native:', 'amp' ); ?></strong>
|
| 154 |
+
<?php echo wp_kses_post( $native_description ); ?>
|
| 155 |
+
<?php else : ?>
|
| 156 |
+
<strong><?php esc_html_e( 'Paired:', 'amp' ); ?></strong>
|
| 157 |
+
<?php echo wp_kses_post( $paired_description ); ?>
|
| 158 |
+
<?php endif; ?>
|
| 159 |
+
</p>
|
| 160 |
+
<?php else : ?>
|
| 161 |
+
<fieldset <?php disabled( ! current_user_can( 'manage_options' ) ); ?>>
|
| 162 |
+
<?php if ( $builtin_support ) : ?>
|
| 163 |
+
<div class="notice notice-success notice-alt inline">
|
| 164 |
+
<p><?php esc_html_e( 'Your active theme is known to work well in paired or native mode.', 'amp' ); ?></p>
|
| 165 |
+
</div>
|
| 166 |
+
<?php endif; ?>
|
| 167 |
+
<dl>
|
| 168 |
+
<dt>
|
| 169 |
+
<input type="radio" id="theme_support_native" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[theme_support]' ); ?>" value="native" <?php checked( $theme_support, 'native' ); ?>>
|
| 170 |
+
<label for="theme_support_native">
|
| 171 |
+
<strong><?php esc_html_e( 'Native', 'amp' ); ?></strong>
|
| 172 |
+
</label>
|
| 173 |
+
</dt>
|
| 174 |
+
<dd>
|
| 175 |
+
<?php echo wp_kses_post( $native_description ); ?>
|
| 176 |
+
</dd>
|
| 177 |
+
<dt>
|
| 178 |
+
<input type="radio" id="theme_support_paired" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[theme_support]' ); ?>" value="paired" <?php checked( $theme_support, 'paired' ); ?>>
|
| 179 |
+
<label for="theme_support_paired">
|
| 180 |
+
<strong><?php esc_html_e( 'Paired', 'amp' ); ?></strong>
|
| 181 |
+
</label>
|
| 182 |
+
</dt>
|
| 183 |
+
<dd>
|
| 184 |
+
<?php echo wp_kses_post( $paired_description ); ?>
|
| 185 |
+
</dd>
|
| 186 |
+
<dt>
|
| 187 |
+
<input type="radio" id="theme_support_disabled" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[theme_support]' ); ?>" value="disabled" <?php checked( $theme_support, 'disabled' ); ?>>
|
| 188 |
+
<label for="theme_support_disabled">
|
| 189 |
+
<strong><?php esc_html_e( 'Classic', 'amp' ); ?></strong>
|
| 190 |
+
</label>
|
| 191 |
+
</dt>
|
| 192 |
+
<dd>
|
| 193 |
+
<?php esc_html_e( 'Display AMP responses in classic (legacy) post templates in a basic design that does not match your theme\'s templates.', 'amp' ); ?>
|
| 194 |
+
|
| 195 |
+
<?php if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) && wp_count_posts( AMP_Validated_URL_Post_Type::POST_TYPE_SLUG )->publish > 0 ) : ?>
|
| 196 |
+
<div class="notice notice-info inline notice-alt">
|
| 197 |
+
<p>
|
| 198 |
+
<?php
|
| 199 |
+
echo wp_kses_post(
|
| 200 |
+
sprintf(
|
| 201 |
+
/* translators: %1$s is link to invalid URLs and %2$s is link to validation errors */
|
| 202 |
+
__( 'View current site compatibility results for native and paired modes: %1$s and %2$s.', 'amp' ),
|
| 203 |
+
sprintf(
|
| 204 |
+
'<a href="%s">%s</a>',
|
| 205 |
+
esc_url( add_query_arg( 'post_type', AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, admin_url( 'edit.php' ) ) ),
|
| 206 |
+
esc_html( get_post_type_object( AMP_Validated_URL_Post_Type::POST_TYPE_SLUG )->labels->name )
|
| 207 |
+
),
|
| 208 |
+
sprintf(
|
| 209 |
+
'<a href="%s">%s</a>',
|
| 210 |
+
esc_url(
|
| 211 |
+
add_query_arg(
|
| 212 |
+
array(
|
| 213 |
+
'taxonomy' => AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG,
|
| 214 |
+
'post_type' => AMP_Validated_URL_Post_Type::POST_TYPE_SLUG,
|
| 215 |
+
),
|
| 216 |
+
admin_url( 'edit-tags.php' )
|
| 217 |
+
)
|
| 218 |
+
),
|
| 219 |
+
esc_html( get_taxonomy( AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG )->labels->name )
|
| 220 |
+
)
|
| 221 |
+
)
|
| 222 |
+
);
|
| 223 |
+
?>
|
| 224 |
+
</p>
|
| 225 |
+
</div>
|
| 226 |
+
<?php endif; ?>
|
| 227 |
+
</dd>
|
| 228 |
+
</dl>
|
| 229 |
+
</fieldset>
|
| 230 |
+
<?php endif; ?>
|
| 231 |
+
<?php
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
/**
|
| 235 |
* Post types support section renderer.
|
| 236 |
*
|
| 237 |
+
* @todo If dirty AMP is ever allowed (that is, post-processed documents which can be served with non-sanitized valdation errors), then automatically forcing sanitization in native should be able to be turned off.
|
| 238 |
+
*
|
| 239 |
+
* @since 1.0
|
| 240 |
+
*/
|
| 241 |
+
public function render_validation_handling() {
|
| 242 |
+
?>
|
| 243 |
+
<fieldset <?php disabled( ! current_user_can( 'manage_options' ) ); ?>>
|
| 244 |
+
<?php
|
| 245 |
+
$auto_sanitization = AMP_Validation_Error_Taxonomy::get_validation_error_sanitization( array(
|
| 246 |
+
'code' => 'non_existent',
|
| 247 |
+
) );
|
| 248 |
+
remove_filter( 'amp_validation_error_sanitized', array( 'AMP_Validation_Manager', 'filter_tree_shaking_validation_error_as_accepted' ) );
|
| 249 |
+
$tree_shaking_sanitization = AMP_Validation_Error_Taxonomy::get_validation_error_sanitization( array(
|
| 250 |
+
'code' => AMP_Style_Sanitizer::TREE_SHAKING_ERROR_CODE,
|
| 251 |
+
) );
|
| 252 |
+
|
| 253 |
+
$forced_sanitization = 'with_filter' === $auto_sanitization['forced'];
|
| 254 |
+
$forced_tree_shaking = $forced_sanitization || 'with_filter' === $tree_shaking_sanitization['forced'];
|
| 255 |
+
?>
|
| 256 |
+
|
| 257 |
+
<?php if ( $forced_sanitization ) : ?>
|
| 258 |
+
<div class="notice notice-info notice-alt inline">
|
| 259 |
+
<p><?php esc_html_e( 'Your install is configured via a theme or plugin to automatically sanitize any AMP validation error that is encountered.', 'amp' ); ?></p>
|
| 260 |
+
</div>
|
| 261 |
+
<input type="hidden" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[auto_accept_sanitization]' ); ?>" value="<?php echo AMP_Options_Manager::get_option( 'auto_accept_sanitization' ) ? 'on' : ''; ?>">
|
| 262 |
+
<?php else : ?>
|
| 263 |
+
<div class="amp-auto-accept-sanitize-canonical notice notice-info notice-alt inline">
|
| 264 |
+
<p><?php esc_html_e( 'All new validation errors are automatically accepted when in native mode.', 'amp' ); ?></p>
|
| 265 |
+
</div>
|
| 266 |
+
<div class="amp-auto-accept-sanitize">
|
| 267 |
+
<p>
|
| 268 |
+
<label for="auto_accept_sanitization">
|
| 269 |
+
<input id="auto_accept_sanitization" type="checkbox" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[auto_accept_sanitization]' ); ?>" <?php checked( AMP_Options_Manager::get_option( 'auto_accept_sanitization' ) ); ?>>
|
| 270 |
+
<?php esc_html_e( 'Automatically accept sanitization for any newly encountered AMP validation errors.', 'amp' ); ?>
|
| 271 |
+
</label>
|
| 272 |
+
</p>
|
| 273 |
+
<p class="description">
|
| 274 |
+
<?php esc_html_e( 'This will ensure your responses are always valid AMP but some important content may get stripped out (e.g. scripts).', 'amp' ); ?>
|
| 275 |
+
<?php
|
| 276 |
+
echo wp_kses_post(
|
| 277 |
+
sprintf(
|
| 278 |
+
/* translators: %s is URL to validation errors screen */
|
| 279 |
+
__( 'Existing validation errors which you have already rejected will not be modified (you may want to consider <a href="%s">bulk-accepting them</a>).', 'amp' ),
|
| 280 |
+
esc_url(
|
| 281 |
+
add_query_arg(
|
| 282 |
+
array(
|
| 283 |
+
'taxonomy' => AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG,
|
| 284 |
+
'post_type' => AMP_Validated_URL_Post_Type::POST_TYPE_SLUG,
|
| 285 |
+
),
|
| 286 |
+
admin_url( 'edit-tags.php' )
|
| 287 |
+
)
|
| 288 |
+
)
|
| 289 |
+
)
|
| 290 |
+
)
|
| 291 |
+
?>
|
| 292 |
+
</p>
|
| 293 |
+
</div>
|
| 294 |
+
<?php endif; ?>
|
| 295 |
+
|
| 296 |
+
<?php if ( $forced_tree_shaking ) : ?>
|
| 297 |
+
<input type="hidden" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[accept_tree_shaking]' ); ?>" value="<?php echo AMP_Options_Manager::get_option( 'accept_tree_shaking' ) ? 'on' : ''; ?>">
|
| 298 |
+
<?php else : ?>
|
| 299 |
+
<div class="amp-tree-shaking">
|
| 300 |
+
<p>
|
| 301 |
+
<label for="accept_tree_shaking">
|
| 302 |
+
<input id="accept_tree_shaking" type="checkbox" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[accept_tree_shaking]' ); ?>" <?php checked( AMP_Options_Manager::get_option( 'accept_tree_shaking' ) ); ?>>
|
| 303 |
+
<?php esc_html_e( 'Automatically remove CSS rules that are not relevant to a given page (tree shaking).', 'amp' ); ?>
|
| 304 |
+
</label>
|
| 305 |
+
</p>
|
| 306 |
+
<p class="description">
|
| 307 |
+
<?php esc_html_e( 'AMP limits the total amount of CSS to no more than 50KB; if you have more, than it is a validation error. The need to tree shake the CSS is not done by default because in some situations (in particular for dynamic content) it can result in CSS rules being removed that are needed.', 'amp' ); ?>
|
| 308 |
+
</p>
|
| 309 |
+
</div>
|
| 310 |
+
<?php endif; ?>
|
| 311 |
+
|
| 312 |
+
<script>
|
| 313 |
+
(function( $ ) {
|
| 314 |
+
var getThemeSupportMode = function() {
|
| 315 |
+
var checkedInput = $( 'input[type=radio][name="amp-options[theme_support]"]:checked' );
|
| 316 |
+
if ( 0 === checkedInput.length ) {
|
| 317 |
+
return <?php echo wp_json_encode( amp_is_canonical() ? 'native' : 'paired' ); ?>;
|
| 318 |
+
}
|
| 319 |
+
return checkedInput.val();
|
| 320 |
+
};
|
| 321 |
+
|
| 322 |
+
var updateTreeShakingHiddenClass = function() {
|
| 323 |
+
var checkbox = $( '#auto_accept_sanitization' );
|
| 324 |
+
$( '.amp-tree-shaking' ).toggleClass( 'hidden', checkbox.prop( 'checked' ) && 'native' !== getThemeSupportMode() );
|
| 325 |
+
};
|
| 326 |
+
|
| 327 |
+
var updateHiddenClasses = function() {
|
| 328 |
+
var themeSupportMode = getThemeSupportMode();
|
| 329 |
+
$( '.amp-auto-accept-sanitize' ).toggleClass( 'hidden', 'native' === themeSupportMode );
|
| 330 |
+
$( '.amp-validation-field' ).toggleClass( 'hidden', 'disabled' === themeSupportMode );
|
| 331 |
+
$( '.amp-auto-accept-sanitize-canonical' ).toggleClass( 'hidden', 'native' !== themeSupportMode );
|
| 332 |
+
updateTreeShakingHiddenClass();
|
| 333 |
+
};
|
| 334 |
+
|
| 335 |
+
$( 'input[type=radio][name="amp-options[theme_support]"]' ).change( updateHiddenClasses );
|
| 336 |
+
$( '#auto_accept_sanitization' ).change( updateTreeShakingHiddenClass );
|
| 337 |
+
|
| 338 |
+
updateHiddenClasses();
|
| 339 |
+
})( jQuery );
|
| 340 |
+
</script>
|
| 341 |
+
|
| 342 |
+
<p>
|
| 343 |
+
<label for="disable_admin_bar">
|
| 344 |
+
<input id="disable_admin_bar" type="checkbox" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[disable_admin_bar]' ); ?>" <?php checked( AMP_Options_Manager::get_option( 'disable_admin_bar' ) ); ?>>
|
| 345 |
+
<?php esc_html_e( 'Disable admin bar on AMP pages.', 'amp' ); ?>
|
| 346 |
+
</label>
|
| 347 |
+
</p>
|
| 348 |
+
<p class="description">
|
| 349 |
+
<?php esc_html_e( 'An additional stylesheet is required to properly render the admin bar. If the additional stylesheet causes the total CSS to surpass 50KB then the admin bar should be disabled to prevent a validation error or an unstyled admin bar in AMP responses.', 'amp' ); ?>
|
| 350 |
+
</p>
|
| 351 |
+
</fieldset>
|
| 352 |
+
<?php
|
| 353 |
+
}
|
| 354 |
+
|
| 355 |
+
/**
|
| 356 |
+
* Supported templates section renderer.
|
| 357 |
+
*
|
| 358 |
+
* @since 1.0
|
| 359 |
*/
|
| 360 |
+
public function render_supported_templates() {
|
| 361 |
+
$theme_support_args = AMP_Theme_Support::get_theme_support_args();
|
|
|
|
| 362 |
?>
|
| 363 |
+
|
| 364 |
+
<?php if ( ! isset( $theme_support_args['available_callback'] ) ) : ?>
|
| 365 |
+
<fieldset id="all_templates_supported_fieldset" <?php disabled( ! current_user_can( 'manage_options' ) ); ?>>
|
| 366 |
+
<?php if ( isset( $theme_support_args['templates_supported'] ) && 'all' === $theme_support_args['templates_supported'] ) : ?>
|
| 367 |
+
<div class="notice notice-info notice-alt inline">
|
| 368 |
+
<p>
|
| 369 |
+
<?php esc_html_e( 'The current theme requires all templates to support AMP.', 'amp' ); ?>
|
| 370 |
+
</p>
|
| 371 |
+
</div>
|
| 372 |
+
<?php else : ?>
|
| 373 |
+
<p>
|
| 374 |
+
<label for="all_templates_supported">
|
| 375 |
+
<input id="all_templates_supported" type="checkbox" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[all_templates_supported]' ); ?>" <?php checked( AMP_Options_Manager::get_option( 'all_templates_supported' ) ); ?>>
|
| 376 |
+
<?php esc_html_e( 'Serve all templates as AMP regardless of what is being queried.', 'amp' ); ?>
|
| 377 |
+
</label>
|
| 378 |
+
</p>
|
| 379 |
+
<p class="description">
|
| 380 |
+
<?php esc_html_e( 'This will allow all of the URLs on your site to be served as AMP by default.', 'amp' ); ?>
|
| 381 |
+
</p>
|
| 382 |
+
<?php endif; ?>
|
| 383 |
+
</fieldset>
|
| 384 |
+
<?php else : ?>
|
| 385 |
+
<div class="notice notice-warning notice-alt inline">
|
| 386 |
+
<p>
|
| 387 |
+
<?php esc_html_e( 'Your theme is using the deprecated available_callback argument for AMP theme support.', 'amp' ); ?>
|
| 388 |
+
</p>
|
| 389 |
+
</div>
|
| 390 |
+
<?php endif; ?>
|
| 391 |
+
|
| 392 |
+
<fieldset id="supported_post_types_fieldset" <?php disabled( ! current_user_can( 'manage_options' ) ); ?>>
|
| 393 |
+
<?php $element_name = AMP_Options_Manager::OPTION_NAME . '[supported_post_types][]'; ?>
|
| 394 |
+
<h4 class="title"><?php esc_html_e( 'Content Types', 'amp' ); ?></h4>
|
| 395 |
+
<p>
|
| 396 |
+
<?php esc_html_e( 'The following content types will be available as AMP:', 'amp' ); ?>
|
| 397 |
+
</p>
|
| 398 |
+
<ul>
|
| 399 |
<?php foreach ( array_map( 'get_post_type_object', AMP_Post_Type_Support::get_eligible_post_types() ) as $post_type ) : ?>
|
| 400 |
+
<li>
|
| 401 |
+
<?php $element_id = AMP_Options_Manager::OPTION_NAME . "-supported_post_types-{$post_type->name}"; ?>
|
| 402 |
+
<input
|
| 403 |
+
type="checkbox"
|
| 404 |
+
id="<?php echo esc_attr( $element_id ); ?>"
|
| 405 |
+
name="<?php echo esc_attr( $element_name ); ?>"
|
| 406 |
+
value="<?php echo esc_attr( $post_type->name ); ?>"
|
| 407 |
+
<?php checked( post_type_supports( $post_type->name, AMP_Post_Type_Support::SLUG ) ); ?>
|
| 408 |
+
>
|
| 409 |
+
<label for="<?php echo esc_attr( $element_id ); ?>">
|
| 410 |
+
<?php echo esc_html( $post_type->label ); ?>
|
| 411 |
+
</label>
|
| 412 |
+
</li>
|
| 413 |
+
<?php endforeach; ?>
|
| 414 |
+
</ul>
|
| 415 |
+
</fieldset>
|
| 416 |
+
|
| 417 |
+
<?php if ( ! isset( $theme_support_args['available_callback'] ) ) : ?>
|
| 418 |
+
<fieldset id="supported_templates_fieldset" <?php disabled( ! current_user_can( 'manage_options' ) ); ?>>
|
| 419 |
+
<style>
|
| 420 |
+
#supported_templates_fieldset ul ul {
|
| 421 |
+
margin-left: 40px;
|
| 422 |
+
}
|
| 423 |
+
</style>
|
| 424 |
+
<h4 class="title"><?php esc_html_e( 'Templates', 'amp' ); ?></h4>
|
| 425 |
<?php
|
| 426 |
+
self::list_template_conditional_options( AMP_Theme_Support::get_supportable_templates() );
|
|
|
|
| 427 |
?>
|
| 428 |
+
<script>
|
| 429 |
+
// Let clicks on parent items automatically cause the children checkboxes to have same checked state applied.
|
| 430 |
+
(function ( $ ) {
|
| 431 |
+
$( '#supported_templates_fieldset input[type=checkbox]' ).on( 'click', function() {
|
| 432 |
+
$( this ).siblings( 'ul' ).find( 'input[type=checkbox]' ).prop( 'checked', this.checked );
|
| 433 |
+
} );
|
| 434 |
+
})( jQuery );
|
| 435 |
+
</script>
|
| 436 |
+
</fieldset>
|
| 437 |
+
|
| 438 |
+
<script>
|
| 439 |
+
// Update the visibility of the fieldsets based on the selected template mode and then whether all templates are indicated to be supported.
|
| 440 |
+
(function ( $ ) {
|
| 441 |
+
var templateModeInputs, themeSupportDisabledInput, allTemplatesSupportedInput, supportForced;
|
| 442 |
+
templateModeInputs = $( 'input[type=radio][name="amp-options[theme_support]"]' );
|
| 443 |
+
themeSupportDisabledInput = $( '#theme_support_disabled' );
|
| 444 |
+
allTemplatesSupportedInput = $( '#all_templates_supported' );
|
| 445 |
+
supportForced = <?php echo wp_json_encode( current_theme_supports( AMP_Theme_Support::SLUG ) && ! AMP_Theme_Support::is_support_added_via_option() ); ?>;
|
| 446 |
+
|
| 447 |
+
function isThemeSupportDisabled() {
|
| 448 |
+
return ! supportForced && themeSupportDisabledInput.prop( 'checked' );
|
| 449 |
+
}
|
| 450 |
+
|
| 451 |
+
function updateFieldsetVisibility() {
|
| 452 |
+
var allTemplatesSupported = 0 === allTemplatesSupportedInput.length || allTemplatesSupportedInput.prop( 'checked' );
|
| 453 |
+
$( '#all_templates_supported_fieldset, #supported_post_types_fieldset > .title' ).toggleClass(
|
| 454 |
+
'hidden',
|
| 455 |
+
isThemeSupportDisabled()
|
| 456 |
+
);
|
| 457 |
+
$( '#supported_post_types_fieldset' ).toggleClass(
|
| 458 |
+
'hidden',
|
| 459 |
+
allTemplatesSupported && ! isThemeSupportDisabled()
|
| 460 |
+
);
|
| 461 |
+
$( '#supported_templates_fieldset' ).toggleClass(
|
| 462 |
+
'hidden',
|
| 463 |
+
allTemplatesSupported || isThemeSupportDisabled()
|
| 464 |
+
);
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
templateModeInputs.on( 'change', updateFieldsetVisibility );
|
| 468 |
+
allTemplatesSupportedInput.on( 'click', updateFieldsetVisibility );
|
| 469 |
+
updateFieldsetVisibility();
|
| 470 |
+
})( jQuery );
|
| 471 |
+
</script>
|
| 472 |
+
<?php endif; ?>
|
| 473 |
+
<?php
|
| 474 |
+
}
|
| 475 |
+
|
| 476 |
+
/**
|
| 477 |
+
* Render the caching settings section.
|
| 478 |
+
*
|
| 479 |
+
* @since 1.0
|
| 480 |
+
*
|
| 481 |
+
* @todo Change the messaging and description to be user-friendly and helpful.
|
| 482 |
+
*/
|
| 483 |
+
public function render_caching() {
|
| 484 |
+
?>
|
| 485 |
+
<fieldset <?php disabled( ! current_user_can( 'manage_options' ) ); ?>>
|
| 486 |
+
<?php if ( AMP_Options_Manager::show_response_cache_disabled_notice() ) : ?>
|
| 487 |
+
<div class="notice notice-info notice-alt inline">
|
| 488 |
+
<p><?php esc_html_e( 'The post-processor cache was disabled due to detecting randomly generated content found on', 'amp' ); ?> <a href="<?php echo esc_url( get_option( AMP_Theme_Support::CACHE_MISS_URL_OPTION, '' ) ); ?>"><?php esc_html_e( 'on this web page.', 'amp' ); ?></a></p>
|
| 489 |
+
<p><?php esc_html_e( 'Randomly generated content was detected on this web page. To avoid filling up the cache with unusable content, the AMP plugin\'s post-processor cache was automatically disabled.', 'amp' ); ?>
|
| 490 |
+
<a href="<?php echo esc_url( 'https://github.com/ampproject/amp-wp/wiki/Post-Processor-Cache' ); ?>"><?php esc_html_e( 'Read more', 'amp' ); ?></a>.</p>
|
| 491 |
+
</div>
|
| 492 |
+
<?php endif; ?>
|
| 493 |
+
<p>
|
| 494 |
+
<label for="enable_response_caching">
|
| 495 |
+
<input id="enable_response_caching" type="checkbox" name="<?php echo esc_attr( AMP_Options_Manager::OPTION_NAME . '[enable_response_caching]' ); ?>" <?php checked( AMP_Options_Manager::get_option( 'enable_response_caching' ) ); ?>>
|
| 496 |
+
<?php esc_html_e( 'Enable post-processor caching.', 'amp' ); ?>
|
| 497 |
</label>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 498 |
</p>
|
| 499 |
+
<p class="description"><?php esc_html_e( 'This will enable post-processor caching to speed up processing an AMP response after WordPress renders a template.', 'amp' ); ?></p>
|
| 500 |
</fieldset>
|
| 501 |
<?php
|
| 502 |
}
|
| 503 |
|
| 504 |
+
/**
|
| 505 |
+
* List template conditional options.
|
| 506 |
+
*
|
| 507 |
+
* @param array $options Options.
|
| 508 |
+
* @param string|null $parent ID of the parent option.
|
| 509 |
+
*/
|
| 510 |
+
private function list_template_conditional_options( $options, $parent = null ) {
|
| 511 |
+
$element_name = AMP_Options_Manager::OPTION_NAME . '[supported_templates][]';
|
| 512 |
+
?>
|
| 513 |
+
<ul>
|
| 514 |
+
<?php foreach ( $options as $id => $option ) : ?>
|
| 515 |
+
<?php
|
| 516 |
+
$element_id = AMP_Options_Manager::OPTION_NAME . '-supported-templates-' . $id;
|
| 517 |
+
if ( $parent ? empty( $option['parent'] ) || $parent !== $option['parent'] : ! empty( $option['parent'] ) ) {
|
| 518 |
+
continue;
|
| 519 |
+
}
|
| 520 |
+
|
| 521 |
+
// Skip showing an option if it doesn't have a label.
|
| 522 |
+
if ( empty( $option['label'] ) ) {
|
| 523 |
+
continue;
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
?>
|
| 527 |
+
<li>
|
| 528 |
+
<?php if ( empty( $option['immutable'] ) ) : ?>
|
| 529 |
+
<input
|
| 530 |
+
type="checkbox"
|
| 531 |
+
id="<?php echo esc_attr( $element_id ); ?>"
|
| 532 |
+
name="<?php echo esc_attr( $element_name ); ?>"
|
| 533 |
+
value="<?php echo esc_attr( $id ); ?>"
|
| 534 |
+
<?php checked( ! empty( $option['user_supported'] ) ); ?>
|
| 535 |
+
>
|
| 536 |
+
<?php else : // Persist user selection even when checkbox disabled, when selection forced by theme/filter. ?>
|
| 537 |
+
<input
|
| 538 |
+
type="checkbox"
|
| 539 |
+
id="<?php echo esc_attr( $element_id ); ?>"
|
| 540 |
+
<?php checked( ! empty( $option['supported'] ) ); ?>
|
| 541 |
+
<?php disabled( true ); ?>
|
| 542 |
+
>
|
| 543 |
+
<?php if ( ! empty( $option['user_supported'] ) ) : ?>
|
| 544 |
+
<input type="hidden" name="<?php echo esc_attr( $element_name ); ?>" value="<?php echo esc_attr( $id ); ?>">
|
| 545 |
+
<?php endif; ?>
|
| 546 |
+
<?php endif; ?>
|
| 547 |
+
<label for="<?php echo esc_attr( $element_id ); ?>">
|
| 548 |
+
<?php echo esc_html( $option['label'] ); ?>
|
| 549 |
+
</label>
|
| 550 |
+
|
| 551 |
+
<?php if ( ! empty( $option['description'] ) ) : ?>
|
| 552 |
+
<span class="description">
|
| 553 |
+
— <?php echo wp_kses_post( $option['description'] ); ?>
|
| 554 |
+
</span>
|
| 555 |
+
<?php endif; ?>
|
| 556 |
+
|
| 557 |
+
<?php self::list_template_conditional_options( $options, $id ); ?>
|
| 558 |
+
</li>
|
| 559 |
+
<?php endforeach; ?>
|
| 560 |
+
</ul>
|
| 561 |
+
<?php
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
/**
|
| 565 |
* Display Settings.
|
| 566 |
*
|
| 571 |
AMP_Options_Manager::check_supported_post_type_update_errors();
|
| 572 |
}
|
| 573 |
?>
|
| 574 |
+
<?php if ( ! current_user_can( 'manage_options' ) ) : ?>
|
| 575 |
+
<div class="notice notice-info">
|
| 576 |
+
<p><?php esc_html_e( 'You do not have permission to modify these settings. They are shown here for your reference. Please contact your administrator to make changes.', 'amp' ); ?></p>
|
| 577 |
+
</div>
|
| 578 |
+
<?php endif; ?>
|
| 579 |
<div class="wrap">
|
| 580 |
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
| 581 |
<?php settings_errors(); ?>
|
| 582 |
+
<form id="amp-settings" action="options.php" method="post">
|
| 583 |
<?php
|
| 584 |
settings_fields( AMP_Options_Manager::OPTION_NAME );
|
| 585 |
do_settings_sections( AMP_Options_Manager::OPTION_NAME );
|
| 586 |
+
if ( current_user_can( 'manage_options' ) ) {
|
| 587 |
submit_button();
|
| 588 |
}
|
| 589 |
?>
|
|
@@ -17,18 +17,24 @@ class AMP_Analytics_Options_Submenu_Page {
|
|
| 17 |
* @param string $type Entry type.
|
| 18 |
* @param string $config Entry config as serialized JSON.
|
| 19 |
*/
|
| 20 |
-
private function render_entry( $id = '', $type = '', $config = '' ) {
|
| 21 |
$is_existing_entry = ! empty( $id );
|
| 22 |
|
| 23 |
if ( $is_existing_entry ) {
|
| 24 |
$entry_slug = sprintf( '%s%s', ( $type ? $type . '-' : '' ), substr( $id, - 6 ) );
|
| 25 |
-
/* translators: %s
|
| 26 |
$analytics_title = sprintf( __( 'Analytics: %s', 'amp' ), $entry_slug );
|
| 27 |
} else {
|
| 28 |
$analytics_title = __( 'Add new entry:', 'amp' );
|
| 29 |
$id = '__new__';
|
| 30 |
}
|
| 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
$id_base = sprintf( '%s[analytics][%s]', AMP_Options_Manager::OPTION_NAME, $id );
|
| 33 |
?>
|
| 34 |
<div class="analytics-data-container">
|
|
@@ -40,7 +46,7 @@ class AMP_Analytics_Options_Submenu_Page {
|
|
| 40 |
<p>
|
| 41 |
<label>
|
| 42 |
<?php esc_html_e( 'Type:', 'amp' ); ?>
|
| 43 |
-
<input class="option-input" type="text" name="<?php echo esc_attr( $id_base . '[type]' ); ?>" value="<?php echo esc_attr( $type ); ?>" />
|
| 44 |
</label>
|
| 45 |
<label>
|
| 46 |
<?php esc_html_e( 'ID:', 'amp' ); ?>
|
|
@@ -52,7 +58,15 @@ class AMP_Analytics_Options_Submenu_Page {
|
|
| 52 |
<label>
|
| 53 |
<?php esc_html_e( 'JSON Configuration:', 'amp' ); ?>
|
| 54 |
<br />
|
| 55 |
-
<textarea
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
</label>
|
| 57 |
</p>
|
| 58 |
<input type="hidden" name="action" value="amp_analytics_options">
|
|
@@ -73,23 +87,92 @@ class AMP_Analytics_Options_Submenu_Page {
|
|
| 73 |
|
| 74 |
/**
|
| 75 |
* Render title.
|
|
|
|
|
|
|
| 76 |
*/
|
| 77 |
-
public function render_title() {
|
| 78 |
?>
|
| 79 |
<div class="wrap">
|
| 80 |
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
| 81 |
<?php settings_errors(); ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
</div><!-- .wrap -->
|
| 83 |
<?php
|
| 84 |
}
|
| 85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
/**
|
| 87 |
* Render.
|
| 88 |
*/
|
| 89 |
public function render() {
|
|
|
|
|
|
|
| 90 |
$analytics_entries = AMP_Options_Manager::get_option( 'analytics', array() );
|
| 91 |
|
| 92 |
-
$this->render_title();
|
| 93 |
|
| 94 |
// Render entries stored in the DB.
|
| 95 |
foreach ( $analytics_entries as $entry_id => $entry ) {
|
|
@@ -98,5 +181,7 @@ class AMP_Analytics_Options_Submenu_Page {
|
|
| 98 |
|
| 99 |
// Empty form for adding more entries.
|
| 100 |
$this->render_entry();
|
|
|
|
|
|
|
| 101 |
}
|
| 102 |
}
|
| 17 |
* @param string $type Entry type.
|
| 18 |
* @param string $config Entry config as serialized JSON.
|
| 19 |
*/
|
| 20 |
+
private function render_entry( $id = '', $type = '', $config = '{}' ) {
|
| 21 |
$is_existing_entry = ! empty( $id );
|
| 22 |
|
| 23 |
if ( $is_existing_entry ) {
|
| 24 |
$entry_slug = sprintf( '%s%s', ( $type ? $type . '-' : '' ), substr( $id, - 6 ) );
|
| 25 |
+
/* translators: %s: the entry slug. */
|
| 26 |
$analytics_title = sprintf( __( 'Analytics: %s', 'amp' ), $entry_slug );
|
| 27 |
} else {
|
| 28 |
$analytics_title = __( 'Add new entry:', 'amp' );
|
| 29 |
$id = '__new__';
|
| 30 |
}
|
| 31 |
|
| 32 |
+
// Tidy-up the JSON for display.
|
| 33 |
+
if ( $config ) {
|
| 34 |
+
$options = ( 128 /* JSON_PRETTY_PRINT */ | 64 /* JSON_UNESCAPED_SLASHES */ );
|
| 35 |
+
$config = wp_json_encode( json_decode( $config ), $options );
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
$id_base = sprintf( '%s[analytics][%s]', AMP_Options_Manager::OPTION_NAME, $id );
|
| 39 |
?>
|
| 40 |
<div class="analytics-data-container">
|
| 46 |
<p>
|
| 47 |
<label>
|
| 48 |
<?php esc_html_e( 'Type:', 'amp' ); ?>
|
| 49 |
+
<input class="option-input" type="text" required name="<?php echo esc_attr( $id_base . '[type]' ); ?>" placeholder="<?php esc_attr_e( 'e.g. googleanalytics', 'amp' ); ?>" value="<?php echo esc_attr( $type ); ?>" />
|
| 50 |
</label>
|
| 51 |
<label>
|
| 52 |
<?php esc_html_e( 'ID:', 'amp' ); ?>
|
| 58 |
<label>
|
| 59 |
<?php esc_html_e( 'JSON Configuration:', 'amp' ); ?>
|
| 60 |
<br />
|
| 61 |
+
<textarea
|
| 62 |
+
rows="10"
|
| 63 |
+
cols="100"
|
| 64 |
+
name="<?php echo esc_attr( $id_base . '[config]' ); ?>"
|
| 65 |
+
class="amp-analytics-input"
|
| 66 |
+
placeholder="{...}"
|
| 67 |
+
title="<?php esc_attr_e( 'A JSON object begins with a “{” and ends with a “}”. Do not include any HTML tags like "<amp-analytics>" or "<script>".', 'amp' ); ?>"
|
| 68 |
+
required
|
| 69 |
+
><?php echo esc_textarea( $config ); ?></textarea>
|
| 70 |
</label>
|
| 71 |
</p>
|
| 72 |
<input type="hidden" name="action" value="amp_analytics_options">
|
| 87 |
|
| 88 |
/**
|
| 89 |
* Render title.
|
| 90 |
+
*
|
| 91 |
+
* @param bool $has_entries Whether there are entries.
|
| 92 |
*/
|
| 93 |
+
public function render_title( $has_entries = false ) {
|
| 94 |
?>
|
| 95 |
<div class="wrap">
|
| 96 |
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
| 97 |
<?php settings_errors(); ?>
|
| 98 |
+
|
| 99 |
+
<details <?php echo ! $has_entries ? 'open' : ''; ?>>
|
| 100 |
+
<summary>
|
| 101 |
+
<?php esc_html_e( 'Learn about analytics for AMP.', 'amp' ); ?>
|
| 102 |
+
</summary>
|
| 103 |
+
<p>
|
| 104 |
+
<?php echo wp_kses_post( __( 'For Google Analytics, please see <a href="https://developers.google.com/analytics/devguides/collection/amp-analytics/" target="_blank">Adding Analytics to your AMP pages</a>; see also the <a href="https://github.com/ampproject/amp-wp/wiki/Analytics" target="_blank">Analytics wiki page</a> and the AMP project\'s <a href="https://www.ampproject.org/docs/reference/components/amp-analytics" target="_blank">amp-analytics documentation</a>. The analytics configuration supplied below must take the form of JSON objects, which begin with a “{” and end with a “}”. Do not include any HTML tags like “<code><amp-analytics></code>” or “<code><script></code>”. A common entry would have the type “<code>googleanalytics</code>” (see <a href="https://www.ampproject.org/docs/analytics/analytics-vendors" target="_blank">available vendors</a>) and a configuration that looks like the following (where <code>UA-XXXXX-Y</code> is replaced with your own site\'s account number):', 'amp' ) ); ?>
|
| 105 |
+
|
| 106 |
+
<pre>{
|
| 107 |
+
"vars": {
|
| 108 |
+
"account": "UA-XXXXX-Y"
|
| 109 |
+
},
|
| 110 |
+
"triggers": {
|
| 111 |
+
"trackPageview": {
|
| 112 |
+
"on": "visible",
|
| 113 |
+
"request": "pageview"
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
}</pre>
|
| 117 |
+
</p>
|
| 118 |
+
</details>
|
| 119 |
</div><!-- .wrap -->
|
| 120 |
<?php
|
| 121 |
}
|
| 122 |
|
| 123 |
+
/**
|
| 124 |
+
* Render styles.
|
| 125 |
+
*/
|
| 126 |
+
protected function render_styles() {
|
| 127 |
+
?>
|
| 128 |
+
<style>
|
| 129 |
+
.amp-analytics-input {
|
| 130 |
+
font-family: monospace;
|
| 131 |
+
}
|
| 132 |
+
.amp-analytics-input:invalid {
|
| 133 |
+
border-color: red;
|
| 134 |
+
}
|
| 135 |
+
</style>
|
| 136 |
+
<?php
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
/**
|
| 140 |
+
* Render scripts.
|
| 141 |
+
*/
|
| 142 |
+
protected function render_scripts() {
|
| 143 |
+
?>
|
| 144 |
+
<script>
|
| 145 |
+
Array.prototype.forEach.call( document.querySelectorAll( '.amp-analytics-input' ), function( textarea ) {
|
| 146 |
+
textarea.addEventListener( 'input', function() {
|
| 147 |
+
if ( ! this.value ) {
|
| 148 |
+
this.setCustomValidity( '' );
|
| 149 |
+
return;
|
| 150 |
+
}
|
| 151 |
+
try {
|
| 152 |
+
var value = JSON.parse( this.value );
|
| 153 |
+
if ( null === value || typeof value !== 'object' || Array.isArray( value ) ) {
|
| 154 |
+
this.setCustomValidity( <?php echo wp_json_encode( __( 'A JSON object is required, e.g. {...}', 'amp' ) ); ?> )
|
| 155 |
+
} else {
|
| 156 |
+
this.setCustomValidity( '' );
|
| 157 |
+
}
|
| 158 |
+
} catch ( e ) {
|
| 159 |
+
this.setCustomValidity( e.message )
|
| 160 |
+
}
|
| 161 |
+
} );
|
| 162 |
+
} );
|
| 163 |
+
</script>
|
| 164 |
+
<?php
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
/**
|
| 168 |
* Render.
|
| 169 |
*/
|
| 170 |
public function render() {
|
| 171 |
+
$this->render_styles();
|
| 172 |
+
|
| 173 |
$analytics_entries = AMP_Options_Manager::get_option( 'analytics', array() );
|
| 174 |
|
| 175 |
+
$this->render_title( ! empty( $analytics_entries ) );
|
| 176 |
|
| 177 |
// Render entries stored in the DB.
|
| 178 |
foreach ( $analytics_entries as $entry_id => $entry ) {
|
| 181 |
|
| 182 |
// Empty form for adding more entries.
|
| 183 |
$this->render_entry();
|
| 184 |
+
|
| 185 |
+
$this->render_scripts();
|
| 186 |
}
|
| 187 |
}
|
|
@@ -13,8 +13,8 @@
|
|
| 13 |
*/
|
| 14 |
class AMP_Allowed_Tags_Generated {
|
| 15 |
|
| 16 |
-
private static $spec_file_revision =
|
| 17 |
-
private static $minimum_validator_revision_required =
|
| 18 |
|
| 19 |
private static $allowed_tags = array(
|
| 20 |
'a' => array(
|
|
@@ -27,14 +27,14 @@ class AMP_Allowed_Tags_Generated {
|
|
| 27 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 28 |
'value_url' => array(
|
| 29 |
'allow_empty' => true,
|
| 30 |
-
'
|
| 31 |
-
'allowed_protocol' => array(
|
| 32 |
'ftp',
|
| 33 |
'geo',
|
| 34 |
'http',
|
| 35 |
'https',
|
| 36 |
'mailto',
|
| 37 |
'maps',
|
|
|
|
| 38 |
'bbmi',
|
| 39 |
'fb-messenger',
|
| 40 |
'intent',
|
|
@@ -47,6 +47,8 @@ class AMP_Allowed_Tags_Generated {
|
|
| 47 |
'threema',
|
| 48 |
'twitter',
|
| 49 |
'viber',
|
|
|
|
|
|
|
| 50 |
'whatsapp',
|
| 51 |
),
|
| 52 |
),
|
|
@@ -61,10 +63,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 61 |
'role' => array(),
|
| 62 |
'tabindex' => array(),
|
| 63 |
'target' => array(
|
| 64 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
),
|
| 66 |
'type' => array(
|
| 67 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 68 |
),
|
| 69 |
),
|
| 70 |
'tag_spec' => array(
|
|
@@ -90,21 +98,95 @@ class AMP_Allowed_Tags_Generated {
|
|
| 90 |
'tag_spec' => array(),
|
| 91 |
),
|
| 92 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
'amp-3q-player' => array(
|
| 94 |
array(
|
| 95 |
'attr_spec_list' => array(
|
| 96 |
'autoplay' => array(
|
| 97 |
-
'value' =>
|
|
|
|
|
|
|
| 98 |
),
|
| 99 |
'data-id' => array(
|
| 100 |
'mandatory' => true,
|
| 101 |
),
|
| 102 |
'media' => array(),
|
| 103 |
'noloading' => array(
|
| 104 |
-
'value' =>
|
|
|
|
|
|
|
| 105 |
),
|
| 106 |
),
|
| 107 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
'requires_extension' => array(
|
| 109 |
'amp-3q-player',
|
| 110 |
),
|
|
@@ -114,14 +196,34 @@ class AMP_Allowed_Tags_Generated {
|
|
| 114 |
'amp-accordion' => array(
|
| 115 |
array(
|
| 116 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
'disable-session-states' => array(
|
| 118 |
-
'value' =>
|
|
|
|
|
|
|
| 119 |
),
|
| 120 |
'expand-single-section' => array(
|
| 121 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
),
|
| 123 |
),
|
| 124 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
'requires_extension' => array(
|
| 126 |
'amp-accordion',
|
| 127 |
),
|
|
@@ -136,14 +238,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 136 |
'json' => array(),
|
| 137 |
'media' => array(),
|
| 138 |
'noloading' => array(
|
| 139 |
-
'value' =>
|
|
|
|
|
|
|
| 140 |
),
|
| 141 |
'rtc-config' => array(),
|
| 142 |
'src' => array(
|
| 143 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 144 |
'value_url' => array(
|
| 145 |
'allow_relative' => true,
|
| 146 |
-
'
|
| 147 |
'https',
|
| 148 |
),
|
| 149 |
),
|
|
@@ -157,6 +261,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 157 |
'also_requires_tag_warning' => array(
|
| 158 |
'amp-ad extension .js script',
|
| 159 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
'disallowed_ancestor' => array(
|
| 161 |
'amp-app-banner',
|
| 162 |
),
|
|
@@ -172,19 +288,23 @@ class AMP_Allowed_Tags_Generated {
|
|
| 172 |
'data-multi-size' => array(
|
| 173 |
'dispatch_key' => 2,
|
| 174 |
'mandatory' => true,
|
| 175 |
-
'value' =>
|
|
|
|
|
|
|
| 176 |
),
|
| 177 |
'json' => array(),
|
| 178 |
'media' => array(),
|
| 179 |
'noloading' => array(
|
| 180 |
-
'value' =>
|
|
|
|
|
|
|
| 181 |
),
|
| 182 |
'rtc-config' => array(),
|
| 183 |
'src' => array(
|
| 184 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 185 |
'value_url' => array(
|
| 186 |
'allow_relative' => true,
|
| 187 |
-
'
|
| 188 |
'https',
|
| 189 |
),
|
| 190 |
),
|
|
@@ -197,6 +317,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 197 |
'also_requires_tag_warning' => array(
|
| 198 |
'amp-ad extension .js script',
|
| 199 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
'disallowed_ancestor' => array(
|
| 201 |
'amp-app-banner',
|
| 202 |
'amp-carousel',
|
|
@@ -217,18 +349,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 217 |
'data-enable-refresh' => array(
|
| 218 |
'dispatch_key' => 2,
|
| 219 |
'mandatory' => true,
|
| 220 |
-
'value' =>
|
|
|
|
|
|
|
| 221 |
),
|
| 222 |
'json' => array(),
|
| 223 |
'media' => array(),
|
| 224 |
'noloading' => array(
|
| 225 |
-
'value' =>
|
|
|
|
|
|
|
| 226 |
),
|
| 227 |
'src' => array(
|
| 228 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 229 |
'value_url' => array(
|
| 230 |
'allow_relative' => true,
|
| 231 |
-
'
|
| 232 |
'https',
|
| 233 |
),
|
| 234 |
),
|
|
@@ -241,6 +377,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 241 |
'also_requires_tag_warning' => array(
|
| 242 |
'amp-ad extension .js script',
|
| 243 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
'disallowed_ancestor' => array(
|
| 245 |
'amp-app-banner',
|
| 246 |
'amp-fx-flying-carpet',
|
|
@@ -254,6 +402,57 @@ class AMP_Allowed_Tags_Generated {
|
|
| 254 |
),
|
| 255 |
),
|
| 256 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
'amp-analytics' => array(
|
| 258 |
array(
|
| 259 |
'attr_spec_list' => array(
|
|
@@ -262,7 +461,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 262 |
'value_url' => array(
|
| 263 |
'allow_empty' => true,
|
| 264 |
'allow_relative' => true,
|
| 265 |
-
'
|
| 266 |
'https',
|
| 267 |
),
|
| 268 |
),
|
|
@@ -282,10 +481,11 @@ class AMP_Allowed_Tags_Generated {
|
|
| 282 |
'attr_spec_list' => array(
|
| 283 |
'alt' => array(),
|
| 284 |
'attribution' => array(),
|
| 285 |
-
'controls' => array(),
|
| 286 |
'media' => array(),
|
| 287 |
'noloading' => array(
|
| 288 |
-
'value' =>
|
|
|
|
|
|
|
| 289 |
),
|
| 290 |
'src' => array(
|
| 291 |
'alternative_names' => array(
|
|
@@ -294,8 +494,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 294 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 295 |
'mandatory' => true,
|
| 296 |
'value_url' => array(
|
| 297 |
-
'
|
| 298 |
-
'allowed_protocol' => array(
|
| 299 |
'data',
|
| 300 |
'http',
|
| 301 |
'https',
|
|
@@ -304,6 +503,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 304 |
),
|
| 305 |
),
|
| 306 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
'requires_extension' => array(
|
| 308 |
'amp-anim',
|
| 309 |
),
|
|
@@ -316,13 +526,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 316 |
'attr_spec_list' => array(
|
| 317 |
'media' => array(),
|
| 318 |
'noloading' => array(
|
| 319 |
-
'value' =>
|
|
|
|
|
|
|
| 320 |
),
|
| 321 |
'trigger' => array(
|
| 322 |
-
'value' =>
|
|
|
|
|
|
|
| 323 |
),
|
| 324 |
),
|
| 325 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
'requires_extension' => array(
|
| 327 |
'amp-animation',
|
| 328 |
),
|
|
@@ -340,10 +559,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 340 |
),
|
| 341 |
'media' => array(),
|
| 342 |
'noloading' => array(
|
| 343 |
-
'value' =>
|
|
|
|
|
|
|
| 344 |
),
|
| 345 |
),
|
| 346 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 347 |
'requires_extension' => array(
|
| 348 |
'amp-apester-media',
|
| 349 |
),
|
|
@@ -359,10 +590,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 359 |
),
|
| 360 |
'media' => array(),
|
| 361 |
'noloading' => array(
|
| 362 |
-
'value' =>
|
|
|
|
|
|
|
| 363 |
),
|
| 364 |
),
|
| 365 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
'mandatory_parent' => 'body',
|
| 367 |
'requires_extension' => array(
|
| 368 |
'amp-app-banner',
|
|
@@ -379,34 +617,55 @@ class AMP_Allowed_Tags_Generated {
|
|
| 379 |
'artist' => array(),
|
| 380 |
'artwork' => array(),
|
| 381 |
'autoplay' => array(
|
| 382 |
-
'value' =>
|
|
|
|
|
|
|
| 383 |
),
|
| 384 |
'controls' => array(),
|
| 385 |
'controlslist' => array(),
|
| 386 |
'loop' => array(
|
| 387 |
-
'value' =>
|
|
|
|
|
|
|
| 388 |
),
|
| 389 |
'media' => array(),
|
| 390 |
'muted' => array(
|
| 391 |
-
'value' =>
|
|
|
|
|
|
|
| 392 |
),
|
| 393 |
'noloading' => array(
|
| 394 |
-
'value' =>
|
|
|
|
|
|
|
| 395 |
),
|
| 396 |
'preload' => array(
|
| 397 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 398 |
),
|
| 399 |
'src' => array(
|
| 400 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 401 |
'value_url' => array(
|
| 402 |
'allow_relative' => true,
|
| 403 |
-
'
|
| 404 |
'https',
|
| 405 |
),
|
| 406 |
),
|
| 407 |
),
|
| 408 |
),
|
| 409 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 410 |
'disallowed_ancestor' => array(
|
| 411 |
'amp-story',
|
| 412 |
),
|
|
@@ -423,31 +682,48 @@ class AMP_Allowed_Tags_Generated {
|
|
| 423 |
'artwork' => array(),
|
| 424 |
'autoplay' => array(
|
| 425 |
'mandatory' => true,
|
| 426 |
-
'value' =>
|
|
|
|
|
|
|
| 427 |
),
|
| 428 |
'controls' => array(),
|
| 429 |
'controlslist' => array(),
|
| 430 |
'loop' => array(
|
| 431 |
-
'value' =>
|
|
|
|
|
|
|
| 432 |
),
|
| 433 |
'media' => array(),
|
| 434 |
'muted' => array(
|
| 435 |
-
'value' =>
|
|
|
|
|
|
|
| 436 |
),
|
| 437 |
'noloading' => array(
|
| 438 |
-
'value' =>
|
|
|
|
|
|
|
| 439 |
),
|
| 440 |
'src' => array(
|
| 441 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 442 |
'value_url' => array(
|
| 443 |
'allow_relative' => true,
|
| 444 |
-
'
|
| 445 |
'https',
|
| 446 |
),
|
| 447 |
),
|
| 448 |
),
|
| 449 |
),
|
| 450 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
'mandatory_ancestor' => 'amp-story',
|
| 452 |
'requires_extension' => array(
|
| 453 |
'amp-audio',
|
|
@@ -462,14 +738,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 462 |
'attr_spec_list' => array(
|
| 463 |
'media' => array(),
|
| 464 |
'noloading' => array(
|
| 465 |
-
'value' =>
|
|
|
|
|
|
|
| 466 |
),
|
| 467 |
'type' => array(
|
| 468 |
'mandatory' => true,
|
| 469 |
),
|
| 470 |
),
|
| 471 |
'tag_spec' => array(
|
| 472 |
-
'
|
|
|
|
|
|
|
| 473 |
'requires_extension' => array(
|
| 474 |
'amp-auto-ads',
|
| 475 |
),
|
|
@@ -488,15 +768,31 @@ class AMP_Allowed_Tags_Generated {
|
|
| 488 |
'value_regex_casei' => '[0-9a-f]{24}',
|
| 489 |
),
|
| 490 |
'data-my-content' => array(
|
| 491 |
-
'
|
|
|
|
|
|
|
|
|
|
| 492 |
),
|
| 493 |
'data-name' => array(),
|
| 494 |
'media' => array(),
|
| 495 |
'noloading' => array(
|
| 496 |
-
'value' =>
|
|
|
|
|
|
|
| 497 |
),
|
| 498 |
),
|
| 499 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
'requires_extension' => array(
|
| 501 |
'amp-beopinion',
|
| 502 |
),
|
|
@@ -526,22 +822,44 @@ class AMP_Allowed_Tags_Generated {
|
|
| 526 |
array(
|
| 527 |
'attr_spec_list' => array(
|
| 528 |
'loop' => array(
|
| 529 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 530 |
),
|
| 531 |
'noautoplay' => array(
|
| 532 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 533 |
),
|
| 534 |
'src' => array(
|
| 535 |
'mandatory' => true,
|
| 536 |
'value_url' => array(
|
| 537 |
'allow_relative' => false,
|
| 538 |
-
'
|
| 539 |
'https',
|
| 540 |
),
|
| 541 |
),
|
| 542 |
),
|
| 543 |
),
|
| 544 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 545 |
'requires_extension' => array(
|
| 546 |
'amp-bodymovin-animation',
|
| 547 |
),
|
|
@@ -572,10 +890,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 572 |
),
|
| 573 |
'media' => array(),
|
| 574 |
'noloading' => array(
|
| 575 |
-
'value' =>
|
|
|
|
|
|
|
| 576 |
),
|
| 577 |
),
|
| 578 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 579 |
'requires_extension' => array(
|
| 580 |
'amp-brid-player',
|
| 581 |
),
|
|
@@ -591,16 +921,34 @@ class AMP_Allowed_Tags_Generated {
|
|
| 591 |
'[data-player-id]' => array(),
|
| 592 |
'[data-player]' => array(),
|
| 593 |
'[data-playlist-id]' => array(),
|
|
|
|
| 594 |
'[data-video-id]' => array(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 595 |
'data-account' => array(
|
| 596 |
'mandatory' => true,
|
| 597 |
),
|
| 598 |
'media' => array(),
|
| 599 |
'noloading' => array(
|
| 600 |
-
'value' =>
|
|
|
|
|
|
|
| 601 |
),
|
| 602 |
),
|
| 603 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 604 |
'requires_extension' => array(
|
| 605 |
'amp-brightcove',
|
| 606 |
),
|
|
@@ -619,10 +967,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 619 |
),
|
| 620 |
'media' => array(),
|
| 621 |
'noloading' => array(
|
| 622 |
-
'value' =>
|
|
|
|
|
|
|
| 623 |
),
|
| 624 |
),
|
| 625 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 626 |
'requires_extension' => array(
|
| 627 |
'amp-byside-content',
|
| 628 |
),
|
|
@@ -637,17 +997,29 @@ class AMP_Allowed_Tags_Generated {
|
|
| 637 |
'mandatory' => true,
|
| 638 |
'value_url' => array(
|
| 639 |
'allow_relative' => false,
|
| 640 |
-
'
|
| 641 |
'https',
|
| 642 |
),
|
| 643 |
),
|
| 644 |
),
|
| 645 |
'media' => array(),
|
| 646 |
'noloading' => array(
|
| 647 |
-
'value' =>
|
|
|
|
|
|
|
| 648 |
),
|
| 649 |
),
|
| 650 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 651 |
'requires_extension' => array(
|
| 652 |
'amp-call-tracking',
|
| 653 |
),
|
|
@@ -660,40 +1032,128 @@ class AMP_Allowed_Tags_Generated {
|
|
| 660 |
'attr_spec_list' => array(
|
| 661 |
'[slide]' => array(),
|
| 662 |
'arrows' => array(
|
| 663 |
-
'value' =>
|
|
|
|
|
|
|
| 664 |
),
|
| 665 |
'autoplay' => array(
|
| 666 |
-
'
|
| 667 |
),
|
| 668 |
'controls' => array(),
|
| 669 |
'delay' => array(
|
| 670 |
'value_regex' => '[0-9]+',
|
| 671 |
),
|
| 672 |
'dots' => array(
|
| 673 |
-
'value' =>
|
|
|
|
|
|
|
| 674 |
),
|
| 675 |
-
'
|
| 676 |
-
|
| 677 |
-
|
|
|
|
| 678 |
),
|
| 679 |
-
'
|
| 680 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 681 |
),
|
| 682 |
'loop' => array(
|
| 683 |
-
'value' =>
|
|
|
|
|
|
|
| 684 |
),
|
| 685 |
'media' => array(),
|
| 686 |
'noloading' => array(
|
| 687 |
-
'value' =>
|
|
|
|
|
|
|
| 688 |
),
|
| 689 |
'type' => array(
|
| 690 |
-
'
|
|
|
|
|
|
|
|
|
|
| 691 |
),
|
| 692 |
),
|
| 693 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 694 |
'requires_extension' => array(
|
| 695 |
'amp-carousel',
|
|
|
|
| 696 |
),
|
|
|
|
| 697 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-carousel',
|
| 698 |
),
|
| 699 |
),
|
|
@@ -703,10 +1163,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 703 |
'attr_spec_list' => array(
|
| 704 |
'media' => array(),
|
| 705 |
'noloading' => array(
|
| 706 |
-
'value' =>
|
|
|
|
|
|
|
| 707 |
),
|
| 708 |
),
|
| 709 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
'requires_extension' => array(
|
| 711 |
'amp-consent',
|
| 712 |
),
|
|
@@ -719,16 +1186,28 @@ class AMP_Allowed_Tags_Generated {
|
|
| 719 |
'attr_spec_list' => array(
|
| 720 |
'autoplay' => array(),
|
| 721 |
'data-endscreen-enable' => array(
|
| 722 |
-
'
|
|
|
|
|
|
|
|
|
|
| 723 |
),
|
| 724 |
'data-info' => array(
|
| 725 |
-
'
|
|
|
|
|
|
|
|
|
|
| 726 |
),
|
| 727 |
'data-mute' => array(
|
| 728 |
-
'
|
|
|
|
|
|
|
|
|
|
| 729 |
),
|
| 730 |
'data-sharing-enable' => array(
|
| 731 |
-
'
|
|
|
|
|
|
|
|
|
|
| 732 |
),
|
| 733 |
'data-start' => array(
|
| 734 |
'value_regex' => '[0-9]+',
|
|
@@ -737,7 +1216,10 @@ class AMP_Allowed_Tags_Generated {
|
|
| 737 |
'value_regex_casei' => '([0-9a-f]{3}){1,2}',
|
| 738 |
),
|
| 739 |
'data-ui-logo' => array(
|
| 740 |
-
'
|
|
|
|
|
|
|
|
|
|
| 741 |
),
|
| 742 |
'data-videoid' => array(
|
| 743 |
'mandatory' => true,
|
|
@@ -745,10 +1227,21 @@ class AMP_Allowed_Tags_Generated {
|
|
| 745 |
),
|
| 746 |
'media' => array(),
|
| 747 |
'noloading' => array(
|
| 748 |
-
'value' =>
|
|
|
|
|
|
|
| 749 |
),
|
| 750 |
),
|
| 751 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 752 |
'requires_extension' => array(
|
| 753 |
'amp-dailymotion',
|
| 754 |
),
|
|
@@ -756,13 +1249,95 @@ class AMP_Allowed_Tags_Generated {
|
|
| 756 |
),
|
| 757 |
),
|
| 758 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 759 |
'amp-date-picker' => array(
|
| 760 |
array(
|
| 761 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
| 762 |
'allow-blocked-ranges' => array(
|
| 763 |
-
'value' =>
|
|
|
|
|
|
|
| 764 |
),
|
| 765 |
'blocked' => array(),
|
|
|
|
| 766 |
'day-size' => array(
|
| 767 |
'value_regex' => '[0-9]+',
|
| 768 |
),
|
|
@@ -771,7 +1346,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 771 |
),
|
| 772 |
'format' => array(),
|
| 773 |
'fullscreen' => array(
|
| 774 |
-
'value' =>
|
|
|
|
|
|
|
| 775 |
),
|
| 776 |
'highlighted' => array(),
|
| 777 |
'input-selector' => array(),
|
|
@@ -780,36 +1357,57 @@ class AMP_Allowed_Tags_Generated {
|
|
| 780 |
'media' => array(),
|
| 781 |
'min' => array(),
|
| 782 |
'mode' => array(
|
| 783 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 784 |
),
|
| 785 |
'month-format' => array(),
|
| 786 |
'noloading' => array(
|
| 787 |
-
'value' =>
|
|
|
|
|
|
|
| 788 |
),
|
| 789 |
'number-of-months' => array(
|
| 790 |
'value_regex' => '[0-9]+',
|
| 791 |
),
|
| 792 |
'open-after-clear' => array(
|
| 793 |
-
'value' =>
|
|
|
|
|
|
|
| 794 |
),
|
| 795 |
'open-after-select' => array(
|
| 796 |
-
'value' =>
|
|
|
|
|
|
|
| 797 |
),
|
| 798 |
'src' => array(
|
| 799 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 800 |
'value_url' => array(
|
| 801 |
-
'allow_relative' =>
|
| 802 |
-
'
|
| 803 |
'https',
|
| 804 |
),
|
| 805 |
),
|
| 806 |
),
|
| 807 |
'type' => array(
|
| 808 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 809 |
),
|
| 810 |
'week-day-format' => array(),
|
| 811 |
),
|
| 812 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 813 |
'requires_extension' => array(
|
| 814 |
'amp-date-picker',
|
| 815 |
),
|
|
@@ -818,10 +1416,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 818 |
),
|
| 819 |
array(
|
| 820 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
| 821 |
'allow-blocked-ranges' => array(
|
| 822 |
-
'value' =>
|
|
|
|
|
|
|
| 823 |
),
|
| 824 |
'blocked' => array(),
|
|
|
|
| 825 |
'day-size' => array(
|
| 826 |
'value_regex' => '[0-9]+',
|
| 827 |
),
|
|
@@ -837,36 +1440,57 @@ class AMP_Allowed_Tags_Generated {
|
|
| 837 |
'min' => array(),
|
| 838 |
'mode' => array(
|
| 839 |
'mandatory' => true,
|
| 840 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 841 |
),
|
| 842 |
'month-format' => array(),
|
| 843 |
'noloading' => array(
|
| 844 |
-
'value' =>
|
|
|
|
|
|
|
| 845 |
),
|
| 846 |
'number-of-months' => array(
|
| 847 |
'value_regex' => '[0-9]+',
|
| 848 |
),
|
| 849 |
'open-after-clear' => array(
|
| 850 |
-
'value' =>
|
|
|
|
|
|
|
| 851 |
),
|
| 852 |
'open-after-select' => array(
|
| 853 |
-
'value' =>
|
|
|
|
|
|
|
| 854 |
),
|
| 855 |
'src' => array(
|
| 856 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 857 |
'value_url' => array(
|
| 858 |
-
'allow_relative' =>
|
| 859 |
-
'
|
| 860 |
'https',
|
| 861 |
),
|
| 862 |
),
|
| 863 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 864 |
'type' => array(
|
| 865 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 866 |
),
|
| 867 |
'week-day-format' => array(),
|
| 868 |
),
|
| 869 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 870 |
'requires_extension' => array(
|
| 871 |
'amp-date-picker',
|
| 872 |
),
|
|
@@ -875,59 +1499,91 @@ class AMP_Allowed_Tags_Generated {
|
|
| 875 |
),
|
| 876 |
array(
|
| 877 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
| 878 |
'allow-blocked-ranges' => array(
|
| 879 |
-
'value' =>
|
|
|
|
|
|
|
| 880 |
),
|
| 881 |
'blocked' => array(),
|
| 882 |
'day-size' => array(
|
| 883 |
'value_regex' => '[0-9]+',
|
| 884 |
),
|
|
|
|
| 885 |
'end-input-selector' => array(),
|
| 886 |
'first-day-of-week' => array(
|
| 887 |
'value_regex' => '[0-6]',
|
| 888 |
),
|
| 889 |
'format' => array(),
|
| 890 |
'fullscreen' => array(
|
| 891 |
-
'value' =>
|
|
|
|
|
|
|
| 892 |
),
|
| 893 |
'highlighted' => array(),
|
| 894 |
'locale' => array(),
|
| 895 |
'max' => array(),
|
| 896 |
'media' => array(),
|
| 897 |
'min' => array(),
|
|
|
|
|
|
|
|
|
|
| 898 |
'mode' => array(
|
| 899 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 900 |
),
|
| 901 |
'month-format' => array(),
|
| 902 |
'noloading' => array(
|
| 903 |
-
'value' =>
|
|
|
|
|
|
|
| 904 |
),
|
| 905 |
'number-of-months' => array(
|
| 906 |
'value_regex' => '[0-9]+',
|
| 907 |
),
|
| 908 |
'open-after-clear' => array(
|
| 909 |
-
'value' =>
|
|
|
|
|
|
|
| 910 |
),
|
| 911 |
'open-after-select' => array(
|
| 912 |
-
'value' =>
|
|
|
|
|
|
|
| 913 |
),
|
| 914 |
'src' => array(
|
| 915 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 916 |
'value_url' => array(
|
| 917 |
-
'allow_relative' =>
|
| 918 |
-
'
|
| 919 |
'https',
|
| 920 |
),
|
| 921 |
),
|
| 922 |
),
|
|
|
|
| 923 |
'start-input-selector' => array(),
|
| 924 |
'type' => array(
|
| 925 |
'mandatory' => true,
|
| 926 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 927 |
),
|
| 928 |
'week-day-format' => array(),
|
| 929 |
),
|
| 930 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 931 |
'requires_extension' => array(
|
| 932 |
'amp-date-picker',
|
| 933 |
),
|
|
@@ -936,13 +1592,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 936 |
),
|
| 937 |
array(
|
| 938 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
| 939 |
'allow-blocked-ranges' => array(
|
| 940 |
-
'value' =>
|
|
|
|
|
|
|
| 941 |
),
|
| 942 |
'blocked' => array(),
|
| 943 |
'day-size' => array(
|
| 944 |
'value_regex' => '[0-9]+',
|
| 945 |
),
|
|
|
|
| 946 |
'end-input-selector' => array(),
|
| 947 |
'first-day-of-week' => array(
|
| 948 |
'value_regex' => '[0-6]',
|
|
@@ -953,40 +1614,65 @@ class AMP_Allowed_Tags_Generated {
|
|
| 953 |
'max' => array(),
|
| 954 |
'media' => array(),
|
| 955 |
'min' => array(),
|
|
|
|
|
|
|
|
|
|
| 956 |
'mode' => array(
|
| 957 |
'mandatory' => true,
|
| 958 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 959 |
),
|
| 960 |
'month-format' => array(),
|
| 961 |
'noloading' => array(
|
| 962 |
-
'value' =>
|
|
|
|
|
|
|
| 963 |
),
|
| 964 |
'number-of-months' => array(
|
| 965 |
'value_regex' => '[0-9]+',
|
| 966 |
),
|
| 967 |
'open-after-clear' => array(
|
| 968 |
-
'value' =>
|
|
|
|
|
|
|
| 969 |
),
|
| 970 |
'open-after-select' => array(
|
| 971 |
-
'value' =>
|
|
|
|
|
|
|
| 972 |
),
|
| 973 |
'src' => array(
|
| 974 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 975 |
'value_url' => array(
|
| 976 |
-
'allow_relative' =>
|
| 977 |
-
'
|
| 978 |
'https',
|
| 979 |
),
|
| 980 |
),
|
| 981 |
),
|
|
|
|
| 982 |
'start-input-selector' => array(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 983 |
'type' => array(
|
| 984 |
'mandatory' => true,
|
| 985 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 986 |
),
|
| 987 |
'week-day-format' => array(),
|
| 988 |
),
|
| 989 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 990 |
'requires_extension' => array(
|
| 991 |
'amp-date-picker',
|
| 992 |
),
|
|
@@ -994,15 +1680,33 @@ class AMP_Allowed_Tags_Generated {
|
|
| 994 |
),
|
| 995 |
),
|
| 996 |
),
|
| 997 |
-
'amp-
|
| 998 |
array(
|
| 999 |
-
'attr_spec_list' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1000 |
'tag_spec' => array(
|
| 1001 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1002 |
'requires_extension' => array(
|
| 1003 |
-
'amp-
|
| 1004 |
),
|
| 1005 |
-
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-document-recommendations',
|
| 1006 |
),
|
| 1007 |
),
|
| 1008 |
),
|
|
@@ -1013,14 +1717,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1013 |
'json' => array(),
|
| 1014 |
'media' => array(),
|
| 1015 |
'noloading' => array(
|
| 1016 |
-
'value' =>
|
|
|
|
|
|
|
| 1017 |
),
|
| 1018 |
'rtc-config' => array(),
|
| 1019 |
'src' => array(
|
| 1020 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1021 |
'value_url' => array(
|
| 1022 |
'allow_relative' => true,
|
| 1023 |
-
'
|
| 1024 |
'https',
|
| 1025 |
),
|
| 1026 |
),
|
|
@@ -1034,6 +1740,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1034 |
'also_requires_tag_warning' => array(
|
| 1035 |
'amp-ad extension .js script',
|
| 1036 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1037 |
'disallowed_ancestor' => array(
|
| 1038 |
'amp-app-banner',
|
| 1039 |
),
|
|
@@ -1049,19 +1767,23 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1049 |
'data-multi-size' => array(
|
| 1050 |
'dispatch_key' => 2,
|
| 1051 |
'mandatory' => true,
|
| 1052 |
-
'value' =>
|
|
|
|
|
|
|
| 1053 |
),
|
| 1054 |
'json' => array(),
|
| 1055 |
'media' => array(),
|
| 1056 |
'noloading' => array(
|
| 1057 |
-
'value' =>
|
|
|
|
|
|
|
| 1058 |
),
|
| 1059 |
'rtc-config' => array(),
|
| 1060 |
'src' => array(
|
| 1061 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1062 |
'value_url' => array(
|
| 1063 |
'allow_relative' => true,
|
| 1064 |
-
'
|
| 1065 |
'https',
|
| 1066 |
),
|
| 1067 |
),
|
|
@@ -1074,6 +1796,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1074 |
'also_requires_tag_warning' => array(
|
| 1075 |
'amp-ad extension .js script',
|
| 1076 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1077 |
'disallowed_ancestor' => array(
|
| 1078 |
'amp-app-banner',
|
| 1079 |
'amp-carousel',
|
|
@@ -1089,6 +1823,58 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1089 |
),
|
| 1090 |
),
|
| 1091 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1092 |
'amp-experiment' => array(
|
| 1093 |
array(
|
| 1094 |
'attr_spec_list' => array(),
|
|
@@ -1109,10 +1895,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1109 |
),
|
| 1110 |
'media' => array(),
|
| 1111 |
'noloading' => array(
|
| 1112 |
-
'value' =>
|
|
|
|
|
|
|
| 1113 |
),
|
| 1114 |
),
|
| 1115 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1116 |
'requires_extension' => array(
|
| 1117 |
'amp-facebook',
|
| 1118 |
),
|
|
@@ -1127,10 +1925,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1127 |
),
|
| 1128 |
'media' => array(),
|
| 1129 |
'noloading' => array(
|
| 1130 |
-
'value' =>
|
|
|
|
|
|
|
| 1131 |
),
|
| 1132 |
),
|
| 1133 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1134 |
'requires_extension' => array(
|
| 1135 |
'amp-facebook-comments',
|
| 1136 |
),
|
|
@@ -1144,7 +1954,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1144 |
'mandatory' => true,
|
| 1145 |
'value_url' => array(
|
| 1146 |
'allow_relative' => false,
|
| 1147 |
-
'
|
| 1148 |
'http',
|
| 1149 |
'https',
|
| 1150 |
),
|
|
@@ -1152,10 +1962,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1152 |
),
|
| 1153 |
'media' => array(),
|
| 1154 |
'noloading' => array(
|
| 1155 |
-
'value' =>
|
|
|
|
|
|
|
| 1156 |
),
|
| 1157 |
),
|
| 1158 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1159 |
'requires_extension' => array(
|
| 1160 |
'amp-facebook-like',
|
| 1161 |
),
|
|
@@ -1169,7 +1991,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1169 |
'mandatory' => true,
|
| 1170 |
'value_url' => array(
|
| 1171 |
'allow_relative' => false,
|
| 1172 |
-
'
|
| 1173 |
'http',
|
| 1174 |
'https',
|
| 1175 |
),
|
|
@@ -1177,10 +1999,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1177 |
),
|
| 1178 |
'media' => array(),
|
| 1179 |
'noloading' => array(
|
| 1180 |
-
'value' =>
|
|
|
|
|
|
|
| 1181 |
),
|
| 1182 |
),
|
| 1183 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1184 |
'requires_extension' => array(
|
| 1185 |
'amp-facebook-page',
|
| 1186 |
),
|
|
@@ -1194,10 +2028,23 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1194 |
'media' => array(),
|
| 1195 |
'min-font-size' => array(),
|
| 1196 |
'noloading' => array(
|
| 1197 |
-
'value' =>
|
|
|
|
|
|
|
| 1198 |
),
|
| 1199 |
),
|
| 1200 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1201 |
'requires_extension' => array(
|
| 1202 |
'amp-fit-text',
|
| 1203 |
),
|
|
@@ -1215,7 +2062,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1215 |
'font-weight' => array(),
|
| 1216 |
'media' => array(),
|
| 1217 |
'noloading' => array(
|
| 1218 |
-
'value' =>
|
|
|
|
|
|
|
| 1219 |
),
|
| 1220 |
'on-error-add-class' => array(),
|
| 1221 |
'on-error-remove-class' => array(),
|
|
@@ -1226,6 +2075,11 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1226 |
),
|
| 1227 |
),
|
| 1228 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1229 |
'requires_extension' => array(
|
| 1230 |
'amp-font',
|
| 1231 |
),
|
|
@@ -1240,7 +2094,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1240 |
),
|
| 1241 |
'media' => array(),
|
| 1242 |
'noloading' => array(
|
| 1243 |
-
'value' =>
|
|
|
|
|
|
|
| 1244 |
),
|
| 1245 |
),
|
| 1246 |
'tag_spec' => array(
|
|
@@ -1250,6 +2106,29 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1250 |
),
|
| 1251 |
),
|
| 1252 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1253 |
'amp-gfycat' => array(
|
| 1254 |
array(
|
| 1255 |
'attr_spec_list' => array(
|
|
@@ -1258,13 +2137,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1258 |
),
|
| 1259 |
'media' => array(),
|
| 1260 |
'noautoplay' => array(
|
| 1261 |
-
'value' =>
|
|
|
|
|
|
|
| 1262 |
),
|
| 1263 |
'noloading' => array(
|
| 1264 |
-
'value' =>
|
|
|
|
|
|
|
| 1265 |
),
|
| 1266 |
),
|
| 1267 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1268 |
'requires_extension' => array(
|
| 1269 |
'amp-gfycat',
|
| 1270 |
),
|
|
@@ -1280,10 +2172,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1280 |
),
|
| 1281 |
'media' => array(),
|
| 1282 |
'noloading' => array(
|
| 1283 |
-
'value' =>
|
|
|
|
|
|
|
| 1284 |
),
|
| 1285 |
),
|
| 1286 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1287 |
'requires_extension' => array(
|
| 1288 |
'amp-gist',
|
| 1289 |
),
|
|
@@ -1291,6 +2190,47 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1291 |
),
|
| 1292 |
),
|
| 1293 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1294 |
'amp-hulu' => array(
|
| 1295 |
array(
|
| 1296 |
'attr_spec_list' => array(
|
|
@@ -1299,10 +2239,21 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1299 |
),
|
| 1300 |
'media' => array(),
|
| 1301 |
'noloading' => array(
|
| 1302 |
-
'value' =>
|
|
|
|
|
|
|
| 1303 |
),
|
| 1304 |
),
|
| 1305 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1306 |
'requires_extension' => array(
|
| 1307 |
'amp-hulu',
|
| 1308 |
),
|
|
@@ -1316,34 +2267,51 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1316 |
'[src]' => array(),
|
| 1317 |
'allow' => array(),
|
| 1318 |
'allowfullscreen' => array(
|
| 1319 |
-
'value' =>
|
|
|
|
|
|
|
| 1320 |
),
|
| 1321 |
'allowpaymentrequest' => array(
|
| 1322 |
-
'value' =>
|
|
|
|
|
|
|
| 1323 |
),
|
| 1324 |
'allowtransparency' => array(
|
| 1325 |
-
'value' =>
|
|
|
|
|
|
|
| 1326 |
),
|
| 1327 |
'frameborder' => array(
|
| 1328 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1329 |
),
|
| 1330 |
'media' => array(),
|
| 1331 |
'noloading' => array(
|
| 1332 |
-
'value' =>
|
|
|
|
|
|
|
| 1333 |
),
|
| 1334 |
'referrerpolicy' => array(),
|
| 1335 |
'resizable' => array(
|
| 1336 |
-
'value' =>
|
|
|
|
|
|
|
| 1337 |
),
|
| 1338 |
'sandbox' => array(),
|
| 1339 |
'scrolling' => array(
|
| 1340 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1341 |
),
|
| 1342 |
'src' => array(
|
| 1343 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1344 |
'value_url' => array(
|
| 1345 |
'allow_relative' => true,
|
| 1346 |
-
'
|
| 1347 |
'data',
|
| 1348 |
'https',
|
| 1349 |
),
|
|
@@ -1352,6 +2320,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1352 |
'srcdoc' => array(),
|
| 1353 |
),
|
| 1354 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1355 |
'requires_extension' => array(
|
| 1356 |
'amp-iframe',
|
| 1357 |
),
|
|
@@ -1362,13 +2341,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1362 |
array(
|
| 1363 |
'attr_spec_list' => array(
|
| 1364 |
'autoplay' => array(
|
| 1365 |
-
'value' =>
|
|
|
|
|
|
|
| 1366 |
),
|
| 1367 |
'data-src' => array(
|
| 1368 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1369 |
'value_url' => array(
|
| 1370 |
'allow_relative' => true,
|
| 1371 |
-
'
|
| 1372 |
'https',
|
| 1373 |
),
|
| 1374 |
),
|
|
@@ -1377,17 +2358,33 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1377 |
'mandatory' => true,
|
| 1378 |
'value_url' => array(
|
| 1379 |
'allow_relative' => true,
|
| 1380 |
-
'
|
| 1381 |
'https',
|
| 1382 |
),
|
| 1383 |
),
|
| 1384 |
),
|
| 1385 |
'media' => array(),
|
| 1386 |
'noloading' => array(
|
| 1387 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1388 |
),
|
| 1389 |
),
|
| 1390 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1391 |
'requires_extension' => array(
|
| 1392 |
'amp-ima-video',
|
| 1393 |
),
|
|
@@ -1401,16 +2398,56 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1401 |
'controls' => array(),
|
| 1402 |
'media' => array(),
|
| 1403 |
'noloading' => array(
|
| 1404 |
-
'value' =>
|
|
|
|
|
|
|
| 1405 |
),
|
| 1406 |
),
|
| 1407 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1408 |
'requires_extension' => array(
|
| 1409 |
'amp-image-lightbox',
|
| 1410 |
),
|
| 1411 |
),
|
| 1412 |
),
|
| 1413 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1414 |
'amp-img' => array(
|
| 1415 |
array(
|
| 1416 |
'attr_spec_list' => array(
|
|
@@ -1421,15 +2458,14 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1421 |
'alt' => array(),
|
| 1422 |
'attribution' => array(),
|
| 1423 |
'lightbox' => array(),
|
| 1424 |
-
'lightbox-exclude' => array(
|
| 1425 |
-
'value' => '',
|
| 1426 |
-
),
|
| 1427 |
'lightbox-thumbnail-id' => array(
|
| 1428 |
'value_regex_casei' => '^[a-z][a-z\\d_-]*',
|
| 1429 |
),
|
| 1430 |
'media' => array(),
|
| 1431 |
'noloading' => array(
|
| 1432 |
-
'value' =>
|
|
|
|
|
|
|
| 1433 |
),
|
| 1434 |
'placeholder' => array(),
|
| 1435 |
'src' => array(
|
|
@@ -1439,8 +2475,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1439 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1440 |
'mandatory' => true,
|
| 1441 |
'value_url' => array(
|
| 1442 |
-
'
|
| 1443 |
-
'allowed_protocol' => array(
|
| 1444 |
'data',
|
| 1445 |
'http',
|
| 1446 |
'https',
|
|
@@ -1449,6 +2484,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1449 |
),
|
| 1450 |
),
|
| 1451 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1452 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-img',
|
| 1453 |
),
|
| 1454 |
),
|
|
@@ -1461,10 +2507,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1461 |
),
|
| 1462 |
'media' => array(),
|
| 1463 |
'noloading' => array(
|
| 1464 |
-
'value' =>
|
|
|
|
|
|
|
| 1465 |
),
|
| 1466 |
),
|
| 1467 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1468 |
'requires_extension' => array(
|
| 1469 |
'amp-imgur',
|
| 1470 |
),
|
|
@@ -1480,10 +2538,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1480 |
),
|
| 1481 |
'media' => array(),
|
| 1482 |
'noloading' => array(
|
| 1483 |
-
'value' =>
|
|
|
|
|
|
|
| 1484 |
),
|
| 1485 |
),
|
| 1486 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1487 |
'requires_extension' => array(
|
| 1488 |
'amp-instagram',
|
| 1489 |
),
|
|
@@ -1497,7 +2567,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1497 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1498 |
'value_url' => array(
|
| 1499 |
'allow_relative' => true,
|
| 1500 |
-
'
|
| 1501 |
'https',
|
| 1502 |
),
|
| 1503 |
),
|
|
@@ -1507,13 +2577,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1507 |
'mandatory' => true,
|
| 1508 |
'value_url' => array(
|
| 1509 |
'allow_relative' => true,
|
| 1510 |
-
'
|
| 1511 |
'https',
|
| 1512 |
),
|
| 1513 |
),
|
| 1514 |
),
|
| 1515 |
),
|
| 1516 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1517 |
'requires_extension' => array(
|
| 1518 |
'amp-install-serviceworker',
|
| 1519 |
),
|
|
@@ -1529,10 +2604,21 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1529 |
),
|
| 1530 |
'media' => array(),
|
| 1531 |
'noloading' => array(
|
| 1532 |
-
'value' =>
|
|
|
|
|
|
|
| 1533 |
),
|
| 1534 |
),
|
| 1535 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1536 |
'requires_extension' => array(
|
| 1537 |
'amp-izlesene',
|
| 1538 |
),
|
|
@@ -1554,6 +2640,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1554 |
),
|
| 1555 |
),
|
| 1556 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1557 |
'requires_extension' => array(
|
| 1558 |
'amp-jwplayer',
|
| 1559 |
),
|
|
@@ -1568,10 +2664,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1568 |
),
|
| 1569 |
'media' => array(),
|
| 1570 |
'noloading' => array(
|
| 1571 |
-
'value' =>
|
|
|
|
|
|
|
| 1572 |
),
|
| 1573 |
),
|
| 1574 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1575 |
'requires_extension' => array(
|
| 1576 |
'amp-kaltura-player',
|
| 1577 |
),
|
|
@@ -1583,10 +2691,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1583 |
'attr_spec_list' => array(
|
| 1584 |
'media' => array(),
|
| 1585 |
'noloading' => array(
|
| 1586 |
-
'value' =>
|
|
|
|
|
|
|
| 1587 |
),
|
| 1588 |
),
|
| 1589 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1590 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-layout',
|
| 1591 |
),
|
| 1592 |
),
|
|
@@ -1594,15 +2716,30 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1594 |
'amp-lightbox' => array(
|
| 1595 |
array(
|
| 1596 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1597 |
'controls' => array(),
|
| 1598 |
'from' => array(),
|
| 1599 |
'media' => array(),
|
| 1600 |
'noloading' => array(
|
| 1601 |
-
'value' =>
|
|
|
|
|
|
|
| 1602 |
),
|
| 1603 |
'scrollable' => array(),
|
| 1604 |
),
|
| 1605 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1606 |
'requires_extension' => array(
|
| 1607 |
'amp-lightbox',
|
| 1608 |
),
|
|
@@ -1614,23 +2751,40 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1614 |
'attr_spec_list' => array(
|
| 1615 |
'[src]' => array(),
|
| 1616 |
'[state]' => array(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1617 |
'credentials' => array(),
|
| 1618 |
'items' => array(),
|
| 1619 |
'max-items' => array(),
|
| 1620 |
'media' => array(),
|
| 1621 |
'noloading' => array(
|
| 1622 |
-
'value' =>
|
|
|
|
|
|
|
| 1623 |
),
|
| 1624 |
'reset-on-refresh' => array(
|
| 1625 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1626 |
),
|
| 1627 |
'single-item' => array(),
|
| 1628 |
'src' => array(
|
| 1629 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1630 |
-
'mandatory' => true,
|
| 1631 |
'value_url' => array(
|
| 1632 |
'allow_relative' => true,
|
| 1633 |
-
'
|
| 1634 |
'https',
|
| 1635 |
),
|
| 1636 |
),
|
|
@@ -1638,86 +2792,208 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1638 |
'template' => array(),
|
| 1639 |
),
|
| 1640 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1641 |
'requires_extension' => array(
|
| 1642 |
'amp-list',
|
| 1643 |
),
|
| 1644 |
),
|
| 1645 |
),
|
|
|
|
|
|
|
| 1646 |
array(
|
| 1647 |
'attr_spec_list' => array(
|
| 1648 |
-
'
|
| 1649 |
'mandatory' => true,
|
|
|
|
| 1650 |
),
|
| 1651 |
-
'
|
| 1652 |
-
|
| 1653 |
-
'max-items' => array(),
|
| 1654 |
-
'media' => array(),
|
| 1655 |
-
'noloading' => array(
|
| 1656 |
-
'value' => '',
|
| 1657 |
),
|
| 1658 |
-
'
|
| 1659 |
-
|
| 1660 |
-
|
| 1661 |
-
|
| 1662 |
-
|
| 1663 |
-
|
| 1664 |
-
|
| 1665 |
-
|
|
|
|
|
|
|
|
|
|
| 1666 |
),
|
| 1667 |
),
|
| 1668 |
-
'template' => array(),
|
| 1669 |
),
|
| 1670 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1671 |
'requires_extension' => array(
|
| 1672 |
-
'amp-list',
|
| 1673 |
),
|
| 1674 |
-
'spec_name' => 'AMP-LIST [SRC]',
|
| 1675 |
),
|
| 1676 |
),
|
| 1677 |
),
|
| 1678 |
-
'amp-
|
| 1679 |
array(
|
| 1680 |
'attr_spec_list' => array(
|
| 1681 |
-
'data-
|
| 1682 |
'mandatory' => true,
|
| 1683 |
-
'value_regex' => '\\d+',
|
| 1684 |
),
|
| 1685 |
-
'
|
| 1686 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1687 |
),
|
| 1688 |
-
|
| 1689 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1690 |
),
|
| 1691 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1692 |
'mandatory' => true,
|
| 1693 |
),
|
| 1694 |
-
'
|
| 1695 |
-
|
|
|
|
|
|
|
|
|
|
| 1696 |
),
|
| 1697 |
),
|
| 1698 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1699 |
'requires_extension' => array(
|
| 1700 |
-
'amp-
|
| 1701 |
),
|
| 1702 |
),
|
| 1703 |
),
|
| 1704 |
),
|
| 1705 |
-
'amp-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1706 |
array(
|
| 1707 |
'attr_spec_list' => array(
|
| 1708 |
-
'
|
|
|
|
| 1709 |
'mandatory' => true,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1710 |
),
|
| 1711 |
-
|
| 1712 |
-
|
| 1713 |
-
'
|
| 1714 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1715 |
),
|
| 1716 |
),
|
| 1717 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1718 |
'requires_extension' => array(
|
| 1719 |
-
'amp-
|
| 1720 |
),
|
|
|
|
|
|
|
|
|
|
| 1721 |
),
|
| 1722 |
),
|
| 1723 |
),
|
|
@@ -1732,26 +3008,48 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1732 |
'value_regex' => '[^=/?:]+',
|
| 1733 |
),
|
| 1734 |
'data-mode' => array(
|
| 1735 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1736 |
),
|
| 1737 |
'data-origin' => array(
|
| 1738 |
'value_url' => array(
|
| 1739 |
'allow_empty' => true,
|
| 1740 |
-
'
|
| 1741 |
'https',
|
| 1742 |
'http',
|
| 1743 |
),
|
| 1744 |
),
|
| 1745 |
),
|
| 1746 |
'data-streamtype' => array(
|
| 1747 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1748 |
),
|
| 1749 |
'media' => array(),
|
| 1750 |
'noloading' => array(
|
| 1751 |
-
'value' =>
|
|
|
|
|
|
|
| 1752 |
),
|
| 1753 |
),
|
| 1754 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1755 |
'requires_extension' => array(
|
| 1756 |
'amp-nexxtv-player',
|
| 1757 |
),
|
|
@@ -1769,10 +3067,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1769 |
),
|
| 1770 |
'media' => array(),
|
| 1771 |
'noloading' => array(
|
| 1772 |
-
'value' =>
|
|
|
|
|
|
|
| 1773 |
),
|
| 1774 |
),
|
| 1775 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1776 |
'requires_extension' => array(
|
| 1777 |
'amp-o2-player',
|
| 1778 |
),
|
|
@@ -1793,16 +3103,104 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1793 |
),
|
| 1794 |
'media' => array(),
|
| 1795 |
'noloading' => array(
|
| 1796 |
-
'value' =>
|
|
|
|
|
|
|
| 1797 |
),
|
| 1798 |
),
|
| 1799 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1800 |
'requires_extension' => array(
|
| 1801 |
'amp-ooyala-player',
|
| 1802 |
),
|
| 1803 |
),
|
| 1804 |
),
|
| 1805 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1806 |
'amp-pinterest' => array(
|
| 1807 |
array(
|
| 1808 |
'attr_spec_list' => array(
|
|
@@ -1812,10 +3210,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1812 |
),
|
| 1813 |
'media' => array(),
|
| 1814 |
'noloading' => array(
|
| 1815 |
-
'value' =>
|
|
|
|
|
|
|
| 1816 |
),
|
| 1817 |
),
|
| 1818 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1819 |
'requires_extension' => array(
|
| 1820 |
'amp-pinterest',
|
| 1821 |
),
|
|
@@ -1829,10 +3239,14 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1829 |
'allow-ssr-img' => array(),
|
| 1830 |
'media' => array(),
|
| 1831 |
'noloading' => array(
|
| 1832 |
-
'value' =>
|
|
|
|
|
|
|
| 1833 |
),
|
| 1834 |
'referrerpolicy' => array(
|
| 1835 |
-
'value' =>
|
|
|
|
|
|
|
| 1836 |
),
|
| 1837 |
'src' => array(
|
| 1838 |
'blacklisted_value_regex' => '__amp_source_origin',
|
|
@@ -1840,13 +3254,21 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1840 |
'value_url' => array(
|
| 1841 |
'allow_empty' => true,
|
| 1842 |
'allow_relative' => true,
|
| 1843 |
-
'
|
| 1844 |
'https',
|
| 1845 |
),
|
| 1846 |
),
|
| 1847 |
),
|
| 1848 |
),
|
| 1849 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1850 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-pixel',
|
| 1851 |
),
|
| 1852 |
),
|
|
@@ -1855,22 +3277,39 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1855 |
array(
|
| 1856 |
'attr_spec_list' => array(
|
| 1857 |
'data-comments' => array(
|
| 1858 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1859 |
),
|
| 1860 |
'data-item' => array(),
|
| 1861 |
'data-item-info' => array(
|
| 1862 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1863 |
),
|
| 1864 |
'data-share-buttons' => array(
|
| 1865 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1866 |
),
|
| 1867 |
'media' => array(),
|
| 1868 |
'noloading' => array(
|
| 1869 |
-
'value' =>
|
|
|
|
|
|
|
| 1870 |
),
|
| 1871 |
'src' => array(),
|
| 1872 |
),
|
| 1873 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1874 |
'requires_extension' => array(
|
| 1875 |
'amp-playbuzz',
|
| 1876 |
),
|
|
@@ -1885,7 +3324,14 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1885 |
),
|
| 1886 |
'media' => array(),
|
| 1887 |
'noloading' => array(
|
| 1888 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1889 |
),
|
| 1890 |
'target' => array(),
|
| 1891 |
'viewport-margins' => array(
|
|
@@ -1893,12 +3339,59 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1893 |
),
|
| 1894 |
),
|
| 1895 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1896 |
'requires_extension' => array(
|
| 1897 |
'amp-position-observer',
|
| 1898 |
),
|
| 1899 |
),
|
| 1900 |
),
|
| 1901 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1902 |
'amp-reach-player' => array(
|
| 1903 |
array(
|
| 1904 |
'attr_spec_list' => array(
|
|
@@ -1908,10 +3401,21 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1908 |
),
|
| 1909 |
'media' => array(),
|
| 1910 |
'noloading' => array(
|
| 1911 |
-
'value' =>
|
|
|
|
|
|
|
| 1912 |
),
|
| 1913 |
),
|
| 1914 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1915 |
'requires_extension' => array(
|
| 1916 |
'amp-reach-player',
|
| 1917 |
),
|
|
@@ -1922,24 +3426,45 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1922 |
array(
|
| 1923 |
'attr_spec_list' => array(
|
| 1924 |
'data-embedlive' => array(
|
| 1925 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1926 |
),
|
| 1927 |
'data-embedparent' => array(
|
| 1928 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1929 |
),
|
| 1930 |
'data-embedtype' => array(
|
| 1931 |
'mandatory' => true,
|
| 1932 |
-
'
|
|
|
|
|
|
|
|
|
|
| 1933 |
),
|
| 1934 |
'data-src' => array(
|
| 1935 |
'mandatory' => true,
|
| 1936 |
),
|
| 1937 |
'media' => array(),
|
| 1938 |
'noloading' => array(
|
| 1939 |
-
'value' =>
|
|
|
|
|
|
|
| 1940 |
),
|
| 1941 |
),
|
| 1942 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1943 |
'requires_extension' => array(
|
| 1944 |
'amp-reddit',
|
| 1945 |
),
|
|
@@ -1955,10 +3480,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1955 |
),
|
| 1956 |
'media' => array(),
|
| 1957 |
'noloading' => array(
|
| 1958 |
-
'value' =>
|
|
|
|
|
|
|
| 1959 |
),
|
| 1960 |
),
|
| 1961 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1962 |
'requires_extension' => array(
|
| 1963 |
'amp-riddle-quiz',
|
| 1964 |
),
|
|
@@ -1972,27 +3504,57 @@ class AMP_Allowed_Tags_Generated {
|
|
| 1972 |
'[disabled]' => array(),
|
| 1973 |
'[selected]' => array(),
|
| 1974 |
'disabled' => array(
|
| 1975 |
-
'value' =>
|
|
|
|
|
|
|
| 1976 |
),
|
| 1977 |
'form' => array(),
|
| 1978 |
'keyboard-select-mode' => array(
|
| 1979 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1980 |
),
|
| 1981 |
'media' => array(),
|
| 1982 |
'multiple' => array(
|
| 1983 |
-
'value' =>
|
|
|
|
|
|
|
| 1984 |
),
|
| 1985 |
'name' => array(
|
| 1986 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 1987 |
),
|
| 1988 |
'noloading' => array(
|
| 1989 |
-
'value' =>
|
|
|
|
|
|
|
| 1990 |
),
|
| 1991 |
),
|
| 1992 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1993 |
'disallowed_ancestor' => array(
|
| 1994 |
'amp-selector',
|
| 1995 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1996 |
'requires_extension' => array(
|
| 1997 |
'amp-selector',
|
| 1998 |
),
|
|
@@ -2004,13 +3566,23 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2004 |
'attr_spec_list' => array(
|
| 2005 |
'media' => array(),
|
| 2006 |
'noloading' => array(
|
| 2007 |
-
'value' =>
|
|
|
|
|
|
|
| 2008 |
),
|
| 2009 |
'side' => array(
|
| 2010 |
-
'
|
|
|
|
|
|
|
|
|
|
| 2011 |
),
|
| 2012 |
),
|
| 2013 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2014 |
'mandatory_parent' => 'body',
|
| 2015 |
'requires_extension' => array(
|
| 2016 |
'amp-sidebar',
|
|
@@ -2018,6 +3590,43 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2018 |
),
|
| 2019 |
),
|
| 2020 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2021 |
'amp-social-share' => array(
|
| 2022 |
array(
|
| 2023 |
'attr_spec_list' => array(
|
|
@@ -2025,7 +3634,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2025 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2026 |
'value_url' => array(
|
| 2027 |
'allow_relative' => false,
|
| 2028 |
-
'
|
| 2029 |
'ftp',
|
| 2030 |
'http',
|
| 2031 |
'https',
|
|
@@ -2047,13 +3656,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2047 |
),
|
| 2048 |
'media' => array(),
|
| 2049 |
'noloading' => array(
|
| 2050 |
-
'value' =>
|
|
|
|
|
|
|
| 2051 |
),
|
| 2052 |
'type' => array(
|
| 2053 |
'mandatory' => true,
|
| 2054 |
),
|
| 2055 |
),
|
| 2056 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2057 |
'requires_extension' => array(
|
| 2058 |
'amp-social-share',
|
| 2059 |
),
|
|
@@ -2076,14 +3698,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2076 |
'value_regex' => '[0-9]+',
|
| 2077 |
),
|
| 2078 |
'data-visual' => array(
|
| 2079 |
-
'
|
|
|
|
|
|
|
|
|
|
| 2080 |
),
|
| 2081 |
'media' => array(),
|
| 2082 |
'noloading' => array(
|
| 2083 |
-
'value' =>
|
|
|
|
|
|
|
| 2084 |
),
|
| 2085 |
),
|
| 2086 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2087 |
'requires_extension' => array(
|
| 2088 |
'amp-soundcloud',
|
| 2089 |
),
|
|
@@ -2104,7 +3736,10 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2104 |
),
|
| 2105 |
'data-mode' => array(
|
| 2106 |
'mandatory' => true,
|
| 2107 |
-
'
|
|
|
|
|
|
|
|
|
|
| 2108 |
),
|
| 2109 |
'data-player-id' => array(
|
| 2110 |
'mandatory' => true,
|
|
@@ -2116,10 +3751,20 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2116 |
),
|
| 2117 |
'media' => array(),
|
| 2118 |
'noloading' => array(
|
| 2119 |
-
'value' =>
|
|
|
|
|
|
|
| 2120 |
),
|
| 2121 |
),
|
| 2122 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2123 |
'requires_extension' => array(
|
| 2124 |
'amp-springboard-player',
|
| 2125 |
),
|
|
@@ -2139,7 +3784,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2139 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2140 |
'value_url' => array(
|
| 2141 |
'allow_relative' => true,
|
| 2142 |
-
'
|
| 2143 |
'https',
|
| 2144 |
),
|
| 2145 |
),
|
|
@@ -2159,10 +3804,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2159 |
'attr_spec_list' => array(
|
| 2160 |
'media' => array(),
|
| 2161 |
'noloading' => array(
|
| 2162 |
-
'value' =>
|
|
|
|
|
|
|
| 2163 |
),
|
| 2164 |
),
|
| 2165 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2166 |
'disallowed_ancestor' => array(
|
| 2167 |
'amp-app-banner',
|
| 2168 |
),
|
|
@@ -2178,7 +3830,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2178 |
'attr_spec_list' => array(
|
| 2179 |
'background-audio' => array(
|
| 2180 |
'value_url' => array(
|
| 2181 |
-
'
|
| 2182 |
'http',
|
| 2183 |
'https',
|
| 2184 |
),
|
|
@@ -2186,15 +3838,57 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2186 |
),
|
| 2187 |
'bookend-config-src' => array(
|
| 2188 |
'value_url' => array(
|
| 2189 |
-
'
|
| 2190 |
'http',
|
| 2191 |
'https',
|
| 2192 |
),
|
| 2193 |
),
|
| 2194 |
),
|
| 2195 |
-
'
|
| 2196 |
-
'
|
| 2197 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2198 |
),
|
| 2199 |
),
|
| 2200 |
'tag_spec' => array(
|
|
@@ -2205,6 +3899,30 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2205 |
),
|
| 2206 |
),
|
| 2207 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2208 |
'amp-story-auto-ads' => array(
|
| 2209 |
array(
|
| 2210 |
'attr_spec_list' => array(),
|
|
@@ -2218,11 +3936,61 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2218 |
),
|
| 2219 |
),
|
| 2220 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2221 |
'amp-story-cta-layer' => array(
|
| 2222 |
array(
|
| 2223 |
'attr_spec_list' => array(),
|
| 2224 |
'tag_spec' => array(
|
| 2225 |
'mandatory_ancestor' => 'amp-story-page',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2226 |
),
|
| 2227 |
),
|
| 2228 |
),
|
|
@@ -2231,11 +3999,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2231 |
'attr_spec_list' => array(
|
| 2232 |
'template' => array(
|
| 2233 |
'mandatory' => true,
|
| 2234 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2235 |
),
|
| 2236 |
),
|
| 2237 |
'tag_spec' => array(
|
| 2238 |
'mandatory_ancestor' => 'amp-story-page',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2239 |
),
|
| 2240 |
),
|
| 2241 |
),
|
|
@@ -2245,7 +4028,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2245 |
'auto-advance-after' => array(),
|
| 2246 |
'background-audio' => array(
|
| 2247 |
'value_url' => array(
|
| 2248 |
-
'
|
| 2249 |
'http',
|
| 2250 |
'https',
|
| 2251 |
),
|
|
@@ -2266,6 +4049,8 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2266 |
'amp-timeago' => array(
|
| 2267 |
array(
|
| 2268 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
| 2269 |
'cutoff' => array(
|
| 2270 |
'value_regex' => '\\d+',
|
| 2271 |
),
|
|
@@ -2276,10 +4061,19 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2276 |
'locale' => array(),
|
| 2277 |
'media' => array(),
|
| 2278 |
'noloading' => array(
|
| 2279 |
-
'value' =>
|
|
|
|
|
|
|
| 2280 |
),
|
| 2281 |
),
|
| 2282 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2283 |
'requires_extension' => array(
|
| 2284 |
'amp-timeago',
|
| 2285 |
),
|
|
@@ -2290,15 +4084,53 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2290 |
'amp-twitter' => array(
|
| 2291 |
array(
|
| 2292 |
'attr_spec_list' => array(
|
| 2293 |
-
'data-
|
| 2294 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2295 |
),
|
|
|
|
| 2296 |
'media' => array(),
|
| 2297 |
'noloading' => array(
|
| 2298 |
-
'value' =>
|
|
|
|
|
|
|
| 2299 |
),
|
| 2300 |
),
|
| 2301 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2302 |
'requires_extension' => array(
|
| 2303 |
'amp-twitter',
|
| 2304 |
),
|
|
@@ -2312,7 +4144,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2312 |
'value_url' => array(
|
| 2313 |
'allow_empty' => false,
|
| 2314 |
'allow_relative' => false,
|
| 2315 |
-
'
|
| 2316 |
'https',
|
| 2317 |
),
|
| 2318 |
),
|
|
@@ -2321,20 +4153,29 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2321 |
'value_url' => array(
|
| 2322 |
'allow_empty' => false,
|
| 2323 |
'allow_relative' => false,
|
| 2324 |
-
'
|
| 2325 |
'https',
|
| 2326 |
),
|
| 2327 |
),
|
| 2328 |
),
|
| 2329 |
'enctype' => array(
|
| 2330 |
-
'value' =>
|
|
|
|
|
|
|
| 2331 |
),
|
| 2332 |
'media' => array(),
|
| 2333 |
'noloading' => array(
|
| 2334 |
-
'value' =>
|
|
|
|
|
|
|
| 2335 |
),
|
| 2336 |
),
|
| 2337 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2338 |
'requires_extension' => array(
|
| 2339 |
'amp-user-notification',
|
| 2340 |
),
|
|
@@ -2362,43 +4203,68 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2362 |
'artwork' => array(),
|
| 2363 |
'attribution' => array(),
|
| 2364 |
'autoplay' => array(
|
| 2365 |
-
'value' =>
|
|
|
|
|
|
|
| 2366 |
),
|
| 2367 |
'controls' => array(
|
| 2368 |
-
'value' =>
|
|
|
|
|
|
|
| 2369 |
),
|
| 2370 |
'controlslist' => array(),
|
| 2371 |
'crossorigin' => array(),
|
| 2372 |
'disableremoteplayback' => array(
|
| 2373 |
-
'value' =>
|
|
|
|
|
|
|
| 2374 |
),
|
|
|
|
| 2375 |
'lightbox' => array(),
|
| 2376 |
-
'lightbox-exclude' => array(
|
| 2377 |
-
'value' => '',
|
| 2378 |
-
),
|
| 2379 |
'lightbox-thumbnail-id' => array(
|
| 2380 |
'value_regex_casei' => '^[a-z][a-z\\d_-]*',
|
| 2381 |
),
|
| 2382 |
'loop' => array(
|
| 2383 |
-
'value' =>
|
|
|
|
|
|
|
| 2384 |
),
|
| 2385 |
'media' => array(),
|
| 2386 |
'muted' => array(
|
| 2387 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2388 |
),
|
| 2389 |
'noloading' => array(
|
| 2390 |
-
'value' =>
|
|
|
|
|
|
|
| 2391 |
),
|
| 2392 |
'placeholder' => array(),
|
| 2393 |
'poster' => array(),
|
| 2394 |
'preload' => array(
|
| 2395 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2396 |
),
|
| 2397 |
'src' => array(
|
| 2398 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2399 |
'value_url' => array(
|
| 2400 |
'allow_relative' => true,
|
| 2401 |
-
'
|
| 2402 |
'https',
|
| 2403 |
),
|
| 2404 |
),
|
|
@@ -2408,6 +4274,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2408 |
'also_requires_tag_warning' => array(
|
| 2409 |
'amp-video extension .js script',
|
| 2410 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2411 |
'disallowed_ancestor' => array(
|
| 2412 |
'amp-story',
|
| 2413 |
),
|
|
@@ -2434,44 +4310,82 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2434 |
'artwork' => array(),
|
| 2435 |
'attribution' => array(),
|
| 2436 |
'autoplay' => array(
|
| 2437 |
-
'value' =>
|
|
|
|
|
|
|
| 2438 |
),
|
| 2439 |
'controls' => array(
|
| 2440 |
-
'value' =>
|
|
|
|
|
|
|
| 2441 |
),
|
| 2442 |
'controlslist' => array(),
|
| 2443 |
'crossorigin' => array(),
|
| 2444 |
'disableremoteplayback' => array(
|
| 2445 |
-
'value' =>
|
|
|
|
|
|
|
| 2446 |
),
|
|
|
|
| 2447 |
'loop' => array(
|
| 2448 |
-
'value' =>
|
|
|
|
|
|
|
| 2449 |
),
|
| 2450 |
'media' => array(),
|
| 2451 |
'muted' => array(
|
| 2452 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2453 |
),
|
| 2454 |
'noloading' => array(
|
| 2455 |
-
'value' =>
|
|
|
|
|
|
|
| 2456 |
),
|
| 2457 |
'placeholder' => array(),
|
| 2458 |
'poster' => array(
|
| 2459 |
'mandatory' => true,
|
| 2460 |
),
|
| 2461 |
'preload' => array(
|
| 2462 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2463 |
),
|
| 2464 |
'src' => array(
|
| 2465 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2466 |
'value_url' => array(
|
| 2467 |
'allow_relative' => true,
|
| 2468 |
-
'
|
| 2469 |
'https',
|
| 2470 |
),
|
| 2471 |
),
|
| 2472 |
),
|
| 2473 |
),
|
| 2474 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2475 |
'mandatory_ancestor' => 'amp-story',
|
| 2476 |
'requires_extension' => array(
|
| 2477 |
'amp-video',
|
|
@@ -2484,16 +4398,32 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2484 |
'amp-vimeo' => array(
|
| 2485 |
array(
|
| 2486 |
'attr_spec_list' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2487 |
'data-videoid' => array(
|
| 2488 |
'mandatory' => true,
|
| 2489 |
'value_regex' => '[0-9]+',
|
| 2490 |
),
|
| 2491 |
'media' => array(),
|
| 2492 |
'noloading' => array(
|
| 2493 |
-
'value' =>
|
|
|
|
|
|
|
| 2494 |
),
|
| 2495 |
),
|
| 2496 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2497 |
'requires_extension' => array(
|
| 2498 |
'amp-vimeo',
|
| 2499 |
),
|
|
@@ -2508,16 +4438,62 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2508 |
),
|
| 2509 |
'media' => array(),
|
| 2510 |
'noloading' => array(
|
| 2511 |
-
'value' =>
|
|
|
|
|
|
|
| 2512 |
),
|
| 2513 |
),
|
| 2514 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2515 |
'requires_extension' => array(
|
| 2516 |
'amp-vine',
|
| 2517 |
),
|
| 2518 |
),
|
| 2519 |
),
|
| 2520 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2521 |
'amp-vk' => array(
|
| 2522 |
array(
|
| 2523 |
'attr_spec_list' => array(
|
|
@@ -2526,10 +4502,19 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2526 |
),
|
| 2527 |
'media' => array(),
|
| 2528 |
'noloading' => array(
|
| 2529 |
-
'value' =>
|
|
|
|
|
|
|
| 2530 |
),
|
| 2531 |
),
|
| 2532 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2533 |
'requires_extension' => array(
|
| 2534 |
'amp-vk',
|
| 2535 |
),
|
|
@@ -2543,24 +4528,28 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2543 |
'mandatory' => true,
|
| 2544 |
'value_url' => array(
|
| 2545 |
'allow_relative' => false,
|
| 2546 |
-
'
|
| 2547 |
'https',
|
| 2548 |
),
|
| 2549 |
),
|
| 2550 |
),
|
| 2551 |
'id' => array(
|
| 2552 |
'mandatory' => true,
|
| 2553 |
-
'
|
|
|
|
|
|
|
| 2554 |
),
|
| 2555 |
'media' => array(),
|
| 2556 |
'noloading' => array(
|
| 2557 |
-
'value' =>
|
|
|
|
|
|
|
| 2558 |
),
|
| 2559 |
'permission-dialog-url' => array(
|
| 2560 |
'mandatory' => true,
|
| 2561 |
'value_url' => array(
|
| 2562 |
'allow_relative' => false,
|
| 2563 |
-
'
|
| 2564 |
'https',
|
| 2565 |
),
|
| 2566 |
),
|
|
@@ -2569,13 +4558,18 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2569 |
'mandatory' => true,
|
| 2570 |
'value_url' => array(
|
| 2571 |
'allow_relative' => false,
|
| 2572 |
-
'
|
| 2573 |
'https',
|
| 2574 |
),
|
| 2575 |
),
|
| 2576 |
),
|
| 2577 |
),
|
| 2578 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2579 |
'requires_extension' => array(
|
| 2580 |
'amp-web-push',
|
| 2581 |
),
|
|
@@ -2588,14 +4582,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2588 |
'attr_spec_list' => array(
|
| 2589 |
'media' => array(),
|
| 2590 |
'noloading' => array(
|
| 2591 |
-
'value' =>
|
|
|
|
|
|
|
| 2592 |
),
|
| 2593 |
'visibility' => array(
|
| 2594 |
'mandatory' => true,
|
| 2595 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2596 |
),
|
| 2597 |
),
|
| 2598 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2599 |
'requires_extension' => array(
|
| 2600 |
'amp-web-push',
|
| 2601 |
),
|
|
@@ -2612,23 +4617,76 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2612 |
),
|
| 2613 |
'media' => array(),
|
| 2614 |
'noloading' => array(
|
| 2615 |
-
'value' =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2616 |
),
|
| 2617 |
),
|
| 2618 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2619 |
'requires_extension' => array(
|
| 2620 |
'amp-wistia-player',
|
| 2621 |
),
|
| 2622 |
),
|
| 2623 |
),
|
| 2624 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2625 |
'amp-youtube' => array(
|
| 2626 |
array(
|
| 2627 |
'attr_spec_list' => array(
|
| 2628 |
'[data-videoid]' => array(),
|
| 2629 |
'autoplay' => array(),
|
| 2630 |
'credentials' => array(
|
| 2631 |
-
'
|
|
|
|
|
|
|
|
|
|
| 2632 |
),
|
| 2633 |
'data-live-channelid' => array(
|
| 2634 |
'value_regex' => '[^=/?:]+',
|
|
@@ -2637,18 +4695,27 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2637 |
'value_regex' => '[^=/?:]+',
|
| 2638 |
),
|
| 2639 |
'lightbox' => array(),
|
| 2640 |
-
'lightbox-exclude' => array(
|
| 2641 |
-
'value' => '',
|
| 2642 |
-
),
|
| 2643 |
'lightbox-thumbnail-id' => array(
|
| 2644 |
'value_regex_casei' => '^[a-z][a-z\\d_-]*',
|
| 2645 |
),
|
| 2646 |
'media' => array(),
|
| 2647 |
'noloading' => array(
|
| 2648 |
-
'value' =>
|
|
|
|
|
|
|
| 2649 |
),
|
| 2650 |
),
|
| 2651 |
'tag_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2652 |
'requires_extension' => array(
|
| 2653 |
'amp-youtube',
|
| 2654 |
),
|
|
@@ -2679,7 +4746,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2679 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2680 |
'value_url' => array(
|
| 2681 |
'allow_relative' => false,
|
| 2682 |
-
'
|
| 2683 |
'data',
|
| 2684 |
'https',
|
| 2685 |
),
|
|
@@ -2703,10 +4770,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2703 |
array(
|
| 2704 |
'attr_spec_list' => array(
|
| 2705 |
'href' => array(
|
| 2706 |
-
'value' =>
|
|
|
|
|
|
|
| 2707 |
),
|
| 2708 |
'target' => array(
|
| 2709 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2710 |
),
|
| 2711 |
),
|
| 2712 |
'tag_spec' => array(
|
|
@@ -2743,8 +4816,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2743 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2744 |
'value_url' => array(
|
| 2745 |
'allow_empty' => true,
|
| 2746 |
-
'
|
| 2747 |
-
'allowed_protocol' => array(
|
| 2748 |
'http',
|
| 2749 |
'https',
|
| 2750 |
),
|
|
@@ -2778,7 +4850,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2778 |
'[type]' => array(),
|
| 2779 |
'[value]' => array(),
|
| 2780 |
'disabled' => array(
|
| 2781 |
-
'value' =>
|
|
|
|
|
|
|
| 2782 |
),
|
| 2783 |
'name' => array(
|
| 2784 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
|
@@ -2796,7 +4870,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2796 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 2797 |
),
|
| 2798 |
'open-button' => array(
|
| 2799 |
-
'value' =>
|
|
|
|
|
|
|
| 2800 |
),
|
| 2801 |
'role' => array(),
|
| 2802 |
'tabindex' => array(),
|
|
@@ -2848,6 +4924,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2848 |
'filter' => array(),
|
| 2849 |
'flood-color' => array(),
|
| 2850 |
'flood-opacity' => array(),
|
|
|
|
| 2851 |
'font-family' => array(),
|
| 2852 |
'font-size' => array(),
|
| 2853 |
'font-size-adjust' => array(),
|
|
@@ -2939,6 +5016,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 2939 |
'filter' => array(),
|
| 2940 |
'flood-color' => array(),
|
| 2941 |
'flood-opacity' => array(),
|
|
|
|
| 2942 |
'font-family' => array(),
|
| 2943 |
'font-size' => array(),
|
| 2944 |
'font-size-adjust' => array(),
|
|
@@ -3063,6 +5141,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3063 |
'filter' => array(),
|
| 3064 |
'flood-color' => array(),
|
| 3065 |
'flood-opacity' => array(),
|
|
|
|
| 3066 |
'font-family' => array(),
|
| 3067 |
'font-size' => array(),
|
| 3068 |
'font-size-adjust' => array(),
|
|
@@ -3127,8 +5206,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3127 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 3128 |
'value_url' => array(
|
| 3129 |
'allow_empty' => true,
|
| 3130 |
-
'
|
| 3131 |
-
'allowed_protocol' => array(
|
| 3132 |
'http',
|
| 3133 |
'https',
|
| 3134 |
),
|
|
@@ -3175,17 +5253,58 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3175 |
),
|
| 3176 |
'tag_spec' => array(),
|
| 3177 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3178 |
array(
|
| 3179 |
'attr_spec_list' => array(
|
| 3180 |
'align' => array(),
|
| 3181 |
'submitting' => array(
|
| 3182 |
-
'dispatch_key' => 1,
|
| 3183 |
'mandatory' => true,
|
| 3184 |
),
|
| 3185 |
),
|
| 3186 |
'tag_spec' => array(
|
| 3187 |
-
'
|
| 3188 |
-
'spec_name' => 'FORM
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3189 |
),
|
| 3190 |
),
|
| 3191 |
array(
|
|
@@ -3196,8 +5315,8 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3196 |
),
|
| 3197 |
),
|
| 3198 |
'tag_spec' => array(
|
| 3199 |
-
'
|
| 3200 |
-
'spec_name' => 'FORM
|
| 3201 |
),
|
| 3202 |
),
|
| 3203 |
array(
|
|
@@ -3211,8 +5330,8 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3211 |
),
|
| 3212 |
),
|
| 3213 |
'tag_spec' => array(
|
| 3214 |
-
'
|
| 3215 |
-
'spec_name' => 'FORM
|
| 3216 |
),
|
| 3217 |
),
|
| 3218 |
array(
|
|
@@ -3223,8 +5342,8 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3223 |
),
|
| 3224 |
),
|
| 3225 |
'tag_spec' => array(
|
| 3226 |
-
'
|
| 3227 |
-
'spec_name' => 'FORM
|
| 3228 |
),
|
| 3229 |
),
|
| 3230 |
array(
|
|
@@ -3238,12 +5357,36 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3238 |
),
|
| 3239 |
),
|
| 3240 |
'tag_spec' => array(
|
| 3241 |
-
'
|
| 3242 |
-
'spec_name' => 'FORM
|
| 3243 |
),
|
| 3244 |
),
|
| 3245 |
-
|
| 3246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3247 |
array(
|
| 3248 |
'attr_spec_list' => array(),
|
| 3249 |
'tag_spec' => array(),
|
|
@@ -3282,6 +5425,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3282 |
'filter' => array(),
|
| 3283 |
'flood-color' => array(),
|
| 3284 |
'flood-opacity' => array(),
|
|
|
|
| 3285 |
'font-family' => array(),
|
| 3286 |
'font-size' => array(),
|
| 3287 |
'font-size-adjust' => array(),
|
|
@@ -3372,6 +5516,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3372 |
'filter' => array(),
|
| 3373 |
'flood-color' => array(),
|
| 3374 |
'flood-opacity' => array(),
|
|
|
|
| 3375 |
'font-family' => array(),
|
| 3376 |
'font-size' => array(),
|
| 3377 |
'font-size-adjust' => array(),
|
|
@@ -3457,6 +5602,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3457 |
'filter' => array(),
|
| 3458 |
'flood-color' => array(),
|
| 3459 |
'flood-opacity' => array(),
|
|
|
|
| 3460 |
'font-family' => array(),
|
| 3461 |
'font-size' => array(),
|
| 3462 |
'font-size-adjust' => array(),
|
|
@@ -3546,6 +5692,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3546 |
'filter' => array(),
|
| 3547 |
'flood-color' => array(),
|
| 3548 |
'flood-opacity' => array(),
|
|
|
|
| 3549 |
'font-family' => array(),
|
| 3550 |
'font-size' => array(),
|
| 3551 |
'font-size-adjust' => array(),
|
|
@@ -3629,6 +5776,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3629 |
'filter' => array(),
|
| 3630 |
'flood-color' => array(),
|
| 3631 |
'flood-opacity' => array(),
|
|
|
|
| 3632 |
'font-family' => array(),
|
| 3633 |
'font-size' => array(),
|
| 3634 |
'font-size-adjust' => array(),
|
|
@@ -3713,6 +5861,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3713 |
'filter' => array(),
|
| 3714 |
'flood-color' => array(),
|
| 3715 |
'flood-opacity' => array(),
|
|
|
|
| 3716 |
'font-family' => array(),
|
| 3717 |
'font-size' => array(),
|
| 3718 |
'font-size-adjust' => array(),
|
|
@@ -3815,6 +5964,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3815 |
'filter' => array(),
|
| 3816 |
'flood-color' => array(),
|
| 3817 |
'flood-opacity' => array(),
|
|
|
|
| 3818 |
'font-family' => array(),
|
| 3819 |
'font-size' => array(),
|
| 3820 |
'font-size-adjust' => array(),
|
|
@@ -3925,6 +6075,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3925 |
'filterunits' => array(),
|
| 3926 |
'flood-color' => array(),
|
| 3927 |
'flood-opacity' => array(),
|
|
|
|
| 3928 |
'font-family' => array(),
|
| 3929 |
'font-size' => array(),
|
| 3930 |
'font-size-adjust' => array(),
|
|
@@ -3979,8 +6130,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 3979 |
),
|
| 3980 |
'value_url' => array(
|
| 3981 |
'allow_empty' => false,
|
| 3982 |
-
'
|
| 3983 |
-
'allowed_protocol' => array(
|
| 3984 |
'http',
|
| 3985 |
'https',
|
| 3986 |
),
|
|
@@ -4008,92 +6158,6 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4008 |
'tag_spec' => array(),
|
| 4009 |
),
|
| 4010 |
),
|
| 4011 |
-
'foreignobject' => array(
|
| 4012 |
-
array(
|
| 4013 |
-
'attr_spec_list' => array(
|
| 4014 |
-
'alignment-baseline' => array(),
|
| 4015 |
-
'baseline-shift' => array(),
|
| 4016 |
-
'clip' => array(),
|
| 4017 |
-
'clip-path' => array(),
|
| 4018 |
-
'clip-rule' => array(),
|
| 4019 |
-
'color' => array(),
|
| 4020 |
-
'color-interpolation' => array(),
|
| 4021 |
-
'color-interpolation-filters' => array(),
|
| 4022 |
-
'color-profile' => array(),
|
| 4023 |
-
'color-rendering' => array(),
|
| 4024 |
-
'cursor' => array(),
|
| 4025 |
-
'direction' => array(),
|
| 4026 |
-
'display' => array(),
|
| 4027 |
-
'dominant-baseline' => array(),
|
| 4028 |
-
'enable-background' => array(),
|
| 4029 |
-
'externalresourcesrequired' => array(),
|
| 4030 |
-
'fill' => array(),
|
| 4031 |
-
'fill-opacity' => array(),
|
| 4032 |
-
'fill-rule' => array(),
|
| 4033 |
-
'filter' => array(),
|
| 4034 |
-
'flood-color' => array(),
|
| 4035 |
-
'flood-opacity' => array(),
|
| 4036 |
-
'font-family' => array(),
|
| 4037 |
-
'font-size' => array(),
|
| 4038 |
-
'font-size-adjust' => array(),
|
| 4039 |
-
'font-stretch' => array(),
|
| 4040 |
-
'font-style' => array(),
|
| 4041 |
-
'font-variant' => array(),
|
| 4042 |
-
'font-weight' => array(),
|
| 4043 |
-
'glyph-orientation-horizontal' => array(),
|
| 4044 |
-
'glyph-orientation-vertical' => array(),
|
| 4045 |
-
'height' => array(),
|
| 4046 |
-
'image-rendering' => array(),
|
| 4047 |
-
'kerning' => array(),
|
| 4048 |
-
'letter-spacing' => array(),
|
| 4049 |
-
'lighting-color' => array(),
|
| 4050 |
-
'marker-end' => array(),
|
| 4051 |
-
'marker-mid' => array(),
|
| 4052 |
-
'marker-start' => array(),
|
| 4053 |
-
'mask' => array(),
|
| 4054 |
-
'opacity' => array(),
|
| 4055 |
-
'overflow' => array(),
|
| 4056 |
-
'pointer-events' => array(),
|
| 4057 |
-
'requiredextensions' => array(),
|
| 4058 |
-
'requiredfeatures' => array(),
|
| 4059 |
-
'shape-rendering' => array(),
|
| 4060 |
-
'stop-color' => array(),
|
| 4061 |
-
'stop-opacity' => array(),
|
| 4062 |
-
'stroke' => array(),
|
| 4063 |
-
'stroke-dasharray' => array(),
|
| 4064 |
-
'stroke-dashoffset' => array(),
|
| 4065 |
-
'stroke-linecap' => array(),
|
| 4066 |
-
'stroke-linejoin' => array(),
|
| 4067 |
-
'stroke-miterlimit' => array(),
|
| 4068 |
-
'stroke-opacity' => array(),
|
| 4069 |
-
'stroke-width' => array(),
|
| 4070 |
-
'style' => array(
|
| 4071 |
-
'blacklisted_value_regex' => '!important',
|
| 4072 |
-
),
|
| 4073 |
-
'systemlanguage' => array(),
|
| 4074 |
-
'text-anchor' => array(),
|
| 4075 |
-
'text-decoration' => array(),
|
| 4076 |
-
'text-rendering' => array(),
|
| 4077 |
-
'transform' => array(),
|
| 4078 |
-
'unicode-bidi' => array(),
|
| 4079 |
-
'vector-effect' => array(),
|
| 4080 |
-
'visibility' => array(),
|
| 4081 |
-
'width' => array(),
|
| 4082 |
-
'word-spacing' => array(),
|
| 4083 |
-
'writing-mode' => array(),
|
| 4084 |
-
'x' => array(),
|
| 4085 |
-
'xml:lang' => array(),
|
| 4086 |
-
'xml:space' => array(),
|
| 4087 |
-
'xmlns' => array(),
|
| 4088 |
-
'xmlns:xlink' => array(),
|
| 4089 |
-
'y' => array(),
|
| 4090 |
-
),
|
| 4091 |
-
'tag_spec' => array(
|
| 4092 |
-
'mandatory_ancestor' => 'svg',
|
| 4093 |
-
'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
|
| 4094 |
-
),
|
| 4095 |
-
),
|
| 4096 |
-
),
|
| 4097 |
'form' => array(
|
| 4098 |
array(
|
| 4099 |
'attr_spec_list' => array(
|
|
@@ -4103,8 +6167,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4103 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4104 |
'mandatory' => true,
|
| 4105 |
'value_url' => array(
|
| 4106 |
-
'
|
| 4107 |
-
'allowed_protocol' => array(
|
| 4108 |
'https',
|
| 4109 |
),
|
| 4110 |
),
|
|
@@ -4112,31 +6175,39 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4112 |
'action-xhr' => array(
|
| 4113 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4114 |
'value_url' => array(
|
| 4115 |
-
'
|
| 4116 |
-
'allowed_protocol' => array(
|
| 4117 |
'https',
|
| 4118 |
),
|
| 4119 |
),
|
| 4120 |
),
|
| 4121 |
'autocomplete' => array(),
|
| 4122 |
'custom-validation-reporting' => array(
|
| 4123 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4124 |
),
|
| 4125 |
'enctype' => array(),
|
| 4126 |
'method' => array(
|
| 4127 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 4128 |
),
|
| 4129 |
'name' => array(),
|
| 4130 |
'novalidate' => array(),
|
| 4131 |
'target' => array(
|
| 4132 |
'mandatory' => true,
|
| 4133 |
-
'
|
|
|
|
|
|
|
|
|
|
| 4134 |
),
|
| 4135 |
'verify-xhr' => array(
|
| 4136 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4137 |
'value_url' => array(
|
| 4138 |
-
'
|
| 4139 |
-
'allowed_protocol' => array(
|
| 4140 |
'https',
|
| 4141 |
),
|
| 4142 |
),
|
|
@@ -4160,33 +6231,40 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4160 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4161 |
'mandatory' => true,
|
| 4162 |
'value_url' => array(
|
| 4163 |
-
'
|
| 4164 |
-
'allowed_protocol' => array(
|
| 4165 |
'https',
|
| 4166 |
),
|
| 4167 |
),
|
| 4168 |
),
|
| 4169 |
'autocomplete' => array(),
|
| 4170 |
'custom-validation-reporting' => array(
|
| 4171 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4172 |
),
|
| 4173 |
'enctype' => array(),
|
| 4174 |
'method' => array(
|
| 4175 |
'dispatch_key' => 2,
|
| 4176 |
'mandatory' => true,
|
| 4177 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 4178 |
),
|
| 4179 |
'name' => array(),
|
| 4180 |
'novalidate' => array(),
|
| 4181 |
'target' => array(
|
| 4182 |
-
'
|
| 4183 |
-
|
|
|
|
|
|
|
| 4184 |
),
|
| 4185 |
'verify-xhr' => array(
|
| 4186 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4187 |
'value_url' => array(
|
| 4188 |
-
'
|
| 4189 |
-
'allowed_protocol' => array(
|
| 4190 |
'https',
|
| 4191 |
),
|
| 4192 |
),
|
|
@@ -4228,6 +6306,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4228 |
'filter' => array(),
|
| 4229 |
'flood-color' => array(),
|
| 4230 |
'flood-opacity' => array(),
|
|
|
|
| 4231 |
'font-family' => array(),
|
| 4232 |
'font-size' => array(),
|
| 4233 |
'font-size-adjust' => array(),
|
|
@@ -4311,6 +6390,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4311 |
'filter' => array(),
|
| 4312 |
'flood-color' => array(),
|
| 4313 |
'flood-opacity' => array(),
|
|
|
|
| 4314 |
'font-family' => array(),
|
| 4315 |
'font-size' => array(),
|
| 4316 |
'font-size-adjust' => array(),
|
|
@@ -4397,6 +6477,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4397 |
'filter' => array(),
|
| 4398 |
'flood-color' => array(),
|
| 4399 |
'flood-opacity' => array(),
|
|
|
|
| 4400 |
'font-family' => array(),
|
| 4401 |
'font-size' => array(),
|
| 4402 |
'font-size-adjust' => array(),
|
|
@@ -4450,8 +6531,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4450 |
),
|
| 4451 |
'value_url' => array(
|
| 4452 |
'allow_empty' => false,
|
| 4453 |
-
'
|
| 4454 |
-
'allowed_protocol' => array(
|
| 4455 |
'http',
|
| 4456 |
'https',
|
| 4457 |
),
|
|
@@ -4574,19 +6654,10 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4574 |
),
|
| 4575 |
'html' => array(
|
| 4576 |
array(
|
| 4577 |
-
'attr_spec_list' => array(
|
| 4578 |
-
'\\u26a1' => array(
|
| 4579 |
-
'alternative_names' => array(
|
| 4580 |
-
'amp',
|
| 4581 |
-
),
|
| 4582 |
-
'mandatory' => true,
|
| 4583 |
-
'value' => '',
|
| 4584 |
-
),
|
| 4585 |
-
),
|
| 4586 |
'tag_spec' => array(
|
| 4587 |
'mandatory' => true,
|
| 4588 |
'mandatory_parent' => '!doctype',
|
| 4589 |
-
'spec_name' => 'html \\u26a1 for top-level html',
|
| 4590 |
'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
|
| 4591 |
'unique' => true,
|
| 4592 |
),
|
|
@@ -4602,23 +6673,32 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4602 |
array(
|
| 4603 |
'attr_spec_list' => array(
|
| 4604 |
'frameborder' => array(
|
| 4605 |
-
'
|
|
|
|
|
|
|
|
|
|
| 4606 |
),
|
| 4607 |
'height' => array(),
|
| 4608 |
'name' => array(),
|
| 4609 |
'referrerpolicy' => array(),
|
| 4610 |
'resizable' => array(
|
| 4611 |
-
'value' =>
|
|
|
|
|
|
|
| 4612 |
),
|
| 4613 |
'sandbox' => array(),
|
| 4614 |
'scrolling' => array(
|
| 4615 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4616 |
),
|
| 4617 |
'src' => array(
|
| 4618 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4619 |
'value_url' => array(
|
| 4620 |
'allow_relative' => false,
|
| 4621 |
-
'
|
| 4622 |
'data',
|
| 4623 |
'https',
|
| 4624 |
),
|
|
@@ -4659,6 +6739,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4659 |
'filter' => array(),
|
| 4660 |
'flood-color' => array(),
|
| 4661 |
'flood-opacity' => array(),
|
|
|
|
| 4662 |
'font-family' => array(),
|
| 4663 |
'font-size' => array(),
|
| 4664 |
'font-size-adjust' => array(),
|
|
@@ -4718,8 +6799,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4718 |
'blacklisted_value_regex' => '(^|\\s)data:image\\/svg\\+xml',
|
| 4719 |
'value_url' => array(
|
| 4720 |
'allow_empty' => false,
|
| 4721 |
-
'
|
| 4722 |
-
'allowed_protocol' => array(
|
| 4723 |
'data',
|
| 4724 |
'http',
|
| 4725 |
'https',
|
|
@@ -4746,19 +6826,27 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4746 |
array(
|
| 4747 |
'attr_spec_list' => array(
|
| 4748 |
'alt' => array(),
|
|
|
|
| 4749 |
'border' => array(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4750 |
'height' => array(),
|
| 4751 |
'ismap' => array(),
|
| 4752 |
'longdesc' => array(
|
| 4753 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4754 |
'value_url' => array(
|
| 4755 |
-
'
|
| 4756 |
-
'allowed_protocol' => array(
|
| 4757 |
'http',
|
| 4758 |
'https',
|
| 4759 |
),
|
| 4760 |
),
|
| 4761 |
),
|
|
|
|
| 4762 |
'src' => array(
|
| 4763 |
'alternative_names' => array(
|
| 4764 |
'srcset',
|
|
@@ -4767,7 +6855,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4767 |
'mandatory' => true,
|
| 4768 |
'value_url' => array(
|
| 4769 |
'allow_relative' => true,
|
| 4770 |
-
'
|
| 4771 |
'data',
|
| 4772 |
'https',
|
| 4773 |
),
|
|
@@ -4825,6 +6913,11 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4825 |
'name' => array(
|
| 4826 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 4827 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4828 |
'pattern' => array(),
|
| 4829 |
'placeholder' => array(),
|
| 4830 |
'readonly' => array(),
|
|
@@ -4844,84 +6937,295 @@ class AMP_Allowed_Tags_Generated {
|
|
| 4844 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
|
| 4845 |
),
|
| 4846 |
),
|
| 4847 |
-
),
|
| 4848 |
-
'ins' => array(
|
| 4849 |
array(
|
| 4850 |
'attr_spec_list' => array(
|
| 4851 |
-
'
|
| 4852 |
-
|
| 4853 |
-
|
| 4854 |
-
|
| 4855 |
-
|
| 4856 |
-
|
| 4857 |
-
|
| 4858 |
-
|
| 4859 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4860 |
),
|
| 4861 |
),
|
| 4862 |
-
'
|
| 4863 |
-
|
| 4864 |
-
|
| 4865 |
-
|
| 4866 |
-
|
| 4867 |
-
|
| 4868 |
-
|
| 4869 |
-
|
| 4870 |
-
|
| 4871 |
-
|
| 4872 |
-
|
| 4873 |
-
|
| 4874 |
-
|
| 4875 |
-
|
| 4876 |
-
|
|
|
|
|
|
|
|
|
|
| 4877 |
),
|
| 4878 |
'tag_spec' => array(
|
|
|
|
|
|
|
| 4879 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
|
| 4880 |
),
|
| 4881 |
),
|
| 4882 |
-
),
|
| 4883 |
-
'legend' => array(
|
| 4884 |
-
array(
|
| 4885 |
-
'attr_spec_list' => array(),
|
| 4886 |
-
'tag_spec' => array(),
|
| 4887 |
-
),
|
| 4888 |
-
),
|
| 4889 |
-
'li' => array(
|
| 4890 |
-
array(
|
| 4891 |
-
'attr_spec_list' => array(
|
| 4892 |
-
'value' => array(
|
| 4893 |
-
'value_regex' => '[0-9]*',
|
| 4894 |
-
),
|
| 4895 |
-
),
|
| 4896 |
-
'tag_spec' => array(),
|
| 4897 |
-
),
|
| 4898 |
-
),
|
| 4899 |
-
'line' => array(
|
| 4900 |
array(
|
| 4901 |
'attr_spec_list' => array(
|
| 4902 |
-
'
|
| 4903 |
-
'
|
| 4904 |
-
'
|
| 4905 |
-
'
|
| 4906 |
-
'
|
| 4907 |
-
'
|
| 4908 |
-
'
|
| 4909 |
-
'
|
| 4910 |
-
'
|
| 4911 |
-
'
|
| 4912 |
-
'
|
| 4913 |
-
'
|
| 4914 |
-
'
|
| 4915 |
-
'
|
| 4916 |
-
'
|
| 4917 |
-
'
|
| 4918 |
-
'
|
| 4919 |
-
'
|
| 4920 |
-
'
|
| 4921 |
-
'
|
| 4922 |
-
'
|
| 4923 |
-
'
|
| 4924 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4925 |
'font-size' => array(),
|
| 4926 |
'font-size-adjust' => array(),
|
| 4927 |
'font-stretch' => array(),
|
|
@@ -5008,6 +7312,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5008 |
'filter' => array(),
|
| 5009 |
'flood-color' => array(),
|
| 5010 |
'flood-opacity' => array(),
|
|
|
|
| 5011 |
'font-family' => array(),
|
| 5012 |
'font-size' => array(),
|
| 5013 |
'font-size-adjust' => array(),
|
|
@@ -5063,8 +7368,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5063 |
),
|
| 5064 |
'value_url' => array(
|
| 5065 |
'allow_empty' => false,
|
| 5066 |
-
'
|
| 5067 |
-
'allowed_protocol' => array(
|
| 5068 |
'http',
|
| 5069 |
'https',
|
| 5070 |
),
|
|
@@ -5091,7 +7395,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5091 |
array(
|
| 5092 |
'attr_spec_list' => array(
|
| 5093 |
'charset' => array(
|
| 5094 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5095 |
),
|
| 5096 |
'color' => array(),
|
| 5097 |
'crossorigin' => array(),
|
|
@@ -5117,7 +7423,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5117 |
array(
|
| 5118 |
'attr_spec_list' => array(
|
| 5119 |
'charset' => array(
|
| 5120 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5121 |
),
|
| 5122 |
'color' => array(),
|
| 5123 |
'crossorigin' => array(),
|
|
@@ -5125,8 +7433,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5125 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 5126 |
'mandatory' => true,
|
| 5127 |
'value_url' => array(
|
| 5128 |
-
'
|
| 5129 |
-
'allowed_protocol' => array(
|
| 5130 |
'http',
|
| 5131 |
'https',
|
| 5132 |
),
|
|
@@ -5137,7 +7444,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5137 |
'rel' => array(
|
| 5138 |
'dispatch_key' => 2,
|
| 5139 |
'mandatory' => true,
|
| 5140 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5141 |
),
|
| 5142 |
'sizes' => array(),
|
| 5143 |
'target' => array(),
|
|
@@ -5154,7 +7463,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5154 |
array(
|
| 5155 |
'attr_spec_list' => array(
|
| 5156 |
'charset' => array(
|
| 5157 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5158 |
),
|
| 5159 |
'color' => array(),
|
| 5160 |
'crossorigin' => array(),
|
|
@@ -5162,8 +7473,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5162 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 5163 |
'mandatory' => true,
|
| 5164 |
'value_url' => array(
|
| 5165 |
-
'
|
| 5166 |
-
'allowed_protocol' => array(
|
| 5167 |
'https',
|
| 5168 |
),
|
| 5169 |
),
|
|
@@ -5173,7 +7483,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5173 |
'rel' => array(
|
| 5174 |
'dispatch_key' => 2,
|
| 5175 |
'mandatory' => true,
|
| 5176 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5177 |
),
|
| 5178 |
'sizes' => array(),
|
| 5179 |
'target' => array(),
|
|
@@ -5189,7 +7501,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5189 |
'attr_spec_list' => array(
|
| 5190 |
'as' => array(),
|
| 5191 |
'charset' => array(
|
| 5192 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5193 |
),
|
| 5194 |
'color' => array(),
|
| 5195 |
'crossorigin' => array(),
|
|
@@ -5199,7 +7513,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5199 |
'rel' => array(
|
| 5200 |
'dispatch_key' => 2,
|
| 5201 |
'mandatory' => true,
|
| 5202 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5203 |
),
|
| 5204 |
'sizes' => array(),
|
| 5205 |
'target' => array(),
|
|
@@ -5219,17 +7535,21 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5219 |
'crossorigin' => array(),
|
| 5220 |
'href' => array(
|
| 5221 |
'mandatory' => true,
|
| 5222 |
-
'value_regex' => 'https://cdn\\.materialdesignicons\\.com/([0-9]+\\.?)+/css/materialdesignicons\\.min\\.css|https://cloud\\.typography\\.com/[0-9]*/[0-9]*/css/fonts\\.css|https://fast\\.fonts\\.net/.*|https://fonts\\.googleapis\\.com/css\\?.*|https://fonts\\.googleapis\\.com/icon\\?.*|https://fonts\\.googleapis\\.com/earlyaccess/.*\\.css|https://maxcdn\\.bootstrapcdn\\.com/font-awesome/([0-9]+\\.?)+/css/font-awesome\\.min\\.css(\\?.*)?|https://use\\.fontawesome\\.com/releases/v([0-9]+\\.?)+/css/(all|brands|
|
| 5223 |
),
|
| 5224 |
'integrity' => array(),
|
| 5225 |
'media' => array(),
|
| 5226 |
'rel' => array(
|
| 5227 |
'dispatch_key' => 2,
|
| 5228 |
'mandatory' => true,
|
| 5229 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5230 |
),
|
| 5231 |
'type' => array(
|
| 5232 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5233 |
),
|
| 5234 |
),
|
| 5235 |
'tag_spec' => array(
|
|
@@ -5241,7 +7561,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5241 |
array(
|
| 5242 |
'attr_spec_list' => array(
|
| 5243 |
'charset' => array(
|
| 5244 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5245 |
),
|
| 5246 |
'color' => array(),
|
| 5247 |
'crossorigin' => array(),
|
|
@@ -5252,7 +7574,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5252 |
'itemprop' => array(
|
| 5253 |
'dispatch_key' => 2,
|
| 5254 |
'mandatory' => true,
|
| 5255 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5256 |
),
|
| 5257 |
'media' => array(),
|
| 5258 |
'sizes' => array(),
|
|
@@ -5267,7 +7591,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5267 |
array(
|
| 5268 |
'attr_spec_list' => array(
|
| 5269 |
'charset' => array(
|
| 5270 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5271 |
),
|
| 5272 |
'color' => array(),
|
| 5273 |
'crossorigin' => array(),
|
|
@@ -5291,7 +7617,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5291 |
array(
|
| 5292 |
'attr_spec_list' => array(
|
| 5293 |
'charset' => array(
|
| 5294 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5295 |
),
|
| 5296 |
'color' => array(),
|
| 5297 |
'crossorigin' => array(),
|
|
@@ -5356,6 +7684,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5356 |
'filter' => array(),
|
| 5357 |
'flood-color' => array(),
|
| 5358 |
'flood-opacity' => array(),
|
|
|
|
| 5359 |
'font-family' => array(),
|
| 5360 |
'font-size' => array(),
|
| 5361 |
'font-size-adjust' => array(),
|
|
@@ -5443,6 +7772,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5443 |
'filter' => array(),
|
| 5444 |
'flood-color' => array(),
|
| 5445 |
'flood-opacity' => array(),
|
|
|
|
| 5446 |
'font-family' => array(),
|
| 5447 |
'font-size' => array(),
|
| 5448 |
'font-size-adjust' => array(),
|
|
@@ -5511,7 +7841,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5511 |
'charset' => array(
|
| 5512 |
'dispatch_key' => 1,
|
| 5513 |
'mandatory' => true,
|
| 5514 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5515 |
),
|
| 5516 |
),
|
| 5517 |
'tag_spec' => array(
|
|
@@ -5530,10 +7862,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5530 |
'height' => array(),
|
| 5531 |
'initial-scale' => array(),
|
| 5532 |
'maximum-scale' => array(),
|
| 5533 |
-
'minimum-scale' => array(
|
| 5534 |
-
'mandatory' => true,
|
| 5535 |
-
'value_double' => 1.0,
|
| 5536 |
-
),
|
| 5537 |
'shrink-to-fit' => array(),
|
| 5538 |
'user-scalable' => array(),
|
| 5539 |
'viewport-fit' => array(),
|
|
@@ -5546,7 +7875,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5546 |
'name' => array(
|
| 5547 |
'dispatch_key' => 2,
|
| 5548 |
'mandatory' => true,
|
| 5549 |
-
'value' =>
|
|
|
|
|
|
|
| 5550 |
),
|
| 5551 |
),
|
| 5552 |
'tag_spec' => array(
|
|
@@ -5573,7 +7904,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5573 |
'http-equiv' => array(
|
| 5574 |
'dispatch_key' => 2,
|
| 5575 |
'mandatory' => true,
|
| 5576 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5577 |
),
|
| 5578 |
),
|
| 5579 |
'tag_spec' => array(
|
|
@@ -5591,7 +7924,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5591 |
'name' => array(
|
| 5592 |
'dispatch_key' => 2,
|
| 5593 |
'mandatory' => true,
|
| 5594 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5595 |
),
|
| 5596 |
),
|
| 5597 |
'tag_spec' => array(
|
|
@@ -5608,7 +7943,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5608 |
'name' => array(
|
| 5609 |
'dispatch_key' => 2,
|
| 5610 |
'mandatory' => true,
|
| 5611 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5612 |
),
|
| 5613 |
),
|
| 5614 |
'tag_spec' => array(
|
|
@@ -5621,7 +7958,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5621 |
'content' => array(
|
| 5622 |
'mandatory' => true,
|
| 5623 |
'value_url' => array(
|
| 5624 |
-
'
|
| 5625 |
'https',
|
| 5626 |
),
|
| 5627 |
),
|
|
@@ -5629,7 +7966,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5629 |
'name' => array(
|
| 5630 |
'dispatch_key' => 2,
|
| 5631 |
'mandatory' => true,
|
| 5632 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5633 |
),
|
| 5634 |
),
|
| 5635 |
'tag_spec' => array(
|
|
@@ -5646,7 +7985,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5646 |
'name' => array(
|
| 5647 |
'dispatch_key' => 2,
|
| 5648 |
'mandatory' => true,
|
| 5649 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5650 |
),
|
| 5651 |
),
|
| 5652 |
'tag_spec' => array(
|
|
@@ -5662,7 +8003,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5662 |
'name' => array(
|
| 5663 |
'dispatch_key' => 2,
|
| 5664 |
'mandatory' => true,
|
| 5665 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5666 |
),
|
| 5667 |
),
|
| 5668 |
'tag_spec' => array(
|
|
@@ -5678,7 +8021,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5678 |
'name' => array(
|
| 5679 |
'dispatch_key' => 2,
|
| 5680 |
'mandatory' => true,
|
| 5681 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5682 |
),
|
| 5683 |
),
|
| 5684 |
'tag_spec' => array(
|
|
@@ -5691,7 +8036,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5691 |
'name' => array(
|
| 5692 |
'dispatch_key' => 2,
|
| 5693 |
'mandatory' => true,
|
| 5694 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5695 |
),
|
| 5696 |
),
|
| 5697 |
'tag_spec' => array(
|
|
@@ -5717,12 +8064,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5717 |
'attr_spec_list' => array(
|
| 5718 |
'content' => array(
|
| 5719 |
'mandatory' => true,
|
| 5720 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5721 |
),
|
| 5722 |
'http-equiv' => array(
|
| 5723 |
'dispatch_key' => 2,
|
| 5724 |
'mandatory' => true,
|
| 5725 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5726 |
),
|
| 5727 |
),
|
| 5728 |
'tag_spec' => array(
|
|
@@ -5739,7 +8090,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5739 |
'http-equiv' => array(
|
| 5740 |
'dispatch_key' => 2,
|
| 5741 |
'mandatory' => true,
|
| 5742 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5743 |
),
|
| 5744 |
),
|
| 5745 |
'tag_spec' => array(
|
|
@@ -5756,7 +8109,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5756 |
'http-equiv' => array(
|
| 5757 |
'dispatch_key' => 2,
|
| 5758 |
'mandatory' => true,
|
| 5759 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5760 |
),
|
| 5761 |
),
|
| 5762 |
'tag_spec' => array(
|
|
@@ -5773,7 +8128,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5773 |
'http-equiv' => array(
|
| 5774 |
'dispatch_key' => 2,
|
| 5775 |
'mandatory' => true,
|
| 5776 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5777 |
),
|
| 5778 |
),
|
| 5779 |
'tag_spec' => array(
|
|
@@ -5786,12 +8143,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5786 |
'attr_spec_list' => array(
|
| 5787 |
'content' => array(
|
| 5788 |
'mandatory' => true,
|
| 5789 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5790 |
),
|
| 5791 |
'http-equiv' => array(
|
| 5792 |
'dispatch_key' => 2,
|
| 5793 |
'mandatory' => true,
|
| 5794 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5795 |
),
|
| 5796 |
),
|
| 5797 |
'tag_spec' => array(
|
|
@@ -5804,12 +8165,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5804 |
'attr_spec_list' => array(
|
| 5805 |
'content' => array(
|
| 5806 |
'mandatory' => true,
|
| 5807 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5808 |
),
|
| 5809 |
'http-equiv' => array(
|
| 5810 |
'dispatch_key' => 2,
|
| 5811 |
'mandatory' => true,
|
| 5812 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5813 |
),
|
| 5814 |
),
|
| 5815 |
'tag_spec' => array(
|
|
@@ -5826,7 +8191,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5826 |
'http-equiv' => array(
|
| 5827 |
'dispatch_key' => 2,
|
| 5828 |
'mandatory' => true,
|
| 5829 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5830 |
),
|
| 5831 |
),
|
| 5832 |
'tag_spec' => array(
|
|
@@ -5843,7 +8210,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5843 |
'http-equiv' => array(
|
| 5844 |
'dispatch_key' => 2,
|
| 5845 |
'mandatory' => true,
|
| 5846 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5847 |
),
|
| 5848 |
),
|
| 5849 |
'tag_spec' => array(
|
|
@@ -5856,12 +8225,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5856 |
'attr_spec_list' => array(
|
| 5857 |
'content' => array(
|
| 5858 |
'mandatory' => true,
|
| 5859 |
-
'
|
|
|
|
|
|
|
|
|
|
| 5860 |
),
|
| 5861 |
'http-equiv' => array(
|
| 5862 |
'dispatch_key' => 2,
|
| 5863 |
'mandatory' => true,
|
| 5864 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5865 |
),
|
| 5866 |
),
|
| 5867 |
'tag_spec' => array(
|
|
@@ -5878,7 +8252,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5878 |
'name' => array(
|
| 5879 |
'dispatch_key' => 2,
|
| 5880 |
'mandatory' => true,
|
| 5881 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5882 |
),
|
| 5883 |
),
|
| 5884 |
'tag_spec' => array(
|
|
@@ -5894,7 +8270,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 5894 |
'name' => array(
|
| 5895 |
'dispatch_key' => 2,
|
| 5896 |
'mandatory' => true,
|
| 5897 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 5898 |
),
|
| 5899 |
),
|
| 5900 |
'tag_spec' => array(
|
|
@@ -6004,7 +8382,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6004 |
array(
|
| 6005 |
'attr_spec_list' => array(
|
| 6006 |
'reversed' => array(
|
| 6007 |
-
'value' =>
|
|
|
|
|
|
|
| 6008 |
),
|
| 6009 |
'start' => array(
|
| 6010 |
'value_regex' => '[0-9]*',
|
|
@@ -6093,6 +8473,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6093 |
'filter' => array(),
|
| 6094 |
'flood-color' => array(),
|
| 6095 |
'flood-opacity' => array(),
|
|
|
|
| 6096 |
'font-family' => array(),
|
| 6097 |
'font-size' => array(),
|
| 6098 |
'font-size-adjust' => array(),
|
|
@@ -6177,6 +8558,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6177 |
'filter' => array(),
|
| 6178 |
'flood-color' => array(),
|
| 6179 |
'flood-opacity' => array(),
|
|
|
|
| 6180 |
'font-family' => array(),
|
| 6181 |
'font-size' => array(),
|
| 6182 |
'font-size-adjust' => array(),
|
|
@@ -6238,8 +8620,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6238 |
),
|
| 6239 |
'value_url' => array(
|
| 6240 |
'allow_empty' => false,
|
| 6241 |
-
'
|
| 6242 |
-
'allowed_protocol' => array(
|
| 6243 |
'http',
|
| 6244 |
'https',
|
| 6245 |
),
|
|
@@ -6261,6 +8642,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6261 |
),
|
| 6262 |
),
|
| 6263 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6264 |
'polygon' => array(
|
| 6265 |
array(
|
| 6266 |
'attr_spec_list' => array(
|
|
@@ -6286,6 +8676,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6286 |
'filter' => array(),
|
| 6287 |
'flood-color' => array(),
|
| 6288 |
'flood-opacity' => array(),
|
|
|
|
| 6289 |
'font-family' => array(),
|
| 6290 |
'font-size' => array(),
|
| 6291 |
'font-size-adjust' => array(),
|
|
@@ -6370,6 +8761,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6370 |
'filter' => array(),
|
| 6371 |
'flood-color' => array(),
|
| 6372 |
'flood-opacity' => array(),
|
|
|
|
| 6373 |
'font-family' => array(),
|
| 6374 |
'font-size' => array(),
|
| 6375 |
'font-size-adjust' => array(),
|
|
@@ -6451,8 +8843,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6451 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6452 |
'value_url' => array(
|
| 6453 |
'allow_empty' => true,
|
| 6454 |
-
'
|
| 6455 |
-
'allowed_protocol' => array(
|
| 6456 |
'http',
|
| 6457 |
'https',
|
| 6458 |
),
|
|
@@ -6489,6 +8880,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6489 |
'filter' => array(),
|
| 6490 |
'flood-color' => array(),
|
| 6491 |
'flood-opacity' => array(),
|
|
|
|
| 6492 |
'font-family' => array(),
|
| 6493 |
'font-size' => array(),
|
| 6494 |
'font-size-adjust' => array(),
|
|
@@ -6546,8 +8938,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6546 |
),
|
| 6547 |
'value_url' => array(
|
| 6548 |
'allow_empty' => false,
|
| 6549 |
-
'
|
| 6550 |
-
'allowed_protocol' => array(
|
| 6551 |
'http',
|
| 6552 |
'https',
|
| 6553 |
),
|
|
@@ -6599,6 +8990,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6599 |
'filter' => array(),
|
| 6600 |
'flood-color' => array(),
|
| 6601 |
'flood-opacity' => array(),
|
|
|
|
| 6602 |
'font-family' => array(),
|
| 6603 |
'font-size' => array(),
|
| 6604 |
'font-size-adjust' => array(),
|
|
@@ -6704,16 +9096,22 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6704 |
'attr_spec_list' => array(
|
| 6705 |
'async' => array(
|
| 6706 |
'mandatory' => true,
|
| 6707 |
-
'value' =>
|
|
|
|
|
|
|
| 6708 |
),
|
| 6709 |
'nonce' => array(),
|
| 6710 |
'src' => array(
|
| 6711 |
'dispatch_key' => 2,
|
| 6712 |
'mandatory' => true,
|
| 6713 |
-
'value' =>
|
|
|
|
|
|
|
| 6714 |
),
|
| 6715 |
'type' => array(
|
| 6716 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6717 |
),
|
| 6718 |
),
|
| 6719 |
'cdata' => array(
|
|
@@ -6736,7 +9134,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6736 |
'type' => array(
|
| 6737 |
'dispatch_key' => 2,
|
| 6738 |
'mandatory' => true,
|
| 6739 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6740 |
),
|
| 6741 |
),
|
| 6742 |
'cdata' => array(
|
|
@@ -6754,12 +9154,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6754 |
'id' => array(
|
| 6755 |
'dispatch_key' => 2,
|
| 6756 |
'mandatory' => true,
|
| 6757 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6758 |
),
|
| 6759 |
'nonce' => array(),
|
| 6760 |
'type' => array(
|
| 6761 |
'mandatory' => true,
|
| 6762 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6763 |
),
|
| 6764 |
),
|
| 6765 |
'cdata' => array(
|
|
@@ -6779,7 +9183,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6779 |
'type' => array(
|
| 6780 |
'dispatch_key' => 3,
|
| 6781 |
'mandatory' => true,
|
| 6782 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6783 |
),
|
| 6784 |
),
|
| 6785 |
'cdata' => array(
|
|
@@ -6797,20 +9203,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6797 |
'attr_spec_list' => array(
|
| 6798 |
'async' => array(
|
| 6799 |
'mandatory' => true,
|
| 6800 |
-
'value' =>
|
|
|
|
|
|
|
| 6801 |
),
|
| 6802 |
'nonce' => array(),
|
| 6803 |
'type' => array(
|
| 6804 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6805 |
),
|
| 6806 |
),
|
| 6807 |
'tag_spec' => array(
|
| 6808 |
'extension_spec' => array(
|
| 6809 |
-
'
|
|
|
|
| 6810 |
'0.1',
|
| 6811 |
'latest',
|
| 6812 |
),
|
| 6813 |
-
'name' => 'amp-3q-player',
|
| 6814 |
),
|
| 6815 |
),
|
| 6816 |
),
|
|
@@ -6818,21 +9228,51 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6818 |
'attr_spec_list' => array(
|
| 6819 |
'async' => array(
|
| 6820 |
'mandatory' => true,
|
| 6821 |
-
'value' =>
|
|
|
|
|
|
|
| 6822 |
),
|
| 6823 |
'nonce' => array(),
|
| 6824 |
'type' => array(
|
| 6825 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6826 |
),
|
| 6827 |
),
|
| 6828 |
'tag_spec' => array(
|
| 6829 |
'extension_spec' => array(
|
| 6830 |
-
'
|
|
|
|
| 6831 |
'0.1',
|
| 6832 |
'latest',
|
| 6833 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6834 |
'name' => 'amp-access-laterpay',
|
| 6835 |
'requires_usage' => 3,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6836 |
),
|
| 6837 |
'requires_extension' => array(
|
| 6838 |
'amp-access',
|
|
@@ -6843,21 +9283,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6843 |
'attr_spec_list' => array(
|
| 6844 |
'async' => array(
|
| 6845 |
'mandatory' => true,
|
| 6846 |
-
'value' =>
|
|
|
|
|
|
|
| 6847 |
),
|
| 6848 |
'nonce' => array(),
|
| 6849 |
'type' => array(
|
| 6850 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6851 |
),
|
| 6852 |
),
|
| 6853 |
'tag_spec' => array(
|
| 6854 |
'extension_spec' => array(
|
| 6855 |
-
'
|
|
|
|
|
|
|
| 6856 |
'0.1',
|
| 6857 |
'latest',
|
| 6858 |
),
|
| 6859 |
-
'name' => 'amp-access-scroll',
|
| 6860 |
-
'requires_usage' => 3,
|
| 6861 |
),
|
| 6862 |
'requires_extension' => array(
|
| 6863 |
'amp-access',
|
|
@@ -6868,22 +9312,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6868 |
'attr_spec_list' => array(
|
| 6869 |
'async' => array(
|
| 6870 |
'mandatory' => true,
|
| 6871 |
-
'value' =>
|
|
|
|
|
|
|
| 6872 |
),
|
| 6873 |
'nonce' => array(),
|
| 6874 |
'type' => array(
|
| 6875 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6876 |
),
|
| 6877 |
),
|
| 6878 |
'tag_spec' => array(
|
| 6879 |
'extension_spec' => array(
|
| 6880 |
-
'allowed_versions' => array(
|
| 6881 |
-
'0.1',
|
| 6882 |
-
'latest',
|
| 6883 |
-
),
|
| 6884 |
'deprecated_allow_duplicates' => true,
|
| 6885 |
'name' => 'amp-access',
|
| 6886 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6887 |
),
|
| 6888 |
),
|
| 6889 |
),
|
|
@@ -6892,12 +9340,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6892 |
'id' => array(
|
| 6893 |
'dispatch_key' => 2,
|
| 6894 |
'mandatory' => true,
|
| 6895 |
-
'value' =>
|
|
|
|
|
|
|
| 6896 |
),
|
| 6897 |
'nonce' => array(),
|
| 6898 |
'type' => array(
|
| 6899 |
'mandatory' => true,
|
| 6900 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6901 |
),
|
| 6902 |
),
|
| 6903 |
'cdata' => array(
|
|
@@ -6910,7 +9362,6 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6910 |
'mandatory_parent' => 'head',
|
| 6911 |
'requires_extension' => array(
|
| 6912 |
'amp-access',
|
| 6913 |
-
'amp-analytics',
|
| 6914 |
),
|
| 6915 |
'spec_name' => 'amp-access extension .json script',
|
| 6916 |
'unique' => true,
|
|
@@ -6920,22 +9371,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6920 |
'attr_spec_list' => array(
|
| 6921 |
'async' => array(
|
| 6922 |
'mandatory' => true,
|
| 6923 |
-
'value' =>
|
|
|
|
|
|
|
| 6924 |
),
|
| 6925 |
'nonce' => array(),
|
| 6926 |
'type' => array(
|
| 6927 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6928 |
),
|
| 6929 |
),
|
| 6930 |
'tag_spec' => array(
|
| 6931 |
'extension_spec' => array(
|
| 6932 |
-
'allowed_versions' => array(
|
| 6933 |
-
'0.1',
|
| 6934 |
-
'latest',
|
| 6935 |
-
),
|
| 6936 |
'deprecated_allow_duplicates' => true,
|
| 6937 |
'name' => 'amp-accordion',
|
| 6938 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6939 |
),
|
| 6940 |
),
|
| 6941 |
),
|
|
@@ -6943,22 +9398,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6943 |
'attr_spec_list' => array(
|
| 6944 |
'async' => array(
|
| 6945 |
'mandatory' => true,
|
| 6946 |
-
'value' =>
|
|
|
|
|
|
|
| 6947 |
),
|
| 6948 |
'nonce' => array(),
|
| 6949 |
'type' => array(
|
| 6950 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6951 |
),
|
| 6952 |
),
|
| 6953 |
'tag_spec' => array(
|
| 6954 |
'extension_spec' => array(
|
| 6955 |
-
'allowed_versions' => array(
|
| 6956 |
-
'0.1',
|
| 6957 |
-
'latest',
|
| 6958 |
-
),
|
| 6959 |
'deprecated_allow_duplicates' => true,
|
| 6960 |
'name' => 'amp-ad',
|
| 6961 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6962 |
),
|
| 6963 |
'spec_name' => 'amp-ad extension .js script',
|
| 6964 |
),
|
|
@@ -6967,22 +9426,51 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6967 |
'attr_spec_list' => array(
|
| 6968 |
'async' => array(
|
| 6969 |
'mandatory' => true,
|
| 6970 |
-
'value' =>
|
|
|
|
|
|
|
| 6971 |
),
|
| 6972 |
'nonce' => array(),
|
| 6973 |
'type' => array(
|
| 6974 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6975 |
),
|
| 6976 |
),
|
| 6977 |
'tag_spec' => array(
|
| 6978 |
'extension_spec' => array(
|
| 6979 |
-
'
|
|
|
|
| 6980 |
'0.1',
|
| 6981 |
'latest',
|
| 6982 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6983 |
'deprecated_allow_duplicates' => true,
|
| 6984 |
'name' => 'amp-analytics',
|
| 6985 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6986 |
),
|
| 6987 |
),
|
| 6988 |
),
|
|
@@ -6992,7 +9480,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 6992 |
'type' => array(
|
| 6993 |
'dispatch_key' => 3,
|
| 6994 |
'mandatory' => true,
|
| 6995 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 6996 |
),
|
| 6997 |
),
|
| 6998 |
'cdata' => array(
|
|
@@ -7014,22 +9504,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7014 |
'attr_spec_list' => array(
|
| 7015 |
'async' => array(
|
| 7016 |
'mandatory' => true,
|
| 7017 |
-
'value' =>
|
|
|
|
|
|
|
| 7018 |
),
|
| 7019 |
'nonce' => array(),
|
| 7020 |
'type' => array(
|
| 7021 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7022 |
),
|
| 7023 |
),
|
| 7024 |
'tag_spec' => array(
|
| 7025 |
'extension_spec' => array(
|
| 7026 |
-
'allowed_versions' => array(
|
| 7027 |
-
'0.1',
|
| 7028 |
-
'latest',
|
| 7029 |
-
),
|
| 7030 |
'deprecated_allow_duplicates' => true,
|
| 7031 |
'name' => 'amp-anim',
|
| 7032 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7033 |
),
|
| 7034 |
),
|
| 7035 |
),
|
|
@@ -7037,20 +9531,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7037 |
'attr_spec_list' => array(
|
| 7038 |
'async' => array(
|
| 7039 |
'mandatory' => true,
|
| 7040 |
-
'value' =>
|
|
|
|
|
|
|
| 7041 |
),
|
| 7042 |
'nonce' => array(),
|
| 7043 |
'type' => array(
|
| 7044 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7045 |
),
|
| 7046 |
),
|
| 7047 |
'tag_spec' => array(
|
| 7048 |
'extension_spec' => array(
|
| 7049 |
-
'
|
|
|
|
| 7050 |
'0.1',
|
| 7051 |
'latest',
|
| 7052 |
),
|
| 7053 |
-
'name' => 'amp-animation',
|
| 7054 |
),
|
| 7055 |
),
|
| 7056 |
),
|
|
@@ -7060,7 +9558,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7060 |
'type' => array(
|
| 7061 |
'dispatch_key' => 3,
|
| 7062 |
'mandatory' => true,
|
| 7063 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7064 |
),
|
| 7065 |
),
|
| 7066 |
'cdata' => array(
|
|
@@ -7081,22 +9581,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7081 |
'attr_spec_list' => array(
|
| 7082 |
'async' => array(
|
| 7083 |
'mandatory' => true,
|
| 7084 |
-
'value' =>
|
|
|
|
|
|
|
| 7085 |
),
|
| 7086 |
'nonce' => array(),
|
| 7087 |
'type' => array(
|
| 7088 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7089 |
),
|
| 7090 |
),
|
| 7091 |
'tag_spec' => array(
|
| 7092 |
'extension_spec' => array(
|
| 7093 |
-
'allowed_versions' => array(
|
| 7094 |
-
'0.1',
|
| 7095 |
-
'latest',
|
| 7096 |
-
),
|
| 7097 |
'deprecated_allow_duplicates' => true,
|
| 7098 |
'name' => 'amp-apester-media',
|
| 7099 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7100 |
),
|
| 7101 |
),
|
| 7102 |
),
|
|
@@ -7104,21 +9608,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7104 |
'attr_spec_list' => array(
|
| 7105 |
'async' => array(
|
| 7106 |
'mandatory' => true,
|
| 7107 |
-
'value' =>
|
|
|
|
|
|
|
| 7108 |
),
|
| 7109 |
'nonce' => array(),
|
| 7110 |
'type' => array(
|
| 7111 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7112 |
),
|
| 7113 |
),
|
| 7114 |
'tag_spec' => array(
|
| 7115 |
'extension_spec' => array(
|
| 7116 |
-
'
|
|
|
|
|
|
|
| 7117 |
'0.1',
|
| 7118 |
'latest',
|
| 7119 |
),
|
| 7120 |
-
'deprecated_allow_duplicates' => true,
|
| 7121 |
-
'name' => 'amp-app-banner',
|
| 7122 |
),
|
| 7123 |
),
|
| 7124 |
),
|
|
@@ -7126,22 +9634,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7126 |
'attr_spec_list' => array(
|
| 7127 |
'async' => array(
|
| 7128 |
'mandatory' => true,
|
| 7129 |
-
'value' =>
|
|
|
|
|
|
|
| 7130 |
),
|
| 7131 |
'nonce' => array(),
|
| 7132 |
'type' => array(
|
| 7133 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7134 |
),
|
| 7135 |
),
|
| 7136 |
'tag_spec' => array(
|
| 7137 |
'extension_spec' => array(
|
| 7138 |
-
'allowed_versions' => array(
|
| 7139 |
-
'0.1',
|
| 7140 |
-
'latest',
|
| 7141 |
-
),
|
| 7142 |
'deprecated_allow_duplicates' => true,
|
| 7143 |
'name' => 'amp-audio',
|
| 7144 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7145 |
),
|
| 7146 |
),
|
| 7147 |
),
|
|
@@ -7149,20 +9661,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7149 |
'attr_spec_list' => array(
|
| 7150 |
'async' => array(
|
| 7151 |
'mandatory' => true,
|
| 7152 |
-
'value' =>
|
|
|
|
|
|
|
| 7153 |
),
|
| 7154 |
'nonce' => array(),
|
| 7155 |
'type' => array(
|
| 7156 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7157 |
),
|
| 7158 |
),
|
| 7159 |
'tag_spec' => array(
|
| 7160 |
'extension_spec' => array(
|
| 7161 |
-
'
|
|
|
|
| 7162 |
'0.1',
|
| 7163 |
'latest',
|
| 7164 |
),
|
| 7165 |
-
'name' => 'amp-auto-ads',
|
| 7166 |
),
|
| 7167 |
),
|
| 7168 |
),
|
|
@@ -7170,20 +9686,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7170 |
'attr_spec_list' => array(
|
| 7171 |
'async' => array(
|
| 7172 |
'mandatory' => true,
|
| 7173 |
-
'value' =>
|
|
|
|
|
|
|
| 7174 |
),
|
| 7175 |
'nonce' => array(),
|
| 7176 |
'type' => array(
|
| 7177 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7178 |
),
|
| 7179 |
),
|
| 7180 |
'tag_spec' => array(
|
| 7181 |
'extension_spec' => array(
|
| 7182 |
-
'
|
|
|
|
| 7183 |
'0.1',
|
| 7184 |
'latest',
|
| 7185 |
),
|
| 7186 |
-
'name' => 'amp-beopinion',
|
| 7187 |
),
|
| 7188 |
),
|
| 7189 |
),
|
|
@@ -7191,21 +9711,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7191 |
'attr_spec_list' => array(
|
| 7192 |
'async' => array(
|
| 7193 |
'mandatory' => true,
|
| 7194 |
-
'value' =>
|
|
|
|
|
|
|
| 7195 |
),
|
| 7196 |
'nonce' => array(),
|
| 7197 |
'type' => array(
|
| 7198 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7199 |
),
|
| 7200 |
),
|
| 7201 |
'tag_spec' => array(
|
| 7202 |
'extension_spec' => array(
|
| 7203 |
-
'
|
|
|
|
|
|
|
| 7204 |
'0.1',
|
| 7205 |
'latest',
|
| 7206 |
),
|
| 7207 |
-
'name' => 'amp-bind',
|
| 7208 |
-
'requires_usage' => 3,
|
| 7209 |
),
|
| 7210 |
),
|
| 7211 |
),
|
|
@@ -7215,7 +9739,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7215 |
'type' => array(
|
| 7216 |
'dispatch_key' => 3,
|
| 7217 |
'mandatory' => true,
|
| 7218 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7219 |
),
|
| 7220 |
),
|
| 7221 |
'cdata' => array(
|
|
@@ -7223,6 +9749,8 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7223 |
'error_message' => 'html comments',
|
| 7224 |
'regex' => '<!--',
|
| 7225 |
),
|
|
|
|
|
|
|
| 7226 |
),
|
| 7227 |
'tag_spec' => array(
|
| 7228 |
'mandatory_parent' => 'amp-state',
|
|
@@ -7237,20 +9765,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7237 |
'attr_spec_list' => array(
|
| 7238 |
'async' => array(
|
| 7239 |
'mandatory' => true,
|
| 7240 |
-
'value' =>
|
|
|
|
|
|
|
| 7241 |
),
|
| 7242 |
'nonce' => array(),
|
| 7243 |
'type' => array(
|
| 7244 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7245 |
),
|
| 7246 |
),
|
| 7247 |
'tag_spec' => array(
|
| 7248 |
'extension_spec' => array(
|
| 7249 |
-
'
|
|
|
|
| 7250 |
'0.1',
|
| 7251 |
'latest',
|
| 7252 |
),
|
| 7253 |
-
'name' => 'amp-bodymovin-animation',
|
| 7254 |
),
|
| 7255 |
),
|
| 7256 |
),
|
|
@@ -7258,22 +9790,53 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7258 |
'attr_spec_list' => array(
|
| 7259 |
'async' => array(
|
| 7260 |
'mandatory' => true,
|
| 7261 |
-
'value' =>
|
|
|
|
|
|
|
| 7262 |
),
|
| 7263 |
'nonce' => array(),
|
| 7264 |
'type' => array(
|
| 7265 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7266 |
),
|
| 7267 |
),
|
| 7268 |
'tag_spec' => array(
|
| 7269 |
'extension_spec' => array(
|
| 7270 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7271 |
'0.1',
|
| 7272 |
'latest',
|
| 7273 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7274 |
'deprecated_allow_duplicates' => true,
|
| 7275 |
-
'name' => 'amp-
|
| 7276 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7277 |
),
|
| 7278 |
),
|
| 7279 |
),
|
|
@@ -7281,22 +9844,50 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7281 |
'attr_spec_list' => array(
|
| 7282 |
'async' => array(
|
| 7283 |
'mandatory' => true,
|
| 7284 |
-
'value' =>
|
|
|
|
|
|
|
| 7285 |
),
|
| 7286 |
'nonce' => array(),
|
| 7287 |
'type' => array(
|
| 7288 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7289 |
),
|
| 7290 |
),
|
| 7291 |
'tag_spec' => array(
|
| 7292 |
'extension_spec' => array(
|
| 7293 |
-
'
|
|
|
|
| 7294 |
'0.1',
|
| 7295 |
'latest',
|
| 7296 |
),
|
| 7297 |
-
|
| 7298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7299 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7300 |
),
|
| 7301 |
),
|
| 7302 |
),
|
|
@@ -7304,20 +9895,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7304 |
'attr_spec_list' => array(
|
| 7305 |
'async' => array(
|
| 7306 |
'mandatory' => true,
|
| 7307 |
-
'value' =>
|
|
|
|
|
|
|
| 7308 |
),
|
| 7309 |
'nonce' => array(),
|
| 7310 |
'type' => array(
|
| 7311 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7312 |
),
|
| 7313 |
),
|
| 7314 |
'tag_spec' => array(
|
| 7315 |
'extension_spec' => array(
|
| 7316 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7317 |
'0.1',
|
| 7318 |
'latest',
|
| 7319 |
),
|
| 7320 |
-
'name' => 'amp-byside-content',
|
| 7321 |
),
|
| 7322 |
),
|
| 7323 |
),
|
|
@@ -7325,21 +9922,77 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7325 |
'attr_spec_list' => array(
|
| 7326 |
'async' => array(
|
| 7327 |
'mandatory' => true,
|
| 7328 |
-
'value' =>
|
|
|
|
|
|
|
| 7329 |
),
|
| 7330 |
'nonce' => array(),
|
| 7331 |
'type' => array(
|
| 7332 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7333 |
),
|
| 7334 |
),
|
| 7335 |
'tag_spec' => array(
|
| 7336 |
'extension_spec' => array(
|
| 7337 |
-
'
|
|
|
|
| 7338 |
'0.1',
|
| 7339 |
'latest',
|
| 7340 |
),
|
| 7341 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7342 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7343 |
),
|
| 7344 |
),
|
| 7345 |
),
|
|
@@ -7347,22 +10000,226 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7347 |
'attr_spec_list' => array(
|
| 7348 |
'async' => array(
|
| 7349 |
'mandatory' => true,
|
| 7350 |
-
'value' =>
|
|
|
|
|
|
|
| 7351 |
),
|
| 7352 |
'nonce' => array(),
|
| 7353 |
'type' => array(
|
| 7354 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7355 |
),
|
| 7356 |
),
|
| 7357 |
'tag_spec' => array(
|
| 7358 |
'extension_spec' => array(
|
| 7359 |
-
'
|
|
|
|
| 7360 |
'0.1',
|
| 7361 |
'latest',
|
| 7362 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7363 |
'deprecated_allow_duplicates' => true,
|
| 7364 |
-
'name' => 'amp-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7365 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7366 |
),
|
| 7367 |
),
|
| 7368 |
),
|
|
@@ -7370,67 +10227,78 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7370 |
'attr_spec_list' => array(
|
| 7371 |
'async' => array(
|
| 7372 |
'mandatory' => true,
|
| 7373 |
-
'value' =>
|
|
|
|
|
|
|
| 7374 |
),
|
| 7375 |
'nonce' => array(),
|
| 7376 |
'type' => array(
|
| 7377 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7378 |
),
|
| 7379 |
),
|
| 7380 |
'tag_spec' => array(
|
| 7381 |
'extension_spec' => array(
|
| 7382 |
-
'
|
|
|
|
| 7383 |
'0.1',
|
| 7384 |
'latest',
|
| 7385 |
),
|
| 7386 |
-
'name' => 'amp-consent',
|
| 7387 |
),
|
| 7388 |
),
|
| 7389 |
),
|
| 7390 |
array(
|
| 7391 |
'attr_spec_list' => array(
|
| 7392 |
-
'
|
| 7393 |
-
'type' => array(
|
| 7394 |
-
'dispatch_key' => 3,
|
| 7395 |
'mandatory' => true,
|
| 7396 |
-
'
|
|
|
|
|
|
|
| 7397 |
),
|
| 7398 |
-
|
| 7399 |
-
|
| 7400 |
-
|
| 7401 |
-
|
| 7402 |
-
|
| 7403 |
),
|
| 7404 |
),
|
| 7405 |
'tag_spec' => array(
|
| 7406 |
-
'
|
| 7407 |
-
|
| 7408 |
-
'amp-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7409 |
),
|
| 7410 |
-
'spec_name' => 'amp-consent extension .json script',
|
| 7411 |
-
'unique' => true,
|
| 7412 |
),
|
| 7413 |
),
|
| 7414 |
array(
|
| 7415 |
'attr_spec_list' => array(
|
| 7416 |
'async' => array(
|
| 7417 |
'mandatory' => true,
|
| 7418 |
-
'value' =>
|
|
|
|
|
|
|
| 7419 |
),
|
| 7420 |
'nonce' => array(),
|
| 7421 |
'type' => array(
|
| 7422 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7423 |
),
|
| 7424 |
),
|
| 7425 |
'tag_spec' => array(
|
| 7426 |
'extension_spec' => array(
|
| 7427 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7428 |
'0.1',
|
| 7429 |
'latest',
|
| 7430 |
),
|
| 7431 |
-
'deprecated_allow_duplicates' => true,
|
| 7432 |
-
'name' => 'amp-dailymotion',
|
| 7433 |
-
'requires_usage' => 2,
|
| 7434 |
),
|
| 7435 |
),
|
| 7436 |
),
|
|
@@ -7438,72 +10306,106 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7438 |
'attr_spec_list' => array(
|
| 7439 |
'async' => array(
|
| 7440 |
'mandatory' => true,
|
| 7441 |
-
'value' =>
|
|
|
|
|
|
|
| 7442 |
),
|
| 7443 |
'nonce' => array(),
|
| 7444 |
'type' => array(
|
| 7445 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7446 |
),
|
| 7447 |
),
|
| 7448 |
'tag_spec' => array(
|
| 7449 |
'extension_spec' => array(
|
| 7450 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7451 |
'0.1',
|
| 7452 |
'latest',
|
| 7453 |
),
|
| 7454 |
-
'name' => 'amp-date-picker',
|
| 7455 |
),
|
| 7456 |
),
|
| 7457 |
),
|
| 7458 |
array(
|
| 7459 |
-
'attr_spec_list' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7460 |
'tag_spec' => array(
|
| 7461 |
'extension_spec' => array(
|
| 7462 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7463 |
'0.1',
|
| 7464 |
'latest',
|
| 7465 |
),
|
| 7466 |
-
'name' => 'amp-document-recommendations',
|
| 7467 |
),
|
| 7468 |
),
|
| 7469 |
),
|
| 7470 |
array(
|
| 7471 |
'attr_spec_list' => array(
|
| 7472 |
-
'
|
| 7473 |
-
'dispatch_key' => 3,
|
| 7474 |
'mandatory' => true,
|
| 7475 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7476 |
),
|
| 7477 |
),
|
| 7478 |
'tag_spec' => array(
|
| 7479 |
-
'
|
| 7480 |
-
|
| 7481 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7482 |
),
|
| 7483 |
-
'spec_name' => 'amp-document-recommendations extension .json configuration',
|
| 7484 |
-
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-document-recommendations',
|
| 7485 |
),
|
| 7486 |
),
|
| 7487 |
array(
|
| 7488 |
'attr_spec_list' => array(
|
| 7489 |
'async' => array(
|
| 7490 |
'mandatory' => true,
|
| 7491 |
-
'value' =>
|
|
|
|
|
|
|
| 7492 |
),
|
| 7493 |
'nonce' => array(),
|
| 7494 |
'type' => array(
|
| 7495 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7496 |
),
|
| 7497 |
),
|
| 7498 |
'tag_spec' => array(
|
| 7499 |
'extension_spec' => array(
|
| 7500 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7501 |
'0.1',
|
| 7502 |
'latest',
|
| 7503 |
),
|
| 7504 |
-
'deprecated_allow_duplicates' => true,
|
| 7505 |
-
'name' => 'amp-dynamic-css-classes',
|
| 7506 |
-
'requires_usage' => 3,
|
| 7507 |
),
|
| 7508 |
),
|
| 7509 |
),
|
|
@@ -7511,22 +10413,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7511 |
'attr_spec_list' => array(
|
| 7512 |
'async' => array(
|
| 7513 |
'mandatory' => true,
|
| 7514 |
-
'value' =>
|
|
|
|
|
|
|
| 7515 |
),
|
| 7516 |
'nonce' => array(),
|
| 7517 |
'type' => array(
|
| 7518 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7519 |
),
|
| 7520 |
),
|
| 7521 |
'tag_spec' => array(
|
| 7522 |
'extension_spec' => array(
|
| 7523 |
-
'
|
|
|
|
| 7524 |
'0.1',
|
| 7525 |
'latest',
|
| 7526 |
),
|
| 7527 |
-
'deprecated_allow_duplicates' => true,
|
| 7528 |
-
'name' => 'amp-experiment',
|
| 7529 |
-
'requires_usage' => 2,
|
| 7530 |
),
|
| 7531 |
),
|
| 7532 |
),
|
|
@@ -7536,7 +10440,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7536 |
'type' => array(
|
| 7537 |
'dispatch_key' => 3,
|
| 7538 |
'mandatory' => true,
|
| 7539 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7540 |
),
|
| 7541 |
),
|
| 7542 |
'cdata' => array(
|
|
@@ -7546,29 +10452,38 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7546 |
),
|
| 7547 |
),
|
| 7548 |
'tag_spec' => array(
|
| 7549 |
-
'mandatory_parent' => 'amp-
|
| 7550 |
-
'
|
| 7551 |
-
|
|
|
|
|
|
|
|
|
|
| 7552 |
),
|
| 7553 |
),
|
| 7554 |
array(
|
| 7555 |
'attr_spec_list' => array(
|
| 7556 |
'async' => array(
|
| 7557 |
'mandatory' => true,
|
| 7558 |
-
'value' =>
|
|
|
|
|
|
|
| 7559 |
),
|
| 7560 |
'nonce' => array(),
|
| 7561 |
'type' => array(
|
| 7562 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7563 |
),
|
| 7564 |
),
|
| 7565 |
'tag_spec' => array(
|
| 7566 |
'extension_spec' => array(
|
| 7567 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7568 |
'0.1',
|
| 7569 |
'latest',
|
| 7570 |
),
|
| 7571 |
-
'name' => 'amp-facebook-comments',
|
| 7572 |
),
|
| 7573 |
),
|
| 7574 |
),
|
|
@@ -7576,20 +10491,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7576 |
'attr_spec_list' => array(
|
| 7577 |
'async' => array(
|
| 7578 |
'mandatory' => true,
|
| 7579 |
-
'value' =>
|
|
|
|
|
|
|
| 7580 |
),
|
| 7581 |
'nonce' => array(),
|
| 7582 |
'type' => array(
|
| 7583 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7584 |
),
|
| 7585 |
),
|
| 7586 |
'tag_spec' => array(
|
| 7587 |
'extension_spec' => array(
|
| 7588 |
-
'
|
|
|
|
| 7589 |
'0.1',
|
| 7590 |
'latest',
|
| 7591 |
),
|
| 7592 |
-
'name' => 'amp-facebook-like',
|
| 7593 |
),
|
| 7594 |
),
|
| 7595 |
),
|
|
@@ -7597,20 +10516,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7597 |
'attr_spec_list' => array(
|
| 7598 |
'async' => array(
|
| 7599 |
'mandatory' => true,
|
| 7600 |
-
'value' =>
|
|
|
|
|
|
|
| 7601 |
),
|
| 7602 |
'nonce' => array(),
|
| 7603 |
'type' => array(
|
| 7604 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7605 |
),
|
| 7606 |
),
|
| 7607 |
'tag_spec' => array(
|
| 7608 |
'extension_spec' => array(
|
| 7609 |
-
'
|
|
|
|
| 7610 |
'0.1',
|
| 7611 |
'latest',
|
| 7612 |
),
|
| 7613 |
-
'name' => 'amp-facebook-page',
|
| 7614 |
),
|
| 7615 |
),
|
| 7616 |
),
|
|
@@ -7618,22 +10541,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7618 |
'attr_spec_list' => array(
|
| 7619 |
'async' => array(
|
| 7620 |
'mandatory' => true,
|
| 7621 |
-
'value' =>
|
|
|
|
|
|
|
| 7622 |
),
|
| 7623 |
'nonce' => array(),
|
| 7624 |
'type' => array(
|
| 7625 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7626 |
),
|
| 7627 |
),
|
| 7628 |
'tag_spec' => array(
|
| 7629 |
'extension_spec' => array(
|
| 7630 |
-
'
|
|
|
|
| 7631 |
'0.1',
|
| 7632 |
'latest',
|
| 7633 |
),
|
| 7634 |
-
'deprecated_allow_duplicates' => true,
|
| 7635 |
-
'name' => 'amp-facebook',
|
| 7636 |
-
'requires_usage' => 2,
|
| 7637 |
),
|
| 7638 |
),
|
| 7639 |
),
|
|
@@ -7641,22 +10566,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7641 |
'attr_spec_list' => array(
|
| 7642 |
'async' => array(
|
| 7643 |
'mandatory' => true,
|
| 7644 |
-
'value' =>
|
|
|
|
|
|
|
| 7645 |
),
|
| 7646 |
'nonce' => array(),
|
| 7647 |
'type' => array(
|
| 7648 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7649 |
),
|
| 7650 |
),
|
| 7651 |
'tag_spec' => array(
|
| 7652 |
'extension_spec' => array(
|
| 7653 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7654 |
'0.1',
|
| 7655 |
'latest',
|
| 7656 |
),
|
| 7657 |
-
'deprecated_allow_duplicates' => true,
|
| 7658 |
-
'name' => 'amp-fit-text',
|
| 7659 |
-
'requires_usage' => 2,
|
| 7660 |
),
|
| 7661 |
),
|
| 7662 |
),
|
|
@@ -7664,22 +10593,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7664 |
'attr_spec_list' => array(
|
| 7665 |
'async' => array(
|
| 7666 |
'mandatory' => true,
|
| 7667 |
-
'value' =>
|
|
|
|
|
|
|
| 7668 |
),
|
| 7669 |
'nonce' => array(),
|
| 7670 |
'type' => array(
|
| 7671 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7672 |
),
|
| 7673 |
),
|
| 7674 |
'tag_spec' => array(
|
| 7675 |
'extension_spec' => array(
|
| 7676 |
-
'
|
|
|
|
| 7677 |
'0.1',
|
| 7678 |
'latest',
|
| 7679 |
),
|
| 7680 |
-
'deprecated_allow_duplicates' => true,
|
| 7681 |
-
'name' => 'amp-font',
|
| 7682 |
-
'requires_usage' => 2,
|
| 7683 |
),
|
| 7684 |
),
|
| 7685 |
),
|
|
@@ -7687,22 +10618,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7687 |
'attr_spec_list' => array(
|
| 7688 |
'async' => array(
|
| 7689 |
'mandatory' => true,
|
| 7690 |
-
'value' =>
|
|
|
|
|
|
|
| 7691 |
),
|
| 7692 |
'nonce' => array(),
|
| 7693 |
'type' => array(
|
| 7694 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7695 |
),
|
| 7696 |
),
|
| 7697 |
'tag_spec' => array(
|
| 7698 |
'extension_spec' => array(
|
| 7699 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7700 |
'0.1',
|
| 7701 |
'latest',
|
| 7702 |
),
|
| 7703 |
-
'deprecated_allow_duplicates' => true,
|
| 7704 |
-
'name' => 'amp-form',
|
| 7705 |
-
'requires_usage' => 2,
|
| 7706 |
),
|
| 7707 |
),
|
| 7708 |
),
|
|
@@ -7710,21 +10645,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7710 |
'attr_spec_list' => array(
|
| 7711 |
'async' => array(
|
| 7712 |
'mandatory' => true,
|
| 7713 |
-
'value' =>
|
|
|
|
|
|
|
| 7714 |
),
|
| 7715 |
'nonce' => array(),
|
| 7716 |
'type' => array(
|
| 7717 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7718 |
),
|
| 7719 |
),
|
| 7720 |
'tag_spec' => array(
|
| 7721 |
'extension_spec' => array(
|
| 7722 |
-
'
|
|
|
|
| 7723 |
'0.1',
|
| 7724 |
'latest',
|
| 7725 |
),
|
| 7726 |
-
'name' => 'amp-fx-collection',
|
| 7727 |
-
'requires_usage' => 3,
|
| 7728 |
),
|
| 7729 |
),
|
| 7730 |
),
|
|
@@ -7732,22 +10670,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7732 |
'attr_spec_list' => array(
|
| 7733 |
'async' => array(
|
| 7734 |
'mandatory' => true,
|
| 7735 |
-
'value' =>
|
|
|
|
|
|
|
| 7736 |
),
|
| 7737 |
'nonce' => array(),
|
| 7738 |
'type' => array(
|
| 7739 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7740 |
),
|
| 7741 |
),
|
| 7742 |
'tag_spec' => array(
|
| 7743 |
'extension_spec' => array(
|
| 7744 |
-
'
|
|
|
|
| 7745 |
'0.1',
|
| 7746 |
'latest',
|
| 7747 |
),
|
| 7748 |
-
'deprecated_allow_duplicates' => true,
|
| 7749 |
-
'name' => 'amp-fx-flying-carpet',
|
| 7750 |
-
'requires_usage' => 2,
|
| 7751 |
),
|
| 7752 |
),
|
| 7753 |
),
|
|
@@ -7755,22 +10695,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7755 |
'attr_spec_list' => array(
|
| 7756 |
'async' => array(
|
| 7757 |
'mandatory' => true,
|
| 7758 |
-
'value' =>
|
|
|
|
|
|
|
| 7759 |
),
|
| 7760 |
'nonce' => array(),
|
| 7761 |
'type' => array(
|
| 7762 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7763 |
),
|
| 7764 |
),
|
| 7765 |
'tag_spec' => array(
|
| 7766 |
'extension_spec' => array(
|
| 7767 |
-
'
|
|
|
|
|
|
|
| 7768 |
'0.1',
|
| 7769 |
'latest',
|
| 7770 |
),
|
| 7771 |
-
'deprecated_allow_duplicates' => true,
|
| 7772 |
-
'name' => 'amp-gfycat',
|
| 7773 |
-
'requires_usage' => 2,
|
| 7774 |
),
|
| 7775 |
),
|
| 7776 |
),
|
|
@@ -7778,20 +10721,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7778 |
'attr_spec_list' => array(
|
| 7779 |
'async' => array(
|
| 7780 |
'mandatory' => true,
|
| 7781 |
-
'value' =>
|
|
|
|
|
|
|
| 7782 |
),
|
| 7783 |
'nonce' => array(),
|
| 7784 |
'type' => array(
|
| 7785 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7786 |
),
|
| 7787 |
),
|
| 7788 |
'tag_spec' => array(
|
| 7789 |
'extension_spec' => array(
|
| 7790 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7791 |
'0.1',
|
| 7792 |
'latest',
|
| 7793 |
),
|
| 7794 |
-
'name' => 'amp-gist',
|
| 7795 |
),
|
| 7796 |
),
|
| 7797 |
),
|
|
@@ -7799,20 +10748,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7799 |
'attr_spec_list' => array(
|
| 7800 |
'async' => array(
|
| 7801 |
'mandatory' => true,
|
| 7802 |
-
'value' =>
|
|
|
|
|
|
|
| 7803 |
),
|
| 7804 |
'nonce' => array(),
|
| 7805 |
'type' => array(
|
| 7806 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7807 |
),
|
| 7808 |
),
|
| 7809 |
'tag_spec' => array(
|
| 7810 |
'extension_spec' => array(
|
| 7811 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7812 |
'0.1',
|
| 7813 |
'latest',
|
| 7814 |
),
|
| 7815 |
-
'name' => 'amp-hulu',
|
| 7816 |
),
|
| 7817 |
),
|
| 7818 |
),
|
|
@@ -7820,22 +10775,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7820 |
'attr_spec_list' => array(
|
| 7821 |
'async' => array(
|
| 7822 |
'mandatory' => true,
|
| 7823 |
-
'value' =>
|
|
|
|
|
|
|
| 7824 |
),
|
| 7825 |
'nonce' => array(),
|
| 7826 |
'type' => array(
|
| 7827 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7828 |
),
|
| 7829 |
),
|
| 7830 |
'tag_spec' => array(
|
| 7831 |
'extension_spec' => array(
|
| 7832 |
-
'
|
|
|
|
|
|
|
| 7833 |
'0.1',
|
| 7834 |
'latest',
|
| 7835 |
),
|
| 7836 |
-
'deprecated_allow_duplicates' => true,
|
| 7837 |
-
'name' => 'amp-iframe',
|
| 7838 |
-
'requires_usage' => 2,
|
| 7839 |
),
|
| 7840 |
),
|
| 7841 |
),
|
|
@@ -7843,20 +10801,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7843 |
'attr_spec_list' => array(
|
| 7844 |
'async' => array(
|
| 7845 |
'mandatory' => true,
|
| 7846 |
-
'value' =>
|
|
|
|
|
|
|
| 7847 |
),
|
| 7848 |
'nonce' => array(),
|
| 7849 |
'type' => array(
|
| 7850 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7851 |
),
|
| 7852 |
),
|
| 7853 |
'tag_spec' => array(
|
| 7854 |
'extension_spec' => array(
|
| 7855 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7856 |
'0.1',
|
| 7857 |
'latest',
|
| 7858 |
),
|
| 7859 |
-
'name' => 'amp-ima-video',
|
| 7860 |
),
|
| 7861 |
),
|
| 7862 |
),
|
|
@@ -7864,22 +10828,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7864 |
'attr_spec_list' => array(
|
| 7865 |
'async' => array(
|
| 7866 |
'mandatory' => true,
|
| 7867 |
-
'value' =>
|
|
|
|
|
|
|
| 7868 |
),
|
| 7869 |
'nonce' => array(),
|
| 7870 |
'type' => array(
|
| 7871 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7872 |
),
|
| 7873 |
),
|
| 7874 |
'tag_spec' => array(
|
| 7875 |
'extension_spec' => array(
|
| 7876 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7877 |
'0.1',
|
| 7878 |
'latest',
|
| 7879 |
),
|
| 7880 |
-
'deprecated_allow_duplicates' => true,
|
| 7881 |
-
'name' => 'amp-image-lightbox',
|
| 7882 |
-
'requires_usage' => 2,
|
| 7883 |
),
|
| 7884 |
),
|
| 7885 |
),
|
|
@@ -7887,20 +10855,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7887 |
'attr_spec_list' => array(
|
| 7888 |
'async' => array(
|
| 7889 |
'mandatory' => true,
|
| 7890 |
-
'value' =>
|
|
|
|
|
|
|
| 7891 |
),
|
| 7892 |
'nonce' => array(),
|
| 7893 |
'type' => array(
|
| 7894 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7895 |
),
|
| 7896 |
),
|
| 7897 |
'tag_spec' => array(
|
| 7898 |
'extension_spec' => array(
|
| 7899 |
-
'
|
|
|
|
|
|
|
| 7900 |
'0.1',
|
| 7901 |
'latest',
|
| 7902 |
),
|
| 7903 |
-
'name' => 'amp-imgur',
|
| 7904 |
),
|
| 7905 |
),
|
| 7906 |
),
|
|
@@ -7908,22 +10881,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7908 |
'attr_spec_list' => array(
|
| 7909 |
'async' => array(
|
| 7910 |
'mandatory' => true,
|
| 7911 |
-
'value' =>
|
|
|
|
|
|
|
| 7912 |
),
|
| 7913 |
'nonce' => array(),
|
| 7914 |
'type' => array(
|
| 7915 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7916 |
),
|
| 7917 |
),
|
| 7918 |
'tag_spec' => array(
|
| 7919 |
'extension_spec' => array(
|
| 7920 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7921 |
'0.1',
|
| 7922 |
'latest',
|
| 7923 |
),
|
| 7924 |
-
'deprecated_allow_duplicates' => true,
|
| 7925 |
-
'name' => 'amp-instagram',
|
| 7926 |
-
'requires_usage' => 2,
|
| 7927 |
),
|
| 7928 |
),
|
| 7929 |
),
|
|
@@ -7931,22 +10908,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7931 |
'attr_spec_list' => array(
|
| 7932 |
'async' => array(
|
| 7933 |
'mandatory' => true,
|
| 7934 |
-
'value' =>
|
|
|
|
|
|
|
| 7935 |
),
|
| 7936 |
'nonce' => array(),
|
| 7937 |
'type' => array(
|
| 7938 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7939 |
),
|
| 7940 |
),
|
| 7941 |
'tag_spec' => array(
|
| 7942 |
'extension_spec' => array(
|
| 7943 |
-
'
|
|
|
|
|
|
|
|
|
|
| 7944 |
'0.1',
|
| 7945 |
'latest',
|
| 7946 |
),
|
| 7947 |
-
'deprecated_allow_duplicates' => true,
|
| 7948 |
-
'name' => 'amp-install-serviceworker',
|
| 7949 |
-
'requires_usage' => 2,
|
| 7950 |
),
|
| 7951 |
),
|
| 7952 |
),
|
|
@@ -7954,44 +10935,52 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7954 |
'attr_spec_list' => array(
|
| 7955 |
'async' => array(
|
| 7956 |
'mandatory' => true,
|
| 7957 |
-
'value' =>
|
|
|
|
|
|
|
| 7958 |
),
|
| 7959 |
'nonce' => array(),
|
| 7960 |
'type' => array(
|
| 7961 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7962 |
),
|
| 7963 |
),
|
| 7964 |
'tag_spec' => array(
|
| 7965 |
'extension_spec' => array(
|
| 7966 |
-
'
|
|
|
|
|
|
|
| 7967 |
'0.1',
|
| 7968 |
'latest',
|
| 7969 |
),
|
| 7970 |
-
'name' => 'amp-izlesene',
|
| 7971 |
-
'requires_usage' => 2,
|
| 7972 |
),
|
|
|
|
|
|
|
| 7973 |
),
|
| 7974 |
),
|
| 7975 |
array(
|
| 7976 |
'attr_spec_list' => array(
|
| 7977 |
'async' => array(
|
| 7978 |
'mandatory' => true,
|
| 7979 |
-
'value' =>
|
|
|
|
|
|
|
| 7980 |
),
|
| 7981 |
'nonce' => array(),
|
| 7982 |
'type' => array(
|
| 7983 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 7984 |
),
|
| 7985 |
),
|
| 7986 |
'tag_spec' => array(
|
| 7987 |
'extension_spec' => array(
|
| 7988 |
-
'
|
|
|
|
| 7989 |
'0.1',
|
| 7990 |
'latest',
|
| 7991 |
),
|
| 7992 |
-
'deprecated_allow_duplicates' => true,
|
| 7993 |
-
'name' => 'amp-jwplayer',
|
| 7994 |
-
'requires_usage' => 2,
|
| 7995 |
),
|
| 7996 |
),
|
| 7997 |
),
|
|
@@ -7999,22 +10988,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 7999 |
'attr_spec_list' => array(
|
| 8000 |
'async' => array(
|
| 8001 |
'mandatory' => true,
|
| 8002 |
-
'value' =>
|
|
|
|
|
|
|
| 8003 |
),
|
| 8004 |
'nonce' => array(),
|
| 8005 |
'type' => array(
|
| 8006 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8007 |
),
|
| 8008 |
),
|
| 8009 |
'tag_spec' => array(
|
| 8010 |
'extension_spec' => array(
|
| 8011 |
-
'
|
|
|
|
| 8012 |
'0.1',
|
| 8013 |
'latest',
|
| 8014 |
),
|
| 8015 |
-
'deprecated_allow_duplicates' => true,
|
| 8016 |
-
'name' => 'amp-kaltura-player',
|
| 8017 |
-
'requires_usage' => 2,
|
| 8018 |
),
|
| 8019 |
),
|
| 8020 |
),
|
|
@@ -8022,21 +11013,31 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8022 |
'attr_spec_list' => array(
|
| 8023 |
'async' => array(
|
| 8024 |
'mandatory' => true,
|
| 8025 |
-
'value' =>
|
|
|
|
|
|
|
| 8026 |
),
|
| 8027 |
'nonce' => array(),
|
| 8028 |
'type' => array(
|
| 8029 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8030 |
),
|
| 8031 |
),
|
| 8032 |
'tag_spec' => array(
|
| 8033 |
'extension_spec' => array(
|
| 8034 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8035 |
'0.1',
|
|
|
|
| 8036 |
'latest',
|
| 8037 |
),
|
| 8038 |
-
'name' => 'amp-lightbox-gallery',
|
| 8039 |
-
'requires_usage' => 3,
|
| 8040 |
),
|
| 8041 |
),
|
| 8042 |
),
|
|
@@ -8044,45 +11045,68 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8044 |
'attr_spec_list' => array(
|
| 8045 |
'async' => array(
|
| 8046 |
'mandatory' => true,
|
| 8047 |
-
'value' =>
|
|
|
|
|
|
|
| 8048 |
),
|
| 8049 |
'nonce' => array(),
|
| 8050 |
'type' => array(
|
| 8051 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8052 |
),
|
| 8053 |
),
|
| 8054 |
'tag_spec' => array(
|
| 8055 |
'extension_spec' => array(
|
| 8056 |
-
'
|
|
|
|
| 8057 |
'0.1',
|
| 8058 |
'latest',
|
| 8059 |
),
|
| 8060 |
-
'deprecated_allow_duplicates' => true,
|
| 8061 |
-
'name' => 'amp-lightbox',
|
| 8062 |
-
'requires_usage' => 2,
|
| 8063 |
),
|
| 8064 |
),
|
| 8065 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8066 |
array(
|
| 8067 |
'attr_spec_list' => array(
|
| 8068 |
'async' => array(
|
| 8069 |
'mandatory' => true,
|
| 8070 |
-
'value' =>
|
|
|
|
|
|
|
| 8071 |
),
|
| 8072 |
'nonce' => array(),
|
| 8073 |
'type' => array(
|
| 8074 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8075 |
),
|
| 8076 |
),
|
| 8077 |
'tag_spec' => array(
|
| 8078 |
'extension_spec' => array(
|
| 8079 |
-
'
|
|
|
|
| 8080 |
'0.1',
|
| 8081 |
-
'latest',
|
| 8082 |
-
),
|
| 8083 |
-
'deprecated_allow_duplicates' => true,
|
| 8084 |
-
'name' => 'amp-list',
|
| 8085 |
-
'requires_usage' => 2,
|
| 8086 |
),
|
| 8087 |
),
|
| 8088 |
),
|
|
@@ -8090,44 +11114,51 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8090 |
'attr_spec_list' => array(
|
| 8091 |
'async' => array(
|
| 8092 |
'mandatory' => true,
|
| 8093 |
-
'value' =>
|
|
|
|
|
|
|
| 8094 |
),
|
| 8095 |
'nonce' => array(),
|
| 8096 |
'type' => array(
|
| 8097 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8098 |
),
|
| 8099 |
),
|
| 8100 |
'tag_spec' => array(
|
| 8101 |
'extension_spec' => array(
|
| 8102 |
-
'
|
|
|
|
|
|
|
|
|
|
| 8103 |
'0.1',
|
| 8104 |
'latest',
|
| 8105 |
),
|
| 8106 |
-
'name' => 'amp-live-list',
|
| 8107 |
-
'requires_usage' => 2,
|
| 8108 |
),
|
| 8109 |
-
'mandatory_parent' => 'head',
|
| 8110 |
-
'unique_warning' => true,
|
| 8111 |
),
|
| 8112 |
),
|
| 8113 |
array(
|
| 8114 |
'attr_spec_list' => array(
|
| 8115 |
'async' => array(
|
| 8116 |
'mandatory' => true,
|
| 8117 |
-
'value' =>
|
|
|
|
|
|
|
| 8118 |
),
|
| 8119 |
'nonce' => array(),
|
| 8120 |
'type' => array(
|
| 8121 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8122 |
),
|
| 8123 |
),
|
| 8124 |
'tag_spec' => array(
|
| 8125 |
'extension_spec' => array(
|
| 8126 |
-
'
|
|
|
|
| 8127 |
'0.1',
|
| 8128 |
'latest',
|
| 8129 |
),
|
| 8130 |
-
'name' => 'amp-mathml',
|
| 8131 |
),
|
| 8132 |
),
|
| 8133 |
),
|
|
@@ -8135,23 +11166,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8135 |
'attr_spec_list' => array(
|
| 8136 |
'async' => array(
|
| 8137 |
'mandatory' => true,
|
| 8138 |
-
'value' =>
|
|
|
|
|
|
|
| 8139 |
),
|
| 8140 |
'nonce' => array(),
|
| 8141 |
'type' => array(
|
| 8142 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8143 |
),
|
| 8144 |
),
|
| 8145 |
'tag_spec' => array(
|
| 8146 |
'extension_spec' => array(
|
| 8147 |
-
'
|
|
|
|
| 8148 |
'0.1',
|
| 8149 |
'latest',
|
| 8150 |
),
|
| 8151 |
-
'deprecated_allow_duplicates' => true,
|
| 8152 |
-
'is_custom_template' => true,
|
| 8153 |
-
'name' => 'amp-mustache',
|
| 8154 |
-
'requires_usage' => 2,
|
| 8155 |
),
|
| 8156 |
),
|
| 8157 |
),
|
|
@@ -8159,20 +11191,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8159 |
'attr_spec_list' => array(
|
| 8160 |
'async' => array(
|
| 8161 |
'mandatory' => true,
|
| 8162 |
-
'value' =>
|
|
|
|
|
|
|
| 8163 |
),
|
| 8164 |
'nonce' => array(),
|
| 8165 |
'type' => array(
|
| 8166 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8167 |
),
|
| 8168 |
),
|
| 8169 |
'tag_spec' => array(
|
| 8170 |
'extension_spec' => array(
|
| 8171 |
-
'
|
|
|
|
| 8172 |
'0.1',
|
| 8173 |
'latest',
|
| 8174 |
),
|
| 8175 |
-
'name' => 'amp-nexxtv-player',
|
| 8176 |
),
|
| 8177 |
),
|
| 8178 |
),
|
|
@@ -8180,22 +11216,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8180 |
'attr_spec_list' => array(
|
| 8181 |
'async' => array(
|
| 8182 |
'mandatory' => true,
|
| 8183 |
-
'value' =>
|
|
|
|
|
|
|
| 8184 |
),
|
| 8185 |
'nonce' => array(),
|
| 8186 |
'type' => array(
|
| 8187 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8188 |
),
|
| 8189 |
),
|
| 8190 |
'tag_spec' => array(
|
| 8191 |
'extension_spec' => array(
|
| 8192 |
-
'
|
|
|
|
|
|
|
|
|
|
| 8193 |
'0.1',
|
| 8194 |
'latest',
|
| 8195 |
),
|
| 8196 |
-
'deprecated_allow_duplicates' => true,
|
| 8197 |
-
'name' => 'amp-o2-player',
|
| 8198 |
-
'requires_usage' => 2,
|
| 8199 |
),
|
| 8200 |
),
|
| 8201 |
),
|
|
@@ -8203,20 +11243,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8203 |
'attr_spec_list' => array(
|
| 8204 |
'async' => array(
|
| 8205 |
'mandatory' => true,
|
| 8206 |
-
'value' =>
|
|
|
|
|
|
|
| 8207 |
),
|
| 8208 |
'nonce' => array(),
|
| 8209 |
'type' => array(
|
| 8210 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8211 |
),
|
| 8212 |
),
|
| 8213 |
'tag_spec' => array(
|
| 8214 |
'extension_spec' => array(
|
| 8215 |
-
'
|
|
|
|
| 8216 |
'0.1',
|
| 8217 |
'latest',
|
| 8218 |
),
|
| 8219 |
-
'name' => 'amp-ooyala-player',
|
| 8220 |
),
|
| 8221 |
),
|
| 8222 |
),
|
|
@@ -8224,22 +11268,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8224 |
'attr_spec_list' => array(
|
| 8225 |
'async' => array(
|
| 8226 |
'mandatory' => true,
|
| 8227 |
-
'value' =>
|
|
|
|
|
|
|
| 8228 |
),
|
| 8229 |
'nonce' => array(),
|
| 8230 |
'type' => array(
|
| 8231 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8232 |
),
|
| 8233 |
),
|
| 8234 |
'tag_spec' => array(
|
| 8235 |
'extension_spec' => array(
|
| 8236 |
-
'
|
|
|
|
| 8237 |
'0.1',
|
| 8238 |
'latest',
|
| 8239 |
),
|
| 8240 |
-
'deprecated_allow_duplicates' => true,
|
| 8241 |
-
'name' => 'amp-pinterest',
|
| 8242 |
-
'requires_usage' => 2,
|
| 8243 |
),
|
| 8244 |
),
|
| 8245 |
),
|
|
@@ -8247,20 +11293,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8247 |
'attr_spec_list' => array(
|
| 8248 |
'async' => array(
|
| 8249 |
'mandatory' => true,
|
| 8250 |
-
'value' =>
|
|
|
|
|
|
|
| 8251 |
),
|
| 8252 |
'nonce' => array(),
|
| 8253 |
'type' => array(
|
| 8254 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8255 |
),
|
| 8256 |
),
|
| 8257 |
'tag_spec' => array(
|
| 8258 |
'extension_spec' => array(
|
| 8259 |
-
'
|
|
|
|
| 8260 |
'0.1',
|
| 8261 |
'latest',
|
| 8262 |
),
|
| 8263 |
-
'name' => 'amp-playbuzz',
|
| 8264 |
),
|
| 8265 |
),
|
| 8266 |
),
|
|
@@ -8268,20 +11318,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8268 |
'attr_spec_list' => array(
|
| 8269 |
'async' => array(
|
| 8270 |
'mandatory' => true,
|
| 8271 |
-
'value' =>
|
|
|
|
|
|
|
| 8272 |
),
|
| 8273 |
'nonce' => array(),
|
| 8274 |
'type' => array(
|
| 8275 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8276 |
),
|
| 8277 |
),
|
| 8278 |
'tag_spec' => array(
|
| 8279 |
'extension_spec' => array(
|
| 8280 |
-
'
|
|
|
|
|
|
|
|
|
|
| 8281 |
'0.1',
|
| 8282 |
'latest',
|
| 8283 |
),
|
| 8284 |
-
'name' => 'amp-position-observer',
|
| 8285 |
),
|
| 8286 |
),
|
| 8287 |
),
|
|
@@ -8289,22 +11345,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8289 |
'attr_spec_list' => array(
|
| 8290 |
'async' => array(
|
| 8291 |
'mandatory' => true,
|
| 8292 |
-
'value' =>
|
|
|
|
|
|
|
| 8293 |
),
|
| 8294 |
'nonce' => array(),
|
| 8295 |
'type' => array(
|
| 8296 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8297 |
),
|
| 8298 |
),
|
| 8299 |
'tag_spec' => array(
|
| 8300 |
'extension_spec' => array(
|
| 8301 |
-
'
|
|
|
|
|
|
|
| 8302 |
'0.1',
|
| 8303 |
'latest',
|
| 8304 |
),
|
| 8305 |
-
'deprecated_allow_duplicates' => true,
|
| 8306 |
-
'name' => 'amp-reach-player',
|
| 8307 |
-
'requires_usage' => 2,
|
| 8308 |
),
|
| 8309 |
),
|
| 8310 |
),
|
|
@@ -8312,21 +11371,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8312 |
'attr_spec_list' => array(
|
| 8313 |
'async' => array(
|
| 8314 |
'mandatory' => true,
|
| 8315 |
-
'value' =>
|
|
|
|
|
|
|
| 8316 |
),
|
| 8317 |
'nonce' => array(),
|
| 8318 |
'type' => array(
|
| 8319 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8320 |
),
|
| 8321 |
),
|
| 8322 |
'tag_spec' => array(
|
| 8323 |
'extension_spec' => array(
|
| 8324 |
-
'
|
|
|
|
| 8325 |
'0.1',
|
| 8326 |
'latest',
|
| 8327 |
),
|
| 8328 |
-
'deprecated_allow_duplicates' => true,
|
| 8329 |
-
'name' => 'amp-reddit',
|
| 8330 |
),
|
| 8331 |
),
|
| 8332 |
),
|
|
@@ -8334,20 +11396,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8334 |
'attr_spec_list' => array(
|
| 8335 |
'async' => array(
|
| 8336 |
'mandatory' => true,
|
| 8337 |
-
'value' =>
|
|
|
|
|
|
|
| 8338 |
),
|
| 8339 |
'nonce' => array(),
|
| 8340 |
'type' => array(
|
| 8341 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8342 |
),
|
| 8343 |
),
|
| 8344 |
'tag_spec' => array(
|
| 8345 |
'extension_spec' => array(
|
| 8346 |
-
'
|
|
|
|
|
|
|
| 8347 |
'0.1',
|
| 8348 |
'latest',
|
| 8349 |
),
|
| 8350 |
-
'name' => 'amp-riddle-quiz',
|
| 8351 |
),
|
| 8352 |
),
|
| 8353 |
),
|
|
@@ -8355,21 +11422,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8355 |
'attr_spec_list' => array(
|
| 8356 |
'async' => array(
|
| 8357 |
'mandatory' => true,
|
| 8358 |
-
'value' =>
|
|
|
|
|
|
|
| 8359 |
),
|
| 8360 |
'nonce' => array(),
|
| 8361 |
'type' => array(
|
| 8362 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8363 |
),
|
| 8364 |
),
|
| 8365 |
'tag_spec' => array(
|
| 8366 |
'extension_spec' => array(
|
| 8367 |
-
'
|
|
|
|
|
|
|
|
|
|
| 8368 |
'0.1',
|
| 8369 |
'latest',
|
| 8370 |
),
|
| 8371 |
-
'name' => 'amp-selector',
|
| 8372 |
-
'requires_usage' => 2,
|
| 8373 |
),
|
| 8374 |
),
|
| 8375 |
),
|
|
@@ -8377,22 +11449,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8377 |
'attr_spec_list' => array(
|
| 8378 |
'async' => array(
|
| 8379 |
'mandatory' => true,
|
| 8380 |
-
'value' =>
|
|
|
|
|
|
|
| 8381 |
),
|
| 8382 |
'nonce' => array(),
|
| 8383 |
'type' => array(
|
| 8384 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8385 |
),
|
| 8386 |
),
|
| 8387 |
'tag_spec' => array(
|
| 8388 |
'extension_spec' => array(
|
| 8389 |
-
'
|
|
|
|
| 8390 |
'0.1',
|
| 8391 |
'latest',
|
| 8392 |
),
|
| 8393 |
-
'deprecated_allow_duplicates' => true,
|
| 8394 |
-
'name' => 'amp-sidebar',
|
| 8395 |
-
'requires_usage' => 2,
|
| 8396 |
),
|
| 8397 |
),
|
| 8398 |
),
|
|
@@ -8400,22 +11474,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8400 |
'attr_spec_list' => array(
|
| 8401 |
'async' => array(
|
| 8402 |
'mandatory' => true,
|
| 8403 |
-
'value' =>
|
|
|
|
|
|
|
| 8404 |
),
|
| 8405 |
'nonce' => array(),
|
| 8406 |
'type' => array(
|
| 8407 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8408 |
),
|
| 8409 |
),
|
| 8410 |
'tag_spec' => array(
|
| 8411 |
'extension_spec' => array(
|
| 8412 |
-
'allowed_versions' => array(
|
| 8413 |
-
'0.1',
|
| 8414 |
-
'latest',
|
| 8415 |
-
),
|
| 8416 |
'deprecated_allow_duplicates' => true,
|
| 8417 |
'name' => 'amp-social-share',
|
| 8418 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8419 |
),
|
| 8420 |
),
|
| 8421 |
),
|
|
@@ -8423,22 +11501,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8423 |
'attr_spec_list' => array(
|
| 8424 |
'async' => array(
|
| 8425 |
'mandatory' => true,
|
| 8426 |
-
'value' =>
|
|
|
|
|
|
|
| 8427 |
),
|
| 8428 |
'nonce' => array(),
|
| 8429 |
'type' => array(
|
| 8430 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8431 |
),
|
| 8432 |
),
|
| 8433 |
'tag_spec' => array(
|
| 8434 |
'extension_spec' => array(
|
| 8435 |
-
'allowed_versions' => array(
|
| 8436 |
-
'0.1',
|
| 8437 |
-
'latest',
|
| 8438 |
-
),
|
| 8439 |
'deprecated_allow_duplicates' => true,
|
| 8440 |
'name' => 'amp-soundcloud',
|
| 8441 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8442 |
),
|
| 8443 |
),
|
| 8444 |
),
|
|
@@ -8446,22 +11528,26 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8446 |
'attr_spec_list' => array(
|
| 8447 |
'async' => array(
|
| 8448 |
'mandatory' => true,
|
| 8449 |
-
'value' =>
|
|
|
|
|
|
|
| 8450 |
),
|
| 8451 |
'nonce' => array(),
|
| 8452 |
'type' => array(
|
| 8453 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8454 |
),
|
| 8455 |
),
|
| 8456 |
'tag_spec' => array(
|
| 8457 |
'extension_spec' => array(
|
| 8458 |
-
'allowed_versions' => array(
|
| 8459 |
-
'0.1',
|
| 8460 |
-
'latest',
|
| 8461 |
-
),
|
| 8462 |
'deprecated_allow_duplicates' => true,
|
| 8463 |
'name' => 'amp-springboard-player',
|
| 8464 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8465 |
),
|
| 8466 |
),
|
| 8467 |
),
|
|
@@ -8469,25 +11555,29 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8469 |
'attr_spec_list' => array(
|
| 8470 |
'async' => array(
|
| 8471 |
'mandatory' => true,
|
| 8472 |
-
'value' =>
|
|
|
|
|
|
|
| 8473 |
),
|
| 8474 |
'nonce' => array(),
|
| 8475 |
'type' => array(
|
| 8476 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8477 |
),
|
| 8478 |
),
|
| 8479 |
'tag_spec' => array(
|
| 8480 |
'extension_spec' => array(
|
| 8481 |
-
'
|
| 8482 |
-
'0.1',
|
| 8483 |
-
'1.0',
|
| 8484 |
-
'latest',
|
| 8485 |
-
),
|
| 8486 |
-
'deprecated_versions' => array(
|
| 8487 |
'0.1',
|
| 8488 |
),
|
| 8489 |
'name' => 'amp-sticky-ad',
|
| 8490 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8491 |
),
|
| 8492 |
),
|
| 8493 |
),
|
|
@@ -8495,20 +11585,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8495 |
'attr_spec_list' => array(
|
| 8496 |
'async' => array(
|
| 8497 |
'mandatory' => true,
|
| 8498 |
-
'value' =>
|
|
|
|
|
|
|
| 8499 |
),
|
| 8500 |
'nonce' => array(),
|
| 8501 |
'type' => array(
|
| 8502 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8503 |
),
|
| 8504 |
),
|
| 8505 |
'tag_spec' => array(
|
| 8506 |
'extension_spec' => array(
|
| 8507 |
-
'
|
|
|
|
| 8508 |
'0.1',
|
| 8509 |
'latest',
|
| 8510 |
),
|
| 8511 |
-
'name' => 'amp-story-auto-ads',
|
| 8512 |
),
|
| 8513 |
),
|
| 8514 |
),
|
|
@@ -8518,7 +11612,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8518 |
'type' => array(
|
| 8519 |
'dispatch_key' => 3,
|
| 8520 |
'mandatory' => true,
|
| 8521 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8522 |
),
|
| 8523 |
),
|
| 8524 |
'cdata' => array(
|
|
@@ -8540,42 +11636,97 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8540 |
'attr_spec_list' => array(
|
| 8541 |
'async' => array(
|
| 8542 |
'mandatory' => true,
|
| 8543 |
-
'value' =>
|
|
|
|
|
|
|
| 8544 |
),
|
| 8545 |
'nonce' => array(),
|
| 8546 |
'type' => array(
|
| 8547 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8548 |
),
|
| 8549 |
),
|
| 8550 |
'tag_spec' => array(
|
| 8551 |
'extension_spec' => array(
|
| 8552 |
-
'
|
|
|
|
| 8553 |
'0.1',
|
|
|
|
| 8554 |
'latest',
|
| 8555 |
),
|
| 8556 |
-
'name' => 'amp-story',
|
| 8557 |
),
|
| 8558 |
),
|
| 8559 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8560 |
array(
|
| 8561 |
'attr_spec_list' => array(
|
| 8562 |
'async' => array(
|
| 8563 |
'mandatory' => true,
|
| 8564 |
-
'value' =>
|
|
|
|
|
|
|
| 8565 |
),
|
| 8566 |
'nonce' => array(),
|
| 8567 |
'type' => array(
|
| 8568 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8569 |
),
|
| 8570 |
),
|
| 8571 |
'tag_spec' => array(
|
| 8572 |
'extension_spec' => array(
|
| 8573 |
-
'
|
|
|
|
|
|
|
| 8574 |
'0.1',
|
| 8575 |
'latest',
|
| 8576 |
),
|
| 8577 |
-
'name' => 'amp-subscriptions',
|
| 8578 |
-
'requires_usage' => 3,
|
| 8579 |
),
|
| 8580 |
),
|
| 8581 |
),
|
|
@@ -8584,12 +11735,16 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8584 |
'id' => array(
|
| 8585 |
'dispatch_key' => 2,
|
| 8586 |
'mandatory' => true,
|
| 8587 |
-
'value' =>
|
|
|
|
|
|
|
| 8588 |
),
|
| 8589 |
'nonce' => array(),
|
| 8590 |
'type' => array(
|
| 8591 |
'mandatory' => true,
|
| 8592 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8593 |
),
|
| 8594 |
),
|
| 8595 |
'cdata' => array(
|
|
@@ -8611,21 +11766,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8611 |
'attr_spec_list' => array(
|
| 8612 |
'async' => array(
|
| 8613 |
'mandatory' => true,
|
| 8614 |
-
'value' =>
|
|
|
|
|
|
|
| 8615 |
),
|
| 8616 |
'nonce' => array(),
|
| 8617 |
'type' => array(
|
| 8618 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8619 |
),
|
| 8620 |
),
|
| 8621 |
'tag_spec' => array(
|
| 8622 |
'extension_spec' => array(
|
| 8623 |
-
'
|
|
|
|
|
|
|
| 8624 |
'0.1',
|
| 8625 |
'latest',
|
| 8626 |
),
|
| 8627 |
-
'name' => 'amp-subscriptions-google',
|
| 8628 |
-
'requires_usage' => 3,
|
| 8629 |
),
|
| 8630 |
'requires_extension' => array(
|
| 8631 |
'amp-subscriptions',
|
|
@@ -8636,20 +11795,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8636 |
'attr_spec_list' => array(
|
| 8637 |
'async' => array(
|
| 8638 |
'mandatory' => true,
|
| 8639 |
-
'value' =>
|
|
|
|
|
|
|
| 8640 |
),
|
| 8641 |
'nonce' => array(),
|
| 8642 |
'type' => array(
|
| 8643 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8644 |
),
|
| 8645 |
),
|
| 8646 |
'tag_spec' => array(
|
| 8647 |
'extension_spec' => array(
|
| 8648 |
-
'
|
|
|
|
| 8649 |
'0.1',
|
| 8650 |
'latest',
|
| 8651 |
),
|
| 8652 |
-
'name' => 'amp-timeago',
|
| 8653 |
),
|
| 8654 |
),
|
| 8655 |
),
|
|
@@ -8657,22 +11820,53 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8657 |
'attr_spec_list' => array(
|
| 8658 |
'async' => array(
|
| 8659 |
'mandatory' => true,
|
| 8660 |
-
'value' =>
|
|
|
|
|
|
|
| 8661 |
),
|
| 8662 |
'nonce' => array(),
|
| 8663 |
'type' => array(
|
| 8664 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8665 |
),
|
| 8666 |
),
|
| 8667 |
'tag_spec' => array(
|
| 8668 |
'extension_spec' => array(
|
| 8669 |
-
'
|
|
|
|
|
|
|
|
|
|
| 8670 |
'0.1',
|
| 8671 |
'latest',
|
| 8672 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8673 |
'deprecated_allow_duplicates' => true,
|
| 8674 |
-
'name' => 'amp-
|
| 8675 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8676 |
),
|
| 8677 |
),
|
| 8678 |
),
|
|
@@ -8680,22 +11874,53 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8680 |
'attr_spec_list' => array(
|
| 8681 |
'async' => array(
|
| 8682 |
'mandatory' => true,
|
| 8683 |
-
'value' =>
|
|
|
|
|
|
|
| 8684 |
),
|
| 8685 |
'nonce' => array(),
|
| 8686 |
'type' => array(
|
| 8687 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8688 |
),
|
| 8689 |
),
|
| 8690 |
'tag_spec' => array(
|
| 8691 |
'extension_spec' => array(
|
| 8692 |
-
'
|
|
|
|
|
|
|
| 8693 |
'0.1',
|
| 8694 |
'latest',
|
| 8695 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8696 |
'deprecated_allow_duplicates' => true,
|
| 8697 |
-
'name' => 'amp-
|
| 8698 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8699 |
),
|
| 8700 |
),
|
| 8701 |
),
|
|
@@ -8703,45 +11928,51 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8703 |
'attr_spec_list' => array(
|
| 8704 |
'async' => array(
|
| 8705 |
'mandatory' => true,
|
| 8706 |
-
'value' =>
|
|
|
|
|
|
|
| 8707 |
),
|
| 8708 |
'nonce' => array(),
|
| 8709 |
'type' => array(
|
| 8710 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8711 |
),
|
| 8712 |
),
|
| 8713 |
'tag_spec' => array(
|
| 8714 |
'extension_spec' => array(
|
| 8715 |
-
'
|
|
|
|
|
|
|
|
|
|
| 8716 |
'0.1',
|
| 8717 |
'latest',
|
| 8718 |
),
|
| 8719 |
-
'name' => 'amp-video',
|
| 8720 |
-
'requires_usage' => 3,
|
| 8721 |
),
|
| 8722 |
-
'spec_name' => 'amp-video extension .js script',
|
| 8723 |
),
|
| 8724 |
),
|
| 8725 |
array(
|
| 8726 |
'attr_spec_list' => array(
|
| 8727 |
'async' => array(
|
| 8728 |
'mandatory' => true,
|
| 8729 |
-
'value' =>
|
|
|
|
|
|
|
| 8730 |
),
|
| 8731 |
'nonce' => array(),
|
| 8732 |
'type' => array(
|
| 8733 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8734 |
),
|
| 8735 |
),
|
| 8736 |
'tag_spec' => array(
|
| 8737 |
'extension_spec' => array(
|
| 8738 |
-
'
|
|
|
|
| 8739 |
'0.1',
|
| 8740 |
'latest',
|
| 8741 |
),
|
| 8742 |
-
'deprecated_allow_duplicates' => true,
|
| 8743 |
-
'name' => 'amp-vimeo',
|
| 8744 |
-
'requires_usage' => 2,
|
| 8745 |
),
|
| 8746 |
),
|
| 8747 |
),
|
|
@@ -8749,22 +11980,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8749 |
'attr_spec_list' => array(
|
| 8750 |
'async' => array(
|
| 8751 |
'mandatory' => true,
|
| 8752 |
-
'value' =>
|
|
|
|
|
|
|
| 8753 |
),
|
| 8754 |
'nonce' => array(),
|
| 8755 |
'type' => array(
|
| 8756 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8757 |
),
|
| 8758 |
),
|
| 8759 |
'tag_spec' => array(
|
| 8760 |
'extension_spec' => array(
|
| 8761 |
-
'
|
|
|
|
| 8762 |
'0.1',
|
| 8763 |
'latest',
|
| 8764 |
),
|
| 8765 |
-
'deprecated_allow_duplicates' => true,
|
| 8766 |
-
'name' => 'amp-vine',
|
| 8767 |
-
'requires_usage' => 2,
|
| 8768 |
),
|
| 8769 |
),
|
| 8770 |
),
|
|
@@ -8772,20 +12005,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8772 |
'attr_spec_list' => array(
|
| 8773 |
'async' => array(
|
| 8774 |
'mandatory' => true,
|
| 8775 |
-
'value' =>
|
|
|
|
|
|
|
| 8776 |
),
|
| 8777 |
'nonce' => array(),
|
| 8778 |
'type' => array(
|
| 8779 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8780 |
),
|
| 8781 |
),
|
| 8782 |
'tag_spec' => array(
|
| 8783 |
'extension_spec' => array(
|
| 8784 |
-
'
|
|
|
|
| 8785 |
'0.1',
|
| 8786 |
'latest',
|
| 8787 |
),
|
| 8788 |
-
'name' => 'amp-vk',
|
| 8789 |
),
|
| 8790 |
),
|
| 8791 |
),
|
|
@@ -8793,20 +12030,24 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8793 |
'attr_spec_list' => array(
|
| 8794 |
'async' => array(
|
| 8795 |
'mandatory' => true,
|
| 8796 |
-
'value' =>
|
|
|
|
|
|
|
| 8797 |
),
|
| 8798 |
'nonce' => array(),
|
| 8799 |
'type' => array(
|
| 8800 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8801 |
),
|
| 8802 |
),
|
| 8803 |
'tag_spec' => array(
|
| 8804 |
'extension_spec' => array(
|
| 8805 |
-
'
|
|
|
|
| 8806 |
'0.1',
|
| 8807 |
'latest',
|
| 8808 |
),
|
| 8809 |
-
'name' => 'amp-web-push',
|
| 8810 |
),
|
| 8811 |
),
|
| 8812 |
),
|
|
@@ -8814,43 +12055,52 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8814 |
'attr_spec_list' => array(
|
| 8815 |
'async' => array(
|
| 8816 |
'mandatory' => true,
|
| 8817 |
-
'value' =>
|
|
|
|
|
|
|
| 8818 |
),
|
| 8819 |
'nonce' => array(),
|
| 8820 |
'type' => array(
|
| 8821 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8822 |
),
|
| 8823 |
),
|
| 8824 |
'tag_spec' => array(
|
| 8825 |
'extension_spec' => array(
|
| 8826 |
-
'
|
|
|
|
| 8827 |
'0.1',
|
| 8828 |
'latest',
|
| 8829 |
),
|
| 8830 |
-
'name' => 'amp-wistia-player',
|
| 8831 |
),
|
|
|
|
| 8832 |
),
|
| 8833 |
),
|
| 8834 |
array(
|
| 8835 |
'attr_spec_list' => array(
|
| 8836 |
'async' => array(
|
| 8837 |
'mandatory' => true,
|
| 8838 |
-
'value' =>
|
|
|
|
|
|
|
| 8839 |
),
|
| 8840 |
'nonce' => array(),
|
| 8841 |
'type' => array(
|
| 8842 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 8843 |
),
|
| 8844 |
),
|
| 8845 |
'tag_spec' => array(
|
| 8846 |
'extension_spec' => array(
|
| 8847 |
-
'allowed_versions' => array(
|
| 8848 |
-
'0.1',
|
| 8849 |
-
'latest',
|
| 8850 |
-
),
|
| 8851 |
'deprecated_allow_duplicates' => true,
|
| 8852 |
'name' => 'amp-youtube',
|
| 8853 |
'requires_usage' => 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8854 |
),
|
| 8855 |
),
|
| 8856 |
),
|
|
@@ -8867,7 +12117,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8867 |
array(
|
| 8868 |
'attr_spec_list' => array(
|
| 8869 |
'expanded' => array(
|
| 8870 |
-
'value' =>
|
|
|
|
|
|
|
| 8871 |
),
|
| 8872 |
),
|
| 8873 |
'tag_spec' => array(
|
|
@@ -8890,6 +12142,11 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8890 |
'name' => array(
|
| 8891 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 8892 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8893 |
'required' => array(),
|
| 8894 |
'size' => array(),
|
| 8895 |
),
|
|
@@ -8936,6 +12193,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8936 |
'filter' => array(),
|
| 8937 |
'flood-color' => array(),
|
| 8938 |
'flood-opacity' => array(),
|
|
|
|
| 8939 |
'font-family' => array(),
|
| 8940 |
'font-size' => array(),
|
| 8941 |
'font-size-adjust' => array(),
|
|
@@ -8992,6 +12250,29 @@ class AMP_Allowed_Tags_Generated {
|
|
| 8992 |
),
|
| 8993 |
),
|
| 8994 |
'source' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8995 |
array(
|
| 8996 |
'attr_spec_list' => array(
|
| 8997 |
'[src]' => array(),
|
|
@@ -9001,7 +12282,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9001 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 9002 |
'value_url' => array(
|
| 9003 |
'allow_relative' => true,
|
| 9004 |
-
'
|
| 9005 |
'https',
|
| 9006 |
),
|
| 9007 |
),
|
|
@@ -9023,7 +12304,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9023 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 9024 |
'value_url' => array(
|
| 9025 |
'allow_relative' => true,
|
| 9026 |
-
'
|
| 9027 |
'https',
|
| 9028 |
),
|
| 9029 |
),
|
|
@@ -9044,7 +12325,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9044 |
'mandatory' => true,
|
| 9045 |
'value_url' => array(
|
| 9046 |
'allow_relative' => true,
|
| 9047 |
-
'
|
| 9048 |
'https',
|
| 9049 |
),
|
| 9050 |
),
|
|
@@ -9067,7 +12348,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9067 |
'mandatory' => true,
|
| 9068 |
'value_url' => array(
|
| 9069 |
'allow_relative' => true,
|
| 9070 |
-
'
|
| 9071 |
'https',
|
| 9072 |
),
|
| 9073 |
),
|
|
@@ -9091,7 +12372,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9091 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 9092 |
'value_url' => array(
|
| 9093 |
'allow_relative' => true,
|
| 9094 |
-
'
|
| 9095 |
'https',
|
| 9096 |
),
|
| 9097 |
),
|
|
@@ -9168,11 +12449,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9168 |
'attr_spec_list' => array(
|
| 9169 |
'amp-custom' => array(
|
| 9170 |
'mandatory' => true,
|
| 9171 |
-
'value' =>
|
|
|
|
|
|
|
| 9172 |
),
|
| 9173 |
'nonce' => array(),
|
| 9174 |
'type' => array(
|
| 9175 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 9176 |
),
|
| 9177 |
),
|
| 9178 |
'cdata' => array(
|
|
@@ -9180,6 +12465,34 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9180 |
'error_message' => 'CSS !important',
|
| 9181 |
'regex' => '!important',
|
| 9182 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9183 |
'max_bytes' => 50000,
|
| 9184 |
'max_bytes_spec_url' => 'https://www.ampproject.org/docs/reference/spec#maximum-size',
|
| 9185 |
),
|
|
@@ -9190,17 +12503,34 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9190 |
'unique' => true,
|
| 9191 |
),
|
| 9192 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9193 |
array(
|
| 9194 |
'attr_spec_list' => array(
|
| 9195 |
'amp-boilerplate' => array(
|
| 9196 |
'dispatch_key' => 3,
|
| 9197 |
'mandatory' => true,
|
| 9198 |
-
'value' =>
|
|
|
|
|
|
|
| 9199 |
),
|
| 9200 |
'nonce' => array(),
|
| 9201 |
),
|
| 9202 |
'cdata' => array(
|
| 9203 |
-
'cdata_regex' => '\\s*body{
|
| 9204 |
),
|
| 9205 |
'tag_spec' => array(
|
| 9206 |
'mandatory_alternatives' => 'head > style[amp-boilerplate]',
|
|
@@ -9215,12 +12545,14 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9215 |
'amp-boilerplate' => array(
|
| 9216 |
'dispatch_key' => 3,
|
| 9217 |
'mandatory' => true,
|
| 9218 |
-
'value' =>
|
|
|
|
|
|
|
| 9219 |
),
|
| 9220 |
'nonce' => array(),
|
| 9221 |
),
|
| 9222 |
'cdata' => array(
|
| 9223 |
-
'cdata_regex' => '\\s*body{
|
| 9224 |
),
|
| 9225 |
'tag_spec' => array(
|
| 9226 |
'mandatory_alternatives' => 'noscript > style[amp-boilerplate]',
|
|
@@ -9236,10 +12568,29 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9236 |
'amp-keyframes' => array(
|
| 9237 |
'dispatch_key' => 1,
|
| 9238 |
'mandatory' => true,
|
| 9239 |
-
'value' =>
|
|
|
|
|
|
|
| 9240 |
),
|
| 9241 |
),
|
| 9242 |
'cdata' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9243 |
'max_bytes' => 500000,
|
| 9244 |
'max_bytes_spec_url' => 'https://www.ampproject.org/docs/reference/spec#keyframes-stylesheet',
|
| 9245 |
),
|
|
@@ -9289,6 +12640,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9289 |
'filter' => array(),
|
| 9290 |
'flood-color' => array(),
|
| 9291 |
'flood-opacity' => array(),
|
|
|
|
| 9292 |
'font-family' => array(),
|
| 9293 |
'font-size' => array(),
|
| 9294 |
'font-size-adjust' => array(),
|
|
@@ -9324,6 +12676,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9324 |
'stroke-miterlimit' => array(),
|
| 9325 |
'stroke-opacity' => array(),
|
| 9326 |
'stroke-width' => array(),
|
|
|
|
|
|
|
|
|
|
| 9327 |
'systemlanguage' => array(),
|
| 9328 |
'text-anchor' => array(),
|
| 9329 |
'text-decoration' => array(),
|
|
@@ -9331,7 +12686,10 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9331 |
'unicode-bidi' => array(),
|
| 9332 |
'vector-effect' => array(),
|
| 9333 |
'version' => array(
|
| 9334 |
-
'
|
|
|
|
|
|
|
|
|
|
| 9335 |
),
|
| 9336 |
'viewbox' => array(),
|
| 9337 |
'visibility' => array(),
|
|
@@ -9375,6 +12733,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9375 |
'filter' => array(),
|
| 9376 |
'flood-color' => array(),
|
| 9377 |
'flood-opacity' => array(),
|
|
|
|
| 9378 |
'font-family' => array(),
|
| 9379 |
'font-size' => array(),
|
| 9380 |
'font-size-adjust' => array(),
|
|
@@ -9456,6 +12815,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9456 |
'filter' => array(),
|
| 9457 |
'flood-color' => array(),
|
| 9458 |
'flood-opacity' => array(),
|
|
|
|
| 9459 |
'font-family' => array(),
|
| 9460 |
'font-size' => array(),
|
| 9461 |
'font-size-adjust' => array(),
|
|
@@ -9517,7 +12877,10 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9517 |
'align' => array(),
|
| 9518 |
'bgcolor' => array(),
|
| 9519 |
'border' => array(
|
| 9520 |
-
'
|
|
|
|
|
|
|
|
|
|
| 9521 |
),
|
| 9522 |
'cellpadding' => array(),
|
| 9523 |
'cellspacing' => array(),
|
|
@@ -9549,19 +12912,71 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9549 |
),
|
| 9550 |
),
|
| 9551 |
'template' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9552 |
array(
|
| 9553 |
'attr_spec_list' => array(
|
| 9554 |
'type' => array(
|
| 9555 |
'mandatory' => true,
|
| 9556 |
-
'value' =>
|
|
|
|
|
|
|
| 9557 |
),
|
| 9558 |
),
|
| 9559 |
'tag_spec' => array(
|
| 9560 |
'disallowed_ancestor' => array(
|
| 9561 |
'template',
|
|
|
|
| 9562 |
'amp-story-auto-ads',
|
| 9563 |
-
'form
|
| 9564 |
-
'form
|
|
|
|
|
|
|
| 9565 |
),
|
| 9566 |
'requires_extension' => array(
|
| 9567 |
'amp-mustache',
|
|
@@ -9571,12 +12986,25 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9571 |
array(
|
| 9572 |
'attr_spec_list' => array(
|
| 9573 |
'type' => array(
|
|
|
|
| 9574 |
'mandatory' => true,
|
| 9575 |
-
'value' =>
|
|
|
|
|
|
|
| 9576 |
),
|
| 9577 |
),
|
| 9578 |
'tag_spec' => array(
|
| 9579 |
'mandatory_parent' => 'amp-story-auto-ads',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9580 |
'requires_extension' => array(
|
| 9581 |
'amp-mustache',
|
| 9582 |
),
|
|
@@ -9611,6 +13039,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9611 |
'filter' => array(),
|
| 9612 |
'flood-color' => array(),
|
| 9613 |
'flood-opacity' => array(),
|
|
|
|
| 9614 |
'font-family' => array(),
|
| 9615 |
'font-size' => array(),
|
| 9616 |
'font-size-adjust' => array(),
|
|
@@ -9700,6 +13129,11 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9700 |
'name' => array(
|
| 9701 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 9702 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9703 |
'placeholder' => array(),
|
| 9704 |
'readonly' => array(),
|
| 9705 |
'required' => array(),
|
|
@@ -9740,6 +13174,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9740 |
'filter' => array(),
|
| 9741 |
'flood-color' => array(),
|
| 9742 |
'flood-opacity' => array(),
|
|
|
|
| 9743 |
'font-family' => array(),
|
| 9744 |
'font-size' => array(),
|
| 9745 |
'font-size-adjust' => array(),
|
|
@@ -9796,8 +13231,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9796 |
),
|
| 9797 |
'value_url' => array(
|
| 9798 |
'allow_empty' => false,
|
| 9799 |
-
'
|
| 9800 |
-
'allowed_protocol' => array(
|
| 9801 |
'http',
|
| 9802 |
'https',
|
| 9803 |
),
|
|
@@ -9858,7 +13292,9 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9858 |
),
|
| 9859 |
'title' => array(
|
| 9860 |
array(
|
| 9861 |
-
'attr_spec_list' => array(
|
|
|
|
|
|
|
| 9862 |
'tag_spec' => array(
|
| 9863 |
'spec_name' => 'title',
|
| 9864 |
),
|
|
@@ -9895,10 +13331,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9895 |
array(
|
| 9896 |
'attr_spec_list' => array(
|
| 9897 |
'default' => array(
|
| 9898 |
-
'value' =>
|
|
|
|
|
|
|
| 9899 |
),
|
| 9900 |
'kind' => array(
|
| 9901 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9902 |
),
|
| 9903 |
'label' => array(),
|
| 9904 |
'src' => array(
|
|
@@ -9906,7 +13349,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9906 |
'mandatory' => true,
|
| 9907 |
'value_url' => array(
|
| 9908 |
'allow_relative' => false,
|
| 9909 |
-
'
|
| 9910 |
'https',
|
| 9911 |
),
|
| 9912 |
),
|
|
@@ -9921,11 +13364,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9921 |
array(
|
| 9922 |
'attr_spec_list' => array(
|
| 9923 |
'default' => array(
|
| 9924 |
-
'value' =>
|
|
|
|
|
|
|
| 9925 |
),
|
| 9926 |
'kind' => array(
|
| 9927 |
'mandatory' => true,
|
| 9928 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 9929 |
),
|
| 9930 |
'label' => array(),
|
| 9931 |
'src' => array(
|
|
@@ -9933,7 +13380,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9933 |
'mandatory' => true,
|
| 9934 |
'value_url' => array(
|
| 9935 |
'allow_relative' => false,
|
| 9936 |
-
'
|
| 9937 |
'https',
|
| 9938 |
),
|
| 9939 |
),
|
|
@@ -9950,10 +13397,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9950 |
array(
|
| 9951 |
'attr_spec_list' => array(
|
| 9952 |
'default' => array(
|
| 9953 |
-
'value' =>
|
|
|
|
|
|
|
| 9954 |
),
|
| 9955 |
'kind' => array(
|
| 9956 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9957 |
),
|
| 9958 |
'label' => array(),
|
| 9959 |
'src' => array(
|
|
@@ -9961,7 +13415,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9961 |
'mandatory' => true,
|
| 9962 |
'value_url' => array(
|
| 9963 |
'allow_relative' => false,
|
| 9964 |
-
'
|
| 9965 |
'https',
|
| 9966 |
),
|
| 9967 |
),
|
|
@@ -9976,11 +13430,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9976 |
array(
|
| 9977 |
'attr_spec_list' => array(
|
| 9978 |
'default' => array(
|
| 9979 |
-
'value' =>
|
|
|
|
|
|
|
| 9980 |
),
|
| 9981 |
'kind' => array(
|
| 9982 |
'mandatory' => true,
|
| 9983 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 9984 |
),
|
| 9985 |
'label' => array(),
|
| 9986 |
'src' => array(
|
|
@@ -9988,7 +13446,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 9988 |
'mandatory' => true,
|
| 9989 |
'value_url' => array(
|
| 9990 |
'allow_relative' => false,
|
| 9991 |
-
'
|
| 9992 |
'https',
|
| 9993 |
),
|
| 9994 |
),
|
|
@@ -10008,10 +13466,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10008 |
'[src]' => array(),
|
| 10009 |
'[srclang]' => array(),
|
| 10010 |
'default' => array(
|
| 10011 |
-
'value' =>
|
|
|
|
|
|
|
| 10012 |
),
|
| 10013 |
'kind' => array(
|
| 10014 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10015 |
),
|
| 10016 |
'label' => array(),
|
| 10017 |
'src' => array(
|
|
@@ -10019,7 +13484,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10019 |
'mandatory' => true,
|
| 10020 |
'value_url' => array(
|
| 10021 |
'allow_relative' => false,
|
| 10022 |
-
'
|
| 10023 |
'https',
|
| 10024 |
),
|
| 10025 |
),
|
|
@@ -10037,11 +13502,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10037 |
'[src]' => array(),
|
| 10038 |
'[srclang]' => array(),
|
| 10039 |
'default' => array(
|
| 10040 |
-
'value' =>
|
|
|
|
|
|
|
| 10041 |
),
|
| 10042 |
'kind' => array(
|
| 10043 |
'mandatory' => true,
|
| 10044 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 10045 |
),
|
| 10046 |
'label' => array(),
|
| 10047 |
'src' => array(
|
|
@@ -10049,7 +13518,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10049 |
'mandatory' => true,
|
| 10050 |
'value_url' => array(
|
| 10051 |
'allow_relative' => false,
|
| 10052 |
-
'
|
| 10053 |
'https',
|
| 10054 |
),
|
| 10055 |
),
|
|
@@ -10069,10 +13538,17 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10069 |
'[src]' => array(),
|
| 10070 |
'[srclang]' => array(),
|
| 10071 |
'default' => array(
|
| 10072 |
-
'value' =>
|
|
|
|
|
|
|
| 10073 |
),
|
| 10074 |
'kind' => array(
|
| 10075 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10076 |
),
|
| 10077 |
'label' => array(),
|
| 10078 |
'src' => array(
|
|
@@ -10080,7 +13556,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10080 |
'mandatory' => true,
|
| 10081 |
'value_url' => array(
|
| 10082 |
'allow_relative' => false,
|
| 10083 |
-
'
|
| 10084 |
'https',
|
| 10085 |
),
|
| 10086 |
),
|
|
@@ -10098,11 +13574,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10098 |
'[src]' => array(),
|
| 10099 |
'[srclang]' => array(),
|
| 10100 |
'default' => array(
|
| 10101 |
-
'value' =>
|
|
|
|
|
|
|
| 10102 |
),
|
| 10103 |
'kind' => array(
|
| 10104 |
'mandatory' => true,
|
| 10105 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 10106 |
),
|
| 10107 |
'label' => array(),
|
| 10108 |
'src' => array(
|
|
@@ -10110,7 +13590,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10110 |
'mandatory' => true,
|
| 10111 |
'value_url' => array(
|
| 10112 |
'allow_relative' => false,
|
| 10113 |
-
'
|
| 10114 |
'https',
|
| 10115 |
),
|
| 10116 |
),
|
|
@@ -10130,11 +13610,15 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10130 |
'[src]' => array(),
|
| 10131 |
'[srclang]' => array(),
|
| 10132 |
'default' => array(
|
| 10133 |
-
'value' =>
|
|
|
|
|
|
|
| 10134 |
),
|
| 10135 |
'kind' => array(
|
| 10136 |
'mandatory' => true,
|
| 10137 |
-
'value_casei' =>
|
|
|
|
|
|
|
| 10138 |
),
|
| 10139 |
'label' => array(),
|
| 10140 |
'src' => array(
|
|
@@ -10142,7 +13626,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10142 |
'mandatory' => true,
|
| 10143 |
'value_url' => array(
|
| 10144 |
'allow_relative' => false,
|
| 10145 |
-
'
|
| 10146 |
'https',
|
| 10147 |
),
|
| 10148 |
),
|
|
@@ -10183,6 +13667,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10183 |
'filter' => array(),
|
| 10184 |
'flood-color' => array(),
|
| 10185 |
'flood-opacity' => array(),
|
|
|
|
| 10186 |
'font-family' => array(),
|
| 10187 |
'font-size' => array(),
|
| 10188 |
'font-size-adjust' => array(),
|
|
@@ -10236,8 +13721,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10236 |
),
|
| 10237 |
'value_url' => array(
|
| 10238 |
'allow_empty' => false,
|
| 10239 |
-
'
|
| 10240 |
-
'allowed_protocol' => array(
|
| 10241 |
'http',
|
| 10242 |
'https',
|
| 10243 |
),
|
|
@@ -10285,6 +13769,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10285 |
'filter' => array(),
|
| 10286 |
'flood-color' => array(),
|
| 10287 |
'flood-opacity' => array(),
|
|
|
|
| 10288 |
'font-family' => array(),
|
| 10289 |
'font-size' => array(),
|
| 10290 |
'font-size-adjust' => array(),
|
|
@@ -10389,6 +13874,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10389 |
'filter' => array(),
|
| 10390 |
'flood-color' => array(),
|
| 10391 |
'flood-opacity' => array(),
|
|
|
|
| 10392 |
'font-family' => array(),
|
| 10393 |
'font-size' => array(),
|
| 10394 |
'font-size-adjust' => array(),
|
|
@@ -10446,8 +13932,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10446 |
),
|
| 10447 |
'value_url' => array(
|
| 10448 |
'allow_empty' => false,
|
| 10449 |
-
'
|
| 10450 |
-
'allowed_protocol' => array(
|
| 10451 |
'http',
|
| 10452 |
'https',
|
| 10453 |
),
|
|
@@ -10490,7 +13975,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10490 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 10491 |
'value_url' => array(
|
| 10492 |
'allow_relative' => false,
|
| 10493 |
-
'
|
| 10494 |
'data',
|
| 10495 |
'https',
|
| 10496 |
),
|
|
@@ -10555,12 +14040,6 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10555 |
'tag_spec' => array(),
|
| 10556 |
),
|
| 10557 |
),
|
| 10558 |
-
'xmp' => array(
|
| 10559 |
-
array(
|
| 10560 |
-
'attr_spec_list' => array(),
|
| 10561 |
-
'tag_spec' => array(),
|
| 10562 |
-
),
|
| 10563 |
-
),
|
| 10564 |
);
|
| 10565 |
|
| 10566 |
private static $layout_allowed_attrs = array(
|
|
@@ -10627,7 +14106,7 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10627 |
'amp-access-style' => array(),
|
| 10628 |
'amp-access-template' => array(),
|
| 10629 |
'amp-fx' => array(
|
| 10630 |
-
'
|
| 10631 |
),
|
| 10632 |
'aria-activedescendant' => array(),
|
| 10633 |
'aria-atomic' => array(),
|
|
@@ -10673,10 +14152,14 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10673 |
'dir' => array(),
|
| 10674 |
'draggable' => array(),
|
| 10675 |
'fallback' => array(
|
| 10676 |
-
'value' =>
|
|
|
|
|
|
|
| 10677 |
),
|
| 10678 |
'hidden' => array(
|
| 10679 |
-
'value' =>
|
|
|
|
|
|
|
| 10680 |
),
|
| 10681 |
'i-amp-access-id' => array(),
|
| 10682 |
'id' => array(
|
|
@@ -10689,11 +14172,12 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10689 |
'itemscope' => array(),
|
| 10690 |
'itemtype' => array(),
|
| 10691 |
'lang' => array(),
|
| 10692 |
-
'lightbox' => array(),
|
| 10693 |
'on' => array(),
|
| 10694 |
'overflow' => array(),
|
| 10695 |
'placeholder' => array(
|
| 10696 |
-
'value' =>
|
|
|
|
|
|
|
| 10697 |
),
|
| 10698 |
'prefix' => array(),
|
| 10699 |
'property' => array(),
|
|
@@ -10703,16 +14187,29 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10703 |
'resource' => array(),
|
| 10704 |
'rev' => array(),
|
| 10705 |
'role' => array(),
|
|
|
|
|
|
|
|
|
|
| 10706 |
'subscriptions-action' => array(),
|
| 10707 |
'subscriptions-actions' => array(
|
| 10708 |
-
'value' =>
|
|
|
|
|
|
|
| 10709 |
),
|
|
|
|
| 10710 |
'subscriptions-dialog' => array(
|
| 10711 |
-
'value' =>
|
|
|
|
|
|
|
| 10712 |
),
|
| 10713 |
'subscriptions-display' => array(),
|
| 10714 |
'subscriptions-section' => array(
|
| 10715 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10716 |
),
|
| 10717 |
'subscriptions-service' => array(),
|
| 10718 |
'tabindex' => array(),
|
|
@@ -10721,12 +14218,349 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10721 |
'typeof' => array(),
|
| 10722 |
'validation-for' => array(),
|
| 10723 |
'visible-when-invalid' => array(
|
| 10724 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10725 |
),
|
| 10726 |
'vocab' => array(),
|
| 10727 |
);
|
| 10728 |
|
| 10729 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10730 |
/**
|
| 10731 |
* Get allowed tags.
|
| 10732 |
*
|
|
@@ -10753,6 +14587,20 @@ class AMP_Allowed_Tags_Generated {
|
|
| 10753 |
return null;
|
| 10754 |
}
|
| 10755 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10756 |
/**
|
| 10757 |
* Get list of globally-allowed attributes.
|
| 10758 |
*
|
| 13 |
*/
|
| 14 |
class AMP_Allowed_Tags_Generated {
|
| 15 |
|
| 16 |
+
private static $spec_file_revision = 767;
|
| 17 |
+
private static $minimum_validator_revision_required = 348;
|
| 18 |
|
| 19 |
private static $allowed_tags = array(
|
| 20 |
'a' => array(
|
| 27 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 28 |
'value_url' => array(
|
| 29 |
'allow_empty' => true,
|
| 30 |
+
'protocol' => array(
|
|
|
|
| 31 |
'ftp',
|
| 32 |
'geo',
|
| 33 |
'http',
|
| 34 |
'https',
|
| 35 |
'mailto',
|
| 36 |
'maps',
|
| 37 |
+
'bip',
|
| 38 |
'bbmi',
|
| 39 |
'fb-messenger',
|
| 40 |
'intent',
|
| 47 |
'threema',
|
| 48 |
'twitter',
|
| 49 |
'viber',
|
| 50 |
+
'webcal',
|
| 51 |
+
'web+mastodon',
|
| 52 |
'whatsapp',
|
| 53 |
),
|
| 54 |
),
|
| 63 |
'role' => array(),
|
| 64 |
'tabindex' => array(),
|
| 65 |
'target' => array(
|
| 66 |
+
'value' => array(
|
| 67 |
+
'_blank',
|
| 68 |
+
'_self',
|
| 69 |
+
'_top',
|
| 70 |
+
),
|
| 71 |
),
|
| 72 |
'type' => array(
|
| 73 |
+
'value_casei' => array(
|
| 74 |
+
'text/html',
|
| 75 |
+
),
|
| 76 |
),
|
| 77 |
),
|
| 78 |
'tag_spec' => array(
|
| 98 |
'tag_spec' => array(),
|
| 99 |
),
|
| 100 |
),
|
| 101 |
+
'amp-3d-gltf' => array(
|
| 102 |
+
array(
|
| 103 |
+
'attr_spec_list' => array(
|
| 104 |
+
'alpha' => array(
|
| 105 |
+
'value' => array(
|
| 106 |
+
'false',
|
| 107 |
+
'true',
|
| 108 |
+
),
|
| 109 |
+
),
|
| 110 |
+
'antialiasing' => array(
|
| 111 |
+
'value' => array(
|
| 112 |
+
'false',
|
| 113 |
+
'true',
|
| 114 |
+
),
|
| 115 |
+
),
|
| 116 |
+
'autorotate' => array(
|
| 117 |
+
'value' => array(
|
| 118 |
+
'false',
|
| 119 |
+
'true',
|
| 120 |
+
),
|
| 121 |
+
),
|
| 122 |
+
'clearcolor' => array(),
|
| 123 |
+
'enablezoom' => array(
|
| 124 |
+
'value' => array(
|
| 125 |
+
'false',
|
| 126 |
+
'true',
|
| 127 |
+
),
|
| 128 |
+
),
|
| 129 |
+
'maxpixelratio' => array(
|
| 130 |
+
'value_regex' => '[+-]?(\\d*\\.)?\\d+',
|
| 131 |
+
),
|
| 132 |
+
'media' => array(),
|
| 133 |
+
'noloading' => array(
|
| 134 |
+
'value' => array(
|
| 135 |
+
'',
|
| 136 |
+
),
|
| 137 |
+
),
|
| 138 |
+
'src' => array(
|
| 139 |
+
'mandatory' => true,
|
| 140 |
+
'value_url' => array(
|
| 141 |
+
'protocol' => array(
|
| 142 |
+
'https',
|
| 143 |
+
),
|
| 144 |
+
),
|
| 145 |
+
),
|
| 146 |
+
),
|
| 147 |
+
'tag_spec' => array(
|
| 148 |
+
'amp_layout' => array(
|
| 149 |
+
'supported_layouts' => array(
|
| 150 |
+
6,
|
| 151 |
+
2,
|
| 152 |
+
3,
|
| 153 |
+
7,
|
| 154 |
+
4,
|
| 155 |
+
),
|
| 156 |
+
),
|
| 157 |
+
'requires_extension' => array(
|
| 158 |
+
'amp-3d-gltf',
|
| 159 |
+
),
|
| 160 |
+
),
|
| 161 |
+
),
|
| 162 |
+
),
|
| 163 |
'amp-3q-player' => array(
|
| 164 |
array(
|
| 165 |
'attr_spec_list' => array(
|
| 166 |
'autoplay' => array(
|
| 167 |
+
'value' => array(
|
| 168 |
+
'',
|
| 169 |
+
),
|
| 170 |
),
|
| 171 |
'data-id' => array(
|
| 172 |
'mandatory' => true,
|
| 173 |
),
|
| 174 |
'media' => array(),
|
| 175 |
'noloading' => array(
|
| 176 |
+
'value' => array(
|
| 177 |
+
'',
|
| 178 |
+
),
|
| 179 |
),
|
| 180 |
),
|
| 181 |
'tag_spec' => array(
|
| 182 |
+
'amp_layout' => array(
|
| 183 |
+
'supported_layouts' => array(
|
| 184 |
+
6,
|
| 185 |
+
2,
|
| 186 |
+
7,
|
| 187 |
+
4,
|
| 188 |
+
),
|
| 189 |
+
),
|
| 190 |
'requires_extension' => array(
|
| 191 |
'amp-3q-player',
|
| 192 |
),
|
| 196 |
'amp-accordion' => array(
|
| 197 |
array(
|
| 198 |
'attr_spec_list' => array(
|
| 199 |
+
'animate' => array(
|
| 200 |
+
'value' => array(
|
| 201 |
+
'',
|
| 202 |
+
),
|
| 203 |
+
),
|
| 204 |
'disable-session-states' => array(
|
| 205 |
+
'value' => array(
|
| 206 |
+
'',
|
| 207 |
+
),
|
| 208 |
),
|
| 209 |
'expand-single-section' => array(
|
| 210 |
+
'value' => array(
|
| 211 |
+
'',
|
| 212 |
+
),
|
| 213 |
+
),
|
| 214 |
+
'media' => array(),
|
| 215 |
+
'noloading' => array(
|
| 216 |
+
'value' => array(
|
| 217 |
+
'',
|
| 218 |
+
),
|
| 219 |
),
|
| 220 |
),
|
| 221 |
'tag_spec' => array(
|
| 222 |
+
'amp_layout' => array(
|
| 223 |
+
'supported_layouts' => array(
|
| 224 |
+
5,
|
| 225 |
+
),
|
| 226 |
+
),
|
| 227 |
'requires_extension' => array(
|
| 228 |
'amp-accordion',
|
| 229 |
),
|
| 238 |
'json' => array(),
|
| 239 |
'media' => array(),
|
| 240 |
'noloading' => array(
|
| 241 |
+
'value' => array(
|
| 242 |
+
'',
|
| 243 |
+
),
|
| 244 |
),
|
| 245 |
'rtc-config' => array(),
|
| 246 |
'src' => array(
|
| 247 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 248 |
'value_url' => array(
|
| 249 |
'allow_relative' => true,
|
| 250 |
+
'protocol' => array(
|
| 251 |
'https',
|
| 252 |
),
|
| 253 |
),
|
| 261 |
'also_requires_tag_warning' => array(
|
| 262 |
'amp-ad extension .js script',
|
| 263 |
),
|
| 264 |
+
'amp_layout' => array(
|
| 265 |
+
'supported_layouts' => array(
|
| 266 |
+
6,
|
| 267 |
+
2,
|
| 268 |
+
3,
|
| 269 |
+
7,
|
| 270 |
+
8,
|
| 271 |
+
9,
|
| 272 |
+
1,
|
| 273 |
+
4,
|
| 274 |
+
),
|
| 275 |
+
),
|
| 276 |
'disallowed_ancestor' => array(
|
| 277 |
'amp-app-banner',
|
| 278 |
),
|
| 288 |
'data-multi-size' => array(
|
| 289 |
'dispatch_key' => 2,
|
| 290 |
'mandatory' => true,
|
| 291 |
+
'value' => array(
|
| 292 |
+
'',
|
| 293 |
+
),
|
| 294 |
),
|
| 295 |
'json' => array(),
|
| 296 |
'media' => array(),
|
| 297 |
'noloading' => array(
|
| 298 |
+
'value' => array(
|
| 299 |
+
'',
|
| 300 |
+
),
|
| 301 |
),
|
| 302 |
'rtc-config' => array(),
|
| 303 |
'src' => array(
|
| 304 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 305 |
'value_url' => array(
|
| 306 |
'allow_relative' => true,
|
| 307 |
+
'protocol' => array(
|
| 308 |
'https',
|
| 309 |
),
|
| 310 |
),
|
| 317 |
'also_requires_tag_warning' => array(
|
| 318 |
'amp-ad extension .js script',
|
| 319 |
),
|
| 320 |
+
'amp_layout' => array(
|
| 321 |
+
'supported_layouts' => array(
|
| 322 |
+
6,
|
| 323 |
+
2,
|
| 324 |
+
3,
|
| 325 |
+
7,
|
| 326 |
+
8,
|
| 327 |
+
9,
|
| 328 |
+
1,
|
| 329 |
+
4,
|
| 330 |
+
),
|
| 331 |
+
),
|
| 332 |
'disallowed_ancestor' => array(
|
| 333 |
'amp-app-banner',
|
| 334 |
'amp-carousel',
|
| 349 |
'data-enable-refresh' => array(
|
| 350 |
'dispatch_key' => 2,
|
| 351 |
'mandatory' => true,
|
| 352 |
+
'value' => array(
|
| 353 |
+
'',
|
| 354 |
+
),
|
| 355 |
),
|
| 356 |
'json' => array(),
|
| 357 |
'media' => array(),
|
| 358 |
'noloading' => array(
|
| 359 |
+
'value' => array(
|
| 360 |
+
'',
|
| 361 |
+
),
|
| 362 |
),
|
| 363 |
'src' => array(
|
| 364 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 365 |
'value_url' => array(
|
| 366 |
'allow_relative' => true,
|
| 367 |
+
'protocol' => array(
|
| 368 |
'https',
|
| 369 |
),
|
| 370 |
),
|
| 377 |
'also_requires_tag_warning' => array(
|
| 378 |
'amp-ad extension .js script',
|
| 379 |
),
|
| 380 |
+
'amp_layout' => array(
|
| 381 |
+
'supported_layouts' => array(
|
| 382 |
+
6,
|
| 383 |
+
2,
|
| 384 |
+
3,
|
| 385 |
+
7,
|
| 386 |
+
8,
|
| 387 |
+
9,
|
| 388 |
+
1,
|
| 389 |
+
4,
|
| 390 |
+
),
|
| 391 |
+
),
|
| 392 |
'disallowed_ancestor' => array(
|
| 393 |
'amp-app-banner',
|
| 394 |
'amp-fx-flying-carpet',
|
| 402 |
),
|
| 403 |
),
|
| 404 |
),
|
| 405 |
+
'amp-addthis' => array(
|
| 406 |
+
array(
|
| 407 |
+
'attr_spec_list' => array(
|
| 408 |
+
'data-pub-id' => array(
|
| 409 |
+
'mandatory' => true,
|
| 410 |
+
),
|
| 411 |
+
'data-share-media' => array(
|
| 412 |
+
'value_url' => array(
|
| 413 |
+
'allow_empty' => true,
|
| 414 |
+
'protocol' => array(
|
| 415 |
+
'http',
|
| 416 |
+
'https',
|
| 417 |
+
),
|
| 418 |
+
),
|
| 419 |
+
),
|
| 420 |
+
'data-share-url' => array(
|
| 421 |
+
'value_url' => array(
|
| 422 |
+
'allow_empty' => true,
|
| 423 |
+
'protocol' => array(
|
| 424 |
+
'http',
|
| 425 |
+
'https',
|
| 426 |
+
),
|
| 427 |
+
),
|
| 428 |
+
),
|
| 429 |
+
'data-widget-id' => array(
|
| 430 |
+
'mandatory' => true,
|
| 431 |
+
),
|
| 432 |
+
'media' => array(),
|
| 433 |
+
'noloading' => array(
|
| 434 |
+
'value' => array(
|
| 435 |
+
'',
|
| 436 |
+
),
|
| 437 |
+
),
|
| 438 |
+
),
|
| 439 |
+
'tag_spec' => array(
|
| 440 |
+
'amp_layout' => array(
|
| 441 |
+
'supported_layouts' => array(
|
| 442 |
+
6,
|
| 443 |
+
2,
|
| 444 |
+
3,
|
| 445 |
+
7,
|
| 446 |
+
1,
|
| 447 |
+
4,
|
| 448 |
+
),
|
| 449 |
+
),
|
| 450 |
+
'requires_extension' => array(
|
| 451 |
+
'amp-addthis',
|
| 452 |
+
),
|
| 453 |
+
),
|
| 454 |
+
),
|
| 455 |
+
),
|
| 456 |
'amp-analytics' => array(
|
| 457 |
array(
|
| 458 |
'attr_spec_list' => array(
|
| 461 |
'value_url' => array(
|
| 462 |
'allow_empty' => true,
|
| 463 |
'allow_relative' => true,
|
| 464 |
+
'protocol' => array(
|
| 465 |
'https',
|
| 466 |
),
|
| 467 |
),
|
| 481 |
'attr_spec_list' => array(
|
| 482 |
'alt' => array(),
|
| 483 |
'attribution' => array(),
|
|
|
|
| 484 |
'media' => array(),
|
| 485 |
'noloading' => array(
|
| 486 |
+
'value' => array(
|
| 487 |
+
'',
|
| 488 |
+
),
|
| 489 |
),
|
| 490 |
'src' => array(
|
| 491 |
'alternative_names' => array(
|
| 494 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 495 |
'mandatory' => true,
|
| 496 |
'value_url' => array(
|
| 497 |
+
'protocol' => array(
|
|
|
|
| 498 |
'data',
|
| 499 |
'http',
|
| 500 |
'https',
|
| 503 |
),
|
| 504 |
),
|
| 505 |
'tag_spec' => array(
|
| 506 |
+
'amp_layout' => array(
|
| 507 |
+
'supported_layouts' => array(
|
| 508 |
+
6,
|
| 509 |
+
2,
|
| 510 |
+
3,
|
| 511 |
+
7,
|
| 512 |
+
9,
|
| 513 |
+
1,
|
| 514 |
+
4,
|
| 515 |
+
),
|
| 516 |
+
),
|
| 517 |
'requires_extension' => array(
|
| 518 |
'amp-anim',
|
| 519 |
),
|
| 526 |
'attr_spec_list' => array(
|
| 527 |
'media' => array(),
|
| 528 |
'noloading' => array(
|
| 529 |
+
'value' => array(
|
| 530 |
+
'',
|
| 531 |
+
),
|
| 532 |
),
|
| 533 |
'trigger' => array(
|
| 534 |
+
'value' => array(
|
| 535 |
+
'visibility',
|
| 536 |
+
),
|
| 537 |
),
|
| 538 |
),
|
| 539 |
'tag_spec' => array(
|
| 540 |
+
'amp_layout' => array(
|
| 541 |
+
'supported_layouts' => array(
|
| 542 |
+
1,
|
| 543 |
+
),
|
| 544 |
+
),
|
| 545 |
'requires_extension' => array(
|
| 546 |
'amp-animation',
|
| 547 |
),
|
| 559 |
),
|
| 560 |
'media' => array(),
|
| 561 |
'noloading' => array(
|
| 562 |
+
'value' => array(
|
| 563 |
+
'',
|
| 564 |
+
),
|
| 565 |
),
|
| 566 |
),
|
| 567 |
'tag_spec' => array(
|
| 568 |
+
'amp_layout' => array(
|
| 569 |
+
'supported_layouts' => array(
|
| 570 |
+
6,
|
| 571 |
+
2,
|
| 572 |
+
3,
|
| 573 |
+
7,
|
| 574 |
+
1,
|
| 575 |
+
4,
|
| 576 |
+
),
|
| 577 |
+
),
|
| 578 |
'requires_extension' => array(
|
| 579 |
'amp-apester-media',
|
| 580 |
),
|
| 590 |
),
|
| 591 |
'media' => array(),
|
| 592 |
'noloading' => array(
|
| 593 |
+
'value' => array(
|
| 594 |
+
'',
|
| 595 |
+
),
|
| 596 |
),
|
| 597 |
),
|
| 598 |
'tag_spec' => array(
|
| 599 |
+
'amp_layout' => array(
|
| 600 |
+
'supported_layouts' => array(
|
| 601 |
+
1,
|
| 602 |
+
),
|
| 603 |
+
),
|
| 604 |
'mandatory_parent' => 'body',
|
| 605 |
'requires_extension' => array(
|
| 606 |
'amp-app-banner',
|
| 617 |
'artist' => array(),
|
| 618 |
'artwork' => array(),
|
| 619 |
'autoplay' => array(
|
| 620 |
+
'value' => array(
|
| 621 |
+
'',
|
| 622 |
+
),
|
| 623 |
),
|
| 624 |
'controls' => array(),
|
| 625 |
'controlslist' => array(),
|
| 626 |
'loop' => array(
|
| 627 |
+
'value' => array(
|
| 628 |
+
'',
|
| 629 |
+
),
|
| 630 |
),
|
| 631 |
'media' => array(),
|
| 632 |
'muted' => array(
|
| 633 |
+
'value' => array(
|
| 634 |
+
'',
|
| 635 |
+
),
|
| 636 |
),
|
| 637 |
'noloading' => array(
|
| 638 |
+
'value' => array(
|
| 639 |
+
'',
|
| 640 |
+
),
|
| 641 |
),
|
| 642 |
'preload' => array(
|
| 643 |
+
'value_casei' => array(
|
| 644 |
+
'auto',
|
| 645 |
+
'metadata',
|
| 646 |
+
'none',
|
| 647 |
+
),
|
| 648 |
),
|
| 649 |
'src' => array(
|
| 650 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 651 |
'value_url' => array(
|
| 652 |
'allow_relative' => true,
|
| 653 |
+
'protocol' => array(
|
| 654 |
'https',
|
| 655 |
),
|
| 656 |
),
|
| 657 |
),
|
| 658 |
),
|
| 659 |
'tag_spec' => array(
|
| 660 |
+
'amp_layout' => array(
|
| 661 |
+
'defines_default_height' => true,
|
| 662 |
+
'defines_default_width' => true,
|
| 663 |
+
'supported_layouts' => array(
|
| 664 |
+
2,
|
| 665 |
+
3,
|
| 666 |
+
1,
|
| 667 |
+
),
|
| 668 |
+
),
|
| 669 |
'disallowed_ancestor' => array(
|
| 670 |
'amp-story',
|
| 671 |
),
|
| 682 |
'artwork' => array(),
|
| 683 |
'autoplay' => array(
|
| 684 |
'mandatory' => true,
|
| 685 |
+
'value' => array(
|
| 686 |
+
'',
|
| 687 |
+
),
|
| 688 |
),
|
| 689 |
'controls' => array(),
|
| 690 |
'controlslist' => array(),
|
| 691 |
'loop' => array(
|
| 692 |
+
'value' => array(
|
| 693 |
+
'',
|
| 694 |
+
),
|
| 695 |
),
|
| 696 |
'media' => array(),
|
| 697 |
'muted' => array(
|
| 698 |
+
'value' => array(
|
| 699 |
+
'',
|
| 700 |
+
),
|
| 701 |
),
|
| 702 |
'noloading' => array(
|
| 703 |
+
'value' => array(
|
| 704 |
+
'',
|
| 705 |
+
),
|
| 706 |
),
|
| 707 |
'src' => array(
|
| 708 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 709 |
'value_url' => array(
|
| 710 |
'allow_relative' => true,
|
| 711 |
+
'protocol' => array(
|
| 712 |
'https',
|
| 713 |
),
|
| 714 |
),
|
| 715 |
),
|
| 716 |
),
|
| 717 |
'tag_spec' => array(
|
| 718 |
+
'amp_layout' => array(
|
| 719 |
+
'defines_default_height' => true,
|
| 720 |
+
'defines_default_width' => true,
|
| 721 |
+
'supported_layouts' => array(
|
| 722 |
+
2,
|
| 723 |
+
3,
|
| 724 |
+
1,
|
| 725 |
+
),
|
| 726 |
+
),
|
| 727 |
'mandatory_ancestor' => 'amp-story',
|
| 728 |
'requires_extension' => array(
|
| 729 |
'amp-audio',
|
| 738 |
'attr_spec_list' => array(
|
| 739 |
'media' => array(),
|
| 740 |
'noloading' => array(
|
| 741 |
+
'value' => array(
|
| 742 |
+
'',
|
| 743 |
+
),
|
| 744 |
),
|
| 745 |
'type' => array(
|
| 746 |
'mandatory' => true,
|
| 747 |
),
|
| 748 |
),
|
| 749 |
'tag_spec' => array(
|
| 750 |
+
'disallowed_ancestor' => array(
|
| 751 |
+
'amp-auto-ads',
|
| 752 |
+
),
|
| 753 |
'requires_extension' => array(
|
| 754 |
'amp-auto-ads',
|
| 755 |
),
|
| 768 |
'value_regex_casei' => '[0-9a-f]{24}',
|
| 769 |
),
|
| 770 |
'data-my-content' => array(
|
| 771 |
+
'value' => array(
|
| 772 |
+
'0',
|
| 773 |
+
'1',
|
| 774 |
+
),
|
| 775 |
),
|
| 776 |
'data-name' => array(),
|
| 777 |
'media' => array(),
|
| 778 |
'noloading' => array(
|
| 779 |
+
'value' => array(
|
| 780 |
+
'',
|
| 781 |
+
),
|
| 782 |
),
|
| 783 |
),
|
| 784 |
'tag_spec' => array(
|
| 785 |
+
'amp_layout' => array(
|
| 786 |
+
'supported_layouts' => array(
|
| 787 |
+
6,
|
| 788 |
+
2,
|
| 789 |
+
3,
|
| 790 |
+
7,
|
| 791 |
+
9,
|
| 792 |
+
1,
|
| 793 |
+
4,
|
| 794 |
+
),
|
| 795 |
+
),
|
| 796 |
'requires_extension' => array(
|
| 797 |
'amp-beopinion',
|
| 798 |
),
|
| 822 |
array(
|
| 823 |
'attr_spec_list' => array(
|
| 824 |
'loop' => array(
|
| 825 |
+
'value_casei' => array(
|
| 826 |
+
'false',
|
| 827 |
+
'number',
|
| 828 |
+
'true',
|
| 829 |
+
),
|
| 830 |
),
|
| 831 |
'noautoplay' => array(
|
| 832 |
+
'value' => array(
|
| 833 |
+
'',
|
| 834 |
+
),
|
| 835 |
+
),
|
| 836 |
+
'renderer' => array(
|
| 837 |
+
'value_casei' => array(
|
| 838 |
+
'svg',
|
| 839 |
+
'html',
|
| 840 |
+
),
|
| 841 |
),
|
| 842 |
'src' => array(
|
| 843 |
'mandatory' => true,
|
| 844 |
'value_url' => array(
|
| 845 |
'allow_relative' => false,
|
| 846 |
+
'protocol' => array(
|
| 847 |
'https',
|
| 848 |
),
|
| 849 |
),
|
| 850 |
),
|
| 851 |
),
|
| 852 |
'tag_spec' => array(
|
| 853 |
+
'amp_layout' => array(
|
| 854 |
+
'supported_layouts' => array(
|
| 855 |
+
6,
|
| 856 |
+
2,
|
| 857 |
+
3,
|
| 858 |
+
7,
|
| 859 |
+
1,
|
| 860 |
+
4,
|
| 861 |
+
),
|
| 862 |
+
),
|
| 863 |
'requires_extension' => array(
|
| 864 |
'amp-bodymovin-animation',
|
| 865 |
),
|
| 890 |
),
|
| 891 |
'media' => array(),
|
| 892 |
'noloading' => array(
|
| 893 |
+
'value' => array(
|
| 894 |
+
'',
|
| 895 |
+
),
|
| 896 |
),
|
| 897 |
),
|
| 898 |
'tag_spec' => array(
|
| 899 |
+
'amp_layout' => array(
|
| 900 |
+
'supported_layouts' => array(
|
| 901 |
+
6,
|
| 902 |
+
2,
|
| 903 |
+
3,
|
| 904 |
+
7,
|
| 905 |
+
1,
|
| 906 |
+
4,
|
| 907 |
+
),
|
| 908 |
+
),
|
| 909 |
'requires_extension' => array(
|
| 910 |
'amp-brid-player',
|
| 911 |
),
|
| 921 |
'[data-player-id]' => array(),
|
| 922 |
'[data-player]' => array(),
|
| 923 |
'[data-playlist-id]' => array(),
|
| 924 |
+
'[data-referrer]' => array(),
|
| 925 |
'[data-video-id]' => array(),
|
| 926 |
+
'autoplay' => array(
|
| 927 |
+
'value' => array(
|
| 928 |
+
'',
|
| 929 |
+
),
|
| 930 |
+
),
|
| 931 |
'data-account' => array(
|
| 932 |
'mandatory' => true,
|
| 933 |
),
|
| 934 |
'media' => array(),
|
| 935 |
'noloading' => array(
|
| 936 |
+
'value' => array(
|
| 937 |
+
'',
|
| 938 |
+
),
|
| 939 |
),
|
| 940 |
),
|
| 941 |
'tag_spec' => array(
|
| 942 |
+
'amp_layout' => array(
|
| 943 |
+
'supported_layouts' => array(
|
| 944 |
+
6,
|
| 945 |
+
2,
|
| 946 |
+
3,
|
| 947 |
+
7,
|
| 948 |
+
1,
|
| 949 |
+
4,
|
| 950 |
+
),
|
| 951 |
+
),
|
| 952 |
'requires_extension' => array(
|
| 953 |
'amp-brightcove',
|
| 954 |
),
|
| 967 |
),
|
| 968 |
'media' => array(),
|
| 969 |
'noloading' => array(
|
| 970 |
+
'value' => array(
|
| 971 |
+
'',
|
| 972 |
+
),
|
| 973 |
),
|
| 974 |
),
|
| 975 |
'tag_spec' => array(
|
| 976 |
+
'amp_layout' => array(
|
| 977 |
+
'supported_layouts' => array(
|
| 978 |
+
6,
|
| 979 |
+
2,
|
| 980 |
+
3,
|
| 981 |
+
7,
|
| 982 |
+
1,
|
| 983 |
+
4,
|
| 984 |
+
),
|
| 985 |
+
),
|
| 986 |
'requires_extension' => array(
|
| 987 |
'amp-byside-content',
|
| 988 |
),
|
| 997 |
'mandatory' => true,
|
| 998 |
'value_url' => array(
|
| 999 |
'allow_relative' => false,
|
| 1000 |
+
'protocol' => array(
|
| 1001 |
'https',
|
| 1002 |
),
|
| 1003 |
),
|
| 1004 |
),
|
| 1005 |
'media' => array(),
|
| 1006 |
'noloading' => array(
|
| 1007 |
+
'value' => array(
|
| 1008 |
+
'',
|
| 1009 |
+
),
|
| 1010 |
),
|
| 1011 |
),
|
| 1012 |
'tag_spec' => array(
|
| 1013 |
+
'amp_layout' => array(
|
| 1014 |
+
'supported_layouts' => array(
|
| 1015 |
+
5,
|
| 1016 |
+
6,
|
| 1017 |
+
2,
|
| 1018 |
+
3,
|
| 1019 |
+
7,
|
| 1020 |
+
4,
|
| 1021 |
+
),
|
| 1022 |
+
),
|
| 1023 |
'requires_extension' => array(
|
| 1024 |
'amp-call-tracking',
|
| 1025 |
),
|
| 1032 |
'attr_spec_list' => array(
|
| 1033 |
'[slide]' => array(),
|
| 1034 |
'arrows' => array(
|
| 1035 |
+
'value' => array(
|
| 1036 |
+
'',
|
| 1037 |
+
),
|
| 1038 |
),
|
| 1039 |
'autoplay' => array(
|
| 1040 |
+
'value_regex' => '(|[0-9]+)',
|
| 1041 |
),
|
| 1042 |
'controls' => array(),
|
| 1043 |
'delay' => array(
|
| 1044 |
'value_regex' => '[0-9]+',
|
| 1045 |
),
|
| 1046 |
'dots' => array(
|
| 1047 |
+
'value' => array(
|
| 1048 |
+
'',
|
| 1049 |
+
),
|
| 1050 |
),
|
| 1051 |
+
'loop' => array(
|
| 1052 |
+
'value' => array(
|
| 1053 |
+
'',
|
| 1054 |
+
),
|
| 1055 |
),
|
| 1056 |
+
'media' => array(),
|
| 1057 |
+
'noloading' => array(
|
| 1058 |
+
'value' => array(
|
| 1059 |
+
'',
|
| 1060 |
+
),
|
| 1061 |
+
),
|
| 1062 |
+
'type' => array(
|
| 1063 |
+
'value' => array(
|
| 1064 |
+
'slides',
|
| 1065 |
+
'carousel',
|
| 1066 |
+
),
|
| 1067 |
+
),
|
| 1068 |
+
),
|
| 1069 |
+
'tag_spec' => array(
|
| 1070 |
+
'amp_layout' => array(
|
| 1071 |
+
'supported_layouts' => array(
|
| 1072 |
+
6,
|
| 1073 |
+
2,
|
| 1074 |
+
3,
|
| 1075 |
+
7,
|
| 1076 |
+
9,
|
| 1077 |
+
1,
|
| 1078 |
+
4,
|
| 1079 |
+
),
|
| 1080 |
+
),
|
| 1081 |
+
'requires_extension' => array(
|
| 1082 |
+
'amp-carousel',
|
| 1083 |
+
),
|
| 1084 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-carousel',
|
| 1085 |
+
),
|
| 1086 |
+
),
|
| 1087 |
+
array(
|
| 1088 |
+
'attr_spec_list' => array(
|
| 1089 |
+
'[slide]' => array(),
|
| 1090 |
+
'arrows' => array(
|
| 1091 |
+
'value' => array(
|
| 1092 |
+
'',
|
| 1093 |
+
),
|
| 1094 |
+
),
|
| 1095 |
+
'autoplay' => array(
|
| 1096 |
+
'value' => array(
|
| 1097 |
+
'',
|
| 1098 |
+
),
|
| 1099 |
+
),
|
| 1100 |
+
'controls' => array(),
|
| 1101 |
+
'delay' => array(
|
| 1102 |
+
'value_regex' => '[0-9]+',
|
| 1103 |
+
),
|
| 1104 |
+
'dots' => array(
|
| 1105 |
+
'value' => array(
|
| 1106 |
+
'',
|
| 1107 |
+
),
|
| 1108 |
+
),
|
| 1109 |
+
'lightbox' => array(
|
| 1110 |
+
'mandatory' => true,
|
| 1111 |
),
|
| 1112 |
'loop' => array(
|
| 1113 |
+
'value' => array(
|
| 1114 |
+
'',
|
| 1115 |
+
),
|
| 1116 |
),
|
| 1117 |
'media' => array(),
|
| 1118 |
'noloading' => array(
|
| 1119 |
+
'value' => array(
|
| 1120 |
+
'',
|
| 1121 |
+
),
|
| 1122 |
),
|
| 1123 |
'type' => array(
|
| 1124 |
+
'value' => array(
|
| 1125 |
+
'slides',
|
| 1126 |
+
'carousel',
|
| 1127 |
+
),
|
| 1128 |
),
|
| 1129 |
),
|
| 1130 |
'tag_spec' => array(
|
| 1131 |
+
'amp_layout' => array(
|
| 1132 |
+
'supported_layouts' => array(
|
| 1133 |
+
6,
|
| 1134 |
+
2,
|
| 1135 |
+
3,
|
| 1136 |
+
7,
|
| 1137 |
+
9,
|
| 1138 |
+
1,
|
| 1139 |
+
4,
|
| 1140 |
+
),
|
| 1141 |
+
),
|
| 1142 |
+
'reference_points' => array(
|
| 1143 |
+
'AMP-CAROUSEL lightbox [child]' => array(
|
| 1144 |
+
'mandatory' => false,
|
| 1145 |
+
'unique' => false,
|
| 1146 |
+
),
|
| 1147 |
+
'AMP-CAROUSEL lightbox [lightbox-exclude]' => array(
|
| 1148 |
+
'mandatory' => false,
|
| 1149 |
+
'unique' => false,
|
| 1150 |
+
),
|
| 1151 |
+
),
|
| 1152 |
'requires_extension' => array(
|
| 1153 |
'amp-carousel',
|
| 1154 |
+
'amp-lightbox-gallery',
|
| 1155 |
),
|
| 1156 |
+
'spec_name' => 'AMP-CAROUSEL [lightbox]',
|
| 1157 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-carousel',
|
| 1158 |
),
|
| 1159 |
),
|
| 1163 |
'attr_spec_list' => array(
|
| 1164 |
'media' => array(),
|
| 1165 |
'noloading' => array(
|
| 1166 |
+
'value' => array(
|
| 1167 |
+
'',
|
| 1168 |
+
),
|
| 1169 |
),
|
| 1170 |
),
|
| 1171 |
'tag_spec' => array(
|
| 1172 |
+
'amp_layout' => array(
|
| 1173 |
+
'supported_layouts' => array(
|
| 1174 |
+
1,
|
| 1175 |
+
),
|
| 1176 |
+
),
|
| 1177 |
'requires_extension' => array(
|
| 1178 |
'amp-consent',
|
| 1179 |
),
|
| 1186 |
'attr_spec_list' => array(
|
| 1187 |
'autoplay' => array(),
|
| 1188 |
'data-endscreen-enable' => array(
|
| 1189 |
+
'value' => array(
|
| 1190 |
+
'false',
|
| 1191 |
+
'true',
|
| 1192 |
+
),
|
| 1193 |
),
|
| 1194 |
'data-info' => array(
|
| 1195 |
+
'value' => array(
|
| 1196 |
+
'false',
|
| 1197 |
+
'true',
|
| 1198 |
+
),
|
| 1199 |
),
|
| 1200 |
'data-mute' => array(
|
| 1201 |
+
'value' => array(
|
| 1202 |
+
'false',
|
| 1203 |
+
'true',
|
| 1204 |
+
),
|
| 1205 |
),
|
| 1206 |
'data-sharing-enable' => array(
|
| 1207 |
+
'value' => array(
|
| 1208 |
+
'false',
|
| 1209 |
+
'true',
|
| 1210 |
+
),
|
| 1211 |
),
|
| 1212 |
'data-start' => array(
|
| 1213 |
'value_regex' => '[0-9]+',
|
| 1216 |
'value_regex_casei' => '([0-9a-f]{3}){1,2}',
|
| 1217 |
),
|
| 1218 |
'data-ui-logo' => array(
|
| 1219 |
+
'value' => array(
|
| 1220 |
+
'false',
|
| 1221 |
+
'true',
|
| 1222 |
+
),
|
| 1223 |
),
|
| 1224 |
'data-videoid' => array(
|
| 1225 |
'mandatory' => true,
|
| 1227 |
),
|
| 1228 |
'media' => array(),
|
| 1229 |
'noloading' => array(
|
| 1230 |
+
'value' => array(
|
| 1231 |
+
'',
|
| 1232 |
+
),
|
| 1233 |
),
|
| 1234 |
),
|
| 1235 |
'tag_spec' => array(
|
| 1236 |
+
'amp_layout' => array(
|
| 1237 |
+
'supported_layouts' => array(
|
| 1238 |
+
6,
|
| 1239 |
+
2,
|
| 1240 |
+
3,
|
| 1241 |
+
7,
|
| 1242 |
+
4,
|
| 1243 |
+
),
|
| 1244 |
+
),
|
| 1245 |
'requires_extension' => array(
|
| 1246 |
'amp-dailymotion',
|
| 1247 |
),
|
| 1249 |
),
|
| 1250 |
),
|
| 1251 |
),
|
| 1252 |
+
'amp-date-countdown' => array(
|
| 1253 |
+
array(
|
| 1254 |
+
'attr_spec_list' => array(
|
| 1255 |
+
'biggest-unit' => array(
|
| 1256 |
+
'value_casei' => array(
|
| 1257 |
+
'days',
|
| 1258 |
+
'hours',
|
| 1259 |
+
'minutes',
|
| 1260 |
+
'seconds',
|
| 1261 |
+
),
|
| 1262 |
+
),
|
| 1263 |
+
'end-date' => array(
|
| 1264 |
+
'value_regex' => '\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d(:[0-5]\\d(\\.\\d+)?)?(Z|[+-][0-1][0-9]:[0-5][0-9])',
|
| 1265 |
+
),
|
| 1266 |
+
'locale' => array(
|
| 1267 |
+
'value_casei' => array(
|
| 1268 |
+
'de',
|
| 1269 |
+
'en',
|
| 1270 |
+
'es',
|
| 1271 |
+
'fr',
|
| 1272 |
+
'id',
|
| 1273 |
+
'it',
|
| 1274 |
+
'ja',
|
| 1275 |
+
'ko',
|
| 1276 |
+
'nl',
|
| 1277 |
+
'pt',
|
| 1278 |
+
'ru',
|
| 1279 |
+
'th',
|
| 1280 |
+
'tr',
|
| 1281 |
+
'vi',
|
| 1282 |
+
'zh-cn',
|
| 1283 |
+
'zh-tw',
|
| 1284 |
+
),
|
| 1285 |
+
),
|
| 1286 |
+
'media' => array(),
|
| 1287 |
+
'noloading' => array(
|
| 1288 |
+
'value' => array(
|
| 1289 |
+
'',
|
| 1290 |
+
),
|
| 1291 |
+
),
|
| 1292 |
+
'offset-seconds' => array(
|
| 1293 |
+
'value_regex' => '-?\\d+',
|
| 1294 |
+
),
|
| 1295 |
+
'template' => array(),
|
| 1296 |
+
'timeleft-ms' => array(
|
| 1297 |
+
'value_regex' => '\\d+',
|
| 1298 |
+
),
|
| 1299 |
+
'timestamp-ms' => array(
|
| 1300 |
+
'value_regex' => '\\d{13}',
|
| 1301 |
+
),
|
| 1302 |
+
'timestamp-seconds' => array(
|
| 1303 |
+
'value_regex' => '\\d{10}',
|
| 1304 |
+
),
|
| 1305 |
+
'when-ended' => array(
|
| 1306 |
+
'value_casei' => array(
|
| 1307 |
+
'continue',
|
| 1308 |
+
'stop',
|
| 1309 |
+
),
|
| 1310 |
+
),
|
| 1311 |
+
),
|
| 1312 |
+
'tag_spec' => array(
|
| 1313 |
+
'amp_layout' => array(
|
| 1314 |
+
'supported_layouts' => array(
|
| 1315 |
+
6,
|
| 1316 |
+
2,
|
| 1317 |
+
3,
|
| 1318 |
+
7,
|
| 1319 |
+
1,
|
| 1320 |
+
4,
|
| 1321 |
+
),
|
| 1322 |
+
),
|
| 1323 |
+
'requires_extension' => array(
|
| 1324 |
+
'amp-date-countdown',
|
| 1325 |
+
),
|
| 1326 |
+
),
|
| 1327 |
+
),
|
| 1328 |
+
),
|
| 1329 |
'amp-date-picker' => array(
|
| 1330 |
array(
|
| 1331 |
'attr_spec_list' => array(
|
| 1332 |
+
'[max]' => array(),
|
| 1333 |
+
'[min]' => array(),
|
| 1334 |
'allow-blocked-ranges' => array(
|
| 1335 |
+
'value' => array(
|
| 1336 |
+
'',
|
| 1337 |
+
),
|
| 1338 |
),
|
| 1339 |
'blocked' => array(),
|
| 1340 |
+
'date' => array(),
|
| 1341 |
'day-size' => array(
|
| 1342 |
'value_regex' => '[0-9]+',
|
| 1343 |
),
|
| 1346 |
),
|
| 1347 |
'format' => array(),
|
| 1348 |
'fullscreen' => array(
|
| 1349 |
+
'value' => array(
|
| 1350 |
+
'',
|
| 1351 |
+
),
|
| 1352 |
),
|
| 1353 |
'highlighted' => array(),
|
| 1354 |
'input-selector' => array(),
|
| 1357 |
'media' => array(),
|
| 1358 |
'min' => array(),
|
| 1359 |
'mode' => array(
|
| 1360 |
+
'value_casei' => array(
|
| 1361 |
+
'static',
|
| 1362 |
+
),
|
| 1363 |
),
|
| 1364 |
'month-format' => array(),
|
| 1365 |
'noloading' => array(
|
| 1366 |
+
'value' => array(
|
| 1367 |
+
'',
|
| 1368 |
+
),
|
| 1369 |
),
|
| 1370 |
'number-of-months' => array(
|
| 1371 |
'value_regex' => '[0-9]+',
|
| 1372 |
),
|
| 1373 |
'open-after-clear' => array(
|
| 1374 |
+
'value' => array(
|
| 1375 |
+
'',
|
| 1376 |
+
),
|
| 1377 |
),
|
| 1378 |
'open-after-select' => array(
|
| 1379 |
+
'value' => array(
|
| 1380 |
+
'',
|
| 1381 |
+
),
|
| 1382 |
),
|
| 1383 |
'src' => array(
|
| 1384 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1385 |
'value_url' => array(
|
| 1386 |
+
'allow_relative' => false,
|
| 1387 |
+
'protocol' => array(
|
| 1388 |
'https',
|
| 1389 |
),
|
| 1390 |
),
|
| 1391 |
),
|
| 1392 |
'type' => array(
|
| 1393 |
+
'value_casei' => array(
|
| 1394 |
+
'single',
|
| 1395 |
+
),
|
| 1396 |
),
|
| 1397 |
'week-day-format' => array(),
|
| 1398 |
),
|
| 1399 |
'tag_spec' => array(
|
| 1400 |
+
'amp_layout' => array(
|
| 1401 |
+
'supported_layouts' => array(
|
| 1402 |
+
6,
|
| 1403 |
+
2,
|
| 1404 |
+
3,
|
| 1405 |
+
7,
|
| 1406 |
+
9,
|
| 1407 |
+
1,
|
| 1408 |
+
4,
|
| 1409 |
+
),
|
| 1410 |
+
),
|
| 1411 |
'requires_extension' => array(
|
| 1412 |
'amp-date-picker',
|
| 1413 |
),
|
| 1416 |
),
|
| 1417 |
array(
|
| 1418 |
'attr_spec_list' => array(
|
| 1419 |
+
'[max]' => array(),
|
| 1420 |
+
'[min]' => array(),
|
| 1421 |
'allow-blocked-ranges' => array(
|
| 1422 |
+
'value' => array(
|
| 1423 |
+
'',
|
| 1424 |
+
),
|
| 1425 |
),
|
| 1426 |
'blocked' => array(),
|
| 1427 |
+
'date' => array(),
|
| 1428 |
'day-size' => array(
|
| 1429 |
'value_regex' => '[0-9]+',
|
| 1430 |
),
|
| 1440 |
'min' => array(),
|
| 1441 |
'mode' => array(
|
| 1442 |
'mandatory' => true,
|
| 1443 |
+
'value_casei' => array(
|
| 1444 |
+
'overlay',
|
| 1445 |
+
),
|
| 1446 |
),
|
| 1447 |
'month-format' => array(),
|
| 1448 |
'noloading' => array(
|
| 1449 |
+
'value' => array(
|
| 1450 |
+
'',
|
| 1451 |
+
),
|
| 1452 |
),
|
| 1453 |
'number-of-months' => array(
|
| 1454 |
'value_regex' => '[0-9]+',
|
| 1455 |
),
|
| 1456 |
'open-after-clear' => array(
|
| 1457 |
+
'value' => array(
|
| 1458 |
+
'',
|
| 1459 |
+
),
|
| 1460 |
),
|
| 1461 |
'open-after-select' => array(
|
| 1462 |
+
'value' => array(
|
| 1463 |
+
'',
|
| 1464 |
+
),
|
| 1465 |
),
|
| 1466 |
'src' => array(
|
| 1467 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1468 |
'value_url' => array(
|
| 1469 |
+
'allow_relative' => false,
|
| 1470 |
+
'protocol' => array(
|
| 1471 |
'https',
|
| 1472 |
),
|
| 1473 |
),
|
| 1474 |
),
|
| 1475 |
+
'touch-keyboard-editable' => array(
|
| 1476 |
+
'value' => array(
|
| 1477 |
+
'',
|
| 1478 |
+
),
|
| 1479 |
+
),
|
| 1480 |
'type' => array(
|
| 1481 |
+
'value_casei' => array(
|
| 1482 |
+
'single',
|
| 1483 |
+
),
|
| 1484 |
),
|
| 1485 |
'week-day-format' => array(),
|
| 1486 |
),
|
| 1487 |
'tag_spec' => array(
|
| 1488 |
+
'amp_layout' => array(
|
| 1489 |
+
'supported_layouts' => array(
|
| 1490 |
+
5,
|
| 1491 |
+
1,
|
| 1492 |
+
),
|
| 1493 |
+
),
|
| 1494 |
'requires_extension' => array(
|
| 1495 |
'amp-date-picker',
|
| 1496 |
),
|
| 1499 |
),
|
| 1500 |
array(
|
| 1501 |
'attr_spec_list' => array(
|
| 1502 |
+
'[max]' => array(),
|
| 1503 |
+
'[min]' => array(),
|
| 1504 |
'allow-blocked-ranges' => array(
|
| 1505 |
+
'value' => array(
|
| 1506 |
+
'',
|
| 1507 |
+
),
|
| 1508 |
),
|
| 1509 |
'blocked' => array(),
|
| 1510 |
'day-size' => array(
|
| 1511 |
'value_regex' => '[0-9]+',
|
| 1512 |
),
|
| 1513 |
+
'end-date' => array(),
|
| 1514 |
'end-input-selector' => array(),
|
| 1515 |
'first-day-of-week' => array(
|
| 1516 |
'value_regex' => '[0-6]',
|
| 1517 |
),
|
| 1518 |
'format' => array(),
|
| 1519 |
'fullscreen' => array(
|
| 1520 |
+
'value' => array(
|
| 1521 |
+
'',
|
| 1522 |
+
),
|
| 1523 |
),
|
| 1524 |
'highlighted' => array(),
|
| 1525 |
'locale' => array(),
|
| 1526 |
'max' => array(),
|
| 1527 |
'media' => array(),
|
| 1528 |
'min' => array(),
|
| 1529 |
+
'minimum-nights' => array(
|
| 1530 |
+
'value_regex' => '[0-9]+',
|
| 1531 |
+
),
|
| 1532 |
'mode' => array(
|
| 1533 |
+
'value_casei' => array(
|
| 1534 |
+
'static',
|
| 1535 |
+
),
|
| 1536 |
),
|
| 1537 |
'month-format' => array(),
|
| 1538 |
'noloading' => array(
|
| 1539 |
+
'value' => array(
|
| 1540 |
+
'',
|
| 1541 |
+
),
|
| 1542 |
),
|
| 1543 |
'number-of-months' => array(
|
| 1544 |
'value_regex' => '[0-9]+',
|
| 1545 |
),
|
| 1546 |
'open-after-clear' => array(
|
| 1547 |
+
'value' => array(
|
| 1548 |
+
'',
|
| 1549 |
+
),
|
| 1550 |
),
|
| 1551 |
'open-after-select' => array(
|
| 1552 |
+
'value' => array(
|
| 1553 |
+
'',
|
| 1554 |
+
),
|
| 1555 |
),
|
| 1556 |
'src' => array(
|
| 1557 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1558 |
'value_url' => array(
|
| 1559 |
+
'allow_relative' => false,
|
| 1560 |
+
'protocol' => array(
|
| 1561 |
'https',
|
| 1562 |
),
|
| 1563 |
),
|
| 1564 |
),
|
| 1565 |
+
'start-date' => array(),
|
| 1566 |
'start-input-selector' => array(),
|
| 1567 |
'type' => array(
|
| 1568 |
'mandatory' => true,
|
| 1569 |
+
'value_casei' => array(
|
| 1570 |
+
'range',
|
| 1571 |
+
),
|
| 1572 |
),
|
| 1573 |
'week-day-format' => array(),
|
| 1574 |
),
|
| 1575 |
'tag_spec' => array(
|
| 1576 |
+
'amp_layout' => array(
|
| 1577 |
+
'supported_layouts' => array(
|
| 1578 |
+
6,
|
| 1579 |
+
2,
|
| 1580 |
+
3,
|
| 1581 |
+
7,
|
| 1582 |
+
9,
|
| 1583 |
+
1,
|
| 1584 |
+
4,
|
| 1585 |
+
),
|
| 1586 |
+
),
|
| 1587 |
'requires_extension' => array(
|
| 1588 |
'amp-date-picker',
|
| 1589 |
),
|
| 1592 |
),
|
| 1593 |
array(
|
| 1594 |
'attr_spec_list' => array(
|
| 1595 |
+
'[max]' => array(),
|
| 1596 |
+
'[min]' => array(),
|
| 1597 |
'allow-blocked-ranges' => array(
|
| 1598 |
+
'value' => array(
|
| 1599 |
+
'',
|
| 1600 |
+
),
|
| 1601 |
),
|
| 1602 |
'blocked' => array(),
|
| 1603 |
'day-size' => array(
|
| 1604 |
'value_regex' => '[0-9]+',
|
| 1605 |
),
|
| 1606 |
+
'end-date' => array(),
|
| 1607 |
'end-input-selector' => array(),
|
| 1608 |
'first-day-of-week' => array(
|
| 1609 |
'value_regex' => '[0-6]',
|
| 1614 |
'max' => array(),
|
| 1615 |
'media' => array(),
|
| 1616 |
'min' => array(),
|
| 1617 |
+
'minimum-nights' => array(
|
| 1618 |
+
'value_regex' => '[0-9]+',
|
| 1619 |
+
),
|
| 1620 |
'mode' => array(
|
| 1621 |
'mandatory' => true,
|
| 1622 |
+
'value_casei' => array(
|
| 1623 |
+
'overlay',
|
| 1624 |
+
),
|
| 1625 |
),
|
| 1626 |
'month-format' => array(),
|
| 1627 |
'noloading' => array(
|
| 1628 |
+
'value' => array(
|
| 1629 |
+
'',
|
| 1630 |
+
),
|
| 1631 |
),
|
| 1632 |
'number-of-months' => array(
|
| 1633 |
'value_regex' => '[0-9]+',
|
| 1634 |
),
|
| 1635 |
'open-after-clear' => array(
|
| 1636 |
+
'value' => array(
|
| 1637 |
+
'',
|
| 1638 |
+
),
|
| 1639 |
),
|
| 1640 |
'open-after-select' => array(
|
| 1641 |
+
'value' => array(
|
| 1642 |
+
'',
|
| 1643 |
+
),
|
| 1644 |
),
|
| 1645 |
'src' => array(
|
| 1646 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1647 |
'value_url' => array(
|
| 1648 |
+
'allow_relative' => false,
|
| 1649 |
+
'protocol' => array(
|
| 1650 |
'https',
|
| 1651 |
),
|
| 1652 |
),
|
| 1653 |
),
|
| 1654 |
+
'start-date' => array(),
|
| 1655 |
'start-input-selector' => array(),
|
| 1656 |
+
'touch-keyboard-editable' => array(
|
| 1657 |
+
'value' => array(
|
| 1658 |
+
'',
|
| 1659 |
+
),
|
| 1660 |
+
),
|
| 1661 |
'type' => array(
|
| 1662 |
'mandatory' => true,
|
| 1663 |
+
'value_casei' => array(
|
| 1664 |
+
'range',
|
| 1665 |
+
),
|
| 1666 |
),
|
| 1667 |
'week-day-format' => array(),
|
| 1668 |
),
|
| 1669 |
'tag_spec' => array(
|
| 1670 |
+
'amp_layout' => array(
|
| 1671 |
+
'supported_layouts' => array(
|
| 1672 |
+
5,
|
| 1673 |
+
1,
|
| 1674 |
+
),
|
| 1675 |
+
),
|
| 1676 |
'requires_extension' => array(
|
| 1677 |
'amp-date-picker',
|
| 1678 |
),
|
| 1680 |
),
|
| 1681 |
),
|
| 1682 |
),
|
| 1683 |
+
'amp-delight-player' => array(
|
| 1684 |
array(
|
| 1685 |
+
'attr_spec_list' => array(
|
| 1686 |
+
'data-content-id' => array(
|
| 1687 |
+
'mandatory' => true,
|
| 1688 |
+
),
|
| 1689 |
+
'media' => array(),
|
| 1690 |
+
'noloading' => array(
|
| 1691 |
+
'value' => array(
|
| 1692 |
+
'',
|
| 1693 |
+
),
|
| 1694 |
+
),
|
| 1695 |
+
),
|
| 1696 |
'tag_spec' => array(
|
| 1697 |
+
'amp_layout' => array(
|
| 1698 |
+
'supported_layouts' => array(
|
| 1699 |
+
6,
|
| 1700 |
+
2,
|
| 1701 |
+
3,
|
| 1702 |
+
7,
|
| 1703 |
+
1,
|
| 1704 |
+
4,
|
| 1705 |
+
),
|
| 1706 |
+
),
|
| 1707 |
'requires_extension' => array(
|
| 1708 |
+
'amp-delight-player',
|
| 1709 |
),
|
|
|
|
| 1710 |
),
|
| 1711 |
),
|
| 1712 |
),
|
| 1717 |
'json' => array(),
|
| 1718 |
'media' => array(),
|
| 1719 |
'noloading' => array(
|
| 1720 |
+
'value' => array(
|
| 1721 |
+
'',
|
| 1722 |
+
),
|
| 1723 |
),
|
| 1724 |
'rtc-config' => array(),
|
| 1725 |
'src' => array(
|
| 1726 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1727 |
'value_url' => array(
|
| 1728 |
'allow_relative' => true,
|
| 1729 |
+
'protocol' => array(
|
| 1730 |
'https',
|
| 1731 |
),
|
| 1732 |
),
|
| 1740 |
'also_requires_tag_warning' => array(
|
| 1741 |
'amp-ad extension .js script',
|
| 1742 |
),
|
| 1743 |
+
'amp_layout' => array(
|
| 1744 |
+
'supported_layouts' => array(
|
| 1745 |
+
6,
|
| 1746 |
+
2,
|
| 1747 |
+
3,
|
| 1748 |
+
7,
|
| 1749 |
+
8,
|
| 1750 |
+
9,
|
| 1751 |
+
1,
|
| 1752 |
+
4,
|
| 1753 |
+
),
|
| 1754 |
+
),
|
| 1755 |
'disallowed_ancestor' => array(
|
| 1756 |
'amp-app-banner',
|
| 1757 |
),
|
| 1767 |
'data-multi-size' => array(
|
| 1768 |
'dispatch_key' => 2,
|
| 1769 |
'mandatory' => true,
|
| 1770 |
+
'value' => array(
|
| 1771 |
+
'',
|
| 1772 |
+
),
|
| 1773 |
),
|
| 1774 |
'json' => array(),
|
| 1775 |
'media' => array(),
|
| 1776 |
'noloading' => array(
|
| 1777 |
+
'value' => array(
|
| 1778 |
+
'',
|
| 1779 |
+
),
|
| 1780 |
),
|
| 1781 |
'rtc-config' => array(),
|
| 1782 |
'src' => array(
|
| 1783 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 1784 |
'value_url' => array(
|
| 1785 |
'allow_relative' => true,
|
| 1786 |
+
'protocol' => array(
|
| 1787 |
'https',
|
| 1788 |
),
|
| 1789 |
),
|
| 1796 |
'also_requires_tag_warning' => array(
|
| 1797 |
'amp-ad extension .js script',
|
| 1798 |
),
|
| 1799 |
+
'amp_layout' => array(
|
| 1800 |
+
'supported_layouts' => array(
|
| 1801 |
+
6,
|
| 1802 |
+
2,
|
| 1803 |
+
3,
|
| 1804 |
+
7,
|
| 1805 |
+
8,
|
| 1806 |
+
9,
|
| 1807 |
+
1,
|
| 1808 |
+
4,
|
| 1809 |
+
),
|
| 1810 |
+
),
|
| 1811 |
'disallowed_ancestor' => array(
|
| 1812 |
'amp-app-banner',
|
| 1813 |
'amp-carousel',
|
| 1823 |
),
|
| 1824 |
),
|
| 1825 |
),
|
| 1826 |
+
'amp-embedly-card' => array(
|
| 1827 |
+
array(
|
| 1828 |
+
'attr_spec_list' => array(
|
| 1829 |
+
'data-url' => array(
|
| 1830 |
+
'mandatory' => true,
|
| 1831 |
+
'value_url' => array(
|
| 1832 |
+
'allow_relative' => false,
|
| 1833 |
+
'protocol' => array(
|
| 1834 |
+
'https',
|
| 1835 |
+
),
|
| 1836 |
+
),
|
| 1837 |
+
),
|
| 1838 |
+
'media' => array(),
|
| 1839 |
+
'noloading' => array(
|
| 1840 |
+
'value' => array(
|
| 1841 |
+
'',
|
| 1842 |
+
),
|
| 1843 |
+
),
|
| 1844 |
+
),
|
| 1845 |
+
'tag_spec' => array(
|
| 1846 |
+
'amp_layout' => array(
|
| 1847 |
+
'supported_layouts' => array(
|
| 1848 |
+
4,
|
| 1849 |
+
),
|
| 1850 |
+
),
|
| 1851 |
+
'requires_extension' => array(
|
| 1852 |
+
'amp-embedly-card',
|
| 1853 |
+
),
|
| 1854 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-embedly-card',
|
| 1855 |
+
),
|
| 1856 |
+
),
|
| 1857 |
+
),
|
| 1858 |
+
'amp-embedly-key' => array(
|
| 1859 |
+
array(
|
| 1860 |
+
'attr_spec_list' => array(
|
| 1861 |
+
'value' => array(
|
| 1862 |
+
'mandatory' => true,
|
| 1863 |
+
),
|
| 1864 |
+
),
|
| 1865 |
+
'tag_spec' => array(
|
| 1866 |
+
'amp_layout' => array(
|
| 1867 |
+
'supported_layouts' => array(
|
| 1868 |
+
1,
|
| 1869 |
+
),
|
| 1870 |
+
),
|
| 1871 |
+
'requires_extension' => array(
|
| 1872 |
+
'amp-embedly-card',
|
| 1873 |
+
),
|
| 1874 |
+
'unique' => true,
|
| 1875 |
+
),
|
| 1876 |
+
),
|
| 1877 |
+
),
|
| 1878 |
'amp-experiment' => array(
|
| 1879 |
array(
|
| 1880 |
'attr_spec_list' => array(),
|
| 1895 |
),
|
| 1896 |
'media' => array(),
|
| 1897 |
'noloading' => array(
|
| 1898 |
+
'value' => array(
|
| 1899 |
+
'',
|
| 1900 |
+
),
|
| 1901 |
),
|
| 1902 |
),
|
| 1903 |
'tag_spec' => array(
|
| 1904 |
+
'amp_layout' => array(
|
| 1905 |
+
'supported_layouts' => array(
|
| 1906 |
+
6,
|
| 1907 |
+
2,
|
| 1908 |
+
3,
|
| 1909 |
+
7,
|
| 1910 |
+
1,
|
| 1911 |
+
4,
|
| 1912 |
+
),
|
| 1913 |
+
),
|
| 1914 |
'requires_extension' => array(
|
| 1915 |
'amp-facebook',
|
| 1916 |
),
|
| 1925 |
),
|
| 1926 |
'media' => array(),
|
| 1927 |
'noloading' => array(
|
| 1928 |
+
'value' => array(
|
| 1929 |
+
'',
|
| 1930 |
+
),
|
| 1931 |
),
|
| 1932 |
),
|
| 1933 |
'tag_spec' => array(
|
| 1934 |
+
'amp_layout' => array(
|
| 1935 |
+
'supported_layouts' => array(
|
| 1936 |
+
6,
|
| 1937 |
+
2,
|
| 1938 |
+
3,
|
| 1939 |
+
7,
|
| 1940 |
+
1,
|
| 1941 |
+
4,
|
| 1942 |
+
),
|
| 1943 |
+
),
|
| 1944 |
'requires_extension' => array(
|
| 1945 |
'amp-facebook-comments',
|
| 1946 |
),
|
| 1954 |
'mandatory' => true,
|
| 1955 |
'value_url' => array(
|
| 1956 |
'allow_relative' => false,
|
| 1957 |
+
'protocol' => array(
|
| 1958 |
'http',
|
| 1959 |
'https',
|
| 1960 |
),
|
| 1962 |
),
|
| 1963 |
'media' => array(),
|
| 1964 |
'noloading' => array(
|
| 1965 |
+
'value' => array(
|
| 1966 |
+
'',
|
| 1967 |
+
),
|
| 1968 |
),
|
| 1969 |
),
|
| 1970 |
'tag_spec' => array(
|
| 1971 |
+
'amp_layout' => array(
|
| 1972 |
+
'supported_layouts' => array(
|
| 1973 |
+
6,
|
| 1974 |
+
2,
|
| 1975 |
+
3,
|
| 1976 |
+
7,
|
| 1977 |
+
1,
|
| 1978 |
+
4,
|
| 1979 |
+
),
|
| 1980 |
+
),
|
| 1981 |
'requires_extension' => array(
|
| 1982 |
'amp-facebook-like',
|
| 1983 |
),
|
| 1991 |
'mandatory' => true,
|
| 1992 |
'value_url' => array(
|
| 1993 |
'allow_relative' => false,
|
| 1994 |
+
'protocol' => array(
|
| 1995 |
'http',
|
| 1996 |
'https',
|
| 1997 |
),
|
| 1999 |
),
|
| 2000 |
'media' => array(),
|
| 2001 |
'noloading' => array(
|
| 2002 |
+
'value' => array(
|
| 2003 |
+
'',
|
| 2004 |
+
),
|
| 2005 |
),
|
| 2006 |
),
|
| 2007 |
'tag_spec' => array(
|
| 2008 |
+
'amp_layout' => array(
|
| 2009 |
+
'supported_layouts' => array(
|
| 2010 |
+
6,
|
| 2011 |
+
2,
|
| 2012 |
+
3,
|
| 2013 |
+
7,
|
| 2014 |
+
1,
|
| 2015 |
+
4,
|
| 2016 |
+
),
|
| 2017 |
+
),
|
| 2018 |
'requires_extension' => array(
|
| 2019 |
'amp-facebook-page',
|
| 2020 |
),
|
| 2028 |
'media' => array(),
|
| 2029 |
'min-font-size' => array(),
|
| 2030 |
'noloading' => array(
|
| 2031 |
+
'value' => array(
|
| 2032 |
+
'',
|
| 2033 |
+
),
|
| 2034 |
),
|
| 2035 |
),
|
| 2036 |
'tag_spec' => array(
|
| 2037 |
+
'amp_layout' => array(
|
| 2038 |
+
'supported_layouts' => array(
|
| 2039 |
+
6,
|
| 2040 |
+
2,
|
| 2041 |
+
3,
|
| 2042 |
+
7,
|
| 2043 |
+
9,
|
| 2044 |
+
1,
|
| 2045 |
+
4,
|
| 2046 |
+
),
|
| 2047 |
+
),
|
| 2048 |
'requires_extension' => array(
|
| 2049 |
'amp-fit-text',
|
| 2050 |
),
|
| 2062 |
'font-weight' => array(),
|
| 2063 |
'media' => array(),
|
| 2064 |
'noloading' => array(
|
| 2065 |
+
'value' => array(
|
| 2066 |
+
'',
|
| 2067 |
+
),
|
| 2068 |
),
|
| 2069 |
'on-error-add-class' => array(),
|
| 2070 |
'on-error-remove-class' => array(),
|
| 2075 |
),
|
| 2076 |
),
|
| 2077 |
'tag_spec' => array(
|
| 2078 |
+
'amp_layout' => array(
|
| 2079 |
+
'supported_layouts' => array(
|
| 2080 |
+
1,
|
| 2081 |
+
),
|
| 2082 |
+
),
|
| 2083 |
'requires_extension' => array(
|
| 2084 |
'amp-font',
|
| 2085 |
),
|
| 2094 |
),
|
| 2095 |
'media' => array(),
|
| 2096 |
'noloading' => array(
|
| 2097 |
+
'value' => array(
|
| 2098 |
+
'',
|
| 2099 |
+
),
|
| 2100 |
),
|
| 2101 |
),
|
| 2102 |
'tag_spec' => array(
|
| 2106 |
),
|
| 2107 |
),
|
| 2108 |
),
|
| 2109 |
+
'amp-geo' => array(
|
| 2110 |
+
array(
|
| 2111 |
+
'attr_spec_list' => array(
|
| 2112 |
+
'media' => array(),
|
| 2113 |
+
'noloading' => array(
|
| 2114 |
+
'value' => array(
|
| 2115 |
+
'',
|
| 2116 |
+
),
|
| 2117 |
+
),
|
| 2118 |
+
),
|
| 2119 |
+
'tag_spec' => array(
|
| 2120 |
+
'amp_layout' => array(
|
| 2121 |
+
'supported_layouts' => array(
|
| 2122 |
+
1,
|
| 2123 |
+
),
|
| 2124 |
+
),
|
| 2125 |
+
'requires_extension' => array(
|
| 2126 |
+
'amp-geo',
|
| 2127 |
+
),
|
| 2128 |
+
'unique' => true,
|
| 2129 |
+
),
|
| 2130 |
+
),
|
| 2131 |
+
),
|
| 2132 |
'amp-gfycat' => array(
|
| 2133 |
array(
|
| 2134 |
'attr_spec_list' => array(
|
| 2137 |
),
|
| 2138 |
'media' => array(),
|
| 2139 |
'noautoplay' => array(
|
| 2140 |
+
'value' => array(
|
| 2141 |
+
'',
|
| 2142 |
+
),
|
| 2143 |
),
|
| 2144 |
'noloading' => array(
|
| 2145 |
+
'value' => array(
|
| 2146 |
+
'',
|
| 2147 |
+
),
|
| 2148 |
),
|
| 2149 |
),
|
| 2150 |
'tag_spec' => array(
|
| 2151 |
+
'amp_layout' => array(
|
| 2152 |
+
'supported_layouts' => array(
|
| 2153 |
+
6,
|
| 2154 |
+
2,
|
| 2155 |
+
3,
|
| 2156 |
+
7,
|
| 2157 |
+
4,
|
| 2158 |
+
),
|
| 2159 |
+
),
|
| 2160 |
'requires_extension' => array(
|
| 2161 |
'amp-gfycat',
|
| 2162 |
),
|
| 2172 |
),
|
| 2173 |
'media' => array(),
|
| 2174 |
'noloading' => array(
|
| 2175 |
+
'value' => array(
|
| 2176 |
+
'',
|
| 2177 |
+
),
|
| 2178 |
),
|
| 2179 |
),
|
| 2180 |
'tag_spec' => array(
|
| 2181 |
+
'amp_layout' => array(
|
| 2182 |
+
'supported_layouts' => array(
|
| 2183 |
+
3,
|
| 2184 |
+
),
|
| 2185 |
+
),
|
| 2186 |
'requires_extension' => array(
|
| 2187 |
'amp-gist',
|
| 2188 |
),
|
| 2190 |
),
|
| 2191 |
),
|
| 2192 |
),
|
| 2193 |
+
'amp-google-document-embed' => array(
|
| 2194 |
+
array(
|
| 2195 |
+
'attr_spec_list' => array(
|
| 2196 |
+
'[src]' => array(),
|
| 2197 |
+
'[title]' => array(),
|
| 2198 |
+
'media' => array(),
|
| 2199 |
+
'noloading' => array(
|
| 2200 |
+
'value' => array(
|
| 2201 |
+
'',
|
| 2202 |
+
),
|
| 2203 |
+
),
|
| 2204 |
+
'src' => array(
|
| 2205 |
+
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2206 |
+
'mandatory' => true,
|
| 2207 |
+
'value_url' => array(
|
| 2208 |
+
'allow_relative' => false,
|
| 2209 |
+
'protocol' => array(
|
| 2210 |
+
'https',
|
| 2211 |
+
),
|
| 2212 |
+
),
|
| 2213 |
+
),
|
| 2214 |
+
),
|
| 2215 |
+
'tag_spec' => array(
|
| 2216 |
+
'amp_layout' => array(
|
| 2217 |
+
'supported_layouts' => array(
|
| 2218 |
+
6,
|
| 2219 |
+
2,
|
| 2220 |
+
3,
|
| 2221 |
+
7,
|
| 2222 |
+
9,
|
| 2223 |
+
1,
|
| 2224 |
+
4,
|
| 2225 |
+
),
|
| 2226 |
+
),
|
| 2227 |
+
'requires_extension' => array(
|
| 2228 |
+
'amp-google-document-embed',
|
| 2229 |
+
),
|
| 2230 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-google-document-embed',
|
| 2231 |
+
),
|
| 2232 |
+
),
|
| 2233 |
+
),
|
| 2234 |
'amp-hulu' => array(
|
| 2235 |
array(
|
| 2236 |
'attr_spec_list' => array(
|
| 2239 |
),
|
| 2240 |
'media' => array(),
|
| 2241 |
'noloading' => array(
|
| 2242 |
+
'value' => array(
|
| 2243 |
+
'',
|
| 2244 |
+
),
|
| 2245 |
),
|
| 2246 |
),
|
| 2247 |
'tag_spec' => array(
|
| 2248 |
+
'amp_layout' => array(
|
| 2249 |
+
'supported_layouts' => array(
|
| 2250 |
+
6,
|
| 2251 |
+
2,
|
| 2252 |
+
3,
|
| 2253 |
+
7,
|
| 2254 |
+
4,
|
| 2255 |
+
),
|
| 2256 |
+
),
|
| 2257 |
'requires_extension' => array(
|
| 2258 |
'amp-hulu',
|
| 2259 |
),
|
| 2267 |
'[src]' => array(),
|
| 2268 |
'allow' => array(),
|
| 2269 |
'allowfullscreen' => array(
|
| 2270 |
+
'value' => array(
|
| 2271 |
+
'',
|
| 2272 |
+
),
|
| 2273 |
),
|
| 2274 |
'allowpaymentrequest' => array(
|
| 2275 |
+
'value' => array(
|
| 2276 |
+
'',
|
| 2277 |
+
),
|
| 2278 |
),
|
| 2279 |
'allowtransparency' => array(
|
| 2280 |
+
'value' => array(
|
| 2281 |
+
'',
|
| 2282 |
+
),
|
| 2283 |
),
|
| 2284 |
'frameborder' => array(
|
| 2285 |
+
'value' => array(
|
| 2286 |
+
'0',
|
| 2287 |
+
'1',
|
| 2288 |
+
),
|
| 2289 |
),
|
| 2290 |
'media' => array(),
|
| 2291 |
'noloading' => array(
|
| 2292 |
+
'value' => array(
|
| 2293 |
+
'',
|
| 2294 |
+
),
|
| 2295 |
),
|
| 2296 |
'referrerpolicy' => array(),
|
| 2297 |
'resizable' => array(
|
| 2298 |
+
'value' => array(
|
| 2299 |
+
'',
|
| 2300 |
+
),
|
| 2301 |
),
|
| 2302 |
'sandbox' => array(),
|
| 2303 |
'scrolling' => array(
|
| 2304 |
+
'value' => array(
|
| 2305 |
+
'auto',
|
| 2306 |
+
'no',
|
| 2307 |
+
'yes',
|
| 2308 |
+
),
|
| 2309 |
),
|
| 2310 |
'src' => array(
|
| 2311 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2312 |
'value_url' => array(
|
| 2313 |
'allow_relative' => true,
|
| 2314 |
+
'protocol' => array(
|
| 2315 |
'data',
|
| 2316 |
'https',
|
| 2317 |
),
|
| 2320 |
'srcdoc' => array(),
|
| 2321 |
),
|
| 2322 |
'tag_spec' => array(
|
| 2323 |
+
'amp_layout' => array(
|
| 2324 |
+
'supported_layouts' => array(
|
| 2325 |
+
6,
|
| 2326 |
+
2,
|
| 2327 |
+
3,
|
| 2328 |
+
7,
|
| 2329 |
+
9,
|
| 2330 |
+
1,
|
| 2331 |
+
4,
|
| 2332 |
+
),
|
| 2333 |
+
),
|
| 2334 |
'requires_extension' => array(
|
| 2335 |
'amp-iframe',
|
| 2336 |
),
|
| 2341 |
array(
|
| 2342 |
'attr_spec_list' => array(
|
| 2343 |
'autoplay' => array(
|
| 2344 |
+
'value' => array(
|
| 2345 |
+
'',
|
| 2346 |
+
),
|
| 2347 |
),
|
| 2348 |
'data-src' => array(
|
| 2349 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2350 |
'value_url' => array(
|
| 2351 |
'allow_relative' => true,
|
| 2352 |
+
'protocol' => array(
|
| 2353 |
'https',
|
| 2354 |
),
|
| 2355 |
),
|
| 2358 |
'mandatory' => true,
|
| 2359 |
'value_url' => array(
|
| 2360 |
'allow_relative' => true,
|
| 2361 |
+
'protocol' => array(
|
| 2362 |
'https',
|
| 2363 |
),
|
| 2364 |
),
|
| 2365 |
),
|
| 2366 |
'media' => array(),
|
| 2367 |
'noloading' => array(
|
| 2368 |
+
'value' => array(
|
| 2369 |
+
'',
|
| 2370 |
+
),
|
| 2371 |
+
),
|
| 2372 |
+
'rotate-to-fullscreen' => array(
|
| 2373 |
+
'value' => array(
|
| 2374 |
+
'',
|
| 2375 |
+
),
|
| 2376 |
),
|
| 2377 |
),
|
| 2378 |
'tag_spec' => array(
|
| 2379 |
+
'amp_layout' => array(
|
| 2380 |
+
'supported_layouts' => array(
|
| 2381 |
+
6,
|
| 2382 |
+
2,
|
| 2383 |
+
3,
|
| 2384 |
+
1,
|
| 2385 |
+
4,
|
| 2386 |
+
),
|
| 2387 |
+
),
|
| 2388 |
'requires_extension' => array(
|
| 2389 |
'amp-ima-video',
|
| 2390 |
),
|
| 2398 |
'controls' => array(),
|
| 2399 |
'media' => array(),
|
| 2400 |
'noloading' => array(
|
| 2401 |
+
'value' => array(
|
| 2402 |
+
'',
|
| 2403 |
+
),
|
| 2404 |
),
|
| 2405 |
),
|
| 2406 |
'tag_spec' => array(
|
| 2407 |
+
'amp_layout' => array(
|
| 2408 |
+
'supported_layouts' => array(
|
| 2409 |
+
1,
|
| 2410 |
+
),
|
| 2411 |
+
),
|
| 2412 |
'requires_extension' => array(
|
| 2413 |
'amp-image-lightbox',
|
| 2414 |
),
|
| 2415 |
),
|
| 2416 |
),
|
| 2417 |
),
|
| 2418 |
+
'amp-image-slider' => array(
|
| 2419 |
+
array(
|
| 2420 |
+
'attr_spec_list' => array(
|
| 2421 |
+
'disable-hint-reappear' => array(),
|
| 2422 |
+
'initial-slider-position' => array(
|
| 2423 |
+
'value_regex' => '0(\\.[0-9]+)?|1(\\.0+)?',
|
| 2424 |
+
),
|
| 2425 |
+
'media' => array(),
|
| 2426 |
+
'noloading' => array(
|
| 2427 |
+
'value' => array(
|
| 2428 |
+
'',
|
| 2429 |
+
),
|
| 2430 |
+
),
|
| 2431 |
+
'step-size' => array(
|
| 2432 |
+
'value_regex' => '0(\\.[0-9]+)?|1(\\.0+)?',
|
| 2433 |
+
),
|
| 2434 |
+
),
|
| 2435 |
+
'tag_spec' => array(
|
| 2436 |
+
'amp_layout' => array(
|
| 2437 |
+
'supported_layouts' => array(
|
| 2438 |
+
2,
|
| 2439 |
+
9,
|
| 2440 |
+
1,
|
| 2441 |
+
4,
|
| 2442 |
+
),
|
| 2443 |
+
),
|
| 2444 |
+
'requires_extension' => array(
|
| 2445 |
+
'amp-image-slider',
|
| 2446 |
+
),
|
| 2447 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-image-slider',
|
| 2448 |
+
),
|
| 2449 |
+
),
|
| 2450 |
+
),
|
| 2451 |
'amp-img' => array(
|
| 2452 |
array(
|
| 2453 |
'attr_spec_list' => array(
|
| 2458 |
'alt' => array(),
|
| 2459 |
'attribution' => array(),
|
| 2460 |
'lightbox' => array(),
|
|
|
|
|
|
|
|
|
|
| 2461 |
'lightbox-thumbnail-id' => array(
|
| 2462 |
'value_regex_casei' => '^[a-z][a-z\\d_-]*',
|
| 2463 |
),
|
| 2464 |
'media' => array(),
|
| 2465 |
'noloading' => array(
|
| 2466 |
+
'value' => array(
|
| 2467 |
+
'',
|
| 2468 |
+
),
|
| 2469 |
),
|
| 2470 |
'placeholder' => array(),
|
| 2471 |
'src' => array(
|
| 2475 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2476 |
'mandatory' => true,
|
| 2477 |
'value_url' => array(
|
| 2478 |
+
'protocol' => array(
|
|
|
|
| 2479 |
'data',
|
| 2480 |
'http',
|
| 2481 |
'https',
|
| 2484 |
),
|
| 2485 |
),
|
| 2486 |
'tag_spec' => array(
|
| 2487 |
+
'amp_layout' => array(
|
| 2488 |
+
'supported_layouts' => array(
|
| 2489 |
+
6,
|
| 2490 |
+
2,
|
| 2491 |
+
3,
|
| 2492 |
+
7,
|
| 2493 |
+
9,
|
| 2494 |
+
1,
|
| 2495 |
+
4,
|
| 2496 |
+
),
|
| 2497 |
+
),
|
| 2498 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-img',
|
| 2499 |
),
|
| 2500 |
),
|
| 2507 |
),
|
| 2508 |
'media' => array(),
|
| 2509 |
'noloading' => array(
|
| 2510 |
+
'value' => array(
|
| 2511 |
+
'',
|
| 2512 |
+
),
|
| 2513 |
),
|
| 2514 |
),
|
| 2515 |
'tag_spec' => array(
|
| 2516 |
+
'amp_layout' => array(
|
| 2517 |
+
'supported_layouts' => array(
|
| 2518 |
+
6,
|
| 2519 |
+
2,
|
| 2520 |
+
3,
|
| 2521 |
+
7,
|
| 2522 |
+
1,
|
| 2523 |
+
4,
|
| 2524 |
+
),
|
| 2525 |
+
),
|
| 2526 |
'requires_extension' => array(
|
| 2527 |
'amp-imgur',
|
| 2528 |
),
|
| 2538 |
),
|
| 2539 |
'media' => array(),
|
| 2540 |
'noloading' => array(
|
| 2541 |
+
'value' => array(
|
| 2542 |
+
'',
|
| 2543 |
+
),
|
| 2544 |
),
|
| 2545 |
),
|
| 2546 |
'tag_spec' => array(
|
| 2547 |
+
'amp_layout' => array(
|
| 2548 |
+
'supported_layouts' => array(
|
| 2549 |
+
6,
|
| 2550 |
+
2,
|
| 2551 |
+
3,
|
| 2552 |
+
7,
|
| 2553 |
+
1,
|
| 2554 |
+
4,
|
| 2555 |
+
),
|
| 2556 |
+
),
|
| 2557 |
'requires_extension' => array(
|
| 2558 |
'amp-instagram',
|
| 2559 |
),
|
| 2567 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2568 |
'value_url' => array(
|
| 2569 |
'allow_relative' => true,
|
| 2570 |
+
'protocol' => array(
|
| 2571 |
'https',
|
| 2572 |
),
|
| 2573 |
),
|
| 2577 |
'mandatory' => true,
|
| 2578 |
'value_url' => array(
|
| 2579 |
'allow_relative' => true,
|
| 2580 |
+
'protocol' => array(
|
| 2581 |
'https',
|
| 2582 |
),
|
| 2583 |
),
|
| 2584 |
),
|
| 2585 |
),
|
| 2586 |
'tag_spec' => array(
|
| 2587 |
+
'amp_layout' => array(
|
| 2588 |
+
'supported_layouts' => array(
|
| 2589 |
+
1,
|
| 2590 |
+
),
|
| 2591 |
+
),
|
| 2592 |
'requires_extension' => array(
|
| 2593 |
'amp-install-serviceworker',
|
| 2594 |
),
|
| 2604 |
),
|
| 2605 |
'media' => array(),
|
| 2606 |
'noloading' => array(
|
| 2607 |
+
'value' => array(
|
| 2608 |
+
'',
|
| 2609 |
+
),
|
| 2610 |
),
|
| 2611 |
),
|
| 2612 |
'tag_spec' => array(
|
| 2613 |
+
'amp_layout' => array(
|
| 2614 |
+
'supported_layouts' => array(
|
| 2615 |
+
6,
|
| 2616 |
+
2,
|
| 2617 |
+
3,
|
| 2618 |
+
7,
|
| 2619 |
+
4,
|
| 2620 |
+
),
|
| 2621 |
+
),
|
| 2622 |
'requires_extension' => array(
|
| 2623 |
'amp-izlesene',
|
| 2624 |
),
|
| 2640 |
),
|
| 2641 |
),
|
| 2642 |
'tag_spec' => array(
|
| 2643 |
+
'amp_layout' => array(
|
| 2644 |
+
'supported_layouts' => array(
|
| 2645 |
+
6,
|
| 2646 |
+
2,
|
| 2647 |
+
3,
|
| 2648 |
+
7,
|
| 2649 |
+
1,
|
| 2650 |
+
4,
|
| 2651 |
+
),
|
| 2652 |
+
),
|
| 2653 |
'requires_extension' => array(
|
| 2654 |
'amp-jwplayer',
|
| 2655 |
),
|
| 2664 |
),
|
| 2665 |
'media' => array(),
|
| 2666 |
'noloading' => array(
|
| 2667 |
+
'value' => array(
|
| 2668 |
+
'',
|
| 2669 |
+
),
|
| 2670 |
),
|
| 2671 |
),
|
| 2672 |
'tag_spec' => array(
|
| 2673 |
+
'amp_layout' => array(
|
| 2674 |
+
'supported_layouts' => array(
|
| 2675 |
+
6,
|
| 2676 |
+
2,
|
| 2677 |
+
3,
|
| 2678 |
+
7,
|
| 2679 |
+
1,
|
| 2680 |
+
4,
|
| 2681 |
+
),
|
| 2682 |
+
),
|
| 2683 |
'requires_extension' => array(
|
| 2684 |
'amp-kaltura-player',
|
| 2685 |
),
|
| 2691 |
'attr_spec_list' => array(
|
| 2692 |
'media' => array(),
|
| 2693 |
'noloading' => array(
|
| 2694 |
+
'value' => array(
|
| 2695 |
+
'',
|
| 2696 |
+
),
|
| 2697 |
),
|
| 2698 |
),
|
| 2699 |
'tag_spec' => array(
|
| 2700 |
+
'amp_layout' => array(
|
| 2701 |
+
'supported_layouts' => array(
|
| 2702 |
+
6,
|
| 2703 |
+
2,
|
| 2704 |
+
3,
|
| 2705 |
+
7,
|
| 2706 |
+
9,
|
| 2707 |
+
1,
|
| 2708 |
+
4,
|
| 2709 |
+
5,
|
| 2710 |
+
),
|
| 2711 |
+
),
|
| 2712 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-layout',
|
| 2713 |
),
|
| 2714 |
),
|
| 2716 |
'amp-lightbox' => array(
|
| 2717 |
array(
|
| 2718 |
'attr_spec_list' => array(
|
| 2719 |
+
'[open]' => array(),
|
| 2720 |
+
'animate-in' => array(
|
| 2721 |
+
'value_casei' => array(
|
| 2722 |
+
'fade-in',
|
| 2723 |
+
'fly-in-bottom',
|
| 2724 |
+
'fly-in-top',
|
| 2725 |
+
),
|
| 2726 |
+
),
|
| 2727 |
'controls' => array(),
|
| 2728 |
'from' => array(),
|
| 2729 |
'media' => array(),
|
| 2730 |
'noloading' => array(
|
| 2731 |
+
'value' => array(
|
| 2732 |
+
'',
|
| 2733 |
+
),
|
| 2734 |
),
|
| 2735 |
'scrollable' => array(),
|
| 2736 |
),
|
| 2737 |
'tag_spec' => array(
|
| 2738 |
+
'amp_layout' => array(
|
| 2739 |
+
'supported_layouts' => array(
|
| 2740 |
+
1,
|
| 2741 |
+
),
|
| 2742 |
+
),
|
| 2743 |
'requires_extension' => array(
|
| 2744 |
'amp-lightbox',
|
| 2745 |
),
|
| 2751 |
'attr_spec_list' => array(
|
| 2752 |
'[src]' => array(),
|
| 2753 |
'[state]' => array(),
|
| 2754 |
+
'auto-resize' => array(
|
| 2755 |
+
'value' => array(
|
| 2756 |
+
'',
|
| 2757 |
+
),
|
| 2758 |
+
),
|
| 2759 |
+
'binding' => array(
|
| 2760 |
+
'value' => array(
|
| 2761 |
+
'always',
|
| 2762 |
+
'no',
|
| 2763 |
+
'refresh',
|
| 2764 |
+
),
|
| 2765 |
+
),
|
| 2766 |
'credentials' => array(),
|
| 2767 |
'items' => array(),
|
| 2768 |
'max-items' => array(),
|
| 2769 |
'media' => array(),
|
| 2770 |
'noloading' => array(
|
| 2771 |
+
'value' => array(
|
| 2772 |
+
'',
|
| 2773 |
+
),
|
| 2774 |
),
|
| 2775 |
'reset-on-refresh' => array(
|
| 2776 |
+
'value' => array(
|
| 2777 |
+
'',
|
| 2778 |
+
'always',
|
| 2779 |
+
'fetch',
|
| 2780 |
+
),
|
| 2781 |
),
|
| 2782 |
'single-item' => array(),
|
| 2783 |
'src' => array(
|
| 2784 |
'blacklisted_value_regex' => '__amp_source_origin',
|
|
|
|
| 2785 |
'value_url' => array(
|
| 2786 |
'allow_relative' => true,
|
| 2787 |
+
'protocol' => array(
|
| 2788 |
'https',
|
| 2789 |
),
|
| 2790 |
),
|
| 2792 |
'template' => array(),
|
| 2793 |
),
|
| 2794 |
'tag_spec' => array(
|
| 2795 |
+
'amp_layout' => array(
|
| 2796 |
+
'supported_layouts' => array(
|
| 2797 |
+
6,
|
| 2798 |
+
2,
|
| 2799 |
+
3,
|
| 2800 |
+
7,
|
| 2801 |
+
1,
|
| 2802 |
+
4,
|
| 2803 |
+
),
|
| 2804 |
+
),
|
| 2805 |
'requires_extension' => array(
|
| 2806 |
'amp-list',
|
| 2807 |
),
|
| 2808 |
),
|
| 2809 |
),
|
| 2810 |
+
),
|
| 2811 |
+
'amp-live-list' => array(
|
| 2812 |
array(
|
| 2813 |
'attr_spec_list' => array(
|
| 2814 |
+
'data-max-items-per-page' => array(
|
| 2815 |
'mandatory' => true,
|
| 2816 |
+
'value_regex' => '\\d+',
|
| 2817 |
),
|
| 2818 |
+
'data-poll-interval' => array(
|
| 2819 |
+
'value_regex' => '\\d{5,}',
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2820 |
),
|
| 2821 |
+
'disabled' => array(
|
| 2822 |
+
'value' => array(
|
| 2823 |
+
'',
|
| 2824 |
+
),
|
| 2825 |
+
),
|
| 2826 |
+
'id' => array(
|
| 2827 |
+
'mandatory' => true,
|
| 2828 |
+
),
|
| 2829 |
+
'sort' => array(
|
| 2830 |
+
'value' => array(
|
| 2831 |
+
'ascending',
|
| 2832 |
),
|
| 2833 |
),
|
|
|
|
| 2834 |
),
|
| 2835 |
'tag_spec' => array(
|
| 2836 |
+
'amp_layout' => array(
|
| 2837 |
+
'supported_layouts' => array(
|
| 2838 |
+
5,
|
| 2839 |
+
3,
|
| 2840 |
+
),
|
| 2841 |
+
),
|
| 2842 |
+
'reference_points' => array(
|
| 2843 |
+
'AMP-LIVE-LIST [items]' => array(
|
| 2844 |
+
'mandatory' => true,
|
| 2845 |
+
'unique' => true,
|
| 2846 |
+
),
|
| 2847 |
+
'AMP-LIVE-LIST [pagination]' => array(
|
| 2848 |
+
'mandatory' => false,
|
| 2849 |
+
'unique' => true,
|
| 2850 |
+
),
|
| 2851 |
+
'AMP-LIVE-LIST [update]' => array(
|
| 2852 |
+
'mandatory' => true,
|
| 2853 |
+
'unique' => true,
|
| 2854 |
+
),
|
| 2855 |
+
),
|
| 2856 |
'requires_extension' => array(
|
| 2857 |
+
'amp-live-list',
|
| 2858 |
),
|
|
|
|
| 2859 |
),
|
| 2860 |
),
|
| 2861 |
),
|
| 2862 |
+
'amp-mathml' => array(
|
| 2863 |
array(
|
| 2864 |
'attr_spec_list' => array(
|
| 2865 |
+
'data-formula' => array(
|
| 2866 |
'mandatory' => true,
|
|
|
|
| 2867 |
),
|
| 2868 |
+
'inline' => array(),
|
| 2869 |
+
'media' => array(),
|
| 2870 |
+
'noloading' => array(
|
| 2871 |
+
'value' => array(
|
| 2872 |
+
'',
|
| 2873 |
+
),
|
| 2874 |
),
|
| 2875 |
+
),
|
| 2876 |
+
'tag_spec' => array(
|
| 2877 |
+
'amp_layout' => array(
|
| 2878 |
+
'supported_layouts' => array(
|
| 2879 |
+
5,
|
| 2880 |
+
),
|
| 2881 |
),
|
| 2882 |
+
'requires_extension' => array(
|
| 2883 |
+
'amp-mathml',
|
| 2884 |
+
),
|
| 2885 |
+
),
|
| 2886 |
+
),
|
| 2887 |
+
),
|
| 2888 |
+
'amp-mowplayer' => array(
|
| 2889 |
+
array(
|
| 2890 |
+
'attr_spec_list' => array(
|
| 2891 |
+
'autoplay' => array(),
|
| 2892 |
+
'data-mediaid' => array(
|
| 2893 |
'mandatory' => true,
|
| 2894 |
),
|
| 2895 |
+
'media' => array(),
|
| 2896 |
+
'noloading' => array(
|
| 2897 |
+
'value' => array(
|
| 2898 |
+
'',
|
| 2899 |
+
),
|
| 2900 |
),
|
| 2901 |
),
|
| 2902 |
'tag_spec' => array(
|
| 2903 |
+
'amp_layout' => array(
|
| 2904 |
+
'supported_layouts' => array(
|
| 2905 |
+
6,
|
| 2906 |
+
2,
|
| 2907 |
+
3,
|
| 2908 |
+
7,
|
| 2909 |
+
1,
|
| 2910 |
+
4,
|
| 2911 |
+
),
|
| 2912 |
+
),
|
| 2913 |
'requires_extension' => array(
|
| 2914 |
+
'amp-mowplayer',
|
| 2915 |
),
|
| 2916 |
),
|
| 2917 |
),
|
| 2918 |
),
|
| 2919 |
+
'amp-next-page' => array(
|
| 2920 |
+
array(
|
| 2921 |
+
'attr_spec_list' => array(),
|
| 2922 |
+
'tag_spec' => array(
|
| 2923 |
+
'reference_points' => array(
|
| 2924 |
+
'AMP-NEXT-PAGE > [separator]' => array(
|
| 2925 |
+
'mandatory' => false,
|
| 2926 |
+
'unique' => true,
|
| 2927 |
+
),
|
| 2928 |
+
'amp-next-page extension .json configuration' => array(
|
| 2929 |
+
'mandatory' => true,
|
| 2930 |
+
'unique' => true,
|
| 2931 |
+
),
|
| 2932 |
+
),
|
| 2933 |
+
'requires_extension' => array(
|
| 2934 |
+
'amp-next-page',
|
| 2935 |
+
),
|
| 2936 |
+
'spec_name' => 'amp-next-page with inline config',
|
| 2937 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-next-page',
|
| 2938 |
+
'unique' => true,
|
| 2939 |
+
),
|
| 2940 |
+
),
|
| 2941 |
array(
|
| 2942 |
'attr_spec_list' => array(
|
| 2943 |
+
'src' => array(
|
| 2944 |
+
'blacklisted_value_regex' => '__amp_source_origin',
|
| 2945 |
'mandatory' => true,
|
| 2946 |
+
'value_url' => array(
|
| 2947 |
+
'allow_relative' => false,
|
| 2948 |
+
'protocol' => array(
|
| 2949 |
+
'https',
|
| 2950 |
+
),
|
| 2951 |
+
),
|
| 2952 |
),
|
| 2953 |
+
),
|
| 2954 |
+
'tag_spec' => array(
|
| 2955 |
+
'reference_points' => array(
|
| 2956 |
+
'AMP-NEXT-PAGE > [separator]' => array(
|
| 2957 |
+
'mandatory' => false,
|
| 2958 |
+
'unique' => true,
|
| 2959 |
+
),
|
| 2960 |
+
),
|
| 2961 |
+
'requires_extension' => array(
|
| 2962 |
+
'amp-next-page',
|
| 2963 |
+
),
|
| 2964 |
+
'spec_name' => 'amp-next-page with src attribute',
|
| 2965 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-next-page',
|
| 2966 |
+
'unique' => true,
|
| 2967 |
+
),
|
| 2968 |
+
),
|
| 2969 |
+
array(
|
| 2970 |
+
'attr_spec_list' => array(
|
| 2971 |
+
'data-client' => array(
|
| 2972 |
+
'mandatory' => true,
|
| 2973 |
+
),
|
| 2974 |
+
'data-slot' => array(
|
| 2975 |
+
'mandatory' => true,
|
| 2976 |
+
),
|
| 2977 |
+
'type' => array(
|
| 2978 |
+
'mandatory' => true,
|
| 2979 |
+
'value' => array(
|
| 2980 |
+
'adsense',
|
| 2981 |
+
),
|
| 2982 |
),
|
| 2983 |
),
|
| 2984 |
'tag_spec' => array(
|
| 2985 |
+
'reference_points' => array(
|
| 2986 |
+
'AMP-NEXT-PAGE > [separator]' => array(
|
| 2987 |
+
'mandatory' => false,
|
| 2988 |
+
'unique' => true,
|
| 2989 |
+
),
|
| 2990 |
+
),
|
| 2991 |
'requires_extension' => array(
|
| 2992 |
+
'amp-next-page',
|
| 2993 |
),
|
| 2994 |
+
'spec_name' => 'amp-next-page [type=adsense]',
|
| 2995 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-next-page',
|
| 2996 |
+
'unique' => true,
|
| 2997 |
),
|
| 2998 |
),
|
| 2999 |
),
|
| 3008 |
'value_regex' => '[^=/?:]+',
|
| 3009 |
),
|
| 3010 |
'data-mode' => array(
|
| 3011 |
+
'value' => array(
|
| 3012 |
+
'api',
|
| 3013 |
+
'static',
|
| 3014 |
+
),
|
| 3015 |
),
|
| 3016 |
'data-origin' => array(
|
| 3017 |
'value_url' => array(
|
| 3018 |
'allow_empty' => true,
|
| 3019 |
+
'protocol' => array(
|
| 3020 |
'https',
|
| 3021 |
'http',
|
| 3022 |
),
|
| 3023 |
),
|
| 3024 |
),
|
| 3025 |
'data-streamtype' => array(
|
| 3026 |
+
'value' => array(
|
| 3027 |
+
'album',
|
| 3028 |
+
'audio',
|
| 3029 |
+
'live',
|
| 3030 |
+
'playlist',
|
| 3031 |
+
'playlist-marked',
|
| 3032 |
+
'video',
|
| 3033 |
+
),
|
| 3034 |
),
|
| 3035 |
'media' => array(),
|
| 3036 |
'noloading' => array(
|
| 3037 |
+
'value' => array(
|
| 3038 |
+
'',
|
| 3039 |
+
),
|
| 3040 |
),
|
| 3041 |
),
|
| 3042 |
'tag_spec' => array(
|
| 3043 |
+
'amp_layout' => array(
|
| 3044 |
+
'supported_layouts' => array(
|
| 3045 |
+
6,
|
| 3046 |
+
2,
|
| 3047 |
+
3,
|
| 3048 |
+
7,
|
| 3049 |
+
1,
|
| 3050 |
+
4,
|
| 3051 |
+
),
|
| 3052 |
+
),
|
| 3053 |
'requires_extension' => array(
|
| 3054 |
'amp-nexxtv-player',
|
| 3055 |
),
|
| 3067 |
),
|
| 3068 |
'media' => array(),
|
| 3069 |
'noloading' => array(
|
| 3070 |
+
'value' => array(
|
| 3071 |
+
'',
|
| 3072 |
+
),
|
| 3073 |
),
|
| 3074 |
),
|
| 3075 |
'tag_spec' => array(
|
| 3076 |
+
'amp_layout' => array(
|
| 3077 |
+
'supported_layouts' => array(
|
| 3078 |
+
6,
|
| 3079 |
+
2,
|
| 3080 |
+
3,
|
| 3081 |
+
7,
|
| 3082 |
+
1,
|
| 3083 |
+
4,
|
| 3084 |
+
),
|
| 3085 |
+
),
|
| 3086 |
'requires_extension' => array(
|
| 3087 |
'amp-o2-player',
|
| 3088 |
),
|
| 3103 |
),
|
| 3104 |
'media' => array(),
|
| 3105 |
'noloading' => array(
|
| 3106 |
+
'value' => array(
|
| 3107 |
+
'',
|
| 3108 |
+
),
|
| 3109 |
),
|
| 3110 |
),
|
| 3111 |
'tag_spec' => array(
|
| 3112 |
+
'amp_layout' => array(
|
| 3113 |
+
'supported_layouts' => array(
|
| 3114 |
+
6,
|
| 3115 |
+
2,
|
| 3116 |
+
7,
|
| 3117 |
+
4,
|
| 3118 |
+
),
|
| 3119 |
+
),
|
| 3120 |
'requires_extension' => array(
|
| 3121 |
'amp-ooyala-player',
|
| 3122 |
),
|
| 3123 |
),
|
| 3124 |
),
|
| 3125 |
),
|
| 3126 |
+
'amp-orientation-observer' => array(
|
| 3127 |
+
array(
|
| 3128 |
+
'attr_spec_list' => array(
|
| 3129 |
+
'alpha-range' => array(
|
| 3130 |
+
'value_regex' => '(\\d+)\\s{1}(\\d+)',
|
| 3131 |
+
),
|
| 3132 |
+
'beta-range' => array(
|
| 3133 |
+
'value_regex' => '(\\d+)\\s{1}(\\d+)',
|
| 3134 |
+
),
|
| 3135 |
+
'gamma-range' => array(
|
| 3136 |
+
'value_regex' => '(\\d+)\\s{1}(\\d+)',
|
| 3137 |
+
),
|
| 3138 |
+
'media' => array(),
|
| 3139 |
+
'noloading' => array(
|
| 3140 |
+
'value' => array(
|
| 3141 |
+
'',
|
| 3142 |
+
),
|
| 3143 |
+
),
|
| 3144 |
+
),
|
| 3145 |
+
'tag_spec' => array(
|
| 3146 |
+
'amp_layout' => array(
|
| 3147 |
+
'supported_layouts' => array(
|
| 3148 |
+
1,
|
| 3149 |
+
),
|
| 3150 |
+
),
|
| 3151 |
+
'requires_extension' => array(
|
| 3152 |
+
'amp-orientation-observer',
|
| 3153 |
+
),
|
| 3154 |
+
),
|
| 3155 |
+
),
|
| 3156 |
+
),
|
| 3157 |
+
'amp-pan-zoom' => array(
|
| 3158 |
+
array(
|
| 3159 |
+
'attr_spec_list' => array(
|
| 3160 |
+
'disable-double-tap' => array(
|
| 3161 |
+
'value' => array(
|
| 3162 |
+
'',
|
| 3163 |
+
),
|
| 3164 |
+
),
|
| 3165 |
+
'initial-scale' => array(
|
| 3166 |
+
'value_regex' => '[0-9]+(\\.[0-9]+)?',
|
| 3167 |
+
),
|
| 3168 |
+
'initial-x' => array(
|
| 3169 |
+
'value_regex' => '[0-9]+',
|
| 3170 |
+
),
|
| 3171 |
+
'initial-y' => array(
|
| 3172 |
+
'value_regex' => '[0-9]+',
|
| 3173 |
+
),
|
| 3174 |
+
'max-scale' => array(
|
| 3175 |
+
'value_regex' => '[0-9]+(\\.[0-9]+)?',
|
| 3176 |
+
),
|
| 3177 |
+
'media' => array(),
|
| 3178 |
+
'noloading' => array(
|
| 3179 |
+
'value' => array(
|
| 3180 |
+
'',
|
| 3181 |
+
),
|
| 3182 |
+
),
|
| 3183 |
+
'reset-on-resize' => array(
|
| 3184 |
+
'value' => array(
|
| 3185 |
+
'',
|
| 3186 |
+
),
|
| 3187 |
+
),
|
| 3188 |
+
),
|
| 3189 |
+
'tag_spec' => array(
|
| 3190 |
+
'amp_layout' => array(
|
| 3191 |
+
'supported_layouts' => array(
|
| 3192 |
+
6,
|
| 3193 |
+
2,
|
| 3194 |
+
3,
|
| 3195 |
+
4,
|
| 3196 |
+
),
|
| 3197 |
+
),
|
| 3198 |
+
'requires_extension' => array(
|
| 3199 |
+
'amp-pan-zoom',
|
| 3200 |
+
),
|
| 3201 |
+
),
|
| 3202 |
+
),
|
| 3203 |
+
),
|
| 3204 |
'amp-pinterest' => array(
|
| 3205 |
array(
|
| 3206 |
'attr_spec_list' => array(
|
| 3210 |
),
|
| 3211 |
'media' => array(),
|
| 3212 |
'noloading' => array(
|
| 3213 |
+
'value' => array(
|
| 3214 |
+
'',
|
| 3215 |
+
),
|
| 3216 |
),
|
| 3217 |
),
|
| 3218 |
'tag_spec' => array(
|
| 3219 |
+
'amp_layout' => array(
|
| 3220 |
+
'supported_layouts' => array(
|
| 3221 |
+
6,
|
| 3222 |
+
2,
|
| 3223 |
+
3,
|
| 3224 |
+
7,
|
| 3225 |
+
1,
|
| 3226 |
+
4,
|
| 3227 |
+
),
|
| 3228 |
+
),
|
| 3229 |
'requires_extension' => array(
|
| 3230 |
'amp-pinterest',
|
| 3231 |
),
|
| 3239 |
'allow-ssr-img' => array(),
|
| 3240 |
'media' => array(),
|
| 3241 |
'noloading' => array(
|
| 3242 |
+
'value' => array(
|
| 3243 |
+
'',
|
| 3244 |
+
),
|
| 3245 |
),
|
| 3246 |
'referrerpolicy' => array(
|
| 3247 |
+
'value' => array(
|
| 3248 |
+
'no-referrer',
|
| 3249 |
+
),
|
| 3250 |
),
|
| 3251 |
'src' => array(
|
| 3252 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 3254 |
'value_url' => array(
|
| 3255 |
'allow_empty' => true,
|
| 3256 |
'allow_relative' => true,
|
| 3257 |
+
'protocol' => array(
|
| 3258 |
'https',
|
| 3259 |
),
|
| 3260 |
),
|
| 3261 |
),
|
| 3262 |
),
|
| 3263 |
'tag_spec' => array(
|
| 3264 |
+
'amp_layout' => array(
|
| 3265 |
+
'defines_default_height' => true,
|
| 3266 |
+
'defines_default_width' => true,
|
| 3267 |
+
'supported_layouts' => array(
|
| 3268 |
+
2,
|
| 3269 |
+
1,
|
| 3270 |
+
),
|
| 3271 |
+
),
|
| 3272 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-pixel',
|
| 3273 |
),
|
| 3274 |
),
|
| 3277 |
array(
|
| 3278 |
'attr_spec_list' => array(
|
| 3279 |
'data-comments' => array(
|
| 3280 |
+
'value_casei' => array(
|
| 3281 |
+
'false',
|
| 3282 |
+
'true',
|
| 3283 |
+
),
|
| 3284 |
),
|
| 3285 |
'data-item' => array(),
|
| 3286 |
'data-item-info' => array(
|
| 3287 |
+
'value_casei' => array(
|
| 3288 |
+
'false',
|
| 3289 |
+
'true',
|
| 3290 |
+
),
|
| 3291 |
),
|
| 3292 |
'data-share-buttons' => array(
|
| 3293 |
+
'value_casei' => array(
|
| 3294 |
+
'false',
|
| 3295 |
+
'true',
|
| 3296 |
+
),
|
| 3297 |
),
|
| 3298 |
'media' => array(),
|
| 3299 |
'noloading' => array(
|
| 3300 |
+
'value' => array(
|
| 3301 |
+
'',
|
| 3302 |
+
),
|
| 3303 |
),
|
| 3304 |
'src' => array(),
|
| 3305 |
),
|
| 3306 |
'tag_spec' => array(
|
| 3307 |
+
'amp_layout' => array(
|
| 3308 |
+
'supported_layouts' => array(
|
| 3309 |
+
4,
|
| 3310 |
+
3,
|
| 3311 |
+
),
|
| 3312 |
+
),
|
| 3313 |
'requires_extension' => array(
|
| 3314 |
'amp-playbuzz',
|
| 3315 |
),
|
| 3324 |
),
|
| 3325 |
'media' => array(),
|
| 3326 |
'noloading' => array(
|
| 3327 |
+
'value' => array(
|
| 3328 |
+
'',
|
| 3329 |
+
),
|
| 3330 |
+
),
|
| 3331 |
+
'once' => array(
|
| 3332 |
+
'value' => array(
|
| 3333 |
+
'',
|
| 3334 |
+
),
|
| 3335 |
),
|
| 3336 |
'target' => array(),
|
| 3337 |
'viewport-margins' => array(
|
| 3339 |
),
|
| 3340 |
),
|
| 3341 |
'tag_spec' => array(
|
| 3342 |
+
'amp_layout' => array(
|
| 3343 |
+
'supported_layouts' => array(
|
| 3344 |
+
1,
|
| 3345 |
+
),
|
| 3346 |
+
),
|
| 3347 |
'requires_extension' => array(
|
| 3348 |
'amp-position-observer',
|
| 3349 |
),
|
| 3350 |
),
|
| 3351 |
),
|
| 3352 |
),
|
| 3353 |
+
'amp-powr-player' => array(
|
| 3354 |
+
array(
|
| 3355 |
+
'attr_spec_list' => array(
|
| 3356 |
+
'[data-referrer]' => array(),
|
| 3357 |
+
'autoplay' => array(),
|
| 3358 |
+
'data-account' => array(
|
| 3359 |
+
'mandatory' => true,
|
| 3360 |
+
'value_regex' => '[0-9a-zA-Z-]+',
|
| 3361 |
+
),
|
| 3362 |
+
'data-player' => array(
|
| 3363 |
+
'mandatory' => true,
|
| 3364 |
+
'value_regex' => '[0-9a-zA-Z-]+',
|
| 3365 |
+
),
|
| 3366 |
+
'data-terms' => array(),
|
| 3367 |
+
'data-video' => array(
|
| 3368 |
+
'value_regex' => '[0-9a-zA-Z-]+',
|
| 3369 |
+
),
|
| 3370 |
+
'media' => array(),
|
| 3371 |
+
'noloading' => array(
|
| 3372 |
+
'value' => array(
|
| 3373 |
+
'',
|
| 3374 |
+
),
|
| 3375 |
+
),
|
| 3376 |
+
),
|
| 3377 |
+
'tag_spec' => array(
|
| 3378 |
+
'amp_layout' => array(
|
| 3379 |
+
'supported_layouts' => array(
|
| 3380 |
+
6,
|
| 3381 |
+
2,
|
| 3382 |
+
3,
|
| 3383 |
+
7,
|
| 3384 |
+
1,
|
| 3385 |
+
4,
|
| 3386 |
+
),
|
| 3387 |
+
),
|
| 3388 |
+
'requires_extension' => array(
|
| 3389 |
+
'amp-powr-player',
|
| 3390 |
+
),
|
| 3391 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-powr-player',
|
| 3392 |
+
),
|
| 3393 |
+
),
|
| 3394 |
+
),
|
| 3395 |
'amp-reach-player' => array(
|
| 3396 |
array(
|
| 3397 |
'attr_spec_list' => array(
|
| 3401 |
),
|
| 3402 |
'media' => array(),
|
| 3403 |
'noloading' => array(
|
| 3404 |
+
'value' => array(
|
| 3405 |
+
'',
|
| 3406 |
+
),
|
| 3407 |
),
|
| 3408 |
),
|
| 3409 |
'tag_spec' => array(
|
| 3410 |
+
'amp_layout' => array(
|
| 3411 |
+
'supported_layouts' => array(
|
| 3412 |
+
6,
|
| 3413 |
+
2,
|
| 3414 |
+
3,
|
| 3415 |
+
7,
|
| 3416 |
+
4,
|
| 3417 |
+
),
|
| 3418 |
+
),
|
| 3419 |
'requires_extension' => array(
|
| 3420 |
'amp-reach-player',
|
| 3421 |
),
|
| 3426 |
array(
|
| 3427 |
'attr_spec_list' => array(
|
| 3428 |
'data-embedlive' => array(
|
| 3429 |
+
'value_casei' => array(
|
| 3430 |
+
'false',
|
| 3431 |
+
'true',
|
| 3432 |
+
),
|
| 3433 |
),
|
| 3434 |
'data-embedparent' => array(
|
| 3435 |
+
'value_casei' => array(
|
| 3436 |
+
'false',
|
| 3437 |
+
'true',
|
| 3438 |
+
),
|
| 3439 |
),
|
| 3440 |
'data-embedtype' => array(
|
| 3441 |
'mandatory' => true,
|
| 3442 |
+
'value_casei' => array(
|
| 3443 |
+
'comment',
|
| 3444 |
+
'post',
|
| 3445 |
+
),
|
| 3446 |
),
|
| 3447 |
'data-src' => array(
|
| 3448 |
'mandatory' => true,
|
| 3449 |
),
|
| 3450 |
'media' => array(),
|
| 3451 |
'noloading' => array(
|
| 3452 |
+
'value' => array(
|
| 3453 |
+
'',
|
| 3454 |
+
),
|
| 3455 |
),
|
| 3456 |
),
|
| 3457 |
'tag_spec' => array(
|
| 3458 |
+
'amp_layout' => array(
|
| 3459 |
+
'supported_layouts' => array(
|
| 3460 |
+
6,
|
| 3461 |
+
2,
|
| 3462 |
+
3,
|
| 3463 |
+
7,
|
| 3464 |
+
1,
|
| 3465 |
+
4,
|
| 3466 |
+
),
|
| 3467 |
+
),
|
| 3468 |
'requires_extension' => array(
|
| 3469 |
'amp-reddit',
|
| 3470 |
),
|
| 3480 |
),
|
| 3481 |
'media' => array(),
|
| 3482 |
'noloading' => array(
|
| 3483 |
+
'value' => array(
|
| 3484 |
+
'',
|
| 3485 |
+
),
|
| 3486 |
),
|
| 3487 |
),
|
| 3488 |
'tag_spec' => array(
|
| 3489 |
+
'amp_layout' => array(
|
| 3490 |
+
'supported_layouts' => array(
|
| 3491 |
+
4,
|
| 3492 |
+
),
|
| 3493 |
+
),
|
| 3494 |
'requires_extension' => array(
|
| 3495 |
'amp-riddle-quiz',
|
| 3496 |
),
|
| 3504 |
'[disabled]' => array(),
|
| 3505 |
'[selected]' => array(),
|
| 3506 |
'disabled' => array(
|
| 3507 |
+
'value' => array(
|
| 3508 |
+
'',
|
| 3509 |
+
),
|
| 3510 |
),
|
| 3511 |
'form' => array(),
|
| 3512 |
'keyboard-select-mode' => array(
|
| 3513 |
+
'value_casei' => array(
|
| 3514 |
+
'focus',
|
| 3515 |
+
'none',
|
| 3516 |
+
'select',
|
| 3517 |
+
),
|
| 3518 |
),
|
| 3519 |
'media' => array(),
|
| 3520 |
'multiple' => array(
|
| 3521 |
+
'value' => array(
|
| 3522 |
+
'',
|
| 3523 |
+
),
|
| 3524 |
),
|
| 3525 |
'name' => array(
|
| 3526 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 3527 |
),
|
| 3528 |
'noloading' => array(
|
| 3529 |
+
'value' => array(
|
| 3530 |
+
'',
|
| 3531 |
+
),
|
| 3532 |
),
|
| 3533 |
),
|
| 3534 |
'tag_spec' => array(
|
| 3535 |
+
'amp_layout' => array(
|
| 3536 |
+
'supported_layouts' => array(
|
| 3537 |
+
6,
|
| 3538 |
+
2,
|
| 3539 |
+
3,
|
| 3540 |
+
1,
|
| 3541 |
+
4,
|
| 3542 |
+
5,
|
| 3543 |
+
),
|
| 3544 |
+
),
|
| 3545 |
'disallowed_ancestor' => array(
|
| 3546 |
'amp-selector',
|
| 3547 |
),
|
| 3548 |
+
'reference_points' => array(
|
| 3549 |
+
'AMP-SELECTOR child' => array(
|
| 3550 |
+
'mandatory' => false,
|
| 3551 |
+
'unique' => false,
|
| 3552 |
+
),
|
| 3553 |
+
'AMP-SELECTOR option' => array(
|
| 3554 |
+
'mandatory' => false,
|
| 3555 |
+
'unique' => false,
|
| 3556 |
+
),
|
| 3557 |
+
),
|
| 3558 |
'requires_extension' => array(
|
| 3559 |
'amp-selector',
|
| 3560 |
),
|
| 3566 |
'attr_spec_list' => array(
|
| 3567 |
'media' => array(),
|
| 3568 |
'noloading' => array(
|
| 3569 |
+
'value' => array(
|
| 3570 |
+
'',
|
| 3571 |
+
),
|
| 3572 |
),
|
| 3573 |
'side' => array(
|
| 3574 |
+
'value' => array(
|
| 3575 |
+
'left',
|
| 3576 |
+
'right',
|
| 3577 |
+
),
|
| 3578 |
),
|
| 3579 |
),
|
| 3580 |
'tag_spec' => array(
|
| 3581 |
+
'amp_layout' => array(
|
| 3582 |
+
'supported_layouts' => array(
|
| 3583 |
+
1,
|
| 3584 |
+
),
|
| 3585 |
+
),
|
| 3586 |
'mandatory_parent' => 'body',
|
| 3587 |
'requires_extension' => array(
|
| 3588 |
'amp-sidebar',
|
| 3590 |
),
|
| 3591 |
),
|
| 3592 |
),
|
| 3593 |
+
'amp-skimlinks' => array(
|
| 3594 |
+
array(
|
| 3595 |
+
'attr_spec_list' => array(
|
| 3596 |
+
'custom-tracking-id' => array(
|
| 3597 |
+
'value_regex_casei' => '^.{0,50}$',
|
| 3598 |
+
),
|
| 3599 |
+
'excluded-domains' => array(),
|
| 3600 |
+
'link-selector' => array(),
|
| 3601 |
+
'media' => array(),
|
| 3602 |
+
'noloading' => array(
|
| 3603 |
+
'value' => array(
|
| 3604 |
+
'',
|
| 3605 |
+
),
|
| 3606 |
+
),
|
| 3607 |
+
'publisher-code' => array(
|
| 3608 |
+
'mandatory' => true,
|
| 3609 |
+
'value_regex_casei' => '^[0-9]+X[0-9]+$',
|
| 3610 |
+
),
|
| 3611 |
+
'tracking' => array(
|
| 3612 |
+
'value' => array(
|
| 3613 |
+
'false',
|
| 3614 |
+
'true',
|
| 3615 |
+
),
|
| 3616 |
+
),
|
| 3617 |
+
),
|
| 3618 |
+
'tag_spec' => array(
|
| 3619 |
+
'amp_layout' => array(
|
| 3620 |
+
'supported_layouts' => array(
|
| 3621 |
+
1,
|
| 3622 |
+
),
|
| 3623 |
+
),
|
| 3624 |
+
'requires_extension' => array(
|
| 3625 |
+
'amp-skimlinks',
|
| 3626 |
+
),
|
| 3627 |
+
),
|
| 3628 |
+
),
|
| 3629 |
+
),
|
| 3630 |
'amp-social-share' => array(
|
| 3631 |
array(
|
| 3632 |
'attr_spec_list' => array(
|
| 3634 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 3635 |
'value_url' => array(
|
| 3636 |
'allow_relative' => false,
|
| 3637 |
+
'protocol' => array(
|
| 3638 |
'ftp',
|
| 3639 |
'http',
|
| 3640 |
'https',
|
| 3656 |
),
|
| 3657 |
'media' => array(),
|
| 3658 |
'noloading' => array(
|
| 3659 |
+
'value' => array(
|
| 3660 |
+
'',
|
| 3661 |
+
),
|
| 3662 |
),
|
| 3663 |
'type' => array(
|
| 3664 |
'mandatory' => true,
|
| 3665 |
),
|
| 3666 |
),
|
| 3667 |
'tag_spec' => array(
|
| 3668 |
+
'amp_layout' => array(
|
| 3669 |
+
'supported_layouts' => array(
|
| 3670 |
+
5,
|
| 3671 |
+
6,
|
| 3672 |
+
2,
|
| 3673 |
+
3,
|
| 3674 |
+
7,
|
| 3675 |
+
1,
|
| 3676 |
+
4,
|
| 3677 |
+
),
|
| 3678 |
+
),
|
| 3679 |
'requires_extension' => array(
|
| 3680 |
'amp-social-share',
|
| 3681 |
),
|
| 3698 |
'value_regex' => '[0-9]+',
|
| 3699 |
),
|
| 3700 |
'data-visual' => array(
|
| 3701 |
+
'value_casei' => array(
|
| 3702 |
+
'false',
|
| 3703 |
+
'true',
|
| 3704 |
+
),
|
| 3705 |
),
|
| 3706 |
'media' => array(),
|
| 3707 |
'noloading' => array(
|
| 3708 |
+
'value' => array(
|
| 3709 |
+
'',
|
| 3710 |
+
),
|
| 3711 |
),
|
| 3712 |
),
|
| 3713 |
'tag_spec' => array(
|
| 3714 |
+
'amp_layout' => array(
|
| 3715 |
+
'supported_layouts' => array(
|
| 3716 |
+
3,
|
| 3717 |
+
),
|
| 3718 |
+
),
|
| 3719 |
'requires_extension' => array(
|
| 3720 |
'amp-soundcloud',
|
| 3721 |
),
|
| 3736 |
),
|
| 3737 |
'data-mode' => array(
|
| 3738 |
'mandatory' => true,
|
| 3739 |
+
'value_casei' => array(
|
| 3740 |
+
'playlist',
|
| 3741 |
+
'video',
|
| 3742 |
+
),
|
| 3743 |
),
|
| 3744 |
'data-player-id' => array(
|
| 3745 |
'mandatory' => true,
|
| 3751 |
),
|
| 3752 |
'media' => array(),
|
| 3753 |
'noloading' => array(
|
| 3754 |
+
'value' => array(
|
| 3755 |
+
'',
|
| 3756 |
+
),
|
| 3757 |
),
|
| 3758 |
),
|
| 3759 |
'tag_spec' => array(
|
| 3760 |
+
'amp_layout' => array(
|
| 3761 |
+
'supported_layouts' => array(
|
| 3762 |
+
6,
|
| 3763 |
+
2,
|
| 3764 |
+
7,
|
| 3765 |
+
4,
|
| 3766 |
+
),
|
| 3767 |
+
),
|
| 3768 |
'requires_extension' => array(
|
| 3769 |
'amp-springboard-player',
|
| 3770 |
),
|
| 3784 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 3785 |
'value_url' => array(
|
| 3786 |
'allow_relative' => true,
|
| 3787 |
+
'protocol' => array(
|
| 3788 |
'https',
|
| 3789 |
),
|
| 3790 |
),
|
| 3804 |
'attr_spec_list' => array(
|
| 3805 |
'media' => array(),
|
| 3806 |
'noloading' => array(
|
| 3807 |
+
'value' => array(
|
| 3808 |
+
'',
|
| 3809 |
+
),
|
| 3810 |
),
|
| 3811 |
),
|
| 3812 |
'tag_spec' => array(
|
| 3813 |
+
'amp_layout' => array(
|
| 3814 |
+
'supported_layouts' => array(
|
| 3815 |
+
1,
|
| 3816 |
+
),
|
| 3817 |
+
),
|
| 3818 |
'disallowed_ancestor' => array(
|
| 3819 |
'amp-app-banner',
|
| 3820 |
),
|
| 3830 |
'attr_spec_list' => array(
|
| 3831 |
'background-audio' => array(
|
| 3832 |
'value_url' => array(
|
| 3833 |
+
'protocol' => array(
|
| 3834 |
'http',
|
| 3835 |
'https',
|
| 3836 |
),
|
| 3838 |
),
|
| 3839 |
'bookend-config-src' => array(
|
| 3840 |
'value_url' => array(
|
| 3841 |
+
'protocol' => array(
|
| 3842 |
'http',
|
| 3843 |
'https',
|
| 3844 |
),
|
| 3845 |
),
|
| 3846 |
),
|
| 3847 |
+
'poster-landscape-src' => array(
|
| 3848 |
+
'value_url' => array(
|
| 3849 |
+
'protocol' => array(
|
| 3850 |
+
'http',
|
| 3851 |
+
'https',
|
| 3852 |
+
),
|
| 3853 |
+
),
|
| 3854 |
+
),
|
| 3855 |
+
'poster-portrait-src' => array(
|
| 3856 |
+
'mandatory' => true,
|
| 3857 |
+
'value_url' => array(
|
| 3858 |
+
'protocol' => array(
|
| 3859 |
+
'http',
|
| 3860 |
+
'https',
|
| 3861 |
+
),
|
| 3862 |
+
),
|
| 3863 |
+
),
|
| 3864 |
+
'poster-square-src' => array(
|
| 3865 |
+
'value_url' => array(
|
| 3866 |
+
'protocol' => array(
|
| 3867 |
+
'http',
|
| 3868 |
+
'https',
|
| 3869 |
+
),
|
| 3870 |
+
),
|
| 3871 |
+
),
|
| 3872 |
+
'publisher' => array(
|
| 3873 |
+
'mandatory' => true,
|
| 3874 |
+
),
|
| 3875 |
+
'publisher-logo-src' => array(
|
| 3876 |
+
'mandatory' => true,
|
| 3877 |
+
'value_url' => array(
|
| 3878 |
+
'protocol' => array(
|
| 3879 |
+
'http',
|
| 3880 |
+
'https',
|
| 3881 |
+
),
|
| 3882 |
+
),
|
| 3883 |
+
),
|
| 3884 |
+
'standalone' => array(
|
| 3885 |
+
'mandatory' => true,
|
| 3886 |
+
'value' => array(
|
| 3887 |
+
'',
|
| 3888 |
+
),
|
| 3889 |
+
),
|
| 3890 |
+
'title' => array(
|
| 3891 |
+
'mandatory' => true,
|
| 3892 |
),
|
| 3893 |
),
|
| 3894 |
'tag_spec' => array(
|
| 3899 |
),
|
| 3900 |
),
|
| 3901 |
),
|
| 3902 |
+
'amp-story-access' => array(
|
| 3903 |
+
array(
|
| 3904 |
+
'attr_spec_list' => array(
|
| 3905 |
+
'media' => array(),
|
| 3906 |
+
'noloading' => array(
|
| 3907 |
+
'value' => array(
|
| 3908 |
+
'',
|
| 3909 |
+
),
|
| 3910 |
+
),
|
| 3911 |
+
'type' => array(
|
| 3912 |
+
'value' => array(
|
| 3913 |
+
'blocking',
|
| 3914 |
+
'notification',
|
| 3915 |
+
),
|
| 3916 |
+
),
|
| 3917 |
+
),
|
| 3918 |
+
'tag_spec' => array(
|
| 3919 |
+
'mandatory_parent' => 'amp-story',
|
| 3920 |
+
'requires_extension' => array(
|
| 3921 |
+
'amp-access',
|
| 3922 |
+
),
|
| 3923 |
+
),
|
| 3924 |
+
),
|
| 3925 |
+
),
|
| 3926 |
'amp-story-auto-ads' => array(
|
| 3927 |
array(
|
| 3928 |
'attr_spec_list' => array(),
|
| 3936 |
),
|
| 3937 |
),
|
| 3938 |
),
|
| 3939 |
+
'amp-story-bookend' => array(
|
| 3940 |
+
array(
|
| 3941 |
+
'attr_spec_list' => array(
|
| 3942 |
+
'layout' => array(
|
| 3943 |
+
'mandatory' => true,
|
| 3944 |
+
'value' => array(
|
| 3945 |
+
'nodisplay',
|
| 3946 |
+
),
|
| 3947 |
+
),
|
| 3948 |
+
'src' => array(
|
| 3949 |
+
'value_url' => array(
|
| 3950 |
+
'protocol' => array(
|
| 3951 |
+
'http',
|
| 3952 |
+
'https',
|
| 3953 |
+
),
|
| 3954 |
+
),
|
| 3955 |
+
),
|
| 3956 |
+
),
|
| 3957 |
+
'tag_spec' => array(
|
| 3958 |
+
'mandatory_ancestor' => 'amp-story',
|
| 3959 |
+
),
|
| 3960 |
+
),
|
| 3961 |
+
),
|
| 3962 |
+
'amp-story-consent' => array(
|
| 3963 |
+
array(
|
| 3964 |
+
'attr_spec_list' => array(
|
| 3965 |
+
'id' => array(
|
| 3966 |
+
'mandatory' => true,
|
| 3967 |
+
),
|
| 3968 |
+
),
|
| 3969 |
+
'tag_spec' => array(
|
| 3970 |
+
'amp_layout' => array(
|
| 3971 |
+
'supported_layouts' => array(
|
| 3972 |
+
1,
|
| 3973 |
+
),
|
| 3974 |
+
),
|
| 3975 |
+
'mandatory_parent' => 'amp-consent',
|
| 3976 |
+
'requires_extension' => array(
|
| 3977 |
+
'amp-consent',
|
| 3978 |
+
'amp-story',
|
| 3979 |
+
),
|
| 3980 |
+
),
|
| 3981 |
+
),
|
| 3982 |
+
),
|
| 3983 |
'amp-story-cta-layer' => array(
|
| 3984 |
array(
|
| 3985 |
'attr_spec_list' => array(),
|
| 3986 |
'tag_spec' => array(
|
| 3987 |
'mandatory_ancestor' => 'amp-story-page',
|
| 3988 |
+
'reference_points' => array(
|
| 3989 |
+
'AMP-STORY-CTA-LAYER animate-in' => array(
|
| 3990 |
+
'mandatory' => false,
|
| 3991 |
+
'unique' => false,
|
| 3992 |
+
),
|
| 3993 |
+
),
|
| 3994 |
),
|
| 3995 |
),
|
| 3996 |
),
|
| 3999 |
'attr_spec_list' => array(
|
| 4000 |
'template' => array(
|
| 4001 |
'mandatory' => true,
|
| 4002 |
+
'value' => array(
|
| 4003 |
+
'fill',
|
| 4004 |
+
'horizontal',
|
| 4005 |
+
'thirds',
|
| 4006 |
+
'vertical',
|
| 4007 |
+
),
|
| 4008 |
),
|
| 4009 |
),
|
| 4010 |
'tag_spec' => array(
|
| 4011 |
'mandatory_ancestor' => 'amp-story-page',
|
| 4012 |
+
'reference_points' => array(
|
| 4013 |
+
'AMP-STORY-GRID-LAYER animate-in' => array(
|
| 4014 |
+
'mandatory' => false,
|
| 4015 |
+
'unique' => false,
|
| 4016 |
+
),
|
| 4017 |
+
'AMP-STORY-GRID-LAYER default' => array(
|
| 4018 |
+
'mandatory' => false,
|
| 4019 |
+
'unique' => false,
|
| 4020 |
+
),
|
| 4021 |
+
),
|
| 4022 |
),
|
| 4023 |
),
|
| 4024 |
),
|
| 4028 |
'auto-advance-after' => array(),
|
| 4029 |
'background-audio' => array(
|
| 4030 |
'value_url' => array(
|
| 4031 |
+
'protocol' => array(
|
| 4032 |
'http',
|
| 4033 |
'https',
|
| 4034 |
),
|
| 4049 |
'amp-timeago' => array(
|
| 4050 |
array(
|
| 4051 |
'attr_spec_list' => array(
|
| 4052 |
+
'[datetime]' => array(),
|
| 4053 |
+
'[title]' => array(),
|
| 4054 |
'cutoff' => array(
|
| 4055 |
'value_regex' => '\\d+',
|
| 4056 |
),
|
| 4061 |
'locale' => array(),
|
| 4062 |
'media' => array(),
|
| 4063 |
'noloading' => array(
|
| 4064 |
+
'value' => array(
|
| 4065 |
+
'',
|
| 4066 |
+
),
|
| 4067 |
),
|
| 4068 |
),
|
| 4069 |
'tag_spec' => array(
|
| 4070 |
+
'amp_layout' => array(
|
| 4071 |
+
'supported_layouts' => array(
|
| 4072 |
+
2,
|
| 4073 |
+
3,
|
| 4074 |
+
4,
|
| 4075 |
+
),
|
| 4076 |
+
),
|
| 4077 |
'requires_extension' => array(
|
| 4078 |
'amp-timeago',
|
| 4079 |
),
|
| 4084 |
'amp-twitter' => array(
|
| 4085 |
array(
|
| 4086 |
'attr_spec_list' => array(
|
| 4087 |
+
'data-cards' => array(),
|
| 4088 |
+
'data-conversation' => array(),
|
| 4089 |
+
'data-limit' => array(),
|
| 4090 |
+
'data-link-color' => array(),
|
| 4091 |
+
'data-momentid' => array(
|
| 4092 |
+
'value_regex' => '\\d+',
|
| 4093 |
+
),
|
| 4094 |
+
'data-theme' => array(),
|
| 4095 |
+
'data-timeline-id' => array(
|
| 4096 |
+
'value_regex' => '\\d+',
|
| 4097 |
+
),
|
| 4098 |
+
'data-timeline-owner-screen-name' => array(),
|
| 4099 |
+
'data-timeline-screen-name' => array(),
|
| 4100 |
+
'data-timeline-slug' => array(),
|
| 4101 |
+
'data-timeline-source-type' => array(),
|
| 4102 |
+
'data-timeline-url' => array(
|
| 4103 |
+
'value_url' => array(
|
| 4104 |
+
'allow_relative' => false,
|
| 4105 |
+
'protocol' => array(
|
| 4106 |
+
'http',
|
| 4107 |
+
'https',
|
| 4108 |
+
),
|
| 4109 |
+
),
|
| 4110 |
+
),
|
| 4111 |
+
'data-timeline-user-id' => array(
|
| 4112 |
+
'value_regex' => '\\d+',
|
| 4113 |
),
|
| 4114 |
+
'data-tweetid' => array(),
|
| 4115 |
'media' => array(),
|
| 4116 |
'noloading' => array(
|
| 4117 |
+
'value' => array(
|
| 4118 |
+
'',
|
| 4119 |
+
),
|
| 4120 |
),
|
| 4121 |
),
|
| 4122 |
'tag_spec' => array(
|
| 4123 |
+
'amp_layout' => array(
|
| 4124 |
+
'supported_layouts' => array(
|
| 4125 |
+
6,
|
| 4126 |
+
2,
|
| 4127 |
+
3,
|
| 4128 |
+
7,
|
| 4129 |
+
9,
|
| 4130 |
+
1,
|
| 4131 |
+
4,
|
| 4132 |
+
),
|
| 4133 |
+
),
|
| 4134 |
'requires_extension' => array(
|
| 4135 |
'amp-twitter',
|
| 4136 |
),
|
| 4144 |
'value_url' => array(
|
| 4145 |
'allow_empty' => false,
|
| 4146 |
'allow_relative' => false,
|
| 4147 |
+
'protocol' => array(
|
| 4148 |
'https',
|
| 4149 |
),
|
| 4150 |
),
|
| 4153 |
'value_url' => array(
|
| 4154 |
'allow_empty' => false,
|
| 4155 |
'allow_relative' => false,
|
| 4156 |
+
'protocol' => array(
|
| 4157 |
'https',
|
| 4158 |
),
|
| 4159 |
),
|
| 4160 |
),
|
| 4161 |
'enctype' => array(
|
| 4162 |
+
'value' => array(
|
| 4163 |
+
'application/x-www-form-urlencoded',
|
| 4164 |
+
),
|
| 4165 |
),
|
| 4166 |
'media' => array(),
|
| 4167 |
'noloading' => array(
|
| 4168 |
+
'value' => array(
|
| 4169 |
+
'',
|
| 4170 |
+
),
|
| 4171 |
),
|
| 4172 |
),
|
| 4173 |
'tag_spec' => array(
|
| 4174 |
+
'amp_layout' => array(
|
| 4175 |
+
'supported_layouts' => array(
|
| 4176 |
+
1,
|
| 4177 |
+
),
|
| 4178 |
+
),
|
| 4179 |
'requires_extension' => array(
|
| 4180 |
'amp-user-notification',
|
| 4181 |
),
|
| 4203 |
'artwork' => array(),
|
| 4204 |
'attribution' => array(),
|
| 4205 |
'autoplay' => array(
|
| 4206 |
+
'value' => array(
|
| 4207 |
+
'',
|
| 4208 |
+
),
|
| 4209 |
),
|
| 4210 |
'controls' => array(
|
| 4211 |
+
'value' => array(
|
| 4212 |
+
'',
|
| 4213 |
+
),
|
| 4214 |
),
|
| 4215 |
'controlslist' => array(),
|
| 4216 |
'crossorigin' => array(),
|
| 4217 |
'disableremoteplayback' => array(
|
| 4218 |
+
'value' => array(
|
| 4219 |
+
'',
|
| 4220 |
+
),
|
| 4221 |
),
|
| 4222 |
+
'dock' => array(),
|
| 4223 |
'lightbox' => array(),
|
|
|
|
|
|
|
|
|
|
| 4224 |
'lightbox-thumbnail-id' => array(
|
| 4225 |
'value_regex_casei' => '^[a-z][a-z\\d_-]*',
|
| 4226 |
),
|
| 4227 |
'loop' => array(
|
| 4228 |
+
'value' => array(
|
| 4229 |
+
'',
|
| 4230 |
+
),
|
| 4231 |
),
|
| 4232 |
'media' => array(),
|
| 4233 |
'muted' => array(
|
| 4234 |
+
'value' => array(
|
| 4235 |
+
'',
|
| 4236 |
+
),
|
| 4237 |
+
),
|
| 4238 |
+
'noaudio' => array(
|
| 4239 |
+
'value' => array(
|
| 4240 |
+
'',
|
| 4241 |
+
),
|
| 4242 |
),
|
| 4243 |
'noloading' => array(
|
| 4244 |
+
'value' => array(
|
| 4245 |
+
'',
|
| 4246 |
+
),
|
| 4247 |
),
|
| 4248 |
'placeholder' => array(),
|
| 4249 |
'poster' => array(),
|
| 4250 |
'preload' => array(
|
| 4251 |
+
'value' => array(
|
| 4252 |
+
'auto',
|
| 4253 |
+
'metadata',
|
| 4254 |
+
'none',
|
| 4255 |
+
'',
|
| 4256 |
+
),
|
| 4257 |
+
),
|
| 4258 |
+
'rotate-to-fullscreen' => array(
|
| 4259 |
+
'value' => array(
|
| 4260 |
+
'',
|
| 4261 |
+
),
|
| 4262 |
),
|
| 4263 |
'src' => array(
|
| 4264 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4265 |
'value_url' => array(
|
| 4266 |
'allow_relative' => true,
|
| 4267 |
+
'protocol' => array(
|
| 4268 |
'https',
|
| 4269 |
),
|
| 4270 |
),
|
| 4274 |
'also_requires_tag_warning' => array(
|
| 4275 |
'amp-video extension .js script',
|
| 4276 |
),
|
| 4277 |
+
'amp_layout' => array(
|
| 4278 |
+
'supported_layouts' => array(
|
| 4279 |
+
6,
|
| 4280 |
+
2,
|
| 4281 |
+
3,
|
| 4282 |
+
7,
|
| 4283 |
+
1,
|
| 4284 |
+
4,
|
| 4285 |
+
),
|
| 4286 |
+
),
|
| 4287 |
'disallowed_ancestor' => array(
|
| 4288 |
'amp-story',
|
| 4289 |
),
|
| 4310 |
'artwork' => array(),
|
| 4311 |
'attribution' => array(),
|
| 4312 |
'autoplay' => array(
|
| 4313 |
+
'value' => array(
|
| 4314 |
+
'',
|
| 4315 |
+
),
|
| 4316 |
),
|
| 4317 |
'controls' => array(
|
| 4318 |
+
'value' => array(
|
| 4319 |
+
'',
|
| 4320 |
+
),
|
| 4321 |
),
|
| 4322 |
'controlslist' => array(),
|
| 4323 |
'crossorigin' => array(),
|
| 4324 |
'disableremoteplayback' => array(
|
| 4325 |
+
'value' => array(
|
| 4326 |
+
'',
|
| 4327 |
+
),
|
| 4328 |
),
|
| 4329 |
+
'dock' => array(),
|
| 4330 |
'loop' => array(
|
| 4331 |
+
'value' => array(
|
| 4332 |
+
'',
|
| 4333 |
+
),
|
| 4334 |
),
|
| 4335 |
'media' => array(),
|
| 4336 |
'muted' => array(
|
| 4337 |
+
'value' => array(
|
| 4338 |
+
'',
|
| 4339 |
+
),
|
| 4340 |
+
),
|
| 4341 |
+
'noaudio' => array(
|
| 4342 |
+
'value' => array(
|
| 4343 |
+
'',
|
| 4344 |
+
),
|
| 4345 |
),
|
| 4346 |
'noloading' => array(
|
| 4347 |
+
'value' => array(
|
| 4348 |
+
'',
|
| 4349 |
+
),
|
| 4350 |
),
|
| 4351 |
'placeholder' => array(),
|
| 4352 |
'poster' => array(
|
| 4353 |
'mandatory' => true,
|
| 4354 |
),
|
| 4355 |
'preload' => array(
|
| 4356 |
+
'value' => array(
|
| 4357 |
+
'auto',
|
| 4358 |
+
'metadata',
|
| 4359 |
+
'none',
|
| 4360 |
+
'',
|
| 4361 |
+
),
|
| 4362 |
+
),
|
| 4363 |
+
'rotate-to-fullscreen' => array(
|
| 4364 |
+
'value' => array(
|
| 4365 |
+
'',
|
| 4366 |
+
),
|
| 4367 |
),
|
| 4368 |
'src' => array(
|
| 4369 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4370 |
'value_url' => array(
|
| 4371 |
'allow_relative' => true,
|
| 4372 |
+
'protocol' => array(
|
| 4373 |
'https',
|
| 4374 |
),
|
| 4375 |
),
|
| 4376 |
),
|
| 4377 |
),
|
| 4378 |
'tag_spec' => array(
|
| 4379 |
+
'amp_layout' => array(
|
| 4380 |
+
'supported_layouts' => array(
|
| 4381 |
+
6,
|
| 4382 |
+
2,
|
| 4383 |
+
3,
|
| 4384 |
+
7,
|
| 4385 |
+
1,
|
| 4386 |
+
4,
|
| 4387 |
+
),
|
| 4388 |
+
),
|
| 4389 |
'mandatory_ancestor' => 'amp-story',
|
| 4390 |
'requires_extension' => array(
|
| 4391 |
'amp-video',
|
| 4398 |
'amp-vimeo' => array(
|
| 4399 |
array(
|
| 4400 |
'attr_spec_list' => array(
|
| 4401 |
+
'autoplay' => array(
|
| 4402 |
+
'value' => array(
|
| 4403 |
+
'',
|
| 4404 |
+
),
|
| 4405 |
+
),
|
| 4406 |
'data-videoid' => array(
|
| 4407 |
'mandatory' => true,
|
| 4408 |
'value_regex' => '[0-9]+',
|
| 4409 |
),
|
| 4410 |
'media' => array(),
|
| 4411 |
'noloading' => array(
|
| 4412 |
+
'value' => array(
|
| 4413 |
+
'',
|
| 4414 |
+
),
|
| 4415 |
),
|
| 4416 |
),
|
| 4417 |
'tag_spec' => array(
|
| 4418 |
+
'amp_layout' => array(
|
| 4419 |
+
'supported_layouts' => array(
|
| 4420 |
+
6,
|
| 4421 |
+
2,
|
| 4422 |
+
3,
|
| 4423 |
+
7,
|
| 4424 |
+
4,
|
| 4425 |
+
),
|
| 4426 |
+
),
|
| 4427 |
'requires_extension' => array(
|
| 4428 |
'amp-vimeo',
|
| 4429 |
),
|
| 4438 |
),
|
| 4439 |
'media' => array(),
|
| 4440 |
'noloading' => array(
|
| 4441 |
+
'value' => array(
|
| 4442 |
+
'',
|
| 4443 |
+
),
|
| 4444 |
),
|
| 4445 |
),
|
| 4446 |
'tag_spec' => array(
|
| 4447 |
+
'amp_layout' => array(
|
| 4448 |
+
'supported_layouts' => array(
|
| 4449 |
+
6,
|
| 4450 |
+
2,
|
| 4451 |
+
3,
|
| 4452 |
+
7,
|
| 4453 |
+
1,
|
| 4454 |
+
4,
|
| 4455 |
+
),
|
| 4456 |
+
),
|
| 4457 |
'requires_extension' => array(
|
| 4458 |
'amp-vine',
|
| 4459 |
),
|
| 4460 |
),
|
| 4461 |
),
|
| 4462 |
),
|
| 4463 |
+
'amp-viqeo-player' => array(
|
| 4464 |
+
array(
|
| 4465 |
+
'attr_spec_list' => array(
|
| 4466 |
+
'autoplay' => array(),
|
| 4467 |
+
'data-profileid' => array(
|
| 4468 |
+
'mandatory' => true,
|
| 4469 |
+
'value_regex' => '[0-9a-f]*',
|
| 4470 |
+
),
|
| 4471 |
+
'data-videoid' => array(
|
| 4472 |
+
'mandatory' => true,
|
| 4473 |
+
),
|
| 4474 |
+
'media' => array(),
|
| 4475 |
+
'noloading' => array(
|
| 4476 |
+
'value' => array(
|
| 4477 |
+
'',
|
| 4478 |
+
),
|
| 4479 |
+
),
|
| 4480 |
+
),
|
| 4481 |
+
'tag_spec' => array(
|
| 4482 |
+
'amp_layout' => array(
|
| 4483 |
+
'supported_layouts' => array(
|
| 4484 |
+
6,
|
| 4485 |
+
2,
|
| 4486 |
+
3,
|
| 4487 |
+
7,
|
| 4488 |
+
4,
|
| 4489 |
+
),
|
| 4490 |
+
),
|
| 4491 |
+
'requires_extension' => array(
|
| 4492 |
+
'amp-viqeo-player',
|
| 4493 |
+
),
|
| 4494 |
+
),
|
| 4495 |
+
),
|
| 4496 |
+
),
|
| 4497 |
'amp-vk' => array(
|
| 4498 |
array(
|
| 4499 |
'attr_spec_list' => array(
|
| 4502 |
),
|
| 4503 |
'media' => array(),
|
| 4504 |
'noloading' => array(
|
| 4505 |
+
'value' => array(
|
| 4506 |
+
'',
|
| 4507 |
+
),
|
| 4508 |
),
|
| 4509 |
),
|
| 4510 |
'tag_spec' => array(
|
| 4511 |
+
'amp_layout' => array(
|
| 4512 |
+
'supported_layouts' => array(
|
| 4513 |
+
2,
|
| 4514 |
+
7,
|
| 4515 |
+
4,
|
| 4516 |
+
),
|
| 4517 |
+
),
|
| 4518 |
'requires_extension' => array(
|
| 4519 |
'amp-vk',
|
| 4520 |
),
|
| 4528 |
'mandatory' => true,
|
| 4529 |
'value_url' => array(
|
| 4530 |
'allow_relative' => false,
|
| 4531 |
+
'protocol' => array(
|
| 4532 |
'https',
|
| 4533 |
),
|
| 4534 |
),
|
| 4535 |
),
|
| 4536 |
'id' => array(
|
| 4537 |
'mandatory' => true,
|
| 4538 |
+
'value' => array(
|
| 4539 |
+
'amp-web-push',
|
| 4540 |
+
),
|
| 4541 |
),
|
| 4542 |
'media' => array(),
|
| 4543 |
'noloading' => array(
|
| 4544 |
+
'value' => array(
|
| 4545 |
+
'',
|
| 4546 |
+
),
|
| 4547 |
),
|
| 4548 |
'permission-dialog-url' => array(
|
| 4549 |
'mandatory' => true,
|
| 4550 |
'value_url' => array(
|
| 4551 |
'allow_relative' => false,
|
| 4552 |
+
'protocol' => array(
|
| 4553 |
'https',
|
| 4554 |
),
|
| 4555 |
),
|
| 4558 |
'mandatory' => true,
|
| 4559 |
'value_url' => array(
|
| 4560 |
'allow_relative' => false,
|
| 4561 |
+
'protocol' => array(
|
| 4562 |
'https',
|
| 4563 |
),
|
| 4564 |
),
|
| 4565 |
),
|
| 4566 |
),
|
| 4567 |
'tag_spec' => array(
|
| 4568 |
+
'amp_layout' => array(
|
| 4569 |
+
'supported_layouts' => array(
|
| 4570 |
+
1,
|
| 4571 |
+
),
|
| 4572 |
+
),
|
| 4573 |
'requires_extension' => array(
|
| 4574 |
'amp-web-push',
|
| 4575 |
),
|
| 4582 |
'attr_spec_list' => array(
|
| 4583 |
'media' => array(),
|
| 4584 |
'noloading' => array(
|
| 4585 |
+
'value' => array(
|
| 4586 |
+
'',
|
| 4587 |
+
),
|
| 4588 |
),
|
| 4589 |
'visibility' => array(
|
| 4590 |
'mandatory' => true,
|
| 4591 |
+
'value' => array(
|
| 4592 |
+
'blocked',
|
| 4593 |
+
'subscribed',
|
| 4594 |
+
'unsubscribed',
|
| 4595 |
+
),
|
| 4596 |
),
|
| 4597 |
),
|
| 4598 |
'tag_spec' => array(
|
| 4599 |
+
'amp_layout' => array(
|
| 4600 |
+
'supported_layouts' => array(
|
| 4601 |
+
2,
|
| 4602 |
+
),
|
| 4603 |
+
),
|
| 4604 |
'requires_extension' => array(
|
| 4605 |
'amp-web-push',
|
| 4606 |
),
|
| 4617 |
),
|
| 4618 |
'media' => array(),
|
| 4619 |
'noloading' => array(
|
| 4620 |
+
'value' => array(
|
| 4621 |
+
'',
|
| 4622 |
+
),
|
| 4623 |
+
),
|
| 4624 |
+
'rotate-to-fullscreen' => array(
|
| 4625 |
+
'value' => array(
|
| 4626 |
+
'',
|
| 4627 |
+
),
|
| 4628 |
),
|
| 4629 |
),
|
| 4630 |
'tag_spec' => array(
|
| 4631 |
+
'amp_layout' => array(
|
| 4632 |
+
'supported_layouts' => array(
|
| 4633 |
+
6,
|
| 4634 |
+
2,
|
| 4635 |
+
3,
|
| 4636 |
+
7,
|
| 4637 |
+
4,
|
| 4638 |
+
),
|
| 4639 |
+
),
|
| 4640 |
'requires_extension' => array(
|
| 4641 |
'amp-wistia-player',
|
| 4642 |
),
|
| 4643 |
),
|
| 4644 |
),
|
| 4645 |
),
|
| 4646 |
+
'amp-yotpo' => array(
|
| 4647 |
+
array(
|
| 4648 |
+
'attr_spec_list' => array(
|
| 4649 |
+
'data-app-key' => array(
|
| 4650 |
+
'mandatory' => true,
|
| 4651 |
+
),
|
| 4652 |
+
'data-widget-type' => array(
|
| 4653 |
+
'mandatory' => true,
|
| 4654 |
+
),
|
| 4655 |
+
'media' => array(),
|
| 4656 |
+
'noloading' => array(
|
| 4657 |
+
'value' => array(
|
| 4658 |
+
'',
|
| 4659 |
+
),
|
| 4660 |
+
),
|
| 4661 |
+
),
|
| 4662 |
+
'tag_spec' => array(
|
| 4663 |
+
'amp_layout' => array(
|
| 4664 |
+
'supported_layouts' => array(
|
| 4665 |
+
6,
|
| 4666 |
+
2,
|
| 4667 |
+
3,
|
| 4668 |
+
7,
|
| 4669 |
+
1,
|
| 4670 |
+
4,
|
| 4671 |
+
),
|
| 4672 |
+
),
|
| 4673 |
+
'requires_extension' => array(
|
| 4674 |
+
'amp-yotpo',
|
| 4675 |
+
),
|
| 4676 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-yotpo',
|
| 4677 |
+
),
|
| 4678 |
+
),
|
| 4679 |
+
),
|
| 4680 |
'amp-youtube' => array(
|
| 4681 |
array(
|
| 4682 |
'attr_spec_list' => array(
|
| 4683 |
'[data-videoid]' => array(),
|
| 4684 |
'autoplay' => array(),
|
| 4685 |
'credentials' => array(
|
| 4686 |
+
'value_casei' => array(
|
| 4687 |
+
'include',
|
| 4688 |
+
'omit',
|
| 4689 |
+
),
|
| 4690 |
),
|
| 4691 |
'data-live-channelid' => array(
|
| 4692 |
'value_regex' => '[^=/?:]+',
|
| 4695 |
'value_regex' => '[^=/?:]+',
|
| 4696 |
),
|
| 4697 |
'lightbox' => array(),
|
|
|
|
|
|
|
|
|
|
| 4698 |
'lightbox-thumbnail-id' => array(
|
| 4699 |
'value_regex_casei' => '^[a-z][a-z\\d_-]*',
|
| 4700 |
),
|
| 4701 |
'media' => array(),
|
| 4702 |
'noloading' => array(
|
| 4703 |
+
'value' => array(
|
| 4704 |
+
'',
|
| 4705 |
+
),
|
| 4706 |
),
|
| 4707 |
),
|
| 4708 |
'tag_spec' => array(
|
| 4709 |
+
'amp_layout' => array(
|
| 4710 |
+
'supported_layouts' => array(
|
| 4711 |
+
6,
|
| 4712 |
+
2,
|
| 4713 |
+
3,
|
| 4714 |
+
7,
|
| 4715 |
+
1,
|
| 4716 |
+
4,
|
| 4717 |
+
),
|
| 4718 |
+
),
|
| 4719 |
'requires_extension' => array(
|
| 4720 |
'amp-youtube',
|
| 4721 |
),
|
| 4746 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4747 |
'value_url' => array(
|
| 4748 |
'allow_relative' => false,
|
| 4749 |
+
'protocol' => array(
|
| 4750 |
'data',
|
| 4751 |
'https',
|
| 4752 |
),
|
| 4770 |
array(
|
| 4771 |
'attr_spec_list' => array(
|
| 4772 |
'href' => array(
|
| 4773 |
+
'value' => array(
|
| 4774 |
+
'/',
|
| 4775 |
+
),
|
| 4776 |
),
|
| 4777 |
'target' => array(
|
| 4778 |
+
'value_casei' => array(
|
| 4779 |
+
'_blank',
|
| 4780 |
+
'_self',
|
| 4781 |
+
'_top',
|
| 4782 |
+
),
|
| 4783 |
),
|
| 4784 |
),
|
| 4785 |
'tag_spec' => array(
|
| 4816 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 4817 |
'value_url' => array(
|
| 4818 |
'allow_empty' => true,
|
| 4819 |
+
'protocol' => array(
|
|
|
|
| 4820 |
'http',
|
| 4821 |
'https',
|
| 4822 |
),
|
| 4850 |
'[type]' => array(),
|
| 4851 |
'[value]' => array(),
|
| 4852 |
'disabled' => array(
|
| 4853 |
+
'value' => array(
|
| 4854 |
+
'',
|
| 4855 |
+
),
|
| 4856 |
),
|
| 4857 |
'name' => array(
|
| 4858 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 4870 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 4871 |
),
|
| 4872 |
'open-button' => array(
|
| 4873 |
+
'value' => array(
|
| 4874 |
+
'',
|
| 4875 |
+
),
|
| 4876 |
),
|
| 4877 |
'role' => array(),
|
| 4878 |
'tabindex' => array(),
|
| 4924 |
'filter' => array(),
|
| 4925 |
'flood-color' => array(),
|
| 4926 |
'flood-opacity' => array(),
|
| 4927 |
+
'focusable' => array(),
|
| 4928 |
'font-family' => array(),
|
| 4929 |
'font-size' => array(),
|
| 4930 |
'font-size-adjust' => array(),
|
| 5016 |
'filter' => array(),
|
| 5017 |
'flood-color' => array(),
|
| 5018 |
'flood-opacity' => array(),
|
| 5019 |
+
'focusable' => array(),
|
| 5020 |
'font-family' => array(),
|
| 5021 |
'font-size' => array(),
|
| 5022 |
'font-size-adjust' => array(),
|
| 5141 |
'filter' => array(),
|
| 5142 |
'flood-color' => array(),
|
| 5143 |
'flood-opacity' => array(),
|
| 5144 |
+
'focusable' => array(),
|
| 5145 |
'font-family' => array(),
|
| 5146 |
'font-size' => array(),
|
| 5147 |
'font-size-adjust' => array(),
|
| 5206 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 5207 |
'value_url' => array(
|
| 5208 |
'allow_empty' => true,
|
| 5209 |
+
'protocol' => array(
|
|
|
|
| 5210 |
'http',
|
| 5211 |
'https',
|
| 5212 |
),
|
| 5253 |
),
|
| 5254 |
'tag_spec' => array(),
|
| 5255 |
),
|
| 5256 |
+
array(
|
| 5257 |
+
'attr_spec_list' => array(
|
| 5258 |
+
'align' => array(),
|
| 5259 |
+
'verify-error' => array(
|
| 5260 |
+
'mandatory' => true,
|
| 5261 |
+
),
|
| 5262 |
+
),
|
| 5263 |
+
'tag_spec' => array(
|
| 5264 |
+
'mandatory_ancestor' => 'form',
|
| 5265 |
+
'spec_name' => 'FORM DIV [verify-error]',
|
| 5266 |
+
),
|
| 5267 |
+
),
|
| 5268 |
+
array(
|
| 5269 |
+
'attr_spec_list' => array(
|
| 5270 |
+
'align' => array(),
|
| 5271 |
+
'template' => array(
|
| 5272 |
+
'mandatory' => true,
|
| 5273 |
+
),
|
| 5274 |
+
'verify-error' => array(
|
| 5275 |
+
'mandatory' => true,
|
| 5276 |
+
),
|
| 5277 |
+
),
|
| 5278 |
+
'tag_spec' => array(
|
| 5279 |
+
'mandatory_ancestor' => 'form',
|
| 5280 |
+
'spec_name' => 'FORM DIV [verify-error][template]',
|
| 5281 |
+
),
|
| 5282 |
+
),
|
| 5283 |
array(
|
| 5284 |
'attr_spec_list' => array(
|
| 5285 |
'align' => array(),
|
| 5286 |
'submitting' => array(
|
|
|
|
| 5287 |
'mandatory' => true,
|
| 5288 |
),
|
| 5289 |
),
|
| 5290 |
'tag_spec' => array(
|
| 5291 |
+
'mandatory_ancestor' => 'form',
|
| 5292 |
+
'spec_name' => 'FORM DIV [submitting]',
|
| 5293 |
+
),
|
| 5294 |
+
),
|
| 5295 |
+
array(
|
| 5296 |
+
'attr_spec_list' => array(
|
| 5297 |
+
'align' => array(),
|
| 5298 |
+
'submitting' => array(
|
| 5299 |
+
'mandatory' => true,
|
| 5300 |
+
),
|
| 5301 |
+
'template' => array(
|
| 5302 |
+
'mandatory' => true,
|
| 5303 |
+
),
|
| 5304 |
+
),
|
| 5305 |
+
'tag_spec' => array(
|
| 5306 |
+
'mandatory_ancestor' => 'form',
|
| 5307 |
+
'spec_name' => 'FORM DIV [submitting][template]',
|
| 5308 |
),
|
| 5309 |
),
|
| 5310 |
array(
|
| 5315 |
),
|
| 5316 |
),
|
| 5317 |
'tag_spec' => array(
|
| 5318 |
+
'mandatory_ancestor' => 'form',
|
| 5319 |
+
'spec_name' => 'FORM DIV [submit-success]',
|
| 5320 |
),
|
| 5321 |
),
|
| 5322 |
array(
|
| 5330 |
),
|
| 5331 |
),
|
| 5332 |
'tag_spec' => array(
|
| 5333 |
+
'mandatory_ancestor' => 'form',
|
| 5334 |
+
'spec_name' => 'FORM DIV [submit-success][template]',
|
| 5335 |
),
|
| 5336 |
),
|
| 5337 |
array(
|
| 5342 |
),
|
| 5343 |
),
|
| 5344 |
'tag_spec' => array(
|
| 5345 |
+
'mandatory_ancestor' => 'form',
|
| 5346 |
+
'spec_name' => 'FORM DIV [submit-error]',
|
| 5347 |
),
|
| 5348 |
),
|
| 5349 |
array(
|
| 5357 |
),
|
| 5358 |
),
|
| 5359 |
'tag_spec' => array(
|
| 5360 |
+
'mandatory_ancestor' => 'form',
|
| 5361 |
+
'spec_name' => 'FORM DIV [submit-error][template]',
|
| 5362 |
),
|
| 5363 |
),
|
| 5364 |
+
array(
|
| 5365 |
+
'attr_spec_list' => array(
|
| 5366 |
+
'first' => array(
|
| 5367 |
+
'mandatory' => true,
|
| 5368 |
+
),
|
| 5369 |
+
),
|
| 5370 |
+
'tag_spec' => array(
|
| 5371 |
+
'mandatory_parent' => 'amp-image-slider',
|
| 5372 |
+
'spec_name' => 'AMP-IMAGE-SLIDER > DIV [first]',
|
| 5373 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-image-slider',
|
| 5374 |
+
),
|
| 5375 |
+
),
|
| 5376 |
+
array(
|
| 5377 |
+
'attr_spec_list' => array(
|
| 5378 |
+
'second' => array(
|
| 5379 |
+
'mandatory' => true,
|
| 5380 |
+
),
|
| 5381 |
+
),
|
| 5382 |
+
'tag_spec' => array(
|
| 5383 |
+
'mandatory_parent' => 'amp-image-slider',
|
| 5384 |
+
'spec_name' => 'AMP-IMAGE-SLIDER > DIV [second]',
|
| 5385 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-image-slider',
|
| 5386 |
+
),
|
| 5387 |
+
),
|
| 5388 |
+
),
|
| 5389 |
+
'dl' => array(
|
| 5390 |
array(
|
| 5391 |
'attr_spec_list' => array(),
|
| 5392 |
'tag_spec' => array(),
|
| 5425 |
'filter' => array(),
|
| 5426 |
'flood-color' => array(),
|
| 5427 |
'flood-opacity' => array(),
|
| 5428 |
+
'focusable' => array(),
|
| 5429 |
'font-family' => array(),
|
| 5430 |
'font-size' => array(),
|
| 5431 |
'font-size-adjust' => array(),
|
| 5516 |
'filter' => array(),
|
| 5517 |
'flood-color' => array(),
|
| 5518 |
'flood-opacity' => array(),
|
| 5519 |
+
'focusable' => array(),
|
| 5520 |
'font-family' => array(),
|
| 5521 |
'font-size' => array(),
|
| 5522 |
'font-size-adjust' => array(),
|
| 5602 |
'filter' => array(),
|
| 5603 |
'flood-color' => array(),
|
| 5604 |
'flood-opacity' => array(),
|
| 5605 |
+
'focusable' => array(),
|
| 5606 |
'font-family' => array(),
|
| 5607 |
'font-size' => array(),
|
| 5608 |
'font-size-adjust' => array(),
|
| 5692 |
'filter' => array(),
|
| 5693 |
'flood-color' => array(),
|
| 5694 |
'flood-opacity' => array(),
|
| 5695 |
+
'focusable' => array(),
|
| 5696 |
'font-family' => array(),
|
| 5697 |
'font-size' => array(),
|
| 5698 |
'font-size-adjust' => array(),
|
| 5776 |
'filter' => array(),
|
| 5777 |
'flood-color' => array(),
|
| 5778 |
'flood-opacity' => array(),
|
| 5779 |
+
'focusable' => array(),
|
| 5780 |
'font-family' => array(),
|
| 5781 |
'font-size' => array(),
|
| 5782 |
'font-size-adjust' => array(),
|
| 5861 |
'filter' => array(),
|
| 5862 |
'flood-color' => array(),
|
| 5863 |
'flood-opacity' => array(),
|
| 5864 |
+
'focusable' => array(),
|
| 5865 |
'font-family' => array(),
|
| 5866 |
'font-size' => array(),
|
| 5867 |
'font-size-adjust' => array(),
|
| 5964 |
'filter' => array(),
|
| 5965 |
'flood-color' => array(),
|
| 5966 |
'flood-opacity' => array(),
|
| 5967 |
+
'focusable' => array(),
|
| 5968 |
'font-family' => array(),
|
| 5969 |
'font-size' => array(),
|
| 5970 |
'font-size-adjust' => array(),
|
| 6075 |
'filterunits' => array(),
|
| 6076 |
'flood-color' => array(),
|
| 6077 |
'flood-opacity' => array(),
|
| 6078 |
+
'focusable' => array(),
|
| 6079 |
'font-family' => array(),
|
| 6080 |
'font-size' => array(),
|
| 6081 |
'font-size-adjust' => array(),
|
| 6130 |
),
|
| 6131 |
'value_url' => array(
|
| 6132 |
'allow_empty' => false,
|
| 6133 |
+
'protocol' => array(
|
|
|
|
| 6134 |
'http',
|
| 6135 |
'https',
|
| 6136 |
),
|
| 6158 |
'tag_spec' => array(),
|
| 6159 |
),
|
| 6160 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6161 |
'form' => array(
|
| 6162 |
array(
|
| 6163 |
'attr_spec_list' => array(
|
| 6167 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6168 |
'mandatory' => true,
|
| 6169 |
'value_url' => array(
|
| 6170 |
+
'protocol' => array(
|
|
|
|
| 6171 |
'https',
|
| 6172 |
),
|
| 6173 |
),
|
| 6175 |
'action-xhr' => array(
|
| 6176 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6177 |
'value_url' => array(
|
| 6178 |
+
'protocol' => array(
|
|
|
|
| 6179 |
'https',
|
| 6180 |
),
|
| 6181 |
),
|
| 6182 |
),
|
| 6183 |
'autocomplete' => array(),
|
| 6184 |
'custom-validation-reporting' => array(
|
| 6185 |
+
'value' => array(
|
| 6186 |
+
'as-you-go',
|
| 6187 |
+
'interact-and-submit',
|
| 6188 |
+
'show-all-on-submit',
|
| 6189 |
+
'show-first-on-submit',
|
| 6190 |
+
),
|
| 6191 |
),
|
| 6192 |
'enctype' => array(),
|
| 6193 |
'method' => array(
|
| 6194 |
+
'value_casei' => array(
|
| 6195 |
+
'get',
|
| 6196 |
+
),
|
| 6197 |
),
|
| 6198 |
'name' => array(),
|
| 6199 |
'novalidate' => array(),
|
| 6200 |
'target' => array(
|
| 6201 |
'mandatory' => true,
|
| 6202 |
+
'value_casei' => array(
|
| 6203 |
+
'_blank',
|
| 6204 |
+
'_top',
|
| 6205 |
+
),
|
| 6206 |
),
|
| 6207 |
'verify-xhr' => array(
|
| 6208 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6209 |
'value_url' => array(
|
| 6210 |
+
'protocol' => array(
|
|
|
|
| 6211 |
'https',
|
| 6212 |
),
|
| 6213 |
),
|
| 6231 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6232 |
'mandatory' => true,
|
| 6233 |
'value_url' => array(
|
| 6234 |
+
'protocol' => array(
|
|
|
|
| 6235 |
'https',
|
| 6236 |
),
|
| 6237 |
),
|
| 6238 |
),
|
| 6239 |
'autocomplete' => array(),
|
| 6240 |
'custom-validation-reporting' => array(
|
| 6241 |
+
'value' => array(
|
| 6242 |
+
'as-you-go',
|
| 6243 |
+
'interact-and-submit',
|
| 6244 |
+
'show-all-on-submit',
|
| 6245 |
+
'show-first-on-submit',
|
| 6246 |
+
),
|
| 6247 |
),
|
| 6248 |
'enctype' => array(),
|
| 6249 |
'method' => array(
|
| 6250 |
'dispatch_key' => 2,
|
| 6251 |
'mandatory' => true,
|
| 6252 |
+
'value_casei' => array(
|
| 6253 |
+
'post',
|
| 6254 |
+
),
|
| 6255 |
),
|
| 6256 |
'name' => array(),
|
| 6257 |
'novalidate' => array(),
|
| 6258 |
'target' => array(
|
| 6259 |
+
'value_casei' => array(
|
| 6260 |
+
'_blank',
|
| 6261 |
+
'_top',
|
| 6262 |
+
),
|
| 6263 |
),
|
| 6264 |
'verify-xhr' => array(
|
| 6265 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6266 |
'value_url' => array(
|
| 6267 |
+
'protocol' => array(
|
|
|
|
| 6268 |
'https',
|
| 6269 |
),
|
| 6270 |
),
|
| 6306 |
'filter' => array(),
|
| 6307 |
'flood-color' => array(),
|
| 6308 |
'flood-opacity' => array(),
|
| 6309 |
+
'focusable' => array(),
|
| 6310 |
'font-family' => array(),
|
| 6311 |
'font-size' => array(),
|
| 6312 |
'font-size-adjust' => array(),
|
| 6390 |
'filter' => array(),
|
| 6391 |
'flood-color' => array(),
|
| 6392 |
'flood-opacity' => array(),
|
| 6393 |
+
'focusable' => array(),
|
| 6394 |
'font-family' => array(),
|
| 6395 |
'font-size' => array(),
|
| 6396 |
'font-size-adjust' => array(),
|
| 6477 |
'filter' => array(),
|
| 6478 |
'flood-color' => array(),
|
| 6479 |
'flood-opacity' => array(),
|
| 6480 |
+
'focusable' => array(),
|
| 6481 |
'font-family' => array(),
|
| 6482 |
'font-size' => array(),
|
| 6483 |
'font-size-adjust' => array(),
|
| 6531 |
),
|
| 6532 |
'value_url' => array(
|
| 6533 |
'allow_empty' => false,
|
| 6534 |
+
'protocol' => array(
|
|
|
|
| 6535 |
'http',
|
| 6536 |
'https',
|
| 6537 |
),
|
| 6654 |
),
|
| 6655 |
'html' => array(
|
| 6656 |
array(
|
| 6657 |
+
'attr_spec_list' => array(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6658 |
'tag_spec' => array(
|
| 6659 |
'mandatory' => true,
|
| 6660 |
'mandatory_parent' => '!doctype',
|
|
|
|
| 6661 |
'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
|
| 6662 |
'unique' => true,
|
| 6663 |
),
|
| 6673 |
array(
|
| 6674 |
'attr_spec_list' => array(
|
| 6675 |
'frameborder' => array(
|
| 6676 |
+
'value' => array(
|
| 6677 |
+
'0',
|
| 6678 |
+
'1',
|
| 6679 |
+
),
|
| 6680 |
),
|
| 6681 |
'height' => array(),
|
| 6682 |
'name' => array(),
|
| 6683 |
'referrerpolicy' => array(),
|
| 6684 |
'resizable' => array(
|
| 6685 |
+
'value' => array(
|
| 6686 |
+
'',
|
| 6687 |
+
),
|
| 6688 |
),
|
| 6689 |
'sandbox' => array(),
|
| 6690 |
'scrolling' => array(
|
| 6691 |
+
'value' => array(
|
| 6692 |
+
'auto',
|
| 6693 |
+
'yes',
|
| 6694 |
+
'no',
|
| 6695 |
+
),
|
| 6696 |
),
|
| 6697 |
'src' => array(
|
| 6698 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6699 |
'value_url' => array(
|
| 6700 |
'allow_relative' => false,
|
| 6701 |
+
'protocol' => array(
|
| 6702 |
'data',
|
| 6703 |
'https',
|
| 6704 |
),
|
| 6739 |
'filter' => array(),
|
| 6740 |
'flood-color' => array(),
|
| 6741 |
'flood-opacity' => array(),
|
| 6742 |
+
'focusable' => array(),
|
| 6743 |
'font-family' => array(),
|
| 6744 |
'font-size' => array(),
|
| 6745 |
'font-size-adjust' => array(),
|
| 6799 |
'blacklisted_value_regex' => '(^|\\s)data:image\\/svg\\+xml',
|
| 6800 |
'value_url' => array(
|
| 6801 |
'allow_empty' => false,
|
| 6802 |
+
'protocol' => array(
|
|
|
|
| 6803 |
'data',
|
| 6804 |
'http',
|
| 6805 |
'https',
|
| 6826 |
array(
|
| 6827 |
'attr_spec_list' => array(
|
| 6828 |
'alt' => array(),
|
| 6829 |
+
'attribution' => array(),
|
| 6830 |
'border' => array(),
|
| 6831 |
+
'decoding' => array(
|
| 6832 |
+
'value' => array(
|
| 6833 |
+
'async',
|
| 6834 |
+
'auto',
|
| 6835 |
+
'sync',
|
| 6836 |
+
),
|
| 6837 |
+
),
|
| 6838 |
'height' => array(),
|
| 6839 |
'ismap' => array(),
|
| 6840 |
'longdesc' => array(
|
| 6841 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 6842 |
'value_url' => array(
|
| 6843 |
+
'protocol' => array(
|
|
|
|
| 6844 |
'http',
|
| 6845 |
'https',
|
| 6846 |
),
|
| 6847 |
),
|
| 6848 |
),
|
| 6849 |
+
'sizes' => array(),
|
| 6850 |
'src' => array(
|
| 6851 |
'alternative_names' => array(
|
| 6852 |
'srcset',
|
| 6855 |
'mandatory' => true,
|
| 6856 |
'value_url' => array(
|
| 6857 |
'allow_relative' => true,
|
| 6858 |
+
'protocol' => array(
|
| 6859 |
'data',
|
| 6860 |
'https',
|
| 6861 |
),
|
| 6913 |
'name' => array(
|
| 6914 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 6915 |
),
|
| 6916 |
+
'no-verify' => array(
|
| 6917 |
+
'value' => array(
|
| 6918 |
+
'',
|
| 6919 |
+
),
|
| 6920 |
+
),
|
| 6921 |
'pattern' => array(),
|
| 6922 |
'placeholder' => array(),
|
| 6923 |
'readonly' => array(),
|
| 6937 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
|
| 6938 |
),
|
| 6939 |
),
|
|
|
|
|
|
|
| 6940 |
array(
|
| 6941 |
'attr_spec_list' => array(
|
| 6942 |
+
'[accept]' => array(),
|
| 6943 |
+
'[accesskey]' => array(),
|
| 6944 |
+
'[autocomplete]' => array(),
|
| 6945 |
+
'[checked]' => array(),
|
| 6946 |
+
'[disabled]' => array(),
|
| 6947 |
+
'[height]' => array(),
|
| 6948 |
+
'[inputmode]' => array(),
|
| 6949 |
+
'[max]' => array(),
|
| 6950 |
+
'[maxlength]' => array(),
|
| 6951 |
+
'[min]' => array(),
|
| 6952 |
+
'[minlength]' => array(),
|
| 6953 |
+
'[multiple]' => array(),
|
| 6954 |
+
'[pattern]' => array(),
|
| 6955 |
+
'[placeholder]' => array(),
|
| 6956 |
+
'[readonly]' => array(),
|
| 6957 |
+
'[required]' => array(),
|
| 6958 |
+
'[selectiondirection]' => array(),
|
| 6959 |
+
'[size]' => array(),
|
| 6960 |
+
'[spellcheck]' => array(),
|
| 6961 |
+
'[step]' => array(),
|
| 6962 |
+
'[value]' => array(),
|
| 6963 |
+
'[width]' => array(),
|
| 6964 |
+
'accept' => array(),
|
| 6965 |
+
'accesskey' => array(),
|
| 6966 |
+
'autocomplete' => array(),
|
| 6967 |
+
'autofocus' => array(),
|
| 6968 |
+
'checked' => array(),
|
| 6969 |
+
'disabled' => array(),
|
| 6970 |
+
'height' => array(),
|
| 6971 |
+
'inputmode' => array(),
|
| 6972 |
+
'list' => array(),
|
| 6973 |
+
'max' => array(),
|
| 6974 |
+
'maxlength' => array(),
|
| 6975 |
+
'min' => array(),
|
| 6976 |
+
'minlength' => array(),
|
| 6977 |
+
'multiple' => array(),
|
| 6978 |
+
'name' => array(
|
| 6979 |
+
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 6980 |
+
),
|
| 6981 |
+
'no-verify' => array(
|
| 6982 |
+
'value' => array(
|
| 6983 |
+
'',
|
| 6984 |
),
|
| 6985 |
),
|
| 6986 |
+
'pattern' => array(),
|
| 6987 |
+
'placeholder' => array(),
|
| 6988 |
+
'readonly' => array(),
|
| 6989 |
+
'required' => array(),
|
| 6990 |
+
'selectiondirection' => array(),
|
| 6991 |
+
'size' => array(),
|
| 6992 |
+
'spellcheck' => array(),
|
| 6993 |
+
'step' => array(),
|
| 6994 |
+
'tabindex' => array(),
|
| 6995 |
+
'type' => array(
|
| 6996 |
+
'dispatch_key' => 2,
|
| 6997 |
+
'mandatory' => true,
|
| 6998 |
+
'value_casei' => array(
|
| 6999 |
+
'file',
|
| 7000 |
+
),
|
| 7001 |
+
),
|
| 7002 |
+
'value' => array(),
|
| 7003 |
+
'width' => array(),
|
| 7004 |
),
|
| 7005 |
'tag_spec' => array(
|
| 7006 |
+
'mandatory_ancestor' => 'form [method=post]',
|
| 7007 |
+
'spec_name' => 'INPUT [type=file]',
|
| 7008 |
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
|
| 7009 |
),
|
| 7010 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7011 |
array(
|
| 7012 |
'attr_spec_list' => array(
|
| 7013 |
+
'[accept]' => array(),
|
| 7014 |
+
'[accesskey]' => array(),
|
| 7015 |
+
'[autocomplete]' => array(),
|
| 7016 |
+
'[checked]' => array(),
|
| 7017 |
+
'[disabled]' => array(),
|
| 7018 |
+
'[height]' => array(),
|
| 7019 |
+
'[inputmode]' => array(),
|
| 7020 |
+
'[max]' => array(),
|
| 7021 |
+
'[maxlength]' => array(),
|
| 7022 |
+
'[min]' => array(),
|
| 7023 |
+
'[minlength]' => array(),
|
| 7024 |
+
'[multiple]' => array(),
|
| 7025 |
+
'[pattern]' => array(),
|
| 7026 |
+
'[placeholder]' => array(),
|
| 7027 |
+
'[readonly]' => array(),
|
| 7028 |
+
'[required]' => array(),
|
| 7029 |
+
'[selectiondirection]' => array(),
|
| 7030 |
+
'[size]' => array(),
|
| 7031 |
+
'[spellcheck]' => array(),
|
| 7032 |
+
'[step]' => array(),
|
| 7033 |
+
'[value]' => array(),
|
| 7034 |
+
'[width]' => array(),
|
| 7035 |
+
'accept' => array(),
|
| 7036 |
+
'accesskey' => array(),
|
| 7037 |
+
'autocomplete' => array(),
|
| 7038 |
+
'autofocus' => array(),
|
| 7039 |
+
'checked' => array(),
|
| 7040 |
+
'disabled' => array(),
|
| 7041 |
+
'height' => array(),
|
| 7042 |
+
'inputmode' => array(),
|
| 7043 |
+
'list' => array(),
|
| 7044 |
+
'max' => array(),
|
| 7045 |
+
'maxlength' => array(),
|
| 7046 |
+
'min' => array(),
|
| 7047 |
+
'minlength' => array(),
|
| 7048 |
+
'multiple' => array(),
|
| 7049 |
+
'name' => array(
|
| 7050 |
+
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 7051 |
+
),
|
| 7052 |
+
'pattern' => array(),
|
| 7053 |
+
'placeholder' => array(),
|
| 7054 |
+
'readonly' => array(),
|
| 7055 |
+
'required' => array(),
|
| 7056 |
+
'selectiondirection' => array(),
|
| 7057 |
+
'size' => array(),
|
| 7058 |
+
'spellcheck' => array(),
|
| 7059 |
+
'step' => array(),
|
| 7060 |
+
'tabindex' => array(),
|
| 7061 |
+
'type' => array(
|
| 7062 |
+
'dispatch_key' => 2,
|
| 7063 |
+
'mandatory' => true,
|
| 7064 |
+
'value_casei' => array(
|
| 7065 |
+
'password',
|
| 7066 |
+
),
|
| 7067 |
+
),
|
| 7068 |
+
'value' => array(),
|
| 7069 |
+
'width' => array(),
|
| 7070 |
+
),
|
| 7071 |
+
'tag_spec' => array(
|
| 7072 |
+
'mandatory_ancestor' => 'form [method=post]',
|
| 7073 |
+
'spec_name' => 'INPUT [type=password]',
|
| 7074 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
|
| 7075 |
+
),
|
| 7076 |
+
),
|
| 7077 |
+
array(
|
| 7078 |
+
'attr_spec_list' => array(
|
| 7079 |
+
'[accept]' => array(),
|
| 7080 |
+
'[accesskey]' => array(),
|
| 7081 |
+
'[autocomplete]' => array(),
|
| 7082 |
+
'[checked]' => array(),
|
| 7083 |
+
'[disabled]' => array(),
|
| 7084 |
+
'[height]' => array(),
|
| 7085 |
+
'[inputmode]' => array(),
|
| 7086 |
+
'[max]' => array(),
|
| 7087 |
+
'[maxlength]' => array(),
|
| 7088 |
+
'[min]' => array(),
|
| 7089 |
+
'[minlength]' => array(),
|
| 7090 |
+
'[multiple]' => array(),
|
| 7091 |
+
'[pattern]' => array(),
|
| 7092 |
+
'[placeholder]' => array(),
|
| 7093 |
+
'[readonly]' => array(),
|
| 7094 |
+
'[required]' => array(),
|
| 7095 |
+
'[selectiondirection]' => array(),
|
| 7096 |
+
'[size]' => array(),
|
| 7097 |
+
'[spellcheck]' => array(),
|
| 7098 |
+
'[step]' => array(),
|
| 7099 |
+
'[type]' => array(),
|
| 7100 |
+
'[value]' => array(),
|
| 7101 |
+
'[width]' => array(),
|
| 7102 |
+
'accept' => array(),
|
| 7103 |
+
'accesskey' => array(),
|
| 7104 |
+
'autocomplete' => array(),
|
| 7105 |
+
'autofocus' => array(),
|
| 7106 |
+
'checked' => array(),
|
| 7107 |
+
'disabled' => array(),
|
| 7108 |
+
'height' => array(),
|
| 7109 |
+
'inputmode' => array(),
|
| 7110 |
+
'list' => array(),
|
| 7111 |
+
'mask' => array(
|
| 7112 |
+
'dispatch_key' => 1,
|
| 7113 |
+
'mandatory' => true,
|
| 7114 |
+
),
|
| 7115 |
+
'mask-output' => array(),
|
| 7116 |
+
'max' => array(),
|
| 7117 |
+
'maxlength' => array(),
|
| 7118 |
+
'min' => array(),
|
| 7119 |
+
'minlength' => array(),
|
| 7120 |
+
'multiple' => array(),
|
| 7121 |
+
'name' => array(
|
| 7122 |
+
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 7123 |
+
),
|
| 7124 |
+
'pattern' => array(),
|
| 7125 |
+
'placeholder' => array(),
|
| 7126 |
+
'readonly' => array(),
|
| 7127 |
+
'required' => array(),
|
| 7128 |
+
'selectiondirection' => array(),
|
| 7129 |
+
'size' => array(),
|
| 7130 |
+
'spellcheck' => array(),
|
| 7131 |
+
'step' => array(),
|
| 7132 |
+
'tabindex' => array(),
|
| 7133 |
+
'type' => array(
|
| 7134 |
+
'value' => array(
|
| 7135 |
+
'text',
|
| 7136 |
+
'tel',
|
| 7137 |
+
'search',
|
| 7138 |
+
),
|
| 7139 |
+
),
|
| 7140 |
+
'value' => array(),
|
| 7141 |
+
'width' => array(),
|
| 7142 |
+
),
|
| 7143 |
+
'tag_spec' => array(
|
| 7144 |
+
'requires_extension' => array(
|
| 7145 |
+
'amp-inputmask',
|
| 7146 |
+
),
|
| 7147 |
+
'spec_name' => 'input [mask]',
|
| 7148 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-inputmask',
|
| 7149 |
+
),
|
| 7150 |
+
),
|
| 7151 |
+
),
|
| 7152 |
+
'ins' => array(
|
| 7153 |
+
array(
|
| 7154 |
+
'attr_spec_list' => array(
|
| 7155 |
+
'cite' => array(
|
| 7156 |
+
'blacklisted_value_regex' => '__amp_source_origin',
|
| 7157 |
+
'value_url' => array(
|
| 7158 |
+
'allow_empty' => true,
|
| 7159 |
+
'protocol' => array(
|
| 7160 |
+
'http',
|
| 7161 |
+
'https',
|
| 7162 |
+
),
|
| 7163 |
+
),
|
| 7164 |
+
),
|
| 7165 |
+
'datetime' => array(),
|
| 7166 |
+
),
|
| 7167 |
+
'tag_spec' => array(),
|
| 7168 |
+
),
|
| 7169 |
+
),
|
| 7170 |
+
'kbd' => array(
|
| 7171 |
+
array(
|
| 7172 |
+
'attr_spec_list' => array(),
|
| 7173 |
+
'tag_spec' => array(),
|
| 7174 |
+
),
|
| 7175 |
+
),
|
| 7176 |
+
'label' => array(
|
| 7177 |
+
array(
|
| 7178 |
+
'attr_spec_list' => array(
|
| 7179 |
+
'for' => array(),
|
| 7180 |
+
),
|
| 7181 |
+
'tag_spec' => array(
|
| 7182 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
|
| 7183 |
+
),
|
| 7184 |
+
),
|
| 7185 |
+
),
|
| 7186 |
+
'legend' => array(
|
| 7187 |
+
array(
|
| 7188 |
+
'attr_spec_list' => array(),
|
| 7189 |
+
'tag_spec' => array(),
|
| 7190 |
+
),
|
| 7191 |
+
),
|
| 7192 |
+
'li' => array(
|
| 7193 |
+
array(
|
| 7194 |
+
'attr_spec_list' => array(
|
| 7195 |
+
'value' => array(
|
| 7196 |
+
'value_regex' => '[0-9]*',
|
| 7197 |
+
),
|
| 7198 |
+
),
|
| 7199 |
+
'tag_spec' => array(),
|
| 7200 |
+
),
|
| 7201 |
+
),
|
| 7202 |
+
'line' => array(
|
| 7203 |
+
array(
|
| 7204 |
+
'attr_spec_list' => array(
|
| 7205 |
+
'alignment-baseline' => array(),
|
| 7206 |
+
'baseline-shift' => array(),
|
| 7207 |
+
'clip' => array(),
|
| 7208 |
+
'clip-path' => array(),
|
| 7209 |
+
'clip-rule' => array(),
|
| 7210 |
+
'color' => array(),
|
| 7211 |
+
'color-interpolation' => array(),
|
| 7212 |
+
'color-interpolation-filters' => array(),
|
| 7213 |
+
'color-profile' => array(),
|
| 7214 |
+
'color-rendering' => array(),
|
| 7215 |
+
'cursor' => array(),
|
| 7216 |
+
'direction' => array(),
|
| 7217 |
+
'display' => array(),
|
| 7218 |
+
'dominant-baseline' => array(),
|
| 7219 |
+
'enable-background' => array(),
|
| 7220 |
+
'externalresourcesrequired' => array(),
|
| 7221 |
+
'fill' => array(),
|
| 7222 |
+
'fill-opacity' => array(),
|
| 7223 |
+
'fill-rule' => array(),
|
| 7224 |
+
'filter' => array(),
|
| 7225 |
+
'flood-color' => array(),
|
| 7226 |
+
'flood-opacity' => array(),
|
| 7227 |
+
'focusable' => array(),
|
| 7228 |
+
'font-family' => array(),
|
| 7229 |
'font-size' => array(),
|
| 7230 |
'font-size-adjust' => array(),
|
| 7231 |
'font-stretch' => array(),
|
| 7312 |
'filter' => array(),
|
| 7313 |
'flood-color' => array(),
|
| 7314 |
'flood-opacity' => array(),
|
| 7315 |
+
'focusable' => array(),
|
| 7316 |
'font-family' => array(),
|
| 7317 |
'font-size' => array(),
|
| 7318 |
'font-size-adjust' => array(),
|
| 7368 |
),
|
| 7369 |
'value_url' => array(
|
| 7370 |
'allow_empty' => false,
|
| 7371 |
+
'protocol' => array(
|
|
|
|
| 7372 |
'http',
|
| 7373 |
'https',
|
| 7374 |
),
|
| 7395 |
array(
|
| 7396 |
'attr_spec_list' => array(
|
| 7397 |
'charset' => array(
|
| 7398 |
+
'value_casei' => array(
|
| 7399 |
+
'utf-8',
|
| 7400 |
+
),
|
| 7401 |
),
|
| 7402 |
'color' => array(),
|
| 7403 |
'crossorigin' => array(),
|
| 7423 |
array(
|
| 7424 |
'attr_spec_list' => array(
|
| 7425 |
'charset' => array(
|
| 7426 |
+
'value_casei' => array(
|
| 7427 |
+
'utf-8',
|
| 7428 |
+
),
|
| 7429 |
),
|
| 7430 |
'color' => array(),
|
| 7431 |
'crossorigin' => array(),
|
| 7433 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 7434 |
'mandatory' => true,
|
| 7435 |
'value_url' => array(
|
| 7436 |
+
'protocol' => array(
|
|
|
|
| 7437 |
'http',
|
| 7438 |
'https',
|
| 7439 |
),
|
| 7444 |
'rel' => array(
|
| 7445 |
'dispatch_key' => 2,
|
| 7446 |
'mandatory' => true,
|
| 7447 |
+
'value_casei' => array(
|
| 7448 |
+
'canonical',
|
| 7449 |
+
),
|
| 7450 |
),
|
| 7451 |
'sizes' => array(),
|
| 7452 |
'target' => array(),
|
| 7463 |
array(
|
| 7464 |
'attr_spec_list' => array(
|
| 7465 |
'charset' => array(
|
| 7466 |
+
'value_casei' => array(
|
| 7467 |
+
'utf-8',
|
| 7468 |
+
),
|
| 7469 |
),
|
| 7470 |
'color' => array(),
|
| 7471 |
'crossorigin' => array(),
|
| 7473 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 7474 |
'mandatory' => true,
|
| 7475 |
'value_url' => array(
|
| 7476 |
+
'protocol' => array(
|
|
|
|
| 7477 |
'https',
|
| 7478 |
),
|
| 7479 |
),
|
| 7483 |
'rel' => array(
|
| 7484 |
'dispatch_key' => 2,
|
| 7485 |
'mandatory' => true,
|
| 7486 |
+
'value_casei' => array(
|
| 7487 |
+
'manifest',
|
| 7488 |
+
),
|
| 7489 |
),
|
| 7490 |
'sizes' => array(),
|
| 7491 |
'target' => array(),
|
| 7501 |
'attr_spec_list' => array(
|
| 7502 |
'as' => array(),
|
| 7503 |
'charset' => array(
|
| 7504 |
+
'value_casei' => array(
|
| 7505 |
+
'utf-8',
|
| 7506 |
+
),
|
| 7507 |
),
|
| 7508 |
'color' => array(),
|
| 7509 |
'crossorigin' => array(),
|
| 7513 |
'rel' => array(
|
| 7514 |
'dispatch_key' => 2,
|
| 7515 |
'mandatory' => true,
|
| 7516 |
+
'value_casei' => array(
|
| 7517 |
+
'preload',
|
| 7518 |
+
),
|
| 7519 |
),
|
| 7520 |
'sizes' => array(),
|
| 7521 |
'target' => array(),
|
| 7535 |
'crossorigin' => array(),
|
| 7536 |
'href' => array(
|
| 7537 |
'mandatory' => true,
|
| 7538 |
+
'value_regex' => 'https://cdn\\.materialdesignicons\\.com/([0-9]+\\.?)+/css/materialdesignicons\\.min\\.css|https://cloud\\.typography\\.com/[0-9]*/[0-9]*/css/fonts\\.css|https://fast\\.fonts\\.net/.*|https://fonts\\.googleapis\\.com/css\\?.*|https://fonts\\.googleapis\\.com/icon\\?.*|https://fonts\\.googleapis\\.com/earlyaccess/.*\\.css|https://maxcdn\\.bootstrapcdn\\.com/font-awesome/([0-9]+\\.?)+/css/font-awesome\\.min\\.css(\\?.*)?|https://(use|pro)\\.fontawesome\\.com/releases/v([0-9]+\\.?)+/css/(all|brands|solid|regular|light|fontawesome)\\.css|https://(use|pro)\\.fontawesome\\.com/[0-9a-zA-Z]+\\.css|https://use\\.typekit\\.net/[\\w\\p{L}\\p{N}_]+\\.css',
|
| 7539 |
),
|
| 7540 |
'integrity' => array(),
|
| 7541 |
'media' => array(),
|
| 7542 |
'rel' => array(
|
| 7543 |
'dispatch_key' => 2,
|
| 7544 |
'mandatory' => true,
|
| 7545 |
+
'value_casei' => array(
|
| 7546 |
+
'stylesheet',
|
| 7547 |
+
),
|
| 7548 |
),
|
| 7549 |
'type' => array(
|
| 7550 |
+
'value_casei' => array(
|
| 7551 |
+
'text/css',
|
| 7552 |
+
),
|
| 7553 |
),
|
| 7554 |
),
|
| 7555 |
'tag_spec' => array(
|
| 7561 |
array(
|
| 7562 |
'attr_spec_list' => array(
|
| 7563 |
'charset' => array(
|
| 7564 |
+
'value_casei' => array(
|
| 7565 |
+
'utf-8',
|
| 7566 |
+
),
|
| 7567 |
),
|
| 7568 |
'color' => array(),
|
| 7569 |
'crossorigin' => array(),
|
| 7574 |
'itemprop' => array(
|
| 7575 |
'dispatch_key' => 2,
|
| 7576 |
'mandatory' => true,
|
| 7577 |
+
'value_casei' => array(
|
| 7578 |
+
'sameas',
|
| 7579 |
+
),
|
| 7580 |
),
|
| 7581 |
'media' => array(),
|
| 7582 |
'sizes' => array(),
|
| 7591 |
array(
|
| 7592 |
'attr_spec_list' => array(
|
| 7593 |
'charset' => array(
|
| 7594 |
+
'value_casei' => array(
|
| 7595 |
+
'utf-8',
|
| 7596 |
+
),
|
| 7597 |
),
|
| 7598 |
'color' => array(),
|
| 7599 |
'crossorigin' => array(),
|
| 7617 |
array(
|
| 7618 |
'attr_spec_list' => array(
|
| 7619 |
'charset' => array(
|
| 7620 |
+
'value_casei' => array(
|
| 7621 |
+
'utf-8',
|
| 7622 |
+
),
|
| 7623 |
),
|
| 7624 |
'color' => array(),
|
| 7625 |
'crossorigin' => array(),
|
| 7684 |
'filter' => array(),
|
| 7685 |
'flood-color' => array(),
|
| 7686 |
'flood-opacity' => array(),
|
| 7687 |
+
'focusable' => array(),
|
| 7688 |
'font-family' => array(),
|
| 7689 |
'font-size' => array(),
|
| 7690 |
'font-size-adjust' => array(),
|
| 7772 |
'filter' => array(),
|
| 7773 |
'flood-color' => array(),
|
| 7774 |
'flood-opacity' => array(),
|
| 7775 |
+
'focusable' => array(),
|
| 7776 |
'font-family' => array(),
|
| 7777 |
'font-size' => array(),
|
| 7778 |
'font-size-adjust' => array(),
|
| 7841 |
'charset' => array(
|
| 7842 |
'dispatch_key' => 1,
|
| 7843 |
'mandatory' => true,
|
| 7844 |
+
'value_casei' => array(
|
| 7845 |
+
'utf-8',
|
| 7846 |
+
),
|
| 7847 |
),
|
| 7848 |
),
|
| 7849 |
'tag_spec' => array(
|
| 7862 |
'height' => array(),
|
| 7863 |
'initial-scale' => array(),
|
| 7864 |
'maximum-scale' => array(),
|
| 7865 |
+
'minimum-scale' => array(),
|
|
|
|
|
|
|
|
|
|
| 7866 |
'shrink-to-fit' => array(),
|
| 7867 |
'user-scalable' => array(),
|
| 7868 |
'viewport-fit' => array(),
|
| 7875 |
'name' => array(
|
| 7876 |
'dispatch_key' => 2,
|
| 7877 |
'mandatory' => true,
|
| 7878 |
+
'value' => array(
|
| 7879 |
+
'viewport',
|
| 7880 |
+
),
|
| 7881 |
),
|
| 7882 |
),
|
| 7883 |
'tag_spec' => array(
|
| 7904 |
'http-equiv' => array(
|
| 7905 |
'dispatch_key' => 2,
|
| 7906 |
'mandatory' => true,
|
| 7907 |
+
'value_casei' => array(
|
| 7908 |
+
'x-ua-compatible',
|
| 7909 |
+
),
|
| 7910 |
),
|
| 7911 |
),
|
| 7912 |
'tag_spec' => array(
|
| 7924 |
'name' => array(
|
| 7925 |
'dispatch_key' => 2,
|
| 7926 |
'mandatory' => true,
|
| 7927 |
+
'value_casei' => array(
|
| 7928 |
+
'apple-itunes-app',
|
| 7929 |
+
),
|
| 7930 |
),
|
| 7931 |
),
|
| 7932 |
'tag_spec' => array(
|
| 7943 |
'name' => array(
|
| 7944 |
'dispatch_key' => 2,
|
| 7945 |
'mandatory' => true,
|
| 7946 |
+
'value_casei' => array(
|
| 7947 |
+
'amp-experiments-opt-in',
|
| 7948 |
+
),
|
| 7949 |
),
|
| 7950 |
),
|
| 7951 |
'tag_spec' => array(
|
| 7958 |
'content' => array(
|
| 7959 |
'mandatory' => true,
|
| 7960 |
'value_url' => array(
|
| 7961 |
+
'protocol' => array(
|
| 7962 |
'https',
|
| 7963 |
),
|
| 7964 |
),
|
| 7966 |
'name' => array(
|
| 7967 |
'dispatch_key' => 2,
|
| 7968 |
'mandatory' => true,
|
| 7969 |
+
'value_casei' => array(
|
| 7970 |
+
'amp-3p-iframe-src',
|
| 7971 |
+
),
|
| 7972 |
),
|
| 7973 |
),
|
| 7974 |
'tag_spec' => array(
|
| 7985 |
'name' => array(
|
| 7986 |
'dispatch_key' => 2,
|
| 7987 |
'mandatory' => true,
|
| 7988 |
+
'value_casei' => array(
|
| 7989 |
+
'amp-experiment-token',
|
| 7990 |
+
),
|
| 7991 |
),
|
| 7992 |
),
|
| 7993 |
'tag_spec' => array(
|
| 8003 |
'name' => array(
|
| 8004 |
'dispatch_key' => 2,
|
| 8005 |
'mandatory' => true,
|
| 8006 |
+
'value_casei' => array(
|
| 8007 |
+
'amp-link-variable-allowed-origin',
|
| 8008 |
+
),
|
| 8009 |
),
|
| 8010 |
),
|
| 8011 |
'tag_spec' => array(
|
| 8021 |
'name' => array(
|
| 8022 |
'dispatch_key' => 2,
|
| 8023 |
'mandatory' => true,
|
| 8024 |
+
'value_casei' => array(
|
| 8025 |
+
'amp-google-client-id-api',
|
| 8026 |
+
),
|
| 8027 |
),
|
| 8028 |
),
|
| 8029 |
'tag_spec' => array(
|
| 8036 |
'name' => array(
|
| 8037 |
'dispatch_key' => 2,
|
| 8038 |
'mandatory' => true,
|
| 8039 |
+
'value_casei' => array(
|
| 8040 |
+
'amp-ad-doubleclick-sra',
|
| 8041 |
+
),
|
| 8042 |
),
|
| 8043 |
),
|
| 8044 |
'tag_spec' => array(
|
| 8064 |
'attr_spec_list' => array(
|
| 8065 |
'content' => array(
|
| 8066 |
'mandatory' => true,
|
| 8067 |
+
'value_casei' => array(
|
| 8068 |
+
'text/html; charset=utf-8',
|
| 8069 |
+
),
|
| 8070 |
),
|
| 8071 |
'http-equiv' => array(
|
| 8072 |
'dispatch_key' => 2,
|
| 8073 |
'mandatory' => true,
|
| 8074 |
+
'value_casei' => array(
|
| 8075 |
+
'content-type',
|
| 8076 |
+
),
|
| 8077 |
),
|
| 8078 |
),
|
| 8079 |
'tag_spec' => array(
|
| 8090 |
'http-equiv' => array(
|
| 8091 |
'dispatch_key' => 2,
|
| 8092 |
'mandatory' => true,
|
| 8093 |
+
'value_casei' => array(
|
| 8094 |
+
'content-language',
|
| 8095 |
+
),
|
| 8096 |
),
|
| 8097 |
),
|
| 8098 |
'tag_spec' => array(
|
| 8109 |
'http-equiv' => array(
|
| 8110 |
'dispatch_key' => 2,
|
| 8111 |
'mandatory' => true,
|
| 8112 |
+
'value_casei' => array(
|
| 8113 |
+
'pics-label',
|
| 8114 |
+
),
|
| 8115 |
),
|
| 8116 |
),
|
| 8117 |
'tag_spec' => array(
|
| 8128 |
'http-equiv' => array(
|
| 8129 |
'dispatch_key' => 2,
|
| 8130 |
'mandatory' => true,
|
| 8131 |
+
'value_casei' => array(
|
| 8132 |
+
'imagetoolbar',
|
| 8133 |
+
),
|
| 8134 |
),
|
| 8135 |
),
|
| 8136 |
'tag_spec' => array(
|
| 8143 |
'attr_spec_list' => array(
|
| 8144 |
'content' => array(
|
| 8145 |
'mandatory' => true,
|
| 8146 |
+
'value_casei' => array(
|
| 8147 |
+
'text/css',
|
| 8148 |
+
),
|
| 8149 |
),
|
| 8150 |
'http-equiv' => array(
|
| 8151 |
'dispatch_key' => 2,
|
| 8152 |
'mandatory' => true,
|
| 8153 |
+
'value_casei' => array(
|
| 8154 |
+
'content-style-type',
|
| 8155 |
+
),
|
| 8156 |
),
|
| 8157 |
),
|
| 8158 |
'tag_spec' => array(
|
| 8165 |
'attr_spec_list' => array(
|
| 8166 |
'content' => array(
|
| 8167 |
'mandatory' => true,
|
| 8168 |
+
'value_casei' => array(
|
| 8169 |
+
'text/javascript',
|
| 8170 |
+
),
|
| 8171 |
),
|
| 8172 |
'http-equiv' => array(
|
| 8173 |
'dispatch_key' => 2,
|
| 8174 |
'mandatory' => true,
|
| 8175 |
+
'value_casei' => array(
|
| 8176 |
+
'content-script-type',
|
| 8177 |
+
),
|
| 8178 |
),
|
| 8179 |
),
|
| 8180 |
'tag_spec' => array(
|
| 8191 |
'http-equiv' => array(
|
| 8192 |
'dispatch_key' => 2,
|
| 8193 |
'mandatory' => true,
|
| 8194 |
+
'value_casei' => array(
|
| 8195 |
+
'origin-trial',
|
| 8196 |
+
),
|
| 8197 |
),
|
| 8198 |
),
|
| 8199 |
'tag_spec' => array(
|
| 8210 |
'http-equiv' => array(
|
| 8211 |
'dispatch_key' => 2,
|
| 8212 |
'mandatory' => true,
|
| 8213 |
+
'value_casei' => array(
|
| 8214 |
+
'resource-type',
|
| 8215 |
+
),
|
| 8216 |
),
|
| 8217 |
),
|
| 8218 |
'tag_spec' => array(
|
| 8225 |
'attr_spec_list' => array(
|
| 8226 |
'content' => array(
|
| 8227 |
'mandatory' => true,
|
| 8228 |
+
'value_casei' => array(
|
| 8229 |
+
'off',
|
| 8230 |
+
'on',
|
| 8231 |
+
),
|
| 8232 |
),
|
| 8233 |
'http-equiv' => array(
|
| 8234 |
'dispatch_key' => 2,
|
| 8235 |
'mandatory' => true,
|
| 8236 |
+
'value_casei' => array(
|
| 8237 |
+
'x-dns-prefetch-control',
|
| 8238 |
+
),
|
| 8239 |
),
|
| 8240 |
),
|
| 8241 |
'tag_spec' => array(
|
| 8252 |
'name' => array(
|
| 8253 |
'dispatch_key' => 2,
|
| 8254 |
'mandatory' => true,
|
| 8255 |
+
'value_casei' => array(
|
| 8256 |
+
'amp-ad-enable-refresh',
|
| 8257 |
+
),
|
| 8258 |
),
|
| 8259 |
),
|
| 8260 |
'tag_spec' => array(
|
| 8270 |
'name' => array(
|
| 8271 |
'dispatch_key' => 2,
|
| 8272 |
'mandatory' => true,
|
| 8273 |
+
'value_casei' => array(
|
| 8274 |
+
'amp-to-amp-navigation',
|
| 8275 |
+
),
|
| 8276 |
),
|
| 8277 |
),
|
| 8278 |
'tag_spec' => array(
|
| 8382 |
array(
|
| 8383 |
'attr_spec_list' => array(
|
| 8384 |
'reversed' => array(
|
| 8385 |
+
'value' => array(
|
| 8386 |
+
'',
|
| 8387 |
+
),
|
| 8388 |
),
|
| 8389 |
'start' => array(
|
| 8390 |
'value_regex' => '[0-9]*',
|
| 8473 |
'filter' => array(),
|
| 8474 |
'flood-color' => array(),
|
| 8475 |
'flood-opacity' => array(),
|
| 8476 |
+
'focusable' => array(),
|
| 8477 |
'font-family' => array(),
|
| 8478 |
'font-size' => array(),
|
| 8479 |
'font-size-adjust' => array(),
|
| 8558 |
'filter' => array(),
|
| 8559 |
'flood-color' => array(),
|
| 8560 |
'flood-opacity' => array(),
|
| 8561 |
+
'focusable' => array(),
|
| 8562 |
'font-family' => array(),
|
| 8563 |
'font-size' => array(),
|
| 8564 |
'font-size-adjust' => array(),
|
| 8620 |
),
|
| 8621 |
'value_url' => array(
|
| 8622 |
'allow_empty' => false,
|
| 8623 |
+
'protocol' => array(
|
|
|
|
| 8624 |
'http',
|
| 8625 |
'https',
|
| 8626 |
),
|
| 8642 |
),
|
| 8643 |
),
|
| 8644 |
),
|
| 8645 |
+
'picture' => array(
|
| 8646 |
+
array(
|
| 8647 |
+
'attr_spec_list' => array(),
|
| 8648 |
+
'tag_spec' => array(
|
| 8649 |
+
'mandatory_parent' => 'noscript',
|
| 8650 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-img',
|
| 8651 |
+
),
|
| 8652 |
+
),
|
| 8653 |
+
),
|
| 8654 |
'polygon' => array(
|
| 8655 |
array(
|
| 8656 |
'attr_spec_list' => array(
|
| 8676 |
'filter' => array(),
|
| 8677 |
'flood-color' => array(),
|
| 8678 |
'flood-opacity' => array(),
|
| 8679 |
+
'focusable' => array(),
|
| 8680 |
'font-family' => array(),
|
| 8681 |
'font-size' => array(),
|
| 8682 |
'font-size-adjust' => array(),
|
| 8761 |
'filter' => array(),
|
| 8762 |
'flood-color' => array(),
|
| 8763 |
'flood-opacity' => array(),
|
| 8764 |
+
'focusable' => array(),
|
| 8765 |
'font-family' => array(),
|
| 8766 |
'font-size' => array(),
|
| 8767 |
'font-size-adjust' => array(),
|
| 8843 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 8844 |
'value_url' => array(
|
| 8845 |
'allow_empty' => true,
|
| 8846 |
+
'protocol' => array(
|
|
|
|
| 8847 |
'http',
|
| 8848 |
'https',
|
| 8849 |
),
|
| 8880 |
'filter' => array(),
|
| 8881 |
'flood-color' => array(),
|
| 8882 |
'flood-opacity' => array(),
|
| 8883 |
+
'focusable' => array(),
|
| 8884 |
'font-family' => array(),
|
| 8885 |
'font-size' => array(),
|
| 8886 |
'font-size-adjust' => array(),
|
| 8938 |
),
|
| 8939 |
'value_url' => array(
|
| 8940 |
'allow_empty' => false,
|
| 8941 |
+
'protocol' => array(
|
|
|
|
| 8942 |
'http',
|
| 8943 |
'https',
|
| 8944 |
),
|
| 8990 |
'filter' => array(),
|
| 8991 |
'flood-color' => array(),
|
| 8992 |
'flood-opacity' => array(),
|
| 8993 |
+
'focusable' => array(),
|
| 8994 |
'font-family' => array(),
|
| 8995 |
'font-size' => array(),
|
| 8996 |
'font-size-adjust' => array(),
|
| 9096 |
'attr_spec_list' => array(
|
| 9097 |
'async' => array(
|
| 9098 |
'mandatory' => true,
|
| 9099 |
+
'value' => array(
|
| 9100 |
+
'',
|
| 9101 |
+
),
|
| 9102 |
),
|
| 9103 |
'nonce' => array(),
|
| 9104 |
'src' => array(
|
| 9105 |
'dispatch_key' => 2,
|
| 9106 |
'mandatory' => true,
|
| 9107 |
+
'value' => array(
|
| 9108 |
+
'https://cdn.ampproject.org/v0.js',
|
| 9109 |
+
),
|
| 9110 |
),
|
| 9111 |
'type' => array(
|
| 9112 |
+
'value_casei' => array(
|
| 9113 |
+
'text/javascript',
|
| 9114 |
+
),
|
| 9115 |
),
|
| 9116 |
),
|
| 9117 |
'cdata' => array(
|
| 9134 |
'type' => array(
|
| 9135 |
'dispatch_key' => 2,
|
| 9136 |
'mandatory' => true,
|
| 9137 |
+
'value_casei' => array(
|
| 9138 |
+
'application/ld+json',
|
| 9139 |
+
),
|
| 9140 |
),
|
| 9141 |
),
|
| 9142 |
'cdata' => array(
|
| 9154 |
'id' => array(
|
| 9155 |
'dispatch_key' => 2,
|
| 9156 |
'mandatory' => true,
|
| 9157 |
+
'value_casei' => array(
|
| 9158 |
+
'amp-rtc',
|
| 9159 |
+
),
|
| 9160 |
),
|
| 9161 |
'nonce' => array(),
|
| 9162 |
'type' => array(
|
| 9163 |
'mandatory' => true,
|
| 9164 |
+
'value_casei' => array(
|
| 9165 |
+
'application/json',
|
| 9166 |
+
),
|
| 9167 |
),
|
| 9168 |
),
|
| 9169 |
'cdata' => array(
|
| 9183 |
'type' => array(
|
| 9184 |
'dispatch_key' => 3,
|
| 9185 |
'mandatory' => true,
|
| 9186 |
+
'value_casei' => array(
|
| 9187 |
+
'application/json',
|
| 9188 |
+
),
|
| 9189 |
),
|
| 9190 |
),
|
| 9191 |
'cdata' => array(
|
| 9203 |
'attr_spec_list' => array(
|
| 9204 |
'async' => array(
|
| 9205 |
'mandatory' => true,
|
| 9206 |
+
'value' => array(
|
| 9207 |
+
'',
|
| 9208 |
+
),
|
| 9209 |
),
|
| 9210 |
'nonce' => array(),
|
| 9211 |
'type' => array(
|
| 9212 |
+
'value_casei' => array(
|
| 9213 |
+
'text/javascript',
|
| 9214 |
+
),
|
| 9215 |
),
|
| 9216 |
),
|
| 9217 |
'tag_spec' => array(
|
| 9218 |
'extension_spec' => array(
|
| 9219 |
+
'name' => 'amp-3d-gltf',
|
| 9220 |
+
'version' => array(
|
| 9221 |
'0.1',
|
| 9222 |
'latest',
|
| 9223 |
),
|
|
|
|
| 9224 |
),
|
| 9225 |
),
|
| 9226 |
),
|
| 9228 |
'attr_spec_list' => array(
|
| 9229 |
'async' => array(
|
| 9230 |
'mandatory' => true,
|
| 9231 |
+
'value' => array(
|
| 9232 |
+
'',
|
| 9233 |
+
),
|
| 9234 |
),
|
| 9235 |
'nonce' => array(),
|
| 9236 |
'type' => array(
|
| 9237 |
+
'value_casei' => array(
|
| 9238 |
+
'text/javascript',
|
| 9239 |
+
),
|
| 9240 |
),
|
| 9241 |
),
|
| 9242 |
'tag_spec' => array(
|
| 9243 |
'extension_spec' => array(
|
| 9244 |
+
'name' => 'amp-3q-player',
|
| 9245 |
+
'version' => array(
|
| 9246 |
'0.1',
|
| 9247 |
'latest',
|
| 9248 |
),
|
| 9249 |
+
),
|
| 9250 |
+
),
|
| 9251 |
+
),
|
| 9252 |
+
array(
|
| 9253 |
+
'attr_spec_list' => array(
|
| 9254 |
+
'async' => array(
|
| 9255 |
+
'mandatory' => true,
|
| 9256 |
+
'value' => array(
|
| 9257 |
+
'',
|
| 9258 |
+
),
|
| 9259 |
+
),
|
| 9260 |
+
'nonce' => array(),
|
| 9261 |
+
'type' => array(
|
| 9262 |
+
'value_casei' => array(
|
| 9263 |
+
'text/javascript',
|
| 9264 |
+
),
|
| 9265 |
+
),
|
| 9266 |
+
),
|
| 9267 |
+
'tag_spec' => array(
|
| 9268 |
+
'extension_spec' => array(
|
| 9269 |
'name' => 'amp-access-laterpay',
|
| 9270 |
'requires_usage' => 3,
|
| 9271 |
+
'version' => array(
|
| 9272 |
+
'0.1',
|
| 9273 |
+
'0.2',
|
| 9274 |
+
'latest',
|
| 9275 |
+
),
|
| 9276 |
),
|
| 9277 |
'requires_extension' => array(
|
| 9278 |
'amp-access',
|
| 9283 |
'attr_spec_list' => array(
|
| 9284 |
'async' => array(
|
| 9285 |
'mandatory' => true,
|
| 9286 |
+
'value' => array(
|
| 9287 |
+
'',
|
| 9288 |
+
),
|
| 9289 |
),
|
| 9290 |
'nonce' => array(),
|
| 9291 |
'type' => array(
|
| 9292 |
+
'value_casei' => array(
|
| 9293 |
+
'text/javascript',
|
| 9294 |
+
),
|
| 9295 |
),
|
| 9296 |
),
|
| 9297 |
'tag_spec' => array(
|
| 9298 |
'extension_spec' => array(
|
| 9299 |
+
'name' => 'amp-access-scroll',
|
| 9300 |
+
'requires_usage' => 3,
|
| 9301 |
+
'version' => array(
|
| 9302 |
'0.1',
|
| 9303 |
'latest',
|
| 9304 |
),
|
|
|
|
|
|
|
| 9305 |
),
|
| 9306 |
'requires_extension' => array(
|
| 9307 |
'amp-access',
|
| 9312 |
'attr_spec_list' => array(
|
| 9313 |
'async' => array(
|
| 9314 |
'mandatory' => true,
|
| 9315 |
+
'value' => array(
|
| 9316 |
+
'',
|
| 9317 |
+
),
|
| 9318 |
),
|
| 9319 |
'nonce' => array(),
|
| 9320 |
'type' => array(
|
| 9321 |
+
'value_casei' => array(
|
| 9322 |
+
'text/javascript',
|
| 9323 |
+
),
|
| 9324 |
),
|
| 9325 |
),
|
| 9326 |
'tag_spec' => array(
|
| 9327 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9328 |
'deprecated_allow_duplicates' => true,
|
| 9329 |
'name' => 'amp-access',
|
| 9330 |
'requires_usage' => 2,
|
| 9331 |
+
'version' => array(
|
| 9332 |
+
'0.1',
|
| 9333 |
+
'latest',
|
| 9334 |
+
),
|
| 9335 |
),
|
| 9336 |
),
|
| 9337 |
),
|
| 9340 |
'id' => array(
|
| 9341 |
'dispatch_key' => 2,
|
| 9342 |
'mandatory' => true,
|
| 9343 |
+
'value' => array(
|
| 9344 |
+
'amp-access',
|
| 9345 |
+
),
|
| 9346 |
),
|
| 9347 |
'nonce' => array(),
|
| 9348 |
'type' => array(
|
| 9349 |
'mandatory' => true,
|
| 9350 |
+
'value_casei' => array(
|
| 9351 |
+
'application/json',
|
| 9352 |
+
),
|
| 9353 |
),
|
| 9354 |
),
|
| 9355 |
'cdata' => array(
|
| 9362 |
'mandatory_parent' => 'head',
|
| 9363 |
'requires_extension' => array(
|
| 9364 |
'amp-access',
|
|
|
|
| 9365 |
),
|
| 9366 |
'spec_name' => 'amp-access extension .json script',
|
| 9367 |
'unique' => true,
|
| 9371 |
'attr_spec_list' => array(
|
| 9372 |
'async' => array(
|
| 9373 |
'mandatory' => true,
|
| 9374 |
+
'value' => array(
|
| 9375 |
+
'',
|
| 9376 |
+
),
|
| 9377 |
),
|
| 9378 |
'nonce' => array(),
|
| 9379 |
'type' => array(
|
| 9380 |
+
'value_casei' => array(
|
| 9381 |
+
'text/javascript',
|
| 9382 |
+
),
|
| 9383 |
),
|
| 9384 |
),
|
| 9385 |
'tag_spec' => array(
|
| 9386 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9387 |
'deprecated_allow_duplicates' => true,
|
| 9388 |
'name' => 'amp-accordion',
|
| 9389 |
'requires_usage' => 2,
|
| 9390 |
+
'version' => array(
|
| 9391 |
+
'0.1',
|
| 9392 |
+
'latest',
|
| 9393 |
+
),
|
| 9394 |
),
|
| 9395 |
),
|
| 9396 |
),
|
| 9398 |
'attr_spec_list' => array(
|
| 9399 |
'async' => array(
|
| 9400 |
'mandatory' => true,
|
| 9401 |
+
'value' => array(
|
| 9402 |
+
'',
|
| 9403 |
+
),
|
| 9404 |
),
|
| 9405 |
'nonce' => array(),
|
| 9406 |
'type' => array(
|
| 9407 |
+
'value_casei' => array(
|
| 9408 |
+
'text/javascript',
|
| 9409 |
+
),
|
| 9410 |
),
|
| 9411 |
),
|
| 9412 |
'tag_spec' => array(
|
| 9413 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9414 |
'deprecated_allow_duplicates' => true,
|
| 9415 |
'name' => 'amp-ad',
|
| 9416 |
'requires_usage' => 2,
|
| 9417 |
+
'version' => array(
|
| 9418 |
+
'0.1',
|
| 9419 |
+
'latest',
|
| 9420 |
+
),
|
| 9421 |
),
|
| 9422 |
'spec_name' => 'amp-ad extension .js script',
|
| 9423 |
),
|
| 9426 |
'attr_spec_list' => array(
|
| 9427 |
'async' => array(
|
| 9428 |
'mandatory' => true,
|
| 9429 |
+
'value' => array(
|
| 9430 |
+
'',
|
| 9431 |
+
),
|
| 9432 |
),
|
| 9433 |
'nonce' => array(),
|
| 9434 |
'type' => array(
|
| 9435 |
+
'value_casei' => array(
|
| 9436 |
+
'text/javascript',
|
| 9437 |
+
),
|
| 9438 |
),
|
| 9439 |
),
|
| 9440 |
'tag_spec' => array(
|
| 9441 |
'extension_spec' => array(
|
| 9442 |
+
'name' => 'amp-addthis',
|
| 9443 |
+
'version' => array(
|
| 9444 |
'0.1',
|
| 9445 |
'latest',
|
| 9446 |
),
|
| 9447 |
+
),
|
| 9448 |
+
),
|
| 9449 |
+
),
|
| 9450 |
+
array(
|
| 9451 |
+
'attr_spec_list' => array(
|
| 9452 |
+
'async' => array(
|
| 9453 |
+
'mandatory' => true,
|
| 9454 |
+
'value' => array(
|
| 9455 |
+
'',
|
| 9456 |
+
),
|
| 9457 |
+
),
|
| 9458 |
+
'nonce' => array(),
|
| 9459 |
+
'type' => array(
|
| 9460 |
+
'value_casei' => array(
|
| 9461 |
+
'text/javascript',
|
| 9462 |
+
),
|
| 9463 |
+
),
|
| 9464 |
+
),
|
| 9465 |
+
'tag_spec' => array(
|
| 9466 |
+
'extension_spec' => array(
|
| 9467 |
'deprecated_allow_duplicates' => true,
|
| 9468 |
'name' => 'amp-analytics',
|
| 9469 |
'requires_usage' => 2,
|
| 9470 |
+
'version' => array(
|
| 9471 |
+
'0.1',
|
| 9472 |
+
'latest',
|
| 9473 |
+
),
|
| 9474 |
),
|
| 9475 |
),
|
| 9476 |
),
|
| 9480 |
'type' => array(
|
| 9481 |
'dispatch_key' => 3,
|
| 9482 |
'mandatory' => true,
|
| 9483 |
+
'value_casei' => array(
|
| 9484 |
+
'application/json',
|
| 9485 |
+
),
|
| 9486 |
),
|
| 9487 |
),
|
| 9488 |
'cdata' => array(
|
| 9504 |
'attr_spec_list' => array(
|
| 9505 |
'async' => array(
|
| 9506 |
'mandatory' => true,
|
| 9507 |
+
'value' => array(
|
| 9508 |
+
'',
|
| 9509 |
+
),
|
| 9510 |
),
|
| 9511 |
'nonce' => array(),
|
| 9512 |
'type' => array(
|
| 9513 |
+
'value_casei' => array(
|
| 9514 |
+
'text/javascript',
|
| 9515 |
+
),
|
| 9516 |
),
|
| 9517 |
),
|
| 9518 |
'tag_spec' => array(
|
| 9519 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9520 |
'deprecated_allow_duplicates' => true,
|
| 9521 |
'name' => 'amp-anim',
|
| 9522 |
'requires_usage' => 2,
|
| 9523 |
+
'version' => array(
|
| 9524 |
+
'0.1',
|
| 9525 |
+
'latest',
|
| 9526 |
+
),
|
| 9527 |
),
|
| 9528 |
),
|
| 9529 |
),
|
| 9531 |
'attr_spec_list' => array(
|
| 9532 |
'async' => array(
|
| 9533 |
'mandatory' => true,
|
| 9534 |
+
'value' => array(
|
| 9535 |
+
'',
|
| 9536 |
+
),
|
| 9537 |
),
|
| 9538 |
'nonce' => array(),
|
| 9539 |
'type' => array(
|
| 9540 |
+
'value_casei' => array(
|
| 9541 |
+
'text/javascript',
|
| 9542 |
+
),
|
| 9543 |
),
|
| 9544 |
),
|
| 9545 |
'tag_spec' => array(
|
| 9546 |
'extension_spec' => array(
|
| 9547 |
+
'name' => 'amp-animation',
|
| 9548 |
+
'version' => array(
|
| 9549 |
'0.1',
|
| 9550 |
'latest',
|
| 9551 |
),
|
|
|
|
| 9552 |
),
|
| 9553 |
),
|
| 9554 |
),
|
| 9558 |
'type' => array(
|
| 9559 |
'dispatch_key' => 3,
|
| 9560 |
'mandatory' => true,
|
| 9561 |
+
'value_casei' => array(
|
| 9562 |
+
'application/json',
|
| 9563 |
+
),
|
| 9564 |
),
|
| 9565 |
),
|
| 9566 |
'cdata' => array(
|
| 9581 |
'attr_spec_list' => array(
|
| 9582 |
'async' => array(
|
| 9583 |
'mandatory' => true,
|
| 9584 |
+
'value' => array(
|
| 9585 |
+
'',
|
| 9586 |
+
),
|
| 9587 |
),
|
| 9588 |
'nonce' => array(),
|
| 9589 |
'type' => array(
|
| 9590 |
+
'value_casei' => array(
|
| 9591 |
+
'text/javascript',
|
| 9592 |
+
),
|
| 9593 |
),
|
| 9594 |
),
|
| 9595 |
'tag_spec' => array(
|
| 9596 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9597 |
'deprecated_allow_duplicates' => true,
|
| 9598 |
'name' => 'amp-apester-media',
|
| 9599 |
'requires_usage' => 2,
|
| 9600 |
+
'version' => array(
|
| 9601 |
+
'0.1',
|
| 9602 |
+
'latest',
|
| 9603 |
+
),
|
| 9604 |
),
|
| 9605 |
),
|
| 9606 |
),
|
| 9608 |
'attr_spec_list' => array(
|
| 9609 |
'async' => array(
|
| 9610 |
'mandatory' => true,
|
| 9611 |
+
'value' => array(
|
| 9612 |
+
'',
|
| 9613 |
+
),
|
| 9614 |
),
|
| 9615 |
'nonce' => array(),
|
| 9616 |
'type' => array(
|
| 9617 |
+
'value_casei' => array(
|
| 9618 |
+
'text/javascript',
|
| 9619 |
+
),
|
| 9620 |
),
|
| 9621 |
),
|
| 9622 |
'tag_spec' => array(
|
| 9623 |
'extension_spec' => array(
|
| 9624 |
+
'deprecated_allow_duplicates' => true,
|
| 9625 |
+
'name' => 'amp-app-banner',
|
| 9626 |
+
'version' => array(
|
| 9627 |
'0.1',
|
| 9628 |
'latest',
|
| 9629 |
),
|
|
|
|
|
|
|
| 9630 |
),
|
| 9631 |
),
|
| 9632 |
),
|
| 9634 |
'attr_spec_list' => array(
|
| 9635 |
'async' => array(
|
| 9636 |
'mandatory' => true,
|
| 9637 |
+
'value' => array(
|
| 9638 |
+
'',
|
| 9639 |
+
),
|
| 9640 |
),
|
| 9641 |
'nonce' => array(),
|
| 9642 |
'type' => array(
|
| 9643 |
+
'value_casei' => array(
|
| 9644 |
+
'text/javascript',
|
| 9645 |
+
),
|
| 9646 |
),
|
| 9647 |
),
|
| 9648 |
'tag_spec' => array(
|
| 9649 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9650 |
'deprecated_allow_duplicates' => true,
|
| 9651 |
'name' => 'amp-audio',
|
| 9652 |
'requires_usage' => 2,
|
| 9653 |
+
'version' => array(
|
| 9654 |
+
'0.1',
|
| 9655 |
+
'latest',
|
| 9656 |
+
),
|
| 9657 |
),
|
| 9658 |
),
|
| 9659 |
),
|
| 9661 |
'attr_spec_list' => array(
|
| 9662 |
'async' => array(
|
| 9663 |
'mandatory' => true,
|
| 9664 |
+
'value' => array(
|
| 9665 |
+
'',
|
| 9666 |
+
),
|
| 9667 |
),
|
| 9668 |
'nonce' => array(),
|
| 9669 |
'type' => array(
|
| 9670 |
+
'value_casei' => array(
|
| 9671 |
+
'text/javascript',
|
| 9672 |
+
),
|
| 9673 |
),
|
| 9674 |
),
|
| 9675 |
'tag_spec' => array(
|
| 9676 |
'extension_spec' => array(
|
| 9677 |
+
'name' => 'amp-auto-ads',
|
| 9678 |
+
'version' => array(
|
| 9679 |
'0.1',
|
| 9680 |
'latest',
|
| 9681 |
),
|
|
|
|
| 9682 |
),
|
| 9683 |
),
|
| 9684 |
),
|
| 9686 |
'attr_spec_list' => array(
|
| 9687 |
'async' => array(
|
| 9688 |
'mandatory' => true,
|
| 9689 |
+
'value' => array(
|
| 9690 |
+
'',
|
| 9691 |
+
),
|
| 9692 |
),
|
| 9693 |
'nonce' => array(),
|
| 9694 |
'type' => array(
|
| 9695 |
+
'value_casei' => array(
|
| 9696 |
+
'text/javascript',
|
| 9697 |
+
),
|
| 9698 |
),
|
| 9699 |
),
|
| 9700 |
'tag_spec' => array(
|
| 9701 |
'extension_spec' => array(
|
| 9702 |
+
'name' => 'amp-beopinion',
|
| 9703 |
+
'version' => array(
|
| 9704 |
'0.1',
|
| 9705 |
'latest',
|
| 9706 |
),
|
|
|
|
| 9707 |
),
|
| 9708 |
),
|
| 9709 |
),
|
| 9711 |
'attr_spec_list' => array(
|
| 9712 |
'async' => array(
|
| 9713 |
'mandatory' => true,
|
| 9714 |
+
'value' => array(
|
| 9715 |
+
'',
|
| 9716 |
+
),
|
| 9717 |
),
|
| 9718 |
'nonce' => array(),
|
| 9719 |
'type' => array(
|
| 9720 |
+
'value_casei' => array(
|
| 9721 |
+
'text/javascript',
|
| 9722 |
+
),
|
| 9723 |
),
|
| 9724 |
),
|
| 9725 |
'tag_spec' => array(
|
| 9726 |
'extension_spec' => array(
|
| 9727 |
+
'name' => 'amp-bind',
|
| 9728 |
+
'requires_usage' => 3,
|
| 9729 |
+
'version' => array(
|
| 9730 |
'0.1',
|
| 9731 |
'latest',
|
| 9732 |
),
|
|
|
|
|
|
|
| 9733 |
),
|
| 9734 |
),
|
| 9735 |
),
|
| 9739 |
'type' => array(
|
| 9740 |
'dispatch_key' => 3,
|
| 9741 |
'mandatory' => true,
|
| 9742 |
+
'value_casei' => array(
|
| 9743 |
+
'application/json',
|
| 9744 |
+
),
|
| 9745 |
),
|
| 9746 |
),
|
| 9747 |
'cdata' => array(
|
| 9749 |
'error_message' => 'html comments',
|
| 9750 |
'regex' => '<!--',
|
| 9751 |
),
|
| 9752 |
+
'max_bytes' => 100000,
|
| 9753 |
+
'max_bytes_spec_url' => 'https://www.ampproject.org/docs/reference/components/dynamic/amp-bind#state',
|
| 9754 |
),
|
| 9755 |
'tag_spec' => array(
|
| 9756 |
'mandatory_parent' => 'amp-state',
|
| 9765 |
'attr_spec_list' => array(
|
| 9766 |
'async' => array(
|
| 9767 |
'mandatory' => true,
|
| 9768 |
+
'value' => array(
|
| 9769 |
+
'',
|
| 9770 |
+
),
|
| 9771 |
),
|
| 9772 |
'nonce' => array(),
|
| 9773 |
'type' => array(
|
| 9774 |
+
'value_casei' => array(
|
| 9775 |
+
'text/javascript',
|
| 9776 |
+
),
|
| 9777 |
),
|
| 9778 |
),
|
| 9779 |
'tag_spec' => array(
|
| 9780 |
'extension_spec' => array(
|
| 9781 |
+
'name' => 'amp-bodymovin-animation',
|
| 9782 |
+
'version' => array(
|
| 9783 |
'0.1',
|
| 9784 |
'latest',
|
| 9785 |
),
|
|
|
|
| 9786 |
),
|
| 9787 |
),
|
| 9788 |
),
|
| 9790 |
'attr_spec_list' => array(
|
| 9791 |
'async' => array(
|
| 9792 |
'mandatory' => true,
|
| 9793 |
+
'value' => array(
|
| 9794 |
+
'',
|
| 9795 |
+
),
|
| 9796 |
),
|
| 9797 |
'nonce' => array(),
|
| 9798 |
'type' => array(
|
| 9799 |
+
'value_casei' => array(
|
| 9800 |
+
'text/javascript',
|
| 9801 |
+
),
|
| 9802 |
),
|
| 9803 |
),
|
| 9804 |
'tag_spec' => array(
|
| 9805 |
'extension_spec' => array(
|
| 9806 |
+
'deprecated_allow_duplicates' => true,
|
| 9807 |
+
'name' => 'amp-brid-player',
|
| 9808 |
+
'requires_usage' => 2,
|
| 9809 |
+
'version' => array(
|
| 9810 |
'0.1',
|
| 9811 |
'latest',
|
| 9812 |
),
|
| 9813 |
+
),
|
| 9814 |
+
),
|
| 9815 |
+
),
|
| 9816 |
+
array(
|
| 9817 |
+
'attr_spec_list' => array(
|
| 9818 |
+
'async' => array(
|
| 9819 |
+
'mandatory' => true,
|
| 9820 |
+
'value' => array(
|
| 9821 |
+
'',
|
| 9822 |
+
),
|
| 9823 |
+
),
|
| 9824 |
+
'nonce' => array(),
|
| 9825 |
+
'type' => array(
|
| 9826 |
+
'value_casei' => array(
|
| 9827 |
+
'text/javascript',
|
| 9828 |
+
),
|
| 9829 |
+
),
|
| 9830 |
+
),
|
| 9831 |
+
'tag_spec' => array(
|
| 9832 |
+
'extension_spec' => array(
|
| 9833 |
'deprecated_allow_duplicates' => true,
|
| 9834 |
+
'name' => 'amp-brightcove',
|
| 9835 |
'requires_usage' => 2,
|
| 9836 |
+
'version' => array(
|
| 9837 |
+
'0.1',
|
| 9838 |
+
'latest',
|
| 9839 |
+
),
|
| 9840 |
),
|
| 9841 |
),
|
| 9842 |
),
|
| 9844 |
'attr_spec_list' => array(
|
| 9845 |
'async' => array(
|
| 9846 |
'mandatory' => true,
|
| 9847 |
+
'value' => array(
|
| 9848 |
+
'',
|
| 9849 |
+
),
|
| 9850 |
),
|
| 9851 |
'nonce' => array(),
|
| 9852 |
'type' => array(
|
| 9853 |
+
'value_casei' => array(
|
| 9854 |
+
'text/javascript',
|
| 9855 |
+
),
|
| 9856 |
),
|
| 9857 |
),
|
| 9858 |
'tag_spec' => array(
|
| 9859 |
'extension_spec' => array(
|
| 9860 |
+
'name' => 'amp-byside-content',
|
| 9861 |
+
'version' => array(
|
| 9862 |
'0.1',
|
| 9863 |
'latest',
|
| 9864 |
),
|
| 9865 |
+
),
|
| 9866 |
+
),
|
| 9867 |
+
),
|
| 9868 |
+
array(
|
| 9869 |
+
'attr_spec_list' => array(
|
| 9870 |
+
'async' => array(
|
| 9871 |
+
'mandatory' => true,
|
| 9872 |
+
'value' => array(
|
| 9873 |
+
'',
|
| 9874 |
+
),
|
| 9875 |
+
),
|
| 9876 |
+
'nonce' => array(),
|
| 9877 |
+
'type' => array(
|
| 9878 |
+
'value_casei' => array(
|
| 9879 |
+
'text/javascript',
|
| 9880 |
+
),
|
| 9881 |
+
),
|
| 9882 |
+
),
|
| 9883 |
+
'tag_spec' => array(
|
| 9884 |
+
'extension_spec' => array(
|
| 9885 |
+
'name' => 'amp-call-tracking',
|
| 9886 |
'requires_usage' => 2,
|
| 9887 |
+
'version' => array(
|
| 9888 |
+
'0.1',
|
| 9889 |
+
'latest',
|
| 9890 |
+
),
|
| 9891 |
),
|
| 9892 |
),
|
| 9893 |
),
|
| 9895 |
'attr_spec_list' => array(
|
| 9896 |
'async' => array(
|
| 9897 |
'mandatory' => true,
|
| 9898 |
+
'value' => array(
|
| 9899 |
+
'',
|
| 9900 |
+
),
|
| 9901 |
),
|
| 9902 |
'nonce' => array(),
|
| 9903 |
'type' => array(
|
| 9904 |
+
'value_casei' => array(
|
| 9905 |
+
'text/javascript',
|
| 9906 |
+
),
|
| 9907 |
),
|
| 9908 |
),
|
| 9909 |
'tag_spec' => array(
|
| 9910 |
'extension_spec' => array(
|
| 9911 |
+
'deprecated_allow_duplicates' => true,
|
| 9912 |
+
'name' => 'amp-carousel',
|
| 9913 |
+
'requires_usage' => 2,
|
| 9914 |
+
'version' => array(
|
| 9915 |
'0.1',
|
| 9916 |
'latest',
|
| 9917 |
),
|
|
|
|
| 9918 |
),
|
| 9919 |
),
|
| 9920 |
),
|
| 9922 |
'attr_spec_list' => array(
|
| 9923 |
'async' => array(
|
| 9924 |
'mandatory' => true,
|
| 9925 |
+
'value' => array(
|
| 9926 |
+
'',
|
| 9927 |
+
),
|
| 9928 |
),
|
| 9929 |
'nonce' => array(),
|
| 9930 |
'type' => array(
|
| 9931 |
+
'value_casei' => array(
|
| 9932 |
+
'text/javascript',
|
| 9933 |
+
),
|
| 9934 |
),
|
| 9935 |
),
|
| 9936 |
'tag_spec' => array(
|
| 9937 |
'extension_spec' => array(
|
| 9938 |
+
'name' => 'amp-consent',
|
| 9939 |
+
'version' => array(
|
| 9940 |
'0.1',
|
| 9941 |
'latest',
|
| 9942 |
),
|
| 9943 |
+
),
|
| 9944 |
+
),
|
| 9945 |
+
),
|
| 9946 |
+
array(
|
| 9947 |
+
'attr_spec_list' => array(
|
| 9948 |
+
'nonce' => array(),
|
| 9949 |
+
'type' => array(
|
| 9950 |
+
'dispatch_key' => 3,
|
| 9951 |
+
'mandatory' => true,
|
| 9952 |
+
'value_casei' => array(
|
| 9953 |
+
'application/json',
|
| 9954 |
+
),
|
| 9955 |
+
),
|
| 9956 |
+
),
|
| 9957 |
+
'cdata' => array(
|
| 9958 |
+
'blacklisted_cdata_regex' => array(
|
| 9959 |
+
'error_message' => 'html comments',
|
| 9960 |
+
'regex' => '<!--',
|
| 9961 |
+
),
|
| 9962 |
+
),
|
| 9963 |
+
'tag_spec' => array(
|
| 9964 |
+
'mandatory_parent' => 'amp-consent',
|
| 9965 |
+
'requires_extension' => array(
|
| 9966 |
+
'amp-consent',
|
| 9967 |
+
),
|
| 9968 |
+
'spec_name' => 'amp-consent extension .json script',
|
| 9969 |
+
'unique' => true,
|
| 9970 |
+
),
|
| 9971 |
+
),
|
| 9972 |
+
array(
|
| 9973 |
+
'attr_spec_list' => array(
|
| 9974 |
+
'async' => array(
|
| 9975 |
+
'mandatory' => true,
|
| 9976 |
+
'value' => array(
|
| 9977 |
+
'',
|
| 9978 |
+
),
|
| 9979 |
+
),
|
| 9980 |
+
'nonce' => array(),
|
| 9981 |
+
'type' => array(
|
| 9982 |
+
'value_casei' => array(
|
| 9983 |
+
'text/javascript',
|
| 9984 |
+
),
|
| 9985 |
+
),
|
| 9986 |
+
),
|
| 9987 |
+
'tag_spec' => array(
|
| 9988 |
+
'extension_spec' => array(
|
| 9989 |
+
'deprecated_allow_duplicates' => true,
|
| 9990 |
+
'name' => 'amp-dailymotion',
|
| 9991 |
'requires_usage' => 2,
|
| 9992 |
+
'version' => array(
|
| 9993 |
+
'0.1',
|
| 9994 |
+
'latest',
|
| 9995 |
+
),
|
| 9996 |
),
|
| 9997 |
),
|
| 9998 |
),
|
| 10000 |
'attr_spec_list' => array(
|
| 10001 |
'async' => array(
|
| 10002 |
'mandatory' => true,
|
| 10003 |
+
'value' => array(
|
| 10004 |
+
'',
|
| 10005 |
+
),
|
| 10006 |
),
|
| 10007 |
'nonce' => array(),
|
| 10008 |
'type' => array(
|
| 10009 |
+
'value_casei' => array(
|
| 10010 |
+
'text/javascript',
|
| 10011 |
+
),
|
| 10012 |
),
|
| 10013 |
),
|
| 10014 |
'tag_spec' => array(
|
| 10015 |
'extension_spec' => array(
|
| 10016 |
+
'name' => 'amp-date-countdown',
|
| 10017 |
+
'version' => array(
|
| 10018 |
'0.1',
|
| 10019 |
'latest',
|
| 10020 |
),
|
| 10021 |
+
),
|
| 10022 |
+
),
|
| 10023 |
+
),
|
| 10024 |
+
array(
|
| 10025 |
+
'attr_spec_list' => array(
|
| 10026 |
+
'async' => array(
|
| 10027 |
+
'mandatory' => true,
|
| 10028 |
+
'value' => array(
|
| 10029 |
+
'',
|
| 10030 |
+
),
|
| 10031 |
+
),
|
| 10032 |
+
'nonce' => array(),
|
| 10033 |
+
'type' => array(
|
| 10034 |
+
'value_casei' => array(
|
| 10035 |
+
'text/javascript',
|
| 10036 |
+
),
|
| 10037 |
+
),
|
| 10038 |
+
),
|
| 10039 |
+
'tag_spec' => array(
|
| 10040 |
+
'extension_spec' => array(
|
| 10041 |
+
'name' => 'amp-date-picker',
|
| 10042 |
+
'version' => array(
|
| 10043 |
+
'0.1',
|
| 10044 |
+
'latest',
|
| 10045 |
+
),
|
| 10046 |
+
),
|
| 10047 |
+
),
|
| 10048 |
+
),
|
| 10049 |
+
array(
|
| 10050 |
+
'attr_spec_list' => array(
|
| 10051 |
+
'async' => array(
|
| 10052 |
+
'mandatory' => true,
|
| 10053 |
+
'value' => array(
|
| 10054 |
+
'',
|
| 10055 |
+
),
|
| 10056 |
+
),
|
| 10057 |
+
'nonce' => array(),
|
| 10058 |
+
'type' => array(
|
| 10059 |
+
'value_casei' => array(
|
| 10060 |
+
'text/javascript',
|
| 10061 |
+
),
|
| 10062 |
+
),
|
| 10063 |
+
),
|
| 10064 |
+
'tag_spec' => array(
|
| 10065 |
+
'extension_spec' => array(
|
| 10066 |
+
'name' => 'amp-delight-player',
|
| 10067 |
+
'version' => array(
|
| 10068 |
+
'0.1',
|
| 10069 |
+
'latest',
|
| 10070 |
+
),
|
| 10071 |
+
),
|
| 10072 |
+
),
|
| 10073 |
+
),
|
| 10074 |
+
array(
|
| 10075 |
+
'attr_spec_list' => array(
|
| 10076 |
+
'async' => array(
|
| 10077 |
+
'mandatory' => true,
|
| 10078 |
+
'value' => array(
|
| 10079 |
+
'',
|
| 10080 |
+
),
|
| 10081 |
+
),
|
| 10082 |
+
'nonce' => array(),
|
| 10083 |
+
'type' => array(
|
| 10084 |
+
'value_casei' => array(
|
| 10085 |
+
'text/javascript',
|
| 10086 |
+
),
|
| 10087 |
+
),
|
| 10088 |
+
),
|
| 10089 |
+
'tag_spec' => array(
|
| 10090 |
+
'extension_spec' => array(
|
| 10091 |
'deprecated_allow_duplicates' => true,
|
| 10092 |
+
'name' => 'amp-dynamic-css-classes',
|
| 10093 |
+
'requires_usage' => 3,
|
| 10094 |
+
'version' => array(
|
| 10095 |
+
'0.1',
|
| 10096 |
+
'latest',
|
| 10097 |
+
),
|
| 10098 |
+
),
|
| 10099 |
+
),
|
| 10100 |
+
),
|
| 10101 |
+
array(
|
| 10102 |
+
'attr_spec_list' => array(
|
| 10103 |
+
'async' => array(
|
| 10104 |
+
'mandatory' => true,
|
| 10105 |
+
'value' => array(
|
| 10106 |
+
'',
|
| 10107 |
+
),
|
| 10108 |
+
),
|
| 10109 |
+
'nonce' => array(),
|
| 10110 |
+
'type' => array(
|
| 10111 |
+
'value_casei' => array(
|
| 10112 |
+
'text/javascript',
|
| 10113 |
+
),
|
| 10114 |
+
),
|
| 10115 |
+
),
|
| 10116 |
+
'tag_spec' => array(
|
| 10117 |
+
'extension_spec' => array(
|
| 10118 |
+
'name' => 'amp-embedly-card',
|
| 10119 |
+
'version' => array(
|
| 10120 |
+
'0.1',
|
| 10121 |
+
'latest',
|
| 10122 |
+
),
|
| 10123 |
+
),
|
| 10124 |
+
),
|
| 10125 |
+
),
|
| 10126 |
+
array(
|
| 10127 |
+
'attr_spec_list' => array(
|
| 10128 |
+
'async' => array(
|
| 10129 |
+
'mandatory' => true,
|
| 10130 |
+
'value' => array(
|
| 10131 |
+
'',
|
| 10132 |
+
),
|
| 10133 |
+
),
|
| 10134 |
+
'nonce' => array(),
|
| 10135 |
+
'type' => array(
|
| 10136 |
+
'value_casei' => array(
|
| 10137 |
+
'text/javascript',
|
| 10138 |
+
),
|
| 10139 |
+
),
|
| 10140 |
+
),
|
| 10141 |
+
'tag_spec' => array(
|
| 10142 |
+
'extension_spec' => array(
|
| 10143 |
+
'deprecated_allow_duplicates' => true,
|
| 10144 |
+
'name' => 'amp-experiment',
|
| 10145 |
'requires_usage' => 2,
|
| 10146 |
+
'version' => array(
|
| 10147 |
+
'0.1',
|
| 10148 |
+
'latest',
|
| 10149 |
+
),
|
| 10150 |
+
),
|
| 10151 |
+
),
|
| 10152 |
+
),
|
| 10153 |
+
array(
|
| 10154 |
+
'attr_spec_list' => array(
|
| 10155 |
+
'nonce' => array(),
|
| 10156 |
+
'type' => array(
|
| 10157 |
+
'dispatch_key' => 3,
|
| 10158 |
+
'mandatory' => true,
|
| 10159 |
+
'value_casei' => array(
|
| 10160 |
+
'application/json',
|
| 10161 |
+
),
|
| 10162 |
+
),
|
| 10163 |
+
),
|
| 10164 |
+
'cdata' => array(
|
| 10165 |
+
'blacklisted_cdata_regex' => array(
|
| 10166 |
+
'error_message' => 'html comments',
|
| 10167 |
+
'regex' => '<!--',
|
| 10168 |
+
),
|
| 10169 |
+
),
|
| 10170 |
+
'tag_spec' => array(
|
| 10171 |
+
'mandatory_parent' => 'amp-experiment',
|
| 10172 |
+
'spec_name' => 'amp-experiment extension .json script',
|
| 10173 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-experiment',
|
| 10174 |
+
),
|
| 10175 |
+
),
|
| 10176 |
+
array(
|
| 10177 |
+
'attr_spec_list' => array(
|
| 10178 |
+
'async' => array(
|
| 10179 |
+
'mandatory' => true,
|
| 10180 |
+
'value' => array(
|
| 10181 |
+
'',
|
| 10182 |
+
),
|
| 10183 |
+
),
|
| 10184 |
+
'nonce' => array(),
|
| 10185 |
+
'type' => array(
|
| 10186 |
+
'value_casei' => array(
|
| 10187 |
+
'text/javascript',
|
| 10188 |
+
),
|
| 10189 |
+
),
|
| 10190 |
+
),
|
| 10191 |
+
'tag_spec' => array(
|
| 10192 |
+
'extension_spec' => array(
|
| 10193 |
+
'name' => 'amp-facebook-comments',
|
| 10194 |
+
'version' => array(
|
| 10195 |
+
'0.1',
|
| 10196 |
+
'latest',
|
| 10197 |
+
),
|
| 10198 |
+
),
|
| 10199 |
+
),
|
| 10200 |
+
),
|
| 10201 |
+
array(
|
| 10202 |
+
'attr_spec_list' => array(
|
| 10203 |
+
'async' => array(
|
| 10204 |
+
'mandatory' => true,
|
| 10205 |
+
'value' => array(
|
| 10206 |
+
'',
|
| 10207 |
+
),
|
| 10208 |
+
),
|
| 10209 |
+
'nonce' => array(),
|
| 10210 |
+
'type' => array(
|
| 10211 |
+
'value_casei' => array(
|
| 10212 |
+
'text/javascript',
|
| 10213 |
+
),
|
| 10214 |
+
),
|
| 10215 |
+
),
|
| 10216 |
+
'tag_spec' => array(
|
| 10217 |
+
'extension_spec' => array(
|
| 10218 |
+
'name' => 'amp-facebook-like',
|
| 10219 |
+
'version' => array(
|
| 10220 |
+
'0.1',
|
| 10221 |
+
'latest',
|
| 10222 |
+
),
|
| 10223 |
),
|
| 10224 |
),
|
| 10225 |
),
|
| 10227 |
'attr_spec_list' => array(
|
| 10228 |
'async' => array(
|
| 10229 |
'mandatory' => true,
|
| 10230 |
+
'value' => array(
|
| 10231 |
+
'',
|
| 10232 |
+
),
|
| 10233 |
),
|
| 10234 |
'nonce' => array(),
|
| 10235 |
'type' => array(
|
| 10236 |
+
'value_casei' => array(
|
| 10237 |
+
'text/javascript',
|
| 10238 |
+
),
|
| 10239 |
),
|
| 10240 |
),
|
| 10241 |
'tag_spec' => array(
|
| 10242 |
'extension_spec' => array(
|
| 10243 |
+
'name' => 'amp-facebook-page',
|
| 10244 |
+
'version' => array(
|
| 10245 |
'0.1',
|
| 10246 |
'latest',
|
| 10247 |
),
|
|
|
|
| 10248 |
),
|
| 10249 |
),
|
| 10250 |
),
|
| 10251 |
array(
|
| 10252 |
'attr_spec_list' => array(
|
| 10253 |
+
'async' => array(
|
|
|
|
|
|
|
| 10254 |
'mandatory' => true,
|
| 10255 |
+
'value' => array(
|
| 10256 |
+
'',
|
| 10257 |
+
),
|
| 10258 |
),
|
| 10259 |
+
'nonce' => array(),
|
| 10260 |
+
'type' => array(
|
| 10261 |
+
'value_casei' => array(
|
| 10262 |
+
'text/javascript',
|
| 10263 |
+
),
|
| 10264 |
),
|
| 10265 |
),
|
| 10266 |
'tag_spec' => array(
|
| 10267 |
+
'extension_spec' => array(
|
| 10268 |
+
'deprecated_allow_duplicates' => true,
|
| 10269 |
+
'name' => 'amp-facebook',
|
| 10270 |
+
'requires_usage' => 2,
|
| 10271 |
+
'version' => array(
|
| 10272 |
+
'0.1',
|
| 10273 |
+
'latest',
|
| 10274 |
+
),
|
| 10275 |
),
|
|
|
|
|
|
|
| 10276 |
),
|
| 10277 |
),
|
| 10278 |
array(
|
| 10279 |
'attr_spec_list' => array(
|
| 10280 |
'async' => array(
|
| 10281 |
'mandatory' => true,
|
| 10282 |
+
'value' => array(
|
| 10283 |
+
'',
|
| 10284 |
+
),
|
| 10285 |
),
|
| 10286 |
'nonce' => array(),
|
| 10287 |
'type' => array(
|
| 10288 |
+
'value_casei' => array(
|
| 10289 |
+
'text/javascript',
|
| 10290 |
+
),
|
| 10291 |
),
|
| 10292 |
),
|
| 10293 |
'tag_spec' => array(
|
| 10294 |
'extension_spec' => array(
|
| 10295 |
+
'deprecated_allow_duplicates' => true,
|
| 10296 |
+
'name' => 'amp-fit-text',
|
| 10297 |
+
'requires_usage' => 2,
|
| 10298 |
+
'version' => array(
|
| 10299 |
'0.1',
|
| 10300 |
'latest',
|
| 10301 |
),
|
|
|
|
|
|
|
|
|
|
| 10302 |
),
|
| 10303 |
),
|
| 10304 |
),
|
| 10306 |
'attr_spec_list' => array(
|
| 10307 |
'async' => array(
|
| 10308 |
'mandatory' => true,
|
| 10309 |
+
'value' => array(
|
| 10310 |
+
'',
|
| 10311 |
+
),
|
| 10312 |
),
|
| 10313 |
'nonce' => array(),
|
| 10314 |
'type' => array(
|
| 10315 |
+
'value_casei' => array(
|
| 10316 |
+
'text/javascript',
|
| 10317 |
+
),
|
| 10318 |
),
|
| 10319 |
),
|
| 10320 |
'tag_spec' => array(
|
| 10321 |
'extension_spec' => array(
|
| 10322 |
+
'deprecated_allow_duplicates' => true,
|
| 10323 |
+
'name' => 'amp-font',
|
| 10324 |
+
'requires_usage' => 2,
|
| 10325 |
+
'version' => array(
|
| 10326 |
'0.1',
|
| 10327 |
'latest',
|
| 10328 |
),
|
|
|
|
| 10329 |
),
|
| 10330 |
),
|
| 10331 |
),
|
| 10332 |
array(
|
| 10333 |
+
'attr_spec_list' => array(
|
| 10334 |
+
'async' => array(
|
| 10335 |
+
'mandatory' => true,
|
| 10336 |
+
'value' => array(
|
| 10337 |
+
'',
|
| 10338 |
+
),
|
| 10339 |
+
),
|
| 10340 |
+
'nonce' => array(),
|
| 10341 |
+
'type' => array(
|
| 10342 |
+
'value_casei' => array(
|
| 10343 |
+
'text/javascript',
|
| 10344 |
+
),
|
| 10345 |
+
),
|
| 10346 |
+
),
|
| 10347 |
'tag_spec' => array(
|
| 10348 |
'extension_spec' => array(
|
| 10349 |
+
'deprecated_allow_duplicates' => true,
|
| 10350 |
+
'name' => 'amp-form',
|
| 10351 |
+
'requires_usage' => 2,
|
| 10352 |
+
'version' => array(
|
| 10353 |
'0.1',
|
| 10354 |
'latest',
|
| 10355 |
),
|
|
|
|
| 10356 |
),
|
| 10357 |
),
|
| 10358 |
),
|
| 10359 |
array(
|
| 10360 |
'attr_spec_list' => array(
|
| 10361 |
+
'async' => array(
|
|
|
|
| 10362 |
'mandatory' => true,
|
| 10363 |
+
'value' => array(
|
| 10364 |
+
'',
|
| 10365 |
+
),
|
| 10366 |
+
),
|
| 10367 |
+
'nonce' => array(),
|
| 10368 |
+
'type' => array(
|
| 10369 |
+
'value_casei' => array(
|
| 10370 |
+
'text/javascript',
|
| 10371 |
+
),
|
| 10372 |
),
|
| 10373 |
),
|
| 10374 |
'tag_spec' => array(
|
| 10375 |
+
'extension_spec' => array(
|
| 10376 |
+
'name' => 'amp-fx-collection',
|
| 10377 |
+
'requires_usage' => 3,
|
| 10378 |
+
'version' => array(
|
| 10379 |
+
'0.1',
|
| 10380 |
+
'latest',
|
| 10381 |
+
),
|
| 10382 |
),
|
|
|
|
|
|
|
| 10383 |
),
|
| 10384 |
),
|
| 10385 |
array(
|
| 10386 |
'attr_spec_list' => array(
|
| 10387 |
'async' => array(
|
| 10388 |
'mandatory' => true,
|
| 10389 |
+
'value' => array(
|
| 10390 |
+
'',
|
| 10391 |
+
),
|
| 10392 |
),
|
| 10393 |
'nonce' => array(),
|
| 10394 |
'type' => array(
|
| 10395 |
+
'value_casei' => array(
|
| 10396 |
+
'text/javascript',
|
| 10397 |
+
),
|
| 10398 |
),
|
| 10399 |
),
|
| 10400 |
'tag_spec' => array(
|
| 10401 |
'extension_spec' => array(
|
| 10402 |
+
'deprecated_allow_duplicates' => true,
|
| 10403 |
+
'name' => 'amp-fx-flying-carpet',
|
| 10404 |
+
'requires_usage' => 2,
|
| 10405 |
+
'version' => array(
|
| 10406 |
'0.1',
|
| 10407 |
'latest',
|
| 10408 |
),
|
|
|
|
|
|
|
|
|
|
| 10409 |
),
|
| 10410 |
),
|
| 10411 |
),
|
| 10413 |
'attr_spec_list' => array(
|
| 10414 |
'async' => array(
|
| 10415 |
'mandatory' => true,
|
| 10416 |
+
'value' => array(
|
| 10417 |
+
'',
|
| 10418 |
+
),
|
| 10419 |
),
|
| 10420 |
'nonce' => array(),
|
| 10421 |
'type' => array(
|
| 10422 |
+
'value_casei' => array(
|
| 10423 |
+
'text/javascript',
|
| 10424 |
+
),
|
| 10425 |
),
|
| 10426 |
),
|
| 10427 |
'tag_spec' => array(
|
| 10428 |
'extension_spec' => array(
|
| 10429 |
+
'name' => 'amp-geo',
|
| 10430 |
+
'version' => array(
|
| 10431 |
'0.1',
|
| 10432 |
'latest',
|
| 10433 |
),
|
|
|
|
|
|
|
|
|
|
| 10434 |
),
|
| 10435 |
),
|
| 10436 |
),
|
| 10440 |
'type' => array(
|
| 10441 |
'dispatch_key' => 3,
|
| 10442 |
'mandatory' => true,
|
| 10443 |
+
'value_casei' => array(
|
| 10444 |
+
'application/json',
|
| 10445 |
+
),
|
| 10446 |
),
|
| 10447 |
),
|
| 10448 |
'cdata' => array(
|
| 10452 |
),
|
| 10453 |
),
|
| 10454 |
'tag_spec' => array(
|
| 10455 |
+
'mandatory_parent' => 'amp-geo',
|
| 10456 |
+
'requires_extension' => array(
|
| 10457 |
+
'amp-geo',
|
| 10458 |
+
),
|
| 10459 |
+
'spec_name' => 'amp-geo extension .json script',
|
| 10460 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-geo',
|
| 10461 |
),
|
| 10462 |
),
|
| 10463 |
array(
|
| 10464 |
'attr_spec_list' => array(
|
| 10465 |
'async' => array(
|
| 10466 |
'mandatory' => true,
|
| 10467 |
+
'value' => array(
|
| 10468 |
+
'',
|
| 10469 |
+
),
|
| 10470 |
),
|
| 10471 |
'nonce' => array(),
|
| 10472 |
'type' => array(
|
| 10473 |
+
'value_casei' => array(
|
| 10474 |
+
'text/javascript',
|
| 10475 |
+
),
|
| 10476 |
),
|
| 10477 |
),
|
| 10478 |
'tag_spec' => array(
|
| 10479 |
'extension_spec' => array(
|
| 10480 |
+
'deprecated_allow_duplicates' => true,
|
| 10481 |
+
'name' => 'amp-gfycat',
|
| 10482 |
+
'requires_usage' => 2,
|
| 10483 |
+
'version' => array(
|
| 10484 |
'0.1',
|
| 10485 |
'latest',
|
| 10486 |
),
|
|
|
|
| 10487 |
),
|
| 10488 |
),
|
| 10489 |
),
|
| 10491 |
'attr_spec_list' => array(
|
| 10492 |
'async' => array(
|
| 10493 |
'mandatory' => true,
|
| 10494 |
+
'value' => array(
|
| 10495 |
+
'',
|
| 10496 |
+
),
|
| 10497 |
),
|
| 10498 |
'nonce' => array(),
|
| 10499 |
'type' => array(
|
| 10500 |
+
'value_casei' => array(
|
| 10501 |
+
'text/javascript',
|
| 10502 |
+
),
|
| 10503 |
),
|
| 10504 |
),
|
| 10505 |
'tag_spec' => array(
|
| 10506 |
'extension_spec' => array(
|
| 10507 |
+
'name' => 'amp-gist',
|
| 10508 |
+
'version' => array(
|
| 10509 |
'0.1',
|
| 10510 |
'latest',
|
| 10511 |
),
|
|
|
|
| 10512 |
),
|
| 10513 |
),
|
| 10514 |
),
|
| 10516 |
'attr_spec_list' => array(
|
| 10517 |
'async' => array(
|
| 10518 |
'mandatory' => true,
|
| 10519 |
+
'value' => array(
|
| 10520 |
+
'',
|
| 10521 |
+
),
|
| 10522 |
),
|
| 10523 |
'nonce' => array(),
|
| 10524 |
'type' => array(
|
| 10525 |
+
'value_casei' => array(
|
| 10526 |
+
'text/javascript',
|
| 10527 |
+
),
|
| 10528 |
),
|
| 10529 |
),
|
| 10530 |
'tag_spec' => array(
|
| 10531 |
'extension_spec' => array(
|
| 10532 |
+
'name' => 'amp-google-document-embed',
|
| 10533 |
+
'version' => array(
|
| 10534 |
'0.1',
|
| 10535 |
'latest',
|
| 10536 |
),
|
|
|
|
| 10537 |
),
|
| 10538 |
),
|
| 10539 |
),
|
| 10541 |
'attr_spec_list' => array(
|
| 10542 |
'async' => array(
|
| 10543 |
'mandatory' => true,
|
| 10544 |
+
'value' => array(
|
| 10545 |
+
'',
|
| 10546 |
+
),
|
| 10547 |
),
|
| 10548 |
'nonce' => array(),
|
| 10549 |
'type' => array(
|
| 10550 |
+
'value_casei' => array(
|
| 10551 |
+
'text/javascript',
|
| 10552 |
+
),
|
| 10553 |
),
|
| 10554 |
),
|
| 10555 |
'tag_spec' => array(
|
| 10556 |
'extension_spec' => array(
|
| 10557 |
+
'name' => 'amp-hulu',
|
| 10558 |
+
'version' => array(
|
| 10559 |
'0.1',
|
| 10560 |
'latest',
|
| 10561 |
),
|
|
|
|
|
|
|
|
|
|
| 10562 |
),
|
| 10563 |
),
|
| 10564 |
),
|
| 10566 |
'attr_spec_list' => array(
|
| 10567 |
'async' => array(
|
| 10568 |
'mandatory' => true,
|
| 10569 |
+
'value' => array(
|
| 10570 |
+
'',
|
| 10571 |
+
),
|
| 10572 |
),
|
| 10573 |
'nonce' => array(),
|
| 10574 |
'type' => array(
|
| 10575 |
+
'value_casei' => array(
|
| 10576 |
+
'text/javascript',
|
| 10577 |
+
),
|
| 10578 |
),
|
| 10579 |
),
|
| 10580 |
'tag_spec' => array(
|
| 10581 |
'extension_spec' => array(
|
| 10582 |
+
'deprecated_allow_duplicates' => true,
|
| 10583 |
+
'name' => 'amp-iframe',
|
| 10584 |
+
'requires_usage' => 2,
|
| 10585 |
+
'version' => array(
|
| 10586 |
'0.1',
|
| 10587 |
'latest',
|
| 10588 |
),
|
|
|
|
|
|
|
|
|
|
| 10589 |
),
|
| 10590 |
),
|
| 10591 |
),
|
| 10593 |
'attr_spec_list' => array(
|
| 10594 |
'async' => array(
|
| 10595 |
'mandatory' => true,
|
| 10596 |
+
'value' => array(
|
| 10597 |
+
'',
|
| 10598 |
+
),
|
| 10599 |
),
|
| 10600 |
'nonce' => array(),
|
| 10601 |
'type' => array(
|
| 10602 |
+
'value_casei' => array(
|
| 10603 |
+
'text/javascript',
|
| 10604 |
+
),
|
| 10605 |
),
|
| 10606 |
),
|
| 10607 |
'tag_spec' => array(
|
| 10608 |
'extension_spec' => array(
|
| 10609 |
+
'name' => 'amp-ima-video',
|
| 10610 |
+
'version' => array(
|
| 10611 |
'0.1',
|
| 10612 |
'latest',
|
| 10613 |
),
|
|
|
|
|
|
|
|
|
|
| 10614 |
),
|
| 10615 |
),
|
| 10616 |
),
|
| 10618 |
'attr_spec_list' => array(
|
| 10619 |
'async' => array(
|
| 10620 |
'mandatory' => true,
|
| 10621 |
+
'value' => array(
|
| 10622 |
+
'',
|
| 10623 |
+
),
|
| 10624 |
),
|
| 10625 |
'nonce' => array(),
|
| 10626 |
'type' => array(
|
| 10627 |
+
'value_casei' => array(
|
| 10628 |
+
'text/javascript',
|
| 10629 |
+
),
|
| 10630 |
),
|
| 10631 |
),
|
| 10632 |
'tag_spec' => array(
|
| 10633 |
'extension_spec' => array(
|
| 10634 |
+
'deprecated_allow_duplicates' => true,
|
| 10635 |
+
'name' => 'amp-image-lightbox',
|
| 10636 |
+
'requires_usage' => 2,
|
| 10637 |
+
'version' => array(
|
| 10638 |
'0.1',
|
| 10639 |
'latest',
|
| 10640 |
),
|
|
|
|
|
|
|
|
|
|
| 10641 |
),
|
| 10642 |
),
|
| 10643 |
),
|
| 10645 |
'attr_spec_list' => array(
|
| 10646 |
'async' => array(
|
| 10647 |
'mandatory' => true,
|
| 10648 |
+
'value' => array(
|
| 10649 |
+
'',
|
| 10650 |
+
),
|
| 10651 |
),
|
| 10652 |
'nonce' => array(),
|
| 10653 |
'type' => array(
|
| 10654 |
+
'value_casei' => array(
|
| 10655 |
+
'text/javascript',
|
| 10656 |
+
),
|
| 10657 |
),
|
| 10658 |
),
|
| 10659 |
'tag_spec' => array(
|
| 10660 |
'extension_spec' => array(
|
| 10661 |
+
'name' => 'amp-image-slider',
|
| 10662 |
+
'version' => array(
|
| 10663 |
'0.1',
|
| 10664 |
'latest',
|
| 10665 |
),
|
|
|
|
|
|
|
| 10666 |
),
|
| 10667 |
),
|
| 10668 |
),
|
| 10670 |
'attr_spec_list' => array(
|
| 10671 |
'async' => array(
|
| 10672 |
'mandatory' => true,
|
| 10673 |
+
'value' => array(
|
| 10674 |
+
'',
|
| 10675 |
+
),
|
| 10676 |
),
|
| 10677 |
'nonce' => array(),
|
| 10678 |
'type' => array(
|
| 10679 |
+
'value_casei' => array(
|
| 10680 |
+
'text/javascript',
|
| 10681 |
+
),
|
| 10682 |
),
|
| 10683 |
),
|
| 10684 |
'tag_spec' => array(
|
| 10685 |
'extension_spec' => array(
|
| 10686 |
+
'name' => 'amp-imgur',
|
| 10687 |
+
'version' => array(
|
| 10688 |
'0.1',
|
| 10689 |
'latest',
|
| 10690 |
),
|
|
|
|
|
|
|
|
|
|
| 10691 |
),
|
| 10692 |
),
|
| 10693 |
),
|
| 10695 |
'attr_spec_list' => array(
|
| 10696 |
'async' => array(
|
| 10697 |
'mandatory' => true,
|
| 10698 |
+
'value' => array(
|
| 10699 |
+
'',
|
| 10700 |
+
),
|
| 10701 |
),
|
| 10702 |
'nonce' => array(),
|
| 10703 |
'type' => array(
|
| 10704 |
+
'value_casei' => array(
|
| 10705 |
+
'text/javascript',
|
| 10706 |
+
),
|
| 10707 |
),
|
| 10708 |
),
|
| 10709 |
'tag_spec' => array(
|
| 10710 |
'extension_spec' => array(
|
| 10711 |
+
'name' => 'amp-inputmask',
|
| 10712 |
+
'requires_usage' => 3,
|
| 10713 |
+
'version' => array(
|
| 10714 |
'0.1',
|
| 10715 |
'latest',
|
| 10716 |
),
|
|
|
|
|
|
|
|
|
|
| 10717 |
),
|
| 10718 |
),
|
| 10719 |
),
|
| 10721 |
'attr_spec_list' => array(
|
| 10722 |
'async' => array(
|
| 10723 |
'mandatory' => true,
|
| 10724 |
+
'value' => array(
|
| 10725 |
+
'',
|
| 10726 |
+
),
|
| 10727 |
),
|
| 10728 |
'nonce' => array(),
|
| 10729 |
'type' => array(
|
| 10730 |
+
'value_casei' => array(
|
| 10731 |
+
'text/javascript',
|
| 10732 |
+
),
|
| 10733 |
),
|
| 10734 |
),
|
| 10735 |
'tag_spec' => array(
|
| 10736 |
'extension_spec' => array(
|
| 10737 |
+
'deprecated_allow_duplicates' => true,
|
| 10738 |
+
'name' => 'amp-instagram',
|
| 10739 |
+
'requires_usage' => 2,
|
| 10740 |
+
'version' => array(
|
| 10741 |
'0.1',
|
| 10742 |
'latest',
|
| 10743 |
),
|
|
|
|
| 10744 |
),
|
| 10745 |
),
|
| 10746 |
),
|
| 10748 |
'attr_spec_list' => array(
|
| 10749 |
'async' => array(
|
| 10750 |
'mandatory' => true,
|
| 10751 |
+
'value' => array(
|
| 10752 |
+
'',
|
| 10753 |
+
),
|
| 10754 |
),
|
| 10755 |
'nonce' => array(),
|
| 10756 |
'type' => array(
|
| 10757 |
+
'value_casei' => array(
|
| 10758 |
+
'text/javascript',
|
| 10759 |
+
),
|
| 10760 |
),
|
| 10761 |
),
|
| 10762 |
'tag_spec' => array(
|
| 10763 |
'extension_spec' => array(
|
| 10764 |
+
'deprecated_allow_duplicates' => true,
|
| 10765 |
+
'name' => 'amp-install-serviceworker',
|
| 10766 |
+
'requires_usage' => 2,
|
| 10767 |
+
'version' => array(
|
| 10768 |
'0.1',
|
| 10769 |
'latest',
|
| 10770 |
),
|
|
|
|
| 10771 |
),
|
| 10772 |
),
|
| 10773 |
),
|
| 10775 |
'attr_spec_list' => array(
|
| 10776 |
'async' => array(
|
| 10777 |
'mandatory' => true,
|
| 10778 |
+
'value' => array(
|
| 10779 |
+
'',
|
| 10780 |
+
),
|
| 10781 |
),
|
| 10782 |
'nonce' => array(),
|
| 10783 |
'type' => array(
|
| 10784 |
+
'value_casei' => array(
|
| 10785 |
+
'text/javascript',
|
| 10786 |
+
),
|
| 10787 |
),
|
| 10788 |
),
|
| 10789 |
'tag_spec' => array(
|
| 10790 |
'extension_spec' => array(
|
| 10791 |
+
'name' => 'amp-izlesene',
|
| 10792 |
+
'requires_usage' => 2,
|
| 10793 |
+
'version' => array(
|
| 10794 |
'0.1',
|
| 10795 |
'latest',
|
| 10796 |
),
|
|
|
|
|
|
|
|
|
|
| 10797 |
),
|
| 10798 |
),
|
| 10799 |
),
|
| 10801 |
'attr_spec_list' => array(
|
| 10802 |
'async' => array(
|
| 10803 |
'mandatory' => true,
|
| 10804 |
+
'value' => array(
|
| 10805 |
+
'',
|
| 10806 |
+
),
|
| 10807 |
),
|
| 10808 |
'nonce' => array(),
|
| 10809 |
'type' => array(
|
| 10810 |
+
'value_casei' => array(
|
| 10811 |
+
'text/javascript',
|
| 10812 |
+
),
|
| 10813 |
),
|
| 10814 |
),
|
| 10815 |
'tag_spec' => array(
|
| 10816 |
'extension_spec' => array(
|
| 10817 |
+
'deprecated_allow_duplicates' => true,
|
| 10818 |
+
'name' => 'amp-jwplayer',
|
| 10819 |
+
'requires_usage' => 2,
|
| 10820 |
+
'version' => array(
|
| 10821 |
'0.1',
|
| 10822 |
'latest',
|
| 10823 |
),
|
|
|
|
| 10824 |
),
|
| 10825 |
),
|
| 10826 |
),
|
| 10828 |
'attr_spec_list' => array(
|
| 10829 |
'async' => array(
|
| 10830 |
'mandatory' => true,
|
| 10831 |
+
'value' => array(
|
| 10832 |
+
'',
|
| 10833 |
+
),
|
| 10834 |
),
|
| 10835 |
'nonce' => array(),
|
| 10836 |
'type' => array(
|
| 10837 |
+
'value_casei' => array(
|
| 10838 |
+
'text/javascript',
|
| 10839 |
+
),
|
| 10840 |
),
|
| 10841 |
),
|
| 10842 |
'tag_spec' => array(
|
| 10843 |
'extension_spec' => array(
|
| 10844 |
+
'deprecated_allow_duplicates' => true,
|
| 10845 |
+
'name' => 'amp-kaltura-player',
|
| 10846 |
+
'requires_usage' => 2,
|
| 10847 |
+
'version' => array(
|
| 10848 |
'0.1',
|
| 10849 |
'latest',
|
| 10850 |
),
|
|
|
|
|
|
|
|
|
|
| 10851 |
),
|
| 10852 |
),
|
| 10853 |
),
|
| 10855 |
'attr_spec_list' => array(
|
| 10856 |
'async' => array(
|
| 10857 |
'mandatory' => true,
|
| 10858 |
+
'value' => array(
|
| 10859 |
+
'',
|
| 10860 |
+
),
|
| 10861 |
),
|
| 10862 |
'nonce' => array(),
|
| 10863 |
'type' => array(
|
| 10864 |
+
'value_casei' => array(
|
| 10865 |
+
'text/javascript',
|
| 10866 |
+
),
|
| 10867 |
),
|
| 10868 |
),
|
| 10869 |
'tag_spec' => array(
|
| 10870 |
'extension_spec' => array(
|
| 10871 |
+
'name' => 'amp-lightbox-gallery',
|
| 10872 |
+
'requires_usage' => 3,
|
| 10873 |
+
'version' => array(
|
| 10874 |
'0.1',
|
| 10875 |
'latest',
|
| 10876 |
),
|
|
|
|
| 10877 |
),
|
| 10878 |
),
|
| 10879 |
),
|
| 10881 |
'attr_spec_list' => array(
|
| 10882 |
'async' => array(
|
| 10883 |
'mandatory' => true,
|
| 10884 |
+
'value' => array(
|
| 10885 |
+
'',
|
| 10886 |
+
),
|
| 10887 |
),
|
| 10888 |
'nonce' => array(),
|
| 10889 |
'type' => array(
|
| 10890 |
+
'value_casei' => array(
|
| 10891 |
+
'text/javascript',
|
| 10892 |
+
),
|
| 10893 |
),
|
| 10894 |
),
|
| 10895 |
'tag_spec' => array(
|
| 10896 |
'extension_spec' => array(
|
| 10897 |
+
'deprecated_allow_duplicates' => true,
|
| 10898 |
+
'name' => 'amp-lightbox',
|
| 10899 |
+
'requires_usage' => 2,
|
| 10900 |
+
'version' => array(
|
| 10901 |
'0.1',
|
| 10902 |
'latest',
|
| 10903 |
),
|
|
|
|
|
|
|
|
|
|
| 10904 |
),
|
| 10905 |
),
|
| 10906 |
),
|
| 10908 |
'attr_spec_list' => array(
|
| 10909 |
'async' => array(
|
| 10910 |
'mandatory' => true,
|
| 10911 |
+
'value' => array(
|
| 10912 |
+
'',
|
| 10913 |
+
),
|
| 10914 |
),
|
| 10915 |
'nonce' => array(),
|
| 10916 |
'type' => array(
|
| 10917 |
+
'value_casei' => array(
|
| 10918 |
+
'text/javascript',
|
| 10919 |
+
),
|
| 10920 |
),
|
| 10921 |
),
|
| 10922 |
'tag_spec' => array(
|
| 10923 |
'extension_spec' => array(
|
| 10924 |
+
'deprecated_allow_duplicates' => true,
|
| 10925 |
+
'name' => 'amp-list',
|
| 10926 |
+
'requires_usage' => 2,
|
| 10927 |
+
'version' => array(
|
| 10928 |
'0.1',
|
| 10929 |
'latest',
|
| 10930 |
),
|
|
|
|
|
|
|
|
|
|
| 10931 |
),
|
| 10932 |
),
|
| 10933 |
),
|
| 10935 |
'attr_spec_list' => array(
|
| 10936 |
'async' => array(
|
| 10937 |
'mandatory' => true,
|
| 10938 |
+
'value' => array(
|
| 10939 |
+
'',
|
| 10940 |
+
),
|
| 10941 |
),
|
| 10942 |
'nonce' => array(),
|
| 10943 |
'type' => array(
|
| 10944 |
+
'value_casei' => array(
|
| 10945 |
+
'text/javascript',
|
| 10946 |
+
),
|
| 10947 |
),
|
| 10948 |
),
|
| 10949 |
'tag_spec' => array(
|
| 10950 |
'extension_spec' => array(
|
| 10951 |
+
'name' => 'amp-live-list',
|
| 10952 |
+
'requires_usage' => 2,
|
| 10953 |
+
'version' => array(
|
| 10954 |
'0.1',
|
| 10955 |
'latest',
|
| 10956 |
),
|
|
|
|
|
|
|
| 10957 |
),
|
| 10958 |
+
'mandatory_parent' => 'head',
|
| 10959 |
+
'unique_warning' => true,
|
| 10960 |
),
|
| 10961 |
),
|
| 10962 |
array(
|
| 10963 |
'attr_spec_list' => array(
|
| 10964 |
'async' => array(
|
| 10965 |
'mandatory' => true,
|
| 10966 |
+
'value' => array(
|
| 10967 |
+
'',
|
| 10968 |
+
),
|
| 10969 |
),
|
| 10970 |
'nonce' => array(),
|
| 10971 |
'type' => array(
|
| 10972 |
+
'value_casei' => array(
|
| 10973 |
+
'text/javascript',
|
| 10974 |
+
),
|
| 10975 |
),
|
| 10976 |
),
|
| 10977 |
'tag_spec' => array(
|
| 10978 |
'extension_spec' => array(
|
| 10979 |
+
'name' => 'amp-mathml',
|
| 10980 |
+
'version' => array(
|
| 10981 |
'0.1',
|
| 10982 |
'latest',
|
| 10983 |
),
|
|
|
|
|
|
|
|
|
|
| 10984 |
),
|
| 10985 |
),
|
| 10986 |
),
|
| 10988 |
'attr_spec_list' => array(
|
| 10989 |
'async' => array(
|
| 10990 |
'mandatory' => true,
|
| 10991 |
+
'value' => array(
|
| 10992 |
+
'',
|
| 10993 |
+
),
|
| 10994 |
),
|
| 10995 |
'nonce' => array(),
|
| 10996 |
'type' => array(
|
| 10997 |
+
'value_casei' => array(
|
| 10998 |
+
'text/javascript',
|
| 10999 |
+
),
|
| 11000 |
),
|
| 11001 |
),
|
| 11002 |
'tag_spec' => array(
|
| 11003 |
'extension_spec' => array(
|
| 11004 |
+
'name' => 'amp-mowplayer',
|
| 11005 |
+
'version' => array(
|
| 11006 |
'0.1',
|
| 11007 |
'latest',
|
| 11008 |
),
|
|
|
|
|
|
|
|
|
|
| 11009 |
),
|
| 11010 |
),
|
| 11011 |
),
|
| 11013 |
'attr_spec_list' => array(
|
| 11014 |
'async' => array(
|
| 11015 |
'mandatory' => true,
|
| 11016 |
+
'value' => array(
|
| 11017 |
+
'',
|
| 11018 |
+
),
|
| 11019 |
),
|
| 11020 |
'nonce' => array(),
|
| 11021 |
'type' => array(
|
| 11022 |
+
'value_casei' => array(
|
| 11023 |
+
'text/javascript',
|
| 11024 |
+
),
|
| 11025 |
),
|
| 11026 |
),
|
| 11027 |
'tag_spec' => array(
|
| 11028 |
'extension_spec' => array(
|
| 11029 |
+
'deprecated_allow_duplicates' => true,
|
| 11030 |
+
'deprecated_version' => array(
|
| 11031 |
+
'0.1',
|
| 11032 |
+
),
|
| 11033 |
+
'is_custom_template' => true,
|
| 11034 |
+
'name' => 'amp-mustache',
|
| 11035 |
+
'requires_usage' => 2,
|
| 11036 |
+
'version' => array(
|
| 11037 |
'0.1',
|
| 11038 |
+
'0.2',
|
| 11039 |
'latest',
|
| 11040 |
),
|
|
|
|
|
|
|
| 11041 |
),
|
| 11042 |
),
|
| 11043 |
),
|
| 11045 |
'attr_spec_list' => array(
|
| 11046 |
'async' => array(
|
| 11047 |
'mandatory' => true,
|
| 11048 |
+
'value' => array(
|
| 11049 |
+
'',
|
| 11050 |
+
),
|
| 11051 |
),
|
| 11052 |
'nonce' => array(),
|
| 11053 |
'type' => array(
|
| 11054 |
+
'value_casei' => array(
|
| 11055 |
+
'text/javascript',
|
| 11056 |
+
),
|
| 11057 |
),
|
| 11058 |
),
|
| 11059 |
'tag_spec' => array(
|
| 11060 |
'extension_spec' => array(
|
| 11061 |
+
'name' => 'amp-next-page',
|
| 11062 |
+
'version' => array(
|
| 11063 |
'0.1',
|
| 11064 |
'latest',
|
| 11065 |
),
|
|
|
|
|
|
|
|
|
|
| 11066 |
),
|
| 11067 |
),
|
| 11068 |
),
|
| 11069 |
+
array(
|
| 11070 |
+
'attr_spec_list' => array(
|
| 11071 |
+
'type' => array(
|
| 11072 |
+
'dispatch_key' => 3,
|
| 11073 |
+
'mandatory' => true,
|
| 11074 |
+
'value_casei' => array(
|
| 11075 |
+
'application/json',
|
| 11076 |
+
),
|
| 11077 |
+
),
|
| 11078 |
+
),
|
| 11079 |
+
'tag_spec' => array(
|
| 11080 |
+
'mandatory_parent' => 'amp-next-page',
|
| 11081 |
+
'requires_extension' => array(
|
| 11082 |
+
'amp-next-page',
|
| 11083 |
+
),
|
| 11084 |
+
'spec_name' => 'amp-next-page extension .json configuration',
|
| 11085 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-next-page',
|
| 11086 |
+
),
|
| 11087 |
+
),
|
| 11088 |
array(
|
| 11089 |
'attr_spec_list' => array(
|
| 11090 |
'async' => array(
|
| 11091 |
'mandatory' => true,
|
| 11092 |
+
'value' => array(
|
| 11093 |
+
'',
|
| 11094 |
+
),
|
| 11095 |
),
|
| 11096 |
'nonce' => array(),
|
| 11097 |
'type' => array(
|
| 11098 |
+
'value_casei' => array(
|
| 11099 |
+
'text/javascript',
|
| 11100 |
+
),
|
| 11101 |
),
|
| 11102 |
),
|
| 11103 |
'tag_spec' => array(
|
| 11104 |
'extension_spec' => array(
|
| 11105 |
+
'name' => 'amp-nexxtv-player',
|
| 11106 |
+
'version' => array(
|
| 11107 |
'0.1',
|
| 11108 |
+
'latest',
|
| 11109 |
+
),
|
|
|
|
|
|
|
|
|
|
| 11110 |
),
|
| 11111 |
),
|
| 11112 |
),
|
| 11114 |
'attr_spec_list' => array(
|
| 11115 |
'async' => array(
|
| 11116 |
'mandatory' => true,
|
| 11117 |
+
'value' => array(
|
| 11118 |
+
'',
|
| 11119 |
+
),
|
| 11120 |
),
|
| 11121 |
'nonce' => array(),
|
| 11122 |
'type' => array(
|
| 11123 |
+
'value_casei' => array(
|
| 11124 |
+
'text/javascript',
|
| 11125 |
+
),
|
| 11126 |
),
|
| 11127 |
),
|
| 11128 |
'tag_spec' => array(
|
| 11129 |
'extension_spec' => array(
|
| 11130 |
+
'deprecated_allow_duplicates' => true,
|
| 11131 |
+
'name' => 'amp-o2-player',
|
| 11132 |
+
'requires_usage' => 2,
|
| 11133 |
+
'version' => array(
|
| 11134 |
'0.1',
|
| 11135 |
'latest',
|
| 11136 |
),
|
|
|
|
|
|
|
| 11137 |
),
|
|
|
|
|
|
|
| 11138 |
),
|
| 11139 |
),
|
| 11140 |
array(
|
| 11141 |
'attr_spec_list' => array(
|
| 11142 |
'async' => array(
|
| 11143 |
'mandatory' => true,
|
| 11144 |
+
'value' => array(
|
| 11145 |
+
'',
|
| 11146 |
+
),
|
| 11147 |
),
|
| 11148 |
'nonce' => array(),
|
| 11149 |
'type' => array(
|
| 11150 |
+
'value_casei' => array(
|
| 11151 |
+
'text/javascript',
|
| 11152 |
+
),
|
| 11153 |
),
|
| 11154 |
),
|
| 11155 |
'tag_spec' => array(
|
| 11156 |
'extension_spec' => array(
|
| 11157 |
+
'name' => 'amp-ooyala-player',
|
| 11158 |
+
'version' => array(
|
| 11159 |
'0.1',
|
| 11160 |
'latest',
|
| 11161 |
),
|
|
|
|
| 11162 |
),
|
| 11163 |
),
|
| 11164 |
),
|
| 11166 |
'attr_spec_list' => array(
|
| 11167 |
'async' => array(
|
| 11168 |
'mandatory' => true,
|
| 11169 |
+
'value' => array(
|
| 11170 |
+
'',
|
| 11171 |
+
),
|
| 11172 |
),
|
| 11173 |
'nonce' => array(),
|
| 11174 |
'type' => array(
|
| 11175 |
+
'value_casei' => array(
|
| 11176 |
+
'text/javascript',
|
| 11177 |
+
),
|
| 11178 |
),
|
| 11179 |
),
|
| 11180 |
'tag_spec' => array(
|
| 11181 |
'extension_spec' => array(
|
| 11182 |
+
'name' => 'amp-orientation-observer',
|
| 11183 |
+
'version' => array(
|
| 11184 |
'0.1',
|
| 11185 |
'latest',
|
| 11186 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11187 |
),
|
| 11188 |
),
|
| 11189 |
),
|
| 11191 |
'attr_spec_list' => array(
|
| 11192 |
'async' => array(
|
| 11193 |
'mandatory' => true,
|
| 11194 |
+
'value' => array(
|
| 11195 |
+
'',
|
| 11196 |
+
),
|
| 11197 |
),
|
| 11198 |
'nonce' => array(),
|
| 11199 |
'type' => array(
|
| 11200 |
+
'value_casei' => array(
|
| 11201 |
+
'text/javascript',
|
| 11202 |
+
),
|
| 11203 |
),
|
| 11204 |
),
|
| 11205 |
'tag_spec' => array(
|
| 11206 |
'extension_spec' => array(
|
| 11207 |
+
'name' => 'amp-pan-zoom',
|
| 11208 |
+
'version' => array(
|
| 11209 |
'0.1',
|
| 11210 |
'latest',
|
| 11211 |
),
|
|
|
|
| 11212 |
),
|
| 11213 |
),
|
| 11214 |
),
|
| 11216 |
'attr_spec_list' => array(
|
| 11217 |
'async' => array(
|
| 11218 |
'mandatory' => true,
|
| 11219 |
+
'value' => array(
|
| 11220 |
+
'',
|
| 11221 |
+
),
|
| 11222 |
),
|
| 11223 |
'nonce' => array(),
|
| 11224 |
'type' => array(
|
| 11225 |
+
'value_casei' => array(
|
| 11226 |
+
'text/javascript',
|
| 11227 |
+
),
|
| 11228 |
),
|
| 11229 |
),
|
| 11230 |
'tag_spec' => array(
|
| 11231 |
'extension_spec' => array(
|
| 11232 |
+
'deprecated_allow_duplicates' => true,
|
| 11233 |
+
'name' => 'amp-pinterest',
|
| 11234 |
+
'requires_usage' => 2,
|
| 11235 |
+
'version' => array(
|
| 11236 |
'0.1',
|
| 11237 |
'latest',
|
| 11238 |
),
|
|
|
|
|
|
|
|
|
|
| 11239 |
),
|
| 11240 |
),
|
| 11241 |
),
|
| 11243 |
'attr_spec_list' => array(
|
| 11244 |
'async' => array(
|
| 11245 |
'mandatory' => true,
|
| 11246 |
+
'value' => array(
|
| 11247 |
+
'',
|
| 11248 |
+
),
|
| 11249 |
),
|
| 11250 |
'nonce' => array(),
|
| 11251 |
'type' => array(
|
| 11252 |
+
'value_casei' => array(
|
| 11253 |
+
'text/javascript',
|
| 11254 |
+
),
|
| 11255 |
),
|
| 11256 |
),
|
| 11257 |
'tag_spec' => array(
|
| 11258 |
'extension_spec' => array(
|
| 11259 |
+
'name' => 'amp-playbuzz',
|
| 11260 |
+
'version' => array(
|
| 11261 |
'0.1',
|
| 11262 |
'latest',
|
| 11263 |
),
|
|
|
|
| 11264 |
),
|
| 11265 |
),
|
| 11266 |
),
|
| 11268 |
'attr_spec_list' => array(
|
| 11269 |
'async' => array(
|
| 11270 |
'mandatory' => true,
|
| 11271 |
+
'value' => array(
|
| 11272 |
+
'',
|
| 11273 |
+
),
|
| 11274 |
),
|
| 11275 |
'nonce' => array(),
|
| 11276 |
'type' => array(
|
| 11277 |
+
'value_casei' => array(
|
| 11278 |
+
'text/javascript',
|
| 11279 |
+
),
|
| 11280 |
),
|
| 11281 |
),
|
| 11282 |
'tag_spec' => array(
|
| 11283 |
'extension_spec' => array(
|
| 11284 |
+
'name' => 'amp-position-observer',
|
| 11285 |
+
'version' => array(
|
| 11286 |
'0.1',
|
| 11287 |
'latest',
|
| 11288 |
),
|
|
|
|
|
|
|
|
|
|
| 11289 |
),
|
| 11290 |
),
|
| 11291 |
),
|
| 11293 |
'attr_spec_list' => array(
|
| 11294 |
'async' => array(
|
| 11295 |
'mandatory' => true,
|
| 11296 |
+
'value' => array(
|
| 11297 |
+
'',
|
| 11298 |
+
),
|
| 11299 |
),
|
| 11300 |
'nonce' => array(),
|
| 11301 |
'type' => array(
|
| 11302 |
+
'value_casei' => array(
|
| 11303 |
+
'text/javascript',
|
| 11304 |
+
),
|
| 11305 |
),
|
| 11306 |
),
|
| 11307 |
'tag_spec' => array(
|
| 11308 |
'extension_spec' => array(
|
| 11309 |
+
'name' => 'amp-powr-player',
|
| 11310 |
+
'version' => array(
|
| 11311 |
'0.1',
|
| 11312 |
'latest',
|
| 11313 |
),
|
|
|
|
| 11314 |
),
|
| 11315 |
),
|
| 11316 |
),
|
| 11318 |
'attr_spec_list' => array(
|
| 11319 |
'async' => array(
|
| 11320 |
'mandatory' => true,
|
| 11321 |
+
'value' => array(
|
| 11322 |
+
'',
|
| 11323 |
+
),
|
| 11324 |
),
|
| 11325 |
'nonce' => array(),
|
| 11326 |
'type' => array(
|
| 11327 |
+
'value_casei' => array(
|
| 11328 |
+
'text/javascript',
|
| 11329 |
+
),
|
| 11330 |
),
|
| 11331 |
),
|
| 11332 |
'tag_spec' => array(
|
| 11333 |
'extension_spec' => array(
|
| 11334 |
+
'deprecated_allow_duplicates' => true,
|
| 11335 |
+
'name' => 'amp-reach-player',
|
| 11336 |
+
'requires_usage' => 2,
|
| 11337 |
+
'version' => array(
|
| 11338 |
'0.1',
|
| 11339 |
'latest',
|
| 11340 |
),
|
|
|
|
| 11341 |
),
|
| 11342 |
),
|
| 11343 |
),
|
| 11345 |
'attr_spec_list' => array(
|
| 11346 |
'async' => array(
|
| 11347 |
'mandatory' => true,
|
| 11348 |
+
'value' => array(
|
| 11349 |
+
'',
|
| 11350 |
+
),
|
| 11351 |
),
|
| 11352 |
'nonce' => array(),
|
| 11353 |
'type' => array(
|
| 11354 |
+
'value_casei' => array(
|
| 11355 |
+
'text/javascript',
|
| 11356 |
+
),
|
| 11357 |
),
|
| 11358 |
),
|
| 11359 |
'tag_spec' => array(
|
| 11360 |
'extension_spec' => array(
|
| 11361 |
+
'deprecated_allow_duplicates' => true,
|
| 11362 |
+
'name' => 'amp-reddit',
|
| 11363 |
+
'version' => array(
|
| 11364 |
'0.1',
|
| 11365 |
'latest',
|
| 11366 |
),
|
|
|
|
|
|
|
|
|
|
| 11367 |
),
|
| 11368 |
),
|
| 11369 |
),
|
| 11371 |
'attr_spec_list' => array(
|
| 11372 |
'async' => array(
|
| 11373 |
'mandatory' => true,
|
| 11374 |
+
'value' => array(
|
| 11375 |
+
'',
|
| 11376 |
+
),
|
| 11377 |
),
|
| 11378 |
'nonce' => array(),
|
| 11379 |
'type' => array(
|
| 11380 |
+
'value_casei' => array(
|
| 11381 |
+
'text/javascript',
|
| 11382 |
+
),
|
| 11383 |
),
|
| 11384 |
),
|
| 11385 |
'tag_spec' => array(
|
| 11386 |
'extension_spec' => array(
|
| 11387 |
+
'name' => 'amp-riddle-quiz',
|
| 11388 |
+
'version' => array(
|
| 11389 |
'0.1',
|
| 11390 |
'latest',
|
| 11391 |
),
|
|
|
|
|
|
|
| 11392 |
),
|
| 11393 |
),
|
| 11394 |
),
|
| 11396 |
'attr_spec_list' => array(
|
| 11397 |
'async' => array(
|
| 11398 |
'mandatory' => true,
|
| 11399 |
+
'value' => array(
|
| 11400 |
+
'',
|
| 11401 |
+
),
|
| 11402 |
),
|
| 11403 |
'nonce' => array(),
|
| 11404 |
'type' => array(
|
| 11405 |
+
'value_casei' => array(
|
| 11406 |
+
'text/javascript',
|
| 11407 |
+
),
|
| 11408 |
),
|
| 11409 |
),
|
| 11410 |
'tag_spec' => array(
|
| 11411 |
'extension_spec' => array(
|
| 11412 |
+
'name' => 'amp-selector',
|
| 11413 |
+
'requires_usage' => 2,
|
| 11414 |
+
'version' => array(
|
| 11415 |
'0.1',
|
| 11416 |
'latest',
|
| 11417 |
),
|
|
|
|
| 11418 |
),
|
| 11419 |
),
|
| 11420 |
),
|
| 11422 |
'attr_spec_list' => array(
|
| 11423 |
'async' => array(
|
| 11424 |
'mandatory' => true,
|
| 11425 |
+
'value' => array(
|
| 11426 |
+
'',
|
| 11427 |
+
),
|
| 11428 |
),
|
| 11429 |
'nonce' => array(),
|
| 11430 |
'type' => array(
|
| 11431 |
+
'value_casei' => array(
|
| 11432 |
+
'text/javascript',
|
| 11433 |
+
),
|
| 11434 |
),
|
| 11435 |
),
|
| 11436 |
'tag_spec' => array(
|
| 11437 |
'extension_spec' => array(
|
| 11438 |
+
'deprecated_allow_duplicates' => true,
|
| 11439 |
+
'name' => 'amp-sidebar',
|
| 11440 |
+
'requires_usage' => 2,
|
| 11441 |
+
'version' => array(
|
| 11442 |
'0.1',
|
| 11443 |
'latest',
|
| 11444 |
),
|
|
|
|
|
|
|
| 11445 |
),
|
| 11446 |
),
|
| 11447 |
),
|
| 11449 |
'attr_spec_list' => array(
|
| 11450 |
'async' => array(
|
| 11451 |
'mandatory' => true,
|
| 11452 |
+
'value' => array(
|
| 11453 |
+
'',
|
| 11454 |
+
),
|
| 11455 |
),
|
| 11456 |
'nonce' => array(),
|
| 11457 |
'type' => array(
|
| 11458 |
+
'value_casei' => array(
|
| 11459 |
+
'text/javascript',
|
| 11460 |
+
),
|
| 11461 |
),
|
| 11462 |
),
|
| 11463 |
'tag_spec' => array(
|
| 11464 |
'extension_spec' => array(
|
| 11465 |
+
'name' => 'amp-skimlinks',
|
| 11466 |
+
'version' => array(
|
| 11467 |
'0.1',
|
| 11468 |
'latest',
|
| 11469 |
),
|
|
|
|
|
|
|
|
|
|
| 11470 |
),
|
| 11471 |
),
|
| 11472 |
),
|
| 11474 |
'attr_spec_list' => array(
|
| 11475 |
'async' => array(
|
| 11476 |
'mandatory' => true,
|
| 11477 |
+
'value' => array(
|
| 11478 |
+
'',
|
| 11479 |
+
),
|
| 11480 |
),
|
| 11481 |
'nonce' => array(),
|
| 11482 |
'type' => array(
|
| 11483 |
+
'value_casei' => array(
|
| 11484 |
+
'text/javascript',
|
| 11485 |
+
),
|
| 11486 |
),
|
| 11487 |
),
|
| 11488 |
'tag_spec' => array(
|
| 11489 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11490 |
'deprecated_allow_duplicates' => true,
|
| 11491 |
'name' => 'amp-social-share',
|
| 11492 |
'requires_usage' => 2,
|
| 11493 |
+
'version' => array(
|
| 11494 |
+
'0.1',
|
| 11495 |
+
'latest',
|
| 11496 |
+
),
|
| 11497 |
),
|
| 11498 |
),
|
| 11499 |
),
|
| 11501 |
'attr_spec_list' => array(
|
| 11502 |
'async' => array(
|
| 11503 |
'mandatory' => true,
|
| 11504 |
+
'value' => array(
|
| 11505 |
+
'',
|
| 11506 |
+
),
|
| 11507 |
),
|
| 11508 |
'nonce' => array(),
|
| 11509 |
'type' => array(
|
| 11510 |
+
'value_casei' => array(
|
| 11511 |
+
'text/javascript',
|
| 11512 |
+
),
|
| 11513 |
),
|
| 11514 |
),
|
| 11515 |
'tag_spec' => array(
|
| 11516 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11517 |
'deprecated_allow_duplicates' => true,
|
| 11518 |
'name' => 'amp-soundcloud',
|
| 11519 |
'requires_usage' => 2,
|
| 11520 |
+
'version' => array(
|
| 11521 |
+
'0.1',
|
| 11522 |
+
'latest',
|
| 11523 |
+
),
|
| 11524 |
),
|
| 11525 |
),
|
| 11526 |
),
|
| 11528 |
'attr_spec_list' => array(
|
| 11529 |
'async' => array(
|
| 11530 |
'mandatory' => true,
|
| 11531 |
+
'value' => array(
|
| 11532 |
+
'',
|
| 11533 |
+
),
|
| 11534 |
),
|
| 11535 |
'nonce' => array(),
|
| 11536 |
'type' => array(
|
| 11537 |
+
'value_casei' => array(
|
| 11538 |
+
'text/javascript',
|
| 11539 |
+
),
|
| 11540 |
),
|
| 11541 |
),
|
| 11542 |
'tag_spec' => array(
|
| 11543 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11544 |
'deprecated_allow_duplicates' => true,
|
| 11545 |
'name' => 'amp-springboard-player',
|
| 11546 |
'requires_usage' => 2,
|
| 11547 |
+
'version' => array(
|
| 11548 |
+
'0.1',
|
| 11549 |
+
'latest',
|
| 11550 |
+
),
|
| 11551 |
),
|
| 11552 |
),
|
| 11553 |
),
|
| 11555 |
'attr_spec_list' => array(
|
| 11556 |
'async' => array(
|
| 11557 |
'mandatory' => true,
|
| 11558 |
+
'value' => array(
|
| 11559 |
+
'',
|
| 11560 |
+
),
|
| 11561 |
),
|
| 11562 |
'nonce' => array(),
|
| 11563 |
'type' => array(
|
| 11564 |
+
'value_casei' => array(
|
| 11565 |
+
'text/javascript',
|
| 11566 |
+
),
|
| 11567 |
),
|
| 11568 |
),
|
| 11569 |
'tag_spec' => array(
|
| 11570 |
'extension_spec' => array(
|
| 11571 |
+
'deprecated_version' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11572 |
'0.1',
|
| 11573 |
),
|
| 11574 |
'name' => 'amp-sticky-ad',
|
| 11575 |
'requires_usage' => 2,
|
| 11576 |
+
'version' => array(
|
| 11577 |
+
'0.1',
|
| 11578 |
+
'1.0',
|
| 11579 |
+
'latest',
|
| 11580 |
+
),
|
| 11581 |
),
|
| 11582 |
),
|
| 11583 |
),
|
| 11585 |
'attr_spec_list' => array(
|
| 11586 |
'async' => array(
|
| 11587 |
'mandatory' => true,
|
| 11588 |
+
'value' => array(
|
| 11589 |
+
'',
|
| 11590 |
+
),
|
| 11591 |
),
|
| 11592 |
'nonce' => array(),
|
| 11593 |
'type' => array(
|
| 11594 |
+
'value_casei' => array(
|
| 11595 |
+
'text/javascript',
|
| 11596 |
+
),
|
| 11597 |
),
|
| 11598 |
),
|
| 11599 |
'tag_spec' => array(
|
| 11600 |
'extension_spec' => array(
|
| 11601 |
+
'name' => 'amp-story-auto-ads',
|
| 11602 |
+
'version' => array(
|
| 11603 |
'0.1',
|
| 11604 |
'latest',
|
| 11605 |
),
|
|
|
|
| 11606 |
),
|
| 11607 |
),
|
| 11608 |
),
|
| 11612 |
'type' => array(
|
| 11613 |
'dispatch_key' => 3,
|
| 11614 |
'mandatory' => true,
|
| 11615 |
+
'value_casei' => array(
|
| 11616 |
+
'application/json',
|
| 11617 |
+
),
|
| 11618 |
),
|
| 11619 |
),
|
| 11620 |
'cdata' => array(
|
| 11636 |
'attr_spec_list' => array(
|
| 11637 |
'async' => array(
|
| 11638 |
'mandatory' => true,
|
| 11639 |
+
'value' => array(
|
| 11640 |
+
'',
|
| 11641 |
+
),
|
| 11642 |
),
|
| 11643 |
'nonce' => array(),
|
| 11644 |
'type' => array(
|
| 11645 |
+
'value_casei' => array(
|
| 11646 |
+
'text/javascript',
|
| 11647 |
+
),
|
| 11648 |
),
|
| 11649 |
),
|
| 11650 |
'tag_spec' => array(
|
| 11651 |
'extension_spec' => array(
|
| 11652 |
+
'name' => 'amp-story',
|
| 11653 |
+
'version' => array(
|
| 11654 |
'0.1',
|
| 11655 |
+
'1.0',
|
| 11656 |
'latest',
|
| 11657 |
),
|
|
|
|
| 11658 |
),
|
| 11659 |
),
|
| 11660 |
),
|
| 11661 |
+
array(
|
| 11662 |
+
'attr_spec_list' => array(
|
| 11663 |
+
'type' => array(
|
| 11664 |
+
'dispatch_key' => 3,
|
| 11665 |
+
'mandatory' => true,
|
| 11666 |
+
'value_casei' => array(
|
| 11667 |
+
'application/json',
|
| 11668 |
+
),
|
| 11669 |
+
),
|
| 11670 |
+
),
|
| 11671 |
+
'tag_spec' => array(
|
| 11672 |
+
'mandatory_parent' => 'amp-story-bookend',
|
| 11673 |
+
'requires_extension' => array(
|
| 11674 |
+
'amp-story',
|
| 11675 |
+
),
|
| 11676 |
+
'spec_name' => 'amp-story-bookend extension .json script',
|
| 11677 |
+
'unique' => true,
|
| 11678 |
+
),
|
| 11679 |
+
),
|
| 11680 |
+
array(
|
| 11681 |
+
'attr_spec_list' => array(
|
| 11682 |
+
'nonce' => array(),
|
| 11683 |
+
'type' => array(
|
| 11684 |
+
'dispatch_key' => 3,
|
| 11685 |
+
'mandatory' => true,
|
| 11686 |
+
'value_casei' => array(
|
| 11687 |
+
'application/json',
|
| 11688 |
+
),
|
| 11689 |
+
),
|
| 11690 |
+
),
|
| 11691 |
+
'cdata' => array(
|
| 11692 |
+
'blacklisted_cdata_regex' => array(
|
| 11693 |
+
'error_message' => 'html comments',
|
| 11694 |
+
'regex' => '<!--',
|
| 11695 |
+
),
|
| 11696 |
+
),
|
| 11697 |
+
'tag_spec' => array(
|
| 11698 |
+
'mandatory_parent' => 'amp-story-consent',
|
| 11699 |
+
'requires_extension' => array(
|
| 11700 |
+
'amp-consent',
|
| 11701 |
+
'amp-story',
|
| 11702 |
+
),
|
| 11703 |
+
'spec_name' => 'amp-story-consent extension .json script',
|
| 11704 |
+
'unique' => true,
|
| 11705 |
+
),
|
| 11706 |
+
),
|
| 11707 |
array(
|
| 11708 |
'attr_spec_list' => array(
|
| 11709 |
'async' => array(
|
| 11710 |
'mandatory' => true,
|
| 11711 |
+
'value' => array(
|
| 11712 |
+
'',
|
| 11713 |
+
),
|
| 11714 |
),
|
| 11715 |
'nonce' => array(),
|
| 11716 |
'type' => array(
|
| 11717 |
+
'value_casei' => array(
|
| 11718 |
+
'text/javascript',
|
| 11719 |
+
),
|
| 11720 |
),
|
| 11721 |
),
|
| 11722 |
'tag_spec' => array(
|
| 11723 |
'extension_spec' => array(
|
| 11724 |
+
'name' => 'amp-subscriptions',
|
| 11725 |
+
'requires_usage' => 3,
|
| 11726 |
+
'version' => array(
|
| 11727 |
'0.1',
|
| 11728 |
'latest',
|
| 11729 |
),
|
|
|
|
|
|
|
| 11730 |
),
|
| 11731 |
),
|
| 11732 |
),
|
| 11735 |
'id' => array(
|
| 11736 |
'dispatch_key' => 2,
|
| 11737 |
'mandatory' => true,
|
| 11738 |
+
'value' => array(
|
| 11739 |
+
'amp-subscriptions',
|
| 11740 |
+
),
|
| 11741 |
),
|
| 11742 |
'nonce' => array(),
|
| 11743 |
'type' => array(
|
| 11744 |
'mandatory' => true,
|
| 11745 |
+
'value_casei' => array(
|
| 11746 |
+
'application/json',
|
| 11747 |
+
),
|
| 11748 |
),
|
| 11749 |
),
|
| 11750 |
'cdata' => array(
|
| 11766 |
'attr_spec_list' => array(
|
| 11767 |
'async' => array(
|
| 11768 |
'mandatory' => true,
|
| 11769 |
+
'value' => array(
|
| 11770 |
+
'',
|
| 11771 |
+
),
|
| 11772 |
),
|
| 11773 |
'nonce' => array(),
|
| 11774 |
'type' => array(
|
| 11775 |
+
'value_casei' => array(
|
| 11776 |
+
'text/javascript',
|
| 11777 |
+
),
|
| 11778 |
),
|
| 11779 |
),
|
| 11780 |
'tag_spec' => array(
|
| 11781 |
'extension_spec' => array(
|
| 11782 |
+
'name' => 'amp-subscriptions-google',
|
| 11783 |
+
'requires_usage' => 3,
|
| 11784 |
+
'version' => array(
|
| 11785 |
'0.1',
|
| 11786 |
'latest',
|
| 11787 |
),
|
|
|
|
|
|
|
| 11788 |
),
|
| 11789 |
'requires_extension' => array(
|
| 11790 |
'amp-subscriptions',
|
| 11795 |
'attr_spec_list' => array(
|
| 11796 |
'async' => array(
|
| 11797 |
'mandatory' => true,
|
| 11798 |
+
'value' => array(
|
| 11799 |
+
'',
|
| 11800 |
+
),
|
| 11801 |
),
|
| 11802 |
'nonce' => array(),
|
| 11803 |
'type' => array(
|
| 11804 |
+
'value_casei' => array(
|
| 11805 |
+
'text/javascript',
|
| 11806 |
+
),
|
| 11807 |
),
|
| 11808 |
),
|
| 11809 |
'tag_spec' => array(
|
| 11810 |
'extension_spec' => array(
|
| 11811 |
+
'name' => 'amp-timeago',
|
| 11812 |
+
'version' => array(
|
| 11813 |
'0.1',
|
| 11814 |
'latest',
|
| 11815 |
),
|
|
|
|
| 11816 |
),
|
| 11817 |
),
|
| 11818 |
),
|
| 11820 |
'attr_spec_list' => array(
|
| 11821 |
'async' => array(
|
| 11822 |
'mandatory' => true,
|
| 11823 |
+
'value' => array(
|
| 11824 |
+
'',
|
| 11825 |
+
),
|
| 11826 |
),
|
| 11827 |
'nonce' => array(),
|
| 11828 |
'type' => array(
|
| 11829 |
+
'value_casei' => array(
|
| 11830 |
+
'text/javascript',
|
| 11831 |
+
),
|
| 11832 |
),
|
| 11833 |
),
|
| 11834 |
'tag_spec' => array(
|
| 11835 |
'extension_spec' => array(
|
| 11836 |
+
'deprecated_allow_duplicates' => true,
|
| 11837 |
+
'name' => 'amp-twitter',
|
| 11838 |
+
'requires_usage' => 2,
|
| 11839 |
+
'version' => array(
|
| 11840 |
'0.1',
|
| 11841 |
'latest',
|
| 11842 |
),
|
| 11843 |
+
),
|
| 11844 |
+
),
|
| 11845 |
+
),
|
| 11846 |
+
array(
|
| 11847 |
+
'attr_spec_list' => array(
|
| 11848 |
+
'async' => array(
|
| 11849 |
+
'mandatory' => true,
|
| 11850 |
+
'value' => array(
|
| 11851 |
+
'',
|
| 11852 |
+
),
|
| 11853 |
+
),
|
| 11854 |
+
'nonce' => array(),
|
| 11855 |
+
'type' => array(
|
| 11856 |
+
'value_casei' => array(
|
| 11857 |
+
'text/javascript',
|
| 11858 |
+
),
|
| 11859 |
+
),
|
| 11860 |
+
),
|
| 11861 |
+
'tag_spec' => array(
|
| 11862 |
+
'extension_spec' => array(
|
| 11863 |
'deprecated_allow_duplicates' => true,
|
| 11864 |
+
'name' => 'amp-user-notification',
|
| 11865 |
'requires_usage' => 2,
|
| 11866 |
+
'version' => array(
|
| 11867 |
+
'0.1',
|
| 11868 |
+
'latest',
|
| 11869 |
+
),
|
| 11870 |
),
|
| 11871 |
),
|
| 11872 |
),
|
| 11874 |
'attr_spec_list' => array(
|
| 11875 |
'async' => array(
|
| 11876 |
'mandatory' => true,
|
| 11877 |
+
'value' => array(
|
| 11878 |
+
'',
|
| 11879 |
+
),
|
| 11880 |
),
|
| 11881 |
'nonce' => array(),
|
| 11882 |
'type' => array(
|
| 11883 |
+
'value_casei' => array(
|
| 11884 |
+
'text/javascript',
|
| 11885 |
+
),
|
| 11886 |
),
|
| 11887 |
),
|
| 11888 |
'tag_spec' => array(
|
| 11889 |
'extension_spec' => array(
|
| 11890 |
+
'name' => 'amp-video',
|
| 11891 |
+
'requires_usage' => 3,
|
| 11892 |
+
'version' => array(
|
| 11893 |
'0.1',
|
| 11894 |
'latest',
|
| 11895 |
),
|
| 11896 |
+
),
|
| 11897 |
+
'spec_name' => 'amp-video extension .js script',
|
| 11898 |
+
),
|
| 11899 |
+
),
|
| 11900 |
+
array(
|
| 11901 |
+
'attr_spec_list' => array(
|
| 11902 |
+
'async' => array(
|
| 11903 |
+
'mandatory' => true,
|
| 11904 |
+
'value' => array(
|
| 11905 |
+
'',
|
| 11906 |
+
),
|
| 11907 |
+
),
|
| 11908 |
+
'nonce' => array(),
|
| 11909 |
+
'type' => array(
|
| 11910 |
+
'value_casei' => array(
|
| 11911 |
+
'text/javascript',
|
| 11912 |
+
),
|
| 11913 |
+
),
|
| 11914 |
+
),
|
| 11915 |
+
'tag_spec' => array(
|
| 11916 |
+
'extension_spec' => array(
|
| 11917 |
'deprecated_allow_duplicates' => true,
|
| 11918 |
+
'name' => 'amp-vimeo',
|
| 11919 |
'requires_usage' => 2,
|
| 11920 |
+
'version' => array(
|
| 11921 |
+
'0.1',
|
| 11922 |
+
'latest',
|
| 11923 |
+
),
|
| 11924 |
),
|
| 11925 |
),
|
| 11926 |
),
|
| 11928 |
'attr_spec_list' => array(
|
| 11929 |
'async' => array(
|
| 11930 |
'mandatory' => true,
|
| 11931 |
+
'value' => array(
|
| 11932 |
+
'',
|
| 11933 |
+
),
|
| 11934 |
),
|
| 11935 |
'nonce' => array(),
|
| 11936 |
'type' => array(
|
| 11937 |
+
'value_casei' => array(
|
| 11938 |
+
'text/javascript',
|
| 11939 |
+
),
|
| 11940 |
),
|
| 11941 |
),
|
| 11942 |
'tag_spec' => array(
|
| 11943 |
'extension_spec' => array(
|
| 11944 |
+
'deprecated_allow_duplicates' => true,
|
| 11945 |
+
'name' => 'amp-vine',
|
| 11946 |
+
'requires_usage' => 2,
|
| 11947 |
+
'version' => array(
|
| 11948 |
'0.1',
|
| 11949 |
'latest',
|
| 11950 |
),
|
|
|
|
|
|
|
| 11951 |
),
|
|
|
|
| 11952 |
),
|
| 11953 |
),
|
| 11954 |
array(
|
| 11955 |
'attr_spec_list' => array(
|
| 11956 |
'async' => array(
|
| 11957 |
'mandatory' => true,
|
| 11958 |
+
'value' => array(
|
| 11959 |
+
'',
|
| 11960 |
+
),
|
| 11961 |
),
|
| 11962 |
'nonce' => array(),
|
| 11963 |
'type' => array(
|
| 11964 |
+
'value_casei' => array(
|
| 11965 |
+
'text/javascript',
|
| 11966 |
+
),
|
| 11967 |
),
|
| 11968 |
),
|
| 11969 |
'tag_spec' => array(
|
| 11970 |
'extension_spec' => array(
|
| 11971 |
+
'name' => 'amp-viqeo-player',
|
| 11972 |
+
'version' => array(
|
| 11973 |
'0.1',
|
| 11974 |
'latest',
|
| 11975 |
),
|
|
|
|
|
|
|
|
|
|
| 11976 |
),
|
| 11977 |
),
|
| 11978 |
),
|
| 11980 |
'attr_spec_list' => array(
|
| 11981 |
'async' => array(
|
| 11982 |
'mandatory' => true,
|
| 11983 |
+
'value' => array(
|
| 11984 |
+
'',
|
| 11985 |
+
),
|
| 11986 |
),
|
| 11987 |
'nonce' => array(),
|
| 11988 |
'type' => array(
|
| 11989 |
+
'value_casei' => array(
|
| 11990 |
+
'text/javascript',
|
| 11991 |
+
),
|
| 11992 |
),
|
| 11993 |
),
|
| 11994 |
'tag_spec' => array(
|
| 11995 |
'extension_spec' => array(
|
| 11996 |
+
'name' => 'amp-vk',
|
| 11997 |
+
'version' => array(
|
| 11998 |
'0.1',
|
| 11999 |
'latest',
|
| 12000 |
),
|
|
|
|
|
|
|
|
|
|
| 12001 |
),
|
| 12002 |
),
|
| 12003 |
),
|
| 12005 |
'attr_spec_list' => array(
|
| 12006 |
'async' => array(
|
| 12007 |
'mandatory' => true,
|
| 12008 |
+
'value' => array(
|
| 12009 |
+
'',
|
| 12010 |
+
),
|
| 12011 |
),
|
| 12012 |
'nonce' => array(),
|
| 12013 |
'type' => array(
|
| 12014 |
+
'value_casei' => array(
|
| 12015 |
+
'text/javascript',
|
| 12016 |
+
),
|
| 12017 |
),
|
| 12018 |
),
|
| 12019 |
'tag_spec' => array(
|
| 12020 |
'extension_spec' => array(
|
| 12021 |
+
'name' => 'amp-web-push',
|
| 12022 |
+
'version' => array(
|
| 12023 |
'0.1',
|
| 12024 |
'latest',
|
| 12025 |
),
|
|
|
|
| 12026 |
),
|
| 12027 |
),
|
| 12028 |
),
|
| 12030 |
'attr_spec_list' => array(
|
| 12031 |
'async' => array(
|
| 12032 |
'mandatory' => true,
|
| 12033 |
+
'value' => array(
|
| 12034 |
+
'',
|
| 12035 |
+
),
|
| 12036 |
),
|
| 12037 |
'nonce' => array(),
|
| 12038 |
'type' => array(
|
| 12039 |
+
'value_casei' => array(
|
| 12040 |
+
'text/javascript',
|
| 12041 |
+
),
|
| 12042 |
),
|
| 12043 |
),
|
| 12044 |
'tag_spec' => array(
|
| 12045 |
'extension_spec' => array(
|
| 12046 |
+
'name' => 'amp-wistia-player',
|
| 12047 |
+
'version' => array(
|
| 12048 |
'0.1',
|
| 12049 |
'latest',
|
| 12050 |
),
|
|
|
|
| 12051 |
),
|
| 12052 |
),
|
| 12053 |
),
|
| 12055 |
'attr_spec_list' => array(
|
| 12056 |
'async' => array(
|
| 12057 |
'mandatory' => true,
|
| 12058 |
+
'value' => array(
|
| 12059 |
+
'',
|
| 12060 |
+
),
|
| 12061 |
),
|
| 12062 |
'nonce' => array(),
|
| 12063 |
'type' => array(
|
| 12064 |
+
'value_casei' => array(
|
| 12065 |
+
'text/javascript',
|
| 12066 |
+
),
|
| 12067 |
),
|
| 12068 |
),
|
| 12069 |
'tag_spec' => array(
|
| 12070 |
'extension_spec' => array(
|
| 12071 |
+
'name' => 'amp-yotpo',
|
| 12072 |
+
'version' => array(
|
| 12073 |
'0.1',
|
| 12074 |
'latest',
|
| 12075 |
),
|
|
|
|
| 12076 |
),
|
| 12077 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-yotpo',
|
| 12078 |
),
|
| 12079 |
),
|
| 12080 |
array(
|
| 12081 |
'attr_spec_list' => array(
|
| 12082 |
'async' => array(
|
| 12083 |
'mandatory' => true,
|
| 12084 |
+
'value' => array(
|
| 12085 |
+
'',
|
| 12086 |
+
),
|
| 12087 |
),
|
| 12088 |
'nonce' => array(),
|
| 12089 |
'type' => array(
|
| 12090 |
+
'value_casei' => array(
|
| 12091 |
+
'text/javascript',
|
| 12092 |
+
),
|
| 12093 |
),
|
| 12094 |
),
|
| 12095 |
'tag_spec' => array(
|
| 12096 |
'extension_spec' => array(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12097 |
'deprecated_allow_duplicates' => true,
|
| 12098 |
'name' => 'amp-youtube',
|
| 12099 |
'requires_usage' => 2,
|
| 12100 |
+
'version' => array(
|
| 12101 |
+
'0.1',
|
| 12102 |
+
'latest',
|
| 12103 |
+
),
|
| 12104 |
),
|
| 12105 |
),
|
| 12106 |
),
|
| 12117 |
array(
|
| 12118 |
'attr_spec_list' => array(
|
| 12119 |
'expanded' => array(
|
| 12120 |
+
'value' => array(
|
| 12121 |
+
'',
|
| 12122 |
+
),
|
| 12123 |
),
|
| 12124 |
),
|
| 12125 |
'tag_spec' => array(
|
| 12142 |
'name' => array(
|
| 12143 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 12144 |
),
|
| 12145 |
+
'no-verify' => array(
|
| 12146 |
+
'value' => array(
|
| 12147 |
+
'',
|
| 12148 |
+
),
|
| 12149 |
+
),
|
| 12150 |
'required' => array(),
|
| 12151 |
'size' => array(),
|
| 12152 |
),
|
| 12193 |
'filter' => array(),
|
| 12194 |
'flood-color' => array(),
|
| 12195 |
'flood-opacity' => array(),
|
| 12196 |
+
'focusable' => array(),
|
| 12197 |
'font-family' => array(),
|
| 12198 |
'font-size' => array(),
|
| 12199 |
'font-size-adjust' => array(),
|
| 12250 |
),
|
| 12251 |
),
|
| 12252 |
'source' => array(
|
| 12253 |
+
array(
|
| 12254 |
+
'attr_spec_list' => array(
|
| 12255 |
+
'media' => array(),
|
| 12256 |
+
'sizes' => array(),
|
| 12257 |
+
'srcset' => array(
|
| 12258 |
+
'blacklisted_value_regex' => '__amp_source_origin',
|
| 12259 |
+
'value_url' => array(
|
| 12260 |
+
'allow_relative' => true,
|
| 12261 |
+
'protocol' => array(
|
| 12262 |
+
'data',
|
| 12263 |
+
'http',
|
| 12264 |
+
'https',
|
| 12265 |
+
),
|
| 12266 |
+
),
|
| 12267 |
+
),
|
| 12268 |
+
'type' => array(),
|
| 12269 |
+
),
|
| 12270 |
+
'tag_spec' => array(
|
| 12271 |
+
'mandatory_parent' => 'picture',
|
| 12272 |
+
'spec_name' => 'picture > source',
|
| 12273 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-img',
|
| 12274 |
+
),
|
| 12275 |
+
),
|
| 12276 |
array(
|
| 12277 |
'attr_spec_list' => array(
|
| 12278 |
'[src]' => array(),
|
| 12282 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 12283 |
'value_url' => array(
|
| 12284 |
'allow_relative' => true,
|
| 12285 |
+
'protocol' => array(
|
| 12286 |
'https',
|
| 12287 |
),
|
| 12288 |
),
|
| 12304 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 12305 |
'value_url' => array(
|
| 12306 |
'allow_relative' => true,
|
| 12307 |
+
'protocol' => array(
|
| 12308 |
'https',
|
| 12309 |
),
|
| 12310 |
),
|
| 12325 |
'mandatory' => true,
|
| 12326 |
'value_url' => array(
|
| 12327 |
'allow_relative' => true,
|
| 12328 |
+
'protocol' => array(
|
| 12329 |
'https',
|
| 12330 |
),
|
| 12331 |
),
|
| 12348 |
'mandatory' => true,
|
| 12349 |
'value_url' => array(
|
| 12350 |
'allow_relative' => true,
|
| 12351 |
+
'protocol' => array(
|
| 12352 |
'https',
|
| 12353 |
),
|
| 12354 |
),
|
| 12372 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 12373 |
'value_url' => array(
|
| 12374 |
'allow_relative' => true,
|
| 12375 |
+
'protocol' => array(
|
| 12376 |
'https',
|
| 12377 |
),
|
| 12378 |
),
|
| 12449 |
'attr_spec_list' => array(
|
| 12450 |
'amp-custom' => array(
|
| 12451 |
'mandatory' => true,
|
| 12452 |
+
'value' => array(
|
| 12453 |
+
'',
|
| 12454 |
+
),
|
| 12455 |
),
|
| 12456 |
'nonce' => array(),
|
| 12457 |
'type' => array(
|
| 12458 |
+
'value_casei' => array(
|
| 12459 |
+
'text/css',
|
| 12460 |
+
),
|
| 12461 |
),
|
| 12462 |
),
|
| 12463 |
'cdata' => array(
|
| 12465 |
'error_message' => 'CSS !important',
|
| 12466 |
'regex' => '!important',
|
| 12467 |
),
|
| 12468 |
+
'css_spec' => array(
|
| 12469 |
+
'allowed_at_rules' => array(
|
| 12470 |
+
'font-face',
|
| 12471 |
+
'keyframes',
|
| 12472 |
+
'media',
|
| 12473 |
+
'page',
|
| 12474 |
+
'supports',
|
| 12475 |
+
),
|
| 12476 |
+
'declaration' => array(),
|
| 12477 |
+
'font_url_spec' => array(
|
| 12478 |
+
'allow_empty' => true,
|
| 12479 |
+
'protocol' => array(
|
| 12480 |
+
'https',
|
| 12481 |
+
'http',
|
| 12482 |
+
'data',
|
| 12483 |
+
),
|
| 12484 |
+
),
|
| 12485 |
+
'image_url_spec' => array(
|
| 12486 |
+
'allow_empty' => true,
|
| 12487 |
+
'protocol' => array(
|
| 12488 |
+
'https',
|
| 12489 |
+
'http',
|
| 12490 |
+
'data',
|
| 12491 |
+
'absolute',
|
| 12492 |
+
),
|
| 12493 |
+
),
|
| 12494 |
+
'validate_keyframes' => false,
|
| 12495 |
+
),
|
| 12496 |
'max_bytes' => 50000,
|
| 12497 |
'max_bytes_spec_url' => 'https://www.ampproject.org/docs/reference/spec#maximum-size',
|
| 12498 |
),
|
| 12503 |
'unique' => true,
|
| 12504 |
),
|
| 12505 |
),
|
| 12506 |
+
array(
|
| 12507 |
+
'attr_spec_list' => array(
|
| 12508 |
+
'nonce' => array(),
|
| 12509 |
+
),
|
| 12510 |
+
'cdata' => array(
|
| 12511 |
+
'cdata_regex' => 'body ?{opacity: ?0}',
|
| 12512 |
+
),
|
| 12513 |
+
'tag_spec' => array(
|
| 12514 |
+
'mandatory_alternatives' => 'head > style[amp-boilerplate]',
|
| 12515 |
+
'mandatory_parent' => 'head',
|
| 12516 |
+
'spec_name' => 'head > style[amp-boilerplate] - old variant',
|
| 12517 |
+
'spec_url' => 'https://github.com/ampproject/amphtml/blob/master/spec/amp-boilerplate.md',
|
| 12518 |
+
'unique' => true,
|
| 12519 |
+
),
|
| 12520 |
+
),
|
| 12521 |
array(
|
| 12522 |
'attr_spec_list' => array(
|
| 12523 |
'amp-boilerplate' => array(
|
| 12524 |
'dispatch_key' => 3,
|
| 12525 |
'mandatory' => true,
|
| 12526 |
+
'value' => array(
|
| 12527 |
+
'',
|
| 12528 |
+
),
|
| 12529 |
),
|
| 12530 |
'nonce' => array(),
|
| 12531 |
),
|
| 12532 |
'cdata' => array(
|
| 12533 |
+
'cdata_regex' => '\\s*body\\s*{\\s*-webkit-animation:\\s*-amp-start\\s+8s\\s+steps\\(1,\\s*end\\)\\s+0s\\s+1\\s+normal\\s+both;\\s*-moz-animation:\\s*-amp-start\\s+8s\\s+steps\\s*\\(1\\s*,\\s*end\\s*\\)\\s+0s\\s+1\\s+normal\\s+both;\\s*-ms-animation:\\s*-amp-start\\s+8s\\s+steps\\s*\\(1\\s*,\\s*end\\s*\\)\\s+0s\\s+1\\s+normal\\s+both;\\s*animation:\\s*-amp-start\\s+8s\\s+steps\\(1,\\s*end\\)\\s+0s\\s+1\\s+normal\\s+both;?\\s*}\\s*@-webkit-keyframes\\s+-amp-start\\s*{\\s*from\\s*{\\s*visibility:\\s*hidden;?\\s*}\\s*to\\s*{\\s*visibility:\\s*visible;?\\s*}\\s*}\\s*@-moz-keyframes\\s+-amp-start\\s*{\\s*from\\s*{\\s*visibility:\\s*hidden;?\\s*}\\s*to\\s*{\\s*visibility:\\s*visible;?\\s*}\\s*}\\s*@-ms-keyframes\\s+-amp-start\\s*{\\s*from\\s*{\\s*visibility:\\s*hidden;?\\s*}\\s*to\\s*{\\s*visibility:\\s*visible;?\\s*}\\s*}\\s*@-o-keyframes\\s+-amp-start\\s*{\\s*from\\s*{\\s*visibility:\\s*hidden;?\\s*}\\s*to\\s*{\\s*visibility:\\s*visible;?\\s*}\\s*}\\s*@keyframes\\s+-amp-start\\s*{\\s*from\\s*{\\s*visibility:\\s*hidden;?\\s*}\\s*to\\s*{\\s*visibility:\\s*visible;?\\s*}\\s*}\\s*',
|
| 12534 |
),
|
| 12535 |
'tag_spec' => array(
|
| 12536 |
'mandatory_alternatives' => 'head > style[amp-boilerplate]',
|
| 12545 |
'amp-boilerplate' => array(
|
| 12546 |
'dispatch_key' => 3,
|
| 12547 |
'mandatory' => true,
|
| 12548 |
+
'value' => array(
|
| 12549 |
+
'',
|
| 12550 |
+
),
|
| 12551 |
),
|
| 12552 |
'nonce' => array(),
|
| 12553 |
),
|
| 12554 |
'cdata' => array(
|
| 12555 |
+
'cdata_regex' => '\\s*body\\s*{\\s*-webkit-animation:\\s*none;\\s*-moz-animation:\\s*none;\\s*-ms-animation:\\s*none;\\s*animation:\\s*none;?\\s*}\\s*',
|
| 12556 |
),
|
| 12557 |
'tag_spec' => array(
|
| 12558 |
'mandatory_alternatives' => 'noscript > style[amp-boilerplate]',
|
| 12568 |
'amp-keyframes' => array(
|
| 12569 |
'dispatch_key' => 1,
|
| 12570 |
'mandatory' => true,
|
| 12571 |
+
'value' => array(
|
| 12572 |
+
'',
|
| 12573 |
+
),
|
| 12574 |
),
|
| 12575 |
),
|
| 12576 |
'cdata' => array(
|
| 12577 |
+
'css_spec' => array(
|
| 12578 |
+
'allowed_at_rules' => array(
|
| 12579 |
+
'keyframes',
|
| 12580 |
+
'media',
|
| 12581 |
+
'supports',
|
| 12582 |
+
),
|
| 12583 |
+
'declaration' => array(
|
| 12584 |
+
'animation-timing-function',
|
| 12585 |
+
'offset-distance',
|
| 12586 |
+
'opacity',
|
| 12587 |
+
'transform',
|
| 12588 |
+
'visibility',
|
| 12589 |
+
),
|
| 12590 |
+
'font_url_spec' => array(),
|
| 12591 |
+
'image_url_spec' => array(),
|
| 12592 |
+
'validate_keyframes' => true,
|
| 12593 |
+
),
|
| 12594 |
'max_bytes' => 500000,
|
| 12595 |
'max_bytes_spec_url' => 'https://www.ampproject.org/docs/reference/spec#keyframes-stylesheet',
|
| 12596 |
),
|
| 12640 |
'filter' => array(),
|
| 12641 |
'flood-color' => array(),
|
| 12642 |
'flood-opacity' => array(),
|
| 12643 |
+
'focusable' => array(),
|
| 12644 |
'font-family' => array(),
|
| 12645 |
'font-size' => array(),
|
| 12646 |
'font-size-adjust' => array(),
|
| 12676 |
'stroke-miterlimit' => array(),
|
| 12677 |
'stroke-opacity' => array(),
|
| 12678 |
'stroke-width' => array(),
|
| 12679 |
+
'style' => array(
|
| 12680 |
+
'blacklisted_value_regex' => '!important',
|
| 12681 |
+
),
|
| 12682 |
'systemlanguage' => array(),
|
| 12683 |
'text-anchor' => array(),
|
| 12684 |
'text-decoration' => array(),
|
| 12686 |
'unicode-bidi' => array(),
|
| 12687 |
'vector-effect' => array(),
|
| 12688 |
'version' => array(
|
| 12689 |
+
'value' => array(
|
| 12690 |
+
'1.0',
|
| 12691 |
+
'1.1',
|
| 12692 |
+
),
|
| 12693 |
),
|
| 12694 |
'viewbox' => array(),
|
| 12695 |
'visibility' => array(),
|
| 12733 |
'filter' => array(),
|
| 12734 |
'flood-color' => array(),
|
| 12735 |
'flood-opacity' => array(),
|
| 12736 |
+
'focusable' => array(),
|
| 12737 |
'font-family' => array(),
|
| 12738 |
'font-size' => array(),
|
| 12739 |
'font-size-adjust' => array(),
|
| 12815 |
'filter' => array(),
|
| 12816 |
'flood-color' => array(),
|
| 12817 |
'flood-opacity' => array(),
|
| 12818 |
+
'focusable' => array(),
|
| 12819 |
'font-family' => array(),
|
| 12820 |
'font-size' => array(),
|
| 12821 |
'font-size-adjust' => array(),
|
| 12877 |
'align' => array(),
|
| 12878 |
'bgcolor' => array(),
|
| 12879 |
'border' => array(
|
| 12880 |
+
'value' => array(
|
| 12881 |
+
'0',
|
| 12882 |
+
'1',
|
| 12883 |
+
),
|
| 12884 |
),
|
| 12885 |
'cellpadding' => array(),
|
| 12886 |
'cellspacing' => array(),
|
| 12912 |
),
|
| 12913 |
),
|
| 12914 |
'template' => array(
|
| 12915 |
+
array(
|
| 12916 |
+
'attr_spec_list' => array(
|
| 12917 |
+
'date-template' => array(
|
| 12918 |
+
'dispatch_key' => 1,
|
| 12919 |
+
'mandatory' => true,
|
| 12920 |
+
'value' => array(
|
| 12921 |
+
'',
|
| 12922 |
+
),
|
| 12923 |
+
),
|
| 12924 |
+
'dates' => array(),
|
| 12925 |
+
'default' => array(),
|
| 12926 |
+
'type' => array(
|
| 12927 |
+
'mandatory' => true,
|
| 12928 |
+
'value' => array(
|
| 12929 |
+
'amp-mustache',
|
| 12930 |
+
),
|
| 12931 |
+
),
|
| 12932 |
+
),
|
| 12933 |
+
'tag_spec' => array(
|
| 12934 |
+
'mandatory_parent' => 'amp-date-picker',
|
| 12935 |
+
'requires_extension' => array(
|
| 12936 |
+
'amp-mustache',
|
| 12937 |
+
),
|
| 12938 |
+
'spec_name' => 'amp-date-picker > template [date-template]',
|
| 12939 |
+
),
|
| 12940 |
+
),
|
| 12941 |
+
array(
|
| 12942 |
+
'attr_spec_list' => array(
|
| 12943 |
+
'info-template' => array(
|
| 12944 |
+
'dispatch_key' => 1,
|
| 12945 |
+
'mandatory' => true,
|
| 12946 |
+
),
|
| 12947 |
+
'type' => array(
|
| 12948 |
+
'mandatory' => true,
|
| 12949 |
+
'value' => array(
|
| 12950 |
+
'amp-mustache',
|
| 12951 |
+
),
|
| 12952 |
+
),
|
| 12953 |
+
),
|
| 12954 |
+
'tag_spec' => array(
|
| 12955 |
+
'mandatory_parent' => 'amp-date-picker',
|
| 12956 |
+
'requires_extension' => array(
|
| 12957 |
+
'amp-mustache',
|
| 12958 |
+
),
|
| 12959 |
+
'spec_name' => 'amp-date-picker > template [info-template]',
|
| 12960 |
+
),
|
| 12961 |
+
),
|
| 12962 |
array(
|
| 12963 |
'attr_spec_list' => array(
|
| 12964 |
'type' => array(
|
| 12965 |
'mandatory' => true,
|
| 12966 |
+
'value' => array(
|
| 12967 |
+
'amp-mustache',
|
| 12968 |
+
),
|
| 12969 |
),
|
| 12970 |
),
|
| 12971 |
'tag_spec' => array(
|
| 12972 |
'disallowed_ancestor' => array(
|
| 12973 |
'template',
|
| 12974 |
+
'amp-date-picker',
|
| 12975 |
'amp-story-auto-ads',
|
| 12976 |
+
'form div [submit-success][template]',
|
| 12977 |
+
'form div [submit-error][template]',
|
| 12978 |
+
'form div [submitting][template]',
|
| 12979 |
+
'form div [verify-error][template]',
|
| 12980 |
),
|
| 12981 |
'requires_extension' => array(
|
| 12982 |
'amp-mustache',
|
| 12986 |
array(
|
| 12987 |
'attr_spec_list' => array(
|
| 12988 |
'type' => array(
|
| 12989 |
+
'dispatch_key' => 3,
|
| 12990 |
'mandatory' => true,
|
| 12991 |
+
'value' => array(
|
| 12992 |
+
'amp-mustache',
|
| 12993 |
+
),
|
| 12994 |
),
|
| 12995 |
),
|
| 12996 |
'tag_spec' => array(
|
| 12997 |
'mandatory_parent' => 'amp-story-auto-ads',
|
| 12998 |
+
'reference_points' => array(
|
| 12999 |
+
'AMP-STORY-GRID-LAYER animate-in' => array(
|
| 13000 |
+
'mandatory' => false,
|
| 13001 |
+
'unique' => false,
|
| 13002 |
+
),
|
| 13003 |
+
'AMP-STORY-GRID-LAYER default' => array(
|
| 13004 |
+
'mandatory' => false,
|
| 13005 |
+
'unique' => false,
|
| 13006 |
+
),
|
| 13007 |
+
),
|
| 13008 |
'requires_extension' => array(
|
| 13009 |
'amp-mustache',
|
| 13010 |
),
|
| 13039 |
'filter' => array(),
|
| 13040 |
'flood-color' => array(),
|
| 13041 |
'flood-opacity' => array(),
|
| 13042 |
+
'focusable' => array(),
|
| 13043 |
'font-family' => array(),
|
| 13044 |
'font-size' => array(),
|
| 13045 |
'font-size-adjust' => array(),
|
| 13129 |
'name' => array(
|
| 13130 |
'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
|
| 13131 |
),
|
| 13132 |
+
'no-verify' => array(
|
| 13133 |
+
'value' => array(
|
| 13134 |
+
'',
|
| 13135 |
+
),
|
| 13136 |
+
),
|
| 13137 |
'placeholder' => array(),
|
| 13138 |
'readonly' => array(),
|
| 13139 |
'required' => array(),
|
| 13174 |
'filter' => array(),
|
| 13175 |
'flood-color' => array(),
|
| 13176 |
'flood-opacity' => array(),
|
| 13177 |
+
'focusable' => array(),
|
| 13178 |
'font-family' => array(),
|
| 13179 |
'font-size' => array(),
|
| 13180 |
'font-size-adjust' => array(),
|
| 13231 |
),
|
| 13232 |
'value_url' => array(
|
| 13233 |
'allow_empty' => false,
|
| 13234 |
+
'protocol' => array(
|
|
|
|
| 13235 |
'http',
|
| 13236 |
'https',
|
| 13237 |
),
|
| 13292 |
),
|
| 13293 |
'title' => array(
|
| 13294 |
array(
|
| 13295 |
+
'attr_spec_list' => array(
|
| 13296 |
+
'[text]' => array(),
|
| 13297 |
+
),
|
| 13298 |
'tag_spec' => array(
|
| 13299 |
'spec_name' => 'title',
|
| 13300 |
),
|
| 13331 |
array(
|
| 13332 |
'attr_spec_list' => array(
|
| 13333 |
'default' => array(
|
| 13334 |
+
'value' => array(
|
| 13335 |
+
'',
|
| 13336 |
+
),
|
| 13337 |
),
|
| 13338 |
'kind' => array(
|
| 13339 |
+
'value' => array(
|
| 13340 |
+
'captions',
|
| 13341 |
+
'chapters',
|
| 13342 |
+
'descriptions',
|
| 13343 |
+
'metadata',
|
| 13344 |
+
),
|
| 13345 |
),
|
| 13346 |
'label' => array(),
|
| 13347 |
'src' => array(
|
| 13349 |
'mandatory' => true,
|
| 13350 |
'value_url' => array(
|
| 13351 |
'allow_relative' => false,
|
| 13352 |
+
'protocol' => array(
|
| 13353 |
'https',
|
| 13354 |
),
|
| 13355 |
),
|
| 13364 |
array(
|
| 13365 |
'attr_spec_list' => array(
|
| 13366 |
'default' => array(
|
| 13367 |
+
'value' => array(
|
| 13368 |
+
'',
|
| 13369 |
+
),
|
| 13370 |
),
|
| 13371 |
'kind' => array(
|
| 13372 |
'mandatory' => true,
|
| 13373 |
+
'value_casei' => array(
|
| 13374 |
+
'subtitles',
|
| 13375 |
+
),
|
| 13376 |
),
|
| 13377 |
'label' => array(),
|
| 13378 |
'src' => array(
|
| 13380 |
'mandatory' => true,
|
| 13381 |
'value_url' => array(
|
| 13382 |
'allow_relative' => false,
|
| 13383 |
+
'protocol' => array(
|
| 13384 |
'https',
|
| 13385 |
),
|
| 13386 |
),
|
| 13397 |
array(
|
| 13398 |
'attr_spec_list' => array(
|
| 13399 |
'default' => array(
|
| 13400 |
+
'value' => array(
|
| 13401 |
+
'',
|
| 13402 |
+
),
|
| 13403 |
),
|
| 13404 |
'kind' => array(
|
| 13405 |
+
'value' => array(
|
| 13406 |
+
'captions',
|
| 13407 |
+
'chapters',
|
| 13408 |
+
'descriptions',
|
| 13409 |
+
'metadata',
|
| 13410 |
+
),
|
| 13411 |
),
|
| 13412 |
'label' => array(),
|
| 13413 |
'src' => array(
|
| 13415 |
'mandatory' => true,
|
| 13416 |
'value_url' => array(
|
| 13417 |
'allow_relative' => false,
|
| 13418 |
+
'protocol' => array(
|
| 13419 |
'https',
|
| 13420 |
),
|
| 13421 |
),
|
| 13430 |
array(
|
| 13431 |
'attr_spec_list' => array(
|
| 13432 |
'default' => array(
|
| 13433 |
+
'value' => array(
|
| 13434 |
+
'',
|
| 13435 |
+
),
|
| 13436 |
),
|
| 13437 |
'kind' => array(
|
| 13438 |
'mandatory' => true,
|
| 13439 |
+
'value_casei' => array(
|
| 13440 |
+
'subtitles',
|
| 13441 |
+
),
|
| 13442 |
),
|
| 13443 |
'label' => array(),
|
| 13444 |
'src' => array(
|
| 13446 |
'mandatory' => true,
|
| 13447 |
'value_url' => array(
|
| 13448 |
'allow_relative' => false,
|
| 13449 |
+
'protocol' => array(
|
| 13450 |
'https',
|
| 13451 |
),
|
| 13452 |
),
|
| 13466 |
'[src]' => array(),
|
| 13467 |
'[srclang]' => array(),
|
| 13468 |
'default' => array(
|
| 13469 |
+
'value' => array(
|
| 13470 |
+
'',
|
| 13471 |
+
),
|
| 13472 |
),
|
| 13473 |
'kind' => array(
|
| 13474 |
+
'value' => array(
|
| 13475 |
+
'captions',
|
| 13476 |
+
'chapters',
|
| 13477 |
+
'descriptions',
|
| 13478 |
+
'metadata',
|
| 13479 |
+
),
|
| 13480 |
),
|
| 13481 |
'label' => array(),
|
| 13482 |
'src' => array(
|
| 13484 |
'mandatory' => true,
|
| 13485 |
'value_url' => array(
|
| 13486 |
'allow_relative' => false,
|
| 13487 |
+
'protocol' => array(
|
| 13488 |
'https',
|
| 13489 |
),
|
| 13490 |
),
|
| 13502 |
'[src]' => array(),
|
| 13503 |
'[srclang]' => array(),
|
| 13504 |
'default' => array(
|
| 13505 |
+
'value' => array(
|
| 13506 |
+
'',
|
| 13507 |
+
),
|
| 13508 |
),
|
| 13509 |
'kind' => array(
|
| 13510 |
'mandatory' => true,
|
| 13511 |
+
'value_casei' => array(
|
| 13512 |
+
'subtitles',
|
| 13513 |
+
),
|
| 13514 |
),
|
| 13515 |
'label' => array(),
|
| 13516 |
'src' => array(
|
| 13518 |
'mandatory' => true,
|
| 13519 |
'value_url' => array(
|
| 13520 |
'allow_relative' => false,
|
| 13521 |
+
'protocol' => array(
|
| 13522 |
'https',
|
| 13523 |
),
|
| 13524 |
),
|
| 13538 |
'[src]' => array(),
|
| 13539 |
'[srclang]' => array(),
|
| 13540 |
'default' => array(
|
| 13541 |
+
'value' => array(
|
| 13542 |
+
'',
|
| 13543 |
+
),
|
| 13544 |
),
|
| 13545 |
'kind' => array(
|
| 13546 |
+
'value' => array(
|
| 13547 |
+
'captions',
|
| 13548 |
+
'chapters',
|
| 13549 |
+
'descriptions',
|
| 13550 |
+
'metadata',
|
| 13551 |
+
),
|
| 13552 |
),
|
| 13553 |
'label' => array(),
|
| 13554 |
'src' => array(
|
| 13556 |
'mandatory' => true,
|
| 13557 |
'value_url' => array(
|
| 13558 |
'allow_relative' => false,
|
| 13559 |
+
'protocol' => array(
|
| 13560 |
'https',
|
| 13561 |
),
|
| 13562 |
),
|
| 13574 |
'[src]' => array(),
|
| 13575 |
'[srclang]' => array(),
|
| 13576 |
'default' => array(
|
| 13577 |
+
'value' => array(
|
| 13578 |
+
'',
|
| 13579 |
+
),
|
| 13580 |
),
|
| 13581 |
'kind' => array(
|
| 13582 |
'mandatory' => true,
|
| 13583 |
+
'value_casei' => array(
|
| 13584 |
+
'subtitles',
|
| 13585 |
+
),
|
| 13586 |
),
|
| 13587 |
'label' => array(),
|
| 13588 |
'src' => array(
|
| 13590 |
'mandatory' => true,
|
| 13591 |
'value_url' => array(
|
| 13592 |
'allow_relative' => false,
|
| 13593 |
+
'protocol' => array(
|
| 13594 |
'https',
|
| 13595 |
),
|
| 13596 |
),
|
| 13610 |
'[src]' => array(),
|
| 13611 |
'[srclang]' => array(),
|
| 13612 |
'default' => array(
|
| 13613 |
+
'value' => array(
|
| 13614 |
+
'',
|
| 13615 |
+
),
|
| 13616 |
),
|
| 13617 |
'kind' => array(
|
| 13618 |
'mandatory' => true,
|
| 13619 |
+
'value_casei' => array(
|
| 13620 |
+
'subtitles',
|
| 13621 |
+
),
|
| 13622 |
),
|
| 13623 |
'label' => array(),
|
| 13624 |
'src' => array(
|
| 13626 |
'mandatory' => true,
|
| 13627 |
'value_url' => array(
|
| 13628 |
'allow_relative' => false,
|
| 13629 |
+
'protocol' => array(
|
| 13630 |
'https',
|
| 13631 |
),
|
| 13632 |
),
|
| 13667 |
'filter' => array(),
|
| 13668 |
'flood-color' => array(),
|
| 13669 |
'flood-opacity' => array(),
|
| 13670 |
+
'focusable' => array(),
|
| 13671 |
'font-family' => array(),
|
| 13672 |
'font-size' => array(),
|
| 13673 |
'font-size-adjust' => array(),
|
| 13721 |
),
|
| 13722 |
'value_url' => array(
|
| 13723 |
'allow_empty' => false,
|
| 13724 |
+
'protocol' => array(
|
|
|
|
| 13725 |
'http',
|
| 13726 |
'https',
|
| 13727 |
),
|
| 13769 |
'filter' => array(),
|
| 13770 |
'flood-color' => array(),
|
| 13771 |
'flood-opacity' => array(),
|
| 13772 |
+
'focusable' => array(),
|
| 13773 |
'font-family' => array(),
|
| 13774 |
'font-size' => array(),
|
| 13775 |
'font-size-adjust' => array(),
|
| 13874 |
'filter' => array(),
|
| 13875 |
'flood-color' => array(),
|
| 13876 |
'flood-opacity' => array(),
|
| 13877 |
+
'focusable' => array(),
|
| 13878 |
'font-family' => array(),
|
| 13879 |
'font-size' => array(),
|
| 13880 |
'font-size-adjust' => array(),
|
| 13932 |
),
|
| 13933 |
'value_url' => array(
|
| 13934 |
'allow_empty' => false,
|
| 13935 |
+
'protocol' => array(
|
|
|
|
| 13936 |
'http',
|
| 13937 |
'https',
|
| 13938 |
),
|
| 13975 |
'blacklisted_value_regex' => '__amp_source_origin',
|
| 13976 |
'value_url' => array(
|
| 13977 |
'allow_relative' => false,
|
| 13978 |
+
'protocol' => array(
|
| 13979 |
'data',
|
| 13980 |
'https',
|
| 13981 |
),
|
| 14040 |
'tag_spec' => array(),
|
| 14041 |
),
|
| 14042 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14043 |
);
|
| 14044 |
|
| 14045 |
private static $layout_allowed_attrs = array(
|
| 14106 |
'amp-access-style' => array(),
|
| 14107 |
'amp-access-template' => array(),
|
| 14108 |
'amp-fx' => array(
|
| 14109 |
+
'value_regex_casei' => '(fade-in|fade-in-scroll|fly-in-bottom|fly-in-left|fly-in-right|fly-in-top|parallax)(\\s|fade-in|fade-in-scroll|fly-in-bottom|fly-in-left|fly-in-right|fly-in-top|parallax)*',
|
| 14110 |
),
|
| 14111 |
'aria-activedescendant' => array(),
|
| 14112 |
'aria-atomic' => array(),
|
| 14152 |
'dir' => array(),
|
| 14153 |
'draggable' => array(),
|
| 14154 |
'fallback' => array(
|
| 14155 |
+
'value' => array(
|
| 14156 |
+
'',
|
| 14157 |
+
),
|
| 14158 |
),
|
| 14159 |
'hidden' => array(
|
| 14160 |
+
'value' => array(
|
| 14161 |
+
'',
|
| 14162 |
+
),
|
| 14163 |
),
|
| 14164 |
'i-amp-access-id' => array(),
|
| 14165 |
'id' => array(
|
| 14172 |
'itemscope' => array(),
|
| 14173 |
'itemtype' => array(),
|
| 14174 |
'lang' => array(),
|
|
|
|
| 14175 |
'on' => array(),
|
| 14176 |
'overflow' => array(),
|
| 14177 |
'placeholder' => array(
|
| 14178 |
+
'value' => array(
|
| 14179 |
+
'',
|
| 14180 |
+
),
|
| 14181 |
),
|
| 14182 |
'prefix' => array(),
|
| 14183 |
'property' => array(),
|
| 14187 |
'resource' => array(),
|
| 14188 |
'rev' => array(),
|
| 14189 |
'role' => array(),
|
| 14190 |
+
'style' => array(
|
| 14191 |
+
'blacklisted_value_regex' => '(!important|<!--)',
|
| 14192 |
+
),
|
| 14193 |
'subscriptions-action' => array(),
|
| 14194 |
'subscriptions-actions' => array(
|
| 14195 |
+
'value' => array(
|
| 14196 |
+
'',
|
| 14197 |
+
),
|
| 14198 |
),
|
| 14199 |
+
'subscriptions-decorate' => array(),
|
| 14200 |
'subscriptions-dialog' => array(
|
| 14201 |
+
'value' => array(
|
| 14202 |
+
'',
|
| 14203 |
+
),
|
| 14204 |
),
|
| 14205 |
'subscriptions-display' => array(),
|
| 14206 |
'subscriptions-section' => array(
|
| 14207 |
+
'value_casei' => array(
|
| 14208 |
+
'actions',
|
| 14209 |
+
'content',
|
| 14210 |
+
'content-not-granted',
|
| 14211 |
+
'loading',
|
| 14212 |
+
),
|
| 14213 |
),
|
| 14214 |
'subscriptions-service' => array(),
|
| 14215 |
'tabindex' => array(),
|
| 14218 |
'typeof' => array(),
|
| 14219 |
'validation-for' => array(),
|
| 14220 |
'visible-when-invalid' => array(
|
| 14221 |
+
'value' => array(
|
| 14222 |
+
'badInput',
|
| 14223 |
+
'customError',
|
| 14224 |
+
'patternMismatch',
|
| 14225 |
+
'rangeOverflow',
|
| 14226 |
+
'rangeUnderflow',
|
| 14227 |
+
'stepMismatch',
|
| 14228 |
+
'tooLong',
|
| 14229 |
+
'typeMismatch',
|
| 14230 |
+
'valueMissing',
|
| 14231 |
+
),
|
| 14232 |
),
|
| 14233 |
'vocab' => array(),
|
| 14234 |
);
|
| 14235 |
|
| 14236 |
|
| 14237 |
+
private static $reference_points = array(
|
| 14238 |
+
'AMP-CAROUSEL lightbox [child]' => array(
|
| 14239 |
+
'attr_spec_list' => array(
|
| 14240 |
+
'lightbox-thumbnail-id' => array(
|
| 14241 |
+
'value_regex_casei' => '^[a-z][a-z\\d_-]*',
|
| 14242 |
+
),
|
| 14243 |
+
),
|
| 14244 |
+
'tag_spec' => array(
|
| 14245 |
+
'spec_name' => 'AMP-CAROUSEL lightbox [child]',
|
| 14246 |
+
),
|
| 14247 |
+
),
|
| 14248 |
+
'AMP-CAROUSEL lightbox [lightbox-exclude]' => array(
|
| 14249 |
+
'attr_spec_list' => array(
|
| 14250 |
+
'lightbox-exclude' => array(
|
| 14251 |
+
'mandatory' => true,
|
| 14252 |
+
),
|
| 14253 |
+
),
|
| 14254 |
+
'tag_spec' => array(
|
| 14255 |
+
'spec_name' => 'AMP-CAROUSEL lightbox [lightbox-exclude]',
|
| 14256 |
+
),
|
| 14257 |
+
),
|
| 14258 |
+
'AMP-LIVE-LIST [items]' => array(
|
| 14259 |
+
'attr_spec_list' => array(
|
| 14260 |
+
'items' => array(
|
| 14261 |
+
'mandatory' => true,
|
| 14262 |
+
),
|
| 14263 |
+
),
|
| 14264 |
+
'tag_spec' => array(
|
| 14265 |
+
'reference_points' => array(
|
| 14266 |
+
'AMP-LIVE-LIST [items] item' => array(
|
| 14267 |
+
'mandatory' => false,
|
| 14268 |
+
'unique' => false,
|
| 14269 |
+
),
|
| 14270 |
+
),
|
| 14271 |
+
'spec_name' => 'AMP-LIVE-LIST [items]',
|
| 14272 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-live-list#items',
|
| 14273 |
+
),
|
| 14274 |
+
),
|
| 14275 |
+
'AMP-LIVE-LIST [items] item' => array(
|
| 14276 |
+
'attr_spec_list' => array(
|
| 14277 |
+
'data-sort-time' => array(
|
| 14278 |
+
'mandatory' => true,
|
| 14279 |
+
),
|
| 14280 |
+
'data-tombstone' => array(),
|
| 14281 |
+
'data-update-time' => array(),
|
| 14282 |
+
'id' => array(
|
| 14283 |
+
'mandatory' => true,
|
| 14284 |
+
),
|
| 14285 |
+
),
|
| 14286 |
+
'tag_spec' => array(
|
| 14287 |
+
'spec_name' => 'AMP-LIVE-LIST [items] item',
|
| 14288 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-live-list#items',
|
| 14289 |
+
),
|
| 14290 |
+
),
|
| 14291 |
+
'AMP-LIVE-LIST [pagination]' => array(
|
| 14292 |
+
'attr_spec_list' => array(
|
| 14293 |
+
'pagination' => array(
|
| 14294 |
+
'mandatory' => true,
|
| 14295 |
+
),
|
| 14296 |
+
),
|
| 14297 |
+
'tag_spec' => array(
|
| 14298 |
+
'spec_name' => 'AMP-LIVE-LIST [pagination]',
|
| 14299 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-live-list#pagination',
|
| 14300 |
+
),
|
| 14301 |
+
),
|
| 14302 |
+
'AMP-LIVE-LIST [update]' => array(
|
| 14303 |
+
'attr_spec_list' => array(
|
| 14304 |
+
'update' => array(
|
| 14305 |
+
'mandatory' => true,
|
| 14306 |
+
),
|
| 14307 |
+
),
|
| 14308 |
+
'tag_spec' => array(
|
| 14309 |
+
'spec_name' => 'AMP-LIVE-LIST [update]',
|
| 14310 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-live-list#update',
|
| 14311 |
+
),
|
| 14312 |
+
),
|
| 14313 |
+
'AMP-NEXT-PAGE > [separator]' => array(
|
| 14314 |
+
'attr_spec_list' => array(
|
| 14315 |
+
'separator' => array(
|
| 14316 |
+
'mandatory' => true,
|
| 14317 |
+
),
|
| 14318 |
+
),
|
| 14319 |
+
'tag_spec' => array(
|
| 14320 |
+
'mandatory_parent' => 'amp-next-page',
|
| 14321 |
+
'spec_name' => 'AMP-NEXT-PAGE > [separator]',
|
| 14322 |
+
),
|
| 14323 |
+
),
|
| 14324 |
+
'AMP-SELECTOR child' => array(
|
| 14325 |
+
'attr_spec_list' => array(),
|
| 14326 |
+
'tag_spec' => array(
|
| 14327 |
+
'reference_points' => array(
|
| 14328 |
+
'AMP-SELECTOR child' => array(
|
| 14329 |
+
'mandatory' => false,
|
| 14330 |
+
'unique' => false,
|
| 14331 |
+
),
|
| 14332 |
+
'AMP-SELECTOR option' => array(
|
| 14333 |
+
'mandatory' => false,
|
| 14334 |
+
'unique' => false,
|
| 14335 |
+
),
|
| 14336 |
+
),
|
| 14337 |
+
'spec_name' => 'AMP-SELECTOR child',
|
| 14338 |
+
),
|
| 14339 |
+
),
|
| 14340 |
+
'AMP-SELECTOR option' => array(
|
| 14341 |
+
'attr_spec_list' => array(
|
| 14342 |
+
'disabled' => array(
|
| 14343 |
+
'value' => array(
|
| 14344 |
+
'',
|
| 14345 |
+
),
|
| 14346 |
+
),
|
| 14347 |
+
'option' => array(
|
| 14348 |
+
'mandatory' => true,
|
| 14349 |
+
),
|
| 14350 |
+
'selected' => array(
|
| 14351 |
+
'value' => array(
|
| 14352 |
+
'',
|
| 14353 |
+
),
|
| 14354 |
+
),
|
| 14355 |
+
),
|
| 14356 |
+
'tag_spec' => array(
|
| 14357 |
+
'spec_name' => 'AMP-SELECTOR option',
|
| 14358 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-selector',
|
| 14359 |
+
),
|
| 14360 |
+
),
|
| 14361 |
+
'AMP-STORY-CTA-LAYER animate-in' => array(
|
| 14362 |
+
'attr_spec_list' => array(
|
| 14363 |
+
'animate-in' => array(
|
| 14364 |
+
'value' => array(
|
| 14365 |
+
'drop',
|
| 14366 |
+
'fade-in',
|
| 14367 |
+
'fly-in-bottom',
|
| 14368 |
+
'fly-in-left',
|
| 14369 |
+
'fly-in-right',
|
| 14370 |
+
'fly-in-top',
|
| 14371 |
+
'pan-down',
|
| 14372 |
+
'pan-left',
|
| 14373 |
+
'pan-right',
|
| 14374 |
+
'pan-up',
|
| 14375 |
+
'pulse',
|
| 14376 |
+
'rotate-in-left',
|
| 14377 |
+
'rotate-in-right',
|
| 14378 |
+
'twirl-in',
|
| 14379 |
+
'whoosh-in-left',
|
| 14380 |
+
'whoosh-in-right',
|
| 14381 |
+
'zoom-in',
|
| 14382 |
+
'zoom-out',
|
| 14383 |
+
),
|
| 14384 |
+
),
|
| 14385 |
+
'animate-in-after' => array(),
|
| 14386 |
+
'animate-in-delay' => array(),
|
| 14387 |
+
'animate-in-duration' => array(),
|
| 14388 |
+
),
|
| 14389 |
+
'tag_spec' => array(
|
| 14390 |
+
'reference_points' => array(
|
| 14391 |
+
'AMP-STORY-CTA-LAYER animate-in' => array(
|
| 14392 |
+
'mandatory' => false,
|
| 14393 |
+
'unique' => false,
|
| 14394 |
+
),
|
| 14395 |
+
),
|
| 14396 |
+
'spec_name' => 'AMP-STORY-CTA-LAYER animate-in',
|
| 14397 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-story',
|
| 14398 |
+
),
|
| 14399 |
+
),
|
| 14400 |
+
'AMP-STORY-GRID-LAYER animate-in' => array(
|
| 14401 |
+
'attr_spec_list' => array(
|
| 14402 |
+
'animate-in' => array(
|
| 14403 |
+
'value' => array(
|
| 14404 |
+
'drop',
|
| 14405 |
+
'fade-in',
|
| 14406 |
+
'fly-in-bottom',
|
| 14407 |
+
'fly-in-left',
|
| 14408 |
+
'fly-in-right',
|
| 14409 |
+
'fly-in-top',
|
| 14410 |
+
'pan-down',
|
| 14411 |
+
'pan-left',
|
| 14412 |
+
'pan-right',
|
| 14413 |
+
'pan-up',
|
| 14414 |
+
'pulse',
|
| 14415 |
+
'rotate-in-left',
|
| 14416 |
+
'rotate-in-right',
|
| 14417 |
+
'twirl-in',
|
| 14418 |
+
'whoosh-in-left',
|
| 14419 |
+
'whoosh-in-right',
|
| 14420 |
+
'zoom-in',
|
| 14421 |
+
'zoom-out',
|
| 14422 |
+
),
|
| 14423 |
+
),
|
| 14424 |
+
'animate-in-after' => array(),
|
| 14425 |
+
'animate-in-delay' => array(),
|
| 14426 |
+
'animate-in-duration' => array(),
|
| 14427 |
+
'data-tooltip-icon' => array(
|
| 14428 |
+
'value_url' => array(
|
| 14429 |
+
'protocol' => array(
|
| 14430 |
+
'http',
|
| 14431 |
+
'https',
|
| 14432 |
+
'data',
|
| 14433 |
+
),
|
| 14434 |
+
),
|
| 14435 |
+
),
|
| 14436 |
+
'target' => array(
|
| 14437 |
+
'value' => array(
|
| 14438 |
+
'_blank',
|
| 14439 |
+
),
|
| 14440 |
+
),
|
| 14441 |
+
),
|
| 14442 |
+
'tag_spec' => array(
|
| 14443 |
+
'reference_points' => array(
|
| 14444 |
+
'AMP-STORY-GRID-LAYER animate-in' => array(
|
| 14445 |
+
'mandatory' => false,
|
| 14446 |
+
'unique' => false,
|
| 14447 |
+
),
|
| 14448 |
+
),
|
| 14449 |
+
'spec_name' => 'AMP-STORY-GRID-LAYER animate-in',
|
| 14450 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-story',
|
| 14451 |
+
),
|
| 14452 |
+
),
|
| 14453 |
+
'AMP-STORY-GRID-LAYER default' => array(
|
| 14454 |
+
'attr_spec_list' => array(
|
| 14455 |
+
'align-content' => array(
|
| 14456 |
+
'value' => array(
|
| 14457 |
+
'center',
|
| 14458 |
+
'end',
|
| 14459 |
+
'space-around',
|
| 14460 |
+
'space-between',
|
| 14461 |
+
'space-evenly',
|
| 14462 |
+
'start',
|
| 14463 |
+
'stretch',
|
| 14464 |
+
),
|
| 14465 |
+
),
|
| 14466 |
+
'align-items' => array(
|
| 14467 |
+
'value' => array(
|
| 14468 |
+
'center',
|
| 14469 |
+
'end',
|
| 14470 |
+
'start',
|
| 14471 |
+
'stretch',
|
| 14472 |
+
),
|
| 14473 |
+
),
|
| 14474 |
+
'align-self' => array(
|
| 14475 |
+
'value' => array(
|
| 14476 |
+
'center',
|
| 14477 |
+
'end',
|
| 14478 |
+
'start',
|
| 14479 |
+
'stretch',
|
| 14480 |
+
),
|
| 14481 |
+
),
|
| 14482 |
+
'animate-in' => array(
|
| 14483 |
+
'value' => array(
|
| 14484 |
+
'drop',
|
| 14485 |
+
'fade-in',
|
| 14486 |
+
'fly-in-bottom',
|
| 14487 |
+
'fly-in-left',
|
| 14488 |
+
'fly-in-right',
|
| 14489 |
+
'fly-in-top',
|
| 14490 |
+
'pan-down',
|
| 14491 |
+
'pan-left',
|
| 14492 |
+
'pan-right',
|
| 14493 |
+
'pan-up',
|
| 14494 |
+
'pulse',
|
| 14495 |
+
'rotate-in-left',
|
| 14496 |
+
'rotate-in-right',
|
| 14497 |
+
'twirl-in',
|
| 14498 |
+
'whoosh-in-left',
|
| 14499 |
+
'whoosh-in-right',
|
| 14500 |
+
'zoom-in',
|
| 14501 |
+
'zoom-out',
|
| 14502 |
+
),
|
| 14503 |
+
),
|
| 14504 |
+
'animate-in-after' => array(),
|
| 14505 |
+
'animate-in-delay' => array(),
|
| 14506 |
+
'animate-in-duration' => array(),
|
| 14507 |
+
'data-tooltip-icon' => array(
|
| 14508 |
+
'value_url' => array(
|
| 14509 |
+
'protocol' => array(
|
| 14510 |
+
'http',
|
| 14511 |
+
'https',
|
| 14512 |
+
'data',
|
| 14513 |
+
),
|
| 14514 |
+
),
|
| 14515 |
+
),
|
| 14516 |
+
'grid-area' => array(),
|
| 14517 |
+
'justify-content' => array(
|
| 14518 |
+
'value' => array(
|
| 14519 |
+
'center',
|
| 14520 |
+
'end',
|
| 14521 |
+
'space-around',
|
| 14522 |
+
'space-between',
|
| 14523 |
+
'space-evenly',
|
| 14524 |
+
'start',
|
| 14525 |
+
'stretch',
|
| 14526 |
+
),
|
| 14527 |
+
),
|
| 14528 |
+
'justify-items' => array(
|
| 14529 |
+
'value' => array(
|
| 14530 |
+
'center',
|
| 14531 |
+
'end',
|
| 14532 |
+
'start',
|
| 14533 |
+
'stretch',
|
| 14534 |
+
),
|
| 14535 |
+
),
|
| 14536 |
+
'justify-self' => array(
|
| 14537 |
+
'value' => array(
|
| 14538 |
+
'center',
|
| 14539 |
+
'end',
|
| 14540 |
+
'start',
|
| 14541 |
+
'stretch',
|
| 14542 |
+
),
|
| 14543 |
+
),
|
| 14544 |
+
'target' => array(
|
| 14545 |
+
'value' => array(
|
| 14546 |
+
'_blank',
|
| 14547 |
+
),
|
| 14548 |
+
),
|
| 14549 |
+
),
|
| 14550 |
+
'tag_spec' => array(
|
| 14551 |
+
'reference_points' => array(
|
| 14552 |
+
'AMP-STORY-GRID-LAYER animate-in' => array(
|
| 14553 |
+
'mandatory' => false,
|
| 14554 |
+
'unique' => false,
|
| 14555 |
+
),
|
| 14556 |
+
),
|
| 14557 |
+
'spec_name' => 'AMP-STORY-GRID-LAYER default',
|
| 14558 |
+
'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-story',
|
| 14559 |
+
),
|
| 14560 |
+
),
|
| 14561 |
+
);
|
| 14562 |
+
|
| 14563 |
+
|
| 14564 |
/**
|
| 14565 |
* Get allowed tags.
|
| 14566 |
*
|
| 14587 |
return null;
|
| 14588 |
}
|
| 14589 |
|
| 14590 |
+
/**
|
| 14591 |
+
* Get reference point spec.
|
| 14592 |
+
*
|
| 14593 |
+
* @since 1.0
|
| 14594 |
+
* @param string $tag_spec_name Tag spec name.
|
| 14595 |
+
* @return array|null Reference point spec, or null if does not exist.
|
| 14596 |
+
*/
|
| 14597 |
+
public static function get_reference_point_spec( $tag_spec_name ) {
|
| 14598 |
+
if ( isset( self::$reference_points[ $tag_spec_name ] ) ) {
|
| 14599 |
+
return self::$reference_points[ $tag_spec_name ];
|
| 14600 |
+
}
|
| 14601 |
+
return null;
|
| 14602 |
+
}
|
| 14603 |
+
|
| 14604 |
/**
|
| 14605 |
* Get list of globally-allowed attributes.
|
| 14606 |
*
|
|
@@ -20,6 +20,17 @@ class AMP_Audio_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 20 |
*/
|
| 21 |
public static $tag = 'audio';
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
/**
|
| 24 |
* Sanitize the <audio> elements from the HTML contained in this instance's DOMDocument.
|
| 25 |
*
|
|
@@ -34,7 +45,9 @@ class AMP_Audio_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 34 |
|
| 35 |
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 36 |
$node = $nodes->item( $i );
|
|
|
|
| 37 |
$old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
|
|
|
| 38 |
|
| 39 |
$new_attributes = $this->filter_attributes( $old_attributes );
|
| 40 |
|
|
@@ -83,6 +96,14 @@ class AMP_Audio_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 83 |
if ( 0 === $new_node->childNodes->length && empty( $new_attributes['src'] ) ) {
|
| 84 |
$this->remove_invalid_child( $node );
|
| 85 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
$node->parentNode->replaceChild( $new_node, $node );
|
| 87 |
}
|
| 88 |
|
|
@@ -133,6 +154,14 @@ class AMP_Audio_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 133 |
}
|
| 134 |
break;
|
| 135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
default:
|
| 137 |
break;
|
| 138 |
}
|
| 20 |
*/
|
| 21 |
public static $tag = 'audio';
|
| 22 |
|
| 23 |
+
/**
|
| 24 |
+
* Get mapping of HTML selectors to the AMP component selectors which they may be converted into.
|
| 25 |
+
*
|
| 26 |
+
* @return array Mapping.
|
| 27 |
+
*/
|
| 28 |
+
public function get_selector_conversion_mapping() {
|
| 29 |
+
return array(
|
| 30 |
+
'audio' => array( 'amp-audio' ),
|
| 31 |
+
);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
/**
|
| 35 |
* Sanitize the <audio> elements from the HTML contained in this instance's DOMDocument.
|
| 36 |
*
|
| 45 |
|
| 46 |
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 47 |
$node = $nodes->item( $i );
|
| 48 |
+
$amp_data = $this->get_data_amp_attributes( $node );
|
| 49 |
$old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
| 50 |
+
$old_attributes = $this->filter_data_amp_attributes( $old_attributes, $amp_data );
|
| 51 |
|
| 52 |
$new_attributes = $this->filter_attributes( $old_attributes );
|
| 53 |
|
| 96 |
if ( 0 === $new_node->childNodes->length && empty( $new_attributes['src'] ) ) {
|
| 97 |
$this->remove_invalid_child( $node );
|
| 98 |
} else {
|
| 99 |
+
|
| 100 |
+
$layout = isset( $new_attributes['layout'] ) ? $new_attributes['layout'] : false;
|
| 101 |
+
|
| 102 |
+
// The width has to be unset / auto in case of fixed-height.
|
| 103 |
+
if ( 'fixed-height' === $layout ) {
|
| 104 |
+
$new_node->setAttribute( 'width', 'auto' );
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
$node->parentNode->replaceChild( $new_node, $node );
|
| 108 |
}
|
| 109 |
|
| 154 |
}
|
| 155 |
break;
|
| 156 |
|
| 157 |
+
case 'data-amp-layout':
|
| 158 |
+
$out['layout'] = $value;
|
| 159 |
+
break;
|
| 160 |
+
|
| 161 |
+
case 'data-amp-noloading':
|
| 162 |
+
$out['noloading'] = $value;
|
| 163 |
+
break;
|
| 164 |
+
|
| 165 |
default:
|
| 166 |
break;
|
| 167 |
}
|
|
@@ -19,6 +19,15 @@ abstract class AMP_Base_Sanitizer {
|
|
| 19 |
*/
|
| 20 |
const FALLBACK_HEIGHT = 400;
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
/**
|
| 23 |
* Placeholder for default args, to be set in child classes.
|
| 24 |
*
|
|
@@ -54,8 +63,8 @@ abstract class AMP_Base_Sanitizer {
|
|
| 54 |
* @type array $amp_bind_placeholder_prefix
|
| 55 |
* @type bool $allow_dirty_styles
|
| 56 |
* @type bool $allow_dirty_scripts
|
| 57 |
-
* @type bool $
|
| 58 |
-
* @type callable $
|
| 59 |
* }
|
| 60 |
*/
|
| 61 |
protected $args;
|
|
@@ -77,6 +86,13 @@ abstract class AMP_Base_Sanitizer {
|
|
| 77 |
*/
|
| 78 |
protected $root_element;
|
| 79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
/**
|
| 81 |
* AMP_Base_Sanitizer constructor.
|
| 82 |
*
|
|
@@ -105,6 +121,41 @@ abstract class AMP_Base_Sanitizer {
|
|
| 105 |
}
|
| 106 |
}
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
/**
|
| 109 |
* Sanitize the HTML contained in the DOMDocument received by the constructor
|
| 110 |
*/
|
|
@@ -130,6 +181,7 @@ abstract class AMP_Base_Sanitizer {
|
|
| 130 |
* Return array of values that would be valid as an HTML `style` attribute.
|
| 131 |
*
|
| 132 |
* @since 0.4
|
|
|
|
| 133 |
*
|
| 134 |
* @return array[][] Mapping of CSS selectors to arrays of properties.
|
| 135 |
*/
|
|
@@ -211,9 +263,12 @@ abstract class AMP_Base_Sanitizer {
|
|
| 211 |
* @type string $class
|
| 212 |
* @type string $layout
|
| 213 |
* }
|
| 214 |
-
* @return
|
| 215 |
*/
|
| 216 |
public function set_layout( $attributes ) {
|
|
|
|
|
|
|
|
|
|
| 217 |
if ( empty( $attributes['height'] ) ) {
|
| 218 |
unset( $attributes['width'] );
|
| 219 |
$attributes['height'] = self::FALLBACK_HEIGHT;
|
|
@@ -262,7 +317,7 @@ abstract class AMP_Base_Sanitizer {
|
|
| 262 |
* @return string URL which may have been updated with HTTPS, or may have been made empty.
|
| 263 |
*/
|
| 264 |
public function maybe_enforce_https_src( $src, $force_https = false ) {
|
| 265 |
-
$protocol = strtok( $src, ':' );
|
| 266 |
if ( 'https' !== $protocol ) {
|
| 267 |
// Check if https is required.
|
| 268 |
if ( isset( $this->args['require_https_src'] ) && true === $this->args['require_https_src'] ) {
|
|
@@ -286,20 +341,24 @@ abstract class AMP_Base_Sanitizer {
|
|
| 286 |
*
|
| 287 |
* @since 0.7
|
| 288 |
*
|
| 289 |
-
* @param DOMNode|DOMElement $node
|
| 290 |
-
* @param array $
|
| 291 |
-
*
|
| 292 |
-
* @return void
|
| 293 |
*/
|
| 294 |
-
public function remove_invalid_child( $node, $
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
}
|
| 300 |
-
|
|
|
|
|
|
|
| 301 |
$node->parentNode->removeChild( $node );
|
|
|
|
|
|
|
| 302 |
}
|
|
|
|
| 303 |
}
|
| 304 |
|
| 305 |
/**
|
|
@@ -312,33 +371,213 @@ abstract class AMP_Base_Sanitizer {
|
|
| 312 |
*
|
| 313 |
* @param DOMElement $element The node for which to remove the attribute.
|
| 314 |
* @param DOMAttr|string $attribute The attribute to remove from the element.
|
| 315 |
-
* @param array $
|
| 316 |
-
* @return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
*/
|
| 318 |
-
public function
|
| 319 |
-
if (
|
| 320 |
-
|
| 321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
}
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
}
|
| 335 |
}
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 341 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 343 |
}
|
| 344 |
}
|
| 19 |
*/
|
| 20 |
const FALLBACK_HEIGHT = 400;
|
| 21 |
|
| 22 |
+
/**
|
| 23 |
+
* Value for <amp-image-lightbox> ID.
|
| 24 |
+
*
|
| 25 |
+
* @since 1.0
|
| 26 |
+
*
|
| 27 |
+
* @const string
|
| 28 |
+
*/
|
| 29 |
+
const AMP_IMAGE_LIGHTBOX_ID = 'amp-image-lightbox';
|
| 30 |
+
|
| 31 |
/**
|
| 32 |
* Placeholder for default args, to be set in child classes.
|
| 33 |
*
|
| 63 |
* @type array $amp_bind_placeholder_prefix
|
| 64 |
* @type bool $allow_dirty_styles
|
| 65 |
* @type bool $allow_dirty_scripts
|
| 66 |
+
* @type bool $should_locate_sources
|
| 67 |
+
* @type callable $validation_error_callback
|
| 68 |
* }
|
| 69 |
*/
|
| 70 |
protected $args;
|
| 86 |
*/
|
| 87 |
protected $root_element;
|
| 88 |
|
| 89 |
+
/**
|
| 90 |
+
* Keep track of nodes that should not be removed to prevent duplicated validation errors since sanitization is rejected.
|
| 91 |
+
*
|
| 92 |
+
* @var array
|
| 93 |
+
*/
|
| 94 |
+
private $should_not_removed_nodes = array();
|
| 95 |
+
|
| 96 |
/**
|
| 97 |
* AMP_Base_Sanitizer constructor.
|
| 98 |
*
|
| 121 |
}
|
| 122 |
}
|
| 123 |
|
| 124 |
+
/**
|
| 125 |
+
* Add filters to manipulate output during output buffering before the DOM is constructed.
|
| 126 |
+
*
|
| 127 |
+
* Add actions and filters before the page is rendered so that the sanitizer can fix issues during output buffering.
|
| 128 |
+
* This provides an alternative to manipulating the DOM in the sanitize method. This is a static function because
|
| 129 |
+
* it is invoked before the class is instantiated, as the DOM is not available yet. This method is only called
|
| 130 |
+
* when 'amp' theme support is present. It is conceptually similar to the AMP_Base_Embed_Handler class's register_embed
|
| 131 |
+
* method.
|
| 132 |
+
*
|
| 133 |
+
* @since 1.0
|
| 134 |
+
* @see \AMP_Base_Embed_Handler::register_embed()
|
| 135 |
+
*
|
| 136 |
+
* @param array $args Args.
|
| 137 |
+
*/
|
| 138 |
+
public static function add_buffering_hooks( $args = array() ) {}
|
| 139 |
+
|
| 140 |
+
/**
|
| 141 |
+
* Get mapping of HTML selectors to the AMP component selectors which they may be converted into.
|
| 142 |
+
*
|
| 143 |
+
* @return array Mapping.
|
| 144 |
+
*/
|
| 145 |
+
public function get_selector_conversion_mapping() {
|
| 146 |
+
return array();
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
/**
|
| 150 |
+
* Run logic before any sanitizers are run.
|
| 151 |
+
*
|
| 152 |
+
* After the sanitizers are instantiated but before calling sanitize on each of them, this
|
| 153 |
+
* method is called with list of all the instantiated sanitizers.
|
| 154 |
+
*
|
| 155 |
+
* @param AMP_Base_Sanitizer[] $sanitizers Sanitizers.
|
| 156 |
+
*/
|
| 157 |
+
public function init( $sanitizers ) {}
|
| 158 |
+
|
| 159 |
/**
|
| 160 |
* Sanitize the HTML contained in the DOMDocument received by the constructor
|
| 161 |
*/
|
| 181 |
* Return array of values that would be valid as an HTML `style` attribute.
|
| 182 |
*
|
| 183 |
* @since 0.4
|
| 184 |
+
* @deprecated As of 1.0, use get_stylesheets().
|
| 185 |
*
|
| 186 |
* @return array[][] Mapping of CSS selectors to arrays of properties.
|
| 187 |
*/
|
| 263 |
* @type string $class
|
| 264 |
* @type string $layout
|
| 265 |
* }
|
| 266 |
+
* @return array Attributes.
|
| 267 |
*/
|
| 268 |
public function set_layout( $attributes ) {
|
| 269 |
+
if ( isset( $attributes['layout'] ) && ( 'fill' === $attributes['layout'] || 'flex-item' !== $attributes['layout'] ) ) {
|
| 270 |
+
return $attributes;
|
| 271 |
+
}
|
| 272 |
if ( empty( $attributes['height'] ) ) {
|
| 273 |
unset( $attributes['width'] );
|
| 274 |
$attributes['height'] = self::FALLBACK_HEIGHT;
|
| 317 |
* @return string URL which may have been updated with HTTPS, or may have been made empty.
|
| 318 |
*/
|
| 319 |
public function maybe_enforce_https_src( $src, $force_https = false ) {
|
| 320 |
+
$protocol = strtok( $src, ':' ); // @todo What about relative URLs? This should use wp_parse_url( $src, PHP_URL_SCHEME )
|
| 321 |
if ( 'https' !== $protocol ) {
|
| 322 |
// Check if https is required.
|
| 323 |
if ( isset( $this->args['require_https_src'] ) && true === $this->args['require_https_src'] ) {
|
| 341 |
*
|
| 342 |
* @since 0.7
|
| 343 |
*
|
| 344 |
+
* @param DOMNode|DOMElement $node The node to remove.
|
| 345 |
+
* @param array $validation_error Validation error details.
|
| 346 |
+
* @return bool Whether the node should have been removed, that is, that the node was sanitized for validity.
|
|
|
|
| 347 |
*/
|
| 348 |
+
public function remove_invalid_child( $node, $validation_error = array() ) {
|
| 349 |
+
|
| 350 |
+
// Prevent double-reporting nodes that are rejected for sanitization.
|
| 351 |
+
if ( isset( $this->should_not_removed_nodes[ $node->nodeName ] ) && in_array( $node, $this->should_not_removed_nodes[ $node->nodeName ], true ) ) {
|
| 352 |
+
return false;
|
| 353 |
}
|
| 354 |
+
|
| 355 |
+
$should_remove = $this->should_sanitize_validation_error( $validation_error, compact( 'node' ) );
|
| 356 |
+
if ( $should_remove ) {
|
| 357 |
$node->parentNode->removeChild( $node );
|
| 358 |
+
} else {
|
| 359 |
+
$this->should_not_removed_nodes[ $node->nodeName ][] = $node;
|
| 360 |
}
|
| 361 |
+
return $should_remove;
|
| 362 |
}
|
| 363 |
|
| 364 |
/**
|
| 371 |
*
|
| 372 |
* @param DOMElement $element The node for which to remove the attribute.
|
| 373 |
* @param DOMAttr|string $attribute The attribute to remove from the element.
|
| 374 |
+
* @param array $validation_error Validation error details.
|
| 375 |
+
* @return bool Whether the node should have been removed, that is, that the node was sanitized for validity.
|
| 376 |
+
*/
|
| 377 |
+
public function remove_invalid_attribute( $element, $attribute, $validation_error = array() ) {
|
| 378 |
+
if ( is_string( $attribute ) ) {
|
| 379 |
+
$node = $element->getAttributeNode( $attribute );
|
| 380 |
+
} else {
|
| 381 |
+
$node = $attribute;
|
| 382 |
+
}
|
| 383 |
+
$should_remove = $this->should_sanitize_validation_error( $validation_error, compact( 'node' ) );
|
| 384 |
+
if ( $should_remove ) {
|
| 385 |
+
$element->removeAttributeNode( $node );
|
| 386 |
+
}
|
| 387 |
+
return $should_remove;
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
/**
|
| 391 |
+
* Check whether or not sanitization should occur in response to validation error.
|
| 392 |
+
*
|
| 393 |
+
* @since 1.0
|
| 394 |
+
*
|
| 395 |
+
* @param array $validation_error Validation error.
|
| 396 |
+
* @param array $data Data including the node.
|
| 397 |
+
* @return bool Whether to sanitize.
|
| 398 |
*/
|
| 399 |
+
public function should_sanitize_validation_error( $validation_error, $data = array() ) {
|
| 400 |
+
if ( empty( $this->args['validation_error_callback'] ) || ! is_callable( $this->args['validation_error_callback'] ) ) {
|
| 401 |
+
return true;
|
| 402 |
+
}
|
| 403 |
+
$validation_error = $this->prepare_validation_error( $validation_error, $data );
|
| 404 |
+
return false !== call_user_func( $this->args['validation_error_callback'], $validation_error, $data );
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
/**
|
| 408 |
+
* Prepare validation error.
|
| 409 |
+
*
|
| 410 |
+
* @param array $error {
|
| 411 |
+
* Error.
|
| 412 |
+
*
|
| 413 |
+
* @type string $code Error code.
|
| 414 |
+
* }
|
| 415 |
+
* @param array $data {
|
| 416 |
+
* Data.
|
| 417 |
+
*
|
| 418 |
+
* @type DOMElement|DOMNode $node The removed node.
|
| 419 |
+
* }
|
| 420 |
+
* @return array Error.
|
| 421 |
+
*/
|
| 422 |
+
public function prepare_validation_error( array $error = array(), array $data = array() ) {
|
| 423 |
+
$node = null;
|
| 424 |
+
$matches = null;
|
| 425 |
+
|
| 426 |
+
if ( isset( $data['node'] ) && $data['node'] instanceof DOMNode ) {
|
| 427 |
+
$node = $data['node'];
|
| 428 |
+
|
| 429 |
+
$error['node_name'] = $node->nodeName;
|
| 430 |
+
if ( $node->parentNode ) {
|
| 431 |
+
$error['parent_name'] = $node->parentNode->nodeName;
|
| 432 |
}
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
if ( $node instanceof DOMElement ) {
|
| 436 |
+
if ( ! isset( $error['code'] ) ) {
|
| 437 |
+
$error['code'] = AMP_Validation_Error_Taxonomy::INVALID_ELEMENT_CODE;
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
if ( ! isset( $error['type'] ) ) {
|
| 441 |
+
$error['type'] = 'script' === $node->nodeName ? AMP_Validation_Error_Taxonomy::JS_ERROR_TYPE : AMP_Validation_Error_Taxonomy::HTML_ELEMENT_ERROR_TYPE;
|
| 442 |
+
}
|
| 443 |
+
|
| 444 |
+
if ( ! isset( $error['node_attributes'] ) ) {
|
| 445 |
+
$error['node_attributes'] = array();
|
| 446 |
+
foreach ( $node->attributes as $attribute ) {
|
| 447 |
+
$error['node_attributes'][ $attribute->nodeName ] = $attribute->nodeValue;
|
| 448 |
}
|
| 449 |
}
|
| 450 |
+
|
| 451 |
+
// Capture script contents.
|
| 452 |
+
if ( 'script' === $node->nodeName && ! $node->hasAttribute( 'src' ) ) {
|
| 453 |
+
$error['text'] = $node->textContent;
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
+
// Suppress 'ver' param from enqueued scripts and styles.
|
| 457 |
+
if ( 'script' === $node->nodeName && isset( $error['node_attributes']['src'] ) && false !== strpos( $error['node_attributes']['src'], 'ver=' ) ) {
|
| 458 |
+
$error['node_attributes']['src'] = add_query_arg( 'ver', '__normalized__', $error['node_attributes']['src'] );
|
| 459 |
+
} elseif ( 'link' === $node->nodeName && isset( $error['node_attributes']['href'] ) && false !== strpos( $error['node_attributes']['href'], 'ver=' ) ) {
|
| 460 |
+
$error['node_attributes']['href'] = add_query_arg( 'ver', '__normalized__', $error['node_attributes']['href'] );
|
| 461 |
+
}
|
| 462 |
+
} elseif ( $node instanceof DOMAttr ) {
|
| 463 |
+
if ( ! isset( $error['code'] ) ) {
|
| 464 |
+
$error['code'] = AMP_Validation_Error_Taxonomy::INVALID_ATTRIBUTE_CODE;
|
| 465 |
+
}
|
| 466 |
+
if ( ! isset( $error['type'] ) ) {
|
| 467 |
+
// If this is an attribute that begins with on, like onclick, it should be a js_error.
|
| 468 |
+
$error['type'] = preg_match( '/^on\w+/', $node->nodeName ) ? AMP_Validation_Error_Taxonomy::JS_ERROR_TYPE : AMP_Validation_Error_Taxonomy::HTML_ATTRIBUTE_ERROR_TYPE;
|
| 469 |
}
|
| 470 |
+
if ( ! isset( $error['element_attributes'] ) ) {
|
| 471 |
+
$error['element_attributes'] = array();
|
| 472 |
+
if ( $node->parentNode && $node->parentNode->hasAttributes() ) {
|
| 473 |
+
foreach ( $node->parentNode->attributes as $attribute ) {
|
| 474 |
+
$error['element_attributes'][ $attribute->nodeName ] = $attribute->nodeValue;
|
| 475 |
+
}
|
| 476 |
+
}
|
| 477 |
+
}
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
return $error;
|
| 481 |
+
}
|
| 482 |
+
|
| 483 |
+
/**
|
| 484 |
+
* Get data-amp-* values from the parent node 'figure' added by editor block.
|
| 485 |
+
*
|
| 486 |
+
* @param DOMElement $node Base node.
|
| 487 |
+
* @return array AMP data array.
|
| 488 |
+
*/
|
| 489 |
+
public function get_data_amp_attributes( $node ) {
|
| 490 |
+
$attributes = array();
|
| 491 |
+
|
| 492 |
+
// Editor blocks add 'figure' as the parent node for images. If this node has data-amp-layout then we should add this as the layout attribute.
|
| 493 |
+
$parent_node = $node->parentNode;
|
| 494 |
+
if ( 'figure' === $parent_node->tagName ) {
|
| 495 |
+
$parent_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $parent_node );
|
| 496 |
+
if ( isset( $parent_attributes['data-amp-layout'] ) ) {
|
| 497 |
+
$attributes['layout'] = $parent_attributes['data-amp-layout'];
|
| 498 |
+
}
|
| 499 |
+
if ( isset( $parent_attributes['data-amp-noloading'] ) && true === filter_var( $parent_attributes['data-amp-noloading'], FILTER_VALIDATE_BOOLEAN ) ) {
|
| 500 |
+
$attributes['noloading'] = $parent_attributes['data-amp-noloading'];
|
| 501 |
+
}
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
return $attributes;
|
| 505 |
+
}
|
| 506 |
+
|
| 507 |
+
/**
|
| 508 |
+
* Set AMP attributes.
|
| 509 |
+
*
|
| 510 |
+
* @param array $attributes Array of attributes.
|
| 511 |
+
* @param array $amp_data Array of AMP attributes.
|
| 512 |
+
* @return array Updated attributes.
|
| 513 |
+
*/
|
| 514 |
+
public function filter_data_amp_attributes( $attributes, $amp_data ) {
|
| 515 |
+
if ( isset( $amp_data['layout'] ) ) {
|
| 516 |
+
$attributes['data-amp-layout'] = $amp_data['layout'];
|
| 517 |
+
}
|
| 518 |
+
if ( isset( $amp_data['noloading'] ) ) {
|
| 519 |
+
$attributes['data-amp-noloading'] = '';
|
| 520 |
+
}
|
| 521 |
+
return $attributes;
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
/**
|
| 525 |
+
* Set attributes to node's parent element according to layout.
|
| 526 |
+
*
|
| 527 |
+
* @param DOMElement $node Node.
|
| 528 |
+
* @param array $new_attributes Attributes array.
|
| 529 |
+
* @param string $layout Layout.
|
| 530 |
+
* @return array New attributes.
|
| 531 |
+
*/
|
| 532 |
+
public function filter_attachment_layout_attributes( $node, $new_attributes, $layout ) {
|
| 533 |
+
|
| 534 |
+
// The width has to be unset / auto in case of fixed-height.
|
| 535 |
+
if ( 'fixed-height' === $layout ) {
|
| 536 |
+
if ( ! isset( $new_attributes['height'] ) ) {
|
| 537 |
+
$new_attributes['height'] = self::FALLBACK_HEIGHT;
|
| 538 |
+
}
|
| 539 |
+
$new_attributes['width'] = 'auto';
|
| 540 |
+
$node->parentNode->setAttribute( 'style', 'height: ' . $new_attributes['height'] . 'px; width: auto;' );
|
| 541 |
+
|
| 542 |
+
// The parent element should have width/height set and position set in case of 'fill'.
|
| 543 |
+
} elseif ( 'fill' === $layout ) {
|
| 544 |
+
if ( ! isset( $new_attributes['height'] ) ) {
|
| 545 |
+
$new_attributes['height'] = self::FALLBACK_HEIGHT;
|
| 546 |
+
}
|
| 547 |
+
$node->parentNode->setAttribute( 'style', 'position:relative; width: 100%; height: ' . $new_attributes['height'] . 'px;' );
|
| 548 |
+
unset( $new_attributes['width'] );
|
| 549 |
+
unset( $new_attributes['height'] );
|
| 550 |
+
} elseif ( 'responsive' === $layout ) {
|
| 551 |
+
$node->parentNode->setAttribute( 'style', 'position:relative; width: 100%; height: auto' );
|
| 552 |
+
} elseif ( 'fixed' === $layout ) {
|
| 553 |
+
if ( ! isset( $new_attributes['height'] ) ) {
|
| 554 |
+
$new_attributes['height'] = self::FALLBACK_HEIGHT;
|
| 555 |
+
}
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
return $new_attributes;
|
| 559 |
+
}
|
| 560 |
+
|
| 561 |
+
/**
|
| 562 |
+
* Add <amp-image-lightbox> element to body tag if it doesn't exist yet.
|
| 563 |
+
*/
|
| 564 |
+
public function maybe_add_amp_image_lightbox_node() {
|
| 565 |
+
|
| 566 |
+
$nodes = $this->dom->getElementById( self::AMP_IMAGE_LIGHTBOX_ID );
|
| 567 |
+
if ( null !== $nodes ) {
|
| 568 |
+
return;
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
$nodes = $this->dom->getElementsByTagName( 'body' );
|
| 572 |
+
if ( ! $nodes->length ) {
|
| 573 |
+
return;
|
| 574 |
}
|
| 575 |
+
$body_node = $nodes->item( 0 );
|
| 576 |
+
$amp_image_lightbox = AMP_DOM_Utils::create_node( $this->dom, 'amp-image-lightbox', array(
|
| 577 |
+
'id' => self::AMP_IMAGE_LIGHTBOX_ID,
|
| 578 |
+
'layout' => 'nodisplay',
|
| 579 |
+
'data-close-button-aria-label' => __( 'Close', 'amp' ),
|
| 580 |
+
) );
|
| 581 |
+
$body_node->appendChild( $amp_image_lightbox );
|
| 582 |
}
|
| 583 |
}
|
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Block_Sanitizer.
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Class AMP_Block_Sanitizer
|
| 10 |
+
*
|
| 11 |
+
* Modifies elements created as blocks to match the blocks' AMP-specific configuration.
|
| 12 |
+
*/
|
| 13 |
+
class AMP_Block_Sanitizer extends AMP_Base_Sanitizer {
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* Tag.
|
| 17 |
+
*
|
| 18 |
+
* @var string Figure tag to identify wrapper around AMP elements.
|
| 19 |
+
* @since 1.0
|
| 20 |
+
*/
|
| 21 |
+
public static $tag = 'figure';
|
| 22 |
+
|
| 23 |
+
/**
|
| 24 |
+
* Sanitize the AMP elements contained by <figure> element where necessary.
|
| 25 |
+
*
|
| 26 |
+
* @since 0.2
|
| 27 |
+
*/
|
| 28 |
+
public function sanitize() {
|
| 29 |
+
$nodes = $this->dom->getElementsByTagName( self::$tag );
|
| 30 |
+
$num_nodes = $nodes->length;
|
| 31 |
+
if ( 0 === $num_nodes ) {
|
| 32 |
+
return;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 36 |
+
$node = $nodes->item( $i );
|
| 37 |
+
|
| 38 |
+
// We are only looking for <figure> elements which have wp-block-embed as class.
|
| 39 |
+
$class = (string) $node->getAttribute( 'class' );
|
| 40 |
+
if ( false === strpos( $class, 'wp-block-embed' ) ) {
|
| 41 |
+
continue;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// Remove classes like wp-embed-aspect-16-9 since responsive layout is handled by AMP's layout system.
|
| 45 |
+
$node->setAttribute( 'class', preg_replace( '/(?<=^|\s)wp-embed-aspect-\d+-\d+(?=\s|$)/', '', $class ) );
|
| 46 |
+
|
| 47 |
+
// We're looking for <figure> elements that have one child node only.
|
| 48 |
+
if ( 1 !== count( $node->childNodes ) ) {
|
| 49 |
+
continue;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
$attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
| 53 |
+
|
| 54 |
+
// We are looking for <figure> elements with layout attribute only.
|
| 55 |
+
if (
|
| 56 |
+
! isset( $attributes['data-amp-layout'] ) &&
|
| 57 |
+
! isset( $attributes['data-amp-noloading'] ) &&
|
| 58 |
+
! isset( $attributes['data-amp-lightbox'] )
|
| 59 |
+
) {
|
| 60 |
+
continue;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
$amp_el_found = false;
|
| 64 |
+
|
| 65 |
+
foreach ( $node->childNodes as $child_node ) {
|
| 66 |
+
|
| 67 |
+
// We are looking for child elements which start with 'amp-'.
|
| 68 |
+
if ( 0 !== strpos( $child_node->tagName, 'amp-' ) ) {
|
| 69 |
+
continue;
|
| 70 |
+
}
|
| 71 |
+
$amp_el_found = true;
|
| 72 |
+
|
| 73 |
+
$this->set_attributes( $child_node, $node, $attributes );
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
if ( false === $amp_el_found ) {
|
| 77 |
+
continue;
|
| 78 |
+
}
|
| 79 |
+
$this->did_convert_elements = true;
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
/**
|
| 84 |
+
* Sets necessary attributes to both parent and AMP element node.
|
| 85 |
+
*
|
| 86 |
+
* @param DOMNode $node AMP element node.
|
| 87 |
+
* @param DOMNode $parent_node <figure> node.
|
| 88 |
+
* @param array $attributes Current attributes of the AMP element.
|
| 89 |
+
*/
|
| 90 |
+
protected function set_attributes( $node, $parent_node, $attributes ) {
|
| 91 |
+
|
| 92 |
+
if ( isset( $attributes['data-amp-layout'] ) ) {
|
| 93 |
+
$node->setAttribute( 'layout', $attributes['data-amp-layout'] );
|
| 94 |
+
}
|
| 95 |
+
if ( isset( $attributes['data-amp-noloading'] ) && true === filter_var( $attributes['data-amp-noloading'], FILTER_VALIDATE_BOOLEAN ) ) {
|
| 96 |
+
$node->setAttribute( 'noloading', '' );
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
$layout = $node->getAttribute( 'layout' );
|
| 100 |
+
|
| 101 |
+
// The width has to be unset / auto in case of fixed-height.
|
| 102 |
+
if ( 'fixed-height' === $layout ) {
|
| 103 |
+
if ( ! isset( $attributes['height'] ) ) {
|
| 104 |
+
$node->setAttribute( 'height', self::FALLBACK_HEIGHT );
|
| 105 |
+
}
|
| 106 |
+
$node->setAttribute( 'width', 'auto' );
|
| 107 |
+
|
| 108 |
+
$height = $node->getAttribute( 'height' );
|
| 109 |
+
if ( is_numeric( $height ) ) {
|
| 110 |
+
$height .= 'px';
|
| 111 |
+
}
|
| 112 |
+
$parent_node->setAttribute( 'style', "height: $height; width: auto;" );
|
| 113 |
+
|
| 114 |
+
// The parent element should have width/height set and position set in case of 'fill'.
|
| 115 |
+
} elseif ( 'fill' === $layout ) {
|
| 116 |
+
if ( ! isset( $attributes['height'] ) ) {
|
| 117 |
+
$attributes['height'] = self::FALLBACK_HEIGHT;
|
| 118 |
+
}
|
| 119 |
+
$parent_node->setAttribute( 'style', 'position:relative; width: 100%; height: ' . $attributes['height'] . 'px;' );
|
| 120 |
+
$node->removeAttribute( 'width' );
|
| 121 |
+
$node->removeAttribute( 'height' );
|
| 122 |
+
} elseif ( 'responsive' === $layout ) {
|
| 123 |
+
$parent_node->setAttribute( 'style', 'position:relative; width: 100%; height: auto' );
|
| 124 |
+
} elseif ( 'fixed' === $layout ) {
|
| 125 |
+
if ( ! isset( $attributes['height'] ) ) {
|
| 126 |
+
$node->setAttribute( 'height', self::FALLBACK_HEIGHT );
|
| 127 |
+
}
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
// Set the fallback layout in case needed.
|
| 131 |
+
$attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
| 132 |
+
$attributes = $this->set_layout( $attributes );
|
| 133 |
+
if ( $layout !== $attributes['layout'] ) {
|
| 134 |
+
$node->setAttribute( 'layout', $attributes['layout'] );
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
}
|
|
@@ -0,0 +1,1151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Core_Theme_Sanitizer.
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
* @since 1.0
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Class AMP_Core_Theme_Sanitizer
|
| 11 |
+
*
|
| 12 |
+
* Fixes up common issues in core themes and others.
|
| 13 |
+
*
|
| 14 |
+
* @see AMP_Validation_Error_Taxonomy::accept_core_theme_validation_errors()
|
| 15 |
+
* @since 1.0
|
| 16 |
+
*/
|
| 17 |
+
class AMP_Core_Theme_Sanitizer extends AMP_Base_Sanitizer {
|
| 18 |
+
|
| 19 |
+
/**
|
| 20 |
+
* Array of flags used to control sanitization.
|
| 21 |
+
*
|
| 22 |
+
* @since 1.0
|
| 23 |
+
* @var array {
|
| 24 |
+
* @type string $stylesheet Stylesheet slug.
|
| 25 |
+
* @type string $template Template slug.
|
| 26 |
+
* @type array $theme_features List of theme features that need to be applied. Features are method names,
|
| 27 |
+
* }
|
| 28 |
+
*/
|
| 29 |
+
protected $args;
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* Body element.
|
| 33 |
+
*
|
| 34 |
+
* @since 1.0
|
| 35 |
+
* @var DOMElement
|
| 36 |
+
*/
|
| 37 |
+
protected $body;
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* XPath.
|
| 41 |
+
*
|
| 42 |
+
* @since 1.0
|
| 43 |
+
* @var DOMXPath
|
| 44 |
+
*/
|
| 45 |
+
protected $xpath;
|
| 46 |
+
|
| 47 |
+
/**
|
| 48 |
+
* Config for features needed by themes.
|
| 49 |
+
*
|
| 50 |
+
* @since 1.0
|
| 51 |
+
* @var array
|
| 52 |
+
*/
|
| 53 |
+
protected static $theme_features = array(
|
| 54 |
+
// Twenty Nineteen.
|
| 55 |
+
'twentynineteen' => array(
|
| 56 |
+
'dequeue_scripts' => array(
|
| 57 |
+
'twentynineteen-skip-link-focus-fix', // This is part of AMP. See <https://github.com/ampproject/amphtml/issues/18671>.
|
| 58 |
+
'twentynineteen-priority-menu',
|
| 59 |
+
'twentynineteen-touch-navigation', // @todo There could be an AMP implementation of this, similar to what is implemented on ampproject.org.
|
| 60 |
+
),
|
| 61 |
+
'remove_actions' => array(
|
| 62 |
+
'wp_print_footer_scripts' => array(
|
| 63 |
+
'twentynineteen_skip_link_focus_fix', // See <https://github.com/WordPress/twentynineteen/pull/47>.
|
| 64 |
+
),
|
| 65 |
+
),
|
| 66 |
+
'add_twentynineteen_masthead_styles' => array(),
|
| 67 |
+
'add_twentynineteen_image_styles' => array(),
|
| 68 |
+
'remove_twentynineteen_thumbnail_image_sizes' => array(),
|
| 69 |
+
|
| 70 |
+
),
|
| 71 |
+
|
| 72 |
+
// Twenty Seventeen.
|
| 73 |
+
'twentyseventeen' => array(
|
| 74 |
+
// @todo Try to implement belowEntryMetaClass().
|
| 75 |
+
'dequeue_scripts' => array(
|
| 76 |
+
'twentyseventeen-html5', // Only relevant for IE<9.
|
| 77 |
+
'twentyseventeen-global', // There are somethings not yet implemented in AMP. See todos below.
|
| 78 |
+
'jquery-scrollto', // Implemented via add_smooth_scrolling().
|
| 79 |
+
'twentyseventeen-navigation', // Handled by add_nav_menu_styles, add_nav_menu_toggle, add_nav_sub_menu_buttons.
|
| 80 |
+
'twentyseventeen-skip-link-focus-fix', // Only needed by IE11 and when admin bar is present.
|
| 81 |
+
),
|
| 82 |
+
'remove_actions' => array(
|
| 83 |
+
'wp_head' => array(
|
| 84 |
+
'twentyseventeen_javascript_detection', // AMP is essentially no-js, with any interactively added explicitly via amp-bind.
|
| 85 |
+
),
|
| 86 |
+
),
|
| 87 |
+
'force_svg_support' => array(),
|
| 88 |
+
'force_fixed_background_support' => array(),
|
| 89 |
+
'add_twentyseventeen_masthead_styles' => array(),
|
| 90 |
+
'add_twentyseventeen_image_styles' => array(),
|
| 91 |
+
'add_twentyseventeen_sticky_nav_menu' => array(),
|
| 92 |
+
'add_has_header_video_body_class' => array(),
|
| 93 |
+
'add_nav_menu_styles' => array(),
|
| 94 |
+
'add_nav_menu_toggle' => array(),
|
| 95 |
+
'add_nav_sub_menu_buttons' => array(),
|
| 96 |
+
'add_smooth_scrolling' => array(
|
| 97 |
+
'//header[@id = "masthead"]//a[ contains( @class, "menu-scroll-down" ) ]',
|
| 98 |
+
),
|
| 99 |
+
'set_twentyseventeen_quotes_icon' => array(),
|
| 100 |
+
'add_twentyseventeen_attachment_image_attributes' => array(),
|
| 101 |
+
),
|
| 102 |
+
|
| 103 |
+
// Twenty Sixteen.
|
| 104 |
+
'twentysixteen' => array(
|
| 105 |
+
// @todo Figure out an AMP solution for onResizeARIA().
|
| 106 |
+
// @todo Try to implement belowEntryMetaClass().
|
| 107 |
+
'dequeue_scripts' => array(
|
| 108 |
+
'twentysixteen-script',
|
| 109 |
+
'twentysixteen-html5', // Only relevant for IE<9.
|
| 110 |
+
'twentysixteen-keyboard-image-navigation', // AMP does not yet allow for listening to keydown events.
|
| 111 |
+
'twentysixteen-skip-link-focus-fix', // Only needed by IE11 and when admin bar is present.
|
| 112 |
+
),
|
| 113 |
+
'remove_actions' => array(
|
| 114 |
+
'wp_head' => array(
|
| 115 |
+
'twentysixteen_javascript_detection', // AMP is essentially no-js, with any interactively added explicitly via amp-bind.
|
| 116 |
+
),
|
| 117 |
+
),
|
| 118 |
+
'add_nav_menu_styles' => array(),
|
| 119 |
+
'add_nav_menu_toggle' => array(),
|
| 120 |
+
'add_nav_sub_menu_buttons' => array(),
|
| 121 |
+
),
|
| 122 |
+
|
| 123 |
+
// Twenty Fifteen.
|
| 124 |
+
'twentyfifteen' => array(
|
| 125 |
+
// @todo Figure out an AMP solution for onResizeARIA().
|
| 126 |
+
'dequeue_scripts' => array(
|
| 127 |
+
'twentyfifteen-script',
|
| 128 |
+
'twentyfifteen-keyboard-image-navigation', // AMP does not yet allow for listening to keydown events.
|
| 129 |
+
'twentyfifteen-skip-link-focus-fix', // Only needed by IE11 and when admin bar is present.
|
| 130 |
+
),
|
| 131 |
+
'remove_actions' => array(
|
| 132 |
+
'wp_head' => array(
|
| 133 |
+
'twentyfifteen_javascript_detection', // AMP is essentially no-js, with any interactively added explicitly via amp-bind.
|
| 134 |
+
),
|
| 135 |
+
),
|
| 136 |
+
'add_nav_menu_styles' => array(),
|
| 137 |
+
'add_nav_menu_toggle' => array(),
|
| 138 |
+
'add_nav_sub_menu_buttons' => array(),
|
| 139 |
+
),
|
| 140 |
+
);
|
| 141 |
+
|
| 142 |
+
/**
|
| 143 |
+
* Get list of supported core themes.
|
| 144 |
+
*
|
| 145 |
+
* @since 1.0
|
| 146 |
+
*
|
| 147 |
+
* @return string[] Slugs for supported themes.
|
| 148 |
+
*/
|
| 149 |
+
public static function get_supported_themes() {
|
| 150 |
+
return array_keys( self::$theme_features );
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
/**
|
| 154 |
+
* Get the acceptable validation errors.
|
| 155 |
+
*
|
| 156 |
+
* @since 1.0
|
| 157 |
+
*
|
| 158 |
+
* @param string $template Template.
|
| 159 |
+
* @return array Acceptable errors.
|
| 160 |
+
*/
|
| 161 |
+
public static function get_acceptable_errors( $template ) {
|
| 162 |
+
switch ( $template ) {
|
| 163 |
+
case 'twentyfifteen':
|
| 164 |
+
return array(
|
| 165 |
+
'removed_unused_css_rules' => true,
|
| 166 |
+
'illegal_css_at_rule' => array(
|
| 167 |
+
array(
|
| 168 |
+
'at_rule' => 'viewport',
|
| 169 |
+
'node_attributes' => array(
|
| 170 |
+
'id' => 'twentyfifteen-style-css',
|
| 171 |
+
),
|
| 172 |
+
),
|
| 173 |
+
array(
|
| 174 |
+
'at_rule' => '-ms-viewport',
|
| 175 |
+
'node_attributes' => array(
|
| 176 |
+
'id' => 'twentyfifteen-style-css',
|
| 177 |
+
),
|
| 178 |
+
),
|
| 179 |
+
),
|
| 180 |
+
);
|
| 181 |
+
case 'twentysixteen':
|
| 182 |
+
return array(
|
| 183 |
+
'removed_unused_css_rules' => true,
|
| 184 |
+
'illegal_css_at_rule' => array(
|
| 185 |
+
array(
|
| 186 |
+
'at_rule' => 'viewport',
|
| 187 |
+
'node_attributes' => array(
|
| 188 |
+
'id' => 'twentysixteen-style-css',
|
| 189 |
+
),
|
| 190 |
+
),
|
| 191 |
+
array(
|
| 192 |
+
'at_rule' => '-ms-viewport',
|
| 193 |
+
'node_attributes' => array(
|
| 194 |
+
'id' => 'twentysixteen-style-css',
|
| 195 |
+
),
|
| 196 |
+
),
|
| 197 |
+
),
|
| 198 |
+
);
|
| 199 |
+
case 'twentyseventeen':
|
| 200 |
+
return array(
|
| 201 |
+
'removed_unused_css_rules' => true,
|
| 202 |
+
);
|
| 203 |
+
}
|
| 204 |
+
return array();
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
/**
|
| 208 |
+
* Get theme config.
|
| 209 |
+
*
|
| 210 |
+
* @since 1.0
|
| 211 |
+
*
|
| 212 |
+
* @param string $theme Theme slug.
|
| 213 |
+
* @return array Class names.
|
| 214 |
+
*/
|
| 215 |
+
protected static function get_theme_config( $theme ) {
|
| 216 |
+
// phpcs:disable WordPress.WP.I18n.TextDomainMismatch
|
| 217 |
+
$config = array(
|
| 218 |
+
'sub_menu_button_class' => 'dropdown-toggle',
|
| 219 |
+
);
|
| 220 |
+
switch ( $theme ) {
|
| 221 |
+
case 'twentyfifteen':
|
| 222 |
+
return array_merge(
|
| 223 |
+
$config,
|
| 224 |
+
array(
|
| 225 |
+
'nav_container_id' => 'secondary',
|
| 226 |
+
'nav_container_toggle_class' => 'toggled-on',
|
| 227 |
+
'menu_button_class' => 'secondary-toggle',
|
| 228 |
+
'menu_button_xpath' => '//header[ @id = "masthead" ]//button[ contains( @class, "secondary-toggle" ) ]',
|
| 229 |
+
'menu_button_toggle_class' => 'toggled-on',
|
| 230 |
+
'sub_menu_button_toggle_class' => 'toggle-on',
|
| 231 |
+
'expand_text ' => __( 'expand child menu', 'twentyfifteen' ),
|
| 232 |
+
'collapse_text' => __( 'collapse child menu', 'twentyfifteen' ),
|
| 233 |
+
)
|
| 234 |
+
);
|
| 235 |
+
|
| 236 |
+
case 'twentysixteen':
|
| 237 |
+
return array_merge(
|
| 238 |
+
$config,
|
| 239 |
+
array(
|
| 240 |
+
'nav_container_id' => 'site-header-menu',
|
| 241 |
+
'nav_container_toggle_class' => 'toggled-on',
|
| 242 |
+
'menu_button_class' => 'menu-toggle',
|
| 243 |
+
'menu_button_xpath' => '//header[@id = "masthead"]//button[ @id = "menu-toggle" ]',
|
| 244 |
+
'menu_button_toggle_class' => 'toggled-on',
|
| 245 |
+
'sub_menu_button_toggle_class' => 'toggled-on',
|
| 246 |
+
'expand_text ' => __( 'expand child menu', 'twentysixteen' ),
|
| 247 |
+
'collapse_text' => __( 'collapse child menu', 'twentysixteen' ),
|
| 248 |
+
)
|
| 249 |
+
);
|
| 250 |
+
|
| 251 |
+
case 'twentyseventeen':
|
| 252 |
+
default:
|
| 253 |
+
return array_merge(
|
| 254 |
+
$config,
|
| 255 |
+
array(
|
| 256 |
+
'nav_container_id' => 'site-navigation',
|
| 257 |
+
'nav_container_toggle_class' => 'toggled-on',
|
| 258 |
+
'menu_button_class' => 'menu-toggle',
|
| 259 |
+
'menu_button_xpath' => '//nav[@id = "site-navigation"]//button[ contains( @class, "menu-toggle" ) ]',
|
| 260 |
+
'menu_button_toggle_class' => 'toggled-on',
|
| 261 |
+
'sub_menu_button_toggle_class' => 'toggled-on',
|
| 262 |
+
'expand_text ' => __( 'expand child menu', 'twentyseventeen' ),
|
| 263 |
+
'collapse_text' => __( 'collapse child menu', 'twentyseventeen' ),
|
| 264 |
+
)
|
| 265 |
+
);
|
| 266 |
+
}
|
| 267 |
+
// phpcs:enable WordPress.WP.I18n.TextDomainMismatch
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
/**
|
| 271 |
+
* Find theme features for core theme.
|
| 272 |
+
*
|
| 273 |
+
* @since 1.0
|
| 274 |
+
*
|
| 275 |
+
* @param array $args Args.
|
| 276 |
+
* @param bool $static Static. that is, whether should run during output buffering.
|
| 277 |
+
* @return array Theme features.
|
| 278 |
+
*/
|
| 279 |
+
protected static function get_theme_features( $args, $static = false ) {
|
| 280 |
+
$theme_features = array();
|
| 281 |
+
$theme_candidates = wp_array_slice_assoc( $args, array( 'stylesheet', 'template' ) );
|
| 282 |
+
foreach ( $theme_candidates as $theme_candidate ) {
|
| 283 |
+
if ( isset( self::$theme_features[ $theme_candidate ] ) ) {
|
| 284 |
+
$theme_features = self::$theme_features[ $theme_candidate ];
|
| 285 |
+
break;
|
| 286 |
+
}
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
// Allow specific theme features to be requested even if the theme is not in core.
|
| 290 |
+
if ( isset( $args['theme_features'] ) ) {
|
| 291 |
+
$theme_features = array_merge( $args['theme_features'], $theme_features );
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
$final_theme_features = array();
|
| 295 |
+
foreach ( $theme_features as $theme_feature => $feature_args ) {
|
| 296 |
+
if ( ! method_exists( __CLASS__, $theme_feature ) ) {
|
| 297 |
+
continue;
|
| 298 |
+
}
|
| 299 |
+
try {
|
| 300 |
+
$reflection = new ReflectionMethod( __CLASS__, $theme_feature );
|
| 301 |
+
if ( $reflection->isStatic() === $static ) {
|
| 302 |
+
$final_theme_features[ $theme_feature ] = $feature_args;
|
| 303 |
+
}
|
| 304 |
+
} catch ( Exception $e ) {
|
| 305 |
+
unset( $e );
|
| 306 |
+
}
|
| 307 |
+
}
|
| 308 |
+
return $final_theme_features;
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
/**
|
| 312 |
+
* Add filters to manipulate output during output buffering before the DOM is constructed.
|
| 313 |
+
*
|
| 314 |
+
* @since 1.0
|
| 315 |
+
*
|
| 316 |
+
* @param array $args Args.
|
| 317 |
+
*/
|
| 318 |
+
public static function add_buffering_hooks( $args = array() ) {
|
| 319 |
+
$theme_features = self::get_theme_features( $args, true );
|
| 320 |
+
foreach ( $theme_features as $theme_feature => $feature_args ) {
|
| 321 |
+
if ( method_exists( __CLASS__, $theme_feature ) ) {
|
| 322 |
+
call_user_func( array( __CLASS__, $theme_feature ), $feature_args );
|
| 323 |
+
}
|
| 324 |
+
}
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
/**
|
| 328 |
+
* Add filter to output the quote icons in front of the article content.
|
| 329 |
+
*
|
| 330 |
+
* This is only used in Twenty Seventeen.
|
| 331 |
+
*
|
| 332 |
+
* @since 1.0
|
| 333 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/f4580c122b7d0d2d66d22f806c6fe6e11023c6f0/src/wp-content/themes/twentyseventeen/assets/js/global.js#L105-L108
|
| 334 |
+
*/
|
| 335 |
+
public static function set_twentyseventeen_quotes_icon() {
|
| 336 |
+
add_filter( 'the_content', function ( $content ) {
|
| 337 |
+
|
| 338 |
+
// Why isn't Twenty Seventeen doing this to begin with? Why is it using JS to add the quote icon?
|
| 339 |
+
if ( function_exists( 'twentyseventeen_get_svg' ) && 'quote' === get_post_format() ) {
|
| 340 |
+
$icon = twentyseventeen_get_svg( array( 'icon' => 'quote-right' ) );
|
| 341 |
+
$content = preg_replace( '#(<blockquote.*?>)#s', '$1' . $icon, $content );
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
return $content;
|
| 345 |
+
} );
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
/**
|
| 349 |
+
* Remove the sizes attribute from thumbnail images in Twenty Nineteen.
|
| 350 |
+
*
|
| 351 |
+
* The AMP runtime sets an inline style on an <amp-img> based on the sizes attribute if it's present.
|
| 352 |
+
* For example, <amp-img style="width:calc(50vw)">.
|
| 353 |
+
* Removing the 'sizes' attribute isn't ideal, but it looks like it's not possible to override that inline style.
|
| 354 |
+
*
|
| 355 |
+
* @todo: remove when this is resolved: https://github.com/ampproject/amphtml/issues/17053
|
| 356 |
+
* @since 1.0
|
| 357 |
+
*/
|
| 358 |
+
public static function remove_twentynineteen_thumbnail_image_sizes() {
|
| 359 |
+
add_filter( 'wp_get_attachment_image_attributes', function( $attr ) {
|
| 360 |
+
if ( isset( $attr['class'] ) && false !== strpos( $attr['class'], 'attachment-post-thumbnail' ) ) {
|
| 361 |
+
unset( $attr['sizes'] );
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
return $attr;
|
| 365 |
+
}, 11 );
|
| 366 |
+
}
|
| 367 |
+
|
| 368 |
+
/**
|
| 369 |
+
* Add filter to adjust the attachment image attributes to ensure attachment pages have a consistent <amp-img> rendering.
|
| 370 |
+
*
|
| 371 |
+
* This is only used in Twenty Seventeen.
|
| 372 |
+
*
|
| 373 |
+
* @since 1.0
|
| 374 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/ddc8f803c6e99118998191fd2ea24124feb53659/src/wp-content/themes/twentyseventeen/functions.php#L545:L554
|
| 375 |
+
*/
|
| 376 |
+
public static function add_twentyseventeen_attachment_image_attributes() {
|
| 377 |
+
add_filter( 'wp_get_attachment_image_attributes', function ( $attr, $attachment, $size ) {
|
| 378 |
+
if (
|
| 379 |
+
isset( $attr['class'] )
|
| 380 |
+
&&
|
| 381 |
+
(
|
| 382 |
+
'custom-logo' === $attr['class']
|
| 383 |
+
||
|
| 384 |
+
false !== strpos( $attr['class'], 'attachment-twentyseventeen-featured-image' )
|
| 385 |
+
)
|
| 386 |
+
) {
|
| 387 |
+
/*
|
| 388 |
+
* The AMP runtime sets an inline style on an <amp-img> based on the sizes attribute if it's present.
|
| 389 |
+
* For example, <amp-img style="width:100%">.
|
| 390 |
+
* Removing the 'sizes' attribute is only a workaround, as it looks like it's not possible to override that inline style.
|
| 391 |
+
*
|
| 392 |
+
* @todo: remove when this is resolved: https://github.com/ampproject/amphtml/issues/17053
|
| 393 |
+
*/
|
| 394 |
+
unset( $attr['sizes'] );
|
| 395 |
+
} elseif ( is_attachment() ) {
|
| 396 |
+
$sizes = wp_get_attachment_image_sizes( $attachment->ID, $size );
|
| 397 |
+
if ( false !== $sizes ) {
|
| 398 |
+
$attr['sizes'] = $sizes;
|
| 399 |
+
}
|
| 400 |
+
}
|
| 401 |
+
return $attr;
|
| 402 |
+
}, 11, 3 );
|
| 403 |
+
|
| 404 |
+
/*
|
| 405 |
+
* The max-height of the `.custom-logo-link img` is defined as being 80px, unless
|
| 406 |
+
* there is header media in which case it is 200px. Issues related to vertically-squashed
|
| 407 |
+
* images can be avoided if we just make sure that the image has this height to begin with.
|
| 408 |
+
*/
|
| 409 |
+
add_filter( 'get_custom_logo', function( $html ) {
|
| 410 |
+
$src = wp_get_attachment_image_src( get_theme_mod( 'custom_logo' ), 'full' );
|
| 411 |
+
if ( ! $src ) {
|
| 412 |
+
return $html;
|
| 413 |
+
}
|
| 414 |
+
|
| 415 |
+
if ( 'blank' === get_header_textcolor() && has_custom_header() ) {
|
| 416 |
+
$height = 200;
|
| 417 |
+
} else {
|
| 418 |
+
$height = 80;
|
| 419 |
+
}
|
| 420 |
+
$width = $height * ( $src[1] / $src[2] ); // Note that float values are allowed.
|
| 421 |
+
|
| 422 |
+
$html = preg_replace( '/(?<=width=")\d+(?=")/', $width, $html );
|
| 423 |
+
$html = preg_replace( '/(?<=height=")\d+(?=")/', $height, $html );
|
| 424 |
+
return $html;
|
| 425 |
+
} );
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
/**
|
| 429 |
+
* Fix up core themes to do things in the AMP way.
|
| 430 |
+
*
|
| 431 |
+
* @since 1.0
|
| 432 |
+
*/
|
| 433 |
+
public function sanitize() {
|
| 434 |
+
$this->body = $this->dom->getElementsByTagName( 'body' )->item( 0 );
|
| 435 |
+
if ( ! $this->body ) {
|
| 436 |
+
return;
|
| 437 |
+
}
|
| 438 |
+
|
| 439 |
+
$this->xpath = new DOMXPath( $this->dom );
|
| 440 |
+
|
| 441 |
+
$theme_features = self::get_theme_features( $this->args, false );
|
| 442 |
+
foreach ( $theme_features as $theme_feature => $feature_args ) {
|
| 443 |
+
if ( method_exists( $this, $theme_feature ) ) {
|
| 444 |
+
call_user_func( array( $this, $theme_feature ), $feature_args );
|
| 445 |
+
}
|
| 446 |
+
}
|
| 447 |
+
}
|
| 448 |
+
|
| 449 |
+
/**
|
| 450 |
+
* Dequeue scripts.
|
| 451 |
+
*
|
| 452 |
+
* @since 1.0
|
| 453 |
+
*
|
| 454 |
+
* @param string[] $handles Handles, where each item value is the script handle.
|
| 455 |
+
*/
|
| 456 |
+
public static function dequeue_scripts( $handles = array() ) {
|
| 457 |
+
add_action( 'wp_enqueue_scripts', function() use ( $handles ) {
|
| 458 |
+
foreach ( $handles as $handle ) {
|
| 459 |
+
wp_dequeue_script( $handle );
|
| 460 |
+
}
|
| 461 |
+
}, PHP_INT_MAX );
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
/**
|
| 465 |
+
* Remove actions.
|
| 466 |
+
*
|
| 467 |
+
* @since 1.0
|
| 468 |
+
*
|
| 469 |
+
* @param array $actions Actions, with action name as key and value being callback.
|
| 470 |
+
*/
|
| 471 |
+
public static function remove_actions( $actions = array() ) {
|
| 472 |
+
foreach ( $actions as $action => $callbacks ) {
|
| 473 |
+
foreach ( $callbacks as $callback ) {
|
| 474 |
+
$priority = has_action( $action, $callback );
|
| 475 |
+
if ( false !== $priority ) {
|
| 476 |
+
remove_action( $action, $callback, $priority );
|
| 477 |
+
}
|
| 478 |
+
}
|
| 479 |
+
}
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
/**
|
| 483 |
+
* Add smooth scrolling from link to target element.
|
| 484 |
+
*
|
| 485 |
+
* @since 1.0
|
| 486 |
+
*
|
| 487 |
+
* @param string[] $link_xpaths XPath queries to the links that should smooth scroll.
|
| 488 |
+
*/
|
| 489 |
+
public function add_smooth_scrolling( $link_xpaths ) {
|
| 490 |
+
foreach ( $link_xpaths as $link_xpath ) {
|
| 491 |
+
foreach ( $this->xpath->query( $link_xpath ) as $link ) {
|
| 492 |
+
if ( $link instanceof DOMElement && preg_match( '/#(.+)/', $link->getAttribute( 'href' ), $matches ) ) {
|
| 493 |
+
$link->setAttribute( 'on', sprintf( 'tap:%s.scrollTo(duration=600)', $matches[1] ) );
|
| 494 |
+
}
|
| 495 |
+
}
|
| 496 |
+
}
|
| 497 |
+
}
|
| 498 |
+
|
| 499 |
+
/**
|
| 500 |
+
* Force SVG support, replacing no-svg class name with svg class name.
|
| 501 |
+
*
|
| 502 |
+
* @since 1.0
|
| 503 |
+
*
|
| 504 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/assets/js/global.js#L211-L213
|
| 505 |
+
* @link https://caniuse.com/#feat=svg
|
| 506 |
+
*/
|
| 507 |
+
public function force_svg_support() {
|
| 508 |
+
$this->dom->documentElement->setAttribute(
|
| 509 |
+
'class',
|
| 510 |
+
preg_replace(
|
| 511 |
+
'/(^|\s)no-svg(\s|$)/',
|
| 512 |
+
' svg ',
|
| 513 |
+
$this->dom->documentElement->getAttribute( 'class' )
|
| 514 |
+
)
|
| 515 |
+
);
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
/**
|
| 519 |
+
* Force support for fixed background-attachment.
|
| 520 |
+
*
|
| 521 |
+
* @since 1.0
|
| 522 |
+
*
|
| 523 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/assets/js/global.js#L215-L217
|
| 524 |
+
* @link https://caniuse.com/#feat=background-attachment
|
| 525 |
+
*/
|
| 526 |
+
public function force_fixed_background_support() {
|
| 527 |
+
$this->dom->documentElement->setAttribute(
|
| 528 |
+
'class',
|
| 529 |
+
$this->dom->documentElement->getAttribute( 'class' ) . ' background-fixed'
|
| 530 |
+
);
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
+
/**
|
| 534 |
+
* Add body class when there is a header video.
|
| 535 |
+
*
|
| 536 |
+
* @since 1.0
|
| 537 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/a26c24226c6b131a0ed22c722a836c100d3ba254/src/wp-content/themes/twentyseventeen/assets/js/global.js#L244-L247
|
| 538 |
+
*
|
| 539 |
+
* @param array $args Args.
|
| 540 |
+
*/
|
| 541 |
+
public static function add_has_header_video_body_class( $args = array() ) {
|
| 542 |
+
$args = array_merge(
|
| 543 |
+
array(
|
| 544 |
+
'class_name' => 'has-header-video',
|
| 545 |
+
),
|
| 546 |
+
$args
|
| 547 |
+
);
|
| 548 |
+
|
| 549 |
+
add_filter( 'body_class', function( $body_classes ) use ( $args ) {
|
| 550 |
+
if ( has_header_video() ) {
|
| 551 |
+
$body_classes[] = $args['class_name'];
|
| 552 |
+
}
|
| 553 |
+
return $body_classes;
|
| 554 |
+
} );
|
| 555 |
+
}
|
| 556 |
+
|
| 557 |
+
/**
|
| 558 |
+
* Get the (common) navigation outer height.
|
| 559 |
+
*
|
| 560 |
+
* @todo If the nav menu has many items and it spans multiple rows, this will be too small.
|
| 561 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/fd5ba80c5c3d9cf62348567073945e246285fbca/src/wp-content/themes/twentyseventeen/assets/js/global.js#L50
|
| 562 |
+
*
|
| 563 |
+
* @return int Navigation outer height.
|
| 564 |
+
*/
|
| 565 |
+
protected static function get_twentyseventeen_navigation_outer_height() {
|
| 566 |
+
return 72;
|
| 567 |
+
}
|
| 568 |
+
|
| 569 |
+
/**
|
| 570 |
+
* Add required styles for featured image header in Twenty Nineteen.
|
| 571 |
+
*
|
| 572 |
+
* The following is necessary because the styles in the theme apply to the featured img,
|
| 573 |
+
* and the CSS parser will then convert the selectors to amp-img. Nevertheless, object-fit
|
| 574 |
+
* does not apply on amp-img and it needs to apply on an actual img.
|
| 575 |
+
*
|
| 576 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/5.0/src/wp-content/themes/twentynineteen/style.css#L2276-L2299
|
| 577 |
+
* @since 1.0
|
| 578 |
+
*/
|
| 579 |
+
public static function add_twentynineteen_masthead_styles() {
|
| 580 |
+
add_action( 'wp_enqueue_scripts', function() {
|
| 581 |
+
ob_start();
|
| 582 |
+
?>
|
| 583 |
+
<style>
|
| 584 |
+
.site-header.featured-image .site-featured-image .post-thumbnail amp-img > img {
|
| 585 |
+
height: auto;
|
| 586 |
+
left: 50%;
|
| 587 |
+
max-width: 1000%;
|
| 588 |
+
min-height: 100%;
|
| 589 |
+
min-width: 100vw;
|
| 590 |
+
position: absolute;
|
| 591 |
+
top: 50%;
|
| 592 |
+
transform: translateX(-50%) translateY(-50%);
|
| 593 |
+
width: auto;
|
| 594 |
+
z-index: 1;
|
| 595 |
+
/* When image filters are active, make it grayscale to colorize it blue. */
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
@supports (object-fit: cover) {
|
| 599 |
+
.site-header.featured-image .site-featured-image .post-thumbnail amp-img > img {
|
| 600 |
+
height: 100%;
|
| 601 |
+
left: 0;
|
| 602 |
+
object-fit: cover;
|
| 603 |
+
top: 0;
|
| 604 |
+
transform: none;
|
| 605 |
+
width: 100%;
|
| 606 |
+
}
|
| 607 |
+
}
|
| 608 |
+
</style>
|
| 609 |
+
<?php
|
| 610 |
+
$styles = str_replace( array( '<style>', '</style>' ), '', ob_get_clean() );
|
| 611 |
+
wp_add_inline_style( get_template() . '-style', $styles );
|
| 612 |
+
}, 11 );
|
| 613 |
+
}
|
| 614 |
+
|
| 615 |
+
/**
|
| 616 |
+
* Add required styles for video and image headers.
|
| 617 |
+
*
|
| 618 |
+
* This is currently used exclusively for Twenty Seventeen.
|
| 619 |
+
*
|
| 620 |
+
* @since 1.0
|
| 621 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/style.css#L1687
|
| 622 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/style.css#L1743
|
| 623 |
+
*/
|
| 624 |
+
public static function add_twentyseventeen_masthead_styles() {
|
| 625 |
+
$args = self::get_theme_config( get_template() );
|
| 626 |
+
|
| 627 |
+
/*
|
| 628 |
+
* The following is necessary because the styles in the theme apply to img and video,
|
| 629 |
+
* and the CSS parser will then convert the selectors to amp-img and amp-video respectively.
|
| 630 |
+
* Nevertheless, object-fit does not apply on amp-img and it needs to apply on an actual img.
|
| 631 |
+
*/
|
| 632 |
+
add_action( 'wp_enqueue_scripts', function() use ( $args ) {
|
| 633 |
+
$is_front_page_layout = ( is_front_page() && 'posts' !== get_option( 'show_on_front' ) ) || ( is_home() && is_front_page() );
|
| 634 |
+
ob_start();
|
| 635 |
+
?>
|
| 636 |
+
<style>
|
| 637 |
+
.has-header-image .custom-header-media amp-img > img,
|
| 638 |
+
.has-header-video .custom-header-media amp-video > video{
|
| 639 |
+
position: fixed;
|
| 640 |
+
height: auto;
|
| 641 |
+
left: 50%;
|
| 642 |
+
max-width: 1000%;
|
| 643 |
+
min-height: 100%;
|
| 644 |
+
min-width: 100%;
|
| 645 |
+
min-width: 100vw; /* vw prevents 1px gap on left that 100% has */
|
| 646 |
+
width: auto;
|
| 647 |
+
top: 50%;
|
| 648 |
+
padding-bottom: 1px; /* Prevent header from extending beyond the footer */
|
| 649 |
+
-ms-transform: translateX(-50%) translateY(-50%);
|
| 650 |
+
-moz-transform: translateX(-50%) translateY(-50%);
|
| 651 |
+
-webkit-transform: translateX(-50%) translateY(-50%);
|
| 652 |
+
transform: translateX(-50%) translateY(-50%);
|
| 653 |
+
}
|
| 654 |
+
.has-header-image:not(.twentyseventeen-front-page):not(.home) .custom-header-media amp-img > img {
|
| 655 |
+
bottom: 0;
|
| 656 |
+
position: absolute;
|
| 657 |
+
top: auto;
|
| 658 |
+
-ms-transform: translateX(-50%) translateY(0);
|
| 659 |
+
-moz-transform: translateX(-50%) translateY(0);
|
| 660 |
+
-webkit-transform: translateX(-50%) translateY(0);
|
| 661 |
+
transform: translateX(-50%) translateY(0);
|
| 662 |
+
}
|
| 663 |
+
/* For browsers that support object-fit */
|
| 664 |
+
@supports ( object-fit: cover ) {
|
| 665 |
+
.has-header-image .custom-header-media amp-img > img,
|
| 666 |
+
.has-header-video .custom-header-media amp-video > video,
|
| 667 |
+
.has-header-image:not(.twentyseventeen-front-page):not(.home) .custom-header-media amp-img > img {
|
| 668 |
+
height: 100%;
|
| 669 |
+
left: 0;
|
| 670 |
+
-o-object-fit: cover;
|
| 671 |
+
object-fit: cover;
|
| 672 |
+
top: 0;
|
| 673 |
+
-ms-transform: none;
|
| 674 |
+
-moz-transform: none;
|
| 675 |
+
-webkit-transform: none;
|
| 676 |
+
transform: none;
|
| 677 |
+
width: 100%;
|
| 678 |
+
}
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
.navigation-top.site-navigation-fixed {
|
| 682 |
+
display: none;
|
| 683 |
+
}
|
| 684 |
+
|
| 685 |
+
<?php if ( $is_front_page_layout && ! has_custom_header() ) : ?>
|
| 686 |
+
/* https://github.com/WordPress/wordpress-develop/blob/fd5ba80c5c3d9cf62348567073945e246285fbca/src/wp-content/themes/twentyseventeen/assets/js/global.js#L92-L94 */
|
| 687 |
+
.site-branding {
|
| 688 |
+
margin-bottom: <?php echo (int) AMP_Core_Theme_Sanitizer::get_twentyseventeen_navigation_outer_height(); ?>px;
|
| 689 |
+
}
|
| 690 |
+
<?php endif; ?>
|
| 691 |
+
|
| 692 |
+
@media screen and (min-width: 48em) {
|
| 693 |
+
/* Note that adjustHeaderHeight() is irrelevant with this change */
|
| 694 |
+
<?php if ( ! $is_front_page_layout ) : ?>
|
| 695 |
+
.navigation-top {
|
| 696 |
+
position: static;
|
| 697 |
+
}
|
| 698 |
+
<?php endif; ?>
|
| 699 |
+
|
| 700 |
+
/* Initial styles that amp-animations for navigationTopShow and navigationTopHide will override */
|
| 701 |
+
.navigation-top.site-navigation-fixed {
|
| 702 |
+
opacity: 0;
|
| 703 |
+
transform: translateY( -<?php echo (int) AMP_Core_Theme_Sanitizer::get_twentyseventeen_navigation_outer_height(); ?>px );
|
| 704 |
+
display: block;
|
| 705 |
+
}
|
| 706 |
+
}
|
| 707 |
+
</style>
|
| 708 |
+
<?php
|
| 709 |
+
$styles = str_replace( array( '<style>', '</style>' ), '', ob_get_clean() );
|
| 710 |
+
wp_add_inline_style( get_template() . '-style', $styles );
|
| 711 |
+
}, 11 );
|
| 712 |
+
}
|
| 713 |
+
|
| 714 |
+
/**
|
| 715 |
+
* Override the featured image header styling in style.css.
|
| 716 |
+
* Used only for Twenty Seventeen.
|
| 717 |
+
*
|
| 718 |
+
* @since 1.0
|
| 719 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/style.css#L2100
|
| 720 |
+
*/
|
| 721 |
+
public static function add_twentyseventeen_image_styles() {
|
| 722 |
+
add_action( 'wp_enqueue_scripts', function() {
|
| 723 |
+
ob_start();
|
| 724 |
+
?>
|
| 725 |
+
<style>
|
| 726 |
+
/* Override the display: block in twentyseventeen/style.css, as <amp-img> is usually inline-block. */
|
| 727 |
+
.single-featured-image-header amp-img {
|
| 728 |
+
display: inline-block;
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
/* Because the <amp-img> is inline-block, its container needs this rule to center it. */
|
| 732 |
+
.single-featured-image-header {
|
| 733 |
+
text-align: center;
|
| 734 |
+
}
|
| 735 |
+
</style>
|
| 736 |
+
<?php
|
| 737 |
+
$styles = str_replace( array( '<style>', '</style>' ), '', ob_get_clean() );
|
| 738 |
+
wp_add_inline_style( get_template() . '-style', $styles );
|
| 739 |
+
}, 11 );
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
/**
|
| 743 |
+
* Add sticky nav menu to Twenty Seventeen.
|
| 744 |
+
*
|
| 745 |
+
* This is implemented by cloning the navigation-top element, giving it a fixed position outside of the viewport,
|
| 746 |
+
* and then showing it at the top of the window as soon as the original nav begins to get scrolled out of view.
|
| 747 |
+
* In order to improve accessibility, the cloned nav gets aria-hidden=true and all of the links get tabindex=-1
|
| 748 |
+
* to prevent the keyboard from focusing on elements off the screen; it is not necessary to focus on the elements
|
| 749 |
+
* in the fixed nav menu because as soon as the original nav menu is focused then the window is scrolled to the
|
| 750 |
+
* top anyway.
|
| 751 |
+
*
|
| 752 |
+
* @since 1.0
|
| 753 |
+
*/
|
| 754 |
+
public function add_twentyseventeen_sticky_nav_menu() {
|
| 755 |
+
/**
|
| 756 |
+
* Elements.
|
| 757 |
+
*
|
| 758 |
+
* @var DOMElement $link
|
| 759 |
+
* @var DOMElement $navigation_top
|
| 760 |
+
* @var DOMElement $navigation_top_fixed
|
| 761 |
+
*/
|
| 762 |
+
$navigation_top = $this->xpath->query( '//header[ @id = "masthead" ]//div[ contains( @class, "navigation-top" ) ]' )->item( 0 );
|
| 763 |
+
if ( ! $navigation_top ) {
|
| 764 |
+
return;
|
| 765 |
+
}
|
| 766 |
+
|
| 767 |
+
$navigation_top_fixed = $navigation_top->cloneNode( true );
|
| 768 |
+
$navigation_top_fixed->setAttribute( 'class', $navigation_top_fixed->getAttribute( 'class' ) . ' site-navigation-fixed' );
|
| 769 |
+
|
| 770 |
+
$navigation_top_fixed->setAttribute( 'aria-hidden', 'true' );
|
| 771 |
+
foreach ( $navigation_top_fixed->getElementsByTagName( 'a' ) as $link ) {
|
| 772 |
+
$link->setAttribute( 'tabindex', '-1' );
|
| 773 |
+
}
|
| 774 |
+
|
| 775 |
+
$navigation_top->parentNode->insertBefore( $navigation_top_fixed, $navigation_top->nextSibling );
|
| 776 |
+
|
| 777 |
+
$attributes = array(
|
| 778 |
+
'layout' => 'nodisplay',
|
| 779 |
+
'intersection-ratios' => 1,
|
| 780 |
+
'on' => implode( ';', array(
|
| 781 |
+
'exit:navigationTopShow.start',
|
| 782 |
+
'enter:navigationTopHide.start',
|
| 783 |
+
) ),
|
| 784 |
+
);
|
| 785 |
+
if ( is_admin_bar_showing() ) {
|
| 786 |
+
$attributes['viewport-margins'] = '32px 0';
|
| 787 |
+
}
|
| 788 |
+
$position_observer = AMP_DOM_Utils::create_node( $this->dom, 'amp-position-observer', $attributes );
|
| 789 |
+
$navigation_top->appendChild( $position_observer );
|
| 790 |
+
|
| 791 |
+
$animations = array(
|
| 792 |
+
'navigationTopShow' => array(
|
| 793 |
+
'duration' => 0,
|
| 794 |
+
'fill' => 'both',
|
| 795 |
+
'animations' => array(
|
| 796 |
+
'selector' => '.navigation-top.site-navigation-fixed',
|
| 797 |
+
'media' => '(min-width: 48em)',
|
| 798 |
+
'keyframes' => array(
|
| 799 |
+
'opacity' => 1.0,
|
| 800 |
+
'transform' => 'translateY( 0 )',
|
| 801 |
+
),
|
| 802 |
+
),
|
| 803 |
+
),
|
| 804 |
+
'navigationTopHide' => array(
|
| 805 |
+
'duration' => 0,
|
| 806 |
+
'fill' => 'both',
|
| 807 |
+
'animations' => array(
|
| 808 |
+
'selector' => '.navigation-top.site-navigation-fixed',
|
| 809 |
+
'media' => '(min-width: 48em)',
|
| 810 |
+
'keyframes' => array(
|
| 811 |
+
'opacity' => 0.0,
|
| 812 |
+
'transform' => sprintf( 'translateY( -%dpx )', self::get_twentyseventeen_navigation_outer_height() ),
|
| 813 |
+
),
|
| 814 |
+
),
|
| 815 |
+
),
|
| 816 |
+
);
|
| 817 |
+
|
| 818 |
+
foreach ( $animations as $animation_id => $animation ) {
|
| 819 |
+
$amp_animation = AMP_DOM_Utils::create_node( $this->dom, 'amp-animation', array(
|
| 820 |
+
'id' => $animation_id,
|
| 821 |
+
'layout' => 'nodisplay',
|
| 822 |
+
) );
|
| 823 |
+
$position_script = $this->dom->createElement( 'script' );
|
| 824 |
+
$position_script->setAttribute( 'type', 'application/json' );
|
| 825 |
+
$position_script->appendChild( $this->dom->createTextNode( wp_json_encode( $animation ) ) );
|
| 826 |
+
$amp_animation->appendChild( $position_script );
|
| 827 |
+
$this->body->appendChild( $amp_animation );
|
| 828 |
+
}
|
| 829 |
+
}
|
| 830 |
+
|
| 831 |
+
/**
|
| 832 |
+
* Add styles for the nav menu specifically to deal with AMP running in a no-js context.
|
| 833 |
+
*
|
| 834 |
+
* @since 1.0
|
| 835 |
+
*
|
| 836 |
+
* @param array $args Args.
|
| 837 |
+
*/
|
| 838 |
+
public static function add_nav_menu_styles( $args = array() ) {
|
| 839 |
+
$args = array_merge(
|
| 840 |
+
self::get_theme_config( get_template() ),
|
| 841 |
+
$args
|
| 842 |
+
);
|
| 843 |
+
|
| 844 |
+
add_action( 'wp_enqueue_scripts', function() use ( $args ) {
|
| 845 |
+
ob_start();
|
| 846 |
+
?>
|
| 847 |
+
<style>
|
| 848 |
+
/* Override no-js selector in parent theme. */
|
| 849 |
+
.no-js .main-navigation ul ul {
|
| 850 |
+
display: none;
|
| 851 |
+
}
|
| 852 |
+
|
| 853 |
+
/* Use sibling selector and re-use class on button instead of toggling toggle-on class on ul.sub-menu */
|
| 854 |
+
.main-navigation ul .<?php echo esc_html( $args['sub_menu_button_toggle_class'] ); ?> + .sub-menu {
|
| 855 |
+
display: block;
|
| 856 |
+
}
|
| 857 |
+
|
| 858 |
+
<?php if ( 'twentyseventeen' === get_template() ) : ?>
|
| 859 |
+
/* Show the button*/
|
| 860 |
+
.no-js .<?php echo esc_html( $args['menu_button_class'] ); ?> {
|
| 861 |
+
display: block;
|
| 862 |
+
}
|
| 863 |
+
.no-js .main-navigation > div > ul {
|
| 864 |
+
display: none;
|
| 865 |
+
}
|
| 866 |
+
.no-js .main-navigation.<?php echo esc_html( $args['nav_container_toggle_class'] ); ?> > div > ul {
|
| 867 |
+
display: block;
|
| 868 |
+
}
|
| 869 |
+
@media screen and (min-width: 48em) {
|
| 870 |
+
.no-js .<?php echo esc_html( $args['menu_button_class'] ); ?>,
|
| 871 |
+
.no-js .<?php echo esc_html( $args['sub_menu_button_class'] ); ?> {
|
| 872 |
+
display: none;
|
| 873 |
+
}
|
| 874 |
+
.no-js .main-navigation ul,
|
| 875 |
+
.no-js .main-navigation ul ul,
|
| 876 |
+
.no-js .main-navigation > div > ul {
|
| 877 |
+
display: block;
|
| 878 |
+
}
|
| 879 |
+
.main-navigation ul li.menu-item-has-children:focus-within:before,
|
| 880 |
+
.main-navigation ul li.menu-item-has-children:focus-within:after,
|
| 881 |
+
.main-navigation ul li.page_item_has_children:focus-within:before,
|
| 882 |
+
.main-navigation ul li.page_item_has_children:focus-within:after {
|
| 883 |
+
display: block;
|
| 884 |
+
}
|
| 885 |
+
.main-navigation ul ul li:focus-within > ul {
|
| 886 |
+
<?php if ( is_rtl() ) : ?>
|
| 887 |
+
left: auto;
|
| 888 |
+
right: 100%;
|
| 889 |
+
<?php else : ?>
|
| 890 |
+
left: 100%;
|
| 891 |
+
right: auto;
|
| 892 |
+
<?php endif; ?>
|
| 893 |
+
}
|
| 894 |
+
.main-navigation li li:focus-within {
|
| 895 |
+
background: #767676;
|
| 896 |
+
}
|
| 897 |
+
.main-navigation li li:focus-within > a,
|
| 898 |
+
.main-navigation li li a:focus-within,
|
| 899 |
+
.main-navigation li li.current_page_item a:focus-within,
|
| 900 |
+
.main-navigation li li.current-menu-item a:focus-within {
|
| 901 |
+
color: #fff;
|
| 902 |
+
}
|
| 903 |
+
.main-navigation ul li:focus-within > ul {
|
| 904 |
+
<?php if ( is_rtl() ) : ?>
|
| 905 |
+
left: auto;
|
| 906 |
+
right: 0.5em;
|
| 907 |
+
<?php else : ?>
|
| 908 |
+
left: 0.5em;
|
| 909 |
+
right: auto;
|
| 910 |
+
<?php endif; ?>
|
| 911 |
+
}
|
| 912 |
+
|
| 913 |
+
.main-navigation ul ul li.menu-item-has-children:focus-within:before,
|
| 914 |
+
.main-navigation ul ul li.menu-item-has-children:focus-within:after,
|
| 915 |
+
.main-navigation ul ul li.page_item_has_children:focus-within:before,
|
| 916 |
+
.main-navigation ul ul li.page_item_has_children:focus-within:after {
|
| 917 |
+
display: none;
|
| 918 |
+
}
|
| 919 |
+
}
|
| 920 |
+
<?php elseif ( 'twentysixteen' === get_template() ) : ?>
|
| 921 |
+
@media screen and (max-width: 56.875em) {
|
| 922 |
+
/* Show the button*/
|
| 923 |
+
.no-js .<?php echo esc_html( $args['menu_button_class'] ); ?> {
|
| 924 |
+
display: block;
|
| 925 |
+
}
|
| 926 |
+
.no-js .site-header-menu {
|
| 927 |
+
display: none;
|
| 928 |
+
}
|
| 929 |
+
.no-js .site-header-menu.toggled-on {
|
| 930 |
+
display: block;
|
| 931 |
+
}
|
| 932 |
+
}
|
| 933 |
+
@media screen and (min-width: 56.875em) {
|
| 934 |
+
.no-js .main-navigation ul ul {
|
| 935 |
+
display: block;
|
| 936 |
+
}
|
| 937 |
+
.main-navigation li:focus-within > a {
|
| 938 |
+
color: #007acc;
|
| 939 |
+
}
|
| 940 |
+
.main-navigation li:focus-within > ul {
|
| 941 |
+
<?php if ( is_rtl() ) : ?>
|
| 942 |
+
left: auto;
|
| 943 |
+
right: 0;
|
| 944 |
+
<?php else : ?>
|
| 945 |
+
left: 0;
|
| 946 |
+
right: auto;
|
| 947 |
+
<?php endif; ?>
|
| 948 |
+
}
|
| 949 |
+
.main-navigation ul ul li:focus-within > ul {
|
| 950 |
+
<?php if ( is_rtl() ) : ?>
|
| 951 |
+
left: 100%;
|
| 952 |
+
right: auto;
|
| 953 |
+
<?php else : ?>
|
| 954 |
+
left: auto;
|
| 955 |
+
right: 100%;
|
| 956 |
+
<?php endif; ?>
|
| 957 |
+
}
|
| 958 |
+
}
|
| 959 |
+
<?php elseif ( 'twentyfifteen' === get_template() ) : ?>
|
| 960 |
+
@media screen and (min-width: 59.6875em) {
|
| 961 |
+
/* Attempt to emulate https://github.com/WordPress/wordpress-develop/blob/5e9a39baa7d4368f7d3c36dcbcd53db6317677c9/src/wp-content/themes/twentyfifteen/js/functions.js#L108-L149 */
|
| 962 |
+
#sidebar {
|
| 963 |
+
position: sticky;
|
| 964 |
+
top: -9vh;
|
| 965 |
+
max-height: 109vh;
|
| 966 |
+
overflow-y: auto;
|
| 967 |
+
}
|
| 968 |
+
}
|
| 969 |
+
|
| 970 |
+
<?php endif; ?>
|
| 971 |
+
</style>
|
| 972 |
+
<?php
|
| 973 |
+
$styles = str_replace( array( '<style>', '</style>' ), '', ob_get_clean() );
|
| 974 |
+
wp_add_inline_style( get_template() . '-style', $styles );
|
| 975 |
+
}, 11 );
|
| 976 |
+
}
|
| 977 |
+
|
| 978 |
+
/**
|
| 979 |
+
* Ensure that JS-only nav menu styles apply to AMP as well since even though scripts are not allowed, there are AMP-bind implementations.
|
| 980 |
+
*
|
| 981 |
+
* @since 1.0
|
| 982 |
+
*
|
| 983 |
+
* @param array $args Args.
|
| 984 |
+
*/
|
| 985 |
+
public function add_nav_menu_toggle( $args = array() ) {
|
| 986 |
+
$args = array_merge(
|
| 987 |
+
self::get_theme_config( get_template() ),
|
| 988 |
+
$args
|
| 989 |
+
);
|
| 990 |
+
|
| 991 |
+
$nav_el = $this->dom->getElementById( $args['nav_container_id'] );
|
| 992 |
+
$button_el = $this->xpath->query( $args['menu_button_xpath'] )->item( 0 );
|
| 993 |
+
if ( ! $nav_el ) {
|
| 994 |
+
if ( $button_el ) {
|
| 995 |
+
|
| 996 |
+
// Remove the button since it won't be used.
|
| 997 |
+
$button_el->parentNode->removeChild( $button_el );
|
| 998 |
+
}
|
| 999 |
+
return;
|
| 1000 |
+
}
|
| 1001 |
+
|
| 1002 |
+
if ( ! $button_el ) {
|
| 1003 |
+
return;
|
| 1004 |
+
}
|
| 1005 |
+
|
| 1006 |
+
$state_id = 'navMenuToggledOn';
|
| 1007 |
+
$expanded = false;
|
| 1008 |
+
|
| 1009 |
+
$nav_el->setAttribute(
|
| 1010 |
+
AMP_DOM_Utils::get_amp_bind_placeholder_prefix() . 'class',
|
| 1011 |
+
sprintf(
|
| 1012 |
+
"%s + ( $state_id ? %s : '' )",
|
| 1013 |
+
wp_json_encode( $nav_el->getAttribute( 'class' ) ),
|
| 1014 |
+
wp_json_encode( ' ' . $args['nav_container_toggle_class'] )
|
| 1015 |
+
)
|
| 1016 |
+
);
|
| 1017 |
+
|
| 1018 |
+
$state_el = $this->dom->createElement( 'amp-state' );
|
| 1019 |
+
$state_el->setAttribute( 'id', $state_id );
|
| 1020 |
+
$script_el = $this->dom->createElement( 'script' );
|
| 1021 |
+
$script_el->setAttribute( 'type', 'application/json' );
|
| 1022 |
+
$script_el->appendChild( $this->dom->createTextNode( wp_json_encode( $expanded ) ) );
|
| 1023 |
+
$state_el->appendChild( $script_el );
|
| 1024 |
+
$nav_el->parentNode->insertBefore( $state_el, $nav_el );
|
| 1025 |
+
|
| 1026 |
+
$button_on = sprintf( "tap:AMP.setState({ $state_id: ! $state_id })" );
|
| 1027 |
+
$button_el->setAttribute( 'on', $button_on );
|
| 1028 |
+
$button_el->setAttribute( 'aria-expanded', 'false' );
|
| 1029 |
+
$button_el->setAttribute( AMP_DOM_Utils::get_amp_bind_placeholder_prefix() . 'aria-expanded', "$state_id ? 'true' : 'false'" );
|
| 1030 |
+
$button_el->setAttribute(
|
| 1031 |
+
AMP_DOM_Utils::get_amp_bind_placeholder_prefix() . 'class',
|
| 1032 |
+
sprintf( "%s + ( $state_id ? %s : '' )", wp_json_encode( $button_el->getAttribute( 'class' ) ), wp_json_encode( ' ' . $args['menu_button_toggle_class'] ) )
|
| 1033 |
+
);
|
| 1034 |
+
}
|
| 1035 |
+
|
| 1036 |
+
/**
|
| 1037 |
+
* Add buttons for nav sub-menu items.
|
| 1038 |
+
*
|
| 1039 |
+
* @since 1.0
|
| 1040 |
+
* @link https://github.com/WordPress/wordpress-develop/blob/a26c24226c6b131a0ed22c722a836c100d3ba254/src/wp-content/themes/twentyseventeen/assets/js/navigation.js#L11-L43
|
| 1041 |
+
*
|
| 1042 |
+
* @param array $args Args.
|
| 1043 |
+
*/
|
| 1044 |
+
public static function add_nav_sub_menu_buttons( $args = array() ) {
|
| 1045 |
+
$default_args = self::get_theme_config( get_template() );
|
| 1046 |
+
switch ( get_template() ) {
|
| 1047 |
+
case 'twentyseventeen':
|
| 1048 |
+
if ( function_exists( 'twentyseventeen_get_svg' ) ) {
|
| 1049 |
+
$default_args['icon'] = twentyseventeen_get_svg( array(
|
| 1050 |
+
'icon' => 'angle-down',
|
| 1051 |
+
'fallback' => true,
|
| 1052 |
+
) );
|
| 1053 |
+
}
|
| 1054 |
+
break;
|
| 1055 |
+
}
|
| 1056 |
+
$args = array_merge( $default_args, $args );
|
| 1057 |
+
|
| 1058 |
+
/**
|
| 1059 |
+
* Filter the HTML output of a nav menu item to add the AMP dropdown button to reveal the sub-menu.
|
| 1060 |
+
*
|
| 1061 |
+
* @see twentyfifteen_amp_setup_hooks()
|
| 1062 |
+
*
|
| 1063 |
+
* @param string $item_output Nav menu item HTML.
|
| 1064 |
+
* @param object $item Nav menu item.
|
| 1065 |
+
* @return string Modified nav menu item HTML.
|
| 1066 |
+
*/
|
| 1067 |
+
add_filter( 'walker_nav_menu_start_el', function( $item_output, $item, $depth, $nav_menu_args ) use ( $args ) {
|
| 1068 |
+
unset( $depth );
|
| 1069 |
+
|
| 1070 |
+
// Skip adding buttons to nav menu widgets for now.
|
| 1071 |
+
if ( empty( $nav_menu_args->theme_location ) ) {
|
| 1072 |
+
return $item_output;
|
| 1073 |
+
}
|
| 1074 |
+
|
| 1075 |
+
if ( ! in_array( 'menu-item-has-children', $item->classes, true ) ) {
|
| 1076 |
+
return $item_output;
|
| 1077 |
+
}
|
| 1078 |
+
static $nav_menu_item_number = 0;
|
| 1079 |
+
$nav_menu_item_number++;
|
| 1080 |
+
|
| 1081 |
+
$expanded = in_array( 'current-menu-ancestor', $item->classes, true );
|
| 1082 |
+
|
| 1083 |
+
$expanded_state_id = 'navMenuItemExpanded' . $nav_menu_item_number;
|
| 1084 |
+
|
| 1085 |
+
// Create new state for managing storing the whether the sub-menu is expanded.
|
| 1086 |
+
$item_output .= sprintf(
|
| 1087 |
+
'<amp-state id="%s"><script type="application/json">%s</script></amp-state>',
|
| 1088 |
+
esc_attr( $expanded_state_id ),
|
| 1089 |
+
wp_json_encode( $expanded )
|
| 1090 |
+
);
|
| 1091 |
+
|
| 1092 |
+
$dropdown_button = '<button';
|
| 1093 |
+
$dropdown_button .= sprintf(
|
| 1094 |
+
' class="%s" [class]="%s"',
|
| 1095 |
+
esc_attr( $args['sub_menu_button_class'] . ( $expanded ? ' ' . $args['sub_menu_button_toggle_class'] : '' ) ),
|
| 1096 |
+
esc_attr( sprintf( "%s + ( $expanded_state_id ? %s : '' )", wp_json_encode( $args['sub_menu_button_class'] ), wp_json_encode( ' ' . $args['sub_menu_button_toggle_class'] ) ) )
|
| 1097 |
+
);
|
| 1098 |
+
$dropdown_button .= sprintf(
|
| 1099 |
+
' aria-expanded="%s" [aria-expanded]="%s"',
|
| 1100 |
+
esc_attr( wp_json_encode( $expanded ) ),
|
| 1101 |
+
esc_attr( "$expanded_state_id ? 'true' : 'false'" )
|
| 1102 |
+
);
|
| 1103 |
+
$dropdown_button .= sprintf(
|
| 1104 |
+
' on="%s"',
|
| 1105 |
+
esc_attr( "tap:AMP.setState( { $expanded_state_id: ! $expanded_state_id } )" )
|
| 1106 |
+
);
|
| 1107 |
+
$dropdown_button .= '>';
|
| 1108 |
+
|
| 1109 |
+
if ( isset( $args['icon'] ) ) {
|
| 1110 |
+
$dropdown_button .= $args['icon'];
|
| 1111 |
+
}
|
| 1112 |
+
if ( isset( $args['expand_text'] ) && isset( $args['collapse_text'] ) ) {
|
| 1113 |
+
$dropdown_button .= sprintf(
|
| 1114 |
+
'<span class="screen-reader-text" [text]="%s">%s</span>',
|
| 1115 |
+
esc_attr( sprintf( "$expanded_state_id ? %s : %s", wp_json_encode( $args['collapse_text'] ), wp_json_encode( $args['expand_text'] ) ) ),
|
| 1116 |
+
esc_html( $expanded ? $args['collapse_text'] : $args['expand_text'] )
|
| 1117 |
+
);
|
| 1118 |
+
}
|
| 1119 |
+
|
| 1120 |
+
$dropdown_button .= '</button>';
|
| 1121 |
+
|
| 1122 |
+
$item_output .= $dropdown_button;
|
| 1123 |
+
return $item_output;
|
| 1124 |
+
}, 10, 4 );
|
| 1125 |
+
}
|
| 1126 |
+
|
| 1127 |
+
/**
|
| 1128 |
+
* Output image styles for twentynineteen.
|
| 1129 |
+
*
|
| 1130 |
+
* When <img> tags have an 'aligncenter' class, AMP_Img_Sanitizer::handle_centering() wraps theme in <figure class="aligncenter">.
|
| 1131 |
+
* This ensures that the image inside it is centered.
|
| 1132 |
+
*
|
| 1133 |
+
* @since 1.0
|
| 1134 |
+
*
|
| 1135 |
+
* @param array $args Arguments.
|
| 1136 |
+
*/
|
| 1137 |
+
public static function add_twentynineteen_image_styles( $args = array() ) {
|
| 1138 |
+
add_action( 'wp_enqueue_scripts', function() use ( $args ) {
|
| 1139 |
+
ob_start();
|
| 1140 |
+
?>
|
| 1141 |
+
<style>
|
| 1142 |
+
figure.aligncenter {
|
| 1143 |
+
text-align: center
|
| 1144 |
+
}
|
| 1145 |
+
</style>
|
| 1146 |
+
<?php
|
| 1147 |
+
$styles = str_replace( array( '<style>', '</style>' ), '', ob_get_clean() );
|
| 1148 |
+
wp_add_inline_style( get_template() . '-style', $styles );
|
| 1149 |
+
}, 11 );
|
| 1150 |
+
}
|
| 1151 |
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Embed_Sanitizer
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Class AMP_Embed_Sanitizer
|
| 10 |
+
*
|
| 11 |
+
* Calls sanitize_raw_embeds method on embed handlers.
|
| 12 |
+
*/
|
| 13 |
+
class AMP_Embed_Sanitizer extends AMP_Base_Sanitizer {
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* Embed handlers.
|
| 17 |
+
*
|
| 18 |
+
* @var AMP_Base_Embed_Handler[] AMP_Base_Embed_Handler[]
|
| 19 |
+
*/
|
| 20 |
+
private $embed_handlers = array();
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* AMP_Embed_Sanitizer constructor.
|
| 24 |
+
*
|
| 25 |
+
* @param DOMDocument $dom DOM.
|
| 26 |
+
* @param array $args Args.
|
| 27 |
+
*/
|
| 28 |
+
public function __construct( $dom, $args = array() ) {
|
| 29 |
+
parent::__construct( $dom, $args );
|
| 30 |
+
|
| 31 |
+
if ( ! empty( $this->args['embed_handlers'] ) ) {
|
| 32 |
+
$this->embed_handlers = $this->args['embed_handlers'];
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
/**
|
| 37 |
+
* Checks if each embed_handler has sanitize_raw_method and calls it.
|
| 38 |
+
*/
|
| 39 |
+
public function sanitize() {
|
| 40 |
+
|
| 41 |
+
foreach ( $this->embed_handlers as $embed_handler ) {
|
| 42 |
+
if ( method_exists( $embed_handler, 'sanitize_raw_embeds' ) ) {
|
| 43 |
+
$embed_handler->sanitize_raw_embeds( $this->dom );
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
}
|
| 47 |
+
}
|
|
@@ -24,6 +24,17 @@ class AMP_Form_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 24 |
*/
|
| 25 |
public static $tag = 'form';
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
/**
|
| 28 |
* Sanitize the <form> elements from the HTML contained in this instance's DOMDocument.
|
| 29 |
*
|
|
@@ -67,6 +78,10 @@ class AMP_Form_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 67 |
$action_url = esc_url_raw( '//' . $_SERVER['HTTP_HOST'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ); // WPCS: ignore. input var okay, sanitization ok.
|
| 68 |
} else {
|
| 69 |
$action_url = $node->getAttribute( 'action' );
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
}
|
| 71 |
$xhr_action = $node->getAttribute( 'action-xhr' );
|
| 72 |
|
| 24 |
*/
|
| 25 |
public static $tag = 'form';
|
| 26 |
|
| 27 |
+
/**
|
| 28 |
+
* Get mapping of HTML selectors to the AMP component selectors which they may be converted into.
|
| 29 |
+
*
|
| 30 |
+
* @return array Mapping.
|
| 31 |
+
*/
|
| 32 |
+
public function get_selector_conversion_mapping() {
|
| 33 |
+
return array(
|
| 34 |
+
'form' => array( 'amp-form' ),
|
| 35 |
+
);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
/**
|
| 39 |
* Sanitize the <form> elements from the HTML contained in this instance's DOMDocument.
|
| 40 |
*
|
| 78 |
$action_url = esc_url_raw( '//' . $_SERVER['HTTP_HOST'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ); // WPCS: ignore. input var okay, sanitization ok.
|
| 79 |
} else {
|
| 80 |
$action_url = $node->getAttribute( 'action' );
|
| 81 |
+
// Check if action_url is a relative path and add the host to it.
|
| 82 |
+
if ( ! preg_match( '#^(https?:)?//#', $action_url ) ) {
|
| 83 |
+
$action_url = esc_url_raw( '//' . $_SERVER['HTTP_HOST'] . $action_url );
|
| 84 |
+
}
|
| 85 |
}
|
| 86 |
$xhr_action = $node->getAttribute( 'action-xhr' );
|
| 87 |
|
|
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Gallery_Block_Sanitizer.
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Class AMP_Gallery_Block_Sanitizer
|
| 10 |
+
*
|
| 11 |
+
* Modifies gallery block to match the block's AMP-specific configuration.
|
| 12 |
+
*/
|
| 13 |
+
class AMP_Gallery_Block_Sanitizer extends AMP_Base_Sanitizer {
|
| 14 |
+
|
| 15 |
+
/**
|
| 16 |
+
* Value used for width of amp-carousel.
|
| 17 |
+
*
|
| 18 |
+
* @since 1.0
|
| 19 |
+
*
|
| 20 |
+
* @const int
|
| 21 |
+
*/
|
| 22 |
+
const FALLBACK_WIDTH = 600;
|
| 23 |
+
|
| 24 |
+
/**
|
| 25 |
+
* Value used for height of amp-carousel.
|
| 26 |
+
*
|
| 27 |
+
* @since 1.0
|
| 28 |
+
*
|
| 29 |
+
* @const int
|
| 30 |
+
*/
|
| 31 |
+
const FALLBACK_HEIGHT = 480;
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* Tag.
|
| 35 |
+
*
|
| 36 |
+
* @since 1.0
|
| 37 |
+
*
|
| 38 |
+
* @var string Ul tag to identify wrapper around gallery block.
|
| 39 |
+
*/
|
| 40 |
+
public static $tag = 'ul';
|
| 41 |
+
|
| 42 |
+
/**
|
| 43 |
+
* Expected class of the wrapper around the gallery block.
|
| 44 |
+
*
|
| 45 |
+
* @since 1.0
|
| 46 |
+
*
|
| 47 |
+
* @var string
|
| 48 |
+
*/
|
| 49 |
+
public static $class = 'wp-block-gallery';
|
| 50 |
+
|
| 51 |
+
/**
|
| 52 |
+
* Array of flags used to control sanitization.
|
| 53 |
+
*
|
| 54 |
+
* @var array {
|
| 55 |
+
* @type int $content_max_width Max width of content.
|
| 56 |
+
* @type bool $carousel_required Whether carousels are required. This is used when amp theme support is not present, for back-compat.
|
| 57 |
+
* }
|
| 58 |
+
*/
|
| 59 |
+
protected $args;
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Default args.
|
| 63 |
+
*
|
| 64 |
+
* @var array
|
| 65 |
+
*/
|
| 66 |
+
protected $DEFAULT_ARGS = array(
|
| 67 |
+
'carousel_required' => false,
|
| 68 |
+
);
|
| 69 |
+
|
| 70 |
+
/**
|
| 71 |
+
* Sanitize the gallery block contained by <ul> element where necessary.
|
| 72 |
+
*
|
| 73 |
+
* @since 0.2
|
| 74 |
+
*/
|
| 75 |
+
public function sanitize() {
|
| 76 |
+
$nodes = $this->dom->getElementsByTagName( self::$tag );
|
| 77 |
+
$num_nodes = $nodes->length;
|
| 78 |
+
if ( 0 === $num_nodes ) {
|
| 79 |
+
return;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 83 |
+
$node = $nodes->item( $i );
|
| 84 |
+
|
| 85 |
+
// We're looking for <ul> elements that have at least one child and the proper class.
|
| 86 |
+
if ( 0 === count( $node->childNodes ) || false === strpos( $node->getAttribute( 'class' ), self::$class ) ) {
|
| 87 |
+
continue;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
$attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
| 91 |
+
$is_amp_lightbox = isset( $attributes['data-amp-lightbox'] ) && true === filter_var( $attributes['data-amp-lightbox'], FILTER_VALIDATE_BOOLEAN );
|
| 92 |
+
$is_amp_carousel = ! empty( $this->args['carousel_required'] ) || ( isset( $attributes['data-amp-carousel'] ) && true === filter_var( $attributes['data-amp-carousel'], FILTER_VALIDATE_BOOLEAN ) );
|
| 93 |
+
|
| 94 |
+
// We are only looking for <ul> elements which have amp-carousel / amp-lightbox true.
|
| 95 |
+
if ( ! $is_amp_carousel && ! $is_amp_lightbox ) {
|
| 96 |
+
continue;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
// If lightbox is set, we should add lightbox feature to the gallery images.
|
| 100 |
+
if ( $is_amp_lightbox ) {
|
| 101 |
+
$this->add_lightbox_attributes_to_image_nodes( $node );
|
| 102 |
+
$this->maybe_add_amp_image_lightbox_node();
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
// If amp-carousel is not set, nothing else to do here.
|
| 106 |
+
if ( ! $is_amp_carousel ) {
|
| 107 |
+
continue;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
$images = array();
|
| 111 |
+
|
| 112 |
+
// If it's not AMP lightbox, look for links first.
|
| 113 |
+
if ( ! $is_amp_lightbox ) {
|
| 114 |
+
foreach ( $node->getElementsByTagName( 'a' ) as $element ) {
|
| 115 |
+
$images[] = $element;
|
| 116 |
+
}
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
// If not linking to anything then look for <amp-img>.
|
| 120 |
+
if ( empty( $images ) ) {
|
| 121 |
+
foreach ( $node->getElementsByTagName( 'amp-img' ) as $element ) {
|
| 122 |
+
$images[] = $element;
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
// Skip if no images found.
|
| 127 |
+
if ( empty( $images ) ) {
|
| 128 |
+
continue;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
$amp_carousel = AMP_DOM_Utils::create_node( $this->dom, 'amp-carousel', array(
|
| 132 |
+
'height' => $this->get_carousel_height( $node ),
|
| 133 |
+
'type' => 'slides',
|
| 134 |
+
'layout' => 'fixed-height',
|
| 135 |
+
) );
|
| 136 |
+
foreach ( $images as $image ) {
|
| 137 |
+
$amp_carousel->appendChild( $image );
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
$node->parentNode->replaceChild( $amp_carousel, $node );
|
| 141 |
+
}
|
| 142 |
+
$this->did_convert_elements = true;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
/**
|
| 146 |
+
* Get carousel height by containing images.
|
| 147 |
+
*
|
| 148 |
+
* @param DOMElement $element The UL element.
|
| 149 |
+
* @return int Height.
|
| 150 |
+
*/
|
| 151 |
+
protected function get_carousel_height( $element ) {
|
| 152 |
+
$images = $element->getElementsByTagName( 'amp-img' );
|
| 153 |
+
$num_images = $images->length;
|
| 154 |
+
$max_height = 0;
|
| 155 |
+
$max_width = 0;
|
| 156 |
+
if ( 0 === $num_images ) {
|
| 157 |
+
return self::FALLBACK_HEIGHT;
|
| 158 |
+
}
|
| 159 |
+
foreach ( $images as $image ) {
|
| 160 |
+
/**
|
| 161 |
+
* Image.
|
| 162 |
+
*
|
| 163 |
+
* @var DOMElement $image
|
| 164 |
+
*/
|
| 165 |
+
$image_height = $image->getAttribute( 'height' );
|
| 166 |
+
if ( is_numeric( $image_height ) ) {
|
| 167 |
+
$max_height = max( $max_height, $image_height );
|
| 168 |
+
}
|
| 169 |
+
$image_width = $image->getAttribute( 'height' );
|
| 170 |
+
if ( is_numeric( $image_width ) ) {
|
| 171 |
+
$max_width = max( $max_width, $image_width );
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
if ( ! empty( $this->args['content_max_width'] ) && $max_height > 0 && $max_width > $this->args['content_max_width'] ) {
|
| 176 |
+
$max_height = ( $max_width * $this->args['content_max_width'] ) / $max_height;
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
return ! $max_height ? self::FALLBACK_HEIGHT : $max_height;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
/**
|
| 183 |
+
* Set lightbox related attributes to <amp-img> within gallery.
|
| 184 |
+
*
|
| 185 |
+
* @param DOMElement $element The UL element.
|
| 186 |
+
*/
|
| 187 |
+
protected function add_lightbox_attributes_to_image_nodes( $element ) {
|
| 188 |
+
$images = $element->getElementsByTagName( 'amp-img' );
|
| 189 |
+
$num_images = $images->length;
|
| 190 |
+
if ( 0 === $num_images ) {
|
| 191 |
+
return;
|
| 192 |
+
}
|
| 193 |
+
$attributes = array(
|
| 194 |
+
'data-amp-lightbox' => '',
|
| 195 |
+
'on' => 'tap:' . self::AMP_IMAGE_LIGHTBOX_ID,
|
| 196 |
+
'role' => 'button',
|
| 197 |
+
'tabindex' => 0,
|
| 198 |
+
);
|
| 199 |
+
|
| 200 |
+
for ( $j = $num_images - 1; $j >= 0; $j-- ) {
|
| 201 |
+
$image_node = $images->item( $j );
|
| 202 |
+
foreach ( $attributes as $att => $value ) {
|
| 203 |
+
$image_node->setAttribute( $att, $value );
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
}
|
| 207 |
+
}
|
|
@@ -48,6 +48,19 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 48 |
'add_placeholder' => false,
|
| 49 |
);
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
/**
|
| 52 |
* Sanitize the <iframe> elements from the HTML contained in this instance's DOMDocument.
|
| 53 |
*
|
|
@@ -62,9 +75,7 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 62 |
|
| 63 |
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 64 |
$node = $nodes->item( $i );
|
| 65 |
-
$
|
| 66 |
-
|
| 67 |
-
$new_attributes = $this->filter_attributes( $old_attributes );
|
| 68 |
|
| 69 |
/**
|
| 70 |
* If the src doesn't exist, remove the node. Either it never
|
|
@@ -73,44 +84,32 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 73 |
* @todo: add a filter to allow for a fallback element in this instance.
|
| 74 |
* @see: https://github.com/ampproject/amphtml/issues/2261
|
| 75 |
*/
|
| 76 |
-
if ( empty( $
|
| 77 |
$this->remove_invalid_child( $node );
|
| 78 |
continue;
|
| 79 |
}
|
| 80 |
|
| 81 |
$this->did_convert_elements = true;
|
| 82 |
-
$
|
| 83 |
-
if ( empty( $
|
| 84 |
-
$
|
| 85 |
-
$this->add_or_append_attribute( $
|
| 86 |
}
|
| 87 |
|
| 88 |
-
$new_node = AMP_DOM_Utils::create_node( $this->dom, 'amp-iframe', $
|
| 89 |
|
| 90 |
if ( true === $this->args['add_placeholder'] ) {
|
| 91 |
-
$placeholder_node = $this->build_placeholder( $
|
| 92 |
$new_node->appendChild( $placeholder_node );
|
| 93 |
}
|
| 94 |
|
| 95 |
-
$
|
| 96 |
-
if ( 'p' !== strtolower( $parent_node->tagName ) ) {
|
| 97 |
-
$parent_node->replaceChild( $new_node, $node );
|
| 98 |
-
} else {
|
| 99 |
-
// AMP does not like iframes in <p> tags.
|
| 100 |
-
$parent_node->removeChild( $node );
|
| 101 |
-
$parent_node->parentNode->insertBefore( $new_node, $parent_node->nextSibling );
|
| 102 |
-
|
| 103 |
-
if ( AMP_DOM_Utils::is_node_empty( $parent_node ) ) {
|
| 104 |
-
$parent_node->parentNode->removeChild( $parent_node );
|
| 105 |
-
}
|
| 106 |
-
}
|
| 107 |
}
|
| 108 |
}
|
| 109 |
|
| 110 |
/**
|
| 111 |
-
*
|
| 112 |
*
|
| 113 |
-
* @since 0.2
|
| 114 |
*
|
| 115 |
* @param string[] $attributes {
|
| 116 |
* Attributes.
|
|
@@ -121,23 +120,18 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 121 |
* @type string $sandbox <iframe> `sandbox` attribute - Pass along if found; default to value of self::SANDBOX_DEFAULTS
|
| 122 |
* @type string $class <iframe> `class` attribute - Pass along if found
|
| 123 |
* @type string $sizes <iframe> `sizes` attribute - Pass along if found
|
|
|
|
| 124 |
* @type int $frameborder <iframe> `frameborder` attribute - Filter to '0' or '1'; default to '0'
|
| 125 |
* @type bool $allowfullscreen <iframe> `allowfullscreen` attribute - Convert 'false' to empty string ''
|
| 126 |
* @type bool $allowtransparency <iframe> `allowtransparency` attribute - Convert 'false' to empty string ''
|
| 127 |
* }
|
| 128 |
-
* @return array Returns HTML attributes;
|
| 129 |
*/
|
| 130 |
-
private function
|
| 131 |
$out = array();
|
| 132 |
|
| 133 |
foreach ( $attributes as $name => $value ) {
|
| 134 |
switch ( $name ) {
|
| 135 |
-
case 'sandbox':
|
| 136 |
-
case 'class':
|
| 137 |
-
case 'sizes':
|
| 138 |
-
$out[ $name ] = $value;
|
| 139 |
-
break;
|
| 140 |
-
|
| 141 |
case 'src':
|
| 142 |
$out[ $name ] = $this->maybe_enforce_https_src( $value, true );
|
| 143 |
break;
|
|
@@ -162,6 +156,7 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 162 |
break;
|
| 163 |
|
| 164 |
default:
|
|
|
|
| 165 |
break;
|
| 166 |
}
|
| 167 |
}
|
|
@@ -176,6 +171,9 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 176 |
/**
|
| 177 |
* Builds a DOMElement to use as a placeholder for an <iframe>.
|
| 178 |
*
|
|
|
|
|
|
|
|
|
|
| 179 |
* @since 0.2
|
| 180 |
*
|
| 181 |
* @param string[] $parent_attributes {
|
|
@@ -187,9 +185,9 @@ class AMP_Iframe_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 187 |
* @return DOMElement|false
|
| 188 |
*/
|
| 189 |
private function build_placeholder( $parent_attributes ) {
|
| 190 |
-
$placeholder_node = AMP_DOM_Utils::create_node( $this->dom, '
|
| 191 |
'placeholder' => '',
|
| 192 |
-
'class'
|
| 193 |
) );
|
| 194 |
|
| 195 |
return $placeholder_node;
|
| 48 |
'add_placeholder' => false,
|
| 49 |
);
|
| 50 |
|
| 51 |
+
/**
|
| 52 |
+
* Get mapping of HTML selectors to the AMP component selectors which they may be converted into.
|
| 53 |
+
*
|
| 54 |
+
* @return array Mapping.
|
| 55 |
+
*/
|
| 56 |
+
public function get_selector_conversion_mapping() {
|
| 57 |
+
return array(
|
| 58 |
+
'iframe' => array(
|
| 59 |
+
'amp-iframe',
|
| 60 |
+
),
|
| 61 |
+
);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
/**
|
| 65 |
* Sanitize the <iframe> elements from the HTML contained in this instance's DOMDocument.
|
| 66 |
*
|
| 75 |
|
| 76 |
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 77 |
$node = $nodes->item( $i );
|
| 78 |
+
$normalized_attributes = $this->normalize_attributes( AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node ) );
|
|
|
|
|
|
|
| 79 |
|
| 80 |
/**
|
| 81 |
* If the src doesn't exist, remove the node. Either it never
|
| 84 |
* @todo: add a filter to allow for a fallback element in this instance.
|
| 85 |
* @see: https://github.com/ampproject/amphtml/issues/2261
|
| 86 |
*/
|
| 87 |
+
if ( empty( $normalized_attributes['src'] ) ) {
|
| 88 |
$this->remove_invalid_child( $node );
|
| 89 |
continue;
|
| 90 |
}
|
| 91 |
|
| 92 |
$this->did_convert_elements = true;
|
| 93 |
+
$normalized_attributes = $this->set_layout( $normalized_attributes );
|
| 94 |
+
if ( empty( $normalized_attributes['layout'] ) && ! empty( $normalized_attributes['width'] ) && ! empty( $normalized_attributes['height'] ) ) {
|
| 95 |
+
$normalized_attributes['layout'] = 'intrinsic';
|
| 96 |
+
$this->add_or_append_attribute( $normalized_attributes, 'class', 'amp-wp-enforced-sizes' );
|
| 97 |
}
|
| 98 |
|
| 99 |
+
$new_node = AMP_DOM_Utils::create_node( $this->dom, 'amp-iframe', $normalized_attributes );
|
| 100 |
|
| 101 |
if ( true === $this->args['add_placeholder'] ) {
|
| 102 |
+
$placeholder_node = $this->build_placeholder( $normalized_attributes );
|
| 103 |
$new_node->appendChild( $placeholder_node );
|
| 104 |
}
|
| 105 |
|
| 106 |
+
$node->parentNode->replaceChild( $new_node, $node );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
}
|
| 108 |
}
|
| 109 |
|
| 110 |
/**
|
| 111 |
+
* Normalize HTML attributes for <amp-iframe> elements.
|
| 112 |
*
|
|
|
|
| 113 |
*
|
| 114 |
* @param string[] $attributes {
|
| 115 |
* Attributes.
|
| 120 |
* @type string $sandbox <iframe> `sandbox` attribute - Pass along if found; default to value of self::SANDBOX_DEFAULTS
|
| 121 |
* @type string $class <iframe> `class` attribute - Pass along if found
|
| 122 |
* @type string $sizes <iframe> `sizes` attribute - Pass along if found
|
| 123 |
+
* @type string $id <iframe> `id` attribute - Pass along if found
|
| 124 |
* @type int $frameborder <iframe> `frameborder` attribute - Filter to '0' or '1'; default to '0'
|
| 125 |
* @type bool $allowfullscreen <iframe> `allowfullscreen` attribute - Convert 'false' to empty string ''
|
| 126 |
* @type bool $allowtransparency <iframe> `allowtransparency` attribute - Convert 'false' to empty string ''
|
| 127 |
* }
|
| 128 |
+
* @return array Returns HTML attributes; normalizes src, dimensions, frameborder, sandox, allowtransparency and allowfullscreen
|
| 129 |
*/
|
| 130 |
+
private function normalize_attributes( $attributes ) {
|
| 131 |
$out = array();
|
| 132 |
|
| 133 |
foreach ( $attributes as $name => $value ) {
|
| 134 |
switch ( $name ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
case 'src':
|
| 136 |
$out[ $name ] = $this->maybe_enforce_https_src( $value, true );
|
| 137 |
break;
|
| 156 |
break;
|
| 157 |
|
| 158 |
default:
|
| 159 |
+
$out[ $name ] = $value;
|
| 160 |
break;
|
| 161 |
}
|
| 162 |
}
|
| 171 |
/**
|
| 172 |
* Builds a DOMElement to use as a placeholder for an <iframe>.
|
| 173 |
*
|
| 174 |
+
* Important: The element returned must not be block-level (e.g. div) as the PHP DOM parser
|
| 175 |
+
* will move it out from inside any containing paragraph. So this is why a span is used.
|
| 176 |
+
*
|
| 177 |
* @since 0.2
|
| 178 |
*
|
| 179 |
* @param string[] $parent_attributes {
|
| 185 |
* @return DOMElement|false
|
| 186 |
*/
|
| 187 |
private function build_placeholder( $parent_attributes ) {
|
| 188 |
+
$placeholder_node = AMP_DOM_Utils::create_node( $this->dom, 'span', array(
|
| 189 |
'placeholder' => '',
|
| 190 |
+
'class' => 'amp-wp-iframe-placeholder',
|
| 191 |
) );
|
| 192 |
|
| 193 |
return $placeholder_node;
|
|
@@ -46,6 +46,20 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 46 |
*/
|
| 47 |
private static $anim_extension = '.gif';
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
/**
|
| 50 |
* Sanitize the <img> elements from the HTML contained in this instance's DOMDocument.
|
| 51 |
*
|
|
@@ -115,15 +129,6 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 115 |
|
| 116 |
foreach ( $attributes as $name => $value ) {
|
| 117 |
switch ( $name ) {
|
| 118 |
-
case 'src':
|
| 119 |
-
case 'alt':
|
| 120 |
-
case 'class':
|
| 121 |
-
case 'srcset':
|
| 122 |
-
case 'on':
|
| 123 |
-
case 'attribution':
|
| 124 |
-
$out[ $name ] = $value;
|
| 125 |
-
break;
|
| 126 |
-
|
| 127 |
case 'width':
|
| 128 |
case 'height':
|
| 129 |
$out[ $name ] = $this->sanitize_dimension( $value, $name );
|
|
@@ -133,7 +138,12 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 133 |
$out['layout'] = $value;
|
| 134 |
break;
|
| 135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
default:
|
|
|
|
| 137 |
break;
|
| 138 |
}
|
| 139 |
}
|
|
@@ -219,15 +229,24 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 219 |
/**
|
| 220 |
* Make final modifications to DOMNode
|
| 221 |
*
|
| 222 |
-
* @param
|
| 223 |
*/
|
| 224 |
private function adjust_and_replace_node( $node ) {
|
|
|
|
|
|
|
| 225 |
$old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
|
|
|
|
|
|
|
|
|
| 226 |
$new_attributes = $this->filter_attributes( $old_attributes );
|
|
|
|
|
|
|
|
|
|
| 227 |
$this->add_or_append_attribute( $new_attributes, 'class', 'amp-wp-enforced-sizes' );
|
| 228 |
if ( empty( $new_attributes['layout'] ) && ! empty( $new_attributes['height'] ) && ! empty( $new_attributes['width'] ) ) {
|
| 229 |
$new_attributes['layout'] = 'intrinsic';
|
| 230 |
}
|
|
|
|
| 231 |
if ( $this->is_gif_url( $new_attributes['src'] ) ) {
|
| 232 |
$this->did_convert_elements = true;
|
| 233 |
|
|
@@ -238,6 +257,34 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 238 |
$new_node = AMP_DOM_Utils::create_node( $this->dom, $new_tag, $new_attributes );
|
| 239 |
$new_node = $this->handle_centering( $new_node );
|
| 240 |
$node->parentNode->replaceChild( $new_node, $node );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
}
|
| 242 |
|
| 243 |
/**
|
|
@@ -251,7 +298,7 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 251 |
*/
|
| 252 |
private function is_gif_url( $url ) {
|
| 253 |
$ext = self::$anim_extension;
|
| 254 |
-
$path =
|
| 255 |
return substr( $path, -strlen( $ext ) ) === $ext;
|
| 256 |
}
|
| 257 |
|
|
@@ -263,7 +310,7 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 263 |
* So this strips that class, and instead wraps the image in a <figure> to center it.
|
| 264 |
*
|
| 265 |
* @since 0.7
|
| 266 |
-
* @see https://github.com/
|
| 267 |
*
|
| 268 |
* @param DOMElement $node The <amp-img> node.
|
| 269 |
* @return DOMElement $node The <amp-img> node, possibly wrapped in a <figure>.
|
|
@@ -293,4 +340,37 @@ class AMP_Img_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 293 |
|
| 294 |
return $figure;
|
| 295 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
}
|
| 46 |
*/
|
| 47 |
private static $anim_extension = '.gif';
|
| 48 |
|
| 49 |
+
/**
|
| 50 |
+
* Get mapping of HTML selectors to the AMP component selectors which they may be converted into.
|
| 51 |
+
*
|
| 52 |
+
* @return array Mapping.
|
| 53 |
+
*/
|
| 54 |
+
public function get_selector_conversion_mapping() {
|
| 55 |
+
return array(
|
| 56 |
+
'img' => array(
|
| 57 |
+
'amp-img',
|
| 58 |
+
'amp-anim',
|
| 59 |
+
),
|
| 60 |
+
);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
/**
|
| 64 |
* Sanitize the <img> elements from the HTML contained in this instance's DOMDocument.
|
| 65 |
*
|
| 129 |
|
| 130 |
foreach ( $attributes as $name => $value ) {
|
| 131 |
switch ( $name ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
case 'width':
|
| 133 |
case 'height':
|
| 134 |
$out[ $name ] = $this->sanitize_dimension( $value, $name );
|
| 138 |
$out['layout'] = $value;
|
| 139 |
break;
|
| 140 |
|
| 141 |
+
case 'data-amp-noloading':
|
| 142 |
+
$out['noloading'] = $value;
|
| 143 |
+
break;
|
| 144 |
+
|
| 145 |
default:
|
| 146 |
+
$out[ $name ] = $value;
|
| 147 |
break;
|
| 148 |
}
|
| 149 |
}
|
| 229 |
/**
|
| 230 |
* Make final modifications to DOMNode
|
| 231 |
*
|
| 232 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 233 |
*/
|
| 234 |
private function adjust_and_replace_node( $node ) {
|
| 235 |
+
|
| 236 |
+
$amp_data = $this->get_data_amp_attributes( $node );
|
| 237 |
$old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $node );
|
| 238 |
+
$old_attributes = $this->filter_data_amp_attributes( $old_attributes, $amp_data );
|
| 239 |
+
$old_attributes = $this->maybe_add_lightbox_attributes( $old_attributes, $node );
|
| 240 |
+
|
| 241 |
$new_attributes = $this->filter_attributes( $old_attributes );
|
| 242 |
+
$layout = isset( $amp_data['layout'] ) ? $amp_data['layout'] : false;
|
| 243 |
+
$new_attributes = $this->filter_attachment_layout_attributes( $node, $new_attributes, $layout );
|
| 244 |
+
|
| 245 |
$this->add_or_append_attribute( $new_attributes, 'class', 'amp-wp-enforced-sizes' );
|
| 246 |
if ( empty( $new_attributes['layout'] ) && ! empty( $new_attributes['height'] ) && ! empty( $new_attributes['width'] ) ) {
|
| 247 |
$new_attributes['layout'] = 'intrinsic';
|
| 248 |
}
|
| 249 |
+
|
| 250 |
if ( $this->is_gif_url( $new_attributes['src'] ) ) {
|
| 251 |
$this->did_convert_elements = true;
|
| 252 |
|
| 257 |
$new_node = AMP_DOM_Utils::create_node( $this->dom, $new_tag, $new_attributes );
|
| 258 |
$new_node = $this->handle_centering( $new_node );
|
| 259 |
$node->parentNode->replaceChild( $new_node, $node );
|
| 260 |
+
$this->add_auto_width_to_figure( $new_node );
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
/**
|
| 264 |
+
* Set lightbox attributes.
|
| 265 |
+
*
|
| 266 |
+
* @param array $attributes Array of attributes.
|
| 267 |
+
* @param DomNode $node Array of AMP attributes.
|
| 268 |
+
* @return array Updated attributes.
|
| 269 |
+
*/
|
| 270 |
+
private function maybe_add_lightbox_attributes( $attributes, $node ) {
|
| 271 |
+
$parent_node = $node->parentNode;
|
| 272 |
+
if ( ! ( $parent_node instanceof DOMElement ) || 'figure' !== $parent_node->tagName ) {
|
| 273 |
+
return $attributes;
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
$parent_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $parent_node );
|
| 277 |
+
|
| 278 |
+
if ( isset( $parent_attributes['data-amp-lightbox'] ) && true === filter_var( $parent_attributes['data-amp-lightbox'], FILTER_VALIDATE_BOOLEAN ) ) {
|
| 279 |
+
$attributes['data-amp-lightbox'] = '';
|
| 280 |
+
$attributes['on'] = 'tap:' . self::AMP_IMAGE_LIGHTBOX_ID;
|
| 281 |
+
$attributes['role'] = 'button';
|
| 282 |
+
$attributes['tabindex'] = 0;
|
| 283 |
+
|
| 284 |
+
$this->maybe_add_amp_image_lightbox_node();
|
| 285 |
+
}
|
| 286 |
+
|
| 287 |
+
return $attributes;
|
| 288 |
}
|
| 289 |
|
| 290 |
/**
|
| 298 |
*/
|
| 299 |
private function is_gif_url( $url ) {
|
| 300 |
$ext = self::$anim_extension;
|
| 301 |
+
$path = wp_parse_url( $url, PHP_URL_PATH );
|
| 302 |
return substr( $path, -strlen( $ext ) ) === $ext;
|
| 303 |
}
|
| 304 |
|
| 310 |
* So this strips that class, and instead wraps the image in a <figure> to center it.
|
| 311 |
*
|
| 312 |
* @since 0.7
|
| 313 |
+
* @see https://github.com/ampproject/amp-wp/issues/1104
|
| 314 |
*
|
| 315 |
* @param DOMElement $node The <amp-img> node.
|
| 316 |
* @return DOMElement $node The <amp-img> node, possibly wrapped in a <figure>.
|
| 340 |
|
| 341 |
return $figure;
|
| 342 |
}
|
| 343 |
+
|
| 344 |
+
/**
|
| 345 |
+
* Add an inline style to set the `<figure>` element's width to `auto` instead of `fit-content`.
|
| 346 |
+
*
|
| 347 |
+
* @since 1.0
|
| 348 |
+
* @see https://github.com/ampproject/amp-wp/issues/1086
|
| 349 |
+
*
|
| 350 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 351 |
+
*/
|
| 352 |
+
protected function add_auto_width_to_figure( $node ) {
|
| 353 |
+
$figure = $node->parentNode;
|
| 354 |
+
if ( ! ( $figure instanceof DOMElement ) || 'figure' !== $figure->tagName ) {
|
| 355 |
+
return;
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
$class = $figure->getAttribute( 'class' );
|
| 359 |
+
// Target only the <figure> with a 'wp-block-image' class attribute.
|
| 360 |
+
if ( false === strpos( $class, 'wp-block-image' ) ) {
|
| 361 |
+
return;
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
// Target only <figure> without a 'is-resized' class attribute.
|
| 365 |
+
if ( false !== strpos( $class, 'is-resized' ) ) {
|
| 366 |
+
return;
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
$new_style = 'width: auto;';
|
| 370 |
+
if ( $figure->hasAttribute( 'style' ) ) {
|
| 371 |
+
$figure->setAttribute( 'style', $new_style . $figure->getAttribute( 'style' ) );
|
| 372 |
+
} else {
|
| 373 |
+
$figure->setAttribute( 'style', $new_style );
|
| 374 |
+
}
|
| 375 |
+
}
|
| 376 |
}
|
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_O2_Player_Sanitizer
|
| 4 |
+
*
|
| 5 |
+
* @package AMP
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* Class AMP_O2_Player_Sanitizer
|
| 10 |
+
*
|
| 11 |
+
* Converts <div class="vdb_player><script></script></div> embed to <amp-o2-player>
|
| 12 |
+
*
|
| 13 |
+
* @since 1.0
|
| 14 |
+
* @see https://www.ampproject.org/docs/reference/components/amp-o2-player
|
| 15 |
+
*/
|
| 16 |
+
class AMP_O2_Player_Sanitizer extends AMP_Base_Sanitizer {
|
| 17 |
+
/**
|
| 18 |
+
* Pattern to extract the information required for amp-o2-player element: data-pid, data-vid, data-bcid.
|
| 19 |
+
*
|
| 20 |
+
* @since 1.0
|
| 21 |
+
*/
|
| 22 |
+
const URL_PATTERN = '#.*delivery.vidible.tv\/jsonp\/pid=(?<data_pid>.*)\/vid=(?<data_vid>.*)\/(?<data_bcid>.*).js.*#i';
|
| 23 |
+
|
| 24 |
+
/**
|
| 25 |
+
* AMP Tag.
|
| 26 |
+
*
|
| 27 |
+
* @since 1.0
|
| 28 |
+
* @var string AMP Tag.
|
| 29 |
+
*/
|
| 30 |
+
private static $amp_tag = 'amp-o2-player';
|
| 31 |
+
|
| 32 |
+
/**
|
| 33 |
+
* Amp O2 Player class.
|
| 34 |
+
*
|
| 35 |
+
* @since 1.0
|
| 36 |
+
* @var string CSS class to identify O2 Player <div> to replace with AMP version.
|
| 37 |
+
*/
|
| 38 |
+
private static $xpath_selector = '//div[ contains( @class, \'vdb_player\' ) ]/script';
|
| 39 |
+
|
| 40 |
+
/**
|
| 41 |
+
* Height to set for O2 Player elements.
|
| 42 |
+
*
|
| 43 |
+
* @since 1.0
|
| 44 |
+
* @var string
|
| 45 |
+
*/
|
| 46 |
+
private static $height = '270';
|
| 47 |
+
|
| 48 |
+
/**
|
| 49 |
+
* Width to set for O2 Player elements.
|
| 50 |
+
*
|
| 51 |
+
* @since 1.0
|
| 52 |
+
* @var string
|
| 53 |
+
*/
|
| 54 |
+
private static $width = '480';
|
| 55 |
+
|
| 56 |
+
/**
|
| 57 |
+
* Sanitize the O2 Player elements from the HTML contained in this instance's DOMDocument.
|
| 58 |
+
*
|
| 59 |
+
* @since 1.0
|
| 60 |
+
*/
|
| 61 |
+
public function sanitize() {
|
| 62 |
+
/**
|
| 63 |
+
* XPath.
|
| 64 |
+
*
|
| 65 |
+
* @var DOMXPath $xpath
|
| 66 |
+
*/
|
| 67 |
+
$xpath = new DOMXPath( $this->dom );
|
| 68 |
+
|
| 69 |
+
/**
|
| 70 |
+
* Node list.
|
| 71 |
+
*
|
| 72 |
+
* @var DOMNodeList $nodes
|
| 73 |
+
*/
|
| 74 |
+
$nodes = $xpath->query( self::$xpath_selector );
|
| 75 |
+
$num_nodes = $nodes->length;
|
| 76 |
+
|
| 77 |
+
if ( 0 === $num_nodes ) {
|
| 78 |
+
return;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
for ( $i = $num_nodes - 1; $i >= 0; $i-- ) {
|
| 82 |
+
$node = $nodes->item( $i );
|
| 83 |
+
|
| 84 |
+
$this->create_amp_o2_player( $this->dom, $node );
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
/**
|
| 90 |
+
* Replaces node with amp-o2-player
|
| 91 |
+
*
|
| 92 |
+
* @since 1.0
|
| 93 |
+
* @param DOMDocument $dom The HTML Document.
|
| 94 |
+
* @param DOMElement $node The DOMNode to adjust and replace.
|
| 95 |
+
*/
|
| 96 |
+
private function create_amp_o2_player( $dom, $node ) {
|
| 97 |
+
$o2_attributes = $this->get_o2_player_attributes( $node->getAttribute( 'src' ) );
|
| 98 |
+
|
| 99 |
+
if ( ! empty( $o2_attributes ) ) {
|
| 100 |
+
$component_attributes = array_merge(
|
| 101 |
+
$o2_attributes, array(
|
| 102 |
+
'data-macros' => 'm.playback=click',
|
| 103 |
+
'layout' => 'responsive',
|
| 104 |
+
'width' => self::$width,
|
| 105 |
+
'height' => self::$height,
|
| 106 |
+
)
|
| 107 |
+
);
|
| 108 |
+
|
| 109 |
+
$amp_o2_player = AMP_DOM_Utils::create_node( $dom, self::$amp_tag, $component_attributes );
|
| 110 |
+
|
| 111 |
+
$parent_node = $node->parentNode;
|
| 112 |
+
|
| 113 |
+
// replaces the wrapper that contains the script with amp-o2-player element.
|
| 114 |
+
$parent_node->parentNode->replaceChild( $amp_o2_player, $parent_node );
|
| 115 |
+
|
| 116 |
+
$this->did_convert_elements = true;
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
/**
|
| 121 |
+
* Gets O2 Player's required attributes from script src
|
| 122 |
+
*
|
| 123 |
+
* @since 1.0
|
| 124 |
+
* @param string $src Script src.
|
| 125 |
+
*
|
| 126 |
+
* @return array The data-* attributes for o2 player.
|
| 127 |
+
*/
|
| 128 |
+
private function get_o2_player_attributes( $src ) {
|
| 129 |
+
$found = preg_match( self::URL_PATTERN, $src, $matches );
|
| 130 |
+
if ( $found ) {
|
| 131 |
+
return array(
|
| 132 |
+
'data-pid' => $matches['data_pid'],
|
| 133 |
+
'data-vid' => $matches['data_vid'],
|
| 134 |
+
'data-bcid' => $matches['data_bcid'],
|
| 135 |
+
);
|
| 136 |
+
}
|
| 137 |
+
return array();
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
}
|
|
@@ -40,6 +40,17 @@ class AMP_Playbuzz_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 40 |
*/
|
| 41 |
private static $height = '500';
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
/**
|
| 44 |
* Sanitize the Playbuzz elements from the HTML contained in this instance's DOMDocument.
|
| 45 |
*
|
|
@@ -113,16 +124,14 @@ class AMP_Playbuzz_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 113 |
}
|
| 114 |
break;
|
| 115 |
|
| 116 |
-
case 'data-game-info':
|
| 117 |
-
$out['data-item-info'] = $value;
|
| 118 |
-
break;
|
| 119 |
-
|
| 120 |
case 'data-shares':
|
| 121 |
$out['data-share-buttons'] = $value;
|
| 122 |
break;
|
| 123 |
|
|
|
|
| 124 |
case 'data-comments':
|
| 125 |
-
|
|
|
|
| 126 |
break;
|
| 127 |
|
| 128 |
default:
|
| 40 |
*/
|
| 41 |
private static $height = '500';
|
| 42 |
|
| 43 |
+
/**
|
| 44 |
+
* Get mapping of HTML selectors to the AMP component selectors which they may be converted into.
|
| 45 |
+
*
|
| 46 |
+
* @return array Mapping.
|
| 47 |
+
*/
|
| 48 |
+
public function get_selector_conversion_mapping() {
|
| 49 |
+
return array(
|
| 50 |
+
'div.pb_feed' => array( 'amp-playbuzz.pb_feed' ),
|
| 51 |
+
);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
/**
|
| 55 |
* Sanitize the Playbuzz elements from the HTML contained in this instance's DOMDocument.
|
| 56 |
*
|
| 124 |
}
|
| 125 |
break;
|
| 126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
case 'data-shares':
|
| 128 |
$out['data-share-buttons'] = $value;
|
| 129 |
break;
|
| 130 |
|
| 131 |
+
case 'data-game-info':
|
| 132 |
case 'data-comments':
|
| 133 |
+
case 'class':
|
| 134 |
+
$out[ $name ] = $value;
|
| 135 |
break;
|
| 136 |
|
| 137 |
default:
|
|
@@ -40,7 +40,7 @@ abstract class AMP_Rule_Spec {
|
|
| 40 |
*/
|
| 41 |
const ALLOW_EMPTY = 'allow_empty';
|
| 42 |
const ALLOW_RELATIVE = 'allow_relative';
|
| 43 |
-
const ALLOWED_PROTOCOL = '
|
| 44 |
const ALTERNATIVE_NAMES = 'alternative_names';
|
| 45 |
const BLACKLISTED_VALUE_REGEX = 'blacklisted_value_regex';
|
| 46 |
const DISALLOWED_DOMAIN = 'disallowed_domain';
|
|
@@ -53,36 +53,21 @@ abstract class AMP_Rule_Spec {
|
|
| 53 |
const VALUE_URL = 'value_url';
|
| 54 |
|
| 55 |
/**
|
| 56 |
-
*
|
| 57 |
-
* removed if it is invalid. This is mainly because any children will be
|
| 58 |
-
* non-functional without this parent.
|
| 59 |
-
*
|
| 60 |
-
* If a tag is not listed here, it will be replaced by its children if it
|
| 61 |
-
* is invalid.
|
| 62 |
-
*
|
| 63 |
-
* @todo There are other nodes that should probably be listed here as well.
|
| 64 |
-
*
|
| 65 |
-
* @var array
|
| 66 |
-
*/
|
| 67 |
-
public static $node_types_to_remove_if_invalid = array(
|
| 68 |
-
'form',
|
| 69 |
-
'input',
|
| 70 |
-
'link',
|
| 71 |
-
'meta',
|
| 72 |
-
'style',
|
| 73 |
-
// Include 'script' here?
|
| 74 |
-
);
|
| 75 |
-
|
| 76 |
-
/**
|
| 77 |
-
* It is mentioned in the documentation in several places that data-*
|
| 78 |
-
* is generally allowed, but there is no specific rule for it in the
|
| 79 |
-
* protoascii file, so we include it here.
|
| 80 |
*
|
|
|
|
| 81 |
* @var array
|
| 82 |
*/
|
| 83 |
-
public static $
|
| 84 |
-
'
|
| 85 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
);
|
| 87 |
|
| 88 |
/**
|
| 40 |
*/
|
| 41 |
const ALLOW_EMPTY = 'allow_empty';
|
| 42 |
const ALLOW_RELATIVE = 'allow_relative';
|
| 43 |
+
const ALLOWED_PROTOCOL = 'protocol';
|
| 44 |
const ALTERNATIVE_NAMES = 'alternative_names';
|
| 45 |
const BLACKLISTED_VALUE_REGEX = 'blacklisted_value_regex';
|
| 46 |
const DISALLOWED_DOMAIN = 'disallowed_domain';
|
| 53 |
const VALUE_URL = 'value_url';
|
| 54 |
|
| 55 |
/**
|
| 56 |
+
* Supported layout values.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
*
|
| 58 |
+
* @since 1.0
|
| 59 |
* @var array
|
| 60 |
*/
|
| 61 |
+
public static $layout_enum = array(
|
| 62 |
+
1 => 'nodisplay',
|
| 63 |
+
2 => 'fixed',
|
| 64 |
+
3 => 'fixed-height',
|
| 65 |
+
4 => 'responsive',
|
| 66 |
+
5 => 'container',
|
| 67 |
+
6 => 'fill',
|
| 68 |
+
7 => 'flex-item',
|
| 69 |
+
8 => 'fluid',
|
| 70 |
+
9 => 'intrinsic',
|
| 71 |
);
|
| 72 |
|
| 73 |
/**
|
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Class AMP_Script_Sanitizer
|
| 4 |
+
*
|
| 5 |
+
* @since 1.0
|
| 6 |
+
* @package AMP
|
| 7 |
+
*/
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* Class AMP_Script_Sanitizer
|
| 11 |
+
*
|
| 12 |
+
* @since 1.0
|
| 13 |
+
*/
|
| 14 |
+
class AMP_Script_Sanitizer extends AMP_Base_Sanitizer {
|
| 15 |
+
|
| 16 |
+
/**
|
| 17 |
+
* Sanitize noscript elements.
|
| 18 |
+
*
|
| 19 |
+
* Eventually this should also handle script elements, if there is a known AMP equivalent.
|
| 20 |
+
* If nothing is done with script elements, the whitelist sanitizer will deal with them ultimately.
|
| 21 |
+
*
|
| 22 |
+
* @todo Eventually this try to automatically convert script tags to AMP when they are recognized. See <https://github.com/ampproject/amp-wp/issues/1032>.
|
| 23 |
+
* @todo When a script has an adjacent noscript, consider removing the script here to prevent validation error later. See <https://github.com/ampproject/amp-wp/issues/1213>.
|
| 24 |
+
*
|
| 25 |
+
* @since 1.0
|
| 26 |
+
*/
|
| 27 |
+
public function sanitize() {
|
| 28 |
+
$noscripts = $this->dom->getElementsByTagName( 'noscript' );
|
| 29 |
+
|
| 30 |
+
for ( $i = $noscripts->length - 1; $i >= 0; $i-- ) {
|
| 31 |
+
$noscript = $noscripts->item( $i );
|
| 32 |
+
|
| 33 |
+
// Skip AMP boilerplate.
|
| 34 |
+
if ( $noscript->firstChild instanceof DOMElement && $noscript->firstChild->hasAttribute( 'amp-boilerplate' ) ) {
|
| 35 |
+
continue;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
$fragment = $this->dom->createDocumentFragment();
|
| 39 |
+
$fragment->appendChild( $this->dom->createComment( 'noscript' ) );
|
| 40 |
+
while ( $noscript->firstChild ) {
|
| 41 |
+
$fragment->appendChild( $noscript->firstChild );
|
| 42 |
+
}
|
| 43 |
+
$fragment->appendChild( $this->dom->createComment( '/noscript' ) );
|
| 44 |
+
$noscript->parentNode->replaceChild( $fragment, $noscript );
|
| 45 |
+
|
| 46 |
+
$this->did_convert_elements = true;
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
}
|
|
@@ -5,6 +5,19 @@
|
|
| 5 |
* @package AMP
|
| 6 |
*/
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
/**
|
| 9 |
* Class AMP_Style_Sanitizer
|
| 10 |
*
|
|
@@ -13,49 +26,93 @@
|
|
| 13 |
class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
| 14 |
|
| 15 |
/**
|
| 16 |
-
*
|
| 17 |
*
|
| 18 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
*
|
| 20 |
-
* @
|
| 21 |
-
* @var array[]
|
| 22 |
*/
|
| 23 |
-
|
| 24 |
|
| 25 |
/**
|
| 26 |
-
*
|
| 27 |
*
|
| 28 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
*
|
| 30 |
-
* @
|
| 31 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
*/
|
| 33 |
-
|
| 34 |
|
| 35 |
/**
|
| 36 |
-
*
|
| 37 |
*
|
| 38 |
-
* @
|
| 39 |
-
* @var int
|
| 40 |
*/
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
/**
|
| 44 |
-
*
|
|
|
|
|
|
|
| 45 |
*
|
| 46 |
* @since 0.7
|
| 47 |
-
* @var
|
| 48 |
*/
|
| 49 |
-
private $
|
| 50 |
|
| 51 |
/**
|
| 52 |
-
*
|
| 53 |
*
|
| 54 |
-
*
|
| 55 |
*
|
| 56 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
*/
|
| 58 |
-
private $
|
| 59 |
|
| 60 |
/**
|
| 61 |
* The style[amp-custom] element.
|
|
@@ -64,6 +121,14 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 64 |
*/
|
| 65 |
private $amp_custom_style_element;
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
/**
|
| 68 |
* Regex for allowed font stylesheet URL.
|
| 69 |
*
|
|
@@ -87,6 +152,104 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 87 |
*/
|
| 88 |
private $content_url;
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
/**
|
| 91 |
* AMP_Base_Sanitizer constructor.
|
| 92 |
*
|
|
@@ -98,19 +261,14 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 98 |
public function __construct( DOMDocument $dom, array $args = array() ) {
|
| 99 |
parent::__construct( $dom, $args );
|
| 100 |
|
| 101 |
-
$spec_name = 'style[amp-keyframes]';
|
| 102 |
foreach ( AMP_Allowed_Tags_Generated::get_allowed_tag( 'style' ) as $spec_rule ) {
|
| 103 |
-
if ( isset( $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] )
|
| 104 |
-
|
| 105 |
-
break;
|
| 106 |
}
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
if ( isset( $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] ) && $spec_name === $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] ) {
|
| 112 |
-
$this->custom_max_size = $spec_rule[ AMP_Rule_Spec::CDATA ]['max_bytes'];
|
| 113 |
-
break;
|
| 114 |
}
|
| 115 |
}
|
| 116 |
|
|
@@ -128,20 +286,19 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 128 |
}
|
| 129 |
$this->base_url = $guessurl;
|
| 130 |
$this->content_url = WP_CONTENT_URL;
|
|
|
|
| 131 |
}
|
| 132 |
|
| 133 |
/**
|
| 134 |
* Get list of CSS styles in HTML content of DOMDocument ($this->dom).
|
| 135 |
*
|
| 136 |
* @since 0.4
|
|
|
|
| 137 |
*
|
| 138 |
* @return array[] Mapping CSS selectors to array of properties, or mapping of keys starting with 'stylesheet:' with value being the stylesheet.
|
| 139 |
*/
|
| 140 |
public function get_styles() {
|
| 141 |
-
|
| 142 |
-
return array();
|
| 143 |
-
}
|
| 144 |
-
return $this->styles;
|
| 145 |
}
|
| 146 |
|
| 147 |
/**
|
|
@@ -151,7 +308,80 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 151 |
* @returns array Values are the CSS stylesheets. Keys are MD5 hashes of the stylesheets.
|
| 152 |
*/
|
| 153 |
public function get_stylesheets() {
|
| 154 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
}
|
| 156 |
|
| 157 |
/**
|
|
@@ -167,11 +397,19 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 167 |
return;
|
| 168 |
}
|
| 169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
/*
|
| 171 |
* Note that xpath is used to query the DOM so that the link and style elements will be
|
| 172 |
* in document order. DOMNode::compareDocumentPosition() is not yet implemented.
|
| 173 |
*/
|
| 174 |
-
$xpath =
|
| 175 |
|
| 176 |
$lower_case = 'translate( %s, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" )'; // In XPath 2.0 this is lower-case().
|
| 177 |
$predicates = array(
|
|
@@ -183,6 +421,28 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 183 |
$elements[] = $element;
|
| 184 |
}
|
| 185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
/**
|
| 187 |
* Element.
|
| 188 |
*
|
|
@@ -204,83 +464,113 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 204 |
foreach ( $elements as $element ) {
|
| 205 |
$this->collect_inline_styles( $element );
|
| 206 |
}
|
| 207 |
-
$this->did_convert_elements = true;
|
| 208 |
|
| 209 |
-
|
| 210 |
-
if ( ! empty( $this->args['use_document_element'] ) ) {
|
| 211 |
-
if ( ! $this->amp_custom_style_element ) {
|
| 212 |
-
$this->amp_custom_style_element = $this->dom->createElement( 'style' );
|
| 213 |
-
$this->amp_custom_style_element->setAttribute( 'amp-custom', '' );
|
| 214 |
-
$head = $this->dom->getElementsByTagName( 'head' )->item( 0 );
|
| 215 |
-
if ( ! $head ) {
|
| 216 |
-
$head = $this->dom->createElement( 'head' );
|
| 217 |
-
$this->dom->documentElement->insertBefore( $head, $this->dom->documentElement->firstChild );
|
| 218 |
-
}
|
| 219 |
-
$head->appendChild( $this->amp_custom_style_element );
|
| 220 |
-
}
|
| 221 |
|
| 222 |
-
|
| 223 |
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
* !important: Updating the contents of this style element by setting textContent is not
|
| 227 |
-
* reliable across PHP/libxml versions, so this is why the children are removed and the
|
| 228 |
-
* text node is then explicitly added containing the CSS.
|
| 229 |
-
*/
|
| 230 |
-
while ( $this->amp_custom_style_element->firstChild ) {
|
| 231 |
-
$this->amp_custom_style_element->removeChild( $this->amp_custom_style_element->firstChild );
|
| 232 |
-
}
|
| 233 |
-
$this->amp_custom_style_element->appendChild( $this->dom->createTextNode( $css ) );
|
| 234 |
}
|
| 235 |
}
|
| 236 |
|
| 237 |
/**
|
| 238 |
-
*
|
| 239 |
*
|
| 240 |
* @since 0.7
|
| 241 |
* @see WP_Styles::_css_href()
|
| 242 |
*
|
| 243 |
-
* @param string
|
|
|
|
| 244 |
* @return string|WP_Error Style's absolute validated filesystem path, or WP_Error when error.
|
| 245 |
*/
|
| 246 |
-
public function
|
| 247 |
$needs_base_url = (
|
| 248 |
-
! is_bool( $
|
| 249 |
&&
|
| 250 |
-
! preg_match( '|^(https?:)?//|', $
|
| 251 |
&&
|
| 252 |
-
! ( $this->content_url && 0 === strpos( $
|
| 253 |
);
|
| 254 |
if ( $needs_base_url ) {
|
| 255 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
}
|
| 257 |
|
| 258 |
-
|
| 259 |
-
|
|
|
|
|
|
|
| 260 |
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
}
|
| 265 |
|
| 266 |
-
$
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
$css_path = null;
|
| 270 |
-
if ( 0 === strpos( $src, $content_url ) ) {
|
| 271 |
-
$css_path = WP_CONTENT_DIR . substr( $src, strlen( $content_url ) - 1 );
|
| 272 |
-
} elseif ( 0 === strpos( $src, $includes_url ) ) {
|
| 273 |
-
$css_path = ABSPATH . WPINC . substr( $src, strlen( $includes_url ) - 1 );
|
| 274 |
-
} elseif ( 0 === strpos( $src, $admin_url ) ) {
|
| 275 |
-
$css_path = ABSPATH . 'wp-admin' . substr( $src, strlen( $admin_url ) - 1 );
|
| 276 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 281 |
}
|
| 282 |
|
| 283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
}
|
| 285 |
|
| 286 |
/**
|
|
@@ -289,30 +579,33 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 289 |
* @param DOMElement $element Style element.
|
| 290 |
*/
|
| 291 |
private function process_style_element( DOMElement $element ) {
|
| 292 |
-
|
| 293 |
-
$validity = $this->validate_amp_keyframe( $element );
|
| 294 |
-
if ( is_wp_error( $validity ) ) {
|
| 295 |
-
$this->remove_invalid_child( $element, array(
|
| 296 |
-
'message' => $validity->get_error_message(),
|
| 297 |
-
) );
|
| 298 |
-
}
|
| 299 |
-
return;
|
| 300 |
-
}
|
| 301 |
|
| 302 |
-
|
| 303 |
-
$
|
|
|
|
|
|
|
| 304 |
|
| 305 |
-
//
|
| 306 |
-
$
|
| 307 |
-
if ( $
|
| 308 |
-
$
|
| 309 |
-
'message' => __( 'Too much CSS enqueued.', 'amp' ),
|
| 310 |
-
) );
|
| 311 |
-
return;
|
| 312 |
}
|
| 313 |
|
| 314 |
-
$this->
|
| 315 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
|
| 317 |
if ( $element->hasAttribute( 'amp-custom' ) ) {
|
| 318 |
if ( ! $this->amp_custom_style_element ) {
|
|
@@ -325,6 +618,8 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 325 |
// Remove from DOM since we'll be adding it to amp-custom.
|
| 326 |
$element->parentNode->removeChild( $element );
|
| 327 |
}
|
|
|
|
|
|
|
| 328 |
}
|
| 329 |
|
| 330 |
/**
|
|
@@ -335,244 +630,1596 @@ class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
|
| 335 |
private function process_link_element( DOMElement $element ) {
|
| 336 |
$href = $element->getAttribute( 'href' );
|
| 337 |
|
| 338 |
-
// Allow font URLs.
|
| 339 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
return;
|
| 341 |
}
|
| 342 |
|
| 343 |
-
$css_file_path = $this->
|
| 344 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 345 |
$this->remove_invalid_child( $element, array(
|
|
|
|
| 346 |
'message' => $css_file_path->get_error_message(),
|
|
|
|
| 347 |
) );
|
| 348 |
return;
|
|
|
|
|
|
|
| 349 |
}
|
| 350 |
|
| 351 |
-
|
| 352 |
-
$rules = "\n/* $href */\n";
|
| 353 |
-
$rules .= file_get_contents( $css_file_path ); // phpcs:ignore -- It's a local filesystem path not a remote request.
|
| 354 |
-
|
| 355 |
-
$rules = $this->remove_illegal_css( $rules, $element );
|
| 356 |
-
|
| 357 |
-
$media = $element->getAttribute( 'media' );
|
| 358 |
-
if ( $media && 'all' !== $media ) {
|
| 359 |
-
$rules = sprintf( '@media %s { %s }', $media, $rules );
|
| 360 |
-
}
|
| 361 |
-
|
| 362 |
-
// Remove if surpasses max size.
|
| 363 |
-
$length = strlen( $rules );
|
| 364 |
-
if ( $this->current_custom_size + $length > $this->custom_max_size ) {
|
| 365 |
$this->remove_invalid_child( $element, array(
|
| 366 |
-
'
|
|
|
|
| 367 |
) );
|
| 368 |
return;
|
| 369 |
}
|
| 370 |
|
| 371 |
-
|
| 372 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
|
| 374 |
// Remove now that styles have been processed.
|
| 375 |
$element->parentNode->removeChild( $element );
|
| 376 |
-
}
|
| 377 |
|
| 378 |
-
|
| 379 |
-
* Remove illegal CSS from the stylesheet.
|
| 380 |
-
*
|
| 381 |
-
* @since 0.7
|
| 382 |
-
*
|
| 383 |
-
* @todo This needs proper CSS parser and to take an alternative approach to removing !important by extracting
|
| 384 |
-
* the rule into a separate style rule with a very specific selector.
|
| 385 |
-
* @param string $stylesheet Stylesheet.
|
| 386 |
-
* @param DOMElement $element Element where the stylesheet came from.
|
| 387 |
-
* @return string Scrubbed stylesheet.
|
| 388 |
-
*/
|
| 389 |
-
private function remove_illegal_css( $stylesheet, $element ) {
|
| 390 |
-
$stylesheet = preg_replace( '/\s*!important/', '', $stylesheet, -1, $important_count ); // Note this has to also replace inside comments to be valid.
|
| 391 |
-
if ( $important_count > 0 && ! empty( $this->args['validation_error_callback'] ) ) {
|
| 392 |
-
call_user_func( $this->args['validation_error_callback'], array(
|
| 393 |
-
'code' => 'css_important_removed',
|
| 394 |
-
'node' => $element,
|
| 395 |
-
) );
|
| 396 |
-
}
|
| 397 |
-
$stylesheet = preg_replace( '/overflow(-[xy])?\s*:\s*(auto|scroll)\s*;?\s*/', '', $stylesheet, -1, $overlow_count );
|
| 398 |
-
if ( $overlow_count > 0 && ! empty( $this->args['validation_error_callback'] ) ) {
|
| 399 |
-
call_user_func( $this->args['validation_error_callback'], array(
|
| 400 |
-
'code' => 'css_overflow_property_removed',
|
| 401 |
-
'node' => $element,
|
| 402 |
-
) );
|
| 403 |
-
}
|
| 404 |
-
return $stylesheet;
|
| 405 |
}
|
| 406 |
|
| 407 |
/**
|
| 408 |
-
*
|
| 409 |
-
*
|
| 410 |
-
* @since 0.7
|
| 411 |
-
* @link https://github.com/ampproject/amphtml/blob/b685a0780a7f59313666225478b2b79b463bcd0b/validator/validator-main.protoascii#L1002-L1043
|
| 412 |
*
|
| 413 |
-
* @param
|
| 414 |
-
* @return
|
| 415 |
*/
|
| 416 |
-
private function
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
if ( $next_sibling instanceof DOMElement ) {
|
| 429 |
-
return new WP_Error( 'mandatory_last_child', __( 'amp-keyframes is not last element in body.', 'amp' ) );
|
| 430 |
}
|
| 431 |
-
$
|
| 432 |
}
|
| 433 |
-
|
| 434 |
-
// @todo Also add validation of the CSS spec itself.
|
| 435 |
-
return true;
|
| 436 |
}
|
| 437 |
|
| 438 |
/**
|
| 439 |
-
*
|
| 440 |
*
|
| 441 |
-
*
|
|
|
|
| 442 |
*
|
| 443 |
-
* @
|
| 444 |
*
|
| 445 |
-
* @
|
| 446 |
-
* @
|
|
|
|
| 447 |
*
|
| 448 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
*
|
| 450 |
-
*
|
|
|
|
|
|
|
|
|
|
| 451 |
*/
|
| 452 |
-
private function
|
| 453 |
-
$
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
$
|
| 458 |
-
|
| 459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 460 |
|
| 461 |
-
|
| 462 |
-
$class_name = $this->generate_class_name( $properties );
|
| 463 |
-
$new_class = trim( $class . ' ' . $class_name );
|
| 464 |
|
| 465 |
-
|
| 466 |
-
$
|
|
|
|
|
|
|
|
|
|
| 467 |
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
}
|
|
|
|
| 474 |
|
| 475 |
-
|
| 476 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 477 |
}
|
| 478 |
-
|
|
|
|
| 479 |
}
|
| 480 |
|
| 481 |
/**
|
| 482 |
-
*
|
| 483 |
*
|
| 484 |
-
* @
|
|
|
|
|
|
|
|
|
|
| 485 |
*
|
| 486 |
-
*
|
| 487 |
-
*
|
|
|
|
| 488 |
*/
|
| 489 |
-
private function
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
$
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
$styles = preg_split( '/\s*;\s*(?![^(]*\))/', trim( $css, '; ' ) );
|
| 499 |
-
$styles = array_filter( $styles );
|
| 500 |
|
| 501 |
-
|
| 502 |
-
sort( $styles );
|
| 503 |
|
| 504 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 505 |
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 511 |
}
|
| 512 |
|
| 513 |
-
|
| 514 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 515 |
continue;
|
| 516 |
}
|
| 517 |
|
| 518 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
}
|
| 520 |
|
| 521 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 522 |
}
|
| 523 |
|
| 524 |
/**
|
| 525 |
-
*
|
| 526 |
*
|
| 527 |
-
*
|
| 528 |
-
*
|
| 529 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
* @package AMP
|
| 6 |
*/
|
| 7 |
|
| 8 |
+
use \Sabberworm\CSS\RuleSet\DeclarationBlock;
|
| 9 |
+
use \Sabberworm\CSS\CSSList\CSSList;
|
| 10 |
+
use \Sabberworm\CSS\Property\Selector;
|
| 11 |
+
use \Sabberworm\CSS\RuleSet\RuleSet;
|
| 12 |
+
use \Sabberworm\CSS\Property\AtRule;
|
| 13 |
+
use \Sabberworm\CSS\CSSList\KeyFrame;
|
| 14 |
+
use \Sabberworm\CSS\RuleSet\AtRuleSet;
|
| 15 |
+
use \Sabberworm\CSS\Property\Import;
|
| 16 |
+
use \Sabberworm\CSS\CSSList\AtRuleBlockList;
|
| 17 |
+
use \Sabberworm\CSS\Value\RuleValueList;
|
| 18 |
+
use \Sabberworm\CSS\Value\URL;
|
| 19 |
+
use \Sabberworm\CSS\CSSList\Document;
|
| 20 |
+
|
| 21 |
/**
|
| 22 |
* Class AMP_Style_Sanitizer
|
| 23 |
*
|
| 26 |
class AMP_Style_Sanitizer extends AMP_Base_Sanitizer {
|
| 27 |
|
| 28 |
/**
|
| 29 |
+
* Error code for tree shaking.
|
| 30 |
*
|
| 31 |
+
* @var string
|
| 32 |
+
*/
|
| 33 |
+
const TREE_SHAKING_ERROR_CODE = 'removed_unused_css_rules';
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* Error code for illegal at-rule.
|
| 37 |
*
|
| 38 |
+
* @var string
|
|
|
|
| 39 |
*/
|
| 40 |
+
const ILLEGAL_AT_RULE_ERROR_CODE = 'illegal_css_at_rule';
|
| 41 |
|
| 42 |
/**
|
| 43 |
+
* Inline style selector's specificity multiplier, i.e. used to generate the number of ':not(#_)' placeholders.
|
| 44 |
*
|
| 45 |
+
* @var int
|
| 46 |
+
*/
|
| 47 |
+
const INLINE_SPECIFICITY_MULTIPLIER = 5; // @todo The correctness of using "5" should be validated.
|
| 48 |
+
|
| 49 |
+
/**
|
| 50 |
+
* Array of flags used to control sanitization.
|
| 51 |
*
|
| 52 |
+
* @var array {
|
| 53 |
+
* @type string $remove_unused_rules Enum 'never', 'sometimes' (default), 'always'. If total CSS is greater than max_bytes, whether to strip selectors (and then empty rules) when they are not found to be used in doc. A validation error will be emitted when stripping happens since it is not completely safe in the case of dynamic content.
|
| 54 |
+
* @type string[] $dynamic_element_selectors Selectors for elements (or their ancestors) which contain dynamic content; selectors containing these will not be filtered.
|
| 55 |
+
* @type bool $use_document_element Whether the root of the document should be used rather than the body.
|
| 56 |
+
* @type bool $require_https_src Require HTTPS URLs.
|
| 57 |
+
* @type bool $allow_dirty_styles Allow dirty styles. This short-circuits the sanitize logic; it is used primarily in Customizer preview.
|
| 58 |
+
* @type callable $validation_error_callback Function to call when a validation error is encountered.
|
| 59 |
+
* @type bool $should_locate_sources Whether to locate the sources when reporting validation errors.
|
| 60 |
+
* @type string $parsed_cache_variant Additional value by which to vary parsed cache.
|
| 61 |
+
* @type bool $accept_tree_shaking Whether to accept tree-shaking by default and bypass a validation error.
|
| 62 |
+
* }
|
| 63 |
*/
|
| 64 |
+
protected $args;
|
| 65 |
|
| 66 |
/**
|
| 67 |
+
* Default args.
|
| 68 |
*
|
| 69 |
+
* @var array
|
|
|
|
| 70 |
*/
|
| 71 |
+
protected $DEFAULT_ARGS = array(
|
| 72 |
+
'remove_unused_rules' => 'sometimes',
|
| 73 |
+
'dynamic_element_selectors' => array(
|
| 74 |
+
'amp-list',
|
| 75 |
+
'amp-live-list',
|
| 76 |
+
'[submit-error]',
|
| 77 |
+
'[submit-success]',
|
| 78 |
+
),
|
| 79 |
+
'should_locate_sources' => false,
|
| 80 |
+
'parsed_cache_variant' => null,
|
| 81 |
+
'accept_tree_shaking' => false,
|
| 82 |
+
);
|
| 83 |
|
| 84 |
/**
|
| 85 |
+
* Stylesheets.
|
| 86 |
+
*
|
| 87 |
+
* Values are the CSS stylesheets. Keys are MD5 hashes of the stylesheets,
|
| 88 |
*
|
| 89 |
* @since 0.7
|
| 90 |
+
* @var string[]
|
| 91 |
*/
|
| 92 |
+
private $stylesheets = array();
|
| 93 |
|
| 94 |
/**
|
| 95 |
+
* List of stylesheet parts prior to selector/rule removal (tree shaking).
|
| 96 |
*
|
| 97 |
+
* Keys are MD5 hashes of stylesheets.
|
| 98 |
*
|
| 99 |
+
* @since 1.0
|
| 100 |
+
* @var array[] {
|
| 101 |
+
* @type array $stylesheet Array of stylesheet chunked, with declaration blocks being represented as arrays.
|
| 102 |
+
* @type DOMElement|DOMAttr $node Origin for styles.
|
| 103 |
+
* @type array $sources Sources for the node.
|
| 104 |
+
* @type bool $keyframes Whether an amp-keyframes.
|
| 105 |
+
* }
|
| 106 |
+
*/
|
| 107 |
+
private $pending_stylesheets = array();
|
| 108 |
+
|
| 109 |
+
/**
|
| 110 |
+
* Spec for style[amp-custom] cdata.
|
| 111 |
+
*
|
| 112 |
+
* @since 1.0
|
| 113 |
+
* @var array
|
| 114 |
*/
|
| 115 |
+
private $style_custom_cdata_spec;
|
| 116 |
|
| 117 |
/**
|
| 118 |
* The style[amp-custom] element.
|
| 121 |
*/
|
| 122 |
private $amp_custom_style_element;
|
| 123 |
|
| 124 |
+
/**
|
| 125 |
+
* Spec for style[amp-keyframes] cdata.
|
| 126 |
+
*
|
| 127 |
+
* @since 1.0
|
| 128 |
+
* @var array
|
| 129 |
+
*/
|
| 130 |
+
private $style_keyframes_cdata_spec;
|
| 131 |
+
|
| 132 |
/**
|
| 133 |
* Regex for allowed font stylesheet URL.
|
| 134 |
*
|
| 152 |
*/
|
| 153 |
private $content_url;
|
| 154 |
|
| 155 |
+
/**
|
| 156 |
+
* Class names used in document.
|
| 157 |
+
*
|
| 158 |
+
* @since 1.0
|
| 159 |
+
* @var array
|
| 160 |
+
*/
|
| 161 |
+
private $used_class_names = array();
|
| 162 |
+
|
| 163 |
+
/**
|
| 164 |
+
* Tag names used in document.
|
| 165 |
+
*
|
| 166 |
+
* @since 1.0
|
| 167 |
+
* @var array
|
| 168 |
+
*/
|
| 169 |
+
private $used_tag_names = array();
|
| 170 |
+
|
| 171 |
+
/**
|
| 172 |
+
* XPath.
|
| 173 |
+
*
|
| 174 |
+
* @since 1.0
|
| 175 |
+
* @var DOMXPath
|
| 176 |
+
*/
|
| 177 |
+
private $xpath;
|
| 178 |
+
|
| 179 |
+
/**
|
| 180 |
+
* Amount of time that was spent parsing CSS.
|
| 181 |
+
*
|
| 182 |
+
* @since 1.0
|
| 183 |
+
* @var float
|
| 184 |
+
*/
|
| 185 |
+
private $parse_css_duration = 0.0;
|
| 186 |
+
|
| 187 |
+
/**
|
| 188 |
+
* THe HEAD element.
|
| 189 |
+
*
|
| 190 |
+
* @var DOMElement
|
| 191 |
+
*/
|
| 192 |
+
private $head;
|
| 193 |
+
|
| 194 |
+
/**
|
| 195 |
+
* Current node being processed.
|
| 196 |
+
*
|
| 197 |
+
* @var DOMElement|DOMAttr
|
| 198 |
+
*/
|
| 199 |
+
private $current_node;
|
| 200 |
+
|
| 201 |
+
/**
|
| 202 |
+
* Current sources for a given node.
|
| 203 |
+
*
|
| 204 |
+
* @var array
|
| 205 |
+
*/
|
| 206 |
+
private $current_sources;
|
| 207 |
+
|
| 208 |
+
/**
|
| 209 |
+
* Log of the stylesheet URLs that have been imported to guard against infinite loops.
|
| 210 |
+
*
|
| 211 |
+
* @var array
|
| 212 |
+
*/
|
| 213 |
+
private $processed_imported_stylesheet_urls = array();
|
| 214 |
+
|
| 215 |
+
/**
|
| 216 |
+
* List of font stylesheets that were @import'ed which should have been <link>'ed to instead.
|
| 217 |
+
*
|
| 218 |
+
* These font URLs will be cached with the parsed CSS and then converted into stylesheet links.
|
| 219 |
+
*
|
| 220 |
+
* @var array
|
| 221 |
+
*/
|
| 222 |
+
private $imported_font_urls = array();
|
| 223 |
+
|
| 224 |
+
/**
|
| 225 |
+
* Mapping of HTML element selectors to AMP selector elements.
|
| 226 |
+
*
|
| 227 |
+
* @var array
|
| 228 |
+
*/
|
| 229 |
+
private $selector_mappings = array();
|
| 230 |
+
|
| 231 |
+
/**
|
| 232 |
+
* Get error codes that can be raised during parsing of CSS.
|
| 233 |
+
*
|
| 234 |
+
* This is used to determine which validation errors should be taken into account
|
| 235 |
+
* when determining which validation errors should vary the parse cache.
|
| 236 |
+
*
|
| 237 |
+
* @return array
|
| 238 |
+
*/
|
| 239 |
+
public static function get_css_parser_validation_error_codes() {
|
| 240 |
+
return array(
|
| 241 |
+
'css_parse_error',
|
| 242 |
+
'excessive_css',
|
| 243 |
+
self::ILLEGAL_AT_RULE_ERROR_CODE,
|
| 244 |
+
'illegal_css_important',
|
| 245 |
+
'illegal_css_property',
|
| 246 |
+
self::TREE_SHAKING_ERROR_CODE,
|
| 247 |
+
'unrecognized_css',
|
| 248 |
+
'disallowed_file_extension',
|
| 249 |
+
'file_path_not_found',
|
| 250 |
+
);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
/**
|
| 254 |
* AMP_Base_Sanitizer constructor.
|
| 255 |
*
|
| 261 |
public function __construct( DOMDocument $dom, array $args = array() ) {
|
| 262 |
parent::__construct( $dom, $args );
|
| 263 |
|
|
|
|
| 264 |
foreach ( AMP_Allowed_Tags_Generated::get_allowed_tag( 'style' ) as $spec_rule ) {
|
| 265 |
+
if ( ! isset( $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] ) ) {
|
| 266 |
+
continue;
|
|
|
|
| 267 |
}
|
| 268 |
+
if ( 'style[amp-keyframes]' === $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] ) {
|
| 269 |
+
$this->style_keyframes_cdata_spec = $spec_rule[ AMP_Rule_Spec::CDATA ];
|
| 270 |
+
} elseif ( 'style amp-custom' === $spec_rule[ AMP_Rule_Spec::TAG_SPEC ]['spec_name'] ) {
|
| 271 |
+
$this->style_custom_cdata_spec = $spec_rule[ AMP_Rule_Spec::CDATA ];
|
|
|
|
|
|
|
|
|
|
| 272 |
}
|
| 273 |
}
|
| 274 |
|
| 286 |
}
|
| 287 |
$this->base_url = $guessurl;
|
| 288 |
$this->content_url = WP_CONTENT_URL;
|
| 289 |
+
$this->xpath = new DOMXPath( $dom );
|
| 290 |
}
|
| 291 |
|
| 292 |
/**
|
| 293 |
* Get list of CSS styles in HTML content of DOMDocument ($this->dom).
|
| 294 |
*
|
| 295 |
* @since 0.4
|
| 296 |
+
* @deprecated As of 1.0, use get_stylesheets().
|
| 297 |
*
|
| 298 |
* @return array[] Mapping CSS selectors to array of properties, or mapping of keys starting with 'stylesheet:' with value being the stylesheet.
|
| 299 |
*/
|
| 300 |
public function get_styles() {
|
| 301 |
+
return array();
|
|
|
|
|
|
|
|
|
|
| 302 |
}
|
| 303 |
|
| 304 |
/**
|
| 308 |
* @returns array Values are the CSS stylesheets. Keys are MD5 hashes of the stylesheets.
|
| 309 |
*/
|
| 310 |
public function get_stylesheets() {
|
| 311 |
+
return $this->stylesheets;
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
/**
|
| 315 |
+
* Get list of all the class names used in the document, including those used in [class] attributes.
|
| 316 |
+
*
|
| 317 |
+
* @since 1.0
|
| 318 |
+
* @return array Used class names.
|
| 319 |
+
*/
|
| 320 |
+
private function get_used_class_names() {
|
| 321 |
+
if ( empty( $this->used_class_names ) ) {
|
| 322 |
+
$classes = ' ';
|
| 323 |
+
foreach ( $this->xpath->query( '//*/@class' ) as $class_attribute ) {
|
| 324 |
+
$classes .= ' ' . $class_attribute->nodeValue;
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
// Find all [class] attributes and capture the contents of any single- or double-quoted strings.
|
| 328 |
+
foreach ( $this->xpath->query( '//*/@' . AMP_DOM_Utils::get_amp_bind_placeholder_prefix() . 'class' ) as $bound_class_attribute ) {
|
| 329 |
+
if ( preg_match_all( '/([\'"])([^\1]*?)\1/', $bound_class_attribute->nodeValue, $matches ) ) {
|
| 330 |
+
$classes .= ' ' . implode( ' ', $matches[2] );
|
| 331 |
+
}
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
$this->used_class_names = array_unique( array_filter( preg_split( '/\s+/', trim( $classes ) ) ) );
|
| 335 |
+
}
|
| 336 |
+
return $this->used_class_names;
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
|
| 340 |
+
/**
|
| 341 |
+
* Get list of all the tag names used in the document.
|
| 342 |
+
*
|
| 343 |
+
* @since 1.0
|
| 344 |
+
* @return array Used tag names.
|
| 345 |
+
*/
|
| 346 |
+
private function get_used_tag_names() {
|
| 347 |
+
if ( empty( $this->used_tag_names ) ) {
|
| 348 |
+
$used_tag_names = array();
|
| 349 |
+
foreach ( $this->dom->getElementsByTagName( '*' ) as $el ) {
|
| 350 |
+
$used_tag_names[ $el->tagName ] = true;
|
| 351 |
+
}
|
| 352 |
+
$this->used_tag_names = array_keys( $used_tag_names );
|
| 353 |
+
}
|
| 354 |
+
return $this->used_tag_names;
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
/**
|
| 358 |
+
* Run logic before any sanitizers are run.
|
| 359 |
+
*
|
| 360 |
+
* After the sanitizers are instantiated but before calling sanitize on each of them, this
|
| 361 |
+
* method is called with list of all the instantiated sanitizers.
|
| 362 |
+
*
|
| 363 |
+
* @param AMP_Base_Sanitizer[] $sanitizers Sanitizers.
|
| 364 |
+
*/
|
| 365 |
+
public function init( $sanitizers ) {
|
| 366 |
+
parent::init( $sanitizers );
|
| 367 |
+
|
| 368 |
+
foreach ( $sanitizers as $sanitizer ) {
|
| 369 |
+
foreach ( $sanitizer->get_selector_conversion_mapping() as $html_selectors => $amp_selectors ) {
|
| 370 |
+
if ( ! isset( $this->selector_mappings[ $html_selectors ] ) ) {
|
| 371 |
+
$this->selector_mappings[ $html_selectors ] = $amp_selectors;
|
| 372 |
+
} else {
|
| 373 |
+
$this->selector_mappings[ $html_selectors ] = array_unique(
|
| 374 |
+
array_merge( $this->selector_mappings[ $html_selectors ], $amp_selectors )
|
| 375 |
+
);
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
// Prevent selectors like `amp-img img` getting deleted since `img` does not occur in the DOM.
|
| 379 |
+
$this->args['dynamic_element_selectors'] = array_merge(
|
| 380 |
+
$this->args['dynamic_element_selectors'],
|
| 381 |
+
$this->selector_mappings[ $html_selectors ]
|
| 382 |
+
);
|
| 383 |
+
}
|
| 384 |
+
}
|
| 385 |
}
|
| 386 |
|
| 387 |
/**
|
| 397 |
return;
|
| 398 |
}
|
| 399 |
|
| 400 |
+
$this->head = $this->dom->getElementsByTagName( 'head' )->item( 0 );
|
| 401 |
+
if ( ! $this->head ) {
|
| 402 |
+
$this->head = $this->dom->createElement( 'head' );
|
| 403 |
+
$this->dom->documentElement->insertBefore( $this->head, $this->dom->documentElement->firstChild );
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
$this->parse_css_duration = 0.0;
|
| 407 |
+
|
| 408 |
/*
|
| 409 |
* Note that xpath is used to query the DOM so that the link and style elements will be
|
| 410 |
* in document order. DOMNode::compareDocumentPosition() is not yet implemented.
|
| 411 |
*/
|
| 412 |
+
$xpath = $this->xpath;
|
| 413 |
|
| 414 |
$lower_case = 'translate( %s, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" )'; // In XPath 2.0 this is lower-case().
|
| 415 |
$predicates = array(
|
| 421 |
$elements[] = $element;
|
| 422 |
}
|
| 423 |
|
| 424 |
+
// If 'width' attribute is present for 'col' tag, convert to proper CSS rule.
|
| 425 |
+
foreach ( $this->dom->getElementsByTagName( 'col' ) as $col ) {
|
| 426 |
+
/**
|
| 427 |
+
* Col element.
|
| 428 |
+
*
|
| 429 |
+
* @var DOMElement $col
|
| 430 |
+
*/
|
| 431 |
+
$width_attr = $col->getAttribute( 'width' );
|
| 432 |
+
if ( ! empty( $width_attr ) && ( false === strpos( $width_attr, '*' ) ) ) {
|
| 433 |
+
$width_style = 'width: ' . $width_attr;
|
| 434 |
+
if ( is_numeric( $width_attr ) ) {
|
| 435 |
+
$width_style .= 'px';
|
| 436 |
+
}
|
| 437 |
+
if ( $col->hasAttribute( 'style' ) ) {
|
| 438 |
+
$col->setAttribute( 'style', $width_style . ';' . $col->getAttribute( 'style' ) );
|
| 439 |
+
} else {
|
| 440 |
+
$col->setAttribute( 'style', $width_style );
|
| 441 |
+
}
|
| 442 |
+
$col->removeAttribute( 'width' );
|
| 443 |
+
}
|
| 444 |
+
}
|
| 445 |
+
|
| 446 |
/**
|
| 447 |
* Element.
|
| 448 |
*
|
| 464 |
foreach ( $elements as $element ) {
|
| 465 |
$this->collect_inline_styles( $element );
|
| 466 |
}
|
|
|
|
| 467 |
|
| 468 |
+
$this->finalize_styles();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 469 |
|
| 470 |
+
$this->did_convert_elements = true;
|
| 471 |
|
| 472 |
+
if ( $this->parse_css_duration > 0.0 ) {
|
| 473 |
+
AMP_HTTP::send_server_timing( 'amp_parse_css', $this->parse_css_duration, 'AMP Parse CSS' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 474 |
}
|
| 475 |
}
|
| 476 |
|
| 477 |
/**
|
| 478 |
+
* Generate a URL's fully-qualified file path.
|
| 479 |
*
|
| 480 |
* @since 0.7
|
| 481 |
* @see WP_Styles::_css_href()
|
| 482 |
*
|
| 483 |
+
* @param string $url The file URL.
|
| 484 |
+
* @param string[] $allowed_extensions Allowed file extensions for local files.
|
| 485 |
* @return string|WP_Error Style's absolute validated filesystem path, or WP_Error when error.
|
| 486 |
*/
|
| 487 |
+
public function get_validated_url_file_path( $url, $allowed_extensions = array() ) {
|
| 488 |
$needs_base_url = (
|
| 489 |
+
! is_bool( $url )
|
| 490 |
&&
|
| 491 |
+
! preg_match( '|^(https?:)?//|', $url )
|
| 492 |
&&
|
| 493 |
+
! ( $this->content_url && 0 === strpos( $url, $this->content_url ) )
|
| 494 |
);
|
| 495 |
if ( $needs_base_url ) {
|
| 496 |
+
$url = $this->base_url . $url;
|
| 497 |
+
}
|
| 498 |
+
|
| 499 |
+
$remove_url_scheme = function( $schemed_url ) {
|
| 500 |
+
return preg_replace( '#^\w+:(?=//)#', '', $schemed_url );
|
| 501 |
+
};
|
| 502 |
+
|
| 503 |
+
// Strip URL scheme, query, and fragment.
|
| 504 |
+
$url = $remove_url_scheme( preg_replace( ':[\?#].*$:', '', $url ) );
|
| 505 |
+
|
| 506 |
+
$includes_url = $remove_url_scheme( includes_url( '/' ) );
|
| 507 |
+
$content_url = $remove_url_scheme( content_url( '/' ) );
|
| 508 |
+
$admin_url = $remove_url_scheme( get_admin_url( null, '/' ) );
|
| 509 |
+
|
| 510 |
+
$allowed_hosts = array(
|
| 511 |
+
wp_parse_url( $includes_url, PHP_URL_HOST ),
|
| 512 |
+
wp_parse_url( $content_url, PHP_URL_HOST ),
|
| 513 |
+
wp_parse_url( $admin_url, PHP_URL_HOST ),
|
| 514 |
+
);
|
| 515 |
+
|
| 516 |
+
$url_host = wp_parse_url( $url, PHP_URL_HOST );
|
| 517 |
+
|
| 518 |
+
// Validate file extensions.
|
| 519 |
+
if ( ! empty( $allowed_extensions ) ) {
|
| 520 |
+
$pattern = sprintf( '/\.(%s)$/i', implode( '|', $allowed_extensions ) );
|
| 521 |
+
if ( ! preg_match( $pattern, $url ) ) {
|
| 522 |
+
/* translators: %s: the file URL. */
|
| 523 |
+
return new WP_Error( 'disallowed_file_extension', sprintf( __( 'File does not have an allowed file extension for filesystem access (%s).', 'amp' ), $url ) );
|
| 524 |
+
}
|
| 525 |
}
|
| 526 |
|
| 527 |
+
if ( ! in_array( $url_host, $allowed_hosts, true ) ) {
|
| 528 |
+
/* translators: %s: the file URL */
|
| 529 |
+
return new WP_Error( 'external_file_url', sprintf( __( 'URL is located on an external domain: %s.', 'amp' ), $url_host ) );
|
| 530 |
+
}
|
| 531 |
|
| 532 |
+
$base_path = null;
|
| 533 |
+
$file_path = null;
|
| 534 |
+
if ( 0 === strpos( $url, $content_url ) ) {
|
| 535 |
+
$base_path = WP_CONTENT_DIR;
|
| 536 |
+
$file_path = substr( $url, strlen( $content_url ) - 1 );
|
| 537 |
+
} elseif ( 0 === strpos( $url, $includes_url ) ) {
|
| 538 |
+
$base_path = ABSPATH . WPINC;
|
| 539 |
+
$file_path = substr( $url, strlen( $includes_url ) - 1 );
|
| 540 |
+
} elseif ( 0 === strpos( $url, $admin_url ) ) {
|
| 541 |
+
$base_path = ABSPATH . 'wp-admin';
|
| 542 |
+
$file_path = substr( $url, strlen( $admin_url ) - 1 );
|
| 543 |
}
|
| 544 |
|
| 545 |
+
if ( ! $file_path || false !== strpos( $file_path, '../' ) || false !== strpos( $file_path, '..\\' ) ) {
|
| 546 |
+
/* translators: %s: the file URL. */
|
| 547 |
+
return new WP_Error( 'file_path_not_allowed', sprintf( __( 'Disallowed URL filesystem path for %s.', 'amp' ), $url ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 548 |
}
|
| 549 |
+
if ( ! file_exists( $base_path . $file_path ) ) {
|
| 550 |
+
/* translators: %s: the file URL. */
|
| 551 |
+
return new WP_Error( 'file_path_not_found', sprintf( __( 'Unable to locate filesystem path for %s.', 'amp' ), $url ) );
|
| 552 |
+
}
|
| 553 |
+
|
| 554 |
+
return $base_path . $file_path;
|
| 555 |
+
}
|
| 556 |
|
| 557 |
+
/**
|
| 558 |
+
* Set the current node (and its sources when required).
|
| 559 |
+
*
|
| 560 |
+
* @since 1.0
|
| 561 |
+
* @param DOMElement|DOMAttr|null $node Current node, or null to reset.
|
| 562 |
+
*/
|
| 563 |
+
private function set_current_node( $node ) {
|
| 564 |
+
if ( $this->current_node === $node ) {
|
| 565 |
+
return;
|
| 566 |
}
|
| 567 |
|
| 568 |
+
$this->current_node = $node;
|
| 569 |
+
if ( empty( $node ) ) {
|
| 570 |
+
$this->current_sources = null;
|
| 571 |
+
} elseif ( ! empty( $this->args['should_locate_sources'] ) ) {
|
| 572 |
+
$this->current_sources = AMP_Validation_Manager::locate_sources( $node );
|
| 573 |
+
}
|
| 574 |
}
|
| 575 |
|
| 576 |
/**
|
| 579 |
* @param DOMElement $element Style element.
|
| 580 |
*/
|
| 581 |
private function process_style_element( DOMElement $element ) {
|
| 582 |
+
$this->set_current_node( $element ); // And sources when needing to be located.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 583 |
|
| 584 |
+
// @todo Any @keyframes rules could be removed from amp-custom and instead added to amp-keyframes.
|
| 585 |
+
$is_keyframes = $element->hasAttribute( 'amp-keyframes' );
|
| 586 |
+
$stylesheet = trim( $element->textContent );
|
| 587 |
+
$cdata_spec = $is_keyframes ? $this->style_keyframes_cdata_spec : $this->style_custom_cdata_spec;
|
| 588 |
|
| 589 |
+
// Honor the style's media attribute.
|
| 590 |
+
$media = $element->getAttribute( 'media' );
|
| 591 |
+
if ( $media && 'all' !== $media ) {
|
| 592 |
+
$stylesheet = sprintf( '@media %s { %s }', $media, $stylesheet );
|
|
|
|
|
|
|
|
|
|
| 593 |
}
|
| 594 |
|
| 595 |
+
$processed = $this->process_stylesheet( $stylesheet, array(
|
| 596 |
+
'allowed_at_rules' => $cdata_spec['css_spec']['allowed_at_rules'],
|
| 597 |
+
'property_whitelist' => $cdata_spec['css_spec']['declaration'],
|
| 598 |
+
'validate_keyframes' => $cdata_spec['css_spec']['validate_keyframes'],
|
| 599 |
+
) );
|
| 600 |
+
|
| 601 |
+
$this->pending_stylesheets[] = array_merge(
|
| 602 |
+
array(
|
| 603 |
+
'keyframes' => $is_keyframes,
|
| 604 |
+
'node' => $element,
|
| 605 |
+
'sources' => $this->current_sources,
|
| 606 |
+
),
|
| 607 |
+
wp_array_slice_assoc( $processed, array( 'stylesheet', 'imported_font_urls' ) )
|
| 608 |
+
);
|
| 609 |
|
| 610 |
if ( $element->hasAttribute( 'amp-custom' ) ) {
|
| 611 |
if ( ! $this->amp_custom_style_element ) {
|
| 618 |
// Remove from DOM since we'll be adding it to amp-custom.
|
| 619 |
$element->parentNode->removeChild( $element );
|
| 620 |
}
|
| 621 |
+
|
| 622 |
+
$this->set_current_node( null );
|
| 623 |
}
|
| 624 |
|
| 625 |
/**
|
| 630 |
private function process_link_element( DOMElement $element ) {
|
| 631 |
$href = $element->getAttribute( 'href' );
|
| 632 |
|
| 633 |
+
// Allow font URLs, including protocol-less URLs and recognized URLs that use HTTP instead of HTTPS.
|
| 634 |
+
$normalized_url = preg_replace( '#^(http:)?(?=//)#', 'https:', $href );
|
| 635 |
+
if ( $this->allowed_font_src_regex && preg_match( $this->allowed_font_src_regex, $normalized_url ) ) {
|
| 636 |
+
if ( $href !== $normalized_url ) {
|
| 637 |
+
$element->setAttribute( 'href', $normalized_url );
|
| 638 |
+
}
|
| 639 |
+
|
| 640 |
+
/*
|
| 641 |
+
* Make sure rel=preconnect link is present for Google Fonts stylesheet.
|
| 642 |
+
* Note that core themes normally do this already, per <https://core.trac.wordpress.org/ticket/37171>.
|
| 643 |
+
* But not always, per <https://core.trac.wordpress.org/ticket/44668>.
|
| 644 |
+
* This also ensures that other themes will get the preconnect link when
|
| 645 |
+
* they don't implement the resource hint.
|
| 646 |
+
*/
|
| 647 |
+
$needs_preconnect_link = (
|
| 648 |
+
'https://fonts.googleapis.com/' === substr( $normalized_url, 0, 29 )
|
| 649 |
+
&&
|
| 650 |
+
0 === $this->xpath->query( '//link[ @rel = "preconnect" and @crossorigin and starts-with( @href, "https://fonts.gstatic.com" ) ]', $this->head )->length
|
| 651 |
+
);
|
| 652 |
+
if ( $needs_preconnect_link ) {
|
| 653 |
+
$link = AMP_DOM_Utils::create_node( $this->dom, 'link', array(
|
| 654 |
+
'rel' => 'preconnect',
|
| 655 |
+
'href' => 'https://fonts.gstatic.com/',
|
| 656 |
+
'crossorigin' => '',
|
| 657 |
+
) );
|
| 658 |
+
$this->head->insertBefore( $link ); // Note that \AMP_Theme_Support::ensure_required_markup() will put this in the optimal order.
|
| 659 |
+
}
|
| 660 |
return;
|
| 661 |
}
|
| 662 |
|
| 663 |
+
$css_file_path = $this->get_validated_url_file_path( $href, array( 'css', 'less', 'scss', 'sass' ) );
|
| 664 |
+
|
| 665 |
+
if ( is_wp_error( $css_file_path ) && ( 'disallowed_file_extension' === $css_file_path->get_error_code() || 'external_file_url' === $css_file_path->get_error_code() ) ) {
|
| 666 |
+
$contents = $this->fetch_external_stylesheet( $normalized_url );
|
| 667 |
+
if ( is_wp_error( $contents ) ) {
|
| 668 |
+
$this->remove_invalid_child( $element, array(
|
| 669 |
+
'code' => $css_file_path->get_error_code(),
|
| 670 |
+
'message' => $css_file_path->get_error_message(),
|
| 671 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 672 |
+
) );
|
| 673 |
+
return;
|
| 674 |
+
} else {
|
| 675 |
+
$stylesheet = $contents;
|
| 676 |
+
}
|
| 677 |
+
} elseif ( is_wp_error( $css_file_path ) ) {
|
| 678 |
$this->remove_invalid_child( $element, array(
|
| 679 |
+
'code' => $css_file_path->get_error_code(),
|
| 680 |
'message' => $css_file_path->get_error_message(),
|
| 681 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 682 |
) );
|
| 683 |
return;
|
| 684 |
+
} else {
|
| 685 |
+
$stylesheet = file_get_contents( $css_file_path ); // phpcs:ignore -- It's a local filesystem path not a remote request.
|
| 686 |
}
|
| 687 |
|
| 688 |
+
if ( false === $stylesheet ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 689 |
$this->remove_invalid_child( $element, array(
|
| 690 |
+
'code' => 'stylesheet_file_missing',
|
| 691 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 692 |
) );
|
| 693 |
return;
|
| 694 |
}
|
| 695 |
|
| 696 |
+
// Honor the link's media attribute.
|
| 697 |
+
$media = $element->getAttribute( 'media' );
|
| 698 |
+
if ( $media && 'all' !== $media ) {
|
| 699 |
+
$stylesheet = sprintf( '@media %s { %s }', $media, $stylesheet );
|
| 700 |
+
}
|
| 701 |
+
|
| 702 |
+
$this->set_current_node( $element ); // And sources when needing to be located.
|
| 703 |
+
|
| 704 |
+
$processed = $this->process_stylesheet( $stylesheet, array(
|
| 705 |
+
'allowed_at_rules' => $this->style_custom_cdata_spec['css_spec']['allowed_at_rules'],
|
| 706 |
+
'property_whitelist' => $this->style_custom_cdata_spec['css_spec']['declaration'],
|
| 707 |
+
'stylesheet_url' => $href,
|
| 708 |
+
'stylesheet_path' => $css_file_path,
|
| 709 |
+
) );
|
| 710 |
+
|
| 711 |
+
$this->pending_stylesheets[] = array_merge(
|
| 712 |
+
array(
|
| 713 |
+
'keyframes' => false,
|
| 714 |
+
'node' => $element,
|
| 715 |
+
'sources' => $this->current_sources, // Needed because node is removed below.
|
| 716 |
+
),
|
| 717 |
+
wp_array_slice_assoc( $processed, array( 'stylesheet', 'imported_font_urls' ) )
|
| 718 |
+
);
|
| 719 |
|
| 720 |
// Remove now that styles have been processed.
|
| 721 |
$element->parentNode->removeChild( $element );
|
|
|
|
| 722 |
|
| 723 |
+
$this->set_current_node( null );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 724 |
}
|
| 725 |
|
| 726 |
/**
|
| 727 |
+
* Fetch external stylesheet.
|
|
|
|
|
|
|
|
|
|
| 728 |
*
|
| 729 |
+
* @param string $url External stylesheet URL.
|
| 730 |
+
* @return string|WP_Error Stylesheet contents or WP_Error.
|
| 731 |
*/
|
| 732 |
+
private function fetch_external_stylesheet( $url ) {
|
| 733 |
+
$cache_key = md5( $url );
|
| 734 |
+
$contents = get_transient( $cache_key );
|
| 735 |
+
if ( false === $contents ) {
|
| 736 |
+
$r = wp_remote_get( $url );
|
| 737 |
+
if ( 200 !== wp_remote_retrieve_response_code( $r ) ) {
|
| 738 |
+
$contents = new WP_Error(
|
| 739 |
+
wp_remote_retrieve_response_code( $r ),
|
| 740 |
+
wp_remote_retrieve_response_message( $r )
|
| 741 |
+
);
|
| 742 |
+
} else {
|
| 743 |
+
$contents = wp_remote_retrieve_body( $r );
|
|
|
|
|
|
|
| 744 |
}
|
| 745 |
+
set_transient( $cache_key, $contents, MONTH_IN_SECONDS );
|
| 746 |
}
|
| 747 |
+
return $contents;
|
|
|
|
|
|
|
| 748 |
}
|
| 749 |
|
| 750 |
/**
|
| 751 |
+
* Process stylesheet.
|
| 752 |
*
|
| 753 |
+
* Sanitized invalid CSS properties and rules, removes rules which do not
|
| 754 |
+
* apply to the current document, and compresses the CSS to remove whitespace and comments.
|
| 755 |
*
|
| 756 |
+
* @since 1.0
|
| 757 |
*
|
| 758 |
+
* @param string $stylesheet Stylesheet.
|
| 759 |
+
* @param array $options {
|
| 760 |
+
* Options.
|
| 761 |
*
|
| 762 |
+
* @type string[] $property_whitelist Exclusively-allowed properties.
|
| 763 |
+
* @type string[] $property_blacklist Disallowed properties.
|
| 764 |
+
* @type string $stylesheet_url Original URL for stylesheet when originating via link or @import.
|
| 765 |
+
* @type string $stylesheet_path Original filesystem path for stylesheet when originating via link or @import.
|
| 766 |
+
* @type array $allowed_at_rules Allowed @-rules.
|
| 767 |
+
* @type bool $validate_keyframes Whether keyframes should be validated.
|
| 768 |
+
* }
|
| 769 |
+
* @return array {
|
| 770 |
+
* Processed stylesheet.
|
| 771 |
*
|
| 772 |
+
* @type array $stylesheet Stylesheet parts, where arrays are tuples for declaration blocks.
|
| 773 |
+
* @type array $validation_results Validation results, array containing arrays with error and sanitized keys.
|
| 774 |
+
* @type array $imported_font_urls Imported font stylesheet URLs.
|
| 775 |
+
* }
|
| 776 |
*/
|
| 777 |
+
private function process_stylesheet( $stylesheet, $options = array() ) {
|
| 778 |
+
$parsed = null;
|
| 779 |
+
$cache_key = null;
|
| 780 |
+
$cache_group = 'amp-parsed-stylesheet-v13'; // This should be bumped whenever the PHP-CSS-Parser is updated.
|
| 781 |
+
|
| 782 |
+
$cache_impacting_options = array_merge(
|
| 783 |
+
wp_array_slice_assoc(
|
| 784 |
+
$options,
|
| 785 |
+
array( 'property_whitelist', 'property_blacklist', 'stylesheet_url', 'allowed_at_rules' )
|
| 786 |
+
),
|
| 787 |
+
wp_array_slice_assoc(
|
| 788 |
+
$this->args,
|
| 789 |
+
array( 'should_locate_sources', 'parsed_cache_variant' )
|
| 790 |
+
),
|
| 791 |
+
array(
|
| 792 |
+
'language' => get_bloginfo( 'language' ), // Used to tree-shake html[lang] selectors.
|
| 793 |
+
)
|
| 794 |
+
);
|
| 795 |
|
| 796 |
+
$cache_key = md5( $stylesheet . wp_json_encode( $cache_impacting_options ) );
|
|
|
|
|
|
|
| 797 |
|
| 798 |
+
if ( wp_using_ext_object_cache() ) {
|
| 799 |
+
$parsed = wp_cache_get( $cache_key, $cache_group );
|
| 800 |
+
} else {
|
| 801 |
+
$parsed = get_transient( $cache_key . $cache_group );
|
| 802 |
+
}
|
| 803 |
|
| 804 |
+
/*
|
| 805 |
+
* Make sure that the parsed stylesheet was cached with current sanitizations.
|
| 806 |
+
* The should_sanitize_validation_error method prevents duplicates from being reported.
|
| 807 |
+
*/
|
| 808 |
+
if ( ! empty( $parsed['validation_results'] ) ) {
|
| 809 |
+
foreach ( $parsed['validation_results'] as $validation_result ) {
|
| 810 |
+
$sanitized = $this->should_sanitize_validation_error( $validation_result['error'] );
|
| 811 |
+
if ( $sanitized !== $validation_result['sanitized'] ) {
|
| 812 |
+
$parsed = null; // Change to sanitization of validation error detected, so cache cannot be used.
|
| 813 |
+
break;
|
| 814 |
+
}
|
| 815 |
}
|
| 816 |
+
}
|
| 817 |
|
| 818 |
+
if ( ! $parsed || ! isset( $parsed['stylesheet'] ) || ! is_array( $parsed['stylesheet'] ) ) {
|
| 819 |
+
$parsed = $this->prepare_stylesheet( $stylesheet, $options );
|
| 820 |
+
|
| 821 |
+
/*
|
| 822 |
+
* When an object cache is not available, we cache with an expiration to prevent the options table from
|
| 823 |
+
* getting filled infinitely. On the other hand, if an external object cache is available then we don't
|
| 824 |
+
* set an expiration because it should implement LRU cache expulsion policy.
|
| 825 |
+
*/
|
| 826 |
+
if ( wp_using_ext_object_cache() ) {
|
| 827 |
+
wp_cache_set( $cache_key, $parsed, $cache_group );
|
| 828 |
+
} else {
|
| 829 |
+
// The expiration is to ensure transient doesn't stick around forever since no LRU flushing like with external object cache.
|
| 830 |
+
set_transient( $cache_key . $cache_group, $parsed, MONTH_IN_SECONDS );
|
| 831 |
+
}
|
| 832 |
}
|
| 833 |
+
|
| 834 |
+
return $parsed;
|
| 835 |
}
|
| 836 |
|
| 837 |
/**
|
| 838 |
+
* Parse imported stylesheet.
|
| 839 |
*
|
| 840 |
+
* @param Import $item Import object.
|
| 841 |
+
* @param CSSList $css_list CSS List.
|
| 842 |
+
* @param array $options {
|
| 843 |
+
* Options.
|
| 844 |
*
|
| 845 |
+
* @type string $stylesheet_url Original URL for stylesheet when originating via link or @import.
|
| 846 |
+
* }
|
| 847 |
+
* @return array Validation results.
|
| 848 |
*/
|
| 849 |
+
private function parse_import_stylesheet( Import $item, CSSList $css_list, $options ) {
|
| 850 |
+
$results = array();
|
| 851 |
+
$at_rule_args = $item->atRuleArgs();
|
| 852 |
+
$location = array_shift( $at_rule_args );
|
| 853 |
+
$media_query = array_shift( $at_rule_args );
|
| 854 |
+
|
| 855 |
+
if ( isset( $options['stylesheet_url'] ) ) {
|
| 856 |
+
$this->real_path_urls( array( $location ), $options['stylesheet_url'] );
|
| 857 |
+
}
|
|
|
|
|
|
|
| 858 |
|
| 859 |
+
$import_stylesheet_url = $location->getURL()->getString();
|
|
|
|
| 860 |
|
| 861 |
+
// Prevent importing something that has already been imported, and avoid infinite recursion.
|
| 862 |
+
if ( isset( $this->processed_imported_stylesheet_urls[ $import_stylesheet_url ] ) ) {
|
| 863 |
+
$css_list->remove( $item );
|
| 864 |
+
return array();
|
| 865 |
+
}
|
| 866 |
+
$this->processed_imported_stylesheet_urls[ $import_stylesheet_url ] = true;
|
| 867 |
+
|
| 868 |
+
// Prevent importing font stylesheets from allowed font CDNs. These will get added to the document as links instead.
|
| 869 |
+
$https_import_stylesheet_url = preg_replace( '#^(http:)?(?=//)#', 'https:', $import_stylesheet_url );
|
| 870 |
+
if ( $this->allowed_font_src_regex && preg_match( $this->allowed_font_src_regex, $https_import_stylesheet_url ) ) {
|
| 871 |
+
$this->imported_font_urls[] = $https_import_stylesheet_url;
|
| 872 |
+
$css_list->remove( $item );
|
| 873 |
+
_doing_it_wrong(
|
| 874 |
+
'wp_enqueue_style',
|
| 875 |
+
esc_html( sprintf(
|
| 876 |
+
/* translators: %s is URL to font CDN */
|
| 877 |
+
__( 'It is not a best practice to use @import to load font CDN stylesheets. Please use wp_enqueue_style() to enqueue %s as its own separate script.', 'amp' ),
|
| 878 |
+
$import_stylesheet_url
|
| 879 |
+
) ),
|
| 880 |
+
'1.0'
|
| 881 |
+
);
|
| 882 |
+
return array();
|
| 883 |
+
}
|
| 884 |
|
| 885 |
+
$css_file_path = $this->get_validated_url_file_path( $import_stylesheet_url, array( 'css', 'less', 'scss', 'sass' ) );
|
| 886 |
+
|
| 887 |
+
if ( is_wp_error( $css_file_path ) && ( 'disallowed_file_extension' === $css_file_path->get_error_code() || 'external_file_url' === $css_file_path->get_error_code() ) ) {
|
| 888 |
+
$contents = $this->fetch_external_stylesheet( $import_stylesheet_url );
|
| 889 |
+
if ( is_wp_error( $contents ) ) {
|
| 890 |
+
$error = array(
|
| 891 |
+
'code' => $contents->get_error_code(),
|
| 892 |
+
'message' => $contents->get_error_message(),
|
| 893 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 894 |
+
);
|
| 895 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 896 |
+
if ( $sanitized ) {
|
| 897 |
+
$css_list->remove( $item );
|
| 898 |
+
}
|
| 899 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 900 |
+
return $results;
|
| 901 |
+
} else {
|
| 902 |
+
$stylesheet = $contents;
|
| 903 |
+
}
|
| 904 |
+
} elseif ( is_wp_error( $css_file_path ) ) {
|
| 905 |
+
$error = array(
|
| 906 |
+
'code' => $css_file_path->get_error_code(),
|
| 907 |
+
'message' => $css_file_path->get_error_message(),
|
| 908 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 909 |
+
);
|
| 910 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 911 |
+
if ( $sanitized ) {
|
| 912 |
+
$css_list->remove( $item );
|
| 913 |
+
}
|
| 914 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 915 |
+
return $results;
|
| 916 |
+
} else {
|
| 917 |
+
$stylesheet = file_get_contents( $css_file_path ); // phpcs:ignore -- It's a local filesystem path not a remote request.
|
| 918 |
+
}
|
| 919 |
+
|
| 920 |
+
if ( $media_query ) {
|
| 921 |
+
$stylesheet = sprintf( '@media %s { %s }', $media_query, $stylesheet );
|
| 922 |
+
}
|
| 923 |
+
|
| 924 |
+
$options['stylesheet_url'] = $import_stylesheet_url;
|
| 925 |
+
|
| 926 |
+
$parsed_stylesheet = $this->parse_stylesheet( $stylesheet, $options );
|
| 927 |
+
|
| 928 |
+
$results = array_merge(
|
| 929 |
+
$results,
|
| 930 |
+
$parsed_stylesheet['validation_results']
|
| 931 |
+
);
|
| 932 |
+
|
| 933 |
+
/**
|
| 934 |
+
* CSS Doc.
|
| 935 |
+
*
|
| 936 |
+
* @var Document $css_document
|
| 937 |
+
*/
|
| 938 |
+
$css_document = $parsed_stylesheet['css_document'];
|
| 939 |
+
|
| 940 |
+
if ( ! empty( $parsed_stylesheet['css_document'] ) ) {
|
| 941 |
+
$css_list->replace( $item, $css_document->getContents() );
|
| 942 |
+
} else {
|
| 943 |
+
$css_list->remove( $item );
|
| 944 |
+
}
|
| 945 |
+
|
| 946 |
+
return $results;
|
| 947 |
+
}
|
| 948 |
+
|
| 949 |
+
/**
|
| 950 |
+
* Parse stylesheet.
|
| 951 |
+
*
|
| 952 |
+
* @since 1.0
|
| 953 |
+
*
|
| 954 |
+
* @param string $stylesheet_string Stylesheet.
|
| 955 |
+
* @param array $options Options. See definition in \AMP_Style_Sanitizer::process_stylesheet().
|
| 956 |
+
* @return array {
|
| 957 |
+
* Parsed stylesheet.
|
| 958 |
+
*
|
| 959 |
+
* @type Document $css_document CSS Document.
|
| 960 |
+
* @type array $validation_results Validation results, array containing arrays with error and sanitized keys.
|
| 961 |
+
* }
|
| 962 |
+
*/
|
| 963 |
+
private function parse_stylesheet( $stylesheet_string, $options ) {
|
| 964 |
+
$validation_results = array();
|
| 965 |
+
$css_document = null;
|
| 966 |
+
|
| 967 |
+
$this->imported_font_urls = array();
|
| 968 |
+
try {
|
| 969 |
+
// Remove spaces from data URLs, which cause errors and PHP-CSS-Parser can't handle them.
|
| 970 |
+
$stylesheet_string = $this->remove_spaces_from_data_urls( $stylesheet_string );
|
| 971 |
+
|
| 972 |
+
$parser_settings = Sabberworm\CSS\Settings::create();
|
| 973 |
+
$css_parser = new Sabberworm\CSS\Parser( $stylesheet_string, $parser_settings );
|
| 974 |
+
$css_document = $css_parser->parse(); // @todo If 'utf-8' is not $css_parser->getCharset() then issue warning?
|
| 975 |
+
|
| 976 |
+
if ( ! empty( $options['stylesheet_url'] ) ) {
|
| 977 |
+
$this->real_path_urls(
|
| 978 |
+
array_filter(
|
| 979 |
+
$css_document->getAllValues(),
|
| 980 |
+
function ( $value ) {
|
| 981 |
+
return $value instanceof URL;
|
| 982 |
+
}
|
| 983 |
+
),
|
| 984 |
+
$options['stylesheet_url']
|
| 985 |
+
);
|
| 986 |
}
|
| 987 |
|
| 988 |
+
$validation_results = array_merge(
|
| 989 |
+
$validation_results,
|
| 990 |
+
$this->process_css_list( $css_document, $options )
|
| 991 |
+
);
|
| 992 |
+
} catch ( Exception $exception ) {
|
| 993 |
+
$error = array(
|
| 994 |
+
'code' => 'css_parse_error',
|
| 995 |
+
'message' => $exception->getMessage(),
|
| 996 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 997 |
+
);
|
| 998 |
+
|
| 999 |
+
/*
|
| 1000 |
+
* This is not a recoverable error, so sanitized here is just used to give user control
|
| 1001 |
+
* over whether to proceed with serving this exception-raising stylesheet in AMP.
|
| 1002 |
+
*/
|
| 1003 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1004 |
+
|
| 1005 |
+
$validation_results[] = compact( 'error', 'sanitized' );
|
| 1006 |
+
}
|
| 1007 |
+
return array_merge(
|
| 1008 |
+
compact( 'validation_results', 'css_document' ),
|
| 1009 |
+
array(
|
| 1010 |
+
'imported_font_urls' => $this->imported_font_urls,
|
| 1011 |
+
)
|
| 1012 |
+
);
|
| 1013 |
+
}
|
| 1014 |
+
|
| 1015 |
+
/**
|
| 1016 |
+
* Prepare stylesheet.
|
| 1017 |
+
*
|
| 1018 |
+
* @since 1.0
|
| 1019 |
+
*
|
| 1020 |
+
* @param string $stylesheet_string Stylesheet.
|
| 1021 |
+
* @param array $options Options. See definition in \AMP_Style_Sanitizer::process_stylesheet().
|
| 1022 |
+
* @return array {
|
| 1023 |
+
* Prepared stylesheet.
|
| 1024 |
+
*
|
| 1025 |
+
* @type array $stylesheet Stylesheet parts, where arrays are tuples for declaration blocks.
|
| 1026 |
+
* @type array $validation_results Validation results, array containing arrays with error and sanitized keys.
|
| 1027 |
+
* @type array $imported_font_urls Imported font stylesheet URLs.
|
| 1028 |
+
* }
|
| 1029 |
+
*/
|
| 1030 |
+
private function prepare_stylesheet( $stylesheet_string, $options = array() ) {
|
| 1031 |
+
$start_time = microtime( true );
|
| 1032 |
+
|
| 1033 |
+
$options = array_merge(
|
| 1034 |
+
array(
|
| 1035 |
+
'allowed_at_rules' => array(),
|
| 1036 |
+
'property_blacklist' => array(
|
| 1037 |
+
// See <https://www.ampproject.org/docs/design/responsive/style_pages#disallowed-styles>.
|
| 1038 |
+
'behavior',
|
| 1039 |
+
'-moz-binding',
|
| 1040 |
+
),
|
| 1041 |
+
'property_whitelist' => array(),
|
| 1042 |
+
'validate_keyframes' => false,
|
| 1043 |
+
'stylesheet_url' => null,
|
| 1044 |
+
'stylesheet_path' => null,
|
| 1045 |
+
),
|
| 1046 |
+
$options
|
| 1047 |
+
);
|
| 1048 |
+
|
| 1049 |
+
// Strip the dreaded UTF-8 byte order mark (BOM, \uFEFF). This should ideally get handled by PHP-CSS-Parser <https://github.com/sabberworm/PHP-CSS-Parser/issues/150>.
|
| 1050 |
+
$stylesheet_string = preg_replace( '/^\xEF\xBB\xBF/', '', $stylesheet_string );
|
| 1051 |
+
|
| 1052 |
+
$stylesheet = array();
|
| 1053 |
+
$parsed_stylesheet = $this->parse_stylesheet( $stylesheet_string, $options );
|
| 1054 |
+
$validation_results = $parsed_stylesheet['validation_results'];
|
| 1055 |
+
if ( ! empty( $parsed_stylesheet['css_document'] ) ) {
|
| 1056 |
+
$css_document = $parsed_stylesheet['css_document'];
|
| 1057 |
+
|
| 1058 |
+
$output_format = Sabberworm\CSS\OutputFormat::createCompact();
|
| 1059 |
+
$output_format->setSemicolonAfterLastRule( false );
|
| 1060 |
+
|
| 1061 |
+
$before_declaration_block = '/*AMP_WP_BEFORE_DECLARATION_BLOCK*/';
|
| 1062 |
+
$between_selectors = '/*AMP_WP_BETWEEN_SELECTORS*/';
|
| 1063 |
+
$after_declaration_block_selectors = '/*AMP_WP_BEFORE_DECLARATION_SELECTORS*/';
|
| 1064 |
+
$after_declaration_block = '/*AMP_WP_AFTER_DECLARATION*/';
|
| 1065 |
+
$before_at_rule = '/*AMP_WP_BEFORE_AT_RULE*/';
|
| 1066 |
+
$after_at_rule = '/*AMP_WP_AFTER_AT_RULE*/';
|
| 1067 |
+
|
| 1068 |
+
$output_format->set( 'BeforeDeclarationBlock', $before_declaration_block );
|
| 1069 |
+
$output_format->set( 'SpaceBeforeSelectorSeparator', $between_selectors );
|
| 1070 |
+
$output_format->set( 'AfterDeclarationBlockSelectors', $after_declaration_block_selectors );
|
| 1071 |
+
$output_format->set( 'AfterDeclarationBlock', $after_declaration_block );
|
| 1072 |
+
$output_format->set( 'BeforeAtRuleBlock', $before_at_rule );
|
| 1073 |
+
$output_format->set( 'AfterAtRuleBlock', $after_at_rule );
|
| 1074 |
+
|
| 1075 |
+
$stylesheet_string = $css_document->render( $output_format );
|
| 1076 |
+
|
| 1077 |
+
$pattern = '#';
|
| 1078 |
+
$pattern .= preg_quote( $before_at_rule, '#' );
|
| 1079 |
+
$pattern .= '|';
|
| 1080 |
+
$pattern .= preg_quote( $after_at_rule, '#' );
|
| 1081 |
+
$pattern .= '|';
|
| 1082 |
+
$pattern .= '(' . preg_quote( $before_declaration_block, '#' ) . ')';
|
| 1083 |
+
$pattern .= '(.+?)';
|
| 1084 |
+
$pattern .= preg_quote( $after_declaration_block_selectors, '#' );
|
| 1085 |
+
$pattern .= '(.+?)';
|
| 1086 |
+
$pattern .= preg_quote( $after_declaration_block, '#' );
|
| 1087 |
+
$pattern .= '#s';
|
| 1088 |
+
|
| 1089 |
+
$dynamic_selector_pattern = null;
|
| 1090 |
+
if ( ! empty( $this->args['dynamic_element_selectors'] ) ) {
|
| 1091 |
+
$dynamic_selector_pattern = implode( '|', array_map(
|
| 1092 |
+
function( $selector ) {
|
| 1093 |
+
return preg_quote( $selector, '#' );
|
| 1094 |
+
},
|
| 1095 |
+
$this->args['dynamic_element_selectors']
|
| 1096 |
+
) );
|
| 1097 |
+
}
|
| 1098 |
+
|
| 1099 |
+
$split_stylesheet = preg_split( $pattern, $stylesheet_string, -1, PREG_SPLIT_DELIM_CAPTURE );
|
| 1100 |
+
$length = count( $split_stylesheet );
|
| 1101 |
+
for ( $i = 0; $i < $length; $i++ ) {
|
| 1102 |
+
if ( $before_declaration_block === $split_stylesheet[ $i ] ) {
|
| 1103 |
+
|
| 1104 |
+
// Skip keyframe-selector, which is can be: from | to | <percentage>.
|
| 1105 |
+
if ( preg_match( '/^((from|to)\b|-?\d+(\.\d+)?%)/i', $split_stylesheet[ $i + 1 ] ) ) {
|
| 1106 |
+
$stylesheet[] = str_replace( $between_selectors, '', $split_stylesheet[ ++$i ] ) . $split_stylesheet[ ++$i ];
|
| 1107 |
+
continue;
|
| 1108 |
+
}
|
| 1109 |
+
|
| 1110 |
+
$selectors = explode( $between_selectors . ',', $split_stylesheet[ ++$i ] );
|
| 1111 |
+
$declaration = $split_stylesheet[ ++$i ];
|
| 1112 |
+
|
| 1113 |
+
$selectors_parsed = array();
|
| 1114 |
+
foreach ( $selectors as $selector ) {
|
| 1115 |
+
$selectors_parsed[ $selector ] = array();
|
| 1116 |
+
|
| 1117 |
+
// Remove :not() and pseudo selectors to eliminate false negatives, such as with `body:not(.title-tagline-hidden) .site-branding-text`.
|
| 1118 |
+
$reduced_selector = preg_replace( '/:[a-zA-Z0-9_-]+(\(.+?\))?/', '', $selector );
|
| 1119 |
+
|
| 1120 |
+
// Remove attribute selectors to eliminate false negative, such as with `.social-navigation a[href*="example.com"]:before`.
|
| 1121 |
+
$reduced_selector = preg_replace( '/\[\w.*?\]/', '', $reduced_selector );
|
| 1122 |
+
|
| 1123 |
+
// Ignore any selector terms that occur under a dynamic selector.
|
| 1124 |
+
if ( $dynamic_selector_pattern ) {
|
| 1125 |
+
$reduced_selector = preg_replace( '#((?:' . $dynamic_selector_pattern . ')(?:\.[a-z0-9_-]+)*)[^a-z0-9_-].*#si', '$1', $reduced_selector . ' ' );
|
| 1126 |
+
}
|
| 1127 |
+
|
| 1128 |
+
$reduced_selector = preg_replace_callback(
|
| 1129 |
+
'/\.([a-zA-Z0-9_-]+)/',
|
| 1130 |
+
function( $matches ) use ( $selector, &$selectors_parsed ) {
|
| 1131 |
+
$selectors_parsed[ $selector ]['classes'][] = $matches[1];
|
| 1132 |
+
return '';
|
| 1133 |
+
},
|
| 1134 |
+
$reduced_selector
|
| 1135 |
+
);
|
| 1136 |
+
$reduced_selector = preg_replace_callback(
|
| 1137 |
+
'/#([a-zA-Z0-9_-]+)/',
|
| 1138 |
+
function( $matches ) use ( $selector, &$selectors_parsed ) {
|
| 1139 |
+
$selectors_parsed[ $selector ]['ids'][] = $matches[1];
|
| 1140 |
+
return '';
|
| 1141 |
+
},
|
| 1142 |
+
$reduced_selector
|
| 1143 |
+
);
|
| 1144 |
+
|
| 1145 |
+
if ( preg_match_all( '/[a-zA-Z0-9_-]+/', $reduced_selector, $matches ) ) {
|
| 1146 |
+
$selectors_parsed[ $selector ]['tags'] = $matches[0];
|
| 1147 |
+
}
|
| 1148 |
+
}
|
| 1149 |
+
|
| 1150 |
+
$stylesheet[] = array(
|
| 1151 |
+
$selectors_parsed,
|
| 1152 |
+
$declaration,
|
| 1153 |
+
);
|
| 1154 |
+
} else {
|
| 1155 |
+
$stylesheet[] = $split_stylesheet[ $i ];
|
| 1156 |
+
}
|
| 1157 |
+
}
|
| 1158 |
+
}
|
| 1159 |
+
|
| 1160 |
+
$this->parse_css_duration += ( microtime( true ) - $start_time );
|
| 1161 |
+
|
| 1162 |
+
return array_merge(
|
| 1163 |
+
compact( 'stylesheet', 'validation_results' ),
|
| 1164 |
+
array(
|
| 1165 |
+
'imported_font_urls' => $parsed_stylesheet['imported_font_urls'],
|
| 1166 |
+
)
|
| 1167 |
+
);
|
| 1168 |
+
}
|
| 1169 |
+
|
| 1170 |
+
/**
|
| 1171 |
+
* Previous return values from calls to should_sanitize_validation_error().
|
| 1172 |
+
*
|
| 1173 |
+
* This is used to prevent duplicates from being reported when the sanitization status
|
| 1174 |
+
* changes for a validation error in a previously-cached stylesheet.
|
| 1175 |
+
*
|
| 1176 |
+
* @see AMP_Style_Sanitizer::should_sanitize_validation_error()
|
| 1177 |
+
* @var array
|
| 1178 |
+
*/
|
| 1179 |
+
protected $previous_should_sanitize_validation_error_results = array();
|
| 1180 |
+
|
| 1181 |
+
/**
|
| 1182 |
+
* Check whether or not sanitization should occur in response to validation error.
|
| 1183 |
+
*
|
| 1184 |
+
* Supply sources to the error and the current node to data.
|
| 1185 |
+
*
|
| 1186 |
+
* @since 1.0
|
| 1187 |
+
*
|
| 1188 |
+
* @param array $validation_error Validation error.
|
| 1189 |
+
* @param array $data Data including the node.
|
| 1190 |
+
* @return bool Whether to sanitize.
|
| 1191 |
+
*/
|
| 1192 |
+
public function should_sanitize_validation_error( $validation_error, $data = array() ) {
|
| 1193 |
+
if ( ! isset( $data['node'] ) ) {
|
| 1194 |
+
$data['node'] = $this->current_node;
|
| 1195 |
+
}
|
| 1196 |
+
if ( ! isset( $validation_error['sources'] ) ) {
|
| 1197 |
+
$validation_error['sources'] = $this->current_sources;
|
| 1198 |
+
}
|
| 1199 |
+
|
| 1200 |
+
/*
|
| 1201 |
+
* This is used to prevent duplicates from being reported when the sanitization status
|
| 1202 |
+
* changes for a validation error in a previously-cached stylesheet.
|
| 1203 |
+
*/
|
| 1204 |
+
$args = compact( 'validation_error', 'data' );
|
| 1205 |
+
foreach ( $this->previous_should_sanitize_validation_error_results as $result ) {
|
| 1206 |
+
if ( $result['args'] === $args ) {
|
| 1207 |
+
return $result['sanitized'];
|
| 1208 |
+
}
|
| 1209 |
+
}
|
| 1210 |
+
|
| 1211 |
+
$sanitized = parent::should_sanitize_validation_error( $validation_error, $data );
|
| 1212 |
+
|
| 1213 |
+
$this->previous_should_sanitize_validation_error_results[] = compact( 'args', 'sanitized' );
|
| 1214 |
+
return $sanitized;
|
| 1215 |
+
}
|
| 1216 |
+
|
| 1217 |
+
/**
|
| 1218 |
+
* Remove spaces from data URLs which PHP-CSS-Parser doesn't handle.
|
| 1219 |
+
*
|
| 1220 |
+
* @since 1.0
|
| 1221 |
+
*
|
| 1222 |
+
* @param string $css CSS.
|
| 1223 |
+
* @return string CSS with spaces removed from data URLs.
|
| 1224 |
+
*/
|
| 1225 |
+
private function remove_spaces_from_data_urls( $css ) {
|
| 1226 |
+
return preg_replace_callback(
|
| 1227 |
+
'/\burl\([^}]*?\)/',
|
| 1228 |
+
function( $matches ) {
|
| 1229 |
+
return preg_replace( '/\s+/', '', $matches[0] );
|
| 1230 |
+
},
|
| 1231 |
+
$css
|
| 1232 |
+
);
|
| 1233 |
+
}
|
| 1234 |
+
|
| 1235 |
+
/**
|
| 1236 |
+
* Process CSS list.
|
| 1237 |
+
*
|
| 1238 |
+
* @since 1.0
|
| 1239 |
+
*
|
| 1240 |
+
* @param CSSList $css_list CSS List.
|
| 1241 |
+
* @param array $options Options.
|
| 1242 |
+
* @return array Validation errors.
|
| 1243 |
+
*/
|
| 1244 |
+
private function process_css_list( CSSList $css_list, $options ) {
|
| 1245 |
+
$results = array();
|
| 1246 |
+
|
| 1247 |
+
foreach ( $css_list->getContents() as $css_item ) {
|
| 1248 |
+
$sanitized = false;
|
| 1249 |
+
if ( $css_item instanceof DeclarationBlock && empty( $options['validate_keyframes'] ) ) {
|
| 1250 |
+
$results = array_merge(
|
| 1251 |
+
$results,
|
| 1252 |
+
$this->process_css_declaration_block( $css_item, $css_list, $options )
|
| 1253 |
+
);
|
| 1254 |
+
} elseif ( $css_item instanceof AtRuleBlockList ) {
|
| 1255 |
+
if ( ! in_array( $css_item->atRuleName(), $options['allowed_at_rules'], true ) ) {
|
| 1256 |
+
$error = array(
|
| 1257 |
+
'code' => self::ILLEGAL_AT_RULE_ERROR_CODE,
|
| 1258 |
+
'at_rule' => $css_item->atRuleName(),
|
| 1259 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1260 |
+
);
|
| 1261 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1262 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1263 |
+
}
|
| 1264 |
+
if ( ! $sanitized ) {
|
| 1265 |
+
$results = array_merge(
|
| 1266 |
+
$results,
|
| 1267 |
+
$this->process_css_list( $css_item, $options )
|
| 1268 |
+
);
|
| 1269 |
+
}
|
| 1270 |
+
} elseif ( $css_item instanceof Import ) {
|
| 1271 |
+
$results = array_merge(
|
| 1272 |
+
$results,
|
| 1273 |
+
$this->parse_import_stylesheet( $css_item, $css_list, $options )
|
| 1274 |
+
);
|
| 1275 |
+
} elseif ( $css_item instanceof AtRuleSet ) {
|
| 1276 |
+
if ( ! in_array( $css_item->atRuleName(), $options['allowed_at_rules'], true ) ) {
|
| 1277 |
+
$error = array(
|
| 1278 |
+
'code' => self::ILLEGAL_AT_RULE_ERROR_CODE,
|
| 1279 |
+
'at_rule' => $css_item->atRuleName(),
|
| 1280 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1281 |
+
);
|
| 1282 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1283 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1284 |
+
}
|
| 1285 |
+
|
| 1286 |
+
if ( ! $sanitized ) {
|
| 1287 |
+
$results = array_merge(
|
| 1288 |
+
$results,
|
| 1289 |
+
$this->process_css_declaration_block( $css_item, $css_list, $options )
|
| 1290 |
+
);
|
| 1291 |
+
}
|
| 1292 |
+
} elseif ( $css_item instanceof KeyFrame ) {
|
| 1293 |
+
if ( ! in_array( 'keyframes', $options['allowed_at_rules'], true ) ) {
|
| 1294 |
+
$error = array(
|
| 1295 |
+
'code' => self::ILLEGAL_AT_RULE_ERROR_CODE,
|
| 1296 |
+
'at_rule' => $css_item->atRuleName(),
|
| 1297 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1298 |
+
);
|
| 1299 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1300 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1301 |
+
}
|
| 1302 |
+
|
| 1303 |
+
if ( ! $sanitized ) {
|
| 1304 |
+
$results = array_merge(
|
| 1305 |
+
$results,
|
| 1306 |
+
$this->process_css_keyframes( $css_item, $options )
|
| 1307 |
+
);
|
| 1308 |
+
}
|
| 1309 |
+
} elseif ( $css_item instanceof AtRule ) {
|
| 1310 |
+
if ( 'charset' === $css_item->atRuleName() ) {
|
| 1311 |
+
/*
|
| 1312 |
+
* The @charset at-rule is not allowed in style elements, so it is not allowed in AMP.
|
| 1313 |
+
* If the @charset is defined, then it really should have already been acknowledged
|
| 1314 |
+
* by PHP-CSS-Parser when the CSS was parsed in the first place, so at this point
|
| 1315 |
+
* it is irrelevant and can be removed.
|
| 1316 |
+
*/
|
| 1317 |
+
$sanitized = true;
|
| 1318 |
+
} else {
|
| 1319 |
+
$error = array(
|
| 1320 |
+
'code' => self::ILLEGAL_AT_RULE_ERROR_CODE,
|
| 1321 |
+
'at_rule' => $css_item->atRuleName(),
|
| 1322 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1323 |
+
);
|
| 1324 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1325 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1326 |
+
}
|
| 1327 |
+
} else {
|
| 1328 |
+
$error = array(
|
| 1329 |
+
'code' => 'unrecognized_css',
|
| 1330 |
+
'item' => get_class( $css_item ),
|
| 1331 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1332 |
+
);
|
| 1333 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1334 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1335 |
+
}
|
| 1336 |
+
|
| 1337 |
+
if ( $sanitized ) {
|
| 1338 |
+
$css_list->remove( $css_item );
|
| 1339 |
+
}
|
| 1340 |
+
}
|
| 1341 |
+
return $results;
|
| 1342 |
+
}
|
| 1343 |
+
|
| 1344 |
+
/**
|
| 1345 |
+
* Convert URLs in to non-relative real-paths.
|
| 1346 |
+
*
|
| 1347 |
+
* @param URL[] $urls URLs.
|
| 1348 |
+
* @param string $stylesheet_url Stylesheet URL.
|
| 1349 |
+
*/
|
| 1350 |
+
private function real_path_urls( $urls, $stylesheet_url ) {
|
| 1351 |
+
$base_url = preg_replace( ':[^/]+(\?.*)?(#.*)?$:', '', $stylesheet_url );
|
| 1352 |
+
if ( empty( $base_url ) ) {
|
| 1353 |
+
return;
|
| 1354 |
+
}
|
| 1355 |
+
|
| 1356 |
+
foreach ( $urls as $url ) {
|
| 1357 |
+
// URLs cannot have spaces in them, so strip them (especially when spaces get erroneously injected in data: URLs).
|
| 1358 |
+
$url_string = $url->getURL()->getString();
|
| 1359 |
+
|
| 1360 |
+
// For data: URLs, all that is needed is to remove spaces so set and continue.
|
| 1361 |
+
if ( 'data:' === substr( $url_string, 0, 5 ) ) {
|
| 1362 |
continue;
|
| 1363 |
}
|
| 1364 |
|
| 1365 |
+
// If the URL is already absolute, continue since there there is nothing left to do.
|
| 1366 |
+
$parsed_url = wp_parse_url( $url_string );
|
| 1367 |
+
if ( ! empty( $parsed_url['host'] ) || empty( $parsed_url['path'] ) || '/' === substr( $parsed_url['path'], 0, 1 ) ) {
|
| 1368 |
+
continue;
|
| 1369 |
+
}
|
| 1370 |
+
|
| 1371 |
+
$relative_url = preg_replace( '#^\./#', '', $url->getURL()->getString() );
|
| 1372 |
+
|
| 1373 |
+
// Resolve any relative parent directory paths.
|
| 1374 |
+
$real_url = $base_url . $relative_url;
|
| 1375 |
+
do {
|
| 1376 |
+
$real_url = preg_replace( '#[^/]+/../#', '', $real_url, -1, $count );
|
| 1377 |
+
} while ( 0 !== $count );
|
| 1378 |
+
|
| 1379 |
+
$url->getURL()->setString( $real_url );
|
| 1380 |
+
}
|
| 1381 |
+
}
|
| 1382 |
+
|
| 1383 |
+
/**
|
| 1384 |
+
* Process CSS rule set.
|
| 1385 |
+
*
|
| 1386 |
+
* @since 1.0
|
| 1387 |
+
* @link https://www.ampproject.org/docs/design/responsive/style_pages#disallowed-styles
|
| 1388 |
+
* @link https://www.ampproject.org/docs/design/responsive/style_pages#restricted-styles
|
| 1389 |
+
*
|
| 1390 |
+
* @param RuleSet $ruleset Ruleset.
|
| 1391 |
+
* @param CSSList $css_list CSS List.
|
| 1392 |
+
* @param array $options Options.
|
| 1393 |
+
*
|
| 1394 |
+
* @return array Validation results.
|
| 1395 |
+
*/
|
| 1396 |
+
private function process_css_declaration_block( RuleSet $ruleset, CSSList $css_list, $options ) {
|
| 1397 |
+
$results = array();
|
| 1398 |
+
|
| 1399 |
+
if ( $ruleset instanceof DeclarationBlock ) {
|
| 1400 |
+
$this->ampify_ruleset_selectors( $ruleset );
|
| 1401 |
+
if ( 0 === count( $ruleset->getSelectors() ) ) {
|
| 1402 |
+
$css_list->remove( $ruleset );
|
| 1403 |
+
return $results;
|
| 1404 |
+
}
|
| 1405 |
+
}
|
| 1406 |
+
|
| 1407 |
+
// Remove disallowed properties.
|
| 1408 |
+
if ( ! empty( $options['property_whitelist'] ) ) {
|
| 1409 |
+
$properties = $ruleset->getRules();
|
| 1410 |
+
foreach ( $properties as $property ) {
|
| 1411 |
+
$vendorless_property_name = preg_replace( '/^-\w+-/', '', $property->getRule() );
|
| 1412 |
+
if ( ! in_array( $vendorless_property_name, $options['property_whitelist'], true ) ) {
|
| 1413 |
+
$error = array(
|
| 1414 |
+
'code' => 'illegal_css_property',
|
| 1415 |
+
'property_name' => $property->getRule(),
|
| 1416 |
+
'property_value' => $property->getValue(),
|
| 1417 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1418 |
+
);
|
| 1419 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1420 |
+
if ( $sanitized ) {
|
| 1421 |
+
$ruleset->removeRule( $property->getRule() );
|
| 1422 |
+
}
|
| 1423 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1424 |
+
}
|
| 1425 |
+
}
|
| 1426 |
+
} else {
|
| 1427 |
+
foreach ( $options['property_blacklist'] as $illegal_property_name ) {
|
| 1428 |
+
$properties = $ruleset->getRules( $illegal_property_name );
|
| 1429 |
+
foreach ( $properties as $property ) {
|
| 1430 |
+
$error = array(
|
| 1431 |
+
'code' => 'illegal_css_property',
|
| 1432 |
+
'property_name' => $property->getRule(),
|
| 1433 |
+
'property_value' => (string) $property->getValue(),
|
| 1434 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1435 |
+
);
|
| 1436 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1437 |
+
if ( $sanitized ) {
|
| 1438 |
+
$ruleset->removeRule( $property->getRule() );
|
| 1439 |
+
}
|
| 1440 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1441 |
+
}
|
| 1442 |
+
}
|
| 1443 |
}
|
| 1444 |
|
| 1445 |
+
if ( $ruleset instanceof AtRuleSet && 'font-face' === $ruleset->atRuleName() ) {
|
| 1446 |
+
$this->process_font_face_at_rule( $ruleset );
|
| 1447 |
+
}
|
| 1448 |
+
|
| 1449 |
+
$results = array_merge(
|
| 1450 |
+
$results,
|
| 1451 |
+
$this->transform_important_qualifiers( $ruleset, $css_list )
|
| 1452 |
+
);
|
| 1453 |
+
|
| 1454 |
+
// Remove the ruleset if it is now empty.
|
| 1455 |
+
if ( 0 === count( $ruleset->getRules() ) ) {
|
| 1456 |
+
$css_list->remove( $ruleset );
|
| 1457 |
+
}
|
| 1458 |
+
// @todo Delete rules with selectors for -amphtml- class and i-amphtml- tags.
|
| 1459 |
+
return $results;
|
| 1460 |
}
|
| 1461 |
|
| 1462 |
/**
|
| 1463 |
+
* Process @font-face by making src URLs non-relative and converting data: URLs into (assumed) file URLs.
|
| 1464 |
*
|
| 1465 |
+
* @since 1.0
|
| 1466 |
+
*
|
| 1467 |
+
* @param AtRuleSet $ruleset Ruleset for @font-face.
|
| 1468 |
+
*/
|
| 1469 |
+
private function process_font_face_at_rule( AtRuleSet $ruleset ) {
|
| 1470 |
+
$src_properties = $ruleset->getRules( 'src' );
|
| 1471 |
+
if ( empty( $src_properties ) ) {
|
| 1472 |
+
return;
|
| 1473 |
+
}
|
| 1474 |
+
|
| 1475 |
+
foreach ( $src_properties as $src_property ) {
|
| 1476 |
+
$value = $src_property->getValue();
|
| 1477 |
+
if ( ! ( $value instanceof RuleValueList ) ) {
|
| 1478 |
+
continue;
|
| 1479 |
+
}
|
| 1480 |
+
|
| 1481 |
+
/*
|
| 1482 |
+
* The CSS Parser parses a src such as:
|
| 1483 |
+
*
|
| 1484 |
+
* url(data:application/font-woff;...) format('woff'),
|
| 1485 |
+
* url('Genericons.ttf') format('truetype'),
|
| 1486 |
+
* url('Genericons.svg#genericonsregular') format('svg')
|
| 1487 |
+
*
|
| 1488 |
+
* As a list of components consisting of:
|
| 1489 |
+
*
|
| 1490 |
+
* URL,
|
| 1491 |
+
* RuleValueList( CSSFunction, URL ),
|
| 1492 |
+
* RuleValueList( CSSFunction, URL ),
|
| 1493 |
+
* CSSFunction
|
| 1494 |
+
*
|
| 1495 |
+
* Clearly the components here are not logically grouped. So the first step is to fix the order.
|
| 1496 |
+
*/
|
| 1497 |
+
$sources = array();
|
| 1498 |
+
foreach ( $value->getListComponents() as $component ) {
|
| 1499 |
+
if ( $component instanceof RuleValueList ) {
|
| 1500 |
+
$subcomponents = $component->getListComponents();
|
| 1501 |
+
$subcomponent = array_shift( $subcomponents );
|
| 1502 |
+
if ( $subcomponent ) {
|
| 1503 |
+
if ( empty( $sources ) ) {
|
| 1504 |
+
$sources[] = array( $subcomponent );
|
| 1505 |
+
} else {
|
| 1506 |
+
$sources[ count( $sources ) - 1 ][] = $subcomponent;
|
| 1507 |
+
}
|
| 1508 |
+
}
|
| 1509 |
+
foreach ( $subcomponents as $subcomponent ) {
|
| 1510 |
+
$sources[] = array( $subcomponent );
|
| 1511 |
+
}
|
| 1512 |
+
} else {
|
| 1513 |
+
if ( empty( $sources ) ) {
|
| 1514 |
+
$sources[] = array( $component );
|
| 1515 |
+
} else {
|
| 1516 |
+
$sources[ count( $sources ) - 1 ][] = $component;
|
| 1517 |
+
}
|
| 1518 |
+
}
|
| 1519 |
+
}
|
| 1520 |
+
|
| 1521 |
+
/**
|
| 1522 |
+
* Source URL lists.
|
| 1523 |
+
*
|
| 1524 |
+
* @var URL[] $source_file_urls
|
| 1525 |
+
* @var URL[] $source_data_urls
|
| 1526 |
+
*/
|
| 1527 |
+
$source_file_urls = array();
|
| 1528 |
+
$source_data_urls = array();
|
| 1529 |
+
foreach ( $sources as $i => $source ) {
|
| 1530 |
+
if ( $source[0] instanceof URL ) {
|
| 1531 |
+
if ( 'data:' === substr( $source[0]->getURL()->getString(), 0, 5 ) ) {
|
| 1532 |
+
$source_data_urls[ $i ] = $source[0];
|
| 1533 |
+
} else {
|
| 1534 |
+
$source_file_urls[ $i ] = $source[0];
|
| 1535 |
+
}
|
| 1536 |
+
}
|
| 1537 |
+
}
|
| 1538 |
+
|
| 1539 |
+
// Convert data: URLs into regular URLs, assuming there will be a file present (e.g. woff fonts in core themes).
|
| 1540 |
+
if ( empty( $source_file_urls ) ) {
|
| 1541 |
+
continue;
|
| 1542 |
+
}
|
| 1543 |
+
$source_file_url = current( $source_file_urls );
|
| 1544 |
+
foreach ( $source_data_urls as $i => $data_url ) {
|
| 1545 |
+
$mime_type = strtok( substr( $data_url->getURL()->getString(), 5 ), ';' );
|
| 1546 |
+
if ( ! $mime_type ) {
|
| 1547 |
+
continue;
|
| 1548 |
+
}
|
| 1549 |
+
$extension = preg_replace( ':.+/(.+-)?:', '', $mime_type );
|
| 1550 |
+
$guessed_url = preg_replace(
|
| 1551 |
+
':(?<=\.)\w+(\?.*)?(#.*)?$:', // Match the file extension in the URL.
|
| 1552 |
+
$extension,
|
| 1553 |
+
$source_file_url->getURL()->getString(),
|
| 1554 |
+
1,
|
| 1555 |
+
$count
|
| 1556 |
+
);
|
| 1557 |
+
if ( 1 !== $count ) {
|
| 1558 |
+
continue;
|
| 1559 |
+
}
|
| 1560 |
+
|
| 1561 |
+
// Ensure font file exists.
|
| 1562 |
+
$path = $this->get_validated_url_file_path( $guessed_url, array( 'woff', 'woff2', 'ttf', 'otf', 'svg' ) );
|
| 1563 |
+
if ( is_wp_error( $path ) ) {
|
| 1564 |
+
continue;
|
| 1565 |
+
}
|
| 1566 |
+
|
| 1567 |
+
$data_url->getURL()->setString( $guessed_url );
|
| 1568 |
+
break;
|
| 1569 |
+
}
|
| 1570 |
+
}
|
| 1571 |
+
}
|
| 1572 |
+
|
| 1573 |
+
/**
|
| 1574 |
+
* Process CSS keyframes.
|
| 1575 |
+
*
|
| 1576 |
+
* @since 1.0
|
| 1577 |
+
* @link https://www.ampproject.org/docs/design/responsive/style_pages#restricted-styles.
|
| 1578 |
+
* @link https://github.com/ampproject/amphtml/blob/b685a0780a7f59313666225478b2b79b463bcd0b/validator/validator-main.protoascii#L1002-L1043
|
| 1579 |
+
* @todo Tree shaking could be extended to keyframes, to omit a keyframe if it is not referenced by any rule.
|
| 1580 |
+
*
|
| 1581 |
+
* @param KeyFrame $css_list Ruleset.
|
| 1582 |
+
* @param array $options Options.
|
| 1583 |
+
* @return array Validation results.
|
| 1584 |
+
*/
|
| 1585 |
+
private function process_css_keyframes( KeyFrame $css_list, $options ) {
|
| 1586 |
+
$results = array();
|
| 1587 |
+
if ( ! empty( $options['property_whitelist'] ) ) {
|
| 1588 |
+
foreach ( $css_list->getContents() as $rules ) {
|
| 1589 |
+
if ( ! ( $rules instanceof DeclarationBlock ) ) {
|
| 1590 |
+
$error = array(
|
| 1591 |
+
'code' => 'unrecognized_css',
|
| 1592 |
+
'item' => get_class( $rules ),
|
| 1593 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1594 |
+
);
|
| 1595 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1596 |
+
if ( $sanitized ) {
|
| 1597 |
+
$css_list->remove( $rules );
|
| 1598 |
+
}
|
| 1599 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1600 |
+
continue;
|
| 1601 |
+
}
|
| 1602 |
+
|
| 1603 |
+
$results = array_merge(
|
| 1604 |
+
$results,
|
| 1605 |
+
$this->transform_important_qualifiers( $rules, $css_list )
|
| 1606 |
+
);
|
| 1607 |
+
|
| 1608 |
+
$properties = $rules->getRules();
|
| 1609 |
+
foreach ( $properties as $property ) {
|
| 1610 |
+
$vendorless_property_name = preg_replace( '/^-\w+-/', '', $property->getRule() );
|
| 1611 |
+
if ( ! in_array( $vendorless_property_name, $options['property_whitelist'], true ) ) {
|
| 1612 |
+
$error = array(
|
| 1613 |
+
'code' => 'illegal_css_property',
|
| 1614 |
+
'property_name' => $property->getRule(),
|
| 1615 |
+
'property_value' => (string) $property->getValue(),
|
| 1616 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1617 |
+
);
|
| 1618 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1619 |
+
if ( $sanitized ) {
|
| 1620 |
+
$rules->removeRule( $property->getRule() );
|
| 1621 |
+
}
|
| 1622 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1623 |
+
}
|
| 1624 |
+
}
|
| 1625 |
+
}
|
| 1626 |
+
}
|
| 1627 |
+
return $results;
|
| 1628 |
+
}
|
| 1629 |
+
|
| 1630 |
+
/**
|
| 1631 |
+
* Replace !important qualifiers with more specific rules.
|
| 1632 |
+
*
|
| 1633 |
+
* @since 1.0
|
| 1634 |
+
* @see https://www.npmjs.com/package/replace-important
|
| 1635 |
+
* @see https://www.ampproject.org/docs/fundamentals/spec#important
|
| 1636 |
+
*
|
| 1637 |
+
* @param RuleSet|DeclarationBlock $ruleset Rule set.
|
| 1638 |
+
* @param CSSList $css_list CSS List.
|
| 1639 |
+
* @return array Validation results.
|
| 1640 |
+
*/
|
| 1641 |
+
private function transform_important_qualifiers( RuleSet $ruleset, CSSList $css_list ) {
|
| 1642 |
+
$results = array();
|
| 1643 |
+
|
| 1644 |
+
// An !important only makes sense for rulesets that have selectors.
|
| 1645 |
+
$allow_transformation = (
|
| 1646 |
+
$ruleset instanceof DeclarationBlock
|
| 1647 |
+
&&
|
| 1648 |
+
! ( $css_list instanceof KeyFrame )
|
| 1649 |
+
);
|
| 1650 |
+
|
| 1651 |
+
$properties = $ruleset->getRules();
|
| 1652 |
+
$importants = array();
|
| 1653 |
+
foreach ( $properties as $property ) {
|
| 1654 |
+
if ( $property->getIsImportant() ) {
|
| 1655 |
+
if ( $allow_transformation ) {
|
| 1656 |
+
$importants[] = $property;
|
| 1657 |
+
$property->setIsImportant( false );
|
| 1658 |
+
$ruleset->removeRule( $property->getRule() );
|
| 1659 |
+
} else {
|
| 1660 |
+
$error = array(
|
| 1661 |
+
'code' => 'illegal_css_important',
|
| 1662 |
+
'type' => AMP_Validation_Error_Taxonomy::CSS_ERROR_TYPE,
|
| 1663 |
+
);
|
| 1664 |
+
$sanitized = $this->should_sanitize_validation_error( $error );
|
| 1665 |
+
if ( $sanitized ) {
|
| 1666 |
+
$property->setIsImportant( false );
|
| 1667 |
+
}
|
| 1668 |
+
$results[] = compact( 'error', 'sanitized' );
|
| 1669 |
+
}
|
| 1670 |
+
}
|
| 1671 |
+
}
|
| 1672 |
+
if ( ! $allow_transformation || empty( $importants ) ) {
|
| 1673 |
+
return $results;
|
| 1674 |
+
}
|
| 1675 |
+
|
| 1676 |
+
$important_ruleset = clone $ruleset;
|
| 1677 |
+
$important_ruleset->setSelectors( array_map(
|
| 1678 |
+
/**
|
| 1679 |
+
* Modify selectors to be more specific to roughly match the effect of !important.
|
| 1680 |
+
*
|
| 1681 |
+
* @link https://github.com/ampproject/ampstart/blob/4c21d69afdd07b4c60cd190937bda09901955829/tools/replace-important/lib/index.js#L88-L109
|
| 1682 |
+
*
|
| 1683 |
+
* @param Selector $old_selector Original selector.
|
| 1684 |
+
* @return Selector The new more-specific selector.
|
| 1685 |
+
*/
|
| 1686 |
+
function( Selector $old_selector ) {
|
| 1687 |
+
// Calculate the specificity multiplier for the placeholder.
|
| 1688 |
+
$specificity_multiplier = AMP_Style_Sanitizer::INLINE_SPECIFICITY_MULTIPLIER + 1 + floor( $old_selector->getSpecificity() / 100 );
|
| 1689 |
+
if ( $old_selector->getSpecificity() % 100 > 0 ) {
|
| 1690 |
+
$specificity_multiplier++;
|
| 1691 |
+
|
