diff --git a/app/assets/javascripts/collapsibleCheckboxes.js b/app/assets/javascripts/collapsibleCheckboxes.js index b92c10b4d..4f92673a0 100644 --- a/app/assets/javascripts/collapsibleCheckboxes.js +++ b/app/assets/javascripts/collapsibleCheckboxes.js @@ -220,6 +220,6 @@ this.summary.bindEvents(this); }; - GOVUK.Modules.CollapsibleCheckboxes = CollapsibleCheckboxes; + NotifyModules.CollapsibleCheckboxes = CollapsibleCheckboxes; }(window)); diff --git a/app/assets/javascripts/copyToClipboard.js b/app/assets/javascripts/copyToClipboard.js index d1699ed15..e4b9a6d28 100644 --- a/app/assets/javascripts/copyToClipboard.js +++ b/app/assets/javascripts/copyToClipboard.js @@ -90,11 +90,11 @@ .find('.usa-button').focus() ); - if ('stickAtBottomWhenScrolling' in GOVUK) { - GOVUK.stickAtBottomWhenScrolling.recalculate(); + if ('stickAtBottomWhenScrolling' in window.NotifyModules) { + window.NotifyModules.stickAtBottomWhenScrolling.recalculate(); } }; }; -})(window.GOVUK.Modules); +})(window.NotifyModules); diff --git a/app/assets/javascripts/enhancedTextbox.js b/app/assets/javascripts/enhancedTextbox.js index a4965857a..3c36bb14b 100644 --- a/app/assets/javascripts/enhancedTextbox.js +++ b/app/assets/javascripts/enhancedTextbox.js @@ -1,13 +1,15 @@ -(function(Modules) { +(function(global) { "use strict"; + window.NotifyModules = window.NotifyModules || {}; + if ( !('oninput' in document.createElement('input')) ) return; const tagPattern = /\(\(([^\)\((\?)]+)(\?\?)?([^\)\(]*)\)\)/g; - Modules.EnhancedTextbox = function() { + window.NotifyModules.EnhancedTextbox = function() { this.start = function(textarea) { @@ -58,8 +60,8 @@ ) ); - if ('stickAtBottomWhenScrolling' in GOVUK) { - GOVUK.stickAtBottomWhenScrolling.recalculate(); + if ('stickAtBottomWhenScrolling' in window.NotifyModules) { + window.NotifyModules.stickAtBottomWhenScrolling.recalculate(); } }; @@ -84,4 +86,4 @@ }; -})(window.GOVUK.Modules); +})(window); diff --git a/app/assets/javascripts/errorBanner.js b/app/assets/javascripts/errorBanner.js index c05c821ea..f5adf6364 100644 --- a/app/assets/javascripts/errorBanner.js +++ b/app/assets/javascripts/errorBanner.js @@ -1,6 +1,8 @@ (function (window) { "use strict"; + window.NotifyModules = window.NotifyModules || {}; + /* This module is intended to be used to show and hide an error banner based on a javascript trigger. You should make sure the banner has an appropriate aria-live attribute, and a tabindex of -1 so that screenreaders and keyboard users @@ -8,7 +10,7 @@ This may behave in unexpected ways if you have more than one element with the `banner-dangerous` class on your page. */ - window.GOVUK.ErrorBanner = { + window.NotifyModules.ErrorBanner = { hideBanner: () => $('.banner-dangerous').addClass('display-none'), showBanner: () => $('.banner-dangerous') .removeClass('display-none') diff --git a/app/assets/javascripts/errorTracking.js b/app/assets/javascripts/errorTracking.js index b0ec16f27..035a31b89 100644 --- a/app/assets/javascripts/errorTracking.js +++ b/app/assets/javascripts/errorTracking.js @@ -1,13 +1,13 @@ (function(window) { "use strict"; - window.GOVUK.Modules.TrackError = function() { + window.NotifyModules.TrackError = function() { this.start = function(component) { - if (!('analytics' in window.GOVUK)) return; - - window.GOVUK.analytics.trackEvent( + // Analytics tracking removed - no longer using GOVUK analytics + // If analytics is needed, integrate with USWDS analytics or custom solution + console.log( 'Error', $(component).data('error-type'), { diff --git a/app/assets/javascripts/fileUpload.js b/app/assets/javascripts/fileUpload.js index 19c53b971..16d2e74e9 100644 --- a/app/assets/javascripts/fileUpload.js +++ b/app/assets/javascripts/fileUpload.js @@ -55,7 +55,7 @@ function initUploadStatusAnnouncer() { }); }; }; -})(window.GOVUK.Modules); +})(window.NotifyModules); if (typeof module !== 'undefined' && module.exports) { module.exports = { diff --git a/app/assets/javascripts/fullscreenTable.js b/app/assets/javascripts/fullscreenTable.js index d4062e71c..7662131d5 100644 --- a/app/assets/javascripts/fullscreenTable.js +++ b/app/assets/javascripts/fullscreenTable.js @@ -24,10 +24,10 @@ .on('scroll', this.maintainHeight) if ( - window.GOVUK.stickAtBottomWhenScrolling && - window.GOVUK.stickAtBottomWhenScrolling.recalculate + window.NotifyModules.stickAtBottomWhenScrolling && + window.NotifyModules.stickAtBottomWhenScrolling.recalculate ) { - window.GOVUK.stickAtBottomWhenScrolling.recalculate(); + window.NotifyModules.stickAtBottomWhenScrolling.recalculate(); } this.maintainWidth(); @@ -120,4 +120,4 @@ }; -})(window.GOVUK.Modules); +})(window.NotifyModules); diff --git a/app/assets/javascripts/listEntry.js b/app/assets/javascripts/listEntry.js index 4f7926245..f5c953455 100644 --- a/app/assets/javascripts/listEntry.js +++ b/app/assets/javascripts/listEntry.js @@ -222,4 +222,4 @@ }; -})(window.GOVUK.Modules); +})(window.NotifyModules); diff --git a/app/assets/javascripts/liveSearch.js b/app/assets/javascripts/liveSearch.js index fd3c62002..4c0035103 100644 --- a/app/assets/javascripts/liveSearch.js +++ b/app/assets/javascripts/liveSearch.js @@ -62,7 +62,9 @@ // make sticky JS recalculate its cache of the element's position // because live search can change the height document if ('stickAtBottomWhenScrolling' in GOVUK) { - GOVUK.stickAtBottomWhenScrolling.recalculate(); + if (window.NotifyModules && window.NotifyModules.stickAtBottomWhenScrolling) { + window.NotifyModules.stickAtBottomWhenScrolling.recalculate(); + } } }; @@ -95,4 +97,4 @@ }; -})(window.GOVUK.Modules); +})(window.NotifyModules); diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 758030e2c..185b7a4d8 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -1,9 +1,27 @@ -window.GOVUK.Frontend.initAll(); +// Initialize USWDS components +if (window.uswds) { + window.uswds.init(); +} -var showHideContent = new GOVUK.ShowHideContent(); -showHideContent.init(); +// Initialize custom modules +window.NotifyModules = window.NotifyModules || {}; +window.NotifyModules.start = function() { + var modules = document.querySelectorAll('[data-module]'); + modules.forEach(function(element) { + var moduleName = element.getAttribute('data-module'); + var moduleStarted = element.getAttribute('data-module-started'); -$(() => GOVUK.modules.start()); + if (!moduleStarted && window.NotifyModules[moduleName]) { + var module = new window.NotifyModules[moduleName](); + if (module.start) { + module.start(element); + } + element.setAttribute('data-module-started', 'true'); + } + }); +}; + +$(() => window.NotifyModules.start()); $(() => $('.error-message, .usa-error-message').eq(0).parent('label').next('input').trigger('focus')); diff --git a/app/assets/javascripts/modules/all.mjs b/app/assets/javascripts/modules/all.mjs index 6312f03dc..baa747338 100644 --- a/app/assets/javascripts/modules/all.mjs +++ b/app/assets/javascripts/modules/all.mjs @@ -4,76 +4,16 @@ // When processed by a bundler, this is turned into a Immediately Invoked Function Expression (IIFE) // The IIFE format allows it to run in browsers that don't support JS Modules. // -// Exported items will be added to the window.GOVUK namespace. -// For example, `export { Frontend }` will assign `Frontend` to `window.Frontend` - -// GOVUK Frontend modules -import Header from 'govuk-frontend/components/header/header'; -import Details from 'govuk-frontend/components/details/details'; -import Button from 'govuk-frontend/components/button/button'; -import Radios from 'govuk-frontend/components/radios/radios'; +// Exported items will be added to the window.NotifyModules namespace. // Modules from 3rd party vendors import morphdom from 'morphdom'; -/** - * TODO: Ideally this would be a NodeList.prototype.forEach polyfill - * This seems to fail in IE8, requires more investigation. - * See: https://github.com/imagitama/nodelist-foreach-polyfill - */ -function nodeListForEach(nodes, callback) { - if (window.NodeList.prototype.forEach) { - return nodes.forEach(callback) - } - for (var i = 0; i < nodes.length; i++) { - callback.call(window, nodes[i], i, nodes); - } -} - -// Copy of the initAll function from https://github.com/alphagov/govuk-frontend/blob/v2.13.0/src/all.js -// except it only includes, and initialises, the components used by this application. -function initAll(options) { - // Set the options to an empty object by default if no options are passed. - options = typeof options !== 'undefined' ? options : {} - - // Allow the user to initialise US Frontend in only certain sections of the page - // Defaults to the entire document if nothing is set. - var scope = typeof options.scope !== 'undefined' ? options.scope : document - - // Find all buttons with [role=button] on the scope to enhance. - new Button(scope).init() - - // Find all global details elements to enhance. - var $details = scope.querySelectorAll('details') - nodeListForEach($details, function ($detail) { - new Details($detail).init() - }) - - // Find first header module to enhance. - var $toggleButton = scope.querySelector('[data-module="header"]') - new Header($toggleButton).init() - - var $radios = scope.querySelectorAll('[data-module="radios"]') - nodeListForEach($radios, function ($radio) { - new Radios($radio).init() - }) -} - -// Create separate namespace for GOVUK Frontend. -var Frontend = { - "Header": Header, - "Details": Details, - "Button": Button, - "initAll": initAll -} - var vendor = { - "morphdom": morphdom -} + morphdom: morphdom, +}; -// The exported object will be assigned to window.GOVUK in our production code +// The exported object will be assigned to window in our production code // (bundled into an IIFE by RollupJS) -export { - Frontend, - vendor -} +// Export morphdom globally for backward compatibility +export { morphdom, vendor }; diff --git a/app/assets/javascripts/radioSelect.js b/app/assets/javascripts/radioSelect.js index 02b607c8e..044b4a61f 100644 --- a/app/assets/javascripts/radioSelect.js +++ b/app/assets/javascripts/radioSelect.js @@ -2,7 +2,7 @@ "use strict"; - var Modules = global.GOVUK.Modules; + var Modules = global.NotifyModules; // Template functions for rendering component states let renderStates = { diff --git a/app/assets/javascripts/radioSlider.js b/app/assets/javascripts/radioSlider.js index d0dffce99..cf3371051 100644 --- a/app/assets/javascripts/radioSlider.js +++ b/app/assets/javascripts/radioSlider.js @@ -2,7 +2,7 @@ "use strict"; - global.GOVUK.Modules.RadioSlider = function() { + global.NotifyModules.RadioSlider = function() { this.start = function(component) { diff --git a/app/assets/javascripts/stick-to-window-when-scrolling.js b/app/assets/javascripts/stick-to-window-when-scrolling.js index da1129742..3da64e56b 100644 --- a/app/assets/javascripts/stick-to-window-when-scrolling.js +++ b/app/assets/javascripts/stick-to-window-when-scrolling.js @@ -2,7 +2,7 @@ 'use strict'; var $ = global.jQuery; - var GOVUK = global.GOVUK || {}; + var NotifyModules = global.NotifyModules || {}; var _mode = 'default'; // Constructor to make objects representing the area sticky elements can scroll in @@ -677,7 +677,7 @@ } self.setElementDimensions(elObj, onDimensionsSet); - }; + }; Sticky.prototype.remove = function (el) { if ($.inArray(el, this._els) !== -1) { @@ -989,7 +989,7 @@ el.unstop(); }; - GOVUK.stickAtTopWhenScrolling = stickAtTop; - GOVUK.stickAtBottomWhenScrolling = stickAtBottom; - global.GOVUK = GOVUK; + NotifyModules.stickAtTopWhenScrolling = stickAtTop; + NotifyModules.stickAtBottomWhenScrolling = stickAtBottom; + global.NotifyModules = NotifyModules; })(window); diff --git a/app/assets/javascripts/templateFolderForm.js b/app/assets/javascripts/templateFolderForm.js index b024ced5a..f8040f833 100644 --- a/app/assets/javascripts/templateFolderForm.js +++ b/app/assets/javascripts/templateFolderForm.js @@ -357,4 +357,4 @@ `).get(0); }; -})(window.GOVUK.Modules); +})(window.NotifyModules); diff --git a/app/assets/javascripts/timeoutPopup.js b/app/assets/javascripts/timeoutPopup.js index ed33cf903..6e7fa1fe2 100644 --- a/app/assets/javascripts/timeoutPopup.js +++ b/app/assets/javascripts/timeoutPopup.js @@ -1,6 +1,5 @@ -window.GOVUK = window.GOVUK || {}; -window.GOVUK.Modules = window.GOVUK.Modules || {}; -window.GOVUK.Modules.TimeoutPopup = window.GOVUK.Modules.TimeoutPopup || {}; +window.NotifyModules = window.NotifyModules || {}; +window.NotifyModules.TimeoutPopup = window.NotifyModules.TimeoutPopup || {}; (function(global) { "use strict"; @@ -56,10 +55,10 @@ window.GOVUK.Modules.TimeoutPopup = window.GOVUK.Modules.TimeoutPopup || {}; setTimeout(setSessionTimer, 25 * 60 * 1000); } - global.GOVUK.Modules.TimeoutPopup.checkTimer = checkTimer; - global.GOVUK.Modules.TimeoutPopup.expireUserSession = expireUserSession; - global.GOVUK.Modules.TimeoutPopup.signoutUser = signoutUser; - global.GOVUK.Modules.TimeoutPopup.extendSession = extendSession; - global.GOVUK.Modules.TimeoutPopup.showTimer = showTimer; - global.GOVUK.Modules.TimeoutPopup.closeTimer = closeTimer; + global.NotifyModules.TimeoutPopup.checkTimer = checkTimer; + global.NotifyModules.TimeoutPopup.expireUserSession = expireUserSession; + global.NotifyModules.TimeoutPopup.signoutUser = signoutUser; + global.NotifyModules.TimeoutPopup.extendSession = extendSession; + global.NotifyModules.TimeoutPopup.showTimer = showTimer; + global.NotifyModules.TimeoutPopup.closeTimer = closeTimer; })(window); diff --git a/app/assets/javascripts/updateContent.js b/app/assets/javascripts/updateContent.js index d488cd9a2..3191e034a 100644 --- a/app/assets/javascripts/updateContent.js +++ b/app/assets/javascripts/updateContent.js @@ -2,7 +2,8 @@ "use strict"; var queues = {}; - var morphdom = global.GOVUK.vendor.morphdom; + // morphdom is now imported directly from node_modules + var morphdom = window.morphdom || (window.NotifyModules && window.NotifyModules.vendor && window.NotifyModules.vendor.morphdom); var defaultInterval = 2000; var interval = 0; @@ -105,7 +106,7 @@ ); }; - global.GOVUK.Modules.UpdateContent = function() { + global.NotifyModules.UpdateContent = function() { this.start = component => { var $component = $(component); @@ -143,6 +144,6 @@ }; - global.GOVUK.Modules.UpdateContent.calculateBackoff = calculateBackoff; + global.NotifyModules.UpdateContent.calculateBackoff = calculateBackoff; })(window); diff --git a/app/assets/javascripts/updateStatus.js b/app/assets/javascripts/updateStatus.js index b02ae1690..b128439da 100644 --- a/app/assets/javascripts/updateStatus.js +++ b/app/assets/javascripts/updateStatus.js @@ -1,7 +1,7 @@ (function(window) { "use strict"; - window.GOVUK.Modules.UpdateStatus = function() { + window.NotifyModules.UpdateStatus = function() { const getRenderer = $component => response => $component.html( response.html diff --git a/gulpfile.js b/gulpfile.js index 087039a13..73a11ab8f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -37,7 +37,7 @@ const javascripts = () => { ], output: { format: 'iife', - name: 'GOVUK', + name: 'NotifyModules', }, }) .pipe(source('all.mjs'))