Skip to content

Commit

Permalink
Add site wide feature detect snippet (Fixes #7391)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgibson committed Oct 8, 2019
1 parent d1bc674 commit a4771b0
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 91 deletions.
100 changes: 78 additions & 22 deletions docs/browser-support.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
Browser Support
===============

We seek to provide usable experiences of our most important web content to all user agents. But newer browsers are far more capable than older browsers, and the capabilities they provide are valuable to developers and site visitors. We **will** take advantage of modern browser capabilities. Older browsers **will** have a different experience of the website than newer browsers. We will strike this balance by generally adhering to the core principles of `Progressive Enhancement <https://en.wikipedia.org/wiki/Progressive_enhancement>`_::
We seek to provide usable experiences of our most important web content to all user agents.
But newer browsers are far more capable than older browsers, and the capabilities they
provide are valuable to developers and site visitors. We **will** take advantage of modern
browser capabilities. Older browsers **will** have a different experience of the website than
newer browsers. We will strike this balance by generally adhering to the core principles of
`Progressive Enhancement <https://en.wikipedia.org/wiki/Progressive_enhancement>`_:

* Basic content should be accessible to all web browsers
* Basic functionality should be accessible to all web browsers
Expand All @@ -17,17 +22,15 @@ We seek to provide usable experiences of our most important web content to all u
* Enhanced behavior is provided by unobtrusive, externally linked JavaScript
* End-user web browser preferences are respected

Some website experiences may require us to deviate from these principles -- imagine *a marketing campaign page built under timeline pressure to deliver novel functionality to a particular locale for a short while* -- but those will be exceptions and rare.
Some website experiences may require us to deviate from these principles -- imagine *a
marketing campaign page built under timeline pressure to deliver novel functionality to a
particular locale for a short while* -- but those will be exceptions and rare.

Technical details
-----------------
Browser Support Matrix (Updated 2019-08-10)
-------------------------------------------

We deliver enhanced CSS & JS to browsers in our browser support matrix (below). We deliver basic support to all other user agents.

Basic support consists of no page-specific CSS or JS. Instead, we deliver basic semantic HTML, a universal CSS stylesheet that gets applied to all pages, and a universal JS bundle that only handles downloading Firefox (click a button, get a file), and Google Analytics.

Browser Support Matrix (Updated 20190409)
-----------------------------------------
We deliver enhanced CSS & JS to browsers in our browser support matrix (below).
We deliver basic support to all other user agents.

**The following browsers have enhanced support:**

Expand All @@ -36,23 +39,76 @@ Browser Support Matrix (Updated 20190409)

**The following browsers have basic support:**

* All other IE browsers.
* Outdated evergreen browser versions.
* IE9 and below.

Exceptions (Updated 20190409)
-----------------------------
Delivering experiences to legacy browsers
-----------------------------------------

Some pages of the website provide critical functionality to older browsers. In particular, the Firefox desktop download funnel enables users on older browsers to get a modern browser. To the extent possible, we try to deliver enhanced experiences to all user agents on these pages.
On IE browsers that support `conditional comments`_ (IE9 and below), basic support
consists of no page-specific CSS or JS. Instead, we deliver basic semantic HTML, a
universal CSS stylesheet that gets applied to all pages, and a universal JS bundle that
only handles downloading Firefox (click a button, get a file), and Google Analytics.

**The following pages get enhanced support for a longer list of user agents:**
On other legacy browsers, developers should rely on `feature detection`_ where appropriate.

* www.mozilla.org/firefox/new/
* www.mozilla.org/firefox/download/thanks/
CSS
~~~

.. Note::
For CSS, enhanced experiences can be delivered using `feature queries`_, whilst allowing
older browsers to degrade gracefully using simpler layouts if needed.

Additionally, there is also a universal CSS class hook available that gets delivered via
a site-wide JS feature detection snippet:

.. code-block:: css
.is-modern-browser {
/* Styles will only be applied to browsers that get enhanced support. */
}
.. _conditional comments: https://wikipedia.org/wiki/Conditional_comment
.. _feature detection: https://developer.mozilla.org/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection
.. _feature queries: https://developer.mozilla.org/docs/Web/CSS/@supports

JavaScript
~~~~~~~~~~

For JS, enhanced support can be delivered using a helper that leverages the site-wide
feature detection snippet:

An enhanced experience can be defined as a step above basic support. This can be achieved by delivering extra page-specific CSS or JS to legacy browsers. It does not mean continuing to deliver 1st class support.
.. code-block:: javascript
Future Support (Updated 20190409)
---------------------------------
function onLoad() {
// Code that will only be run on browsers that get enhanced support.
}
window.Mozilla.run(onLoad);
The ``site.isModernBrowser`` global property can also be used within conditionals like so:

.. code-block:: javascript
if (window.site.isModernBrowser) {
// Code that will only be run on browsers that get enhanced support.
}
Exceptions (Updated 2019-08-10)
-------------------------------

Some pages of the website provide critical functionality to older browsers. In particular,
the Firefox desktop download funnel enables users on older browsers to get a modern browser.
To the extent possible, we try to deliver enhanced experiences to all user agents on these
pages.

**The following pages get enhanced support for a longer list of user agents:**

* /firefox/
* /firefox/new/
* /firefox/download/thanks/

.. Note::

Since IE10 does not support conditional comments (the mechanism currently used to deliver basic support to old IE browsers), in the future bedrock will adopt a universal JS feature detection snippet. This snippet will be used to limit the execution of JS on older browsers, delivering a better degraded experience.
An enhanced experience can be defined as a step above basic support. This can be achieved
by delivering extra page-specific CSS or JS to legacy browsers. It does not mean continuing
to deliver 1st class support.
42 changes: 22 additions & 20 deletions media/css/firefox/all/all-unified.scss
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,6 @@ $image-path: '/media/protocol/img';
display: block;
}
}

@media #{$mq-lg} {
.is-supported & {
min-height: 700px;
}
}
}

.c-intro {
Expand Down Expand Up @@ -182,11 +176,6 @@ $image-path: '/media/protocol/img';
.c-selection-options {
display: none;
}

// only show the form if JS is supported.
.is-supported & {
display: block;
}
}

.c-download {
Expand Down Expand Up @@ -233,15 +222,6 @@ $image-path: '/media/protocol/img';
}
}

.js .c-all-downloads {
display: none;

// still allow the list to be shown as a fallback.
&.is-fallback {
display: block;
}
}

.c-product-heading {
@include text-display-md;
background: $color-white;
Expand Down Expand Up @@ -344,3 +324,25 @@ $image-path: '/media/protocol/img';
@include text-body-sm;
}
}

// Modern browsers get the form, legacy browsers the download list.
.is-modern-browser {
.c-all-downloads {
display: none;

// still allow the list to be shown as a fallback.
&.is-fallback {
display: block;
}
}

.c-selection-form {
display: block;
}

.c-product-select-form {
@media #{$mq-lg} {
min-height: 700px;
}
}
}
23 changes: 23 additions & 0 deletions media/js/base/mozilla-run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* 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/. */

// Create namespace
if (typeof window.Mozilla === 'undefined') {
window.Mozilla = {};
}

(function() {
'use strict';

var run = function(callback) {
var isModernBrowser = window.site && window.site.isModernBrowser;

if (isModernBrowser && typeof callback === 'function') {
callback();
}
};

window.Mozilla.run = run;

})(window.Mozilla);
15 changes: 15 additions & 0 deletions media/js/base/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@
return 32;
},

// Universal feature detect to deliver graded browser support.
cutsTheMustard: function () {
return 'querySelector' in document &&
'querySelectorAll' in document &&
'addEventListener' in window &&
'classList' in document.createElement('div');
},

platform: 'other',
platformVersion: undefined,
archType: 'x64',
Expand Down Expand Up @@ -192,6 +200,13 @@
h.className += ' is-firefox';
}

// Add class to reflect browsers that get 1st class JS & CSS support.
var isModernBrowser = window.site.isModernBrowser = window.site.cutsTheMustard();

if (isModernBrowser) {
h.className += ' is-modern-browser';
}

// Add class to reflect javascript availability for CSS
h.className = h.className.replace(/\bno-js\b/, 'js');
})();
Expand Down
73 changes: 34 additions & 39 deletions media/js/firefox/all/all-downloads-unified-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,42 @@
(function(Mozilla){
'use strict';

var browserHelpContent = document.getElementById('browser-help');
var browserHelpIcon = document.getElementById('icon-browser-help');
var downloadList = document.getElementById('all-downloads');
var form = document.getElementById('product-select-form');
var installerHelpContent = document.getElementById('installer-help');
var installerHelpIcon = document.querySelectorAll('.icon-installer-help');

function showHelpModal(modalContent, modalTitle, eventLabel) {
Mzp.Modal.createModal(this, modalContent, {
title: modalTitle,
className: 'help-modal'
});

window.dataLayer.push({
'event': 'in-page-interaction',
'eAction': 'link click',
'eLabel': eventLabel
});
}

if (!Mozilla.FirefoxDownloader.isSupported()) {
downloadList.style.display = 'block';
return;
} else {
form.classList.add('is-supported');
}

Mozilla.FirefoxDownloader.init();

// Browser help modal.
browserHelpIcon.addEventListener('click', function(e) {
e.preventDefault();
showHelpModal.call(this, browserHelpContent, browserHelpIcon.textContent, 'Get Browser Help');
}, false);

// Installer help modal.
for (var i = 0; i < installerHelpIcon.length; i++) {
installerHelpIcon[i].addEventListener('click', function(e) {
function onLoad() {
var browserHelpContent = document.getElementById('browser-help');
var browserHelpIcon = document.getElementById('icon-browser-help');
var installerHelpContent = document.getElementById('installer-help');
var installerHelpIcon = document.querySelectorAll('.icon-installer-help');

function showHelpModal(modalContent, modalTitle, eventLabel) {
Mzp.Modal.createModal(this, modalContent, {
title: modalTitle,
className: 'help-modal'
});

window.dataLayer.push({
'event': 'in-page-interaction',
'eAction': 'link click',
'eLabel': eventLabel
});
}

Mozilla.FirefoxDownloader.init();

// Browser help modal.
browserHelpIcon.addEventListener('click', function(e) {
e.preventDefault();
showHelpModal.call(this, installerHelpContent, e.target.textContent, 'Get Installer Help');
showHelpModal.call(this, browserHelpContent, browserHelpIcon.textContent, 'Get Browser Help');
}, false);

// Installer help modal.
for (var i = 0; i < installerHelpIcon.length; i++) {
installerHelpIcon[i].addEventListener('click', function(e) {
e.preventDefault();
showHelpModal.call(this, installerHelpContent, e.target.textContent, 'Get Installer Help');
}, false);
}
}

Mozilla.run(onLoad);

})(window.Mozilla);
10 changes: 0 additions & 10 deletions media/js/firefox/all/all-downloads-unified.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,16 +447,6 @@
}
};

/**
* Basic feature detect for minimum browser support.
*/
FirefoxDownloader.isSupported = function() {
return 'querySelector' in document &&
'querySelectorAll' in document &&
'addEventListener' in window &&
'classList' in document.createElement('div');
};

/**
* Initialize the form and show the default selection.
*/
Expand Down
3 changes: 3 additions & 0 deletions media/static-bundles.json
Original file line number Diff line number Diff line change
Expand Up @@ -1512,6 +1512,7 @@
"js/newsletter/form.js",
"js/base/mozilla-client.js",
"js/base/class-list-polyfill.js",
"js/base/mozilla-run.js",
"protocol/js/protocol-supports.js",
"protocol/js/protocol-utils.js",
"protocol/js/protocol-menu.js",
Expand All @@ -1535,6 +1536,7 @@
"js/base/mozilla-utils.js",
"js/base/mozilla-client.js",
"js/base/class-list-polyfill.js",
"js/base/mozilla-run.js",
"protocol/js/protocol-supports.js",
"protocol/js/protocol-utils.js",
"protocol/js/protocol-menu.js",
Expand All @@ -1557,6 +1559,7 @@
"js/base/mozilla-utils.js",
"js/base/mozilla-client.js",
"js/base/class-list-polyfill.js",
"js/base/mozilla-run.js",
"protocol/js/protocol-supports.js",
"protocol/js/protocol-utils.js",
"protocol/js/protocol-menu.js",
Expand Down

0 comments on commit a4771b0

Please sign in to comment.