diff --git a/bedrock/base/templates/base-pebbles.html b/bedrock/base/templates/base-pebbles.html
index 9f1e5970fb0..61ea43066f6 100644
--- a/bedrock/base/templates/base-pebbles.html
+++ b/bedrock/base/templates/base-pebbles.html
@@ -3,7 +3,7 @@
{# Note the "windows" class, without javascript platform-specific
assets default to windows #}
-
+
{# Note: Must be within first 512 bytes of page #}
diff --git a/bedrock/base/templates/base-resp.html b/bedrock/base/templates/base-resp.html
index 0ae0344a6e5..740fc316fea 100644
--- a/bedrock/base/templates/base-resp.html
+++ b/bedrock/base/templates/base-resp.html
@@ -3,7 +3,7 @@
{# Note the "windows" class, without javascript platform-specific
assets default to windows #}
-
+
{# Note: Must be within first 512 bytes of page #}
diff --git a/bedrock/exp/__init__.py b/bedrock/exp/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/bedrock/exp/models.py b/bedrock/exp/models.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/bedrock/exp/templates/exp/base/base-firefox.html b/bedrock/exp/templates/exp/base/base-firefox.html
new file mode 100644
index 00000000000..7d266134ffa
--- /dev/null
+++ b/bedrock/exp/templates/exp/base/base-firefox.html
@@ -0,0 +1,18 @@
+{# 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 http://mozilla.org/MPL/2.0/. -#}
+
+ {% extends "exp/base/base.html" %}
+
+ {% block page_title_prefix %}{% endblock %}
+ {% block page_title_suffix %}{% endblock %}
+
+ {% block page_image %}{{ static('img/firefox/template/page-image-firefox.jpg') }}{% endblock %}
+ {% block page_favicon %}{{ static('img/firefox/favicon.ico') }}{% endblock %}
+ {% block page_favicon_large %}{{ static('img/firefox/favicon-196.png') }}{% endblock %}
+ {% block page_ios_icon %}{{ static('img/firefox/ios-icon-180.png') }}{% endblock %}
+
+ {% block facebook_id %}14696440021{# facebook.com/Firefox #}{% endblock %}
+ {% block twitter_id %}firefox{% endblock %}
+
+ {% block body_class %}{{ super() }} mzp-t-firefox{% endblock %}
diff --git a/bedrock/exp/templates/exp/base/base.html b/bedrock/exp/templates/exp/base/base.html
new file mode 100644
index 00000000000..2ea9625ed54
--- /dev/null
+++ b/bedrock/exp/templates/exp/base/base.html
@@ -0,0 +1,27 @@
+{# 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 http://mozilla.org/MPL/2.0/. -#}
+
+{% extends "base-protocol.html" %}
+
+{% block html_attrs %}data-convert-project-id="{{ settings.CONVERT_PROJECT_ID }}"{% endblock %}
+
+{% block experiments %}
+ {% if switch('convert-experiment-script') %}
+ {# Pre-fetch the DNS lookup prior to loading the convert script #}
+
+
+ {{ js_bundle('convert') }}
+
+ {% endif %}
+{% endblock %}
+
+{% block site_js %}
+
+ {{ js_bundle('common-protocol-no-jquery') }}
+
+
+
+{% endblock %}
diff --git a/bedrock/exp/templates/exp/firefox/new/base.html b/bedrock/exp/templates/exp/firefox/new/base.html
new file mode 100644
index 00000000000..e4110a00c43
--- /dev/null
+++ b/bedrock/exp/templates/exp/firefox/new/base.html
@@ -0,0 +1,28 @@
+{# 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 http://mozilla.org/MPL/2.0/. -#}
+
+{% from "macros.html" import google_play_button with context %}
+{% from "macros-protocol.html" import hero, picto_card with context %}
+
+{% extends "exp/base/base-firefox.html" %}
+
+{% block canonical_urls %}
+ {# the SEM campaign page should set canonical to the /firefox/new/ page. #}
+
+{% endblock %}
+
+{# All stylesheets are loaded in extrahead to serve legacy IE basic styles #}
+{% block extrahead %}
+ {{ css_bundle('protocol-core') }}
+ {{ css_bundle('exp-firefox-new') }}
+{% endblock %}
+
+{% block old_ie_styles %}{% endblock %}
+{% block site_css %}{% endblock %}
+{% block page_css %}{% endblock %}
+
+{% block site_header %}{% endblock %}
+
+{# Bug 1381776 #}
+{% block update_notification %}{% endblock %}
diff --git a/bedrock/exp/templates/exp/firefox/new/download.de.html b/bedrock/exp/templates/exp/firefox/new/download.de.html
new file mode 100644
index 00000000000..a3e195c6163
--- /dev/null
+++ b/bedrock/exp/templates/exp/firefox/new/download.de.html
@@ -0,0 +1,43 @@
+{# 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 http://mozilla.org/MPL/2.0/. -#}
+
+{% extends "exp/firefox/new/base.html" %}
+
+{% block page_title_prefix %}Download Firefox — {% endblock %}
+
+{% block page_title %}kostenloser Browser{% endblock %}
+
+{# Bug 1438302 Avoid duplicate content for en-CA and en-GB pages. #}
+{% block page_title_suffix %} — Mozilla{% endblock %}
+
+{% block page_desc %}Download Mozilla Firefox, den kostenlosen Browser für Windows, Mac, Linux, Android und iOS. Firefox wird von Mozilla entwickelt – der Non-Profit-Organisation, die sich für deine Online-Rechte stark macht.{% endblock %}
+
+{#- This will appear as which can be used for social share -#}
+{% block page_og_title %}Jetzt den schnellsten Firefox aller Zeiten herunterladen{% endblock %}
+
+{#- This will appear as which can be used for social share -#}
+{% block page_og_desc %}Der neue Firefox: schnellere Seitenladezeiten, weniger Speicherverbrauch und vollgepackt mit neuen Funktionen.{% endblock %}
+
+{% block content %}
+
+ {% call hero(
+ title='Hol dir den neuesten Firefox Browser.',
+ desc='Und damit eines der Firefox Produkte, für die deine Privatsphäre an erster Stelle steht.',
+ class='mzp-has-image mzp-t-dark',
+ include_cta=True,
+ image_url='firefox/new/trailhead/browser-window.svg',
+ heading_level=1
+ ) %}
+ {{ download_firefox(alt_copy='Jetzt herunterladen', download_location='primary cta') }}
+ {% endcall %}
+
+
+
+ {{ picto_card(title='Komm zu Firefox', desc='Verbinde alle deine Firefox Produkte miteinander und bleib in Sachen Online-Sicherheit immer auf dem neuesten Stand.', class='join') }}
+ {{ picto_card(title='Passwörter immer dabei', desc='Firefox Lockwise hat deine gespeicherten Passwörter immer und auf allen deinen Geräten für dich parat.'|safe, class='lockwise') }}
+ {{ picto_card(title='Schütze deine Privatsphäre', desc='Im Privaten Modus wird dein Browserverlauf automatisch gelöscht, sodass andere Benutzer deines Computers ihn nicht sehen können.'|safe, class='private') }}
+
+
+
+{% endblock %}
diff --git a/bedrock/exp/templates/exp/firefox/new/download.html b/bedrock/exp/templates/exp/firefox/new/download.html
new file mode 100644
index 00000000000..d55351e7f9c
--- /dev/null
+++ b/bedrock/exp/templates/exp/firefox/new/download.html
@@ -0,0 +1,51 @@
+{# 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 http://mozilla.org/MPL/2.0/. -#}
+
+{% extends "exp/firefox/new/base.html" %}
+
+{% block page_title_prefix %}Download Firefox — {% endblock %}
+
+{% block page_title %}Free Web Browser{% endblock %}
+
+{# Bug 1438302 Avoid duplicate content for en-CA and en-GB pages. #}
+{%- block page_title_suffix -%}
+ {% if LANG == 'en-CA' %}
+ — Mozilla (CA)
+ {% elif LANG == 'en-GB' %}
+ — Mozilla (UK)
+ {% else %}
+ — Mozilla
+ {% endif %}
+{%- endblock -%}
+
+{% block page_desc %}Download Mozilla Firefox, a free web browser. Firefox is created by a global non-profit dedicated to putting individuals in control online. Get Firefox for Windows, macOS, Linux, Android and iOS today!{% endblock %}
+
+{#- This will appear as which can be used for social share -#}
+{% block page_og_title %}Download the fastest Firefox ever{% endblock %}
+
+{#- This will appear as which can be used for social share -#}
+{% block page_og_desc %}Faster page loading, less memory usage and packed with features, the new Firefox is here.{% endblock %}
+
+{% block content %}
+
+ {% call hero(
+ title='Get the latest Firefox browser.',
+ desc='And start getting the respect you deserve with our family of privacy-first products.',
+ class='mzp-has-image mzp-t-dark',
+ include_cta=True,
+ image_url='firefox/new/trailhead/browser-window.svg',
+ heading_level=1
+ ) %}
+ {{ download_firefox(alt_copy='Download Now', download_location='primary cta') }}
+ {% endcall %}
+
+
+
+ {{ picto_card(title='Join Firefox', desc='Connect to a whole family of respectful products, plus all the knowledge you need to protect yourself online.', class='join') }}
+ {{ picto_card(title='Passwords made portable', desc='Firefox Lockwise makes the passwords you save in Firefox available on all your devices.'|safe, class='lockwise') }}
+ {{ picto_card(title='Protect your privacy', desc='Private Browsing clears your history to keep it secret from anyone who uses your computer.'|safe, class='private') }}
+
+
+
+{% endblock %}
diff --git a/bedrock/exp/urls.py b/bedrock/exp/urls.py
new file mode 100644
index 00000000000..8c7cc7dc68f
--- /dev/null
+++ b/bedrock/exp/urls.py
@@ -0,0 +1,10 @@
+# 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 http://mozilla.org/MPL/2.0/.
+
+from bedrock.mozorg.util import page
+
+
+urlpatterns = (
+ page('firefox/new', 'exp/firefox/new/download.html', active_locales=['en-US', 'en-GB', 'en-CA', 'de']),
+)
diff --git a/bedrock/exp/views.py b/bedrock/exp/views.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/bedrock/settings/base.py b/bedrock/settings/base.py
index e329bda5798..c93829ac902 100644
--- a/bedrock/settings/base.py
+++ b/bedrock/settings/base.py
@@ -297,6 +297,7 @@ def lazy_langs():
r'^about/legal/impressum/$',
r'^security/announce/',
r'^etc/',
+ r'^exp/',
]
# Pages we do want indexed but don't show up in automated URL discovery
@@ -466,6 +467,7 @@ def get_app_name(hostname):
'bedrock.sitemaps',
'bedrock.etc',
'bedrock.pocketfeed',
+ 'bedrock.exp',
# last so that redirects here will be last
'bedrock.redirects',
@@ -1395,6 +1397,8 @@ def get_app_name(hostname):
'adservice.google.de',
'adservice.google.dk',
'creativecommons.org',
+ 'cdn-3.convertexperiments.com',
+ 'logs.convertexperiments.com',
]
CSP_SCRIPT_SRC = CSP_DEFAULT_SRC + [
# TODO fix things so that we don't need this
@@ -1407,10 +1411,15 @@ def get_app_name(hostname):
'tagmanager.google.com',
'www.youtube.com',
's.ytimg.com',
+ 'cdn-3.convertexperiments.com',
+ 'app.convert.com',
+ '1003350.track.convertexperiments.com',
+ '1003343.track.convertexperiments.com',
]
CSP_STYLE_SRC = CSP_DEFAULT_SRC + [
# TODO fix things so that we don't need this
"'unsafe-inline'",
+ 'app.convert.com',
]
CSP_CHILD_SRC = [
'www.googletagmanager.com',
@@ -1459,3 +1468,6 @@ def get_app_name(hostname):
# FUNNELCAKE_103_LOCALES=de,fr,en-US
#
# where "103" in the variable name is the funnelcake ID.
+
+# Issue 7508 - Convert.com experiment sandbox
+CONVERT_PROJECT_ID = ('10039-1003350' if DEV else '10039-1003343')
diff --git a/bedrock/urls.py b/bedrock/urls.py
index 48e12b716ad..b073d07bfbb 100644
--- a/bedrock/urls.py
+++ b/bedrock/urls.py
@@ -29,6 +29,7 @@
url(r'', include('bedrock.mozorg.urls')),
url(r'', include('bedrock.newsletter.urls')),
url(r'^etc/', include('bedrock.etc.urls')),
+ url(r'^exp/', include('bedrock.exp.urls')),
url(r'^healthz/$', watchman_views.ping, name="watchman.ping"),
url(r'^readiness/$', watchman_views.status, name="watchman.status"),
diff --git a/media/css/exp/firefox/new/download.scss b/media/css/exp/firefox/new/download.scss
new file mode 100644
index 00000000000..eb7bd0ff0b5
--- /dev/null
+++ b/media/css/exp/firefox/new/download.scss
@@ -0,0 +1,100 @@
+// 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 http://mozilla.org/MPL/2.0/.
+
+$font-path: '/media/fonts';
+$image-path: '/media/protocol/img';
+
+@import '../../../../protocol/css/components/hero';
+@import '../../../../protocol/css/components/modal';
+@import '../../../../protocol/css/components/picto-card';
+@import '../../../../protocol/css/includes/lib';
+@import '../../../../protocol/css/templates/card-layout';
+
+
+.mzp-c-hero.mzp-t-dark {
+ @include background-size(auto 100%);
+ background-color: $color-off-black;
+
+ .mzp-c-hero-title {
+ @include at2x('/media/img/logos/firefox/logo-quantum-wordmark-white.png', 147px, 48px);
+ background-position: top center;
+ background-repeat: no-repeat;
+ padding-top: $layout-xl;
+ }
+
+ .mzp-c-hero-image img {
+ top: 48px;
+ bottom: auto;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .5);
+ }
+
+ @media #{$mq-md} {
+ @include bidi((
+ (background-image, url('/media/img/exp/firefox/new/hero-bg.svg'), url('/media/img/exp/firefox/new/hero-bg-rtl.svg')),
+ (background-position, top right -600px, top left -600px),
+ ));
+ background-repeat: no-repeat;
+
+ .mzp-c-hero-title {
+ @include bidi(((background-position, top left, top right),));
+ max-width: 9em;
+ }
+
+ .mzp-c-hero-desc {
+ max-width: 21em;
+ }
+ }
+
+ @media #{$mq-lg} {
+ @include bidi(((background-position, top right -480px, top left -480px),));
+ }
+
+ @media #{$mq-xl} {
+ @include bidi(((background-position, top right -260px, top left -260px),));
+ }
+}
+
+
+/**
+ * Picto card custom icon sizes.
+ * These should be standardized into a `large` icon size.
+ * https://github.com/mozilla/protocol/issues/382
+ */
+.mzp-c-card-picto .mzp-c-card-picto-content {
+ padding-top: 140px;
+
+ &:before {
+ background-color: transparent;
+ background-position: top left;
+ background-repeat: no-repeat;
+ }
+
+ @media #{$mq-lg} {
+ .mzp-c-card-picto-title {
+ @include text-display-sm;
+ margin-bottom: $spacing-xl;
+ }
+ }
+}
+
+.join .mzp-c-card-picto-content::before {
+ height: 104px;
+ width: 104px;
+ margin-left: -52px;
+ background-image: url('/media/img/exp/firefox/new/icon-join.svg');
+}
+
+.lockwise .mzp-c-card-picto-content::before {
+ height: 96px;
+ width: 152px;
+ margin-left: -76px;
+ background-image: url('/media/img/exp/firefox/new/icon-lockwise.svg');
+}
+
+.private .mzp-c-card-picto-content::before {
+ height: 83px;
+ width: 113px;
+ margin-left: -56px;
+ background-image: url('/media/img/exp/firefox/new/icon-private.svg');
+}
diff --git a/media/img/exp/firefox/new/hero-bg-rtl.svg b/media/img/exp/firefox/new/hero-bg-rtl.svg
new file mode 100644
index 00000000000..2bc1b888d4c
--- /dev/null
+++ b/media/img/exp/firefox/new/hero-bg-rtl.svg
@@ -0,0 +1 @@
+
diff --git a/media/img/exp/firefox/new/hero-bg.svg b/media/img/exp/firefox/new/hero-bg.svg
new file mode 100644
index 00000000000..3aff599ffa2
--- /dev/null
+++ b/media/img/exp/firefox/new/hero-bg.svg
@@ -0,0 +1 @@
+
diff --git a/media/img/exp/firefox/new/icon-join.svg b/media/img/exp/firefox/new/icon-join.svg
new file mode 100644
index 00000000000..4b1abcf7a53
--- /dev/null
+++ b/media/img/exp/firefox/new/icon-join.svg
@@ -0,0 +1 @@
+
diff --git a/media/img/exp/firefox/new/icon-lockwise.svg b/media/img/exp/firefox/new/icon-lockwise.svg
new file mode 100644
index 00000000000..a14cf09dfa4
--- /dev/null
+++ b/media/img/exp/firefox/new/icon-lockwise.svg
@@ -0,0 +1 @@
+
diff --git a/media/img/exp/firefox/new/icon-private.svg b/media/img/exp/firefox/new/icon-private.svg
new file mode 100644
index 00000000000..839f292e8e1
--- /dev/null
+++ b/media/img/exp/firefox/new/icon-private.svg
@@ -0,0 +1 @@
+
diff --git a/media/js/exp/convert.js b/media/js/exp/convert.js
new file mode 100644
index 00000000000..a99fb3925ae
--- /dev/null
+++ b/media/js/exp/convert.js
@@ -0,0 +1,17 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+(function() {
+ 'use strict';
+
+ var CONVERT_PROJECT_ID = document.getElementsByTagName('html')[0].getAttribute('data-convert-project-id');
+
+ // Load third-party JS async and respect DNT.
+ if (CONVERT_PROJECT_ID && typeof Mozilla.dntEnabled === 'function' && !Mozilla.dntEnabled()) {
+ var newScriptTag = document.createElement('script');
+ var target = document.getElementsByTagName('script')[0];
+ newScriptTag.src = 'https://cdn-3.convertexperiments.com/js/' + CONVERT_PROJECT_ID + '.js';
+ target.parentNode.insertBefore(newScriptTag, target);
+ }
+})();
diff --git a/media/static-bundles.json b/media/static-bundles.json
index 97e273e681c..421cd5d610e 100644
--- a/media/static-bundles.json
+++ b/media/static-bundles.json
@@ -229,6 +229,12 @@
],
"name": "firefox_campaign_trailhead"
},
+ {
+ "files": [
+ "css/exp/firefox/new/download.scss"
+ ],
+ "name": "exp-firefox-new"
+ },
{
"files": [
"css/security/security.scss"
@@ -1543,6 +1549,28 @@
],
"name": "common-protocol"
},
+ {
+ "files": [
+ "js/base/mozilla-utils.js",
+ "js/base/mozilla-client.js",
+ "js/base/class-list-polyfill.js",
+ "protocol/js/protocol-supports.js",
+ "protocol/js/protocol-utils.js",
+ "protocol/js/protocol-menu.js",
+ "protocol/js/protocol-navigation.js",
+ "js/base/protocol/init-navigation.js",
+ "protocol/js/protocol-lang-switcher.js",
+ "js/base/protocol/init-lang-switcher.js",
+ "protocol/js/protocol-details.js",
+ "protocol/js/protocol-footer.js",
+ "js/base/base-page-init.js",
+ "js/base/core-datalayer.js",
+ "js/base/core-datalayer-init.js",
+ "js/base/search-params.js",
+ "js/base/fxa-utm-referral.js"
+ ],
+ "name": "common-protocol-no-jquery"
+ },
{
"files": [
"js/base/mozilla-article.js",
@@ -1552,6 +1580,13 @@
],
"name": "basic-article"
},
+ {
+ "files": [
+ "js/libs/jquery-3.4.1.min.js",
+ "js/exp/convert.js"
+ ],
+ "name": "convert"
+ },
{
"files": [
"js/libs/matchMedia.js",