govuk_publishing_components 34.7.0 → 34.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-event-tracker.js +3 -10
  3. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-form-tracker.js +113 -0
  4. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +2 -11
  5. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-schemas.js +15 -1
  6. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-specialist-link-tracker.js +20 -29
  7. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4.js +1 -0
  8. data/app/models/govuk_publishing_components/component_doc.rb +14 -0
  9. data/app/models/govuk_publishing_components/component_wrapper_helper_options.rb +14 -0
  10. data/app/views/govuk_publishing_components/component_guide/show.html.erb +21 -6
  11. data/app/views/govuk_publishing_components/components/_action_link.html.erb +5 -2
  12. data/app/views/govuk_publishing_components/components/_breadcrumbs.html.erb +6 -2
  13. data/app/views/govuk_publishing_components/components/_details.html.erb +3 -1
  14. data/app/views/govuk_publishing_components/components/docs/action_link.yml +1 -0
  15. data/app/views/govuk_publishing_components/components/docs/breadcrumbs.yml +1 -0
  16. data/app/views/govuk_publishing_components/components/docs/details.yml +17 -0
  17. data/lib/govuk_publishing_components/presenters/component_wrapper_helper.rb +78 -0
  18. data/lib/govuk_publishing_components/presenters/related_navigation_helper.rb +0 -7
  19. data/lib/govuk_publishing_components/version.rb +1 -1
  20. data/lib/govuk_publishing_components.rb +1 -0
  21. data/node_modules/govuk-frontend/govuk/all.js +4029 -3792
  22. data/node_modules/govuk-frontend/govuk/all.js.map +1 -0
  23. data/node_modules/govuk-frontend/govuk/common/closest-attribute-value.js +52 -51
  24. data/node_modules/govuk-frontend/govuk/common/closest-attribute-value.js.map +1 -0
  25. data/node_modules/govuk-frontend/govuk/common/index.js +153 -145
  26. data/node_modules/govuk-frontend/govuk/common/index.js.map +1 -0
  27. data/node_modules/govuk-frontend/govuk/common/normalise-dataset.js +324 -321
  28. data/node_modules/govuk-frontend/govuk/common/normalise-dataset.js.map +1 -0
  29. data/node_modules/govuk-frontend/govuk/common.js +154 -146
  30. data/node_modules/govuk-frontend/govuk/common.js.map +1 -0
  31. data/node_modules/govuk-frontend/govuk/components/_all.scss +1 -1
  32. data/node_modules/govuk-frontend/govuk/components/accordion/_index.scss +23 -4
  33. data/node_modules/govuk-frontend/govuk/components/accordion/accordion.js +2059 -1654
  34. data/node_modules/govuk-frontend/govuk/components/accordion/accordion.js.map +1 -0
  35. data/node_modules/govuk-frontend/govuk/components/accordion/fixtures.json +11 -11
  36. data/node_modules/govuk-frontend/govuk/components/accordion/template.njk +1 -1
  37. data/node_modules/govuk-frontend/govuk/components/back-link/_index.scss +19 -19
  38. data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_index.scss +21 -10
  39. data/node_modules/govuk-frontend/govuk/components/button/button.js +927 -917
  40. data/node_modules/govuk-frontend/govuk/components/button/button.js.map +1 -0
  41. data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js +2050 -2040
  42. data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js.map +1 -0
  43. data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js +1155 -1147
  44. data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js.map +1 -0
  45. data/node_modules/govuk-frontend/govuk/components/cookie-banner/fixtures.json +23 -23
  46. data/node_modules/govuk-frontend/govuk/components/cookie-banner/template.njk +1 -1
  47. data/node_modules/govuk-frontend/govuk/components/details/details.js +800 -799
  48. data/node_modules/govuk-frontend/govuk/components/details/details.js.map +1 -0
  49. data/node_modules/govuk-frontend/govuk/components/error-summary/error-summary.js +1058 -1045
  50. data/node_modules/govuk-frontend/govuk/components/error-summary/error-summary.js.map +1 -0
  51. data/node_modules/govuk-frontend/govuk/components/header/_index.scss +6 -0
  52. data/node_modules/govuk-frontend/govuk/components/header/header.js +646 -998
  53. data/node_modules/govuk-frontend/govuk/components/header/header.js.map +1 -0
  54. data/node_modules/govuk-frontend/govuk/components/notification-banner/notification-banner.js +760 -752
  55. data/node_modules/govuk-frontend/govuk/components/notification-banner/notification-banner.js.map +1 -0
  56. data/node_modules/govuk-frontend/govuk/components/pagination/fixtures.json +61 -0
  57. data/node_modules/govuk-frontend/govuk/components/pagination/template.njk +1 -1
  58. data/node_modules/govuk-frontend/govuk/components/phase-banner/macro-options.json +1 -1
  59. data/node_modules/govuk-frontend/govuk/components/radios/radios.js +1110 -1107
  60. data/node_modules/govuk-frontend/govuk/components/radios/radios.js.map +1 -0
  61. data/node_modules/govuk-frontend/govuk/components/skip-link/skip-link.js +1017 -1014
  62. data/node_modules/govuk-frontend/govuk/components/skip-link/skip-link.js.map +1 -0
  63. data/node_modules/govuk-frontend/govuk/components/summary-list/_index.scss +107 -0
  64. data/node_modules/govuk-frontend/govuk/components/summary-list/fixtures.json +318 -23
  65. data/node_modules/govuk-frontend/govuk/components/summary-list/macro-options.json +110 -0
  66. data/node_modules/govuk-frontend/govuk/components/summary-list/template.njk +72 -28
  67. data/node_modules/govuk-frontend/govuk/components/tabs/tabs.js +1392 -1264
  68. data/node_modules/govuk-frontend/govuk/components/tabs/tabs.js.map +1 -0
  69. data/node_modules/govuk-frontend/govuk/i18n.js +363 -364
  70. data/node_modules/govuk-frontend/govuk/i18n.js.map +1 -0
  71. data/node_modules/govuk-frontend/govuk/settings/_measurements.scss +5 -5
  72. data/node_modules/govuk-frontend/govuk/vendor/polyfills/DOMTokenList.js +242 -241
  73. data/node_modules/govuk-frontend/govuk/vendor/polyfills/DOMTokenList.js.map +1 -0
  74. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Date/now.js +13 -12
  75. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Date/now.js.map +1 -0
  76. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Document.js +17 -16
  77. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Document.js.map +1 -0
  78. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/classList.js +547 -546
  79. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/classList.js.map +1 -0
  80. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/closest.js +37 -36
  81. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/closest.js.map +1 -0
  82. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/dataset.js +251 -250
  83. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/dataset.js.map +1 -0
  84. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/matches.js +21 -20
  85. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/matches.js.map +1 -0
  86. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/nextElementSibling.js +198 -197
  87. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/nextElementSibling.js.map +1 -0
  88. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/previousElementSibling.js +198 -197
  89. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/previousElementSibling.js.map +1 -0
  90. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element.js +106 -105
  91. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element.js.map +1 -0
  92. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Event.js +400 -399
  93. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Event.js.map +1 -0
  94. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Function/prototype/bind.js +239 -238
  95. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Function/prototype/bind.js.map +1 -0
  96. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Object/defineProperty.js +72 -71
  97. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Object/defineProperty.js.map +1 -0
  98. data/node_modules/govuk-frontend/govuk/vendor/polyfills/String/prototype/trim.js +14 -13
  99. data/node_modules/govuk-frontend/govuk/vendor/polyfills/String/prototype/trim.js.map +1 -0
  100. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Window.js +17 -16
  101. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Window.js.map +1 -0
  102. data/node_modules/govuk-frontend/govuk-esm/all.mjs +2 -2
  103. data/node_modules/govuk-frontend/govuk-esm/common/index.mjs +17 -10
  104. data/node_modules/govuk-frontend/govuk-esm/common/normalise-dataset.mjs +3 -1
  105. data/node_modules/govuk-frontend/govuk-esm/components/accordion/accordion.mjs +135 -52
  106. data/node_modules/govuk-frontend/govuk-esm/components/button/button.mjs +11 -9
  107. data/node_modules/govuk-frontend/govuk-esm/components/character-count/character-count.mjs +10 -7
  108. data/node_modules/govuk-frontend/govuk-esm/components/checkboxes/checkboxes.mjs +24 -18
  109. data/node_modules/govuk-frontend/govuk-esm/components/details/details.mjs +23 -16
  110. data/node_modules/govuk-frontend/govuk-esm/components/error-summary/error-summary.mjs +15 -11
  111. data/node_modules/govuk-frontend/govuk-esm/components/header/header.mjs +3 -2
  112. data/node_modules/govuk-frontend/govuk-esm/components/notification-banner/notification-banner.mjs +3 -4
  113. data/node_modules/govuk-frontend/govuk-esm/components/radios/radios.mjs +10 -9
  114. data/node_modules/govuk-frontend/govuk-esm/components/skip-link/skip-link.mjs +5 -3
  115. data/node_modules/govuk-frontend/govuk-esm/components/tabs/tabs.mjs +165 -38
  116. data/node_modules/govuk-frontend/govuk-esm/i18n.mjs +9 -11
  117. data/node_modules/govuk-frontend/package.json +1 -1
  118. metadata +37 -2
@@ -1,808 +1,816 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
- typeof define === 'function' && define.amd ? define('GOVUKFrontend.NotificationBanner', factory) :
4
- (global.GOVUKFrontend = global.GOVUKFrontend || {}, global.GOVUKFrontend.NotificationBanner = factory());
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define('GOVUKFrontend.NotificationBanner', factory) :
4
+ (global.GOVUKFrontend = global.GOVUKFrontend || {}, global.GOVUKFrontend.NotificationBanner = factory());
5
5
  }(this, (function () { 'use strict';
6
6
 
7
- (function(undefined) {
7
+ /**
8
+ * Common helpers which do not require polyfill.
9
+ *
10
+ * IMPORTANT: If a helper require a polyfill, please isolate it in its own module
11
+ * so that the polyfill can be properly tree-shaken and does not burden
12
+ * the components that do not need that helper
13
+ *
14
+ * @module common/index
15
+ */
8
16
 
9
- // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Window/detect.js
10
- var detect = ('Window' in this);
17
+ /**
18
+ * Config flattening function
19
+ *
20
+ * Takes any number of objects, flattens them into namespaced key-value pairs,
21
+ * (e.g. {'i18n.showSection': 'Show section'}) and combines them together, with
22
+ * greatest priority on the LAST item passed in.
23
+ *
24
+ * @returns {Object<string, unknown>} A flattened object of key-value pairs.
25
+ */
26
+ function mergeConfigs (/* configObject1, configObject2, ...configObjects */) {
27
+ /**
28
+ * Function to take nested objects and flatten them to a dot-separated keyed
29
+ * object. Doing this means we don't need to do any deep/recursive merging of
30
+ * each of our objects, nor transform our dataset from a flat list into a
31
+ * nested object.
32
+ *
33
+ * @param {Object<string, unknown>} configObject - Deeply nested object
34
+ * @returns {Object<string, unknown>} Flattened object with dot-separated keys
35
+ */
36
+ var flattenObject = function (configObject) {
37
+ // Prepare an empty return object
38
+ var flattenedObject = {};
39
+
40
+ /**
41
+ * Our flattening function, this is called recursively for each level of
42
+ * depth in the object. At each level we prepend the previous level names to
43
+ * the key using `prefix`.
44
+ *
45
+ * @param {Partial<Object<string, unknown>>} obj - Object to flatten
46
+ * @param {string} [prefix] - Optional dot-separated prefix
47
+ */
48
+ var flattenLoop = function (obj, prefix) {
49
+ // Loop through keys...
50
+ for (var key in obj) {
51
+ // Check to see if this is a prototypical key/value,
52
+ // if it is, skip it.
53
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) {
54
+ continue
55
+ }
56
+ var value = obj[key];
57
+ var prefixedKey = prefix ? prefix + '.' + key : key;
58
+ if (typeof value === 'object') {
59
+ // If the value is a nested object, recurse over that too
60
+ flattenLoop(value, prefixedKey);
61
+ } else {
62
+ // Otherwise, add this value to our return object
63
+ flattenedObject[prefixedKey] = value;
64
+ }
65
+ }
66
+ };
11
67
 
12
- if (detect) return
68
+ // Kick off the recursive loop
69
+ flattenLoop(configObject);
70
+ return flattenedObject
71
+ };
13
72
 
14
- // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Window&flags=always
15
- if ((typeof WorkerGlobalScope === "undefined") && (typeof importScripts !== "function")) {
16
- (function (global) {
17
- if (global.constructor) {
18
- global.Window = global.constructor;
19
- } else {
20
- (global.Window = global.constructor = new Function('return function Window() {}')()).prototype = this;
21
- }
22
- }(this));
23
- }
73
+ // Start with an empty object as our base
74
+ var formattedConfigObject = {};
24
75
 
25
- })
26
- .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
76
+ // Loop through each of the remaining passed objects and push their keys
77
+ // one-by-one into configObject. Any duplicate keys will override the existing
78
+ // key with the new value.
79
+ for (var i = 0; i < arguments.length; i++) {
80
+ var obj = flattenObject(arguments[i]);
81
+ for (var key in obj) {
82
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
83
+ formattedConfigObject[key] = obj[key];
84
+ }
85
+ }
86
+ }
27
87
 
28
- (function(undefined) {
88
+ return formattedConfigObject
89
+ }
29
90
 
30
- // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Document/detect.js
31
- var detect = ("Document" in this);
91
+ /**
92
+ * @callback nodeListIterator
93
+ * @param {Element} value - The current node being iterated on
94
+ * @param {number} index - The current index in the iteration
95
+ * @param {NodeListOf<Element>} nodes - NodeList from querySelectorAll()
96
+ * @returns {void}
97
+ */
32
98
 
33
- if (detect) return
99
+ (function(undefined) {
100
+
101
+ // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Object/defineProperty/detect.js
102
+ var detect = (
103
+ // In IE8, defineProperty could only act on DOM elements, so full support
104
+ // for the feature requires the ability to set a property on an arbitrary object
105
+ 'defineProperty' in Object && (function() {
106
+ try {
107
+ var a = {};
108
+ Object.defineProperty(a, 'test', {value:42});
109
+ return true;
110
+ } catch(e) {
111
+ return false
112
+ }
113
+ }())
114
+ );
34
115
 
35
- // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Document&flags=always
36
- if ((typeof WorkerGlobalScope === "undefined") && (typeof importScripts !== "function")) {
116
+ if (detect) return
37
117
 
38
- if (this.HTMLDocument) { // IE8
118
+ // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Object.defineProperty&flags=always
119
+ (function (nativeDefineProperty) {
120
+
121
+ var supportsAccessors = Object.prototype.hasOwnProperty('__defineGetter__');
122
+ var ERR_ACCESSORS_NOT_SUPPORTED = 'Getters & setters cannot be defined on this javascript engine';
123
+ var ERR_VALUE_ACCESSORS = 'A property cannot both have accessors and be writable or have a value';
124
+
125
+ Object.defineProperty = function defineProperty(object, property, descriptor) {
126
+
127
+ // Where native support exists, assume it
128
+ if (nativeDefineProperty && (object === window || object === document || object === Element.prototype || object instanceof Element)) {
129
+ return nativeDefineProperty(object, property, descriptor);
130
+ }
131
+
132
+ if (object === null || !(object instanceof Object || typeof object === 'object')) {
133
+ throw new TypeError('Object.defineProperty called on non-object');
134
+ }
135
+
136
+ if (!(descriptor instanceof Object)) {
137
+ throw new TypeError('Property description must be an object');
138
+ }
139
+
140
+ var propertyString = String(property);
141
+ var hasValueOrWritable = 'value' in descriptor || 'writable' in descriptor;
142
+ var getterType = 'get' in descriptor && typeof descriptor.get;
143
+ var setterType = 'set' in descriptor && typeof descriptor.set;
144
+
145
+ // handle descriptor.get
146
+ if (getterType) {
147
+ if (getterType !== 'function') {
148
+ throw new TypeError('Getter must be a function');
149
+ }
150
+ if (!supportsAccessors) {
151
+ throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
152
+ }
153
+ if (hasValueOrWritable) {
154
+ throw new TypeError(ERR_VALUE_ACCESSORS);
155
+ }
156
+ Object.__defineGetter__.call(object, propertyString, descriptor.get);
157
+ } else {
158
+ object[propertyString] = descriptor.value;
159
+ }
160
+
161
+ // handle descriptor.set
162
+ if (setterType) {
163
+ if (setterType !== 'function') {
164
+ throw new TypeError('Setter must be a function');
165
+ }
166
+ if (!supportsAccessors) {
167
+ throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
168
+ }
169
+ if (hasValueOrWritable) {
170
+ throw new TypeError(ERR_VALUE_ACCESSORS);
171
+ }
172
+ Object.__defineSetter__.call(object, propertyString, descriptor.set);
173
+ }
174
+
175
+ // OK to define value unconditionally - if a getter has been specified as well, an error would be thrown above
176
+ if ('value' in descriptor) {
177
+ object[propertyString] = descriptor.value;
178
+ }
179
+
180
+ return object;
181
+ };
182
+ }(Object.defineProperty));
183
+ })
184
+ .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
185
+
186
+ (function(undefined) {
187
+
188
+ // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Document/detect.js
189
+ var detect = ("Document" in this);
39
190
 
40
- // HTMLDocument is an extension of Document. If the browser has HTMLDocument but not Document, the former will suffice as an alias for the latter.
41
- this.Document = this.HTMLDocument;
191
+ if (detect) return
42
192
 
43
- } else {
193
+ // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Document&flags=always
194
+ if ((typeof WorkerGlobalScope === "undefined") && (typeof importScripts !== "function")) {
44
195
 
45
- // Create an empty function to act as the missing constructor for the document object, attach the document object as its prototype. The function needs to be anonymous else it is hoisted and causes the feature detect to prematurely pass, preventing the assignments below being made.
46
- this.Document = this.HTMLDocument = document.constructor = (new Function('return function Document() {}')());
47
- this.Document.prototype = document;
48
- }
49
- }
50
-
51
-
52
- })
53
- .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
54
-
55
- (function(undefined) {
56
-
57
- // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Element/detect.js
58
- var detect = ('Element' in this && 'HTMLElement' in this);
59
-
60
- if (detect) return
61
-
62
- // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Element&flags=always
63
- (function () {
64
-
65
- // IE8
66
- if (window.Element && !window.HTMLElement) {
67
- window.HTMLElement = window.Element;
68
- return;
69
- }
70
-
71
- // create Element constructor
72
- window.Element = window.HTMLElement = new Function('return function Element() {}')();
73
-
74
- // generate sandboxed iframe
75
- var vbody = document.appendChild(document.createElement('body'));
76
- var frame = vbody.appendChild(document.createElement('iframe'));
77
-
78
- // use sandboxed iframe to replicate Element functionality
79
- var frameDocument = frame.contentWindow.document;
80
- var prototype = Element.prototype = frameDocument.appendChild(frameDocument.createElement('*'));
81
- var cache = {};
82
-
83
- // polyfill Element.prototype on an element
84
- var shiv = function (element, deep) {
85
- var
86
- childNodes = element.childNodes || [],
87
- index = -1,
88
- key, value, childNode;
89
-
90
- if (element.nodeType === 1 && element.constructor !== Element) {
91
- element.constructor = Element;
92
-
93
- for (key in cache) {
94
- value = cache[key];
95
- element[key] = value;
96
- }
97
- }
98
-
99
- while (childNode = deep && childNodes[++index]) {
100
- shiv(childNode, deep);
101
- }
102
-
103
- return element;
104
- };
105
-
106
- var elements = document.getElementsByTagName('*');
107
- var nativeCreateElement = document.createElement;
108
- var interval;
109
- var loopLimit = 100;
110
-
111
- prototype.attachEvent('onpropertychange', function (event) {
112
- var
113
- propertyName = event.propertyName,
114
- nonValue = !cache.hasOwnProperty(propertyName),
115
- newValue = prototype[propertyName],
116
- oldValue = cache[propertyName],
117
- index = -1,
118
- element;
119
-
120
- while (element = elements[++index]) {
121
- if (element.nodeType === 1) {
122
- if (nonValue || element[propertyName] === oldValue) {
123
- element[propertyName] = newValue;
124
- }
125
- }
126
- }
127
-
128
- cache[propertyName] = newValue;
129
- });
130
-
131
- prototype.constructor = Element;
132
-
133
- if (!prototype.hasAttribute) {
134
- // <Element>.hasAttribute
135
- prototype.hasAttribute = function hasAttribute(name) {
136
- return this.getAttribute(name) !== null;
137
- };
138
- }
139
-
140
- // Apply Element prototype to the pre-existing DOM as soon as the body element appears.
141
- function bodyCheck() {
142
- if (!(loopLimit--)) clearTimeout(interval);
143
- if (document.body && !document.body.prototype && /(complete|interactive)/.test(document.readyState)) {
144
- shiv(document, true);
145
- if (interval && document.body.prototype) clearTimeout(interval);
146
- return (!!document.body.prototype);
147
- }
148
- return false;
149
- }
150
- if (!bodyCheck()) {
151
- document.onreadystatechange = bodyCheck;
152
- interval = setInterval(bodyCheck, 25);
153
- }
154
-
155
- // Apply to any new elements created after load
156
- document.createElement = function createElement(nodeName) {
157
- var element = nativeCreateElement(String(nodeName).toLowerCase());
158
- return shiv(element);
159
- };
160
-
161
- // remove sandboxed iframe
162
- document.removeChild(vbody);
163
- }());
164
-
165
- })
166
- .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
167
-
168
- (function(undefined) {
169
-
170
- // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Object/defineProperty/detect.js
171
- var detect = (
172
- // In IE8, defineProperty could only act on DOM elements, so full support
173
- // for the feature requires the ability to set a property on an arbitrary object
174
- 'defineProperty' in Object && (function() {
175
- try {
176
- var a = {};
177
- Object.defineProperty(a, 'test', {value:42});
178
- return true;
179
- } catch(e) {
180
- return false
181
- }
182
- }())
183
- );
184
-
185
- if (detect) return
186
-
187
- // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Object.defineProperty&flags=always
188
- (function (nativeDefineProperty) {
189
-
190
- var supportsAccessors = Object.prototype.hasOwnProperty('__defineGetter__');
191
- var ERR_ACCESSORS_NOT_SUPPORTED = 'Getters & setters cannot be defined on this javascript engine';
192
- var ERR_VALUE_ACCESSORS = 'A property cannot both have accessors and be writable or have a value';
193
-
194
- Object.defineProperty = function defineProperty(object, property, descriptor) {
195
-
196
- // Where native support exists, assume it
197
- if (nativeDefineProperty && (object === window || object === document || object === Element.prototype || object instanceof Element)) {
198
- return nativeDefineProperty(object, property, descriptor);
199
- }
200
-
201
- if (object === null || !(object instanceof Object || typeof object === 'object')) {
202
- throw new TypeError('Object.defineProperty called on non-object');
203
- }
204
-
205
- if (!(descriptor instanceof Object)) {
206
- throw new TypeError('Property description must be an object');
207
- }
208
-
209
- var propertyString = String(property);
210
- var hasValueOrWritable = 'value' in descriptor || 'writable' in descriptor;
211
- var getterType = 'get' in descriptor && typeof descriptor.get;
212
- var setterType = 'set' in descriptor && typeof descriptor.set;
213
-
214
- // handle descriptor.get
215
- if (getterType) {
216
- if (getterType !== 'function') {
217
- throw new TypeError('Getter must be a function');
218
- }
219
- if (!supportsAccessors) {
220
- throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
221
- }
222
- if (hasValueOrWritable) {
223
- throw new TypeError(ERR_VALUE_ACCESSORS);
224
- }
225
- Object.__defineGetter__.call(object, propertyString, descriptor.get);
226
- } else {
227
- object[propertyString] = descriptor.value;
228
- }
229
-
230
- // handle descriptor.set
231
- if (setterType) {
232
- if (setterType !== 'function') {
233
- throw new TypeError('Setter must be a function');
234
- }
235
- if (!supportsAccessors) {
236
- throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
237
- }
238
- if (hasValueOrWritable) {
239
- throw new TypeError(ERR_VALUE_ACCESSORS);
240
- }
241
- Object.__defineSetter__.call(object, propertyString, descriptor.set);
242
- }
243
-
244
- // OK to define value unconditionally - if a getter has been specified as well, an error would be thrown above
245
- if ('value' in descriptor) {
246
- object[propertyString] = descriptor.value;
247
- }
248
-
249
- return object;
250
- };
251
- }(Object.defineProperty));
252
- })
253
- .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
254
-
255
- (function(undefined) {
256
-
257
- // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Event/detect.js
258
- var detect = (
259
- (function(global) {
260
-
261
- if (!('Event' in global)) return false;
262
- if (typeof global.Event === 'function') return true;
263
-
264
- try {
265
-
266
- // In IE 9-11, the Event object exists but cannot be instantiated
267
- new Event('click');
268
- return true;
269
- } catch(e) {
270
- return false;
271
- }
272
- }(this))
273
- );
274
-
275
- if (detect) return
276
-
277
- // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Event&flags=always
278
- (function () {
279
- var unlistenableWindowEvents = {
280
- click: 1,
281
- dblclick: 1,
282
- keyup: 1,
283
- keypress: 1,
284
- keydown: 1,
285
- mousedown: 1,
286
- mouseup: 1,
287
- mousemove: 1,
288
- mouseover: 1,
289
- mouseenter: 1,
290
- mouseleave: 1,
291
- mouseout: 1,
292
- storage: 1,
293
- storagecommit: 1,
294
- textinput: 1
295
- };
296
-
297
- // This polyfill depends on availability of `document` so will not run in a worker
298
- // However, we asssume there are no browsers with worker support that lack proper
299
- // support for `Event` within the worker
300
- if (typeof document === 'undefined' || typeof window === 'undefined') return;
301
-
302
- function indexOf(array, element) {
303
- var
304
- index = -1,
305
- length = array.length;
306
-
307
- while (++index < length) {
308
- if (index in array && array[index] === element) {
309
- return index;
310
- }
311
- }
312
-
313
- return -1;
314
- }
315
-
316
- var existingProto = (window.Event && window.Event.prototype) || null;
317
- window.Event = Window.prototype.Event = function Event(type, eventInitDict) {
318
- if (!type) {
319
- throw new Error('Not enough arguments');
320
- }
321
-
322
- var event;
323
- // Shortcut if browser supports createEvent
324
- if ('createEvent' in document) {
325
- event = document.createEvent('Event');
326
- var bubbles = eventInitDict && eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false;
327
- var cancelable = eventInitDict && eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false;
328
-
329
- event.initEvent(type, bubbles, cancelable);
330
-
331
- return event;
332
- }
333
-
334
- event = document.createEventObject();
335
-
336
- event.type = type;
337
- event.bubbles = eventInitDict && eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false;
338
- event.cancelable = eventInitDict && eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false;
339
-
340
- return event;
341
- };
342
- if (existingProto) {
343
- Object.defineProperty(window.Event, 'prototype', {
344
- configurable: false,
345
- enumerable: false,
346
- writable: true,
347
- value: existingProto
348
- });
349
- }
350
-
351
- if (!('createEvent' in document)) {
352
- window.addEventListener = Window.prototype.addEventListener = Document.prototype.addEventListener = Element.prototype.addEventListener = function addEventListener() {
353
- var
354
- element = this,
355
- type = arguments[0],
356
- listener = arguments[1];
357
-
358
- if (element === window && type in unlistenableWindowEvents) {
359
- throw new Error('In IE8 the event: ' + type + ' is not available on the window object. Please see https://github.com/Financial-Times/polyfill-service/issues/317 for more information.');
360
- }
361
-
362
- if (!element._events) {
363
- element._events = {};
364
- }
365
-
366
- if (!element._events[type]) {
367
- element._events[type] = function (event) {
368
- var
369
- list = element._events[event.type].list,
370
- events = list.slice(),
371
- index = -1,
372
- length = events.length,
373
- eventElement;
374
-
375
- event.preventDefault = function preventDefault() {
376
- if (event.cancelable !== false) {
377
- event.returnValue = false;
378
- }
379
- };
380
-
381
- event.stopPropagation = function stopPropagation() {
382
- event.cancelBubble = true;
383
- };
384
-
385
- event.stopImmediatePropagation = function stopImmediatePropagation() {
386
- event.cancelBubble = true;
387
- event.cancelImmediate = true;
388
- };
389
-
390
- event.currentTarget = element;
391
- event.relatedTarget = event.fromElement || null;
392
- event.target = event.target || event.srcElement || element;
393
- event.timeStamp = new Date().getTime();
394
-
395
- if (event.clientX) {
396
- event.pageX = event.clientX + document.documentElement.scrollLeft;
397
- event.pageY = event.clientY + document.documentElement.scrollTop;
398
- }
399
-
400
- while (++index < length && !event.cancelImmediate) {
401
- if (index in events) {
402
- eventElement = events[index];
403
-
404
- if (indexOf(list, eventElement) !== -1 && typeof eventElement === 'function') {
405
- eventElement.call(element, event);
406
- }
407
- }
408
- }
409
- };
410
-
411
- element._events[type].list = [];
412
-
413
- if (element.attachEvent) {
414
- element.attachEvent('on' + type, element._events[type]);
415
- }
416
- }
417
-
418
- element._events[type].list.push(listener);
419
- };
420
-
421
- window.removeEventListener = Window.prototype.removeEventListener = Document.prototype.removeEventListener = Element.prototype.removeEventListener = function removeEventListener() {
422
- var
423
- element = this,
424
- type = arguments[0],
425
- listener = arguments[1],
426
- index;
427
-
428
- if (element._events && element._events[type] && element._events[type].list) {
429
- index = indexOf(element._events[type].list, listener);
430
-
431
- if (index !== -1) {
432
- element._events[type].list.splice(index, 1);
433
-
434
- if (!element._events[type].list.length) {
435
- if (element.detachEvent) {
436
- element.detachEvent('on' + type, element._events[type]);
437
- }
438
- delete element._events[type];
439
- }
440
- }
441
- }
442
- };
443
-
444
- window.dispatchEvent = Window.prototype.dispatchEvent = Document.prototype.dispatchEvent = Element.prototype.dispatchEvent = function dispatchEvent(event) {
445
- if (!arguments.length) {
446
- throw new Error('Not enough arguments');
447
- }
448
-
449
- if (!event || typeof event.type !== 'string') {
450
- throw new Error('DOM Events Exception 0');
451
- }
452
-
453
- var element = this, type = event.type;
454
-
455
- try {
456
- if (!event.bubbles) {
457
- event.cancelBubble = true;
458
-
459
- var cancelBubbleEvent = function (event) {
460
- event.cancelBubble = true;
461
-
462
- (element || window).detachEvent('on' + type, cancelBubbleEvent);
463
- };
464
-
465
- this.attachEvent('on' + type, cancelBubbleEvent);
466
- }
467
-
468
- this.fireEvent('on' + type, event);
469
- } catch (error) {
470
- event.target = element;
471
-
472
- do {
473
- event.currentTarget = element;
474
-
475
- if ('_events' in element && typeof element._events[type] === 'function') {
476
- element._events[type].call(element, event);
477
- }
478
-
479
- if (typeof element['on' + type] === 'function') {
480
- element['on' + type].call(element, event);
481
- }
482
-
483
- element = element.nodeType === 9 ? element.parentWindow : element.parentNode;
484
- } while (element && !event.cancelBubble);
485
- }
486
-
487
- return true;
488
- };
489
-
490
- // Add the DOMContentLoaded Event
491
- document.attachEvent('onreadystatechange', function() {
492
- if (document.readyState === 'complete') {
493
- document.dispatchEvent(new Event('DOMContentLoaded', {
494
- bubbles: true
495
- }));
496
- }
497
- });
498
- }
499
- }());
500
-
501
- })
502
- .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
503
-
504
- /**
505
- * Common helpers which do not require polyfill.
506
- *
507
- * IMPORTANT: If a helper require a polyfill, please isolate it in its own module
508
- * so that the polyfill can be properly tree-shaken and does not burden
509
- * the components that do not need that helper
510
- *
511
- * @module common/index
512
- */
513
-
514
- /**
515
- * Config flattening function
516
- *
517
- * Takes any number of objects, flattens them into namespaced key-value pairs,
518
- * (e.g. {'i18n.showSection': 'Show section'}) and combines them together, with
519
- * greatest priority on the LAST item passed in.
520
- *
521
- * @returns {object} A flattened object of key-value pairs.
522
- */
523
- function mergeConfigs (/* configObject1, configObject2, ...configObjects */) {
524
- /**
525
- * Function to take nested objects and flatten them to a dot-separated keyed
526
- * object. Doing this means we don't need to do any deep/recursive merging of
527
- * each of our objects, nor transform our dataset from a flat list into a
528
- * nested object.
529
- *
530
- * @param {object} configObject - Deeply nested object
531
- * @returns {object} Flattened object with dot-separated keys
532
- */
533
- var flattenObject = function (configObject) {
534
- // Prepare an empty return object
535
- var flattenedObject = {};
536
-
537
- // Our flattening function, this is called recursively for each level of
538
- // depth in the object. At each level we prepend the previous level names to
539
- // the key using `prefix`.
540
- var flattenLoop = function (obj, prefix) {
541
- // Loop through keys...
542
- for (var key in obj) {
543
- // Check to see if this is a prototypical key/value,
544
- // if it is, skip it.
545
- if (!Object.prototype.hasOwnProperty.call(obj, key)) {
546
- continue
547
- }
548
- var value = obj[key];
549
- var prefixedKey = prefix ? prefix + '.' + key : key;
550
- if (typeof value === 'object') {
551
- // If the value is a nested object, recurse over that too
552
- flattenLoop(value, prefixedKey);
553
- } else {
554
- // Otherwise, add this value to our return object
555
- flattenedObject[prefixedKey] = value;
556
- }
557
- }
558
- };
196
+ if (this.HTMLDocument) { // IE8
559
197
 
560
- // Kick off the recursive loop
561
- flattenLoop(configObject);
562
- return flattenedObject
563
- };
198
+ // HTMLDocument is an extension of Document. If the browser has HTMLDocument but not Document, the former will suffice as an alias for the latter.
199
+ this.Document = this.HTMLDocument;
564
200
 
565
- // Start with an empty object as our base
566
- var formattedConfigObject = {};
567
-
568
- // Loop through each of the remaining passed objects and push their keys
569
- // one-by-one into configObject. Any duplicate keys will override the existing
570
- // key with the new value.
571
- for (var i = 0; i < arguments.length; i++) {
572
- var obj = flattenObject(arguments[i]);
573
- for (var key in obj) {
574
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
575
- formattedConfigObject[key] = obj[key];
576
- }
577
- }
201
+ } else {
202
+
203
+ // Create an empty function to act as the missing constructor for the document object, attach the document object as its prototype. The function needs to be anonymous else it is hoisted and causes the feature detect to prematurely pass, preventing the assignments below being made.
204
+ this.Document = this.HTMLDocument = document.constructor = (new Function('return function Document() {}')());
205
+ this.Document.prototype = document;
206
+ }
578
207
  }
579
208
 
580
- return formattedConfigObject
581
- }
582
209
 
583
- /**
584
- * @callback nodeListIterator
585
- * @param {Element} value - The current node being iterated on
586
- * @param {number} index - The current index in the iteration
587
- * @param {NodeListOf<Element>} nodes - NodeList from querySelectorAll()
588
- * @returns {undefined}
589
- */
210
+ })
211
+ .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
590
212
 
591
- (function(undefined) {
213
+ (function(undefined) {
592
214
 
593
- // Detection from https://raw.githubusercontent.com/Financial-Times/polyfill-library/13cf7c340974d128d557580b5e2dafcd1b1192d1/polyfills/Element/prototype/dataset/detect.js
594
- var detect = (function(){
595
- if (!document.documentElement.dataset) {
596
- return false;
597
- }
598
- var el = document.createElement('div');
599
- el.setAttribute("data-a-b", "c");
600
- return el.dataset && el.dataset.aB == "c";
601
- }());
215
+ // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Element/detect.js
216
+ var detect = ('Element' in this && 'HTMLElement' in this);
602
217
 
603
218
  if (detect) return
604
219
 
605
- // Polyfill derived from https://raw.githubusercontent.com/Financial-Times/polyfill-library/13cf7c340974d128d557580b5e2dafcd1b1192d1/polyfills/Element/prototype/dataset/polyfill.js
606
- Object.defineProperty(Element.prototype, 'dataset', {
607
- get: function() {
608
- var element = this;
609
- var attributes = this.attributes;
610
- var map = {};
611
-
612
- for (var i = 0; i < attributes.length; i++) {
613
- var attribute = attributes[i];
614
-
615
- // This regex has been edited from the original polyfill, to add
616
- // support for period (.) separators in data-* attribute names. These
617
- // are allowed in the HTML spec, but were not covered by the original
618
- // polyfill's regex. We use periods in our i18n implementation.
619
- if (attribute && attribute.name && (/^data-\w[.\w-]*$/).test(attribute.name)) {
620
- var name = attribute.name;
621
- var value = attribute.value;
622
-
623
- var propName = name.substr(5).replace(/-./g, function (prop) {
624
- return prop.charAt(1).toUpperCase();
625
- });
626
-
627
- // If this browser supports __defineGetter__ and __defineSetter__,
628
- // continue using defineProperty. If not (like IE 8 and below), we use
629
- // a hacky fallback which at least gives an object in the right format
630
- if ('__defineGetter__' in Object.prototype && '__defineSetter__' in Object.prototype) {
631
- Object.defineProperty(map, propName, {
632
- enumerable: true,
633
- get: function() {
634
- return this.value;
635
- }.bind({value: value || ''}),
636
- set: function setter(name, value) {
637
- if (typeof value !== 'undefined') {
638
- this.setAttribute(name, value);
639
- } else {
640
- this.removeAttribute(name);
641
- }
642
- }.bind(element, name)
220
+ // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Element&flags=always
221
+ (function () {
222
+
223
+ // IE8
224
+ if (window.Element && !window.HTMLElement) {
225
+ window.HTMLElement = window.Element;
226
+ return;
227
+ }
228
+
229
+ // create Element constructor
230
+ window.Element = window.HTMLElement = new Function('return function Element() {}')();
231
+
232
+ // generate sandboxed iframe
233
+ var vbody = document.appendChild(document.createElement('body'));
234
+ var frame = vbody.appendChild(document.createElement('iframe'));
235
+
236
+ // use sandboxed iframe to replicate Element functionality
237
+ var frameDocument = frame.contentWindow.document;
238
+ var prototype = Element.prototype = frameDocument.appendChild(frameDocument.createElement('*'));
239
+ var cache = {};
240
+
241
+ // polyfill Element.prototype on an element
242
+ var shiv = function (element, deep) {
243
+ var
244
+ childNodes = element.childNodes || [],
245
+ index = -1,
246
+ key, value, childNode;
247
+
248
+ if (element.nodeType === 1 && element.constructor !== Element) {
249
+ element.constructor = Element;
250
+
251
+ for (key in cache) {
252
+ value = cache[key];
253
+ element[key] = value;
254
+ }
255
+ }
256
+
257
+ while (childNode = deep && childNodes[++index]) {
258
+ shiv(childNode, deep);
259
+ }
260
+
261
+ return element;
262
+ };
263
+
264
+ var elements = document.getElementsByTagName('*');
265
+ var nativeCreateElement = document.createElement;
266
+ var interval;
267
+ var loopLimit = 100;
268
+
269
+ prototype.attachEvent('onpropertychange', function (event) {
270
+ var
271
+ propertyName = event.propertyName,
272
+ nonValue = !cache.hasOwnProperty(propertyName),
273
+ newValue = prototype[propertyName],
274
+ oldValue = cache[propertyName],
275
+ index = -1,
276
+ element;
277
+
278
+ while (element = elements[++index]) {
279
+ if (element.nodeType === 1) {
280
+ if (nonValue || element[propertyName] === oldValue) {
281
+ element[propertyName] = newValue;
282
+ }
283
+ }
284
+ }
285
+
286
+ cache[propertyName] = newValue;
287
+ });
288
+
289
+ prototype.constructor = Element;
290
+
291
+ if (!prototype.hasAttribute) {
292
+ // <Element>.hasAttribute
293
+ prototype.hasAttribute = function hasAttribute(name) {
294
+ return this.getAttribute(name) !== null;
295
+ };
296
+ }
297
+
298
+ // Apply Element prototype to the pre-existing DOM as soon as the body element appears.
299
+ function bodyCheck() {
300
+ if (!(loopLimit--)) clearTimeout(interval);
301
+ if (document.body && !document.body.prototype && /(complete|interactive)/.test(document.readyState)) {
302
+ shiv(document, true);
303
+ if (interval && document.body.prototype) clearTimeout(interval);
304
+ return (!!document.body.prototype);
305
+ }
306
+ return false;
307
+ }
308
+ if (!bodyCheck()) {
309
+ document.onreadystatechange = bodyCheck;
310
+ interval = setInterval(bodyCheck, 25);
311
+ }
312
+
313
+ // Apply to any new elements created after load
314
+ document.createElement = function createElement(nodeName) {
315
+ var element = nativeCreateElement(String(nodeName).toLowerCase());
316
+ return shiv(element);
317
+ };
318
+
319
+ // remove sandboxed iframe
320
+ document.removeChild(vbody);
321
+ }());
322
+
323
+ })
324
+ .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
325
+
326
+ (function(undefined) {
327
+
328
+ // Detection from https://raw.githubusercontent.com/Financial-Times/polyfill-library/13cf7c340974d128d557580b5e2dafcd1b1192d1/polyfills/Element/prototype/dataset/detect.js
329
+ var detect = (function(){
330
+ if (!document.documentElement.dataset) {
331
+ return false;
332
+ }
333
+ var el = document.createElement('div');
334
+ el.setAttribute("data-a-b", "c");
335
+ return el.dataset && el.dataset.aB == "c";
336
+ }());
337
+
338
+ if (detect) return
339
+
340
+ // Polyfill derived from https://raw.githubusercontent.com/Financial-Times/polyfill-library/13cf7c340974d128d557580b5e2dafcd1b1192d1/polyfills/Element/prototype/dataset/polyfill.js
341
+ Object.defineProperty(Element.prototype, 'dataset', {
342
+ get: function() {
343
+ var element = this;
344
+ var attributes = this.attributes;
345
+ var map = {};
346
+
347
+ for (var i = 0; i < attributes.length; i++) {
348
+ var attribute = attributes[i];
349
+
350
+ // This regex has been edited from the original polyfill, to add
351
+ // support for period (.) separators in data-* attribute names. These
352
+ // are allowed in the HTML spec, but were not covered by the original
353
+ // polyfill's regex. We use periods in our i18n implementation.
354
+ if (attribute && attribute.name && (/^data-\w[.\w-]*$/).test(attribute.name)) {
355
+ var name = attribute.name;
356
+ var value = attribute.value;
357
+
358
+ var propName = name.substr(5).replace(/-./g, function (prop) {
359
+ return prop.charAt(1).toUpperCase();
643
360
  });
644
- } else {
645
- map[propName] = value;
646
- }
361
+
362
+ // If this browser supports __defineGetter__ and __defineSetter__,
363
+ // continue using defineProperty. If not (like IE 8 and below), we use
364
+ // a hacky fallback which at least gives an object in the right format
365
+ if ('__defineGetter__' in Object.prototype && '__defineSetter__' in Object.prototype) {
366
+ Object.defineProperty(map, propName, {
367
+ enumerable: true,
368
+ get: function() {
369
+ return this.value;
370
+ }.bind({value: value || ''}),
371
+ set: function setter(name, value) {
372
+ if (typeof value !== 'undefined') {
373
+ this.setAttribute(name, value);
374
+ } else {
375
+ this.removeAttribute(name);
376
+ }
377
+ }.bind(element, name)
378
+ });
379
+ } else {
380
+ map[propName] = value;
381
+ }
647
382
 
383
+ }
648
384
  }
385
+
386
+ return map;
649
387
  }
650
-
651
- return map;
388
+ });
389
+
390
+ }).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
391
+
392
+ (function(undefined) {
393
+
394
+ // Detection from https://github.com/mdn/content/blob/cf607d68522cd35ee7670782d3ee3a361eaef2e4/files/en-us/web/javascript/reference/global_objects/string/trim/index.md#polyfill
395
+ var detect = ('trim' in String.prototype);
396
+
397
+ if (detect) return
398
+
399
+ // Polyfill from https://github.com/mdn/content/blob/cf607d68522cd35ee7670782d3ee3a361eaef2e4/files/en-us/web/javascript/reference/global_objects/string/trim/index.md#polyfill
400
+ String.prototype.trim = function () {
401
+ return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
402
+ };
403
+
404
+ }).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
405
+
406
+ /* eslint-disable es-x/no-string-prototype-trim -- Polyfill imported */
407
+
408
+ /**
409
+ * Normalise string
410
+ *
411
+ * 'If it looks like a duck, and it quacks like a duck…' 🦆
412
+ *
413
+ * If the passed value looks like a boolean or a number, convert it to a boolean
414
+ * or number.
415
+ *
416
+ * Designed to be used to convert config passed via data attributes (which are
417
+ * always strings) into something sensible.
418
+ *
419
+ * @param {string} value - The value to normalise
420
+ * @returns {string | boolean | number | undefined} Normalised data
421
+ */
422
+ function normaliseString (value) {
423
+ if (typeof value !== 'string') {
424
+ return value
652
425
  }
653
- });
654
426
 
655
- }).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
427
+ var trimmedValue = value.trim();
656
428
 
657
- (function(undefined) {
429
+ if (trimmedValue === 'true') {
430
+ return true
431
+ }
658
432
 
659
- // Detection from https://github.com/mdn/content/blob/cf607d68522cd35ee7670782d3ee3a361eaef2e4/files/en-us/web/javascript/reference/global_objects/string/trim/index.md#polyfill
660
- var detect = ('trim' in String.prototype);
661
-
662
- if (detect) return
433
+ if (trimmedValue === 'false') {
434
+ return false
435
+ }
663
436
 
664
- // Polyfill from https://github.com/mdn/content/blob/cf607d68522cd35ee7670782d3ee3a361eaef2e4/files/en-us/web/javascript/reference/global_objects/string/trim/index.md#polyfill
665
- String.prototype.trim = function () {
666
- return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
667
- };
437
+ // Empty / whitespace-only strings are considered finite so we need to check
438
+ // the length of the trimmed string as well
439
+ if (trimmedValue.length > 0 && isFinite(trimmedValue)) {
440
+ return Number(trimmedValue)
441
+ }
668
442
 
669
- }).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
670
-
671
- /**
672
- * Normalise string
673
- *
674
- * 'If it looks like a duck, and it quacks like a duck…' 🦆
675
- *
676
- * If the passed value looks like a boolean or a number, convert it to a boolean
677
- * or number.
678
- *
679
- * Designed to be used to convert config passed via data attributes (which are
680
- * always strings) into something sensible.
681
- *
682
- * @param {string} value - The value to normalise
683
- * @returns {string | boolean | number | undefined} Normalised data
684
- */
685
- function normaliseString (value) {
686
- if (typeof value !== 'string') {
687
443
  return value
688
444
  }
689
445
 
690
- var trimmedValue = value.trim();
446
+ /**
447
+ * Normalise dataset
448
+ *
449
+ * Loop over an object and normalise each value using normaliseData function
450
+ *
451
+ * @param {DOMStringMap} dataset - HTML element dataset
452
+ * @returns {Object<string, unknown>} Normalised dataset
453
+ */
454
+ function normaliseDataset (dataset) {
455
+ var out = {};
691
456
 
692
- if (trimmedValue === 'true') {
693
- return true
694
- }
457
+ for (var key in dataset) {
458
+ out[key] = normaliseString(dataset[key]);
459
+ }
695
460
 
696
- if (trimmedValue === 'false') {
697
- return false
461
+ return out
698
462
  }
699
463
 
700
- // Empty / whitespace-only strings are considered finite so we need to check
701
- // the length of the trimmed string as well
702
- if (trimmedValue.length > 0 && isFinite(trimmedValue)) {
703
- return Number(trimmedValue)
704
- }
464
+ (function(undefined) {
705
465
 
706
- return value
707
- }
708
-
709
- /**
710
- * Normalise dataset
711
- *
712
- * Loop over an object and normalise each value using normaliseData function
713
- *
714
- * @param {DOMStringMap} dataset - HTML element dataset
715
- * @returns {Object<string, string | boolean | number | undefined>} Normalised dataset
716
- */
717
- function normaliseDataset (dataset) {
718
- var out = {};
719
-
720
- for (var key in dataset) {
721
- out[key] = normaliseString(dataset[key]);
466
+ // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Window/detect.js
467
+ var detect = ('Window' in this);
468
+
469
+ if (detect) return
470
+
471
+ // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Window&flags=always
472
+ if ((typeof WorkerGlobalScope === "undefined") && (typeof importScripts !== "function")) {
473
+ (function (global) {
474
+ if (global.constructor) {
475
+ global.Window = global.constructor;
476
+ } else {
477
+ (global.Window = global.constructor = new Function('return function Window() {}')()).prototype = this;
478
+ }
479
+ }(this));
722
480
  }
723
481
 
724
- return out
725
- }
726
-
727
- /**
728
- * Notification Banner component
729
- *
730
- * @class
731
- * @param {HTMLElement} $module - HTML element to use for notification banner
732
- * @param {NotificationBannerConfig} config - Notification banner config
733
- */
734
- function NotificationBanner ($module, config) {
735
- this.$module = $module;
736
-
737
- var defaultConfig = {
738
- disableAutoFocus: false
739
- };
740
- this.config = mergeConfigs(
741
- defaultConfig,
742
- config || {},
743
- normaliseDataset($module.dataset)
482
+ })
483
+ .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
484
+
485
+ (function(undefined) {
486
+
487
+ // Detection from https://github.com/Financial-Times/polyfill-service/blob/master/packages/polyfill-library/polyfills/Event/detect.js
488
+ var detect = (
489
+ (function(global) {
490
+
491
+ if (!('Event' in global)) return false;
492
+ if (typeof global.Event === 'function') return true;
493
+
494
+ try {
495
+
496
+ // In IE 9-11, the Event object exists but cannot be instantiated
497
+ new Event('click');
498
+ return true;
499
+ } catch(e) {
500
+ return false;
501
+ }
502
+ }(this))
744
503
  );
745
- }
746
-
747
- /**
748
- * Initialise the component
749
- */
750
- NotificationBanner.prototype.init = function () {
751
- var $module = this.$module;
752
- // Check for module
753
- if (!$module) {
754
- return
755
- }
756
504
 
757
- this.setFocus();
758
- };
759
-
760
- /**
761
- * Focus the element
762
- *
763
- * If `role="alert"` is set, focus the element to help some assistive technologies
764
- * prioritise announcing it.
765
- *
766
- * You can turn off the auto-focus functionality by setting `data-disable-auto-focus="true"` in the
767
- * component HTML. You might wish to do this based on user research findings, or to avoid a clash
768
- * with another element which should be focused when the page loads.
769
- */
770
- NotificationBanner.prototype.setFocus = function () {
771
- var $module = this.$module;
772
-
773
- if (this.config.disableAutoFocus) {
774
- return
775
- }
505
+ if (detect) return
776
506
 
777
- if ($module.getAttribute('role') !== 'alert') {
778
- return
779
- }
507
+ // Polyfill from https://cdn.polyfill.io/v2/polyfill.js?features=Event&flags=always
508
+ (function () {
509
+ var unlistenableWindowEvents = {
510
+ click: 1,
511
+ dblclick: 1,
512
+ keyup: 1,
513
+ keypress: 1,
514
+ keydown: 1,
515
+ mousedown: 1,
516
+ mouseup: 1,
517
+ mousemove: 1,
518
+ mouseover: 1,
519
+ mouseenter: 1,
520
+ mouseleave: 1,
521
+ mouseout: 1,
522
+ storage: 1,
523
+ storagecommit: 1,
524
+ textinput: 1
525
+ };
526
+
527
+ // This polyfill depends on availability of `document` so will not run in a worker
528
+ // However, we asssume there are no browsers with worker support that lack proper
529
+ // support for `Event` within the worker
530
+ if (typeof document === 'undefined' || typeof window === 'undefined') return;
531
+
532
+ function indexOf(array, element) {
533
+ var
534
+ index = -1,
535
+ length = array.length;
536
+
537
+ while (++index < length) {
538
+ if (index in array && array[index] === element) {
539
+ return index;
540
+ }
541
+ }
542
+
543
+ return -1;
544
+ }
780
545
 
781
- // Set tabindex to -1 to make the element focusable with JavaScript.
782
- // Remove the tabindex on blur as the component doesn't need to be focusable after the page has
783
- // loaded.
784
- if (!$module.getAttribute('tabindex')) {
785
- $module.setAttribute('tabindex', '-1');
546
+ var existingProto = (window.Event && window.Event.prototype) || null;
547
+ window.Event = Window.prototype.Event = function Event(type, eventInitDict) {
548
+ if (!type) {
549
+ throw new Error('Not enough arguments');
550
+ }
551
+
552
+ var event;
553
+ // Shortcut if browser supports createEvent
554
+ if ('createEvent' in document) {
555
+ event = document.createEvent('Event');
556
+ var bubbles = eventInitDict && eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false;
557
+ var cancelable = eventInitDict && eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false;
558
+
559
+ event.initEvent(type, bubbles, cancelable);
560
+
561
+ return event;
562
+ }
563
+
564
+ event = document.createEventObject();
565
+
566
+ event.type = type;
567
+ event.bubbles = eventInitDict && eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false;
568
+ event.cancelable = eventInitDict && eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false;
569
+
570
+ return event;
571
+ };
572
+ if (existingProto) {
573
+ Object.defineProperty(window.Event, 'prototype', {
574
+ configurable: false,
575
+ enumerable: false,
576
+ writable: true,
577
+ value: existingProto
578
+ });
579
+ }
786
580
 
787
- $module.addEventListener('blur', function () {
788
- $module.removeAttribute('tabindex');
789
- });
581
+ if (!('createEvent' in document)) {
582
+ window.addEventListener = Window.prototype.addEventListener = Document.prototype.addEventListener = Element.prototype.addEventListener = function addEventListener() {
583
+ var
584
+ element = this,
585
+ type = arguments[0],
586
+ listener = arguments[1];
587
+
588
+ if (element === window && type in unlistenableWindowEvents) {
589
+ throw new Error('In IE8 the event: ' + type + ' is not available on the window object. Please see https://github.com/Financial-Times/polyfill-service/issues/317 for more information.');
590
+ }
591
+
592
+ if (!element._events) {
593
+ element._events = {};
594
+ }
595
+
596
+ if (!element._events[type]) {
597
+ element._events[type] = function (event) {
598
+ var
599
+ list = element._events[event.type].list,
600
+ events = list.slice(),
601
+ index = -1,
602
+ length = events.length,
603
+ eventElement;
604
+
605
+ event.preventDefault = function preventDefault() {
606
+ if (event.cancelable !== false) {
607
+ event.returnValue = false;
608
+ }
609
+ };
610
+
611
+ event.stopPropagation = function stopPropagation() {
612
+ event.cancelBubble = true;
613
+ };
614
+
615
+ event.stopImmediatePropagation = function stopImmediatePropagation() {
616
+ event.cancelBubble = true;
617
+ event.cancelImmediate = true;
618
+ };
619
+
620
+ event.currentTarget = element;
621
+ event.relatedTarget = event.fromElement || null;
622
+ event.target = event.target || event.srcElement || element;
623
+ event.timeStamp = new Date().getTime();
624
+
625
+ if (event.clientX) {
626
+ event.pageX = event.clientX + document.documentElement.scrollLeft;
627
+ event.pageY = event.clientY + document.documentElement.scrollTop;
628
+ }
629
+
630
+ while (++index < length && !event.cancelImmediate) {
631
+ if (index in events) {
632
+ eventElement = events[index];
633
+
634
+ if (indexOf(list, eventElement) !== -1 && typeof eventElement === 'function') {
635
+ eventElement.call(element, event);
636
+ }
637
+ }
638
+ }
639
+ };
640
+
641
+ element._events[type].list = [];
642
+
643
+ if (element.attachEvent) {
644
+ element.attachEvent('on' + type, element._events[type]);
645
+ }
646
+ }
647
+
648
+ element._events[type].list.push(listener);
649
+ };
650
+
651
+ window.removeEventListener = Window.prototype.removeEventListener = Document.prototype.removeEventListener = Element.prototype.removeEventListener = function removeEventListener() {
652
+ var
653
+ element = this,
654
+ type = arguments[0],
655
+ listener = arguments[1],
656
+ index;
657
+
658
+ if (element._events && element._events[type] && element._events[type].list) {
659
+ index = indexOf(element._events[type].list, listener);
660
+
661
+ if (index !== -1) {
662
+ element._events[type].list.splice(index, 1);
663
+
664
+ if (!element._events[type].list.length) {
665
+ if (element.detachEvent) {
666
+ element.detachEvent('on' + type, element._events[type]);
667
+ }
668
+ delete element._events[type];
669
+ }
670
+ }
671
+ }
672
+ };
673
+
674
+ window.dispatchEvent = Window.prototype.dispatchEvent = Document.prototype.dispatchEvent = Element.prototype.dispatchEvent = function dispatchEvent(event) {
675
+ if (!arguments.length) {
676
+ throw new Error('Not enough arguments');
677
+ }
678
+
679
+ if (!event || typeof event.type !== 'string') {
680
+ throw new Error('DOM Events Exception 0');
681
+ }
682
+
683
+ var element = this, type = event.type;
684
+
685
+ try {
686
+ if (!event.bubbles) {
687
+ event.cancelBubble = true;
688
+
689
+ var cancelBubbleEvent = function (event) {
690
+ event.cancelBubble = true;
691
+
692
+ (element || window).detachEvent('on' + type, cancelBubbleEvent);
693
+ };
694
+
695
+ this.attachEvent('on' + type, cancelBubbleEvent);
696
+ }
697
+
698
+ this.fireEvent('on' + type, event);
699
+ } catch (error) {
700
+ event.target = element;
701
+
702
+ do {
703
+ event.currentTarget = element;
704
+
705
+ if ('_events' in element && typeof element._events[type] === 'function') {
706
+ element._events[type].call(element, event);
707
+ }
708
+
709
+ if (typeof element['on' + type] === 'function') {
710
+ element['on' + type].call(element, event);
711
+ }
712
+
713
+ element = element.nodeType === 9 ? element.parentWindow : element.parentNode;
714
+ } while (element && !event.cancelBubble);
715
+ }
716
+
717
+ return true;
718
+ };
719
+
720
+ // Add the DOMContentLoaded Event
721
+ document.attachEvent('onreadystatechange', function() {
722
+ if (document.readyState === 'complete') {
723
+ document.dispatchEvent(new Event('DOMContentLoaded', {
724
+ bubbles: true
725
+ }));
726
+ }
727
+ });
728
+ }
729
+ }());
730
+
731
+ })
732
+ .call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {});
733
+
734
+ /**
735
+ * Notification Banner component
736
+ *
737
+ * @class
738
+ * @param {HTMLElement} $module - HTML element to use for notification banner
739
+ * @param {NotificationBannerConfig} [config] - Notification banner config
740
+ */
741
+ function NotificationBanner ($module, config) {
742
+ this.$module = $module;
743
+
744
+ var defaultConfig = {
745
+ disableAutoFocus: false
746
+ };
747
+ this.config = mergeConfigs(
748
+ defaultConfig,
749
+ config || {},
750
+ normaliseDataset($module.dataset)
751
+ );
790
752
  }
791
753
 
792
- $module.focus();
793
- };
754
+ /**
755
+ * Initialise component
756
+ */
757
+ NotificationBanner.prototype.init = function () {
758
+ var $module = this.$module;
759
+ // Check for module
760
+ if (!$module) {
761
+ return
762
+ }
763
+
764
+ this.setFocus();
765
+ };
794
766
 
795
- /**
796
- * Notification banner config
797
- *
798
- * @typedef {object} NotificationBannerConfig
799
- * @property {boolean} [disableAutoFocus = false] -
800
- * If set to `true` the notification banner will not be focussed when the page
801
- * loads. This only applies if the component has a `role` of `alert` in
802
- * other cases the component will not be focused on page load, regardless of
803
- * this option.
804
- */
767
+ /**
768
+ * Focus the element
769
+ *
770
+ * If `role="alert"` is set, focus the element to help some assistive technologies
771
+ * prioritise announcing it.
772
+ *
773
+ * You can turn off the auto-focus functionality by setting `data-disable-auto-focus="true"` in the
774
+ * component HTML. You might wish to do this based on user research findings, or to avoid a clash
775
+ * with another element which should be focused when the page loads.
776
+ */
777
+ NotificationBanner.prototype.setFocus = function () {
778
+ var $module = this.$module;
779
+
780
+ if (this.config.disableAutoFocus) {
781
+ return
782
+ }
783
+
784
+ if ($module.getAttribute('role') !== 'alert') {
785
+ return
786
+ }
787
+
788
+ // Set tabindex to -1 to make the element focusable with JavaScript.
789
+ // Remove the tabindex on blur as the component doesn't need to be focusable after the page has
790
+ // loaded.
791
+ if (!$module.getAttribute('tabindex')) {
792
+ $module.setAttribute('tabindex', '-1');
793
+
794
+ $module.addEventListener('blur', function () {
795
+ $module.removeAttribute('tabindex');
796
+ });
797
+ }
798
+
799
+ $module.focus();
800
+ };
801
+
802
+ /**
803
+ * Notification banner config
804
+ *
805
+ * @typedef {object} NotificationBannerConfig
806
+ * @property {boolean} [disableAutoFocus = false] -
807
+ * If set to `true` the notification banner will not be focussed when the page
808
+ * loads. This only applies if the component has a `role` of `alert` – in
809
+ * other cases the component will not be focused on page load, regardless of
810
+ * this option.
811
+ */
805
812
 
806
- return NotificationBanner;
813
+ return NotificationBanner;
807
814
 
808
815
  })));
816
+ //# sourceMappingURL=notification-banner.js.map