katalyst-govuk-formbuilder 1.3.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -0
  3. data/app/assets/builds/katalyst/govuk/formbuilder.css +58 -5
  4. data/app/assets/builds/katalyst/govuk/formbuilder.js +98 -64
  5. data/app/assets/builds/katalyst/govuk/formbuilder.min.js +1 -1
  6. data/app/assets/stylesheets/katalyst/govuk/components/richtextarea/_index.scss +7 -6
  7. data/app/assets/stylesheets/katalyst/govuk/formbuilder.scss +1 -1
  8. data/lib/katalyst/govuk/formbuilder/engine.rb +1 -0
  9. data/lib/katalyst/govuk/formbuilder/version.rb +1 -1
  10. data/vendor/assets/stylesheets/govuk-frontend/govuk/_base.scss +3 -0
  11. data/vendor/assets/stylesheets/govuk-frontend/govuk/all-ie8.scss +14 -0
  12. data/vendor/assets/stylesheets/govuk-frontend/govuk/all.scss +9 -0
  13. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/_all.scss +34 -0
  14. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/accordion/_accordion.scss +2 -0
  15. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/accordion/_index.scss +392 -0
  16. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/back-link/_back-link.scss +2 -0
  17. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/back-link/_index.scss +99 -0
  18. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/breadcrumbs/_breadcrumbs.scss +2 -0
  19. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/breadcrumbs/_index.scss +147 -0
  20. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/button/_button.scss +2 -0
  21. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/button/_index.scss +297 -0
  22. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/character-count/_character-count.scss +2 -0
  23. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/character-count/_index.scss +34 -0
  24. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/checkboxes/_checkboxes.scss +2 -0
  25. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/checkboxes/_index.scss +335 -0
  26. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/cookie-banner/_cookie-banner.scss +2 -0
  27. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/cookie-banner/_index.scss +49 -0
  28. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/date-input/_date-input.scss +2 -0
  29. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/date-input/_index.scss +26 -0
  30. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/details/_details.scss +2 -0
  31. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/details/_index.scss +88 -0
  32. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/error-message/_error-message.scss +2 -0
  33. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/error-message/_index.scss +12 -0
  34. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/error-summary/_error-summary.scss +2 -0
  35. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/error-summary/_index.scss +43 -0
  36. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/fieldset/_fieldset.scss +2 -0
  37. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/fieldset/_index.scss +64 -0
  38. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/file-upload/_file-upload.scss +2 -0
  39. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/file-upload/_index.scss +55 -0
  40. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/footer/_footer.scss +2 -0
  41. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/footer/_index.scss +193 -0
  42. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/header/_header.scss +2 -0
  43. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/header/_index.scss +349 -0
  44. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/hint/_hint.scss +2 -0
  45. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/hint/_index.scss +42 -0
  46. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/input/_index.scss +193 -0
  47. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/input/_input.scss +2 -0
  48. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/inset-text/_index.scss +24 -0
  49. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/inset-text/_inset-text.scss +2 -0
  50. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/label/_index.scss +41 -0
  51. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/label/_label.scss +2 -0
  52. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/notification-banner/_index.scss +89 -0
  53. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/notification-banner/_notification-banner.scss +2 -0
  54. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/pagination/_index.scss +247 -0
  55. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/pagination/_pagination.scss +2 -0
  56. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/panel/_index.scss +56 -0
  57. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/panel/_panel.scss +2 -0
  58. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/phase-banner/_index.scss +27 -0
  59. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/phase-banner/_phase-banner.scss +2 -0
  60. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/radios/_index.scss +349 -0
  61. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/radios/_radios.scss +2 -0
  62. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/select/_index.scss +66 -0
  63. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/select/_select.scss +2 -0
  64. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/skip-link/_index.scss +47 -0
  65. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/skip-link/_skip-link.scss +2 -0
  66. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/summary-list/_index.scss +276 -0
  67. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/summary-list/_summary-list.scss +2 -0
  68. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/table/_index.scss +71 -0
  69. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/table/_table.scss +2 -0
  70. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/tabs/_index.scss +130 -0
  71. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/tabs/_tabs.scss +2 -0
  72. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/tag/_index.scss +81 -0
  73. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/tag/_tag.scss +2 -0
  74. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/textarea/_index.scss +54 -0
  75. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/textarea/_textarea.scss +2 -0
  76. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/warning-text/_index.scss +66 -0
  77. data/vendor/assets/stylesheets/govuk-frontend/govuk/components/warning-text/_warning-text.scss +2 -0
  78. data/vendor/assets/stylesheets/govuk-frontend/govuk/core/_all.scss +6 -0
  79. data/vendor/assets/stylesheets/govuk-frontend/govuk/core/_global-styles.scss +19 -0
  80. data/vendor/assets/stylesheets/govuk-frontend/govuk/core/_govuk-frontend-version.scss +5 -0
  81. data/vendor/assets/stylesheets/govuk-frontend/govuk/core/_links.scss +35 -0
  82. data/vendor/assets/stylesheets/govuk-frontend/govuk/core/_lists.scss +66 -0
  83. data/vendor/assets/stylesheets/govuk-frontend/govuk/core/_section-break.scss +56 -0
  84. data/vendor/assets/stylesheets/govuk-frontend/govuk/core/_typography.scss +186 -0
  85. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_all.scss +12 -0
  86. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_clearfix.scss +15 -0
  87. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_colour.scss +98 -0
  88. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_device-pixels.scss +37 -0
  89. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_focused.scss +33 -0
  90. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_font-faces.scss +41 -0
  91. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_grid.scss +61 -0
  92. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_links.scss +429 -0
  93. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_media-queries.scss +91 -0
  94. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_shape-arrow.scss +80 -0
  95. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_spacing.scss +171 -0
  96. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_typography.scss +214 -0
  97. data/vendor/assets/stylesheets/govuk-frontend/govuk/helpers/_visually-hidden.scss +84 -0
  98. data/vendor/assets/stylesheets/govuk-frontend/govuk/objects/_all.scss +6 -0
  99. data/vendor/assets/stylesheets/govuk-frontend/govuk/objects/_button-group.scss +85 -0
  100. data/vendor/assets/stylesheets/govuk-frontend/govuk/objects/_form-group.scss +23 -0
  101. data/vendor/assets/stylesheets/govuk-frontend/govuk/objects/_grid.scss +24 -0
  102. data/vendor/assets/stylesheets/govuk-frontend/govuk/objects/_main-wrapper.scss +53 -0
  103. data/vendor/assets/stylesheets/govuk-frontend/govuk/objects/_template.scss +32 -0
  104. data/vendor/assets/stylesheets/govuk-frontend/govuk/objects/_width-container.scss +84 -0
  105. data/vendor/assets/stylesheets/govuk-frontend/govuk/overrides/_all.scss +5 -0
  106. data/vendor/assets/stylesheets/govuk-frontend/govuk/overrides/_display.scss +24 -0
  107. data/vendor/assets/stylesheets/govuk-frontend/govuk/overrides/_spacing.scss +102 -0
  108. data/vendor/assets/stylesheets/govuk-frontend/govuk/overrides/_text-align.scss +14 -0
  109. data/vendor/assets/stylesheets/govuk-frontend/govuk/overrides/_typography.scss +21 -0
  110. data/vendor/assets/stylesheets/govuk-frontend/govuk/overrides/_width.scss +46 -0
  111. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_all.scss +24 -0
  112. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_assets.scss +82 -0
  113. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_colours-applied.scss +155 -0
  114. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_colours-organisations.scss +146 -0
  115. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_colours-palette.scss +120 -0
  116. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_compatibility.scss +100 -0
  117. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_global-styles.scss +13 -0
  118. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_ie8.scss +34 -0
  119. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_links.scss +66 -0
  120. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_measurements.scss +95 -0
  121. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_media-queries.scss +23 -0
  122. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_spacing.scss +76 -0
  123. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_typography-font-families.scss +32 -0
  124. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_typography-font.scss +112 -0
  125. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_typography-responsive.scss +195 -0
  126. data/vendor/assets/stylesheets/govuk-frontend/govuk/settings/_warnings.scss +53 -0
  127. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_all.scss +7 -0
  128. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_compatibility.scss +50 -0
  129. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_exports.scss +33 -0
  130. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_font-url.scss +25 -0
  131. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_ie8.scss +87 -0
  132. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_image-url.scss +25 -0
  133. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_px-to-em.scss +20 -0
  134. data/vendor/assets/stylesheets/govuk-frontend/govuk/tools/_px-to-rem.scss +20 -0
  135. data/vendor/assets/stylesheets/govuk-frontend/govuk/utilities/_all.scss +2 -0
  136. data/vendor/assets/stylesheets/govuk-frontend/govuk/utilities/_clearfix.scss +5 -0
  137. data/vendor/assets/stylesheets/govuk-frontend/govuk/utilities/_visually-hidden.scss +9 -0
  138. data/vendor/assets/stylesheets/govuk-frontend/govuk/vendor/_sass-mq.scss +347 -0
  139. metadata +132 -4
  140. data/app/assets/builds/katalyst/govuk/formbuilder.min.css +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adcae9707fd2bb8a976bc2208e61000139dbe07eaeb309d5d58058588e9da18b
4
- data.tar.gz: e1106ae77973289645d583efee9688bae912bca77b1cd038b2ac1e9f4675d532
3
+ metadata.gz: 58e68fe3ca009403a6a3b6f979919eb10a4841e2d67da05ce35bd76f4c711a9b
4
+ data.tar.gz: ec8757dab48258b437ed24d3393fec87e51d956658262fce3d80113f51d64303
5
5
  SHA512:
6
- metadata.gz: ee422822f141806456f21a44da3989cf560e33fbbbed337513aa8e3918f58ad4c7c499f6a3bfc1a54ac834dcdd3331d117aee75f9727d01fc93758006646e2c1
7
- data.tar.gz: 515c407a9fd737fbe50bc118e9096d7df4deafbf06c805725198511e1bf40a7834ea70f5612e25b6234acc802a9e1b2675aa2a402f067f03664dc77cae5c3e33
6
+ metadata.gz: a2dc00bb4778ee15bdfd8a964cb60b107a48ee41dff48bcab840fdb59185b4d6fddb2406d45af5e2b1ea0b86fc5d71811790ea98ecd62c38191c274411134e0f
7
+ data.tar.gz: f4b98623d425c1107f5e2688ad77482f03dfb803d05378f3f7b4e0d68cdb3fe3aa83df7134b18bbc50425f76e67a00af9a07ed4acfc811a96d205d0f534bede9
data/README.md CHANGED
@@ -47,6 +47,14 @@ helper Katalyst::GOVUK::Formbuilder::Frontend
47
47
 
48
48
  Bug reports and pull requests are welcome on GitHub at https://github.com/katalyst/govuk-formbuilder.
49
49
 
50
+ ## Release
51
+
52
+ Update the version number in `lib/katalyst/govuk/formbuilder/version.rb` and run:
53
+
54
+ ```bash
55
+ bundle exec rake release
56
+ ```
57
+
50
58
  ## License
51
59
 
52
60
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,3 +1,7 @@
1
+ :root {
2
+ --govuk-frontend-version: "4.6.0";
3
+ }
4
+
1
5
  .govuk-link {
2
6
  font-family: "Open Sans", sans-serif;
3
7
  -webkit-font-smoothing: antialiased;
@@ -1128,7 +1132,7 @@
1128
1132
  .govuk-button[disabled=disabled]:hover,
1129
1133
  .govuk-button[disabled]:hover {
1130
1134
  background-color: #00703c;
1131
- cursor: default;
1135
+ cursor: not-allowed;
1132
1136
  }
1133
1137
  .govuk-button--disabled:active,
1134
1138
  .govuk-button[disabled=disabled]:active,
@@ -1728,7 +1732,7 @@
1728
1732
 
1729
1733
  .govuk-checkboxes__input:disabled,
1730
1734
  .govuk-checkboxes__input:disabled + .govuk-checkboxes__label {
1731
- cursor: default;
1735
+ cursor: not-allowed;
1732
1736
  }
1733
1737
 
1734
1738
  .govuk-checkboxes__input:disabled + .govuk-checkboxes__label,
@@ -1893,6 +1897,12 @@
1893
1897
  outline-offset: 0;
1894
1898
  box-shadow: inset 0 0 0 2px;
1895
1899
  }
1900
+ .govuk-input:disabled {
1901
+ opacity: 0.5;
1902
+ color: inherit;
1903
+ background-color: transparent;
1904
+ cursor: not-allowed;
1905
+ }
1896
1906
 
1897
1907
  .govuk-input::-webkit-outer-spin-button,
1898
1908
  .govuk-input::-webkit-inner-spin-button {
@@ -1911,6 +1921,28 @@
1911
1921
  border-color: #0b0c0c;
1912
1922
  }
1913
1923
 
1924
+ .govuk-input--extra-letter-spacing {
1925
+ font-family: "Open Sans", sans-serif;
1926
+ -webkit-font-smoothing: antialiased;
1927
+ -moz-osx-font-smoothing: grayscale;
1928
+ -webkit-font-feature-settings: "tnum" 1;
1929
+ font-feature-settings: "tnum" 1;
1930
+ font-weight: 400;
1931
+ letter-spacing: 0.05em;
1932
+ }
1933
+ @media print {
1934
+ .govuk-input--extra-letter-spacing {
1935
+ font-family: sans-serif;
1936
+ }
1937
+ }
1938
+ @supports (font-variant-numeric: tabular-nums) {
1939
+ .govuk-input--extra-letter-spacing {
1940
+ -webkit-font-feature-settings: normal;
1941
+ font-feature-settings: normal;
1942
+ font-variant-numeric: tabular-nums;
1943
+ }
1944
+ }
1945
+
1914
1946
  .govuk-input--width-30 {
1915
1947
  max-width: 29.5em;
1916
1948
  }
@@ -2249,6 +2281,10 @@
2249
2281
  outline: 3px solid #ffdd00;
2250
2282
  box-shadow: inset 0 0 0 4px #0b0c0c;
2251
2283
  }
2284
+ .govuk-file-upload:disabled {
2285
+ opacity: 0.5;
2286
+ cursor: not-allowed;
2287
+ }
2252
2288
 
2253
2289
  .govuk-radios__item {
2254
2290
  font-family: "Open Sans", sans-serif;
@@ -2360,7 +2396,7 @@
2360
2396
 
2361
2397
  .govuk-radios__input:disabled,
2362
2398
  .govuk-radios__input:disabled + .govuk-radios__label {
2363
- cursor: default;
2399
+ cursor: not-allowed;
2364
2400
  }
2365
2401
 
2366
2402
  .govuk-radios__input:disabled + .govuk-radios__label,
@@ -2540,6 +2576,11 @@
2540
2576
  outline-offset: 0;
2541
2577
  box-shadow: inset 0 0 0 2px;
2542
2578
  }
2579
+ .govuk-select:disabled {
2580
+ opacity: 0.5;
2581
+ color: inherit;
2582
+ cursor: not-allowed;
2583
+ }
2543
2584
 
2544
2585
  .govuk-select option:active,
2545
2586
  .govuk-select option:checked,
@@ -2602,6 +2643,12 @@
2602
2643
  outline-offset: 0;
2603
2644
  box-shadow: inset 0 0 0 2px;
2604
2645
  }
2646
+ .govuk-textarea:disabled {
2647
+ opacity: 0.5;
2648
+ color: inherit;
2649
+ background-color: transparent;
2650
+ cursor: not-allowed;
2651
+ }
2605
2652
 
2606
2653
  .govuk-textarea--error {
2607
2654
  border-color: #d4351c;
@@ -4141,10 +4188,16 @@
4141
4188
  outline-offset: 0;
4142
4189
  box-shadow: inset 0 0 0 2px;
4143
4190
  }
4191
+ .govuk-richtextarea:disabled {
4192
+ opacity: 0.5;
4193
+ color: inherit;
4194
+ background-color: transparent;
4195
+ cursor: not-allowed;
4196
+ }
4144
4197
 
4145
- .govuk-richtextarea--error {
4198
+ .govuk-textarea--error {
4146
4199
  border-color: #d4351c;
4147
4200
  }
4148
- .govuk-richtextarea--error:focus {
4201
+ .govuk-textarea--error:focus {
4149
4202
  border-color: #0b0c0c;
4150
4203
  }
@@ -276,7 +276,7 @@ function normaliseString(value) {
276
276
  if (trimmedValue === "false") {
277
277
  return false;
278
278
  }
279
- if (trimmedValue.length > 0 && isFinite(trimmedValue)) {
279
+ if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
280
280
  return Number(trimmedValue);
281
281
  }
282
282
  return value;
@@ -551,7 +551,7 @@ var KEY_SPACE = 32;
551
551
  var DEBOUNCE_TIMEOUT_IN_SECONDS = 1;
552
552
 
553
553
  function Button($module, config) {
554
- if (!$module) {
554
+ if (!($module instanceof HTMLElement)) {
555
555
  return this;
556
556
  }
557
557
  this.$module = $module;
@@ -572,7 +572,10 @@ Button.prototype.init = function() {
572
572
 
573
573
  Button.prototype.handleKeyDown = function(event) {
574
574
  var $target = event.target;
575
- if ($target.getAttribute("role") === "button" && event.keyCode === KEY_SPACE) {
575
+ if (event.keyCode !== KEY_SPACE) {
576
+ return;
577
+ }
578
+ if ($target instanceof HTMLElement && $target.getAttribute("role") === "button") {
576
579
  event.preventDefault();
577
580
  $target.click();
578
581
  }
@@ -618,10 +621,8 @@ Button.prototype.debounce = function(event) {
618
621
  }).call("object" === typeof window && window || "object" === typeof self && self || "object" === typeof global && global || {});
619
622
 
620
623
  function closestAttributeValue($element, attributeName) {
621
- var closestElementWithAttribute = $element.closest("[" + attributeName + "]");
622
- if (closestElementWithAttribute) {
623
- return closestElementWithAttribute.getAttribute(attributeName);
624
- }
624
+ var $closestElementWithAttribute = $element.closest("[" + attributeName + "]");
625
+ return $closestElementWithAttribute ? $closestElementWithAttribute.getAttribute(attributeName) : null;
625
626
  }
626
627
 
627
628
  function I18n(translations, config) {
@@ -633,11 +634,11 @@ I18n.prototype.t = function(lookupKey, options) {
633
634
  if (!lookupKey) {
634
635
  throw new Error("i18n: lookup key missing");
635
636
  }
636
- if (options && typeof options.count !== "undefined") {
637
+ if (options && typeof options.count === "number") {
637
638
  lookupKey = lookupKey + "." + this.getPluralSuffix(lookupKey, options.count);
638
639
  }
639
- if (lookupKey in this.translations) {
640
- var translationString = this.translations[lookupKey];
640
+ var translationString = this.translations[lookupKey];
641
+ if (typeof translationString === "string") {
641
642
  if (translationString.match(/%{(.\S+)}/)) {
642
643
  if (!options) {
643
644
  throw new Error("i18n: cannot replace placeholders in string if no option data provided");
@@ -659,11 +660,11 @@ I18n.prototype.replacePlaceholders = function(translationString, options) {
659
660
  return translationString.replace(/%{(.\S+)}/g, (function(placeholderWithBraces, placeholderKey) {
660
661
  if (Object.prototype.hasOwnProperty.call(options, placeholderKey)) {
661
662
  var placeholderValue = options[placeholderKey];
662
- if (placeholderValue === false) {
663
+ if (placeholderValue === false || typeof placeholderValue !== "number" && typeof placeholderValue !== "string") {
663
664
  return "";
664
665
  }
665
- if (typeof placeholderValue === "number" && formatter) {
666
- return formatter.format(placeholderValue);
666
+ if (typeof placeholderValue === "number") {
667
+ return formatter ? formatter.format(placeholderValue) : placeholderValue.toString();
667
668
  }
668
669
  return placeholderValue;
669
670
  } else {
@@ -1108,7 +1109,11 @@ var CHARACTER_COUNT_TRANSLATIONS = {
1108
1109
  };
1109
1110
 
1110
1111
  function CharacterCount($module, config) {
1111
- if (!$module) {
1112
+ if (!($module instanceof HTMLElement)) {
1113
+ return this;
1114
+ }
1115
+ var $textarea = $module.querySelector(".govuk-js-character-count");
1116
+ if (!($textarea instanceof HTMLTextAreaElement || $textarea instanceof HTMLInputElement)) {
1112
1117
  return this;
1113
1118
  }
1114
1119
  var defaultConfig = {
@@ -1127,26 +1132,32 @@ function CharacterCount($module, config) {
1127
1132
  this.i18n = new I18n(extractConfigByNamespace(this.config, "i18n"), {
1128
1133
  locale: closestAttributeValue($module, "lang")
1129
1134
  });
1130
- if (this.config.maxwords) {
1135
+ this.maxLength = Infinity;
1136
+ if ("maxwords" in this.config && this.config.maxwords) {
1131
1137
  this.maxLength = this.config.maxwords;
1132
- } else if (this.config.maxlength) {
1138
+ } else if ("maxlength" in this.config && this.config.maxlength) {
1133
1139
  this.maxLength = this.config.maxlength;
1134
1140
  } else {
1135
1141
  return;
1136
1142
  }
1137
1143
  this.$module = $module;
1138
- this.$textarea = $module.querySelector(".govuk-js-character-count");
1144
+ this.$textarea = $textarea;
1139
1145
  this.$visibleCountMessage = null;
1140
1146
  this.$screenReaderCountMessage = null;
1141
1147
  this.lastInputTimestamp = null;
1148
+ this.lastInputValue = "";
1149
+ this.valueChecker = null;
1142
1150
  }
1143
1151
 
1144
1152
  CharacterCount.prototype.init = function() {
1145
- if (!this.$textarea) {
1153
+ if (!this.$module || !this.$textarea) {
1146
1154
  return;
1147
1155
  }
1148
1156
  var $textarea = this.$textarea;
1149
1157
  var $textareaDescription = document.getElementById($textarea.id + "-info");
1158
+ if (!$textareaDescription) {
1159
+ return;
1160
+ }
1150
1161
  if ($textareaDescription.innerText.match(/^\s*$/)) {
1151
1162
  $textareaDescription.innerText = this.i18n.t("textareaDescription", {
1152
1163
  count: this.maxLength
@@ -1167,11 +1178,7 @@ CharacterCount.prototype.init = function() {
1167
1178
  $textareaDescription.classList.add("govuk-visually-hidden");
1168
1179
  $textarea.removeAttribute("maxlength");
1169
1180
  this.bindChangeEvents();
1170
- if ("onpageshow" in window) {
1171
- window.addEventListener("pageshow", this.updateCountMessage.bind(this));
1172
- } else {
1173
- window.addEventListener("DOMContentLoaded", this.updateCountMessage.bind(this));
1174
- }
1181
+ window.addEventListener("onpageshow" in window ? "pageshow" : "DOMContentLoaded", this.updateCountMessage.bind(this));
1175
1182
  this.updateCountMessage();
1176
1183
  };
1177
1184
 
@@ -1200,9 +1207,8 @@ CharacterCount.prototype.handleBlur = function() {
1200
1207
  };
1201
1208
 
1202
1209
  CharacterCount.prototype.updateIfValueChanged = function() {
1203
- if (!this.$textarea.oldValue) this.$textarea.oldValue = "";
1204
- if (this.$textarea.value !== this.$textarea.oldValue) {
1205
- this.$textarea.oldValue = this.$textarea.value;
1210
+ if (this.$textarea.value !== this.lastInputValue) {
1211
+ this.lastInputValue = this.$textarea.value;
1206
1212
  this.updateCountMessage();
1207
1213
  }
1208
1214
  };
@@ -1238,13 +1244,13 @@ CharacterCount.prototype.updateScreenReaderCountMessage = function() {
1238
1244
  if (this.isOverThreshold()) {
1239
1245
  $screenReaderCountMessage.removeAttribute("aria-hidden");
1240
1246
  } else {
1241
- $screenReaderCountMessage.setAttribute("aria-hidden", true);
1247
+ $screenReaderCountMessage.setAttribute("aria-hidden", "true");
1242
1248
  }
1243
1249
  $screenReaderCountMessage.innerText = this.getCountMessage();
1244
1250
  };
1245
1251
 
1246
1252
  CharacterCount.prototype.count = function(text) {
1247
- if (this.config.maxwords) {
1253
+ if ("maxwords" in this.config && this.config.maxwords) {
1248
1254
  var tokens = text.match(/\S+/g) || [];
1249
1255
  return tokens.length;
1250
1256
  } else {
@@ -1254,7 +1260,7 @@ CharacterCount.prototype.count = function(text) {
1254
1260
 
1255
1261
  CharacterCount.prototype.getCountMessage = function() {
1256
1262
  var remainingNumber = this.maxLength - this.count(this.$textarea.value);
1257
- var countType = this.config.maxwords ? "words" : "characters";
1263
+ var countType = "maxwords" in this.config && this.config.maxwords ? "words" : "characters";
1258
1264
  return this.formatCountMessage(remainingNumber, countType);
1259
1265
  };
1260
1266
 
@@ -1280,11 +1286,21 @@ CharacterCount.prototype.isOverThreshold = function() {
1280
1286
  };
1281
1287
 
1282
1288
  function Checkboxes($module) {
1289
+ if (!($module instanceof HTMLElement)) {
1290
+ return this;
1291
+ }
1292
+ var $inputs = $module.querySelectorAll('input[type="checkbox"]');
1293
+ if (!$inputs.length) {
1294
+ return this;
1295
+ }
1283
1296
  this.$module = $module;
1284
- this.$inputs = $module.querySelectorAll('input[type="checkbox"]');
1297
+ this.$inputs = $inputs;
1285
1298
  }
1286
1299
 
1287
1300
  Checkboxes.prototype.init = function() {
1301
+ if (!this.$module || !this.$inputs) {
1302
+ return;
1303
+ }
1288
1304
  var $module = this.$module;
1289
1305
  var $inputs = this.$inputs;
1290
1306
  nodeListForEach($inputs, (function($input) {
@@ -1295,11 +1311,7 @@ Checkboxes.prototype.init = function() {
1295
1311
  $input.setAttribute("aria-controls", targetId);
1296
1312
  $input.removeAttribute("data-aria-controls");
1297
1313
  }));
1298
- if ("onpageshow" in window) {
1299
- window.addEventListener("pageshow", this.syncAllConditionalReveals.bind(this));
1300
- } else {
1301
- window.addEventListener("DOMContentLoaded", this.syncAllConditionalReveals.bind(this));
1302
- }
1314
+ window.addEventListener("onpageshow" in window ? "pageshow" : "DOMContentLoaded", this.syncAllConditionalReveals.bind(this));
1303
1315
  this.syncAllConditionalReveals();
1304
1316
  $module.addEventListener("click", this.handleClick.bind(this));
1305
1317
  };
@@ -1309,39 +1321,45 @@ Checkboxes.prototype.syncAllConditionalReveals = function() {
1309
1321
  };
1310
1322
 
1311
1323
  Checkboxes.prototype.syncConditionalRevealWithInputState = function($input) {
1312
- var $target = document.getElementById($input.getAttribute("aria-controls"));
1324
+ var targetId = $input.getAttribute("aria-controls");
1325
+ if (!targetId) {
1326
+ return;
1327
+ }
1328
+ var $target = document.getElementById(targetId);
1313
1329
  if ($target && $target.classList.contains("govuk-checkboxes__conditional")) {
1314
1330
  var inputIsChecked = $input.checked;
1315
- $input.setAttribute("aria-expanded", inputIsChecked);
1331
+ $input.setAttribute("aria-expanded", inputIsChecked.toString());
1316
1332
  $target.classList.toggle("govuk-checkboxes__conditional--hidden", !inputIsChecked);
1317
1333
  }
1318
1334
  };
1319
1335
 
1320
1336
  Checkboxes.prototype.unCheckAllInputsExcept = function($input) {
1337
+ var $component = this;
1321
1338
  var allInputsWithSameName = document.querySelectorAll('input[type="checkbox"][name="' + $input.name + '"]');
1322
- nodeListForEach(allInputsWithSameName, function($inputWithSameName) {
1339
+ nodeListForEach(allInputsWithSameName, (function($inputWithSameName) {
1323
1340
  var hasSameFormOwner = $input.form === $inputWithSameName.form;
1324
1341
  if (hasSameFormOwner && $inputWithSameName !== $input) {
1325
1342
  $inputWithSameName.checked = false;
1326
- this.syncConditionalRevealWithInputState($inputWithSameName);
1343
+ $component.syncConditionalRevealWithInputState($inputWithSameName);
1327
1344
  }
1328
- }.bind(this));
1345
+ }));
1329
1346
  };
1330
1347
 
1331
1348
  Checkboxes.prototype.unCheckExclusiveInputs = function($input) {
1349
+ var $component = this;
1332
1350
  var allInputsWithSameNameAndExclusiveBehaviour = document.querySelectorAll('input[data-behaviour="exclusive"][type="checkbox"][name="' + $input.name + '"]');
1333
- nodeListForEach(allInputsWithSameNameAndExclusiveBehaviour, function($exclusiveInput) {
1351
+ nodeListForEach(allInputsWithSameNameAndExclusiveBehaviour, (function($exclusiveInput) {
1334
1352
  var hasSameFormOwner = $input.form === $exclusiveInput.form;
1335
1353
  if (hasSameFormOwner) {
1336
1354
  $exclusiveInput.checked = false;
1337
- this.syncConditionalRevealWithInputState($exclusiveInput);
1355
+ $component.syncConditionalRevealWithInputState($exclusiveInput);
1338
1356
  }
1339
- }.bind(this));
1357
+ }));
1340
1358
  };
1341
1359
 
1342
1360
  Checkboxes.prototype.handleClick = function(event) {
1343
1361
  var $clickedInput = event.target;
1344
- if ($clickedInput.type !== "checkbox") {
1362
+ if (!($clickedInput instanceof HTMLInputElement) || $clickedInput.type !== "checkbox") {
1345
1363
  return;
1346
1364
  }
1347
1365
  var hasAriaControls = $clickedInput.getAttribute("aria-controls");
@@ -1360,7 +1378,7 @@ Checkboxes.prototype.handleClick = function(event) {
1360
1378
  };
1361
1379
 
1362
1380
  function ErrorSummary($module, config) {
1363
- if (!$module) {
1381
+ if (!($module instanceof HTMLElement)) {
1364
1382
  return this;
1365
1383
  }
1366
1384
  this.$module = $module;
@@ -1371,10 +1389,10 @@ function ErrorSummary($module, config) {
1371
1389
  }
1372
1390
 
1373
1391
  ErrorSummary.prototype.init = function() {
1374
- var $module = this.$module;
1375
- if (!$module) {
1392
+ if (!this.$module) {
1376
1393
  return;
1377
1394
  }
1395
+ var $module = this.$module;
1378
1396
  this.setFocus();
1379
1397
  $module.addEventListener("click", this.handleClick.bind(this));
1380
1398
  };
@@ -1399,10 +1417,13 @@ ErrorSummary.prototype.handleClick = function(event) {
1399
1417
  };
1400
1418
 
1401
1419
  ErrorSummary.prototype.focusTarget = function($target) {
1402
- if ($target.tagName !== "A" || $target.href === false) {
1420
+ if (!($target instanceof HTMLAnchorElement)) {
1403
1421
  return false;
1404
1422
  }
1405
1423
  var inputId = this.getFragmentFromUrl($target.href);
1424
+ if (!inputId) {
1425
+ return false;
1426
+ }
1406
1427
  var $input = document.getElementById(inputId);
1407
1428
  if (!$input) {
1408
1429
  return false;
@@ -1420,7 +1441,7 @@ ErrorSummary.prototype.focusTarget = function($target) {
1420
1441
 
1421
1442
  ErrorSummary.prototype.getFragmentFromUrl = function(url) {
1422
1443
  if (url.indexOf("#") === -1) {
1423
- return false;
1444
+ return undefined;
1424
1445
  }
1425
1446
  return url.split("#").pop();
1426
1447
  };
@@ -1431,7 +1452,7 @@ ErrorSummary.prototype.getAssociatedLegendOrLabel = function($input) {
1431
1452
  var $legends = $fieldset.getElementsByTagName("legend");
1432
1453
  if ($legends.length) {
1433
1454
  var $candidateLegend = $legends[0];
1434
- if ($input.type === "checkbox" || $input.type === "radio") {
1455
+ if ($input instanceof HTMLInputElement && ($input.type === "checkbox" || $input.type === "radio")) {
1435
1456
  return $candidateLegend;
1436
1457
  }
1437
1458
  var legendTop = $candidateLegend.getBoundingClientRect().top;
@@ -1448,11 +1469,21 @@ ErrorSummary.prototype.getAssociatedLegendOrLabel = function($input) {
1448
1469
  };
1449
1470
 
1450
1471
  function Radios($module) {
1472
+ if (!($module instanceof HTMLElement)) {
1473
+ return this;
1474
+ }
1475
+ var $inputs = $module.querySelectorAll('input[type="radio"]');
1476
+ if (!$inputs.length) {
1477
+ return this;
1478
+ }
1451
1479
  this.$module = $module;
1452
- this.$inputs = $module.querySelectorAll('input[type="radio"]');
1480
+ this.$inputs = $inputs;
1453
1481
  }
1454
1482
 
1455
1483
  Radios.prototype.init = function() {
1484
+ if (!this.$module || !this.$inputs) {
1485
+ return;
1486
+ }
1456
1487
  var $module = this.$module;
1457
1488
  var $inputs = this.$inputs;
1458
1489
  nodeListForEach($inputs, (function($input) {
@@ -1463,11 +1494,7 @@ Radios.prototype.init = function() {
1463
1494
  $input.setAttribute("aria-controls", targetId);
1464
1495
  $input.removeAttribute("data-aria-controls");
1465
1496
  }));
1466
- if ("onpageshow" in window) {
1467
- window.addEventListener("pageshow", this.syncAllConditionalReveals.bind(this));
1468
- } else {
1469
- window.addEventListener("DOMContentLoaded", this.syncAllConditionalReveals.bind(this));
1470
- }
1497
+ window.addEventListener("onpageshow" in window ? "pageshow" : "DOMContentLoaded", this.syncAllConditionalReveals.bind(this));
1471
1498
  this.syncAllConditionalReveals();
1472
1499
  $module.addEventListener("click", this.handleClick.bind(this));
1473
1500
  };
@@ -1477,27 +1504,34 @@ Radios.prototype.syncAllConditionalReveals = function() {
1477
1504
  };
1478
1505
 
1479
1506
  Radios.prototype.syncConditionalRevealWithInputState = function($input) {
1480
- var $target = document.getElementById($input.getAttribute("aria-controls"));
1507
+ var targetId = $input.getAttribute("aria-controls");
1508
+ if (!targetId) {
1509
+ return;
1510
+ }
1511
+ var $target = document.getElementById(targetId);
1481
1512
  if ($target && $target.classList.contains("govuk-radios__conditional")) {
1482
1513
  var inputIsChecked = $input.checked;
1483
- $input.setAttribute("aria-expanded", inputIsChecked);
1514
+ $input.setAttribute("aria-expanded", inputIsChecked.toString());
1484
1515
  $target.classList.toggle("govuk-radios__conditional--hidden", !inputIsChecked);
1485
1516
  }
1486
1517
  };
1487
1518
 
1488
1519
  Radios.prototype.handleClick = function(event) {
1520
+ var $component = this;
1489
1521
  var $clickedInput = event.target;
1490
- if ($clickedInput.type !== "radio") {
1522
+ if (!($clickedInput instanceof HTMLInputElement) || $clickedInput.type !== "radio") {
1491
1523
  return;
1492
1524
  }
1493
1525
  var $allInputs = document.querySelectorAll('input[type="radio"][aria-controls]');
1494
- nodeListForEach($allInputs, function($input) {
1495
- var hasSameFormOwner = $input.form === $clickedInput.form;
1496
- var hasSameName = $input.name === $clickedInput.name;
1526
+ var $clickedInputForm = $clickedInput.form;
1527
+ var $clickedInputName = $clickedInput.name;
1528
+ nodeListForEach($allInputs, (function($input) {
1529
+ var hasSameFormOwner = $input.form === $clickedInputForm;
1530
+ var hasSameName = $input.name === $clickedInputName;
1497
1531
  if (hasSameName && hasSameFormOwner) {
1498
- this.syncConditionalRevealWithInputState($input);
1532
+ $component.syncConditionalRevealWithInputState($input);
1499
1533
  }
1500
- }.bind(this));
1534
+ }));
1501
1535
  };
1502
1536
 
1503
1537
  function initAll(options) {