mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Change-Id: I066c0e7f8ce87ec00b1141a1b44430444a819b42 (cherry picked from commit 05907a1a42da82737090d55046974d401f8af057)
		
			
				
	
	
		
			283 lines
		
	
	
		
			No EOL
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			283 lines
		
	
	
		
			No EOL
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import classesToSelector from '../../shared/classes-to-selector.js';
 | 
						|
import $ from '../../shared/dom.js';
 | 
						|
export default function A11y({
 | 
						|
  swiper,
 | 
						|
  extendParams,
 | 
						|
  on
 | 
						|
}) {
 | 
						|
  extendParams({
 | 
						|
    a11y: {
 | 
						|
      enabled: true,
 | 
						|
      notificationClass: 'swiper-notification',
 | 
						|
      prevSlideMessage: 'Previous slide',
 | 
						|
      nextSlideMessage: 'Next slide',
 | 
						|
      firstSlideMessage: 'This is the first slide',
 | 
						|
      lastSlideMessage: 'This is the last slide',
 | 
						|
      paginationBulletMessage: 'Go to slide {{index}}',
 | 
						|
      slideLabelMessage: '{{index}} / {{slidesLength}}',
 | 
						|
      containerMessage: null,
 | 
						|
      containerRoleDescriptionMessage: null,
 | 
						|
      itemRoleDescriptionMessage: null,
 | 
						|
      slideRole: 'group'
 | 
						|
    }
 | 
						|
  });
 | 
						|
  let liveRegion = null;
 | 
						|
 | 
						|
  function notify(message) {
 | 
						|
    const notification = liveRegion;
 | 
						|
    if (notification.length === 0) return;
 | 
						|
    notification.html('');
 | 
						|
    notification.html(message);
 | 
						|
  }
 | 
						|
 | 
						|
  function getRandomNumber(size = 16) {
 | 
						|
    const randomChar = () => Math.round(16 * Math.random()).toString(16);
 | 
						|
 | 
						|
    return 'x'.repeat(size).replace(/x/g, randomChar);
 | 
						|
  }
 | 
						|
 | 
						|
  function makeElFocusable($el) {
 | 
						|
    $el.attr('tabIndex', '0');
 | 
						|
  }
 | 
						|
 | 
						|
  function makeElNotFocusable($el) {
 | 
						|
    $el.attr('tabIndex', '-1');
 | 
						|
  }
 | 
						|
 | 
						|
  function addElRole($el, role) {
 | 
						|
    $el.attr('role', role);
 | 
						|
  }
 | 
						|
 | 
						|
  function addElRoleDescription($el, description) {
 | 
						|
    $el.attr('aria-roledescription', description);
 | 
						|
  }
 | 
						|
 | 
						|
  function addElControls($el, controls) {
 | 
						|
    $el.attr('aria-controls', controls);
 | 
						|
  }
 | 
						|
 | 
						|
  function addElLabel($el, label) {
 | 
						|
    $el.attr('aria-label', label);
 | 
						|
  }
 | 
						|
 | 
						|
  function addElId($el, id) {
 | 
						|
    $el.attr('id', id);
 | 
						|
  }
 | 
						|
 | 
						|
  function addElLive($el, live) {
 | 
						|
    $el.attr('aria-live', live);
 | 
						|
  }
 | 
						|
 | 
						|
  function disableEl($el) {
 | 
						|
    $el.attr('aria-disabled', true);
 | 
						|
  }
 | 
						|
 | 
						|
  function enableEl($el) {
 | 
						|
    $el.attr('aria-disabled', false);
 | 
						|
  }
 | 
						|
 | 
						|
  function onEnterOrSpaceKey(e) {
 | 
						|
    if (e.keyCode !== 13 && e.keyCode !== 32) return;
 | 
						|
    const params = swiper.params.a11y;
 | 
						|
    const $targetEl = $(e.target);
 | 
						|
 | 
						|
    if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) {
 | 
						|
      if (!(swiper.isEnd && !swiper.params.loop)) {
 | 
						|
        swiper.slideNext();
 | 
						|
      }
 | 
						|
 | 
						|
      if (swiper.isEnd) {
 | 
						|
        notify(params.lastSlideMessage);
 | 
						|
      } else {
 | 
						|
        notify(params.nextSlideMessage);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) {
 | 
						|
      if (!(swiper.isBeginning && !swiper.params.loop)) {
 | 
						|
        swiper.slidePrev();
 | 
						|
      }
 | 
						|
 | 
						|
      if (swiper.isBeginning) {
 | 
						|
        notify(params.firstSlideMessage);
 | 
						|
      } else {
 | 
						|
        notify(params.prevSlideMessage);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (swiper.pagination && $targetEl.is(classesToSelector(swiper.params.pagination.bulletClass))) {
 | 
						|
      $targetEl[0].click();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function updateNavigation() {
 | 
						|
    if (swiper.params.loop || !swiper.navigation) return;
 | 
						|
    const {
 | 
						|
      $nextEl,
 | 
						|
      $prevEl
 | 
						|
    } = swiper.navigation;
 | 
						|
 | 
						|
    if ($prevEl && $prevEl.length > 0) {
 | 
						|
      if (swiper.isBeginning) {
 | 
						|
        disableEl($prevEl);
 | 
						|
        makeElNotFocusable($prevEl);
 | 
						|
      } else {
 | 
						|
        enableEl($prevEl);
 | 
						|
        makeElFocusable($prevEl);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if ($nextEl && $nextEl.length > 0) {
 | 
						|
      if (swiper.isEnd) {
 | 
						|
        disableEl($nextEl);
 | 
						|
        makeElNotFocusable($nextEl);
 | 
						|
      } else {
 | 
						|
        enableEl($nextEl);
 | 
						|
        makeElFocusable($nextEl);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function hasPagination() {
 | 
						|
    return swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length;
 | 
						|
  }
 | 
						|
 | 
						|
  function updatePagination() {
 | 
						|
    const params = swiper.params.a11y;
 | 
						|
 | 
						|
    if (hasPagination()) {
 | 
						|
      swiper.pagination.bullets.each(bulletEl => {
 | 
						|
        const $bulletEl = $(bulletEl);
 | 
						|
        makeElFocusable($bulletEl);
 | 
						|
 | 
						|
        if (!swiper.params.pagination.renderBullet) {
 | 
						|
          addElRole($bulletEl, 'button');
 | 
						|
          addElLabel($bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, $bulletEl.index() + 1));
 | 
						|
        }
 | 
						|
      });
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const initNavEl = ($el, wrapperId, message) => {
 | 
						|
    makeElFocusable($el);
 | 
						|
 | 
						|
    if ($el[0].tagName !== 'BUTTON') {
 | 
						|
      addElRole($el, 'button');
 | 
						|
      $el.on('keydown', onEnterOrSpaceKey);
 | 
						|
    }
 | 
						|
 | 
						|
    addElLabel($el, message);
 | 
						|
    addElControls($el, wrapperId);
 | 
						|
  };
 | 
						|
 | 
						|
  function init() {
 | 
						|
    const params = swiper.params.a11y;
 | 
						|
    swiper.$el.append(liveRegion); // Container
 | 
						|
 | 
						|
    const $containerEl = swiper.$el;
 | 
						|
 | 
						|
    if (params.containerRoleDescriptionMessage) {
 | 
						|
      addElRoleDescription($containerEl, params.containerRoleDescriptionMessage);
 | 
						|
    }
 | 
						|
 | 
						|
    if (params.containerMessage) {
 | 
						|
      addElLabel($containerEl, params.containerMessage);
 | 
						|
    } // Wrapper
 | 
						|
 | 
						|
 | 
						|
    const $wrapperEl = swiper.$wrapperEl;
 | 
						|
    const wrapperId = $wrapperEl.attr('id') || `swiper-wrapper-${getRandomNumber(16)}`;
 | 
						|
    const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
 | 
						|
    addElId($wrapperEl, wrapperId);
 | 
						|
    addElLive($wrapperEl, live); // Slide
 | 
						|
 | 
						|
    if (params.itemRoleDescriptionMessage) {
 | 
						|
      addElRoleDescription($(swiper.slides), params.itemRoleDescriptionMessage);
 | 
						|
    }
 | 
						|
 | 
						|
    addElRole($(swiper.slides), params.slideRole);
 | 
						|
    const slidesLength = swiper.params.loop ? swiper.slides.filter(el => !el.classList.contains(swiper.params.slideDuplicateClass)).length : swiper.slides.length;
 | 
						|
    swiper.slides.each((slideEl, index) => {
 | 
						|
      const $slideEl = $(slideEl);
 | 
						|
      const slideIndex = swiper.params.loop ? parseInt($slideEl.attr('data-swiper-slide-index'), 10) : index;
 | 
						|
      const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength);
 | 
						|
      addElLabel($slideEl, ariaLabelMessage);
 | 
						|
    }); // Navigation
 | 
						|
 | 
						|
    let $nextEl;
 | 
						|
    let $prevEl;
 | 
						|
 | 
						|
    if (swiper.navigation && swiper.navigation.$nextEl) {
 | 
						|
      $nextEl = swiper.navigation.$nextEl;
 | 
						|
    }
 | 
						|
 | 
						|
    if (swiper.navigation && swiper.navigation.$prevEl) {
 | 
						|
      $prevEl = swiper.navigation.$prevEl;
 | 
						|
    }
 | 
						|
 | 
						|
    if ($nextEl && $nextEl.length) {
 | 
						|
      initNavEl($nextEl, wrapperId, params.nextSlideMessage);
 | 
						|
    }
 | 
						|
 | 
						|
    if ($prevEl && $prevEl.length) {
 | 
						|
      initNavEl($prevEl, wrapperId, params.prevSlideMessage);
 | 
						|
    } // Pagination
 | 
						|
 | 
						|
 | 
						|
    if (hasPagination()) {
 | 
						|
      swiper.pagination.$el.on('keydown', classesToSelector(swiper.params.pagination.bulletClass), onEnterOrSpaceKey);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function destroy() {
 | 
						|
    if (liveRegion && liveRegion.length > 0) liveRegion.remove();
 | 
						|
    let $nextEl;
 | 
						|
    let $prevEl;
 | 
						|
 | 
						|
    if (swiper.navigation && swiper.navigation.$nextEl) {
 | 
						|
      $nextEl = swiper.navigation.$nextEl;
 | 
						|
    }
 | 
						|
 | 
						|
    if (swiper.navigation && swiper.navigation.$prevEl) {
 | 
						|
      $prevEl = swiper.navigation.$prevEl;
 | 
						|
    }
 | 
						|
 | 
						|
    if ($nextEl) {
 | 
						|
      $nextEl.off('keydown', onEnterOrSpaceKey);
 | 
						|
    }
 | 
						|
 | 
						|
    if ($prevEl) {
 | 
						|
      $prevEl.off('keydown', onEnterOrSpaceKey);
 | 
						|
    } // Pagination
 | 
						|
 | 
						|
 | 
						|
    if (hasPagination()) {
 | 
						|
      swiper.pagination.$el.off('keydown', classesToSelector(swiper.params.pagination.bulletClass), onEnterOrSpaceKey);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  on('beforeInit', () => {
 | 
						|
    liveRegion = $(`<span class="${swiper.params.a11y.notificationClass}" aria-live="assertive" aria-atomic="true"></span>`);
 | 
						|
  });
 | 
						|
  on('afterInit', () => {
 | 
						|
    if (!swiper.params.a11y.enabled) return;
 | 
						|
    init();
 | 
						|
    updateNavigation();
 | 
						|
  });
 | 
						|
  on('toEdge', () => {
 | 
						|
    if (!swiper.params.a11y.enabled) return;
 | 
						|
    updateNavigation();
 | 
						|
  });
 | 
						|
  on('fromEdge', () => {
 | 
						|
    if (!swiper.params.a11y.enabled) return;
 | 
						|
    updateNavigation();
 | 
						|
  });
 | 
						|
  on('paginationUpdate', () => {
 | 
						|
    if (!swiper.params.a11y.enabled) return;
 | 
						|
    updatePagination();
 | 
						|
  });
 | 
						|
  on('destroy', () => {
 | 
						|
    if (!swiper.params.a11y.enabled) return;
 | 
						|
    destroy();
 | 
						|
  });
 | 
						|
} |