Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 7 additions & 115 deletions extensions/amp-analytics/0.1/amp-analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@
* limitations under the License.
*/

import {Activity} from './activity-impl';
import {AnalyticsConfig, mergeObjects} from './config';
import {AnalyticsEventType} from './events';
import {ChunkPriority, chunk} from '../../../src/chunk';
import {CookieWriter} from './cookie-writer';
import {Deferred} from '../../../src/utils/promise';
import {
ExpansionOptions,
Expand All @@ -31,19 +28,14 @@ import {
instrumentationServicePromiseForDoc,
} from './instrumentation';
import {LayoutPriority} from '../../../src/layout';
import {LinkerManager} from './linker-manager';
import {RequestHandler, expandPostMessage} from './requests';
import {Services} from '../../../src/services';
import {Transport} from './transport';
import {dev, devAssert, rethrowAsync, user} from '../../../src/log';
import {dict, hasOwn} from '../../../src/utils/object';
import {expandTemplate} from '../../../src/string';
import {getMode} from '../../../src/mode';
import {installLinkerReaderService} from './linker-reader';
import {isArray, isEnumValue} from '../../../src/types';
import {isExperimentOn} from '../../../src/experiments';
import {isIframed} from '../../../src/dom';
import {isInFie} from '../../../src/iframe-helper';
import {toggle} from '../../../src/style';

const TAG = 'amp-analytics';
Expand All @@ -58,16 +50,7 @@ const WHITELIST_EVENT_IN_SANDBOX = [
export class AmpAnalytics extends AMP.BaseElement {
/** @param {!AmpElement} element */
constructor(element) {
super(element);

/** @private {!Promise} */
this.consentPromise_ = Promise.resolve();

/**
* The html id of the `amp-user-notification` element.
* @private {?string}
*/
this.consentNotificationId_ = null;
super(element)

/** @private {boolean} */
this.isSandbox_ = false;
Expand Down Expand Up @@ -99,26 +82,17 @@ export class AmpAnalytics extends AMP.BaseElement {

/** @private {./transport.Transport} */
this.transport_ = null;

/** @private {boolean} */
this.isInabox_ = getMode(this.win).runtime == 'inabox';

/** @private {?./linker-manager.LinkerManager} */
this.linkerManager_ = null;

/** @private {?boolean} */
this.isInFie_ = null;
}

/** @override */
getLayoutPriority() {
// Load immediately if inabox, otherwise after other content.
return this.isInabox_ ? LayoutPriority.CONTENT : LayoutPriority.METADATA;
return LayoutPriority.CONTENT;
}

/** @override */
isAlwaysFixed() {
return !isInFie(this.element);
return true
}

/** @override */
Expand All @@ -132,28 +106,7 @@ export class AmpAnalytics extends AMP.BaseElement {

this.element.setAttribute('aria-hidden', 'true');

this.consentNotificationId_ = this.element.getAttribute(
'data-consent-notification-id'
);

if (this.consentNotificationId_ != null) {
this.consentPromise_ = Services.userNotificationManagerForDoc(
this.element
).then((service) =>
service.get(dev().assertString(this.consentNotificationId_))
);
}

if (this.element.getAttribute('trigger') == 'immediate') {
this.ensureInitialized_();
}
}

/** @override */
layoutCallback() {
// Now that we are rendered, stop rendering the element to reduce
// resource consumption.
return this.ensureInitialized_();
this.ensureInitialized_();
}

/** @override */
Expand All @@ -163,26 +116,12 @@ export class AmpAnalytics extends AMP.BaseElement {
this.analyticsGroup_ = null;
}

if (this.linkerManager_) {
this.linkerManager_.dispose();
this.linkerManager_ = null;
}

for (const request in this.requests_) {
this.requests_[request].dispose();
delete this.requests_[request];
}
}

/** @override */
resumeCallback() {
if (this.iniPromise_) {
this.iniPromise_.then(() => {
this.transport_.maybeInitIframeTransport(this.element);
});
}
}

/** @override */
unlayoutCallback() {
if (this.getAmpDoc().isVisible()) {
Expand Down Expand Up @@ -231,26 +170,16 @@ export class AmpAnalytics extends AMP.BaseElement {
const configPromise = new AnalyticsConfig(this.element).loadConfig();
loadConfigDeferred.resolve(configPromise);
};
if (isExperimentOn(this.win, 'analytics-chunks') && !this.isInabox_) {
chunk(this.element, loadConfigTask, ChunkPriority.HIGH);
} else {
loadConfigTask();
}
loadConfigTask();
return loadConfigDeferred.promise;
})
.then((config) => {
this.config_ = /** @type {!JsonObject} */ (config);
// CookieWriter not enabled on proxy origin, do not chunk
return new CookieWriter(this.win, this.element, this.config_).write();
})
.then(() => {
this.transport_ = new Transport(
this.win,
this.config_['transport'] || {}
);
})
.then(this.registerTriggers_.bind(this))
.then(this.initializeLinker_.bind(this));
return this.iniPromise_;
}

Expand All @@ -262,13 +191,7 @@ export class AmpAnalytics extends AMP.BaseElement {
* @private
*/
allowParentPostMessage_() {
if (this.isInabox_) {
return true;
}
if (this.isInFie_ == null) {
this.isInFie_ = isInFie(this.element);
}
return this.isInFie_;
return true;
}

/**
Expand Down Expand Up @@ -305,8 +228,6 @@ export class AmpAnalytics extends AMP.BaseElement {
this.element
);

this.transport_.maybeInitIframeTransport(this.element);

const promises = [];
// Trigger callback can be synchronous. Do the registration at the end.
for (const k in this.config_['triggers']) {
Expand Down Expand Up @@ -567,29 +488,6 @@ export class AmpAnalytics extends AMP.BaseElement {
}
}

/**
* Create the linker-manager that will append linker params as necessary.
* The initialization is asynchronous and non blocking
* @private
*/
initializeLinker_() {
const type = this.element.getAttribute('type');
this.linkerManager_ = new LinkerManager(
this.getAmpDoc(),
this.config_,
type,
this.element
);
const linkerTask = () => {
this.linkerManager_.init();
};
if (isExperimentOn(this.win, 'analytics-chunks') && !this.isInabox_) {
chunk(this.element, linkerTask, ChunkPriority.LOW);
} else {
linkerTask();
}
}

/**
* Callback for events that are registered by the config's triggers. This
* method generates requests and sends them out.
Expand Down Expand Up @@ -720,11 +618,7 @@ export class AmpAnalytics extends AMP.BaseElement {
.then((digest) => digest * 100 < threshold);
sampleDeferred.resolve(samplePromise);
};
if (isExperimentOn(this.win, 'analytics-chunks') && !this.isInabox_) {
chunk(this.element, sampleInTask, ChunkPriority.LOW);
} else {
sampleInTask();
}
sampleInTask();
return sampleDeferred.promise;
}
user()./*OK*/ error(TAG, 'Invalid threshold for sampling.');
Expand Down Expand Up @@ -836,8 +730,6 @@ AMP.extension(TAG, '0.1', (AMP) => {
'amp-analytics-instrumentation',
InstrumentationService
);
AMP.registerServiceForDoc('activity', Activity);
installLinkerReaderService(AMP.win);
AMP.registerServiceForDoc('amp-analytics-variables', VariableService);
// Register the element.
AMP.registerElement(TAG, AmpAnalytics);
Expand Down
28 changes: 1 addition & 27 deletions extensions/amp-analytics/0.1/analytics-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,11 @@
* limitations under the License.
*/

import {ChunkPriority, chunk} from '../../../src/chunk';
import {Deferred} from '../../../src/utils/promise';
import {dev, userAssert} from '../../../src/log';
import {getMode} from '../../../src/mode';
import {getTrackerKeyName, getTrackerTypesForParentType} from './events';
import {isExperimentOn} from '../../../src/experiments';
import {toWin} from '../../../src/types';

/**
* @const {number}
* We want to execute the first trigger immediately to reduce the viewability
* delay as much as possible.
*/
const IMMEDIATE_TRIGGER_THRES = 1;

/** @const {number} */
const HIGH_PRIORITY_TRIGGER_THRES = 3;

/**
* Represents the group of analytics triggers for a single config. All triggers
* are declared and released at the same time.
Expand Down Expand Up @@ -104,20 +91,7 @@ export class AnalyticsGroup {
this.listeners_.push(unlisten);
deferred.resolve();
};
if (
this.triggerCount_ < IMMEDIATE_TRIGGER_THRES ||
!isExperimentOn(this.win_, 'analytics-chunks') ||
getMode(this.win_).runtime == 'inabox'
) {
task();
} else {
const priority =
this.triggerCount_ < HIGH_PRIORITY_TRIGGER_THRES
? ChunkPriority.HIGH
: ChunkPriority.LOW;
chunk(this.analyticsElement_, task, priority);
}
this.triggerCount_++;
task();
return deferred.promise;
}
}
66 changes: 1 addition & 65 deletions extensions/amp-analytics/0.1/analytics-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
* limitations under the License.
*/

import {HostServices} from '../../../src/inabox/host-services';
import {ScrollManager} from './scroll-manager';
import {Services} from '../../../src/services';
import {VisibilityManagerForMApp} from './visibility-manager-for-mapp';
import {
closestAncestorElementBySelector,
matches,
Expand Down Expand Up @@ -60,46 +57,8 @@ export class AnalyticsRoot {

/** @private {?./scroll-manager.ScrollManager} */
this.scrollManager_ = null;

/** @private {?Promise} */
this.usingHostAPIPromise_ = null;

/** @private {?../../../src/inabox/host-services.VisibilityInterface} */
this.hostVisibilityService_ = null;
}

/**
* @return {!Promise<boolean>}
*/
isUsingHostAPI() {
if (this.usingHostAPIPromise_) {
return this.usingHostAPIPromise_;
}
if (!HostServices.isAvailable(this.ampdoc)) {
this.usingHostAPIPromise_ = Promise.resolve(false);
} else {
// TODO: Using the visibility service and apply it for all tracking types
const promise = HostServices.visibilityForDoc(this.ampdoc);
this.usingHostAPIPromise_ = promise
.then((visibilityService) => {
this.hostVisibilityService_ = visibilityService;
return true;
})
.catch((error) => {
dev().fine(
TAG,
'VisibilityServiceError - fallback=' + error.fallback
);
if (error.fallback) {
// Do not use HostAPI, fallback to original implementation.
return false;
}
// Cannot fallback, service error. Throw user error.
throw user().createError('Host Visibility Service Error');
});
}
return this.usingHostAPIPromise_;
}

/** @override */
dispose() {
Expand Down Expand Up @@ -461,33 +420,10 @@ export class AnalyticsRoot {
*/
getVisibilityManager() {
if (!this.visibilityManager_) {
if (this.hostVisibilityService_) {
// If there is hostAPI (hostAPI never exist with the FIE case)
this.visibilityManager_ = new VisibilityManagerForMApp(
this.ampdoc,
this.hostVisibilityService_
);
} else {
this.visibilityManager_ = provideVisibilityManager(this.getRoot());
}
this.visibilityManager_ = provideVisibilityManager(this.getRoot());
}
return this.visibilityManager_;
}

/**
* Returns the Scroll Managet corresponding to this analytics root.
* The Scroll Manager is created lazily as needed, and will handle
* calling all handlers for a scroll event.
* @return {!./scroll-manager.ScrollManager}
*/
getScrollManager() {
// TODO (zhouyx@): Disallow scroll trigger with host API
if (!this.scrollManager_) {
this.scrollManager_ = new ScrollManager(this);
}

return this.scrollManager_;
}
}

/**
Expand Down
Loading