|
381 | 381 | if (options.attrs) { |
382 | 382 | $.extend(fieldAttrs, options.attrs); |
383 | 383 | } |
384 | | - labelPosition = options.labelPosition || (options.type === 'select' ? 'before' : 'after'); |
| 384 | + labelPosition = options.labelPosition || ((options.type === 'select' || options.type === 'number') ? 'before' : 'after'); |
385 | 385 | checkboxValue = (typeof options.value !== 'undefined') ? options.value : 'true'; |
386 | 386 |
|
387 | 387 | $wrapper = $('<div>').addClass(wrapperClass + 'able-player-setting'); |
|
395 | 395 |
|
396 | 396 | if (options.type === 'select') { |
397 | 397 | $field = $('<select>', fieldAttrs); |
| 398 | + } else if (options.type === 'number') { |
| 399 | + fieldAttrs.type = 'number'; |
| 400 | + if (typeof options.value !== 'undefined') { |
| 401 | + fieldAttrs.value = options.value; |
| 402 | + } |
| 403 | + $field = $('<input>', fieldAttrs); |
398 | 404 | } else { |
399 | 405 | fieldAttrs.type = options.type || 'checkbox'; |
400 | 406 | fieldAttrs.value = checkboxValue; |
|
545 | 551 | thisId = this.mediaId + '_' + thisPref; |
546 | 552 | $thisDiv = $('<div>').addClass(thisClass + ' able-player-setting'); |
547 | 553 | if (form === 'captions' ) { |
| 554 | + let isCaptionRateField = (thisPref === 'prefCaptionsRate'); |
548 | 555 | let fieldObj = this.createField({ |
549 | | - wrapperClass: thisClass + ' able-prefs-select', |
| 556 | + wrapperClass: thisClass + ' ' + (isCaptionRateField ? 'able-prefs-number' : 'able-prefs-select'), |
550 | 557 | name: thisPref, |
551 | 558 | id: thisId, |
552 | 559 | label: available[i]['label'], |
553 | | - type: 'select' |
| 560 | + type: isCaptionRateField ? 'number' : 'select', |
| 561 | + value: isCaptionRateField ? this[thisPref] : undefined, |
| 562 | + attrs: isCaptionRateField ? { |
| 563 | + min: 0.5, |
| 564 | + max: 3.0, |
| 565 | + step: 0.1 |
| 566 | + } : undefined |
554 | 567 | }); |
555 | 568 | $thisDiv = fieldObj.wrapper; |
556 | 569 | $thisLabel = fieldObj.label; |
|
563 | 576 | thisObj.stylizeCaptions(thisObj.$sampleCapsDiv,changedPref); |
564 | 577 | }); |
565 | 578 | } |
566 | | - captionsOptions = this.getCaptionsOptions(thisPref); |
567 | | - if ( ! ( thisPref === 'prefCaptionsVoice' && ! this.descVoices.length ) ) { |
568 | | - $thisDiv.append($thisLabel,$thisField); |
| 579 | + if (isCaptionRateField) { |
| 580 | + if (this.synth) { |
| 581 | + $thisField.on('change',function() { |
| 582 | + let captionSample = thisObj.translate( 'sampleCaptionText', 'Sample caption text' ); |
| 583 | + thisObj.announceText('captionSample',captionSample); |
| 584 | + }); |
| 585 | + } |
| 586 | + captionsOptions = []; |
| 587 | + } else { |
| 588 | + captionsOptions = this.getCaptionsOptions(thisPref); |
569 | 589 | } |
570 | 590 | for (j=0; j < captionsOptions.length; j++) { |
571 | 591 | if (thisPref === 'prefCaptionsPosition') { |
|
662 | 682 | $thisLabel = fieldObj.label; |
663 | 683 | $thisField = fieldObj.field; |
664 | 684 | } else if (this.synth) { |
| 685 | + let isDescRateField = (thisPref === 'prefDescRate'); |
665 | 686 | // Only show these options if browser supports speech synthesis |
666 | 687 | let fieldObj = this.createField({ |
667 | | - wrapperClass: thisClass + ' able-prefs-select', |
| 688 | + wrapperClass: thisClass + ' ' + (isDescRateField ? 'able-prefs-number' : 'able-prefs-select'), |
668 | 689 | name: thisPref, |
669 | 690 | id: thisId, |
670 | 691 | label: available[i]['label'], |
671 | | - type: 'select' |
| 692 | + type: isDescRateField ? 'number' : 'select', |
| 693 | + value: isDescRateField ? this[thisPref] : undefined, |
| 694 | + attrs: isDescRateField ? { |
| 695 | + min: 0.5, |
| 696 | + max: 3.0, |
| 697 | + step: 0.1 |
| 698 | + } : undefined |
672 | 699 | }); |
673 | 700 | $thisDiv = fieldObj.wrapper; |
674 | 701 | $thisLabel = fieldObj.label; |
675 | 702 | $thisField = fieldObj.field; |
676 | | - if ( thisPref === 'prefDescVoice' && this.descVoices.length) { |
| 703 | + if (isDescRateField) { |
| 704 | + // Number field has no options to populate. |
| 705 | + } else if ( thisPref === 'prefDescVoice' && this.descVoices.length) { |
677 | 706 | prefDescVoice = this.getPrefVoice(); |
678 | 707 | for (j=0; j < this.descVoices.length; j++) { |
679 | 708 | optionValue = this.descVoices[j].name; |
|
708 | 737 | // 2.5 - fleet |
709 | 738 | // 3 - fast! (some voices don't get any faster than this |
710 | 739 |
|
711 | | - // Note: if these values are modified, must also modfiy them |
712 | | - // in makePrefsValueReadable() |
713 | 740 | options = [0.7,0.8,0.9,1,1.1,1.2,1.5,2,2.5,3]; |
714 | 741 | } else if (thisPref == 'prefDescVolume') { // 0 (mute) to 1 |
715 | 742 | options = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]; |
|
776 | 803 | }); |
777 | 804 | } |
778 | 805 | } |
779 | | - if (thisPref === 'prefDescVoice' && !this.descVoices.length) { |
| 806 | + if ((thisPref === 'prefDescVoice' || thisPref === 'prefCaptionsVoice') && !this.descVoices.length) { |
780 | 807 | // No voices are available (e.g., in Safari 15.4 on Mac OS) |
781 | 808 | } else { |
782 | 809 | $fieldset.append($thisDiv); |
|
1023 | 1050 | } else if (value === 2) { |
1024 | 1051 | return this.translate( 'prefDescPitch5', 'Very high' ); |
1025 | 1052 | } |
1026 | | - } else if (pref === 'prefDescRate' || pref === 'prefCaptionsRate' ) { |
1027 | | - // default in the API is 0.1 to 10, where 1 is normal speaking voice |
1028 | | - // our custom range offers several rates close to 1 |
1029 | | - // plus a couple of crazy fast ones for sport |
1030 | | - // Our more readable options (1-10) or mapped here to API values |
1031 | | - if (value === 0.7) { |
1032 | | - return 1; |
1033 | | - } else if (value === 0.8) { |
1034 | | - return 2; |
1035 | | - } else if (value === 0.9) { |
1036 | | - return 3; |
1037 | | - } else if (value === 1) { |
1038 | | - return 4; |
1039 | | - } else if (value === 1.1) { |
1040 | | - return 5; |
1041 | | - } else if (value === 1.2) { |
1042 | | - return 6; |
1043 | | - } else if (value === 1.5) { |
1044 | | - return 7; |
1045 | | - } else if (value === 2) { |
1046 | | - return 8; |
1047 | | - } else if (value === 2.5) { |
1048 | | - return 9; |
1049 | | - } else if (value === 3) { |
1050 | | - return 10; |
1051 | | - } |
1052 | 1053 | } else if (pref === 'prefDescVolume' || pref === 'prefCaptionsVolume' ) { |
1053 | 1054 | // values range from 0.1 to 1.0 |
1054 | 1055 | return value * 100 + '%'; |
|
1070 | 1071 | available = this.getAvailablePreferences(); |
1071 | 1072 | for (i=0; i<available.length; i++) { |
1072 | 1073 | prefName = available[i]['name']; |
1073 | | - if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) { |
| 1074 | + if (prefName === 'prefCaptionsRate' || prefName === 'prefDescRate') { |
| 1075 | + $('input[name="' + prefName + '"]').val(preferences.preferences[prefName]); |
| 1076 | + } else if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) { |
1074 | 1077 | // this is a caption-related select box |
1075 | 1078 | $('select[name="' + prefName + '"]').val(preferences.preferences[prefName]); |
1076 | 1079 | } else { // all others are checkboxes |
|
1133 | 1136 | preferences.preferences['prefDescMethod'] = this.prefDescMethod; |
1134 | 1137 | numChanges++; |
1135 | 1138 | } |
| 1139 | + } else if (prefName === 'prefCaptionsRate' || prefName === 'prefDescRate') { |
| 1140 | + newValue = parseFloat($('input[id="' + prefId + '"]').val()); |
| 1141 | + if (isNaN(newValue)) { |
| 1142 | + newValue = this[prefName] || 1; |
| 1143 | + } |
| 1144 | + newValue = Math.min(3.0, Math.max(0.5, newValue)); |
| 1145 | + if (preferences.preferences[prefName] !== newValue) { |
| 1146 | + preferences.preferences[prefName] = newValue; |
| 1147 | + this[prefName] = newValue; |
| 1148 | + numChanges++; |
| 1149 | + } |
1136 | 1150 | } else if ((prefName.indexOf('Captions') !== -1) && (prefName !== 'prefCaptions')) { |
1137 | 1151 | // this is one of the caption-related select fields |
1138 | 1152 | newValue = $('select[id="' + prefId + '"]').val(); |
|
0 commit comments