govuk_tech_docs 3.4.0 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/lib/assets/stylesheets/_govuk_tech_docs.scss +13 -0
  4. data/lib/govuk_tech_docs/version.rb +1 -1
  5. data/lib/source/favicon.ico +0 -0
  6. data/lib/source/layouts/_header.erb +13 -15
  7. data/node_modules/govuk-frontend/govuk/all-ie8.scss +8 -0
  8. data/node_modules/govuk-frontend/govuk/all.js +4918 -3796
  9. data/node_modules/govuk-frontend/govuk/common/closest-attribute-value.js +54 -49
  10. data/node_modules/govuk-frontend/govuk/common/govuk-frontend-version.js +17 -0
  11. data/node_modules/govuk-frontend/govuk/common/index.js +172 -152
  12. data/node_modules/govuk-frontend/govuk/common/normalise-dataset.js +334 -321
  13. data/node_modules/govuk-frontend/govuk/common.js +171 -151
  14. data/node_modules/govuk-frontend/govuk/components/_all.scss +3 -2
  15. data/node_modules/govuk-frontend/govuk/components/accordion/_index.scss +26 -7
  16. data/node_modules/govuk-frontend/govuk/components/accordion/accordion.js +2203 -1650
  17. data/node_modules/govuk-frontend/govuk/components/back-link/_index.scss +24 -16
  18. data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_index.scss +34 -11
  19. data/node_modules/govuk-frontend/govuk/components/button/_index.scss +49 -9
  20. data/node_modules/govuk-frontend/govuk/components/button/button.js +961 -916
  21. data/node_modules/govuk-frontend/govuk/components/character-count/character-count.js +2142 -2038
  22. data/node_modules/govuk-frontend/govuk/components/checkboxes/_index.scss +6 -6
  23. data/node_modules/govuk-frontend/govuk/components/checkboxes/checkboxes.js +1204 -1145
  24. data/node_modules/govuk-frontend/govuk/components/details/details.js +826 -799
  25. data/node_modules/govuk-frontend/govuk/components/error-summary/error-summary.js +1097 -1044
  26. data/node_modules/govuk-frontend/govuk/components/exit-this-page/_exit-this-page.scss +2 -0
  27. data/node_modules/govuk-frontend/govuk/components/exit-this-page/_index.scss +97 -0
  28. data/node_modules/govuk-frontend/govuk/components/exit-this-page/exit-this-page.js +2120 -0
  29. data/node_modules/govuk-frontend/govuk/components/file-upload/_index.scss +6 -1
  30. data/node_modules/govuk-frontend/govuk/components/footer/_index.scss +0 -7
  31. data/node_modules/govuk-frontend/govuk/components/header/_index.scss +6 -0
  32. data/node_modules/govuk-frontend/govuk/components/header/header.js +683 -1003
  33. data/node_modules/govuk-frontend/govuk/components/input/_index.scss +15 -3
  34. data/node_modules/govuk-frontend/govuk/components/notification-banner/notification-banner.js +786 -751
  35. data/node_modules/govuk-frontend/govuk/components/radios/_index.scss +5 -5
  36. data/node_modules/govuk-frontend/govuk/components/radios/radios.js +1151 -1105
  37. data/node_modules/govuk-frontend/govuk/components/select/_index.scss +7 -1
  38. data/node_modules/govuk-frontend/govuk/components/skip-link/skip-link.js +1045 -1014
  39. data/node_modules/govuk-frontend/govuk/components/summary-list/_index.scss +107 -0
  40. data/node_modules/govuk-frontend/govuk/components/tabs/tabs.js +1514 -1268
  41. data/node_modules/govuk-frontend/govuk/components/tag/_index.scss +18 -18
  42. data/node_modules/govuk-frontend/govuk/components/textarea/_index.scss +8 -1
  43. data/node_modules/govuk-frontend/govuk/core/_all.scss +1 -0
  44. data/node_modules/govuk-frontend/govuk/core/_govuk-frontend-version.scss +5 -0
  45. data/node_modules/govuk-frontend/govuk/helpers/_colour.scss +5 -2
  46. data/node_modules/govuk-frontend/govuk/helpers/_focused.scss +1 -1
  47. data/node_modules/govuk-frontend/govuk/helpers/_font-faces.scss +1 -1
  48. data/node_modules/govuk-frontend/govuk/helpers/_visually-hidden.scss +12 -0
  49. data/node_modules/govuk-frontend/govuk/i18n.js +371 -364
  50. data/node_modules/govuk-frontend/govuk/objects/_template.scss +20 -0
  51. data/node_modules/govuk-frontend/govuk/objects/_width-container.scss +1 -1
  52. data/node_modules/govuk-frontend/govuk/settings/_colours-organisations.scss +4 -0
  53. data/node_modules/govuk-frontend/govuk/settings/_ie8.scss +16 -0
  54. data/node_modules/govuk-frontend/govuk/settings/_links.scss +5 -1
  55. data/node_modules/govuk-frontend/govuk/settings/_measurements.scss +5 -5
  56. data/node_modules/govuk-frontend/govuk/tools/_ie8.scss +38 -2
  57. data/node_modules/govuk-frontend/govuk/vendor/polyfills/DOMTokenList.js +243 -241
  58. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Date/now.js +14 -12
  59. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Document.js +18 -16
  60. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/classList.js +553 -545
  61. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/closest.js +40 -36
  62. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/dataset.js +257 -250
  63. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/matches.js +22 -20
  64. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/nextElementSibling.js +204 -197
  65. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element/prototype/previousElementSibling.js +204 -197
  66. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Element.js +109 -105
  67. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Event.js +407 -399
  68. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Function/prototype/bind.js +242 -238
  69. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Object/defineProperty.js +73 -71
  70. data/node_modules/govuk-frontend/govuk/vendor/polyfills/String/prototype/trim.js +15 -13
  71. data/node_modules/govuk-frontend/govuk/vendor/polyfills/Window.js +18 -16
  72. data/node_modules/govuk-frontend/govuk-prototype-kit/init.js +1 -0
  73. data/package-lock.json +7 -7
  74. data/package.json +1 -1
  75. metadata +8 -3
@@ -1,390 +1,397 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
- typeof define === 'function' && define.amd ? define('GOVUKFrontend', ['exports'], factory) :
4
- (factory((global.GOVUKFrontend = {})));
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define('GOVUKFrontend', ['exports'], factory) :
4
+ (factory((global.GOVUKFrontend = {})));
5
5
  }(this, (function (exports) { 'use strict';
6
6
 
7
- /**
8
- * Internal support for selecting messages to render, with placeholder
9
- * interpolation and locale-aware number formatting and pluralisation
10
- *
11
- * @class
12
- * @private
13
- * @param {TranslationsFlattened} translations - Key-value pairs of the translation strings to use.
14
- * @param {object} [config] - Configuration options for the function.
15
- * @param {string} config.locale - An overriding locale for the PluralRules functionality.
16
- */
17
- function I18n (translations, config) {
18
- // Make list of translations available throughout function
19
- this.translations = translations || {};
20
-
21
- // The locale to use for PluralRules and NumberFormat
22
- this.locale = (config && config.locale) || document.documentElement.lang || 'en';
23
- }
24
-
25
- /**
26
- * The most used function - takes the key for a given piece of UI text and
27
- * returns the appropriate string.
28
- *
29
- * @param {string} lookupKey - The lookup key of the string to use.
30
- * @param {object} options - Any options passed with the translation string, e.g: for string interpolation.
31
- * @returns {string} The appropriate translation string.
32
- */
33
- I18n.prototype.t = function (lookupKey, options) {
34
- if (!lookupKey) {
35
- // Print a console error if no lookup key has been provided
36
- throw new Error('i18n: lookup key missing')
7
+ /**
8
+ * Internal support for selecting messages to render, with placeholder
9
+ * interpolation and locale-aware number formatting and pluralisation
10
+ *
11
+ * @class
12
+ * @private
13
+ * @param {Object<string, unknown>} translations - Key-value pairs of the translation strings to use.
14
+ * @param {object} [config] - Configuration options for the function.
15
+ * @param {string} [config.locale] - An overriding locale for the PluralRules functionality.
16
+ */
17
+ function I18n (translations, config) {
18
+ // Make list of translations available throughout function
19
+ this.translations = translations || {};
20
+
21
+ // The locale to use for PluralRules and NumberFormat
22
+ this.locale = (config && config.locale) || document.documentElement.lang || 'en';
37
23
  }
38
24
 
39
- // If the `count` option is set, determine which plural suffix is needed and
40
- // change the lookupKey to match. We check to see if it's undefined instead of
41
- // falsy, as this could legitimately be 0.
42
- if (options && typeof options.count !== 'undefined') {
43
- // Get the plural suffix
44
- lookupKey = lookupKey + '.' + this.getPluralSuffix(lookupKey, options.count);
45
- }
25
+ /**
26
+ * The most used function - takes the key for a given piece of UI text and
27
+ * returns the appropriate string.
28
+ *
29
+ * @param {string} lookupKey - The lookup key of the string to use.
30
+ * @param {Object<string, unknown>} [options] - Any options passed with the translation string, e.g: for string interpolation.
31
+ * @returns {string} The appropriate translation string.
32
+ * @throws {Error} Lookup key required
33
+ * @throws {Error} Options required for `${}` placeholders
34
+ */
35
+ I18n.prototype.t = function (lookupKey, options) {
36
+ if (!lookupKey) {
37
+ // Print a console error if no lookup key has been provided
38
+ throw new Error('i18n: lookup key missing')
39
+ }
40
+
41
+ // If the `count` option is set, determine which plural suffix is needed and
42
+ // change the lookupKey to match. We check to see if it's numeric instead of
43
+ // falsy, as this could legitimately be 0.
44
+ if (options && typeof options.count === 'number') {
45
+ // Get the plural suffix
46
+ lookupKey = lookupKey + '.' + this.getPluralSuffix(lookupKey, options.count);
47
+ }
46
48
 
47
- if (lookupKey in this.translations) {
48
49
  // Fetch the translation string for that lookup key
49
50
  var translationString = this.translations[lookupKey];
50
51
 
51
- // Check for ${} placeholders in the translation string
52
- if (translationString.match(/%{(.\S+)}/)) {
53
- if (!options) {
54
- throw new Error('i18n: cannot replace placeholders in string if no option data provided')
55
- }
52
+ if (typeof translationString === 'string') {
53
+ // Check for ${} placeholders in the translation string
54
+ if (translationString.match(/%{(.\S+)}/)) {
55
+ if (!options) {
56
+ throw new Error('i18n: cannot replace placeholders in string if no option data provided')
57
+ }
56
58
 
57
- return this.replacePlaceholders(translationString, options)
59
+ return this.replacePlaceholders(translationString, options)
60
+ } else {
61
+ return translationString
62
+ }
58
63
  } else {
59
- return translationString
64
+ // If the key wasn't found in our translations object,
65
+ // return the lookup key itself as the fallback
66
+ return lookupKey
67
+ }
68
+ };
69
+
70
+ /**
71
+ * Takes a translation string with placeholders, and replaces the placeholders
72
+ * with the provided data
73
+ *
74
+ * @param {string} translationString - The translation string
75
+ * @param {Object<string, unknown>} options - Any options passed with the translation string, e.g: for string interpolation.
76
+ * @returns {string} The translation string to output, with ${} placeholders replaced
77
+ */
78
+ I18n.prototype.replacePlaceholders = function (translationString, options) {
79
+ /** @type {Intl.NumberFormat | undefined} */
80
+ var formatter;
81
+
82
+ if (this.hasIntlNumberFormatSupport()) {
83
+ formatter = new Intl.NumberFormat(this.locale);
60
84
  }
61
- } else {
62
- // If the key wasn't found in our translations object,
63
- // return the lookup key itself as the fallback
64
- return lookupKey
65
- }
66
- };
67
-
68
- /**
69
- * Takes a translation string with placeholders, and replaces the placeholders
70
- * with the provided data
71
- *
72
- * @param {string} translationString - The translation string
73
- * @param {object} options - Any options passed with the translation string, e.g: for string interpolation.
74
- * @returns {string} The translation string to output, with ${} placeholders replaced
75
- */
76
- I18n.prototype.replacePlaceholders = function (translationString, options) {
77
- var formatter;
78
-
79
- if (this.hasIntlNumberFormatSupport()) {
80
- formatter = new Intl.NumberFormat(this.locale);
81
- }
82
-
83
- return translationString.replace(/%{(.\S+)}/g, function (placeholderWithBraces, placeholderKey) {
84
- if (Object.prototype.hasOwnProperty.call(options, placeholderKey)) {
85
- var placeholderValue = options[placeholderKey];
86
85
 
87
- // If a user has passed `false` as the value for the placeholder
88
- // treat it as though the value should not be displayed
89
- if (placeholderValue === false) {
90
- return ''
91
- }
86
+ return translationString.replace(
87
+ /%{(.\S+)}/g,
88
+
89
+ /**
90
+ * Replace translation string placeholders
91
+ *
92
+ * @param {string} placeholderWithBraces - Placeholder with braces
93
+ * @param {string} placeholderKey - Placeholder key
94
+ * @returns {string} Placeholder value
95
+ */
96
+ function (placeholderWithBraces, placeholderKey) {
97
+ if (Object.prototype.hasOwnProperty.call(options, placeholderKey)) {
98
+ var placeholderValue = options[placeholderKey];
99
+
100
+ // If a user has passed `false` as the value for the placeholder
101
+ // treat it as though the value should not be displayed
102
+ if (placeholderValue === false || (
103
+ typeof placeholderValue !== 'number' &&
104
+ typeof placeholderValue !== 'string')
105
+ ) {
106
+ return ''
107
+ }
108
+
109
+ // If the placeholder's value is a number, localise the number formatting
110
+ if (typeof placeholderValue === 'number') {
111
+ return formatter ? formatter.format(placeholderValue) : placeholderValue.toString()
112
+ }
113
+
114
+ return placeholderValue
115
+ } else {
116
+ throw new Error('i18n: no data found to replace ' + placeholderWithBraces + ' placeholder in string')
117
+ }
118
+ })
119
+ };
120
+
121
+ /**
122
+ * Check to see if the browser supports Intl and Intl.PluralRules.
123
+ *
124
+ * It requires all conditions to be met in order to be supported:
125
+ * - The browser supports the Intl class (true in IE11)
126
+ * - The implementation of Intl supports PluralRules (NOT true in IE11)
127
+ * - The browser/OS has plural rules for the current locale (browser dependent)
128
+ *
129
+ * @returns {boolean} Returns true if all conditions are met. Returns false otherwise.
130
+ */
131
+ I18n.prototype.hasIntlPluralRulesSupport = function () {
132
+ return Boolean(window.Intl && ('PluralRules' in window.Intl && Intl.PluralRules.supportedLocalesOf(this.locale).length))
133
+ };
134
+
135
+ /**
136
+ * Check to see if the browser supports Intl and Intl.NumberFormat.
137
+ *
138
+ * It requires all conditions to be met in order to be supported:
139
+ * - The browser supports the Intl class (true in IE11)
140
+ * - The implementation of Intl supports NumberFormat (also true in IE11)
141
+ * - The browser/OS has number formatting rules for the current locale (browser dependent)
142
+ *
143
+ * @returns {boolean} Returns true if all conditions are met. Returns false otherwise.
144
+ */
145
+ I18n.prototype.hasIntlNumberFormatSupport = function () {
146
+ return Boolean(window.Intl && ('NumberFormat' in window.Intl && Intl.NumberFormat.supportedLocalesOf(this.locale).length))
147
+ };
148
+
149
+ /**
150
+ * Get the appropriate suffix for the plural form.
151
+ *
152
+ * Uses Intl.PluralRules (or our own fallback implementation) to get the
153
+ * 'preferred' form to use for the given count.
154
+ *
155
+ * Checks that a translation has been provided for that plural form – if it
156
+ * hasn't, it'll fall back to the 'other' plural form (unless that doesn't exist
157
+ * either, in which case an error will be thrown)
158
+ *
159
+ * @param {string} lookupKey - The lookup key of the string to use.
160
+ * @param {number} count - Number used to determine which pluralisation to use.
161
+ * @returns {PluralRule} The suffix associated with the correct pluralisation for this locale.
162
+ * @throws {Error} Plural form `.other` required when preferred plural form is missing
163
+ */
164
+ I18n.prototype.getPluralSuffix = function (lookupKey, count) {
165
+ // Validate that the number is actually a number.
166
+ //
167
+ // Number(count) will turn anything that can't be converted to a Number type
168
+ // into 'NaN'. isFinite filters out NaN, as it isn't a finite number.
169
+ count = Number(count);
170
+ if (!isFinite(count)) { return 'other' }
171
+
172
+ var preferredForm;
173
+
174
+ // Check to verify that all the requirements for Intl.PluralRules are met.
175
+ // If so, we can use that instead of our custom implementation. Otherwise,
176
+ // use the hardcoded fallback.
177
+ if (this.hasIntlPluralRulesSupport()) {
178
+ preferredForm = new Intl.PluralRules(this.locale).select(count);
179
+ } else {
180
+ preferredForm = this.selectPluralFormUsingFallbackRules(count);
181
+ }
92
182
 
93
- // If the placeholder's value is a number, localise the number formatting
94
- if (typeof placeholderValue === 'number' && formatter) {
95
- return formatter.format(placeholderValue)
183
+ // Use the correct plural form if provided
184
+ if (lookupKey + '.' + preferredForm in this.translations) {
185
+ return preferredForm
186
+ // Fall back to `other` if the plural form is missing, but log a warning
187
+ // to the console
188
+ } else if (lookupKey + '.other' in this.translations) {
189
+ if (console && 'warn' in console) {
190
+ console.warn('i18n: Missing plural form ".' + preferredForm + '" for "' +
191
+ this.locale + '" locale. Falling back to ".other".');
96
192
  }
97
193
 
98
- return placeholderValue
194
+ return 'other'
195
+ // If the required `other` plural form is missing, all we can do is error
99
196
  } else {
100
- throw new Error('i18n: no data found to replace ' + placeholderWithBraces + ' placeholder in string')
197
+ throw new Error(
198
+ 'i18n: Plural form ".other" is required for "' + this.locale + '" locale'
199
+ )
101
200
  }
102
- })
103
- };
104
-
105
- /**
106
- * Check to see if the browser supports Intl and Intl.PluralRules.
107
- *
108
- * It requires all conditions to be met in order to be supported:
109
- * - The browser supports the Intl class (true in IE11)
110
- * - The implementation of Intl supports PluralRules (NOT true in IE11)
111
- * - The browser/OS has plural rules for the current locale (browser dependent)
112
- *
113
- * @returns {boolean} Returns true if all conditions are met. Returns false otherwise.
114
- */
115
- I18n.prototype.hasIntlPluralRulesSupport = function () {
116
- return Boolean(window.Intl && ('PluralRules' in window.Intl && Intl.PluralRules.supportedLocalesOf(this.locale).length))
117
- };
118
-
119
- /**
120
- * Check to see if the browser supports Intl and Intl.NumberFormat.
121
- *
122
- * It requires all conditions to be met in order to be supported:
123
- * - The browser supports the Intl class (true in IE11)
124
- * - The implementation of Intl supports NumberFormat (also true in IE11)
125
- * - The browser/OS has number formatting rules for the current locale (browser dependent)
126
- *
127
- * @returns {boolean} Returns true if all conditions are met. Returns false otherwise.
128
- */
129
- I18n.prototype.hasIntlNumberFormatSupport = function () {
130
- return Boolean(window.Intl && ('NumberFormat' in window.Intl && Intl.NumberFormat.supportedLocalesOf(this.locale).length))
131
- };
132
-
133
- /**
134
- * Get the appropriate suffix for the plural form.
135
- *
136
- * Uses Intl.PluralRules (or our own fallback implementation) to get the
137
- * 'preferred' form to use for the given count.
138
- *
139
- * Checks that a translation has been provided for that plural form – if it
140
- * hasn't, it'll fall back to the 'other' plural form (unless that doesn't exist
141
- * either, in which case an error will be thrown)
142
- *
143
- * @param {string} lookupKey - The lookup key of the string to use.
144
- * @param {number} count - Number used to determine which pluralisation to use.
145
- * @returns {PluralRule} The suffix associated with the correct pluralisation for this locale.
146
- */
147
- I18n.prototype.getPluralSuffix = function (lookupKey, count) {
148
- // Validate that the number is actually a number.
149
- //
150
- // Number(count) will turn anything that can't be converted to a Number type
151
- // into 'NaN'. isFinite filters out NaN, as it isn't a finite number.
152
- count = Number(count);
153
- if (!isFinite(count)) { return 'other' }
154
-
155
- var preferredForm;
156
-
157
- // Check to verify that all the requirements for Intl.PluralRules are met.
158
- // If so, we can use that instead of our custom implementation. Otherwise,
159
- // use the hardcoded fallback.
160
- if (this.hasIntlPluralRulesSupport()) {
161
- preferredForm = new Intl.PluralRules(this.locale).select(count);
162
- } else {
163
- preferredForm = this.selectPluralFormUsingFallbackRules(count);
164
- }
165
-
166
- // Use the correct plural form if provided
167
- if (lookupKey + '.' + preferredForm in this.translations) {
168
- return preferredForm
169
- // Fall back to `other` if the plural form is missing, but log a warning
170
- // to the console
171
- } else if (lookupKey + '.other' in this.translations) {
172
- if (console && 'warn' in console) {
173
- console.warn('i18n: Missing plural form ".' + preferredForm + '" for "' +
174
- this.locale + '" locale. Falling back to ".other".');
201
+ };
202
+
203
+ /**
204
+ * Get the plural form using our fallback implementation
205
+ *
206
+ * This is split out into a separate function to make it easier to test the
207
+ * fallback behaviour in an environment where Intl.PluralRules exists.
208
+ *
209
+ * @param {number} count - Number used to determine which pluralisation to use.
210
+ * @returns {PluralRule} The pluralisation form for count in this locale.
211
+ */
212
+ I18n.prototype.selectPluralFormUsingFallbackRules = function (count) {
213
+ // Currently our custom code can only handle positive integers, so let's
214
+ // make sure our number is one of those.
215
+ count = Math.abs(Math.floor(count));
216
+
217
+ var ruleset = this.getPluralRulesForLocale();
218
+
219
+ if (ruleset) {
220
+ return I18n.pluralRules[ruleset](count)
175
221
  }
176
222
 
177
223
  return 'other'
178
- // If the required `other` plural form is missing, all we can do is error
179
- } else {
180
- throw new Error(
181
- 'i18n: Plural form ".other" is required for "' + this.locale + '" locale'
182
- )
183
- }
184
- };
185
-
186
- /**
187
- * Get the plural form using our fallback implementation
188
- *
189
- * This is split out into a separate function to make it easier to test the
190
- * fallback behaviour in an environment where Intl.PluralRules exists.
191
- *
192
- * @param {number} count - Number used to determine which pluralisation to use.
193
- * @returns {PluralRule} The pluralisation form for count in this locale.
194
- */
195
- I18n.prototype.selectPluralFormUsingFallbackRules = function (count) {
196
- // Currently our custom code can only handle positive integers, so let's
197
- // make sure our number is one of those.
198
- count = Math.abs(Math.floor(count));
199
-
200
- var ruleset = this.getPluralRulesForLocale();
201
-
202
- if (ruleset) {
203
- return I18n.pluralRules[ruleset](count)
204
- }
205
-
206
- return 'other'
207
- };
208
-
209
- /**
210
- * Work out which pluralisation rules to use for the current locale
211
- *
212
- * The locale may include a regional indicator (such as en-GB), but we don't
213
- * usually care about this part, as pluralisation rules are usually the same
214
- * regardless of region. There are exceptions, however, (e.g. Portuguese) so
215
- * this searches by both the full and shortened locale codes, just to be sure.
216
- *
217
- * @returns {PluralRuleName | undefined} The name of the pluralisation rule to use (a key for one
218
- * of the functions in this.pluralRules)
219
- */
220
- I18n.prototype.getPluralRulesForLocale = function () {
221
- var locale = this.locale;
222
- var localeShort = locale.split('-')[0];
223
-
224
- // Look through the plural rules map to find which `pluralRule` is
225
- // appropriate for our current `locale`.
226
- for (var pluralRule in I18n.pluralRulesMap) {
227
- if (Object.prototype.hasOwnProperty.call(I18n.pluralRulesMap, pluralRule)) {
228
- var languages = I18n.pluralRulesMap[pluralRule];
229
- for (var i = 0; i < languages.length; i++) {
230
- if (languages[i] === locale || languages[i] === localeShort) {
231
- return pluralRule
224
+ };
225
+
226
+ /**
227
+ * Work out which pluralisation rules to use for the current locale
228
+ *
229
+ * The locale may include a regional indicator (such as en-GB), but we don't
230
+ * usually care about this part, as pluralisation rules are usually the same
231
+ * regardless of region. There are exceptions, however, (e.g. Portuguese) so
232
+ * this searches by both the full and shortened locale codes, just to be sure.
233
+ *
234
+ * @returns {string | undefined} The name of the pluralisation rule to use (a key for one
235
+ * of the functions in this.pluralRules)
236
+ */
237
+ I18n.prototype.getPluralRulesForLocale = function () {
238
+ var locale = this.locale;
239
+ var localeShort = locale.split('-')[0];
240
+
241
+ // Look through the plural rules map to find which `pluralRule` is
242
+ // appropriate for our current `locale`.
243
+ for (var pluralRule in I18n.pluralRulesMap) {
244
+ if (Object.prototype.hasOwnProperty.call(I18n.pluralRulesMap, pluralRule)) {
245
+ var languages = I18n.pluralRulesMap[pluralRule];
246
+ for (var i = 0; i < languages.length; i++) {
247
+ if (languages[i] === locale || languages[i] === localeShort) {
248
+ return pluralRule
249
+ }
232
250
  }
233
251
  }
234
252
  }
235
- }
236
- };
237
-
238
- /**
239
- * Map of plural rules to languages where those rules apply.
240
- *
241
- * Note: These groups are named for the most dominant or recognisable language
242
- * that uses each system. The groupings do not imply that the languages are
243
- * related to one another. Many languages have evolved the same systems
244
- * independently of one another.
245
- *
246
- * Code to support more languages can be found in the i18n spike:
247
- * {@link https://github.com/alphagov/govuk-frontend/blob/spike-i18n-support/src/govuk/i18n.mjs}
248
- *
249
- * Languages currently supported:
250
- *
251
- * Arabic: Arabic (ar)
252
- * Chinese: Burmese (my), Chinese (zh), Indonesian (id), Japanese (ja),
253
- * Javanese (jv), Korean (ko), Malay (ms), Thai (th), Vietnamese (vi)
254
- * French: Armenian (hy), Bangla (bn), French (fr), Gujarati (gu), Hindi (hi),
255
- * Persian Farsi (fa), Punjabi (pa), Zulu (zu)
256
- * German: Afrikaans (af), Albanian (sq), Azerbaijani (az), Basque (eu),
257
- * Bulgarian (bg), Catalan (ca), Danish (da), Dutch (nl), English (en),
258
- * Estonian (et), Finnish (fi), Georgian (ka), German (de), Greek (el),
259
- * Hungarian (hu), Luxembourgish (lb), Norwegian (no), Somali (so),
260
- * Swahili (sw), Swedish (sv), Tamil (ta), Telugu (te), Turkish (tr),
261
- * Urdu (ur)
262
- * Irish: Irish Gaelic (ga)
263
- * Russian: Russian (ru), Ukrainian (uk)
264
- * Scottish: Scottish Gaelic (gd)
265
- * Spanish: European Portuguese (pt-PT), Italian (it), Spanish (es)
266
- * Welsh: Welsh (cy)
267
- *
268
- * @type {Object<PluralRuleName, string[]>}
269
- */
270
- I18n.pluralRulesMap = {
271
- arabic: ['ar'],
272
- chinese: ['my', 'zh', 'id', 'ja', 'jv', 'ko', 'ms', 'th', 'vi'],
273
- french: ['hy', 'bn', 'fr', 'gu', 'hi', 'fa', 'pa', 'zu'],
274
- german: [
275
- 'af', 'sq', 'az', 'eu', 'bg', 'ca', 'da', 'nl', 'en', 'et', 'fi', 'ka',
276
- 'de', 'el', 'hu', 'lb', 'no', 'so', 'sw', 'sv', 'ta', 'te', 'tr', 'ur'
277
- ],
278
- irish: ['ga'],
279
- russian: ['ru', 'uk'],
280
- scottish: ['gd'],
281
- spanish: ['pt-PT', 'it', 'es'],
282
- welsh: ['cy']
283
- };
284
-
285
- /**
286
- * Different pluralisation rule sets
287
- *
288
- * Returns the appropriate suffix for the plural form associated with `n`.
289
- * Possible suffixes: 'zero', 'one', 'two', 'few', 'many', 'other' (the actual
290
- * meaning of each differs per locale). 'other' should always exist, even in
291
- * languages without plurals, such as Chinese.
292
- * {@link https://cldr.unicode.org/index/cldr-spec/plural-rules}
293
- *
294
- * The count must be a positive integer. Negative numbers and decimals aren't accounted for
295
- *
296
- * @type {Object<string, function(number): PluralRule>}
297
- */
298
- I18n.pluralRules = {
299
- arabic: function (n) {
300
- if (n === 0) { return 'zero' }
301
- if (n === 1) { return 'one' }
302
- if (n === 2) { return 'two' }
303
- if (n % 100 >= 3 && n % 100 <= 10) { return 'few' }
304
- if (n % 100 >= 11 && n % 100 <= 99) { return 'many' }
305
- return 'other'
306
- },
307
- chinese: function () {
308
- return 'other'
309
- },
310
- french: function (n) {
311
- return n === 0 || n === 1 ? 'one' : 'other'
312
- },
313
- german: function (n) {
314
- return n === 1 ? 'one' : 'other'
315
- },
316
- irish: function (n) {
317
- if (n === 1) { return 'one' }
318
- if (n === 2) { return 'two' }
319
- if (n >= 3 && n <= 6) { return 'few' }
320
- if (n >= 7 && n <= 10) { return 'many' }
321
- return 'other'
322
- },
323
- russian: function (n) {
324
- var lastTwo = n % 100;
325
- var last = lastTwo % 10;
326
- if (last === 1 && lastTwo !== 11) { return 'one' }
327
- if (last >= 2 && last <= 4 && !(lastTwo >= 12 && lastTwo <= 14)) { return 'few' }
328
- if (last === 0 || (last >= 5 && last <= 9) || (lastTwo >= 11 && lastTwo <= 14)) { return 'many' }
329
- // Note: The 'other' suffix is only used by decimal numbers in Russian.
330
- // We don't anticipate it being used, but it's here for consistency.
331
- return 'other'
332
- },
333
- scottish: function (n) {
334
- if (n === 1 || n === 11) { return 'one' }
335
- if (n === 2 || n === 12) { return 'two' }
336
- if ((n >= 3 && n <= 10) || (n >= 13 && n <= 19)) { return 'few' }
337
- return 'other'
338
- },
339
- spanish: function (n) {
340
- if (n === 1) { return 'one' }
341
- if (n % 1000000 === 0 && n !== 0) { return 'many' }
342
- return 'other'
343
- },
344
- welsh: function (n) {
345
- if (n === 0) { return 'zero' }
346
- if (n === 1) { return 'one' }
347
- if (n === 2) { return 'two' }
348
- if (n === 3) { return 'few' }
349
- if (n === 6) { return 'many' }
350
- return 'other'
351
- }
352
- };
353
-
354
- /**
355
- * Supported languages for plural rules
356
- *
357
- * @typedef {'arabic' | 'chinese' | 'french' | 'german' | 'irish' | 'russian' | 'scottish' | 'spanish' | 'welsh'} PluralRuleName
358
- */
359
-
360
- /**
361
- * Plural rule category mnemonic tags
362
- *
363
- * @typedef {'zero' | 'one' | 'two' | 'few' | 'many' | 'other'} PluralRule
364
- */
365
-
366
- /**
367
- * Translated message by plural rule they correspond to.
368
- *
369
- * Allows to group pluralised messages under a single key when passing
370
- * translations to a component's constructor
371
- *
372
- * @typedef {object} TranslationPluralForms
373
- * @property {string} [other] - General plural form
374
- * @property {string} [zero] - Plural form used with 0
375
- * @property {string} [one] - Plural form used with 1
376
- * @property {string} [two] - Plural form used with 2
377
- * @property {string} [few] - Plural form used for a few
378
- * @property {string} [many] - Plural form used for many
379
- */
380
-
381
- /**
382
- * Translated messages (flattened)
383
- *
384
- * @private
385
- * @typedef {Object<string, string> | {}} TranslationsFlattened
386
- */
387
-
388
- exports.I18n = I18n;
253
+ };
254
+
255
+ /**
256
+ * Map of plural rules to languages where those rules apply.
257
+ *
258
+ * Note: These groups are named for the most dominant or recognisable language
259
+ * that uses each system. The groupings do not imply that the languages are
260
+ * related to one another. Many languages have evolved the same systems
261
+ * independently of one another.
262
+ *
263
+ * Code to support more languages can be found in the i18n spike:
264
+ * {@link https://github.com/alphagov/govuk-frontend/blob/spike-i18n-support/src/govuk/i18n.mjs}
265
+ *
266
+ * Languages currently supported:
267
+ *
268
+ * Arabic: Arabic (ar)
269
+ * Chinese: Burmese (my), Chinese (zh), Indonesian (id), Japanese (ja),
270
+ * Javanese (jv), Korean (ko), Malay (ms), Thai (th), Vietnamese (vi)
271
+ * French: Armenian (hy), Bangla (bn), French (fr), Gujarati (gu), Hindi (hi),
272
+ * Persian Farsi (fa), Punjabi (pa), Zulu (zu)
273
+ * German: Afrikaans (af), Albanian (sq), Azerbaijani (az), Basque (eu),
274
+ * Bulgarian (bg), Catalan (ca), Danish (da), Dutch (nl), English (en),
275
+ * Estonian (et), Finnish (fi), Georgian (ka), German (de), Greek (el),
276
+ * Hungarian (hu), Luxembourgish (lb), Norwegian (no), Somali (so),
277
+ * Swahili (sw), Swedish (sv), Tamil (ta), Telugu (te), Turkish (tr),
278
+ * Urdu (ur)
279
+ * Irish: Irish Gaelic (ga)
280
+ * Russian: Russian (ru), Ukrainian (uk)
281
+ * Scottish: Scottish Gaelic (gd)
282
+ * Spanish: European Portuguese (pt-PT), Italian (it), Spanish (es)
283
+ * Welsh: Welsh (cy)
284
+ *
285
+ * @type {Object<string, string[]>}
286
+ */
287
+ I18n.pluralRulesMap = {
288
+ arabic: ['ar'],
289
+ chinese: ['my', 'zh', 'id', 'ja', 'jv', 'ko', 'ms', 'th', 'vi'],
290
+ french: ['hy', 'bn', 'fr', 'gu', 'hi', 'fa', 'pa', 'zu'],
291
+ german: [
292
+ 'af', 'sq', 'az', 'eu', 'bg', 'ca', 'da', 'nl', 'en', 'et', 'fi', 'ka',
293
+ 'de', 'el', 'hu', 'lb', 'no', 'so', 'sw', 'sv', 'ta', 'te', 'tr', 'ur'
294
+ ],
295
+ irish: ['ga'],
296
+ russian: ['ru', 'uk'],
297
+ scottish: ['gd'],
298
+ spanish: ['pt-PT', 'it', 'es'],
299
+ welsh: ['cy']
300
+ };
301
+
302
+ /**
303
+ * Different pluralisation rule sets
304
+ *
305
+ * Returns the appropriate suffix for the plural form associated with `n`.
306
+ * Possible suffixes: 'zero', 'one', 'two', 'few', 'many', 'other' (the actual
307
+ * meaning of each differs per locale). 'other' should always exist, even in
308
+ * languages without plurals, such as Chinese.
309
+ * {@link https://cldr.unicode.org/index/cldr-spec/plural-rules}
310
+ *
311
+ * The count must be a positive integer. Negative numbers and decimals aren't accounted for
312
+ *
313
+ * @type {Object<string, function(number): PluralRule>}
314
+ */
315
+ I18n.pluralRules = {
316
+ /* eslint-disable jsdoc/require-jsdoc */
317
+ arabic: function (n) {
318
+ if (n === 0) { return 'zero' }
319
+ if (n === 1) { return 'one' }
320
+ if (n === 2) { return 'two' }
321
+ if (n % 100 >= 3 && n % 100 <= 10) { return 'few' }
322
+ if (n % 100 >= 11 && n % 100 <= 99) { return 'many' }
323
+ return 'other'
324
+ },
325
+ chinese: function () {
326
+ return 'other'
327
+ },
328
+ french: function (n) {
329
+ return n === 0 || n === 1 ? 'one' : 'other'
330
+ },
331
+ german: function (n) {
332
+ return n === 1 ? 'one' : 'other'
333
+ },
334
+ irish: function (n) {
335
+ if (n === 1) { return 'one' }
336
+ if (n === 2) { return 'two' }
337
+ if (n >= 3 && n <= 6) { return 'few' }
338
+ if (n >= 7 && n <= 10) { return 'many' }
339
+ return 'other'
340
+ },
341
+ russian: function (n) {
342
+ var lastTwo = n % 100;
343
+ var last = lastTwo % 10;
344
+ if (last === 1 && lastTwo !== 11) { return 'one' }
345
+ if (last >= 2 && last <= 4 && !(lastTwo >= 12 && lastTwo <= 14)) { return 'few' }
346
+ if (last === 0 || (last >= 5 && last <= 9) || (lastTwo >= 11 && lastTwo <= 14)) { return 'many' }
347
+ // Note: The 'other' suffix is only used by decimal numbers in Russian.
348
+ // We don't anticipate it being used, but it's here for consistency.
349
+ return 'other'
350
+ },
351
+ scottish: function (n) {
352
+ if (n === 1 || n === 11) { return 'one' }
353
+ if (n === 2 || n === 12) { return 'two' }
354
+ if ((n >= 3 && n <= 10) || (n >= 13 && n <= 19)) { return 'few' }
355
+ return 'other'
356
+ },
357
+ spanish: function (n) {
358
+ if (n === 1) { return 'one' }
359
+ if (n % 1000000 === 0 && n !== 0) { return 'many' }
360
+ return 'other'
361
+ },
362
+ welsh: function (n) {
363
+ if (n === 0) { return 'zero' }
364
+ if (n === 1) { return 'one' }
365
+ if (n === 2) { return 'two' }
366
+ if (n === 3) { return 'few' }
367
+ if (n === 6) { return 'many' }
368
+ return 'other'
369
+ }
370
+ /* eslint-enable jsdoc/require-jsdoc */
371
+ };
372
+
373
+ /**
374
+ * Plural rule category mnemonic tags
375
+ *
376
+ * @typedef {'zero' | 'one' | 'two' | 'few' | 'many' | 'other'} PluralRule
377
+ */
378
+
379
+ /**
380
+ * Translated message by plural rule they correspond to.
381
+ *
382
+ * Allows to group pluralised messages under a single key when passing
383
+ * translations to a component's constructor
384
+ *
385
+ * @typedef {object} TranslationPluralForms
386
+ * @property {string} [other] - General plural form
387
+ * @property {string} [zero] - Plural form used with 0
388
+ * @property {string} [one] - Plural form used with 1
389
+ * @property {string} [two] - Plural form used with 2
390
+ * @property {string} [few] - Plural form used for a few
391
+ * @property {string} [many] - Plural form used for many
392
+ */
393
+
394
+ exports.I18n = I18n;
389
395
 
390
396
  })));
397
+ //# sourceMappingURL=i18n.js.map