diff --git a/build-system/compile/bundles.config.js b/build-system/compile/bundles.config.js index c8a090983287..62e520868734 100644 --- a/build-system/compile/bundles.config.js +++ b/build-system/compile/bundles.config.js @@ -27,7 +27,7 @@ const {VERSION: internalRuntimeVersion} = require('./internal-version'); exports.jsBundles = { 'polyfills.js': { srcDir: './src/', - srcFilename: 'polyfills.js', + srcFilename: 'polyfills/index.js', destDir: './build/', minifiedDestDir: './build/', }, diff --git a/build-system/compile/compile.js b/build-system/compile/compile.js index 577f4622ebf6..b548916a71d1 100644 --- a/build-system/compile/compile.js +++ b/build-system/compile/compile.js @@ -154,13 +154,13 @@ function getSrcs(entryModuleFilenames, outputDir, outputFilename, options) { // this works fine. if (options.includePolyfills) { srcs.push( - '!build/fake-module/src/polyfills.js', + '!build/fake-module/src/polyfills/index.js', '!build/fake-module/src/polyfills/**/*.js', '!build/fake-polyfills/**/*.js' ); } else { - srcs.push('!src/polyfills.js', '!build/fake-polyfills/**/*.js'); - unneededFiles.push('build/fake-module/src/polyfills.js'); + srcs.push('!src/polyfills/index.js', '!build/fake-polyfills/**/*.js'); + unneededFiles.push('build/fake-module/src/polyfills/index.js'); } // Negative globstars must come at the end. srcs.push( @@ -248,7 +248,7 @@ function generateCompilerOptions(outputDir, outputFilename, options) { language_out: argv.esm || argv.sxg ? 'NO_TRANSPILE' : 'ECMASCRIPT5_STRICT', // We do not use the polyfills provided by closure compiler. // If you need a polyfill. Manually include them in the - // respective top level polyfills.js files. + // respective top level polyfills/*.js files. rewrite_polyfills: false, externs, js_module_root: [ diff --git a/build-system/tasks/check-sourcemaps.js b/build-system/tasks/check-sourcemaps.js index 991500d9fc7d..22eb66d0c5a3 100644 --- a/build-system/tasks/check-sourcemaps.js +++ b/build-system/tasks/check-sourcemaps.js @@ -110,9 +110,9 @@ function checkSourcemapSources(sourcemapJson, map) { * Performs a sanity check on the mappings field in the sourcemap file. * * Today, the first line of amp.js after resolving imports comes from - * src/polyfills/array-includes.js. (The import chain is src/amp.js -> src/polyfills.js - * -> src/polyfills/array-includes.js.) This sequence changes rarely, so we can - * use it as a sentinel value. Here is the process: + * src/polyfills/array-includes.js. (The import chain is src/amp.js -> + * src/polyfills/index.js -> src/polyfills/array-includes.js.) This sequence + * changes rarely, so we can use it as a sentinel value. Here is the process: * * 1. Decode the 'mappings' field into a 3d array using 'sourcemap-codec'. * 2. Extract the mapping for the first line of code in minified v0.js. diff --git a/build-system/test-configs/dep-check-config.js b/build-system/test-configs/dep-check-config.js index 513ee7880541..66ffd427fc08 100644 --- a/build-system/test-configs/dep-check-config.js +++ b/build-system/test-configs/dep-check-config.js @@ -434,30 +434,6 @@ exports.rules = [ filesMatching: 'extensions/**/*.js', mustNotDependOn: 'src/base-element.js', }, - { - filesMatching: 'src/polyfills/*.js', - mustNotDependOn: '**/*.js', - allowlist: [ - 'src/polyfills/fetch.js->src/log.js', - 'src/polyfills/fetch.js->src/json.js', - 'src/polyfills/fetch.js->src/core/types/index.js', - 'src/polyfills/fetch.js->src/core/types/object.js', - 'src/polyfills/fetch.js->src/utils/bytes.js', - 'src/polyfills/intersection-observer.js->src/polyfills/stubs/intersection-observer-stub.js', - 'src/polyfills/resize-observer.js->src/polyfills/stubs/resize-observer-stub.js', - 'src/polyfills/custom-elements.js->src/core/data-structures/promise.js', - ], - }, - { - filesMatching: 'src/polyfills/stubs/**/*.js', - mustNotDependOn: '**/*.js', - allowlist: [ - 'src/polyfills/stubs/intersection-observer-stub.js->src/services.js', - 'src/polyfills/stubs/intersection-observer-stub.js->src/core/data-structures/promise.js', - 'src/polyfills/stubs/resize-observer-stub.js->src/services.js', - 'src/polyfills/stubs/resize-observer-stub.js->src/core/data-structures/promise.js', - ], - }, { filesMatching: '**/*.js', mustNotDependOn: 'src/polyfills/*.js', @@ -468,22 +444,24 @@ exports.rules = [ '3p/polyfills.js->src/polyfills/object-values.js', '3p/polyfills.js->src/polyfills/promise.js', '3p/polyfills.js->src/polyfills/string-starts-with.js', - 'src/polyfills.js->src/polyfills/abort-controller.js', - 'src/polyfills.js->src/polyfills/domtokenlist.js', - 'src/polyfills.js->src/polyfills/document-contains.js', - 'src/polyfills.js->src/polyfills/fetch.js', - 'src/polyfills.js->src/polyfills/math-sign.js', - 'src/polyfills.js->src/polyfills/object-assign.js', - 'src/polyfills.js->src/polyfills/object-values.js', - 'src/polyfills.js->src/polyfills/promise.js', - 'src/polyfills.js->src/polyfills/array-includes.js', - 'src/polyfills.js->src/polyfills/string-starts-with.js', - 'src/polyfills.js->src/polyfills/custom-elements.js', - 'src/polyfills.js->src/polyfills/intersection-observer.js', - 'src/polyfills.js->src/polyfills/resize-observer.js', - 'src/polyfills.js->src/polyfills/map-set.js', - 'src/polyfills.js->src/polyfills/set-add.js', - 'src/polyfills.js->src/polyfills/weakmap-set.js', + 'src/amp.js->src/polyfills/index.js', + 'src/polyfills/index.js->src/polyfills/abort-controller.js', + 'src/polyfills/index.js->src/polyfills/domtokenlist.js', + 'src/polyfills/index.js->src/polyfills/document-contains.js', + 'src/polyfills/index.js->src/polyfills/fetch.js', + 'src/polyfills/index.js->src/polyfills/get-bounding-client-rect.js', + 'src/polyfills/index.js->src/polyfills/math-sign.js', + 'src/polyfills/index.js->src/polyfills/object-assign.js', + 'src/polyfills/index.js->src/polyfills/object-values.js', + 'src/polyfills/index.js->src/polyfills/promise.js', + 'src/polyfills/index.js->src/polyfills/array-includes.js', + 'src/polyfills/index.js->src/polyfills/string-starts-with.js', + 'src/polyfills/index.js->src/polyfills/custom-elements.js', + 'src/polyfills/index.js->src/polyfills/intersection-observer.js', + 'src/polyfills/index.js->src/polyfills/resize-observer.js', + 'src/polyfills/index.js->src/polyfills/map-set.js', + 'src/polyfills/index.js->src/polyfills/set-add.js', + 'src/polyfills/index.js->src/polyfills/weakmap-set.js', 'src/friendly-iframe-embed.js->src/polyfills/abort-controller.js', 'src/friendly-iframe-embed.js->src/polyfills/custom-elements.js', 'src/friendly-iframe-embed.js->src/polyfills/document-contains.js', @@ -494,8 +472,8 @@ exports.rules = [ }, { filesMatching: '**/*.js', - mustNotDependOn: 'src/polyfills.js', - allowlist: ['src/amp.js->src/polyfills.js'], + mustNotDependOn: 'src/polyfills/index.js', + allowlist: ['src/amp.js->src/polyfills/index.js'], }, // Rules for main src. diff --git a/build-system/test-configs/forbidden-terms.js b/build-system/test-configs/forbidden-terms.js index 523554b5e4ad..760d1ba661d2 100644 --- a/build-system/test-configs/forbidden-terms.js +++ b/build-system/test-configs/forbidden-terms.js @@ -949,8 +949,7 @@ const forbiddenTermsSrcInclusive = { message: bannedTermsHelpString, allowlist: [ 'src/friendly-iframe-embed.js', - 'src/polyfills/stubs/intersection-observer-stub.js', - 'src/polyfills/stubs/resize-observer-stub.js', + 'src/runtime.js', 'src/service/extensions-impl.js', 'src/service/crypto-impl.js', ], diff --git a/extensions/amp-access/0.1/iframe-api/rollup.config.js b/extensions/amp-access/0.1/iframe-api/rollup.config.js index b24997ba2ef4..4e8f618f7197 100644 --- a/extensions/amp-access/0.1/iframe-api/rollup.config.js +++ b/extensions/amp-access/0.1/iframe-api/rollup.config.js @@ -33,5 +33,5 @@ export default { }), cleanup(), ], - external: [path.resolve('../../../../src/polyfills.js')], + external: [path.resolve('../../../../src/polyfills/index.js')], }; diff --git a/src/.eslintrc.js b/src/.eslintrc.js index 0f226b8aafe0..e9e92d11580d 100644 --- a/src/.eslintrc.js +++ b/src/.eslintrc.js @@ -42,6 +42,12 @@ module.exports = { 'from': 'src', 'except': ['./core', './context'], }, + { + // Disallow importing non-core dependencies into polyfills + 'target': 'src/polyfills', + 'from': 'src', + 'except': ['./core', './polyfills'], + }, ], }, ], @@ -54,6 +60,8 @@ module.exports = { './preact/base-element.js', './preact/slot.js', './context/node.js', + './polyfills/fetch.js', + './polyfills/get-bounding-client-rect.js', // TEMPORARY, follow tracking issue #33631 './preact/component/3p-frame.js', ], diff --git a/src/get-bounding-client-rect.js b/src/polyfills/get-bounding-client-rect.js similarity index 95% rename from src/get-bounding-client-rect.js rename to src/polyfills/get-bounding-client-rect.js index cbbd1c20c132..e26115024752 100644 --- a/src/get-bounding-client-rect.js +++ b/src/polyfills/get-bounding-client-rect.js @@ -21,8 +21,8 @@ * @see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/106812/ */ -import {LayoutRectDef, layoutRectLtwh} from './layout-rect'; -import {isConnectedNode} from './dom'; +import {LayoutRectDef, layoutRectLtwh} from '../layout-rect'; +import {isConnectedNode} from '../dom'; /** * Stores the native getBoundingClientRect before we patch it, so that the diff --git a/src/polyfills.js b/src/polyfills/index.js similarity index 55% rename from src/polyfills.js rename to src/polyfills/index.js index 60f50edd4b1f..e903bac80204 100644 --- a/src/polyfills.js +++ b/src/polyfills/index.js @@ -14,25 +14,25 @@ * limitations under the License. */ -/** @fileoverview */ +/** @fileoverview Installs polyfills depending on build environment. */ -import {install as installAbortController} from './polyfills/abort-controller'; -import {install as installArrayIncludes} from './polyfills/array-includes'; -import {install as installCustomElements} from './polyfills/custom-elements'; -import {install as installDOMTokenList} from './polyfills/domtokenlist'; -import {install as installDocContains} from './polyfills/document-contains'; -import {install as installFetch} from './polyfills/fetch'; +import {install as installAbortController} from './abort-controller'; +import {install as installArrayIncludes} from './array-includes'; +import {install as installCustomElements} from './custom-elements'; +import {install as installDOMTokenList} from './domtokenlist'; +import {install as installDocContains} from './document-contains'; +import {install as installFetch} from './fetch'; import {install as installGetBoundingClientRect} from './get-bounding-client-rect'; -import {install as installIntersectionObserver} from './polyfills/intersection-observer'; -import {install as installMapSet} from './polyfills/map-set'; -import {install as installMathSign} from './polyfills/math-sign'; -import {install as installObjectAssign} from './polyfills/object-assign'; -import {install as installObjectValues} from './polyfills/object-values'; -import {install as installPromise} from './polyfills/promise'; -import {install as installResizeObserver} from './polyfills/resize-observer'; -import {install as installSetAdd} from './polyfills/set-add'; -import {install as installStringStartsWith} from './polyfills/string-starts-with'; -import {install as installWeakMapSet} from './polyfills/weakmap-set'; +import {install as installIntersectionObserver} from './intersection-observer'; +import {install as installMapSet} from './map-set'; +import {install as installMathSign} from './math-sign'; +import {install as installObjectAssign} from './object-assign'; +import {install as installObjectValues} from './object-values'; +import {install as installPromise} from './promise'; +import {install as installResizeObserver} from './resize-observer'; +import {install as installSetAdd} from './set-add'; +import {install as installStringStartsWith} from './string-starts-with'; +import {install as installWeakMapSet} from './weakmap-set'; if (!IS_ESM) { installFetch(self); diff --git a/src/polyfills/intersection-observer.js b/src/polyfills/intersection-observer.js index 431ab69de319..6268ac8b0c8e 100644 --- a/src/polyfills/intersection-observer.js +++ b/src/polyfills/intersection-observer.js @@ -22,7 +22,7 @@ import { installStub, shouldLoadPolyfill, -} from '../polyfills/stubs/intersection-observer-stub'; +} from './stubs/intersection-observer-stub'; /** * Installs the IntersectionObserver polyfill. There are a few different modes of operation. diff --git a/src/polyfills/resize-observer.js b/src/polyfills/resize-observer.js index 02a78998ff8e..795b68b9b534 100644 --- a/src/polyfills/resize-observer.js +++ b/src/polyfills/resize-observer.js @@ -19,10 +19,7 @@ * See https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver */ -import { - installStub, - shouldLoadPolyfill, -} from '../polyfills/stubs/resize-observer-stub'; +import {installStub, shouldLoadPolyfill} from './stubs/resize-observer-stub'; /** * Installs the ResizeObserver polyfill. There are a few different modes of diff --git a/src/polyfills/stubs/intersection-observer-stub.js b/src/polyfills/stubs/intersection-observer-stub.js index 480ab580437c..baca8160e620 100644 --- a/src/polyfills/stubs/intersection-observer-stub.js +++ b/src/polyfills/stubs/intersection-observer-stub.js @@ -23,8 +23,6 @@ * amp-intersection-observer-polyfill extension. */ -import {Services} from '../../services'; - const UPGRADERS = '_upgraders'; const NATIVE = '_native'; const STUB = '_stub'; @@ -110,17 +108,6 @@ export function supportsDocumentRoot(win) { } } -/** - * @param {!Window} win - */ -export function scheduleUpgradeIfNeeded(win) { - if (shouldLoadPolyfill(win)) { - Services.extensionsFor(win).preloadExtension( - 'amp-intersection-observer-polyfill' - ); - } -} - /** * @param {!Window} win * @param {function()} installer diff --git a/src/polyfills/stubs/resize-observer-stub.js b/src/polyfills/stubs/resize-observer-stub.js index b18289ddcfbe..d7631ad091d3 100644 --- a/src/polyfills/stubs/resize-observer-stub.js +++ b/src/polyfills/stubs/resize-observer-stub.js @@ -23,8 +23,6 @@ * amp-resize-observer-polyfill extension. */ -import {Services} from '../../services'; - const UPGRADERS = '_upgraders'; const STUB = '_stub'; @@ -51,17 +49,6 @@ export function installStub(win) { win.ResizeObserver[STUB] = ResizeObserverStub; } -/** - * @param {!Window} win - */ -export function scheduleUpgradeIfNeeded(win) { - if (shouldLoadPolyfill(win)) { - Services.extensionsFor(win).preloadExtension( - 'amp-resize-observer-polyfill' - ); - } -} - /** * @param {!Window} win * @param {function()} installer diff --git a/src/runtime.js b/src/runtime.js index 0a93e2640d18..7da2ca1d4bc1 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -40,9 +40,9 @@ import { import {internalRuntimeVersion} from './internal-version'; import {isExperimentOn, toggleExperiment} from './experiments'; import {reportErrorForWin} from './error-reporting'; -import {scheduleUpgradeIfNeeded as scheduleInObUpgradeIfNeeded} from './polyfills/stubs/intersection-observer-stub'; -import {scheduleUpgradeIfNeeded as scheduleResObUpgradeIfNeeded} from './polyfills/stubs/resize-observer-stub'; import {setStyle} from './style'; +import {shouldLoadPolyfill as shouldLoadInObPolyfill} from './polyfills/stubs/intersection-observer-stub'; +import {shouldLoadPolyfill as shouldLoadResObPolyfill} from './polyfills/stubs/resize-observer-stub'; import {startupChunk} from './chunk'; import {stubElementsForDoc} from './service/custom-element-registry'; import {waitForBodyOpenPromise} from './dom'; @@ -262,8 +262,13 @@ function adoptShared(global, callback) { } // Some deferred polyfills. - scheduleInObUpgradeIfNeeded(global); - scheduleResObUpgradeIfNeeded(global); + const extensionsFor = Services.extensionsFor(global); + if (shouldLoadResObPolyfill(global)) { + extensionsFor.preloadExtension('amp-resize-observer-polyfill'); + } + if (shouldLoadInObPolyfill(global)) { + extensionsFor.preloadExtension('amp-intersection-observer-polyfill'); + } return iniPromise; }