Skip to content

Commit

Permalink
Refactors JS utilities; separates IE concerns
Browse files Browse the repository at this point in the history
- Removes unused util/util methods.
- Moves cookie code to its own CRUD module.
- Fixes #565 - Removes server-side handling of Google Translate cookie
and consolidates cookie handling in google-translate-manager.
- Moves isTranslated method to google-translate-manager.
- Updates “close” button method to “clear” to go with new naming.
- Pads header popup title text so (x) button doesn’t risk overlapping.
- Gives alert close button min height/width so that size doesn’t change
as (x) icon is loading.
- Implements addEventListener on alert so events can be attached to it
being dismissed.
- Fixes #573 - Creates IE8-specific override stylesheet and pulls :before and :after
selectors out of main stylesheet into this one. Also provides overrides
to elements that have box-shadows but no border by providing a border
instead (alert and popup).
- Updates modernizr custom build to include html5-shiv and include all core features used on the site.
- Removes gsub from requirejs include tag.
  • Loading branch information
anselmbradford committed Sep 8, 2014
1 parent db1d2c6 commit d6e361f
Show file tree
Hide file tree
Showing 24 changed files with 306 additions and 652 deletions.
20 changes: 19 additions & 1 deletion app/assets/javascripts/app/alert-manager.js
Expand Up @@ -6,6 +6,9 @@ define(
function () {
'use strict';

// The events the alert broadcasts.
var _events = {};

// HTML element for the alert container.
var _alertContainer;

Expand Down Expand Up @@ -59,6 +62,7 @@ function () {

// Hiding the alert box clears its content and hides it using CSS.
function hide() {
_broadcastEvent('close');
_alertContainer.classList.add('hide');
_content.innerHTML = '';
}
Expand All @@ -68,10 +72,24 @@ function () {
hide();
}

// @param evt [String] The type of event to broadcast.
// Supports 'close'.
function _broadcastEvent(evt) {
if (_events[evt])
_events[evt].call();
}

// @param event [String] The event name to listen for. Supports 'close'.
// @param callback [Function] The function called when the event has fired.
function addEventListener(event, callback) {
_events[event] = callback;
}

return {
init:init,
show:show,
hide:hide,
type:type
type:type,
addEventListener:addEventListener
};
});
11 changes: 6 additions & 5 deletions app/assets/javascripts/app/app-init.js
@@ -1,17 +1,18 @@
// Manages the application initialization for most pages.
// This script is called by the homepage, search result
// and search details pages. It is not called by
// the about page, because that page does not have popups to manage.
// the about page.
require([
'util/translation/google-translate-manager',
'app/popup-manager',
'app/alert-manager'
],
function (pm, alert) {
function (googleTranslate, popups, alert) {
'use strict';

// If box-shadow CSS is supported, initialize the popups.
if (Modernizr.boxshadow)
pm.init();
// If page is not translated, initialize the header popups.
if (!googleTranslate.isTranslated())
popups.init();

alert.init();
});
17 changes: 2 additions & 15 deletions app/assets/javascripts/app/popup-manager.js
Expand Up @@ -17,21 +17,8 @@ function (util, feedback) {
var PADDING = 20;

function init() {
if (!_isTranslated()) {
_addPopups();
feedback.init();
}
}

// Check if the page is currently translated using Google Translation.
function _isTranslated() {
var translate = util.getQueryParams().translate;
if (translate && translate !== 'en')
return true;
var googtrans = util.getCookie('googtrans');
if (googtrans && googtrans !== '/en/en')
return true;
return false;
_addPopups();
feedback.init();
}

// Adds hooks for triggering popups present on the page.
Expand Down
7 changes: 6 additions & 1 deletion app/assets/javascripts/application.js
Expand Up @@ -70,11 +70,16 @@
//
require([
'util/translation/google-translate-manager',
'util/browser-upgrade-notice',
'domReady!'
],
function (googleTranslate) {
function (googleTranslate, browserUpgradeNotice) {
'use strict';

// Show a browser upgrade notice on IE8 and below.
if (document.documentElement.classList.contains('lt-ie9'))
browserUpgradeNotice.show();

// The Google translate manager handles loading of the
// Google Website Translator Gadget at the bottom of the page's body.
// The layout settings passed in as an argument to the initialization
Expand Down
5 changes: 2 additions & 3 deletions app/assets/javascripts/search/filter/TextInput.js
Expand Up @@ -32,7 +32,7 @@ function () {
_input.value = '';
}

function _initCloseButton() {
function _initClearButton() {
// Retrieve first and only input element.
// Throw an error if it isn't found.
_input = _container.getElementsByTagName('input')[0];
Expand All @@ -44,7 +44,6 @@ function () {
if (_input.value === '')
_buttonClear.className += ' hide';
_container.appendChild(_buttonClear);

_buttonClear.addEventListener('click', function (evt) {
evt.preventDefault();
reset();
Expand Down Expand Up @@ -85,7 +84,7 @@ function () {
}

// Initialize TextInput instance.
if (_container) _initCloseButton();
if (_container) _initClearButton();
else _throwInitializationError();

return {
Expand Down
31 changes: 31 additions & 0 deletions app/assets/javascripts/util/browser-upgrade-notice.js
@@ -0,0 +1,31 @@
// Provides a upgrade notice that can be shown to outdated browsers (e.g. IE8).
define([
'util/cookie',
'app/alert-manager'
],
function (cookie, alert) {
'use strict';

// Show upgrade notice if ie-upgrade-notice cookie isn't set.
function show() {
if (cookie.read('ie-upgrade-notice') === null) {
var notice = "<i class='fa fa-exclamation-triangle'></i> " +
'Your browser is out-of-date and has known security issues.' +
'<br />' +
"<a href='https://browser-update.org/update.html'>" +
'Please visit this page to download an up-to-date browser.' +
'</a>';
alert.addEventListener('close', _alertClosed);
alert.show(notice, alert.type.INFO);
}
}

// Create a cookie when the alert is closed that will hide the alert for the next day.
function _alertClosed() {
cookie.create('ie-upgrade-notice', 'true', true, 1);
}

return {
show:show
};
});
52 changes: 52 additions & 0 deletions app/assets/javascripts/util/cookie.js.erb
@@ -0,0 +1,52 @@
// Cookie CRUD functions, from http://www.quirksmode.org/js/cookies.html
// ERB needed to retrieve domain name that the cookie is saved under.
define(
function () {
'use strict';

// @param name [String] The cookie's name.
// @param value [String] The cookie's value.
// @param useDomain [Boolean] Whether set under subdomains or not.
// @param days [Number] Number of days till the cookie expires.
// Can be negative.
function create(name, value, useDomain, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
var expires = '; expires=' + date.toGMTString();
}
else var expires = '';

var setting = name + '=' + value + expires + '; path=/';

// Sets the cookie under domain and subdomains (if useDomain parameter is present).
document.cookie = setting;
if (useDomain)
document.cookie = setting + "; domain=.<%= ENV['DOMAIN_NAME'] %>";
}

// @param name [String] The cookie's name to read.
// @return [String] The named cookie's value, or null.
function read(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}

// @param name [String] The cookie's name to remove.
// @param usedDomain [Boolean] Whether to clear subdomains also.
function erase(name, useDomain) {
create(name, '', !!useDomain, -1);
}

return {
create:create,
read:read,
erase:erase
};
});
1 change: 0 additions & 1 deletion app/assets/javascripts/util/geolocation/geolocator.js
Expand Up @@ -8,7 +8,6 @@ define(function () {
function locate(pCallBack) {
_callBack = pCallBack;

// Modernizr should pick this up, but just in case...
var geolocator = navigator.geolocation;
if (geolocator) {
var geoOptions = {
Expand Down
41 changes: 28 additions & 13 deletions app/assets/javascripts/util/translation/google-translate-manager.js
@@ -1,8 +1,10 @@
// Manages behavior of the Google Website Translator Gadget.
define([
'util/util',
'util/cookie',
'util/translation/layout/DropDownLayout'
],
function (DropDownLayout) {
function (util, cookie, DropDownLayout) {
'use strict';

// The layout object in use.
Expand All @@ -26,7 +28,7 @@ function (DropDownLayout) {
function init(layoutType) {
_layoutType = layoutType;

_deleteTranslateCookies();
_writeTranslateCookies();

_layout = DropDownLayout.create();
_layout.init(GOOGLE_TRANSLATE_ELEMENT_ID);
Expand All @@ -45,6 +47,18 @@ function (DropDownLayout) {
window.GoogleTranslate = GoogleTranslate;
}

// Checks if the 'googtrans' cookie is set to English or not,
// indicating whether the page has been translated using the
// Google Website Translator Gadget.
// @return [Boolean] true if Google Translation has translated the page.
// Returns false if the page is not translated and is in English.
function isTranslated() {
var googtrans = cookie.read('googtrans');
if (googtrans && decodeURIComponent(googtrans) === '/en/en')
return true;
return false;
}

// Initialize the Google Website Translator Gadget.
function _googleTranslateElementInit() {
var gadgetOptions = {
Expand All @@ -69,22 +83,23 @@ function (DropDownLayout) {
return google.translate.TranslateElement.InlineLayout.HORIZONTAL;
}

// Removes the Google Website Translator cookies by setting their expiration
// date into the past.
function _deleteTranslateCookies() {
var cookies, cookie, eqPos, name;
cookies = document.cookie.split('; ');
for (var i = 0, len = cookies.length; i < len; i++) {
cookie = cookies[i];
eqPos = cookie.indexOf('=');
name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
if (name === 'googtrans')
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
// Overwrite/Create Google Website Translator Gadget cookies if the
// 'translate' URL parameter is present.
function _writeTranslateCookies() {
var translateRequested = util.getParameterByName('translate');
if (translateRequested) {
var newCookieValue = '/en/'+translateRequested;
var oldCookieValue = decodeURIComponent(cookie.read('googtrans'));
if(newCookieValue !== oldCookieValue) {
cookie.create('googtrans', newCookieValue, true, 30);
window.location.reload();
}
}
}

return {
init:init,
isTranslated:isTranslated,
InlineLayout:InlineLayout
};
});

0 comments on commit d6e361f

Please sign in to comment.