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

fix a4a intersection observer #19838

Merged
merged 2 commits into from
Dec 17, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 14 additions & 13 deletions extensions/amp-a4a/0.1/refresh-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from './refresh-intersection-observer-wrapper';
import {Services} from '../../../src/services';
import {dev, user} from '../../../src/log';
import {dict} from '../../../src/utils/object';

/**
* - visibilePercentageMin: The percentage of pixels that need to be on screen
Expand Down Expand Up @@ -167,18 +168,18 @@ export function getRefreshManager(a4a, opt_predicate) {
if (!refreshInterval || (opt_predicate && !opt_predicate())) {
return null;
}
return new RefreshManager(a4a, {
visiblePercentageMin: 50,
continuousTimeMin: 1,
}, refreshInterval);
return new RefreshManager(a4a, dict({
'visiblePercentageMin': 50,
'continuousTimeMin': 1,
}), refreshInterval);
}


export class RefreshManager {

/**
* @param {!./amp-a4a.AmpA4A} a4a The AmpA4A instance to be refreshed.
* @param {!RefreshConfig} config
* @param {!JsonObject} config
* @param {number} refreshInterval
*/
constructor(a4a, config, refreshInterval) {
Expand All @@ -201,7 +202,7 @@ export class RefreshManager {
/** @const @private {?number} */
this.refreshInterval_ = refreshInterval;

/** @const @private {!RefreshConfig} */
/** @const @private {!JsonObject} */
this.config_ = this.convertAndSanitizeConfiguration_(config);

/** @const @private {!../../../src/service/timer-impl.Timer} */
Expand Down Expand Up @@ -260,20 +261,20 @@ export class RefreshManager {
// viewability conditions have been met, and we can begin the refresh
// timer.
if (entry.intersectionRatio >=
refreshManager.config_.visiblePercentageMin) {
refreshManager.config_['visiblePercentageMin']) {
refreshManager.state_ = RefreshLifecycleState.VIEW_PENDING;
refreshManager.visibilityTimeoutId_ = refreshManager.timer_.delay(
() => {
refreshManager.state_ = RefreshLifecycleState.REFRESH_PENDING;
refreshManager.startRefreshTimer_();
}, refreshManager.config_.continuousTimeMin);
}, refreshManager.config_['continuousTimeMin']);
}
break;
case RefreshLifecycleState.VIEW_PENDING:
// If the element goes off screen before the minimum on screen time
// duration elapses, place it back into INITIAL state.
if (entry.intersectionRatio <
refreshManager.config_.visiblePercentageMin) {
refreshManager.config_['visiblePercentageMin']) {
refreshManager.timer_.cancel(refreshManager.visibilityTimeoutId_);
refreshManager.visibilityTimeoutId_ = null;
refreshManager.state_ = RefreshLifecycleState.INITIAL;
Expand All @@ -294,7 +295,7 @@ export class RefreshManager {
switch (this.state_) {
case RefreshLifecycleState.INITIAL:
this.getIntersectionObserverWithThreshold_(
this.config_.visiblePercentageMin).observe(this.element_);
this.config_['visiblePercentageMin']).observe(this.element_);
break;
case RefreshLifecycleState.REFRESH_PENDING:
case RefreshLifecycleState.VIEW_PENDING:
Expand Down Expand Up @@ -324,8 +325,8 @@ export class RefreshManager {
/**
* Converts config to appropriate units, modifying the argument in place. This
* also ensures that visiblePercentageMin is in the range of [0, 100].
* @param {!RefreshConfig} config
* @return {!RefreshConfig}
* @param {!JsonObject} config
* @return {!JsonObject}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erwinmombay I have one question, instead of returning a JsonObject, can we keep the RefreshConfig defination, but have the convertAndSanitizeConfiguration_ returns an object like

{
  continousTimeMin: config['continuousTimeMin']*1000,
  ...
}

I don't feel that the namespace continousTimeMin and visiblePercentageMin is useful after the read. WDYT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im ok with that for the most part.

just a thought though, using refreshconfig here, somebody is going to get tripped up again i think at some point. having a typedef does not mean closure will preserve the key values, and "configurations" almost always crosses these boundaries (xhr, html, postmessage, iframe) and the other side is going to get garbled obfuscated keys.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

somebody is going to get tripped up again i think at some point

I completely agree. I think this is a tradeoff between code size and style. Given this purely lives within extension code, I believe you're right to go with style.

i think at some point. having a typedef does not mean closure will preserve the key values

Thought typedef is more about type checking. If we move to JsonObject, is there a way to enforce type later?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought typedef is more about type checking. If we move to JsonObject, is there a way to enforce type later?

This is why JsonObject should be used at the boundaries and types/typedefs everywhere else. unfortunately, its a little hard for me to interpret this much code so its easier for me to just JsonObject everything so that I don't make a mistake.

I completely agree. I think this is a tradeoff between code size and style. Given this purely lives within extension code, I believe you're right to go with style.

did you mean you are OK with what I did, or do you prefer that i try to keep the typedef's ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked offline. We agreed it's safest to use JsonObject for extern config at this point. I'll need to figure something out in the future. A read/write method that handle externs, that could be difficult to enforce.

Anyhow this is something that needs further discussion. To fix the current issue, the PR looks good to me.

*/
convertAndSanitizeConfiguration_(config) {
dev().assert(config['visiblePercentageMin'] >= 0 &&
Expand All @@ -342,7 +343,7 @@ export class RefreshManager {
*/
unobserve() {
this.getIntersectionObserverWithThreshold_(
this.config_.visiblePercentageMin).unobserve(this.element_);
this.config_['visiblePercentageMin']).unobserve(this.element_);
}
}