Skip to content

Commit

Permalink
Merge pull request #1583 from alphagov/add-banner-support
Browse files Browse the repository at this point in the history
Add banner support
  • Loading branch information
steventux authored Dec 5, 2018
2 parents 64ec12f + d59ae11 commit f62738d
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 0 deletions.
58 changes: 58 additions & 0 deletions app/assets/javascripts/modules/global-bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
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');
$('html').removeClass('show-global-bar');
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 @@ -158,6 +158,7 @@
if (userSurveys.canShowAnySurvey()) {
var activeSurvey = userSurveys.getActiveSurvey(userSurveys.defaultSurvey, userSurveys.smallSurveys)
if (activeSurvey !== undefined) {
$('#global-bar').hide(); // Hide global bar if one is showing
userSurveys.displaySurvey(activeSurvey)
}
}
Expand Down
45 changes: 45 additions & 0 deletions app/assets/stylesheets/helpers/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,48 @@
margin-right: .5em;
}
}


.show-global-bar #global-header-bar {
display: none;
}

.global-bar {
background-color: #BFE3E0;
display: none;
margin-bottom: 15px;
padding: 15px 0;

.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-bottom: 0;
margin-top: 0;

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

.global-bar-title {
display: block;
font-weight: 700;
margin-right: 10px;
}
}
}
29 changes: 29 additions & 0 deletions app/views/notifications/_global_bar.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<%
show_global_bar ||= false # Toggles the appearance of the global bar
title = "The title"
information = "Some information about something"
link_href = "https://www.gov.uk/"
link_text = %Q(More information<span class="visually-hidden"> about this</span>).html_safe
-%>
<% if show_global_bar %>
<% 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]-->
<% end %>
<!--[if gt IE 7]><!-->
<div id="global-bar" class="global-bar" data-module="global-bar" class="dont-print">
<div class="global-bar-message-container">
<p class="global-bar-message">
<span class="global-bar-title"><%= title %></span>
<%= information %>
<%= link_to(link_text, link_href, rel: "external noreferrer") %>
</p>
<a href="#hide-message"
class="dismiss"
role="button"
aria-controls="global-bar">Hide&nbsp;message</a>
</div>
</div>
<!--<![endif]-->
<% end %>
2 changes: 2 additions & 0 deletions app/views/root/_base.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
<% end %>

<% content_for :content do %>
<%= render "notifications/global_bar" %>

<div id="wrapper" class="group">
<%= yield :wrapper_content %>
</div>
Expand Down
16 changes: 16 additions & 0 deletions doc/global-banner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Global banner

A site-wide banner can be activated to convey important information on GOV.UK which is not deemed emergency level information.
The file `app/views/notifications/_global_bar.html.erb` contains the necessary minified JS and markup to activate and render the banner.

### Activating the global banner

In `app/views/notifications/_global_bar.html.erb`

1. Update the variables `title`, `information`, `link_href` and `link_text` with the relevant info.
2. Update the `show_global_bar` variable to `true`
3. Deploy static

The usual rules apply with static template caching.

![screenshot](/doc/global-banner.png?raw=true)
Binary file added doc/global-banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
133 changes: 133 additions & 0 deletions spec/javascripts/global-bar-class-toggle.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
describe("toggling a global bar HTML class based on cookie", function () {
var root = window;

/**
* The global bar needs to be activated early in page loading to prevent
* a flash of unstyled content, to do this we need to minify and inline
* the activation logic into the page head.
* This spec runs tests against both the full and minified sources of the
* activation JS because minification is not automated.
*/
function globalBarSource(fakeWindow) {
var window = fakeWindow || root;

/* begin minify */

(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);

/* end minify */
}


/**
* This is the minified version of the function above 'globalBarSource',
* when developing and testing updates and features,
* changes should be mirrored here manually.
* Only the code between the 'begin/end minify' comments should be copied.
*/
function globalBarMinified(fakeWindow) {
var window = fakeWindow || root;

/* begin minify */
!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);
/* end minify */
}

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);
}
});

0 comments on commit f62738d

Please sign in to comment.