Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

♻️ Migrate Style and DOM helpers into core/DOM + type-checking #34681

Merged
merged 28 commits into from
Jun 9, 2021

Conversation

rcebulko
Copy link
Contributor

@rcebulko rcebulko commented Jun 3, 2021

Part of #34096 and #32693
"real" diff: a0f19fb...5e6309c
Moves a bulk of DOM-related modules into core, makes type-checking pass, and modernizes some syntax

Moves the following files:

src/
- core/dom/weakref
- full-overlay-frame-helper
- dom
- style
- utils/
  - document-visibility
  - size-observer
  - static-template
  - video
  - pause-helper

Resulting structure:

ads/inabox/full-overlay-frame-helper
src/
- open-dialog-window
- assert-display
- amp-element-helpers
- core/
  - data-structures/dom-based-weakref
  - document-visibility
  - dom/
    - index
    - event.extern
    - size-observer
    - size-observer.extern
    - static-template
    - style
    - video/
      - index
      - pausable-interface
      - pause-helper
      - video.extern

Test files under test/unit/core mirror this structure

@rcebulko rcebulko changed the title ♻️ Migrate bulk of DOM helpers into core/DOM + type-checking ♻️ Migrate Style and DOM helpers into core/DOM + type-checking Jun 3, 2021
@rcebulko rcebulko force-pushed the core-style branch 2 times, most recently from 10606da to 46a6bc4 Compare June 3, 2021 19:55
@rcebulko rcebulko requested a review from jridgewell June 4, 2021 16:06
@rcebulko rcebulko marked this pull request as ready for review June 4, 2021 16:06
@amp-owners-bot
Copy link

amp-owners-bot bot commented Jun 4, 2021

Hey @erwinmombay! These files were changed:

build-system/eslint-rules/no-import-rename.js
build-system/eslint-rules/no-style-display.js
build-system/eslint-rules/query-selector.js

Hey @jridgewell! These files were changed:

build-system/eslint-rules/no-import-rename.js
build-system/eslint-rules/no-style-display.js
build-system/eslint-rules/query-selector.js
src/core/data-structures/dom-based-weakref.js
src/core/document-visibility.js
src/core/dom/event.extern.js
src/core/dom/index.js
src/core/dom/size-observer.js
src/core/dom/static-template.js
src/core/dom/style.js
src/core/dom/video/index.js
src/core/dom/video/pausable-interface.js
+2 more

Hey @alanorozco! These files were changed:

extensions/amp-3q-player/0.1/amp-3q-player.js
extensions/amp-3q-player/0.1/test/test-amp-3q-player.js
extensions/amp-brid-player/0.1/amp-brid-player.js
extensions/amp-connatix-player/0.1/amp-connatix-player.js
extensions/amp-delight-player/0.1/amp-delight-player.js
extensions/amp-kaltura-player/0.1/amp-kaltura-player.js
extensions/amp-minute-media-player/0.1/amp-minute-media-player.js
extensions/amp-nexxtv-player/0.1/amp-nexxtv-player.js
extensions/amp-nexxtv-player/0.1/test/test-amp-nexxtv-player.js
extensions/amp-o2-player/0.1/amp-o2-player.js
extensions/amp-ooyala-player/0.1/amp-ooyala-player.js
extensions/amp-powr-player/0.1/amp-powr-player.js
+5 more

Hey @Jiaming-X! These files were changed:

extensions/amp-ad-network-adsense-impl/0.1/amp-ad-network-adsense-impl.js
extensions/amp-ad-network-adsense-impl/0.1/responsive-state.js
extensions/amp-ad-network-adsense-impl/0.1/test/test-amp-ad-network-adsense-impl.js
extensions/amp-ad-network-adsense-impl/0.1/test/test-responsive-state.js

Hey @jeffkaufman! These files were changed:

extensions/amp-ad-network-adsense-impl/0.1/amp-ad-network-adsense-impl.js
extensions/amp-ad-network-adsense-impl/0.1/responsive-state.js
extensions/amp-ad-network-adsense-impl/0.1/test/test-amp-ad-network-adsense-impl.js
extensions/amp-ad-network-adsense-impl/0.1/test/test-responsive-state.js
extensions/amp-ad-network-doubleclick-impl/0.1/amp-ad-network-doubleclick-impl.js
extensions/amp-ad-network-doubleclick-impl/0.1/safeframe-host.js
extensions/amp-ad-network-doubleclick-impl/0.1/test/test-amp-ad-network-doubleclick-impl.js
extensions/amp-ad-network-doubleclick-impl/0.1/test/test-doubleclick-fluid.js
extensions/amp-ad-network-doubleclick-impl/0.1/test/test-doubleclick-rtc.js
extensions/amp-ad-network-doubleclick-impl/0.1/test/test-doubleclick-safeframe.js
extensions/amp-ad-network-doubleclick-impl/0.1/test/test-doubleclick-sra.js
extensions/amp-ad-network-doubleclick-impl/0.1/test/test-flexible-ad-slot-utils.js

Hey @gmajoulet! These files were changed:

extensions/amp-story-360/0.1/amp-story-360.js
extensions/amp-story-360/0.1/test/test-amp-story-360.js
extensions/amp-story-auto-analytics/0.1/amp-story-auto-analytics.js
extensions/amp-story-auto-analytics/0.1/test/test-amp-story-auto-analytics.js
extensions/amp-story-dev-tools/0.1/amp-story-dev-tools-tab-debug.js
extensions/amp-story-dev-tools/0.1/amp-story-dev-tools-tab-preview.js
extensions/amp-story-dev-tools/0.1/amp-story-dev-tools.js
extensions/amp-story-education/0.1/amp-story-education.js
extensions/amp-story-interactive/0.1/amp-story-interactive-binary-poll.js
extensions/amp-story-interactive/0.1/amp-story-interactive-poll.js
extensions/amp-story-interactive/0.1/amp-story-interactive-quiz.js
extensions/amp-story-interactive/0.1/amp-story-interactive-results.js
+46 more

Hey @processprocess! These files were changed:

extensions/amp-story-360/0.1/amp-story-360.js
extensions/amp-story-360/0.1/test/test-amp-story-360.js
extensions/amp-story-panning-media/0.1/amp-story-panning-media.js
extensions/amp-story-panning-media/0.1/test/test-amp-story-panning-media.js

Hey @t0mg! These files were changed:

extensions/amp-story-360/0.1/amp-story-360.js
extensions/amp-story-360/0.1/test/test-amp-story-360.js

Hey @mszylkowski! These files were changed:

extensions/amp-story-auto-analytics/0.1/amp-story-auto-analytics.js
extensions/amp-story-auto-analytics/0.1/test/test-amp-story-auto-analytics.js
extensions/amp-story-dev-tools/0.1/amp-story-dev-tools-tab-debug.js
extensions/amp-story-dev-tools/0.1/amp-story-dev-tools-tab-preview.js
extensions/amp-story-dev-tools/0.1/amp-story-dev-tools.js
extensions/amp-story-interactive/0.1/amp-story-interactive-binary-poll.js
extensions/amp-story-interactive/0.1/amp-story-interactive-poll.js
extensions/amp-story-interactive/0.1/amp-story-interactive-quiz.js
extensions/amp-story-interactive/0.1/amp-story-interactive-results.js
extensions/amp-story-interactive/0.1/interactive-confetti.js
extensions/amp-story-interactive/0.1/interactive-disclaimer.js
extensions/amp-story-interactive/0.1/test/test-amp-story-interactive.js

Hey @newmuis! These files were changed:

extensions/amp-story-panning-media/0.1/amp-story-panning-media.js
extensions/amp-story-panning-media/0.1/test/test-amp-story-panning-media.js
extensions/amp-story/1.0/amp-story-access.js
extensions/amp-story/1.0/amp-story-affiliate-link.js
extensions/amp-story/1.0/amp-story-consent.js
extensions/amp-story/1.0/amp-story-cta-layer.js
extensions/amp-story/1.0/amp-story-draggable-drawer.js
extensions/amp-story/1.0/amp-story-embedded-component.js
extensions/amp-story/1.0/amp-story-grid-layer.js
extensions/amp-story/1.0/amp-story-info-dialog.js
extensions/amp-story/1.0/amp-story-open-page-attachment.js
extensions/amp-story/1.0/amp-story-page-attachment.js
+31 more

@rcebulko rcebulko force-pushed the core-style branch 3 times, most recently from 3af1d99 to 27a8bb4 Compare June 7, 2021 19:38
@rcebulko
Copy link
Contributor Author

rcebulko commented Jun 7, 2021

@jridgewell building locally to verify, but I suspect the bundle-size diff is all Brotli noise
Edit: Confirmed locally that differences are negligible (Seems like the biggest diffs are ~0.04KB)

@rcebulko
Copy link
Contributor Author

rcebulko commented Jun 8, 2021

Because of how I did the move (temporarily had dom.js do export * from './core/dom';) GitHub isn't showing the diff between them. I've included the diff between below:

`main:src/dom.js` vs `pr:src/core/dom/index.js`
diff --git a/src/dom.js b/src/core/dom/index.js
index ee39dac4e..f766a3dd3 100644
--- a/src/dom.js
+++ b/src/core/dom/index.js
@@ -14,12 +14,9 @@
  * limitations under the License.
  */
 
-import {Deferred} from './core/data-structures/promise';
-import {dev, devAssert} from './log';
-import {dict} from './core/types/object';
-import {includes} from './core/types/string';
-import {matches} from './core/dom/query';
-import {toWin} from './core/window';
+import {dict} from '../types/object';
+import {matches} from './query';
+import {toWin} from '../window';
 
 const HTML_ESCAPE_CHARS = {
   '&': '&',
@@ -31,12 +28,6 @@ const HTML_ESCAPE_CHARS = {
 };
 const HTML_ESCAPE_REGEX = /(&|<|>|"|'|`)/g;
 
-/** @const {string} */
-export const UPGRADE_TO_CUSTOMELEMENT_PROMISE = '__AMP_UPG_PRM';
-
-/** @const {string} */
-export const UPGRADE_TO_CUSTOMELEMENT_RESOLVER = '__AMP_UPG_RES';
-
 /**
  * @typedef {{
  *   bubbles: (boolean|undefined),
@@ -54,17 +45,15 @@ const DEFAULT_CUSTOM_EVENT_OPTIONS = {bubbles: true, cancelable: true};
  * @param {!Element} parent
  * @param {function(!Element):boolean} checkFunc
  * @param {function()} callback
- * @suppress {suspiciousCode}
+ * @suppress {suspiciousCode} due to IS_ESM
  */
 export function waitForChild(parent, checkFunc, callback) {
   if (checkFunc(parent)) {
     callback();
     return;
   }
-  /** @const {!Window} */
   const win = toWin(parent.ownerDocument.defaultView);
   if (IS_ESM || win.MutationObserver) {
-    /** @const {MutationObserver} */
     const observer = new win.MutationObserver(() => {
       if (checkFunc(parent)) {
         observer.disconnect();
@@ -73,7 +62,6 @@ export function waitForChild(parent, checkFunc, callback) {
     });
     observer.observe(parent, {childList: true});
   } else {
-    /** @const {number} */
     const interval = win.setInterval(() => {
       if (checkFunc(parent)) {
         win.clearInterval(interval);
@@ -119,9 +107,7 @@ export function waitForBodyOpenPromise(doc) {
  * @param {!Element} element
  */
 export function removeElement(element) {
-  if (element.parentElement) {
-    element.parentElement.removeChild(element);
-  }
+  element.parentElement?.removeChild(element);
 }
 
 /**
@@ -247,7 +233,7 @@ export function rootNodeFor(node) {
 
 /**
  * Determines if value is actually a `ShadowRoot` node.
- * @param {HTMLElement} value
+ * @param {?HTMLElement} value
  * @return {boolean}
  */
 export function isShadowRoot(value) {
@@ -282,7 +268,7 @@ export function getDataParamsFromAttributes(
   const computeParamNameFunc = opt_computeParamNameFunc || ((key) => key);
   const {dataset} = element;
   const params = dict();
-  const paramPattern = opt_paramPattern ? opt_paramPattern : /^param(.+)/;
+  const paramPattern = opt_paramPattern || /^param(.+)/;
   for (const key in dataset) {
     const matches = key.match(paramPattern);
     if (matches) {
@@ -348,37 +334,6 @@ export function iterateCursor(iterable, cb) {
   }
 }
 
-/**
- * This method wraps around window's open method. It first tries to execute
- * `open` call with the provided target and if it fails, it retries the call
- * with the `_top` target. This is necessary given that in some embedding
- * scenarios, such as iOS' WKWebView, navigation to `_blank` and other targets
- * is blocked by default.
- *
- * @param {!Window} win
- * @param {string} url
- * @param {string} target
- * @param {string=} opt_features
- * @return {?Window}
- */
-export function openWindowDialog(win, url, target, opt_features) {
-  // Try first with the specified target. If we're inside the WKWebView or
-  // a similar environments, this method is expected to fail by default for
-  // all targets except `_top`.
-  let res;
-  try {
-    res = win.open(url, target, opt_features);
-  } catch (e) {
-    dev().error('DOM', 'Failed to open url on target: ', target, e);
-  }
-
-  // Then try with `_top` target.
-  if (!res && target != '_top' && !includes(opt_features || '', 'noopener')) {
-    res = win.open(url, '_top');
-  }
-  return res;
-}
-
 /**
  * Whether the element is a script tag with application/json type.
  * @param {!Element} element
@@ -387,8 +342,7 @@ export function openWindowDialog(win, url, target, opt_features) {
 export function isJsonScriptTag(element) {
   return (
     element.tagName == 'SCRIPT' &&
-    element.hasAttribute('type') &&
-    element.getAttribute('type').toUpperCase() == 'APPLICATION/JSON'
+    element.getAttribute('type')?.toUpperCase() == 'APPLICATION/JSON'
   );
 }
 
@@ -400,7 +354,7 @@ export function isJsonScriptTag(element) {
 export function isJsonLdScriptTag(element) {
   return (
     element.tagName == 'SCRIPT' &&
-    element.getAttribute('type').toUpperCase() == 'APPLICATION/LD+JSON'
+    element.getAttribute('type')?.toUpperCase() == 'APPLICATION/LD+JSON'
   );
 }
 
@@ -459,45 +413,6 @@ export function isIframed(win) {
   return win.parent && win.parent != win;
 }
 
-/**
- * Determines if this element is an AMP element
- * @param {!Element} element
- * @return {boolean}
- */
-export function isAmpElement(element) {
-  const tag = element.tagName;
-  // Use prefix to recognize AMP element. This is necessary because stub
-  // may not be attached yet.
-  return (
-    tag.startsWith('AMP-') &&
-    // Some "amp-*" elements are not really AMP elements. :smh:
-    !(tag == 'AMP-STICKY-AD-TOP-PADDING' || tag == 'AMP-BODY')
-  );
-}
-
-/**
- * Return a promise that resolve when an AMP element upgrade from HTMLElement
- * to CustomElement
- * @param {!HTMLElement} element
- * @return {!Promise<!AmpElement>}
- */
-export function whenUpgradedToCustomElement(element) {
-  devAssert(isAmpElement(element), 'element is not AmpElement');
-  if (element.createdCallback) {
-    // Element already is CustomElement;
-    return Promise.resolve(/**@type {!AmpElement} */ (element));
-  }
-  // If Element is still HTMLElement, wait for it to upgrade to customElement
-  // Note: use pure string to avoid obfuscation between versions.
-  if (!element[UPGRADE_TO_CUSTOMELEMENT_PROMISE]) {
-    const deferred = new Deferred();
-    element[UPGRADE_TO_CUSTOMELEMENT_PROMISE] = deferred.promise;
-    element[UPGRADE_TO_CUSTOMELEMENT_RESOLVER] = deferred.resolve;
-  }
-
-  return element[UPGRADE_TO_CUSTOMELEMENT_PROMISE];
-}
-
 /**
  * Returns true if node is not disabled.
  *
@@ -604,7 +519,7 @@ export function dispatchCustomEvent(node, name, opt_data, opt_options) {
   const event = node.ownerDocument.createEvent('Event');
 
   // Technically .data is not a property of Event.
-  /**@type {?}*/ (event).data = data;
+  event.data = data;
 
   const {bubbles, cancelable} = opt_options || DEFAULT_CUSTOM_EVENT_OPTIONS;
   event.initEvent(name, bubbles, cancelable);

@rcebulko
Copy link
Contributor Author

rcebulko commented Jun 9, 2021

@jridgewell bumping this

@samouri
Copy link
Member

samouri commented Jun 9, 2021

What is the reason for PausableInterface? Wasn't AmpElement more correct?

@rcebulko
Copy link
Contributor Author

rcebulko commented Jun 9, 2021

What is the reason for PausableInterface? Wasn't AmpElement more correct?

AMPElement doesn't exist yet in core, and it's possible this will be called with Bento elements or something else. PausableInterface is the minimal type contract we can specify here.

@rcebulko rcebulko requested a review from kristoferbaxter June 9, 2021 21:25
src/core/dom/video/pause-helper.js Outdated Show resolved Hide resolved
src/core/dom/size-observer.js Outdated Show resolved Hide resolved
@rcebulko rcebulko enabled auto-merge (squash) June 9, 2021 22:18
@rcebulko rcebulko merged commit dce1d79 into ampproject:main Jun 9, 2021
@rcebulko rcebulko deleted the core-style branch June 9, 2021 23:58
westonruter added a commit to westonruter/amphtml that referenced this pull request Jun 11, 2021
…ebook-like-bento-version

* 'main' of github.com:ampproject/amphtml:
  minor updates + fix broken links (ampproject#34840)
  Add "wrapper": "bento" option to Bento components (ampproject#34838)
  ♻️ Move src/layout into core to unblock buildDOM for amp-layout (ampproject#34818)
  ♿ Apply `lang="en"` to relevant snippets in `test/` (ampproject#34768)
  Bento: Enable `npm` for `amp-video` (ampproject#34822)
  ✨[story-ads] Introduce new yellow segment progress bar v2 (ampproject#34804)
  SwG Release (ampproject#34825)
  📦 Update build-system devDependencies to v7.14.5 (ampproject#34802)
  Disable viewport warnings in experiment. (ampproject#34809)
  Apply lang="en" to examples/ (ampproject#34759)
  ✨ [Amp story] Scaffold desktop one panel experiment (ampproject#34755)
  ♻️ Migrate Style and DOM helpers into core/DOM + type-checking (ampproject#34681)
  🏗 Don't pull all externs into experiments (ampproject#34800)
  typechecking: remove pride as not compatible with rest of strategy (ampproject#34787)
  Fix forbidden terms to unblock `main` (ampproject#34799)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants