зеркало из https://github.com/mozilla/bedrock.git
Remove "page ID" and "core page" code (#14913)
* Remove core page variables and dataLayer patch for UA/GA3 Fix #10733 Removes some code that supported our weird UA/GA3 setup including: page id, core page, dataLayer over-rides for click tracking, and variables indicating if a page has a video and download button. - Remove: core-dataLayer.js and associated tests & init - Functionality removed: - page-id - dataLayer "monkey patch" for UA - pageHasDownload, PageVersion, and releaseWindowVersion variables - Removed jinja template code that supported the page-id JS - Moved: amoExperiments to new files, converted to es6
This commit is contained in:
Родитель
554db18556
Коммит
8ff4c3d9c0
|
@ -6,8 +6,6 @@
|
|||
|
||||
{% extends "base-error.html" %}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="404"{% endblock %}
|
||||
|
||||
{% block page_title %}{{ ftl('not-found-page-not-found-page-page-not-found') }}{% endblock %}
|
||||
|
||||
{% block page_css %}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
{% extends "base-error.html" %}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="500"{% endblock %}
|
||||
|
||||
{% block page_title %}{{ ftl('error-page-error-page-internal-server-error') }}{% endblock %}
|
||||
|
||||
{% block page_css %}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<!doctype html>
|
||||
{# Note the "windows" class, without javascript platform-specific assets default to windows #}
|
||||
<html class="windows no-js" lang="{{ LANG|replace('en-US', 'en') }}" dir="{{ DIR }}" data-country-code="{{ country_code }}" data-needs-consent="{{ needs_data_consent(country_code) }}" data-latest-firefox="{{ latest_firefox_version }}" data-esr-versions="{{ esr_firefox_versions|join(' ') }}" {% if settings.GTM_CONTAINER_ID %}data-gtm-container-id="{{ settings.GTM_CONTAINER_ID }}"{% endif %} {% block gtm_page_id %}{% endblock %} {% if settings.STUB_ATTRIBUTION_RATE %}data-stub-attribution-rate="{{ settings.STUB_ATTRIBUTION_RATE }}"{% endif %} {% if settings.SENTRY_FRONTEND_DSN %}data-sentry-dsn="{{ settings.SENTRY_FRONTEND_DSN }}"{% endif %} {% block html_attrs %}{% endblock %}>
|
||||
<html class="windows no-js" lang="{{ LANG|replace('en-US', 'en') }}" dir="{{ DIR }}" data-country-code="{{ country_code }}" data-needs-consent="{{ needs_data_consent(country_code) }}" data-latest-firefox="{{ latest_firefox_version }}" data-esr-versions="{{ esr_firefox_versions|join(' ') }}" {% if settings.GTM_CONTAINER_ID %}data-gtm-container-id="{{ settings.GTM_CONTAINER_ID }}"{% endif %} {% if settings.STUB_ATTRIBUTION_RATE %}data-stub-attribution-rate="{{ settings.STUB_ATTRIBUTION_RATE }}"{% endif %} {% if settings.SENTRY_FRONTEND_DSN %}data-sentry-dsn="{{ settings.SENTRY_FRONTEND_DSN }}"{% endif %} {% block html_attrs %}{% endblock %}>
|
||||
<head>
|
||||
<meta charset="utf-8">{# Note: Must be within first 512 bytes of page #}
|
||||
|
||||
|
|
|
@ -16,12 +16,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1122305#c8
|
|||
<!-- Site Container: NONE -->
|
||||
|
||||
{% if settings.GTM_CONTAINER_ID %}
|
||||
<!--[if !IE]><!-->
|
||||
{{ js_bundle('gtm-snippet') }}
|
||||
<!--<![endif]-->
|
||||
|
||||
<!--[if IE 9]>
|
||||
{{ js_bundle('gtm-snippet-ie') }}
|
||||
<![endif]-->
|
||||
{% endif %}
|
||||
<!-- End Google Tag Manager -->
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
{% extends "firefox/releases/notes.html" %}
|
||||
|
||||
{% if release.product == 'Firefox for Android' %}
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/android/auroranotes/"' %}
|
||||
{% set header_class = 'mzp-t-dark t-nightly' %}
|
||||
{% set brand_product = 'nightly' %}
|
||||
{% set download_button_primary %}
|
||||
|
@ -18,7 +17,6 @@
|
|||
{% endset %}
|
||||
{% set download_all_link = firefox_url('android', 'all', channel='nightly') %}
|
||||
{% elif release.product == 'Firefox' %}
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/auroranotes/"' %}
|
||||
{% set header_class = 'mzp-t-dark' %}
|
||||
{% set brand_product = 'developer t-aurora' %}
|
||||
{% set download_title = 'Build, test, scale and more with the only browser built just for developers.' %}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
{% set brand_product = 'beta' %}
|
||||
|
||||
{% if release.product == 'Firefox for Android' %}
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/android/beta/releasenotes"' %}
|
||||
{% set download_button_primary %}
|
||||
{{ download_firefox('beta', platform='android', alt_copy='Download Firefox for Android Beta', dom_id="download-android-beta-primary") }}
|
||||
{% endset %}
|
||||
|
@ -19,7 +18,6 @@
|
|||
{% endset %}
|
||||
{% set download_all_link = firefox_url('android', 'all', channel='beta') %}
|
||||
{% elif release.product == 'Firefox' %}
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/beta/releasenotes/"' %}
|
||||
{% set download_button_primary %}
|
||||
{{ download_firefox('beta', platform='desktop', force_direct=True, alt_copy='Download Firefox Beta', dom_id="download-beta-primary") }}
|
||||
{% endset %}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% extends "firefox/releases/notes.html" %}
|
||||
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/auroranotes/"' %}
|
||||
{% set product_name = 'Firefox Developer Edition' %}
|
||||
{% set header_class = 'mzp-t-dark t-developer' %}
|
||||
{% set brand_product = 'developer' %}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
{% extends "firefox/releases/notes.html" %}
|
||||
|
||||
{% set page_id ='data-gtm-page-id="/firefox/esr/releasenotes/"' %}
|
||||
|
||||
{% set download_button_primary %}
|
||||
{{ download_firefox('esr', platform='desktop', force_direct=True, alt_copy='Download Firefox ESR', dom_id="download-esr-primary") }}
|
||||
{% endset %}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
{% set header_class = 'mzp-t-dark t-nightly' %}
|
||||
{% set brand_product = 'nightly' %}
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/nightly/releasenotes"' %}
|
||||
|
||||
{% if release.is_latest %}
|
||||
{% set primary_heading = 'See what landed recently in <span>Firefox Nightly</span>!'|safe %}
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
|
||||
{% extends "firefox/base/base-protocol.html" %}
|
||||
|
||||
{# page ID for gtm #}
|
||||
{# page_id may be over-ridden with more appropriate content #}
|
||||
{% set page_id = page_id|default('data-gtm-page-id="/firefox/releasenotes/"') %}
|
||||
|
||||
{# product_name is the product and channel together. Example: Firefox for Android Beta. #}
|
||||
{# product_name may be over-ridden with more appropriate content to avoid bad names like: Firefox Release Release #}
|
||||
{% set product_name = product_name|default(release.product + ' ' + release.channel) %}
|
||||
|
@ -43,7 +39,6 @@
|
|||
{% block page_title_prefix %}{% endblock %}
|
||||
{% block page_title %}{{ release.product }} {{ channel_name }} {{ release.version }}, See All New Features, Updates and Fixes{% endblock %}
|
||||
{% block page_title_suffix %}{% endblock %}
|
||||
{% block gtm_page_id %}{{ page_id }}{% endblock %}
|
||||
|
||||
{% block body_id %}notes{% endblock %}
|
||||
{% block body_class %}mzp-t-firefox {{ theme_class }}{% endblock %}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
{% from "macros.html" import google_play_button, apple_app_store_button with context %}
|
||||
|
||||
{% if release.product == 'Firefox for iOS' %}
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/ios/releasenotes/"' %}
|
||||
{% set product_name = release.product %}
|
||||
{% set download_button_primary %}
|
||||
{{ apple_app_store_button(href=app_store_url('firefox', 'firefox-release-notes'), id='download-ios-primary') }}
|
||||
|
@ -17,7 +16,6 @@
|
|||
{{ apple_app_store_button(href=app_store_url('firefox', 'firefox-release-notes'), id='download-ios-secondary') }}
|
||||
{% endset %}
|
||||
{% elif release.product == 'Firefox for Android' %}
|
||||
{% set page_id = 'data-gtm-page-id="/firefox/android/releasenotes/"' %}
|
||||
{% set product_name = 'Firefox for Android' %}
|
||||
{% set download_button_primary %}
|
||||
{{ google_play_button(id='download-android-primary') }}
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
{% from "macros-protocol.html" import callout, callout_compact %}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="/firefox/system-requirements/"{% endblock %}
|
||||
|
||||
{% set channel_name = '' if release.channel == 'Release' else release.channel %}
|
||||
|
||||
{% block page_title_prefix %}{% endblock %}
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
|
||||
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="/firefox/whatsnew/"{% endblock %}
|
||||
|
||||
{# Exclude stub attribution for in-product pages: issus 9620 #}
|
||||
{% block stub_attribution %}{% endblock %}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
{% extends "base-protocol-mozilla.html" %}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="Homepage"{% endblock %}
|
||||
|
||||
{% block extra_meta %}
|
||||
<!-- validates bing webmaster tools -->
|
||||
<meta name="msvalidate.01" content="B7B177115A634927D608514DA17B2574">
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
{% extends 'newsletter/base.html' %}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="/newsletter/confirm/"{% endblock %}
|
||||
|
||||
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
|
||||
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
{% extends 'newsletter/base.html' %}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="/newsletter/country/"{% endblock %}
|
||||
|
||||
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
|
||||
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}
|
||||
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
{# Template used for a user to manage their subscriptions #}
|
||||
|
||||
{% block gtm_page_id %}data-gtm-page-id="/newsletter/existing/"{% endblock %}
|
||||
|
||||
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
|
||||
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
// init core dataLayer object and push into dataLayer
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var analytics = Mozilla.Analytics;
|
||||
var client = Mozilla.Client;
|
||||
var dataLayer = (window.dataLayer = window.dataLayer || []);
|
||||
|
||||
function sendCoreDataLayer() {
|
||||
var dataLayerCore = {
|
||||
event: 'core-datalayer-loaded',
|
||||
pageHasDownload: analytics.pageHasDownload(),
|
||||
pageVersion: analytics.getPageVersion(),
|
||||
releaseWindowVersion: analytics.getLatestFxVersion()
|
||||
};
|
||||
|
||||
dataLayer.push(dataLayerCore);
|
||||
}
|
||||
|
||||
function initCoreDataLayer() {
|
||||
if (client.isFirefoxDesktop || client.isFirefoxAndroid) {
|
||||
client.getFirefoxDetails(function (details) {
|
||||
dataLayer.push(details);
|
||||
sendCoreDataLayer();
|
||||
});
|
||||
} else {
|
||||
sendCoreDataLayer();
|
||||
}
|
||||
|
||||
analytics.updateDataLayerPush();
|
||||
}
|
||||
|
||||
// Init dataLayer event on DOM Ready.
|
||||
if (typeof Mozilla.Utils !== 'undefined') {
|
||||
Mozilla.Utils.onDocumentReady(function () {
|
||||
initCoreDataLayer();
|
||||
|
||||
// Add GA custom dimension for AMO experiments (Issue 10175).
|
||||
if (typeof window._SearchParams !== 'undefined') {
|
||||
var params = new window._SearchParams().params;
|
||||
var validParams = analytics.getAMOExperiment(params);
|
||||
|
||||
if (validParams) {
|
||||
// UA
|
||||
dataLayer.push({
|
||||
'data-ex-name': validParams['experiment'],
|
||||
'data-ex-variant': validParams['variation']
|
||||
});
|
||||
// GA4
|
||||
dataLayer.push({
|
||||
event: 'experiment_view',
|
||||
id: validParams['experiment'],
|
||||
variant: validParams['variation']
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
if (typeof window.Mozilla === 'undefined') {
|
||||
window.Mozilla = {};
|
||||
}
|
||||
|
||||
(function (Mozilla) {
|
||||
'use strict';
|
||||
|
||||
// init dataLayer object
|
||||
var dataLayer = (window.dataLayer = window.dataLayer || []);
|
||||
var Analytics = {};
|
||||
|
||||
/** Returns page ID used in Event Category for GA events tracked on page.
|
||||
* @param {String} path - URL path name fallback if page ID does not exist.
|
||||
* @return {String} GTM page ID.
|
||||
*/
|
||||
Analytics.getPageId = function (path) {
|
||||
var pageId = document
|
||||
.getElementsByTagName('html')[0]
|
||||
.getAttribute('data-gtm-page-id');
|
||||
var pathName = path ? path : document.location.pathname;
|
||||
|
||||
return pageId
|
||||
? pageId
|
||||
: pathName.replace(/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/, '/');
|
||||
};
|
||||
|
||||
Analytics.buildDataObject = function () {
|
||||
var dataObj = {
|
||||
event: 'page-id-loaded',
|
||||
pageId: Analytics.getPageId()
|
||||
};
|
||||
|
||||
return dataObj;
|
||||
};
|
||||
|
||||
// Push page ID into dataLayer so it's ready when GTM container loads.
|
||||
dataLayer.push(Analytics.buildDataObject());
|
||||
|
||||
Mozilla.Analytics = Analytics;
|
||||
})(window.Mozilla);
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utility class for core dataLayer object to track contextual user and page data
|
||||
*/
|
||||
|
||||
if (typeof window.Mozilla.Analytics === 'undefined') {
|
||||
window.Mozilla.Analytics = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var analytics = Mozilla.Analytics;
|
||||
var isModernBrowser =
|
||||
'querySelector' in document && 'querySelectorAll' in document;
|
||||
|
||||
/** Returns whether page has download button.
|
||||
* @param {String} path - URL path name fallback if page ID does not exist.
|
||||
* @return {String} string.
|
||||
*/
|
||||
analytics.pageHasDownload = function () {
|
||||
if (!isModernBrowser) {
|
||||
return 'false';
|
||||
}
|
||||
return document.querySelector('[data-download-os]') !== null
|
||||
? 'true'
|
||||
: 'false';
|
||||
};
|
||||
|
||||
/** Returns page version.
|
||||
* @param {String} path - URL path name fallback if page ID does not exist.
|
||||
* @return {String} version number from URL.
|
||||
*/
|
||||
analytics.getPageVersion = function (path) {
|
||||
var pathName = path ? path : document.location.pathname;
|
||||
var versionResults = /firefox\/(\d+(?:\.\d+)?\.\da?\d?)/.exec(pathName);
|
||||
|
||||
return versionResults ? versionResults[1] : null;
|
||||
};
|
||||
|
||||
/** Returns latest Fx version.
|
||||
* @return {String} latest Fx version.
|
||||
*/
|
||||
analytics.getLatestFxVersion = function () {
|
||||
return document
|
||||
.getElementsByTagName('html')[0]
|
||||
.getAttribute('data-latest-firefox');
|
||||
};
|
||||
|
||||
analytics.getAMOExperiment = function (params) {
|
||||
var allowedExperiment = /^\d{8}_amo_.[\w/.%-]{1,50}$/; // should match the format YYYYMMDD_amo_experiment_name.
|
||||
var allowedVariation = /^[\w/.%-]{1,50}$/; // allow alpha numeric & common URL encoded chars.
|
||||
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(params, 'experiment') &&
|
||||
Object.prototype.hasOwnProperty.call(params, 'variation')
|
||||
) {
|
||||
var experiment = decodeURIComponent(params['experiment']);
|
||||
var variation = decodeURIComponent(params['variation']);
|
||||
|
||||
if (
|
||||
allowedExperiment.test(experiment) &&
|
||||
allowedVariation.test(variation)
|
||||
) {
|
||||
return {
|
||||
experiment: experiment,
|
||||
variation: variation
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/** Monkey patch for dataLayer.push
|
||||
* Adds href stripped of locale to link click objects when pushed to the dataLayer,
|
||||
* also removes protocol and host if same as parent page from href.
|
||||
*/
|
||||
analytics.updateDataLayerPush = function (host) {
|
||||
var dataLayer = (window.dataLayer = window.dataLayer || []);
|
||||
var hostname = host || document.location.hostname;
|
||||
|
||||
dataLayer.defaultPush = dataLayer.push;
|
||||
dataLayer.push = function () {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
if (arguments[i].event === 'gtm.linkClick') {
|
||||
var element = arguments[i]['gtm.element'];
|
||||
var href = element.href;
|
||||
|
||||
if (element.hostname === hostname) {
|
||||
// remove host and locale from internal links
|
||||
var path = href.replace(
|
||||
/^(?:https?:\/\/)(?:[^/])*/,
|
||||
''
|
||||
);
|
||||
var locale = path.match(
|
||||
/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/
|
||||
);
|
||||
|
||||
path = locale ? path.replace(locale[0], '/') : path;
|
||||
arguments[i].newClickHref = path;
|
||||
} else {
|
||||
arguments[i].newClickHref = href;
|
||||
}
|
||||
|
||||
dataLayer.defaultPush(arguments[i]);
|
||||
} else {
|
||||
dataLayer.defaultPush(arguments[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { getAMOExperiment } from './experiment-amo.es6.js';
|
||||
|
||||
const dataLayer = (window.dataLayer = window.dataLayer || []);
|
||||
|
||||
// Look for AMO experiment on DOM Ready.
|
||||
if (typeof Mozilla.Utils !== 'undefined') {
|
||||
Mozilla.Utils.onDocumentReady(() => {
|
||||
// Add GA custom dimension for AMO experiments (Issue 10175).
|
||||
if (typeof window._SearchParams !== 'undefined') {
|
||||
const params = new window._SearchParams().params;
|
||||
const validParams = getAMOExperiment(params);
|
||||
|
||||
if (validParams) {
|
||||
// GA4
|
||||
dataLayer.push({
|
||||
event: 'experiment_view',
|
||||
id: validParams['experiment'],
|
||||
variant: validParams['variation']
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
function getAMOExperiment(params) {
|
||||
const allowedExperiment = /^\d{8}_amo_.[\w/.%-]{1,50}$/; // should match the format YYYYMMDD_amo_experiment_name.
|
||||
const allowedVariation = /^[\w/.%-]{1,50}$/; // allow alpha numeric & common URL encoded chars.
|
||||
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(params, 'experiment') &&
|
||||
Object.prototype.hasOwnProperty.call(params, 'variation')
|
||||
) {
|
||||
const experiment = decodeURIComponent(params['experiment']);
|
||||
const variation = decodeURIComponent(params['variation']);
|
||||
|
||||
if (
|
||||
allowedExperiment.test(experiment) &&
|
||||
allowedVariation.test(variation)
|
||||
) {
|
||||
return {
|
||||
experiment: experiment,
|
||||
variation: variation
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export { getAMOExperiment };
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import GTMSnippet from '../gtm-snippet.es6.js';
|
||||
|
||||
// Push page ID into dataLayer so it's ready when GTM container loads.
|
||||
const dataLayer = (window.dataLayer = window.dataLayer || []);
|
||||
|
||||
/**
|
||||
* Get the page ID from the data-gtm-page-id attribute on the html element.
|
||||
* @returns {string} The page ID to be used in GTM.
|
||||
*/
|
||||
function getPageId() {
|
||||
const pageId = document
|
||||
.getElementsByTagName('html')[0]
|
||||
.getAttribute('data-gtm-page-id');
|
||||
const pathName = document.location.pathname;
|
||||
|
||||
return pageId
|
||||
? pageId
|
||||
: pathName.replace(/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Monkey patch for dataLayer.push
|
||||
* Adds href stripped of locale to link click objects when pushed to the dataLayer,
|
||||
* also removes protocol and host if same as parent page from href.
|
||||
*/
|
||||
function updateDataLayerPush() {
|
||||
const dataLayer = (window.dataLayer = window.dataLayer || []);
|
||||
const hostname = document.location.hostname;
|
||||
|
||||
dataLayer.defaultPush = dataLayer.push;
|
||||
dataLayer.push = function () {
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
if (arguments[i].event === 'gtm.linkClick') {
|
||||
const element = arguments[i]['gtm.element'];
|
||||
const href = element.href;
|
||||
|
||||
if (element.hostname === hostname) {
|
||||
// remove host and locale from internal links
|
||||
let path = href.replace(/^(?:https?:\/\/)(?:[^/])*/, '');
|
||||
const locale = path.match(/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/);
|
||||
|
||||
path = locale ? path.replace(locale[0], '/') : path;
|
||||
arguments[i].newClickHref = path;
|
||||
} else {
|
||||
arguments[i].newClickHref = href;
|
||||
}
|
||||
|
||||
dataLayer.defaultPush(arguments[i]);
|
||||
} else {
|
||||
dataLayer.defaultPush(arguments[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
dataLayer.push({
|
||||
event: 'page-id-loaded',
|
||||
pageId: getPageId()
|
||||
});
|
||||
|
||||
GTMSnippet.init();
|
||||
|
||||
// Monkey patch dataLayer.push() click events
|
||||
updateDataLayerPush();
|
|
@ -9,6 +9,10 @@ import { isApprovedToRun } from '../../base/experiment-utils.es6.js';
|
|||
|
||||
const href = window.location.href;
|
||||
|
||||
if (typeof window.dataLayer === 'undefined') {
|
||||
window.dataLayer = [];
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
if (href.indexOf('v=1') !== -1) {
|
||||
window.dataLayer.push({
|
||||
|
|
|
@ -1256,8 +1256,7 @@
|
|||
"files": [
|
||||
"js/base/site.js",
|
||||
"js/base/consent/privacy-helpers.js",
|
||||
"js/base/mozilla-cookie-helper.js",
|
||||
"js/base/core-datalayer-page-id.js"
|
||||
"js/base/mozilla-cookie-helper.js"
|
||||
],
|
||||
"name": "site"
|
||||
},
|
||||
|
@ -1447,12 +1446,6 @@
|
|||
],
|
||||
"name": "gtm-snippet"
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"js/base/gtm/ie/gtm-snippet-ie-init.es6.js"
|
||||
],
|
||||
"name": "gtm-snippet-ie"
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"js/base/protocol/init-sidemenu.es6.js"
|
||||
|
@ -1616,8 +1609,8 @@
|
|||
},
|
||||
{
|
||||
"files": [
|
||||
"js/base/core-datalayer.js",
|
||||
"js/base/core-datalayer-init.js",
|
||||
"js/base/experiment-amo.es6.js",
|
||||
"js/base/experiment-amo-init.es6.js",
|
||||
"js/base/datalayer-productdownload-init.es6.js"
|
||||
],
|
||||
"name": "data"
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/* For reference read the Jasmine and Sinon docs
|
||||
* Jasmine docs: https://jasmine.github.io/
|
||||
* Sinon docs: http://sinonjs.org/docs/
|
||||
*/
|
||||
|
||||
describe('core-datalayer-page-id.js', function () {
|
||||
describe('getPageId', function () {
|
||||
const html = document.documentElement;
|
||||
|
||||
afterEach(function () {
|
||||
html.removeAttribute('data-gtm-page-id');
|
||||
});
|
||||
|
||||
it('will grab data-gtm-page-id value if present on <html> element', function () {
|
||||
html.setAttribute('data-gtm-page-id', 'test');
|
||||
expect(Mozilla.Analytics.getPageId('/en-US/firefox/new/')).toBe(
|
||||
'test'
|
||||
);
|
||||
});
|
||||
|
||||
it('will grab the pathname minus the first directory if no data-gtm-page-id value is present on <html> element', function () {
|
||||
expect(Mozilla.Analytics.getPageId('/en-US/firefox/new/')).toBe(
|
||||
'/firefox/new/'
|
||||
);
|
||||
});
|
||||
|
||||
it('will return the full page path when no data-gtm-page-id value is present and no locale is in page path', function () {
|
||||
expect(Mozilla.Analytics.getPageId('/firefox/new/')).toBe(
|
||||
'/firefox/new/'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/* For reference read the Jasmine and Sinon docs
|
||||
* Jasmine docs: https://jasmine.github.io/
|
||||
* Sinon docs: http://sinonjs.org/docs/
|
||||
*/
|
||||
|
||||
describe('core-datalayer.js', function () {
|
||||
describe('pageHasDownload', function () {
|
||||
it('will return "true" when download button is present on page.', function () {
|
||||
const downloadMarkup =
|
||||
'<a class="download" href="#" data-link-type="download" data-download-os="Desktop">';
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', downloadMarkup);
|
||||
expect(Mozilla.Analytics.pageHasDownload()).toBe('true');
|
||||
|
||||
const content = document.querySelector('.download');
|
||||
content.parentNode.removeChild(content);
|
||||
});
|
||||
|
||||
it('will return "false" when download button is not present on page.', function () {
|
||||
expect(Mozilla.Analytics.pageHasDownload()).toBe('false');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPageVersion', function () {
|
||||
it('will return the Firefox version number form the URL if present', function () {
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/firefox/107.0.11/firstrun/'
|
||||
)
|
||||
).toBe('107.0.11');
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/firefox/46.0.1/firstrun/learnmore/'
|
||||
)
|
||||
).toBe('46.0.1');
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/firefox/11.0/whatsnew/'
|
||||
)
|
||||
).toBe('11.0');
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/firefox/46.0.1a2/firstrun/'
|
||||
)
|
||||
).toBe('46.0.1a2');
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/firefox/46.0a1/whatsnew/'
|
||||
)
|
||||
).toBe('46.0a1');
|
||||
});
|
||||
|
||||
it('will return null if no version number present in URL', function () {
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/'
|
||||
)
|
||||
).toBeNull();
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/firefox/new'
|
||||
)
|
||||
).toBeNull();
|
||||
expect(
|
||||
Mozilla.Analytics.getPageVersion(
|
||||
'https://www.mozilla.org/en-US/firefox/whatsnew'
|
||||
)
|
||||
).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLatestFxVersion', function () {
|
||||
afterEach(function () {
|
||||
document
|
||||
.getElementsByTagName('html')[0]
|
||||
.removeAttribute('data-latest-firefox');
|
||||
});
|
||||
|
||||
it('will return the Firefox version from the data-latest-firefox attribute from the html element if present', function () {
|
||||
document
|
||||
.getElementsByTagName('html')[0]
|
||||
.setAttribute('data-latest-firefox', '48.0');
|
||||
expect(Mozilla.Analytics.getLatestFxVersion()).toBe('48.0');
|
||||
});
|
||||
|
||||
it('will return null if no data-latest-firefox attribute is present on the html element', function () {
|
||||
expect(Mozilla.Analytics.getLatestFxVersion()).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAMOExperiment', function () {
|
||||
it('should return true when experiment and variation params are well formatted', function () {
|
||||
const params = {
|
||||
experiment: '20210708_amo_experiment_name',
|
||||
variation: 'variation_1_name'
|
||||
};
|
||||
expect(Mozilla.Analytics.getAMOExperiment(params)).toEqual(params);
|
||||
});
|
||||
|
||||
it('should return falsy when experiment and variation params are not specific to amo', function () {
|
||||
const params = {
|
||||
experiment: 'some_other_experiment',
|
||||
variation: 'variation_1_name'
|
||||
};
|
||||
expect(Mozilla.Analytics.getAMOExperiment(params)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return falsy when experiment and variation params contain dangerous characters', function () {
|
||||
const params = {
|
||||
experiment: '20210708_amo_"><h1>hello</h1>',
|
||||
variation: '<script>alert("test");</script>'
|
||||
};
|
||||
expect(Mozilla.Analytics.getAMOExperiment(params)).toBeFalsy();
|
||||
|
||||
const params2 = {
|
||||
experiment: '20210708_amo_%22%3E%3Ch1%3Ehello%3C%2Fh1%3E',
|
||||
variation: '%3Cscript%3Ealert%28%22test%22%29%3B%3C%2Fscript%3E'
|
||||
};
|
||||
expect(Mozilla.Analytics.getAMOExperiment(params2)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return falsy if parameters values are more than 50 chars', function () {
|
||||
const params = {
|
||||
experiment: '20210708_amo_experiment_name',
|
||||
variation:
|
||||
'a_very_very_very_very_very_long_experiment_variation_name_much_much_much_more_than_50_chars'
|
||||
};
|
||||
expect(Mozilla.Analytics.getAMOExperiment(params)).toBeFalsy();
|
||||
|
||||
const params2 = {
|
||||
experiment:
|
||||
'20210708_amo_a_very_very_very_long_experiment_name_much_much_much_much_more_than_50_chars',
|
||||
variation: 'variation_1_name'
|
||||
};
|
||||
expect(Mozilla.Analytics.getAMOExperiment(params2)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateDataLayerPush', function () {
|
||||
beforeEach(function () {
|
||||
const link =
|
||||
'<a id="link" href="https://www.mozilla.org/en-US/firefox/new/">';
|
||||
document.body.insertAdjacentHTML('beforeend', link);
|
||||
|
||||
window.dataLayer = [];
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
const content = document.getElementById('link');
|
||||
content.parentNode.removeChild(content);
|
||||
delete window.dataLayer;
|
||||
});
|
||||
|
||||
it('will add newClickHref property to link click object when pushed to the dataLayer', function () {
|
||||
Mozilla.Analytics.updateDataLayerPush('www.allizom.org');
|
||||
|
||||
window.dataLayer.push({
|
||||
event: 'gtm.linkClick',
|
||||
'gtm.element': document.getElementById('link')
|
||||
});
|
||||
|
||||
expect(window.dataLayer[0].newClickHref).toBeDefined();
|
||||
});
|
||||
|
||||
it('will not add newClickHref property to object pushed to dataLayer if not a link click object', function () {
|
||||
Mozilla.Analytics.updateDataLayerPush('www.allizom.org');
|
||||
|
||||
window.dataLayer.push({
|
||||
event: 'gtm.click',
|
||||
'gtm.element': document.getElementById('link')
|
||||
});
|
||||
|
||||
expect(window.dataLayer[0].newClickHref).toBeUndefined();
|
||||
});
|
||||
|
||||
it("will keep host in newClickHref when clicked link's href host value is different thatn the page's", function () {
|
||||
Mozilla.Analytics.updateDataLayerPush('www.allizom.org');
|
||||
|
||||
window.dataLayer.push({
|
||||
event: 'gtm.linkClick',
|
||||
'gtm.element': document.getElementById('link')
|
||||
});
|
||||
|
||||
expect(window.dataLayer[0].newClickHref).toEqual(
|
||||
'https://www.mozilla.org/en-US/firefox/new/'
|
||||
);
|
||||
});
|
||||
|
||||
it("will remove host and locale in newClickHref when clicked link's href value matches the page's", function () {
|
||||
const link = document.getElementById('link');
|
||||
Mozilla.Analytics.updateDataLayerPush('www.mozilla.org');
|
||||
|
||||
// Bug 1278426
|
||||
link.href = 'https://www.mozilla.org:443/en-US/firefox/new/';
|
||||
|
||||
window.dataLayer.push({
|
||||
event: 'gtm.linkClick',
|
||||
'gtm.element': link
|
||||
});
|
||||
|
||||
expect(window.dataLayer[0].newClickHref).toEqual('/firefox/new/');
|
||||
});
|
||||
|
||||
it('will remove host and non-en-US locale', function () {
|
||||
const link = document.getElementById('link');
|
||||
Mozilla.Analytics.updateDataLayerPush('www.mozilla.org');
|
||||
|
||||
link.href = 'https://www.mozilla.org:443/de/firefox/new/';
|
||||
|
||||
window.dataLayer.push({
|
||||
event: 'gtm.linkClick',
|
||||
'gtm.element': link
|
||||
});
|
||||
|
||||
expect(window.dataLayer[0].newClickHref).toEqual('/firefox/new/');
|
||||
});
|
||||
|
||||
it('will not remove locale if absent from the URL', function () {
|
||||
const link = document.getElementById('link');
|
||||
Mozilla.Analytics.updateDataLayerPush('www.mozilla.org');
|
||||
|
||||
link.href = 'https://www.mozilla.org/firefox/new/';
|
||||
|
||||
window.dataLayer.push({
|
||||
event: 'gtm.linkClick',
|
||||
'gtm.element': link
|
||||
});
|
||||
|
||||
expect(window.dataLayer[0].newClickHref).toEqual('/firefox/new/');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/* For reference read the Jasmine and Sinon docs
|
||||
* Jasmine docs: https://jasmine.github.io/
|
||||
* Sinon docs: http://sinonjs.org/docs/
|
||||
*/
|
||||
|
||||
import { getAMOExperiment } from '../../../../media/js/base/experiment-amo.es6';
|
||||
|
||||
describe('experiment-amo.js', function () {
|
||||
describe('getAMOExperiment', function () {
|
||||
it('should return true when experiment and variation params are well formatted', function () {
|
||||
const params = {
|
||||
experiment: '20210708_amo_experiment_name',
|
||||
variation: 'variation_1_name'
|
||||
};
|
||||
expect(getAMOExperiment(params)).toEqual(params);
|
||||
});
|
||||
|
||||
it('should return falsy when experiment and variation params are not specific to amo', function () {
|
||||
const params = {
|
||||
experiment: 'some_other_experiment',
|
||||
variation: 'variation_1_name'
|
||||
};
|
||||
expect(getAMOExperiment(params)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return falsy when experiment and variation params contain dangerous characters', function () {
|
||||
const params = {
|
||||
experiment: '20210708_amo_"><h1>hello</h1>',
|
||||
variation: '<script>alert("test");</script>'
|
||||
};
|
||||
expect(getAMOExperiment(params)).toBeFalsy();
|
||||
|
||||
const params2 = {
|
||||
experiment: '20210708_amo_%22%3E%3Ch1%3Ehello%3C%2Fh1%3E',
|
||||
variation: '%3Cscript%3Ealert%28%22test%22%29%3B%3C%2Fscript%3E'
|
||||
};
|
||||
expect(getAMOExperiment(params2)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return falsy if parameters values are more than 50 chars', function () {
|
||||
const params = {
|
||||
experiment: '20210708_amo_experiment_name',
|
||||
variation:
|
||||
'a_very_very_very_very_very_long_experiment_variation_name_much_much_much_more_than_50_chars'
|
||||
};
|
||||
expect(getAMOExperiment(params)).toBeFalsy();
|
||||
|
||||
const params2 = {
|
||||
experiment:
|
||||
'20210708_amo_a_very_very_very_long_experiment_name_much_much_much_much_more_than_50_chars',
|
||||
variation: 'variation_1_name'
|
||||
};
|
||||
expect(getAMOExperiment(params2)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -20,8 +20,7 @@ module.exports = {
|
|||
'media/js/base/search-params.js',
|
||||
'media/js/base/mozilla-cookie-helper.js',
|
||||
'media/js/base/mozilla-run.js',
|
||||
'media/js/base/core-datalayer-page-id.js',
|
||||
'media/js/base/core-datalayer.js',
|
||||
'media/js/base/experiment-amo.es6.js',
|
||||
'media/js/base/mozilla-fxa.js',
|
||||
'media/js/base/mozilla-smoothscroll.js',
|
||||
'media/js/base/stub-attribution/stub-attribution.js',
|
||||
|
|
Загрузка…
Ссылка в новой задаче