PageSourceSearch

https://umbro.fr/modules/pm_advancedsearch4/views/js/selectize/selectize-plugin-a11y.js

js umbro.fr collected 2026-10-04 02:25:43 UTC 5,102 bytes, 165 lines download raw bytes

1/*
2 * selectize-plugin-a11y
3 * https://github.com/SalmenBejaoui/selectize-plugin-a11y
4 *
5 * Copyright 2018-present Salmen Bejaoui
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25/* global Selectize */
26Selectize.define("selectize-plugin-a11y", function (options) {
27  var self = this;
28  var KEY_RETURN = 13;
29
30  if (typeof self.accessibility === "undefined") {
31    self.accessibility = {};
32  }
33
34  self.accessibility.helpers = {
35    randomId: function (len) {
36      var str = "",
37        strLength = len || 10,
38        base = "abcdefghijklmnopqrstuvwxyz0123456789",
39        baseLength = base.length;
40
41      for (var i = 0; i < strLength; i++) {
42        str += base[Math.floor(baseLength * Math.random())];
43      }
44
45      return str;
46    }
47  };
48
49  self.accessibility.liveRegion = {
50    $region: "",
51    speak: function (msg) {
52      var $container = $("<div></div>");
53      $container.text(msg);
54      this.$region.html($container);
55    },
56    domListener: function () {
57      var observer = new MutationObserver(function (mutations) {
58        mutations.forEach(function (mutation) {
59          var $target = $(mutation.target);
60          if ($target.hasClass("items")) {
61            if ($target.hasClass("dropdown-active")) {
62              // open
63              self.$control_input.attr("aria-expanded", "true");
64            } else {
65              // close
66              self.$control_input.attr("aria-expanded", "false");
67              self.$control_input.removeAttr("aria-activedescendant");
68            }
69          } else {
70            // option change
71            if ($target.hasClass("active")) {
72              if (!!$target.attr("data-value")) { // eslint-disable-line no-extra-boolean-cast
73                self.$control_input.attr(
74                  "aria-activedescendant",
75                  $target.attr("id")
76                );
77                self.accessibility.liveRegion.speak($target.text(), 500);
78              }
79            }
80          }
81        });
82      });
83      observer.observe(self.$dropdown[0], {
84        attributes: true,
85        attributeFilter: ["class"],
86        subtree: true,
87        attributeOldValue: true
88      });
89
90      observer.observe(self.$control[0], {
91        attributes: true,
92        attributeFilter: ["class"]
93      });
94
95      observer.observe(self.$control_input[0], {
96        attributes: true,
97        attributeFilter: ["value"]
98      });
99    },
100    setAttributes: function () {
101      this.$region.attr({
102        "aria-live": "assertive",
103        role: "log",
104        "aria-relevant": "additions",
105        "aria-atomic": "true"
106      });
107    },
108    setStyles: function () {
109      this.$region.css({
110        position: "absolute",
111        width: "1px",
112        height: "1px",
113        "margin-top": "-1px",
114        clip: "rect(1px, 1px, 1px, 1px)",
115        overflow: "hidden"
116      });
117    },
118    init: function () {
119      this.$region = $("<div>");
120      this.setAttributes();
121      this.setStyles();
122      $("body").append(this.$region);
123      this.domListener();
124    }
125  };
126
127  this.setup = (function () {
128    var original = self.setup;
129    return function () {
130      original.apply(this, arguments);
131      var inputId = self.accessibility.helpers.randomId(),
132        listboxId = self.accessibility.helpers.randomId();
133
134      self.$control.on("keydown", function (e) {
135        if (e.keyCode === KEY_RETURN) {
136          $(this).click();
137        }
138      });
139
140      self.$control_input.attr({
141        role: "combobox",
142        "aria-expanded": "false",
143        haspopup: "listbox",
144        "aria-owns": listboxId,
145        "aria-label": self.$wrapper
146          .closest("[data-accessibility-selectize-label]")
147          .attr("data-accessibility-selectize-label")
148      });
149
150      self.$dropdown_content.attr({
151        role: "listbox",
152        id: listboxId
153      });
154      self.accessibility.liveRegion.init();
155    };
156  })();
157
158  this.destroy = (function () {
159    var original = self.destroy;
160    return function () {
161      self.accessibility.liveRegion.$region.remove();
162      return original.apply(this, arguments);
163    };
164  })();
165});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.