Skip to content

Commit

Permalink
This is a replication of the referendum banner
Browse files Browse the repository at this point in the history
implemented in #769, #770, and #775.
  • Loading branch information
timblair authored and boffbowsh committed Mar 13, 2017
1 parent 89bdcd7 commit 4cebe28
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 0 deletions.
57 changes: 57 additions & 0 deletions app/assets/javascripts/modules/global-bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Global bar
Manages count of how many times a global bar has been seen
using cookies.
*/
(function(Modules) {
"use strict";

Modules.GlobalBar = function() {
this.start = function($el) {
var GLOBAL_BAR_SEEN_COOKIE = "global_bar_seen",
count = viewCount();

$el.on('click', '.dismiss', hide);

if ($el.is(':visible')) {
incrementViewCount(count);
track('Viewed');
}

function hide(evt) {
$el.hide();
GOVUK.setCookie(GLOBAL_BAR_SEEN_COOKIE, 999, {days: 84});
track('Manually dismissed');
evt.preventDefault();
}

function incrementViewCount(count) {
count = count + 1;
GOVUK.setCookie(GLOBAL_BAR_SEEN_COOKIE, count, {days: 84});

if (count == 2) {
track('Automatically dismissed');
}
}

function viewCount() {
var viewCountCookie = GOVUK.getCookie(GLOBAL_BAR_SEEN_COOKIE),
viewCount = parseInt(viewCountCookie, 10);

if (isNaN(viewCount)) {
viewCount = 0;
}

return viewCount;
}

function track(action) {
if (GOVUK.analytics && typeof GOVUK.analytics.trackEvent === "function") {
GOVUK.analytics.trackEvent('Global bar', action, {nonInteraction: 1});
}
}
};
};

})(window.GOVUK.Modules);
1 change: 1 addition & 0 deletions app/assets/javascripts/start-modules.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//= require govuk/modules
//= require modules/global-bar
//= require modules/sticky-element-container
//= require modules/toggle
//= require modules/track-click
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/surveys.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
init: function() {
var activeSurvey = userSurveys.getActiveSurvey(userSurveys.defaultSurvey, userSurveys.smallSurveys);
if (userSurveys.isSurveyToBeDisplayed(activeSurvey)) {
$('#global-bar').hide(); // Hide global bar if one is showing
userSurveys.displaySurvey(activeSurvey);
}
},
Expand Down
48 changes: 48 additions & 0 deletions app/assets/stylesheets/helpers/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,51 @@
}
}
}

#global-bar {
margin: 20px 0 15px;
padding: 15px 0;
background-color: $light-blue-25;
display: none;

.show-global-bar & {
display: block;
}

.global-bar-message-container {
@include core-19;
@extend %site-width-container;
position: relative;

@include media(tablet) {
.dismiss {
position: absolute;
right: 0;
top: 0;
}
}
}

.global-bar-message {
margin-top: 0;
margin-bottom: 0;

@include media(tablet) {
max-width: 66.67%;
}

strong {
font-weight: 700;
margin-right: 10px;
}

a[rel~="external"] {
@include external-link-default;
@include external-link-16;

@include media(tablet) {
@include external-link-19;
}
}
}
}
18 changes: 18 additions & 0 deletions app/views/root/_base.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
<% end %>

<% content_for :head do %>
<!--[if gt IE 7]><!-->
<script>!function(t){"use strict";function e(){return!/^\/register-to-vote|^\/done/.test(window.location.pathname)}function n(){var e=t.cookie.match("(?:^|[ ;])global_bar_seen=([0-9]+)");return e?parseInt(e.pop(),10)<3:!0}var o=t.documentElement;e()&&n()&&(o.className=o.className.concat(" show-global-bar"))}(document);</script>
<!--<![endif]-->
<%= render :partial => 'stylesheet', :locals => { :css_file => local_assigns[:css_file] || 'static' } %>
<% end %>

Expand All @@ -30,6 +33,21 @@
<% end %>

<% content_for :content do %>

<% unless @banner_notification.present? || local_assigns[:hide_banner_notification] %>
<!--[if gt IE 7]><!-->
<div id="global-bar" data-module="global-bar" class="dont-print">
<div class="global-bar-message-container">
<p class="global-bar-message"><strong>Some Title</strong> On [some date] [something will happen / has happened]. <a href="https://www.gov.uk/" rel="external noreferrer">More&nbsp;information<span class="visuallyhidden"> about [things]</span></a></p>
<a href="#hide-message"
class="dismiss"
role="button"
aria-controls="global-bar">Hide&nbsp;message</a>
</div>
</div>
<!--<![endif]-->
<% end %>

<div id="wrapper" class="group">
<%= yield :wrapper_content %>
</div>
Expand Down
119 changes: 119 additions & 0 deletions spec/javascripts/global-bar-class-toggle.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
describe("toggling a global bar HTML class based on cookie", function () {
var root = window;

function globalBarSource(fakeWindow) {
var window = fakeWindow || root;

/* --------------------------------------- */

(function (document) {
"use strict"
var documentElement = document.documentElement;
if (urlPermitsShow() && viewCountPermitsShow()) {
documentElement.className = documentElement.className.concat(' show-global-bar');
}

function urlPermitsShow() {
return !/^\/register-to-vote|^\/done/.test(window.location.pathname);
}

function viewCountPermitsShow() {
var c = document.cookie.match('(?:^|[ ;])global_bar_seen=([0-9]+)');
if (!c) {
return true;
}

return parseInt(c.pop(), 10) < 3;
}
})(document);

/* --------------------------------------- */
}

function globalBarMinified(fakeWindow) {
var window = fakeWindow || root;

/* --------------------------------------- */
!function(t){"use strict";function e(){return!/^\/register-to-vote|^\/done/.test(window.location.pathname)}function n(){var e=t.cookie.match("(?:^|[ ;])global_bar_seen=([0-9]+)");return e?parseInt(e.pop(),10)<3:!0}var o=t.documentElement;e()&&n()&&(o.className=o.className.concat(" show-global-bar"))}(document);
/* --------------------------------------- */
}

afterEach(function() {
$('html').removeClass('show-global-bar');
deleteAllCookies();

function deleteAllCookies() {
var cookies = document.cookie.split(";");

for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
}
});

describe('when running the full source', function() {
runTests(globalBarSource);
});

describe('when running the minified source', function() {
runTests(globalBarMinified);
});

function runTests(globalBarFn) {
it("shows when no cookie is set", function() {
expectGlobalBarToBeHidden();
globalBarFn();
expectGlobalBarToShow();
});

it("does not show when bar has been seen 3 times", function() {
GOVUK.setCookie('global_bar_seen', 3);
expectGlobalBarToBeHidden();
globalBarFn();
expectGlobalBarToBeHidden();
});

it("shows when the bar has been seen 2 times", function() {
GOVUK.setCookie('global_bar_seen', '2');
globalBarFn();
expectGlobalBarToShow();
});

it("shows when the bar has been seen 2 times and there are lots of cookies", function() {
GOVUK.setCookie('global_bar_thing', '10');
GOVUK.setCookie('seen_cookie_message', 'true');
GOVUK.setCookie('global_bar_seen', '2');
GOVUK.setCookie('is_global_bar_seen', '8');
GOVUK.setCookie('_ua', '1234873487');
globalBarFn();
expectGlobalBarToShow();
});

it("shows when the cookie value is not a parseable number", function() {
GOVUK.setCookie('global_bar_seen', 'foo_bar2');
globalBarFn();
expectGlobalBarToShow();
});

it("does not show on register to vote pages", function() {
globalBarFn({location: {pathname: '/register-to-vote'}});
expectGlobalBarToBeHidden();
});

it("does not show on done pages", function() {
globalBarFn({location: {pathname: '/done'}});
expectGlobalBarToBeHidden();
});
}

function expectGlobalBarToShow() {
expect($('html').is('.show-global-bar')).toBe(true);
}

function expectGlobalBarToBeHidden() {
expect($('html').is('.show-global-bar')).toBe(false);
}
});
80 changes: 80 additions & 0 deletions spec/javascripts/modules/global-bar.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
describe('A global bar module', function() {
"use strict";

var bar,
element;

beforeEach(function() {
bar = new GOVUK.Modules.GlobalBar();
element = $('<div>Bar message <a href="#" class="dismiss">Dismiss</a></div>');
$('body').append(element);
});

afterEach(function() {
element.remove();
});

describe('when no cookies are set', function() {
beforeEach(function() {
spyOn(GOVUK.analytics, 'trackEvent');
spyOn(GOVUK, 'setCookie');
spyOn(GOVUK, 'getCookie').and.returnValue(undefined);
bar.start(element);
});

it('sets a new cookie with view count set to 1', function() {
expect(GOVUK.setCookie).toHaveBeenCalledWith('global_bar_seen', 1, {days: 84});
});

it('tracks to analytics', function() {
expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith('Global bar', 'Viewed', {nonInteraction: 1});
expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalledWith('Global bar', 'Automatically dismissed', {nonInteraction: 1});
});
});

describe('when a cookie has been set', function() {
describe('when the bar is visible', function() {
beforeEach(function() {
spyOn(GOVUK.analytics, 'trackEvent');
spyOn(GOVUK, 'setCookie');
spyOn(GOVUK, 'getCookie').and.returnValue('1');
bar.start(element);
});

it('increments the view count in the cookie', function() {
expect(GOVUK.setCookie).toHaveBeenCalledWith('global_bar_seen', 2, {days: 84});
});

it('tracks to analytics', function() {
expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith('Global bar', 'Viewed', {nonInteraction: 1});
expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith('Global bar', 'Automatically dismissed', {nonInteraction: 1});
});
});

describe('when the bar is invisible', function() {
it('leaves the view count in the cookie the same', function() {
spyOn(GOVUK, 'setCookie');
spyOn(GOVUK, 'getCookie').and.returnValue('1');
element.hide();
bar.start(element);

expect(GOVUK.setCookie).not.toHaveBeenCalled();
});
});
});

describe('when a dismiss link is clicked', function() {
it('hides the bar and sets a cookie so it doesn’t show again', function() {
spyOn(GOVUK.analytics, 'trackEvent');
spyOn(GOVUK, 'setCookie');
spyOn(GOVUK, 'getCookie').and.returnValue('1');
expect(element.is(':visible')).toBe(true);
bar.start(element);

element.find('.dismiss').trigger('click');
expect(element.is(':visible')).toBe(false);
expect(GOVUK.setCookie).toHaveBeenCalledWith('global_bar_seen', 999, {days: 84});
expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith('Global bar', 'Manually dismissed', {nonInteraction: 1});
});
});
});

0 comments on commit 4cebe28

Please sign in to comment.