Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add banner support #1583

Merged
merged 11 commits into from
Dec 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
andysellick marked this conversation as resolved.
Show resolved Hide resolved
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);
}
});