Commit e55ae36e authored by Doris Tam's avatar Doris Tam 🌷 Committed by Robert Lyon
Browse files

Bug 1940893 - Select2 customisation: Improve accessibility of select2 (Bug #1492081)

Compare to https://reviews.mahara.org/#/c/5251/11/htdocs/js/select2/select2.full.js

Change-Id: I7236cf2d9371076fb869a0cb261a8c172c9fb98c
parent 714bbf18
Loading
Loading
Loading
Loading
+76 −21
Original line number Diff line number Diff line
@@ -877,8 +877,9 @@ S2.define('select2/results',[
    this.clear();
    this.hideLoading();

    var messageId = this.data.generateResultId({ id: this.$results.attr('id') }, {});
    var $message = $(
      '<li role="alert" aria-live="assertive"' +
      '<li id="' + messageId + '" role="alert" aria-live="assertive"' +
      ' class="select2-results__option"></li>'
    );

@@ -893,6 +894,7 @@ S2.define('select2/results',[
    $message[0].className += ' select2-results__message';

    this.$results.append($message);
    this.trigger('results:speak', { id: messageId });
  };

  Results.prototype.hideMessages = function () {
@@ -957,7 +959,7 @@ S2.define('select2/results',[
    this.ensureHighlightVisible();
  };

  Results.prototype.setClasses = function () {
  Results.prototype.setClasses = function (highlightIndex) {
    var self = this;

    this.data.current(function (selected) {
@@ -984,6 +986,19 @@ S2.define('select2/results',[
        }
      });

      var $selected = $options.filter('[aria-selected=true]');

      if (highlightIndex >= 0) {
        // If a specific index has been given, highlight it
        $options.eq(highlightIndex).trigger('mouseenter');
      } else if ($selected.length > 0) {
        // If there are selected options, highlight the first
        $selected.first().trigger('mouseenter');
      } else {
        // If there are no selected options, highlight the first option
        // in the dropdown
        $options.first().trigger('mouseenter');
      }
    });
  };

@@ -1044,6 +1059,14 @@ S2.define('select2/results',[
      delete attrs['aria-selected'];
    }

    if (data.element) {
        $element = $(data.element);
        if ($element.hasClass('readonly')) {
            var currentclass = option.getAttribute('class');
            option.setAttribute('class', 'readonly ' + currentclass);
        }
    }

    for (var attr in attrs) {
      var val = attrs[attr];

@@ -1104,10 +1127,13 @@ S2.define('select2/results',[
    });

    container.on('results:append', function (params) {
      var previousIndex = self.$results
        .find('.select2-results__option[aria-selected]').length - 1;

      self.append(params.data);

      if (container.isOpen()) {
        self.setClasses();
        self.setClasses(previousIndex);
      }
    });

@@ -1290,10 +1316,12 @@ S2.define('select2/results',[

      if ($this.attr('aria-selected') === 'true') {
        if (self.options.get('multiple')) {
          if (!$this.hasClass('readonly')) {
            self.trigger('unselect', {
              originalEvent: evt,
              data: data
            });
          }
        } else {
          self.trigger('close', {});
        }
@@ -1318,6 +1346,9 @@ S2.define('select2/results',[
        data: data,
        element: $(this)
      });
      self.trigger('results:speak', {
        id: $(this).attr('id')
      });
    });
  };

@@ -1418,7 +1449,7 @@ S2.define('select2/selection/base',[
  BaseSelection.prototype.render = function () {
    var $selection = $(
      '<span class="select2-selection" role="combobox" ' +
      ' aria-haspopup="true" aria-expanded="false">' +
      ' aria-haspopup="true" aria-expanded="false" aria-labelledby="' + this.options.labels.join(' ') + '">' +
      '</span>'
    );

@@ -1462,10 +1493,6 @@ S2.define('select2/selection/base',[
      }
    });

    container.on('results:focus', function (params) {
      self.$selection.attr('aria-activedescendant', params.data._resultId);
    });

    container.on('selection:update', function (params) {
      self.update(params.data);
    });
@@ -1741,8 +1768,7 @@ S2.define('select2/selection/multiple',[
          data: data
        });
      }
    );
  };
    )};

  MultipleSelection.prototype.clear = function () {
    var $rendered = this.$selection.find('.select2-selection__rendered');
@@ -2026,6 +2052,10 @@ S2.define('select2/selection/search',[
      self.$search.prop('disabled', true);
    });

    container.on('results:speak', function (params) {
      self.$search.attr('aria-activedescendant', params.id);
    });

    container.on('focus', function (evt) {
      self.$search.trigger('focus');
    });
@@ -3624,6 +3654,11 @@ S2.define('select2/data/ajax',[
      var $request = options.transport(options, function (data) {
        var results = self.processResults(data, params);

        var items = results.results;
        for (var i = 0; i < items.length; i++) {
            items[i] = self._normalizeItem(items[i]);
        }

        if (self.options.get('debug') && window.console && console.error) {
          // Check to make sure that the response included a `results` key.
          if (!results || !results.results || !$.isArray(results.results)) {
@@ -5367,6 +5402,8 @@ S2.define('select2/core',[
      Utils.GetData($element[0], 'select2').destroy();
    }

    var self = this;

    this.$element = $element;

    this.id = this._generateId($element);
@@ -5375,6 +5412,10 @@ S2.define('select2/core',[

    this.options = new Options(options, $element);

    if (this.options.labels == null) {
      this.options.labels = this._findOriginalLabels();
    }

    Select2.__super__.constructor.call(this);

    // Set up the tabindex
@@ -5412,8 +5453,6 @@ S2.define('select2/core',[

    // Bind events

    var self = this;

    // Bind the container to all of the adapters
    this._bindAdapters();

@@ -5435,8 +5474,7 @@ S2.define('select2/core',[
    });

    // Hide the original select
    $element.addClass('select2-hidden-accessible');
    $element.attr('aria-hidden', 'true');
    $element.hide();

    // Synchronize any monitored attributes
    this._syncAttributes();
@@ -5449,6 +5487,23 @@ S2.define('select2/core',[

  Utils.Extend(Select2, Utils.Observable);

  Select2.prototype._findOriginalLabels = function() {
    var self = this;
    var id = this.$element.attr('id');

    if (id) {
      return jQuery.map($('label[for="' + id + '"]'), function(el, i) {
        if (!$(el).attr('id')) {
          $(el).attr('id', self.id + '-label-' + i);
        }
        return $(el).attr('id');
      });
    }
    else {
      return [];
    }
  }

  Select2.prototype._generateId = function ($element) {
    var id = '';

@@ -5710,10 +5765,10 @@ S2.define('select2/core',[
          evt.preventDefault();
        }
      } else {
        if (key === KEYS.ENTER || key === KEYS.SPACE ||
            (key === KEYS.DOWN && evt.altKey)) {
        if ((key === KEYS.ENTER || key === KEYS.SPACE ||
            (key === KEYS.DOWN && evt.altKey)) &&
            $(evt.target).hasClass('select2-selection')) {
          self.open();

          evt.preventDefault();
        }
      }