Skip to content

Commit 5047f3b

Browse files
Add auto-download JS
This is a combination of thanks, thanks-init, and thanks-direct logic Copy-pasted with superficial changes: - shouldAutoDownload - getDownloadURL - beginFirefoxDownload - onSuccess - onTimeout Auto-download pages will not use the default download attribution init logic from the stub attribution block. These pages will only create/update download attribution if there is essential data to pass to the download installer. Otherwise, they will attempt to start download immediately. There is a timeout to prevent an overly long wait before download auto-starts (i.e. if the stub attribution service response is slow). This means we prioritize a timely download over passing essential information.
1 parent 269e785 commit 5047f3b

7 files changed

Lines changed: 229 additions & 4 deletions

File tree

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*/
6+
7+
let timeout;
8+
let requestComplete = false;
9+
10+
/**
11+
* Determine if browser should attempt to download Firefox on page load.
12+
* @param {String} platform
13+
* @param {Boolean} fxSupported
14+
* @returns {Boolean}
15+
*/
16+
function shouldAutoDownload(platform, fxSupported) {
17+
const supportedPlatforms = ['windows', 'osx', 'android', 'ios'];
18+
19+
if (fxSupported && supportedPlatforms.indexOf(platform) !== -1) {
20+
return true;
21+
}
22+
23+
return false;
24+
}
25+
26+
/**
27+
* Get the Firefox download link for the appropriate platform.
28+
* @param {Object} window.site
29+
* @returns {String} download url
30+
*/
31+
function getDownloadURL(site) {
32+
// TODO: confirm if we want to hardcode 'thanks-' prefix here
33+
// It is part of a helper, but maybe unnecessarily specific to /thanks page?
34+
const prefix = 'thanks-download-button-';
35+
let link;
36+
let url;
37+
38+
switch (site.platform) {
39+
case 'windows':
40+
link = document.getElementById(prefix + 'win');
41+
break;
42+
case 'osx':
43+
link = document.getElementById(prefix + 'osx');
44+
break;
45+
case 'linux':
46+
// Linux users get SUMO install instructions.
47+
link = null;
48+
break;
49+
case 'android':
50+
link = document.getElementById(prefix + 'android');
51+
break;
52+
case 'ios':
53+
link = document.getElementById(prefix + 'ios');
54+
break;
55+
}
56+
57+
if (link && link.href) {
58+
url = link.href;
59+
}
60+
61+
return url;
62+
}
63+
64+
/**
65+
* Auto-start download
66+
*/
67+
function beginFirefoxDownload() {
68+
const directDownloadLink = document.getElementById('direct-download-link');
69+
let downloadURL;
70+
71+
// Only auto-start the download if a supported platform is detected.
72+
if (
73+
shouldAutoDownload(window.site.platform, window.site.fxSupported) &&
74+
typeof Mozilla.Utils !== 'undefined'
75+
) {
76+
downloadURL = getDownloadURL(window.site);
77+
78+
if (downloadURL) {
79+
// Pull download link from the download button and add to the 'Try downloading again' link.
80+
// Make sure the 'Try downloading again' link is well formatted! (issue 9615)
81+
if (directDownloadLink && directDownloadLink.href) {
82+
directDownloadLink.href = downloadURL;
83+
directDownloadLink.addEventListener(
84+
'click',
85+
(event) => {
86+
try {
87+
Mozilla.TrackProductDownload.handleLink(event);
88+
} catch (error) {
89+
return;
90+
}
91+
},
92+
false
93+
);
94+
}
95+
96+
// Start the platform-detected download a second after DOM ready event.
97+
Mozilla.Utils.onDocumentReady(() => {
98+
setTimeout(() => {
99+
try {
100+
Mozilla.TrackProductDownload.sendEventFromURL(
101+
downloadURL
102+
);
103+
} catch (error) {
104+
return;
105+
}
106+
window.location.href = downloadURL;
107+
}, 1000);
108+
});
109+
}
110+
}
111+
}
112+
113+
/**
114+
* On success of new download attribution request
115+
*/
116+
function onSuccess() {
117+
// Make sure we only initiate the download once!
118+
clearTimeout(timeout);
119+
if (requestComplete) {
120+
return;
121+
}
122+
requestComplete = true;
123+
124+
// Fire GA event to log attribution success
125+
// GA4
126+
window.dataLayer.push({
127+
event: 'widget_action',
128+
type: 'direct-attribution',
129+
action: 'success',
130+
non_interaction: true
131+
});
132+
133+
beginFirefoxDownload();
134+
}
135+
136+
/**
137+
* On timeout of new download attribution request
138+
*/
139+
function onTimeout() {
140+
// Make sure we only initiate the download once!
141+
clearTimeout(timeout);
142+
if (requestComplete) {
143+
return;
144+
}
145+
requestComplete = true;
146+
147+
// Fire GA event to log attribution timeout
148+
// GA4
149+
window.dataLayer.push({
150+
event: 'widget_action',
151+
type: 'direct-attribution',
152+
action: 'timeout',
153+
non_interaction: true
154+
});
155+
156+
beginFirefoxDownload();
157+
}
158+
159+
// Force cookie update if there is essential data to add
160+
if (
161+
Mozilla.DownloadAttribution !== undefined &&
162+
document.documentElement.hasAttribute(
163+
'data-stub-attribution-campaign-force'
164+
)
165+
) {
166+
// Custom success and timeout callbacks are only relevant for direct attribution
167+
// (i.e. when we have updated the cookie on the auto-download page)
168+
Mozilla.DownloadAttribution.successCallback = onSuccess;
169+
Mozilla.DownloadAttribution.timeoutCallback = onTimeout;
170+
// Don't wait too long before starting download
171+
// (even if it means we have to leave the essential information out)
172+
timeout = setTimeout(onTimeout, 2000);
173+
Mozilla.DownloadAttribution.initEssential();
174+
} else {
175+
beginFirefoxDownload();
176+
}
177+
178+
// Bug 1354334 - add a hint for test automation that page has loaded.
179+
document.getElementsByTagName('html')[0].classList.add('download-ready');

media/static-bundles.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,13 @@
571571
],
572572
"name": "download-attribution"
573573
},
574+
{
575+
"files": [
576+
"js/base/download-attribution/download-attribution.es6.js",
577+
"js/firefox/download/auto-download.es6.js"
578+
],
579+
"name": "auto-download"
580+
},
574581
{
575582
"files": [
576583
"js/base/protocol/modal-global.es6.js"

springfield/cms/templates/cms/thanks_page.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,17 @@
88

99
{% block body_class %}fl-thanks-body{% endblock %}
1010

11+
{% if switch('enable_attribution_refactor') %}
12+
<!-- let auto-download handle attribution -->
13+
{% block stub_attribution %}{% endblock %}
14+
{% endif%}
15+
1116
{% block js %}
12-
{{ js_bundle('firefox_download_thanks') }}
17+
{% if switch('enable_attribution_refactor') %}
18+
{{ js_bundle('auto-download') }}
19+
{% else %}
20+
{{ js_bundle('firefox_download_thanks') }}
21+
{% endif %}
1322
{% endblock %}
1423

1524

springfield/firefox/templates/firefox/download/basic/thanks.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ <h1 class="mzp-c-callout-title show-unknown">{{ ftl('firefox-new-download-interr
8080
</main>
8181
{% endblock %}
8282

83+
{% if switch('enable_attribution_refactor') %}
84+
<!-- let auto-download handle attribution -->
85+
{% block stub_attribution %}{% endblock %}
86+
{% endif%}
87+
8388
{% block js %}
84-
{{ js_bundle('firefox_download_thanks') }}
89+
{% if switch('enable_attribution_refactor') %}
90+
{{ js_bundle('auto-download') }}
91+
{% else %}
92+
{{ js_bundle('firefox_download_thanks') }}
93+
{% endif %}
8594
{% endblock %}

springfield/firefox/templates/firefox/download/desktop/thanks.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ <h1 class="c-section-title show-unknown">{{ ftl('firefox-desktop-download-interr
9898
</main>
9999
{% endblock %}
100100

101+
{% if switch('enable_attribution_refactor') %}
102+
<!-- let auto-download handle attribution -->
103+
{% block stub_attribution %}{% endblock %}
104+
{% endif%}
105+
101106
{% block js %}
102-
{{ js_bundle('firefox_download_thanks') }}
107+
{% if switch('enable_attribution_refactor') %}
108+
{{ js_bundle('auto-download') }}
109+
{% else %}
110+
{{ js_bundle('firefox_download_thanks') }}
111+
{% endif %}
103112
{% endblock %}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{#
2+
This Source Code Form is subject to the terms of the Mozilla Public
3+
License, v. 2.0. If a copy of the MPL was not distributed with this
4+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
#}
6+
7+
{% extends "firefox/download/desktop/thanks.html" %}
8+
9+
{% block html_attrs %}data-stub-attribution-campaign-force="rtamo"{% endblock %}

springfield/firefox/views.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,10 @@ def get_template_names(self):
454454
template = "firefox/download/desktop/thanks.html"
455455
else:
456456
if source == "direct":
457-
template = "firefox/download/basic/thanks_direct.html"
457+
if waffle.switch("ENABLE_ATTRIBUTION_REFACTOR"):
458+
template = "firefox/download/rtamo.html"
459+
else:
460+
template = "firefox/download/basic/thanks_direct.html"
458461
else:
459462
template = "firefox/download/basic/thanks.html"
460463

0 commit comments

Comments
 (0)