1/** 2 * @file 3 * JavaScript behaviors for webform_image_select and jQuery Image Picker integration. 4 */ 5 6(function ($, Drupal, once) { 7 8 'use strict'; 9 10 // @see https://rvera.github.io/image-picker/ 11 Drupal.webform = Drupal.webform || {}; 12 Drupal.webform.imageSelect = Drupal.webform.imageSelect || {}; 13 Drupal.webform.imageSelect.options = Drupal.webform.imageSelect.options || {}; 14 15 /** 16 * Initialize image select. 17 * 18 * @type {Drupal~behavior} 19 */ 20 Drupal.behaviors.webformImageSelect = { 21 attach: function (context) { 22 if (!$.fn.imagepicker) { 23 return; 24 } 25 26 $(once('webform-image-select', '.js-webform-image-select', context)).each(function () { 27 var $select = $(this); 28 var isMultiple = $select.attr('multiple'); 29 30 // Apply image data to options. 31 var images = JSON.parse($select.attr('data-images')); 32 for (var value in images) { 33 if (images.hasOwnProperty(value)) { 34 var image = images[value]; 35 // Escape double quotes in value 36 value = value.toString().replace(/"/g, '\\"'); 37 $select.find('option[value="' + value + '"]').attr({ 38 'data-img-src': image.src, 39 'data-img-label': image.text, 40 'data-img-alt': image.text 41 }); 42 } 43 } 44 45 var options = $.extend({ 46 hide_select: false 47 }, Drupal.webform.imageSelect.options); 48 49 if ($select.attr('data-show-label')) { 50 options.show_label = true; 51 } 52 53 $select.imagepicker(options); 54 55 // Add very basic accessibility to the image picker by 56 // enabling tabbing and toggling via the spacebar. 57 // @see https://github.com/rvera/image-picker/issues/108 58 59 // Block select menu from being tabbed. 60 $select.attr('tabindex', '-1'); 61 62 if (isMultiple) { 63 $select.next('.image_picker_selector').attr('role', 'radiogroup'); 64 } 65 66 var $thumbnail = $select.next('.image_picker_selector').find('.thumbnail'); 67 $thumbnail 68 // Allow thumbnail to be tabbed. 69 .prop('tabindex', '0') 70 .attr('role', isMultiple ? 'checkbox' : 'radio') 71 .each(function () { 72 var alt = $(this).find('img').attr('alt'); 73 // Cleanup alt, set title, and fix aria. 74 if (alt) { 75 alt = alt.replace(/<\/?[^>]+(>|$)/g, ''); 76 $(this).find('img').attr('alt', alt); 77 $(this).attr('title', alt); 78 } 79 80 // Aria hide caption since the 'title' attribute will be read aloud. 81 $(this).find('p').attr('aria-hidden', true); 82 }) 83 .on('focus', function (event) { 84 $(this).addClass('focused'); 85 }) 86 .on('blur', function (event) { 87 $(this).removeClass('focused'); 88 }) 89 .on('keydown', function (event) { 90 if (event.which === 32) { 91 // Space. 92 $(this).trigger('click'); 93 event.preventDefault(); 94 } 95 else if (event.which === 37 || event.which === 38) { 96 // Left or Up. 97 var $prev = $(this).parent(); 98 do { 99 $prev = $prev.prev(); 100 } 101 while ($prev.length && $prev.is(':hidden')); 102 $prev.find('.thumbnail').trigger('focus'); 103 event.preventDefault(); 104 } 105 else if (event.which === 39 || event.which === 40) { 106 // Right or Down. 107 var $next = $(this).parent(); 108 do { 109 $next = $next.next(); 110 } 111 while ($next.length && $next.is(':hidden')); 112 $next.find('.thumbnail').trigger('focus'); 113 event.preventDefault(); 114 } 115 }) 116 .on('click', function (event) { 117 var selected = $(this).hasClass('selected'); 118 $(this).attr('aria-checked', selected); 119 }); 120 }); 121 } 122 }; 123 124})(jQuery, Drupal, once);
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.