shaka-player
Version:
DASH/EME video player library
709 lines (657 loc) • 25.3 kB
JavaScript
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.provide('shakaDemo.Config');
goog.require('goog.asserts');
goog.require('shakaDemo.BoolInput');
goog.require('shakaDemo.DatalistInput');
goog.require('shakaDemo.InputContainer');
goog.require('shakaDemo.MessageIds');
goog.require('shakaDemo.NumberInput');
goog.require('shakaDemo.SelectInput');
goog.require('shakaDemo.TextInput');
goog.requireType('shakaDemo.Input');
/** @type {?shakaDemo.Config} */
let shakaDemoConfig;
/**
* Shaka Player demo, configuration page layout.
*/
shakaDemo.Config = class {
/**
* Register the page configuration.
*/
static init() {
const container = shakaDemoMain.getHamburgerMenu();
shakaDemoConfig = new shakaDemo.Config(container);
}
/** @param {!Element} container */
constructor(container) {
/** @private {!Element} */
this.container_ = container;
/**
* A list of all sections.
* @private {!Array.<!shakaDemo.InputContainer>}
*/
this.sections_ = [];
/**
* The input object for the control currently being constructed.
* @private {?shakaDemo.Input}
*/
this.latestInput_ = null;
this.reload_();
// Listen to external config changes (i.e. from hash changes).
document.addEventListener('shaka-main-config-change', () => {
// Respond to them by remaking. This is to avoid triggering any config
// changes based on the config changes.
this.reloadAndSaveState_();
});
document.addEventListener('shaka-main-locale-changed', () => {
// Respond to them by remaking. This is to avoid triggering any config
// changes based on the config changes.
this.reloadAndSaveState_();
});
document.addEventListener('shaka-main-drawer-state-change', () => {
this.setContentAvailability_(shakaDemoMain.getIsDrawerOpen());
});
this.setContentAvailability_(shakaDemoMain.getIsDrawerOpen());
}
/**
* @param {boolean} availability
* @private
*/
setContentAvailability_(availability) {
if (availability) {
this.container_.classList.remove('hidden');
} else {
this.container_.classList.add('hidden');
}
}
/** @private */
reload_() {
shaka.util.Dom.removeAllChildren(this.container_);
this.sections_ = [];
this.addMetaSection_();
this.addLanguageSection_();
this.addAbrSection_();
this.addOfflineSection_();
this.addDrmSection_();
this.addStreamingSection_();
this.addManifestSection_();
this.addRetrictionsSection_('',
shakaDemo.MessageIds.RESTRICTIONS_SECTION_HEADER);
}
/**
* Remake the contents of the div. Unlike |reload_|, this will also remember
* which sections were open.
* @private
*/
reloadAndSaveState_() {
const wasOpenArray = this.sections_.map((section) => section.getIsOpen());
this.reload_();
for (let i = 0; i < wasOpenArray.length; i++) {
const wasOpen = wasOpenArray[i];
const section = this.sections_[i];
if (wasOpen) {
section.open();
}
}
// Update the componentHandler, to account for any new MDL elements added.
componentHandler.upgradeDom();
}
/** @private */
addDrmSection_() {
const MessageIds = shakaDemo.MessageIds;
const docLink = this.resolveExternLink_('.DrmConfiguration');
this.addSection_(MessageIds.DRM_SECTION_HEADER, docLink)
.addBoolInput_(MessageIds.DELAY_LICENSE,
'drm.delayLicenseRequestUntilPlayed')
.addBoolInput_(MessageIds.LOG_LICENSE_EXCHANGE,
'drm.logLicenseExchange')
.addNumberInput_(MessageIds.UPDATE_EXPIRATION_TIME,
'drm.updateExpirationTime',
/* canBeDecimal= */ true,
/* canBeZero= */ false,
/* canBeUnset= */ true);
const advanced = shakaDemoMain.getConfiguration().drm.advanced || {};
const addDRMAdvancedField = (name, valueName, suggestions) => {
// All advanced fields of a given type are set at once.
this.addDatalistInput_(name, suggestions, (input) => {
// Add in any common drmSystem not currently in advanced.
for (const drmSystem of shakaDemo.Main.commonDrmSystems) {
if (!(drmSystem in advanced)) {
advanced[drmSystem] = shakaDemo.Main.defaultAdvancedDrmConfig();
}
}
// Set the robustness.
for (const drmSystem in advanced) {
advanced[drmSystem][valueName] = input.value;
}
shakaDemoMain.configure('drm.advanced', advanced);
shakaDemoMain.remakeHash();
});
const keySystem = Object.keys(advanced)[0];
if (keySystem) {
const currentValue = advanced[keySystem][valueName];
this.latestInput_.input().value = currentValue;
}
};
const robustnessSuggestions = [
'SW_SECURE_CRYPTO',
'SW_SECURE_DECODE',
'HW_SECURE_CRYPTO',
'HW_SECURE_DECODE',
'HW_SECURE_ALL',
'150',
'2000',
'3000',
];
const sessionTypeSuggestions = ['temporary', 'persistent-license'];
addDRMAdvancedField(
MessageIds.VIDEO_ROBUSTNESS,
'videoRobustness',
robustnessSuggestions);
addDRMAdvancedField(
MessageIds.AUDIO_ROBUSTNESS,
'audioRobustness',
robustnessSuggestions);
addDRMAdvancedField(
MessageIds.DRM_SESSION_TYPE,
'sessionType',
sessionTypeSuggestions);
this.addRetrySection_('drm', MessageIds.DRM_RETRY_SECTION_HEADER);
}
/** @private */
addManifestSection_() {
const MessageIds = shakaDemo.MessageIds;
const docLink = this.resolveExternLink_('.ManifestConfiguration');
this.addSection_(MessageIds.MANIFEST_SECTION_HEADER, docLink)
.addBoolInput_(MessageIds.IGNORE_DASH_DRM,
'manifest.dash.ignoreDrmInfo')
.addBoolInput_(MessageIds.AUTO_CORRECT_DASH_DRIFT,
'manifest.dash.autoCorrectDrift')
.addBoolInput_(MessageIds.DISABLE_XLINK_PROCESSING,
'manifest.dash.disableXlinkProcessing')
.addBoolInput_(MessageIds.XLINK_FAIL_GRACEFULLY,
'manifest.dash.xlinkFailGracefully')
.addBoolInput_(MessageIds.IGNORE_DASH_SUGGESTED_PRESENTATION_DELAY,
'manifest.dash.ignoreSuggestedPresentationDelay')
.addBoolInput_(MessageIds.IGNORE_DASH_EMPTY_ADAPTATION_SET,
'manifest.dash.ignoreEmptyAdaptationSet')
.addBoolInput_(MessageIds.IGNORE_DASH_MAX_SEGMENT_DURATION,
'manifest.dash.ignoreMaxSegmentDuration')
.addBoolInput_(MessageIds.IGNORE_HLS_TEXT_FAILURES,
'manifest.hls.ignoreTextStreamFailures')
.addBoolInput_(MessageIds.IGNORE_HLS_IMAGE_FAILURES,
'manifest.hls.ignoreImageStreamFailures')
.addBoolInput_(MessageIds.USE_FULL_SEGMENTS_FOR_START_TIME,
'manifest.hls.useFullSegmentsForStartTime')
.addNumberInput_(MessageIds.AVAILABILITY_WINDOW_OVERRIDE,
'manifest.availabilityWindowOverride',
/* canBeDecimal= */ true,
/* canBeZero= */ false,
/* canBeUnset= */ true)
.addTextInput_(MessageIds.CLOCK_SYNC_URI, 'manifest.dash.clockSyncUri')
.addNumberInput_(MessageIds.DEFAULT_PRESENTATION_DELAY,
'manifest.defaultPresentationDelay')
.addBoolInput_(MessageIds.IGNORE_MIN_BUFFER_TIME,
'manifest.dash.ignoreMinBufferTime')
.addNumberInput_(MessageIds.INITIAL_SEGMENT_LIMIT,
'manifest.dash.initialSegmentLimit',
/* canBeDecimal= */ false,
/* canBeZero= */ false,
/* canBeUnset= */ true)
.addBoolInput_(MessageIds.DISABLE_AUDIO,
'manifest.disableAudio')
.addBoolInput_(MessageIds.DISABLE_VIDEO,
'manifest.disableVideo')
.addBoolInput_(MessageIds.DISABLE_TEXT,
'manifest.disableText')
.addBoolInput_(MessageIds.DISABLE_THUMBNAILS,
'manifest.disableThumbnails');
this.addRetrySection_('manifest', MessageIds.MANIFEST_RETRY_SECTION_HEADER);
}
/** @private */
addAbrSection_() {
const MessageIds = shakaDemo.MessageIds;
const docLink = this.resolveExternLink_('.AbrConfiguration');
this.addSection_(MessageIds.ADAPTATION_SECTION_HEADER, docLink)
.addBoolInput_(MessageIds.ENABLED, 'abr.enabled')
.addBoolInput_(MessageIds.NETWORK_INFORMATION,
'abr.useNetworkInformation')
.addNumberInput_(MessageIds.BANDWIDTH_ESTIMATE,
'abr.defaultBandwidthEstimate')
.addNumberInput_(MessageIds.BANDWIDTH_DOWNGRADE,
'abr.bandwidthDowngradeTarget',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.BANDWIDTH_UPGRADE,
'abr.bandwidthUpgradeTarget',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.SWITCH_INTERVAL,
'abr.switchInterval',
/* canBeDecimal= */ true);
this.addRetrictionsSection_('abr',
MessageIds.ADAPTATION_RESTRICTIONS_SECTION_HEADER);
}
/**
* @param {string} category
* @param {!shakaDemo.MessageIds} sectionName
* @private
*/
addRetrictionsSection_(category, sectionName) {
const MessageIds = shakaDemo.MessageIds;
const prefix = (category ? category + '.' : '') + 'restrictions.';
const docLink = this.resolveExternLink_('.Restrictions');
this.addSection_(sectionName, docLink)
.addNumberInput_(MessageIds.MIN_WIDTH, prefix + 'minWidth')
.addNumberInput_(MessageIds.MAX_WIDTH, prefix + 'maxWidth')
.addNumberInput_(MessageIds.MIN_HEIGHT, prefix + 'minHeight')
.addNumberInput_(MessageIds.MAX_HEIGHT, prefix + 'maxHeight')
.addNumberInput_(MessageIds.MIN_PIXELS, prefix + 'minPixels')
.addNumberInput_(MessageIds.MAX_PIXELS, prefix + 'maxPixels')
.addNumberInput_(MessageIds.MIN_FRAMERATE, prefix + 'minFrameRate')
.addNumberInput_(MessageIds.MAX_FRAMERATE, prefix + 'maxFrameRate')
.addNumberInput_(MessageIds.MIN_BANDWIDTH, prefix + 'minBandwidth')
.addNumberInput_(MessageIds.MAX_BANDWIDTH, prefix + 'maxBandwidth');
}
/**
* @param {string} category
* @param {!shakaDemo.MessageIds} sectionName
* @private
*/
addRetrySection_(category, sectionName) {
const MessageIds = shakaDemo.MessageIds;
const prefix = category + '.retryParameters.';
const docLink = this.resolveExternLink_('.RetryParameters');
this.addSection_(sectionName, docLink)
.addNumberInput_(MessageIds.MAX_ATTEMPTS, prefix + 'maxAttempts')
.addNumberInput_(MessageIds.BASE_DELAY, prefix + 'baseDelay',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.BACKOFF_FACTOR, prefix + 'backoffFactor',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.FUZZ_FACTOR, prefix + 'fuzzFactor',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.TIMEOUT, prefix + 'timeout',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.STALL_TIMEOUT, prefix + 'stallTimeout',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.CONNECTION_TIMEOUT,
prefix + 'connectionTimeout',
/* canBeDecimal= */ true);
}
/** @private */
addOfflineSection_() {
const MessageIds = shakaDemo.MessageIds;
const docLink = this.resolveExternLink_('.OfflineConfiguration');
this.addSection_(MessageIds.OFFLINE_SECTION_HEADER, docLink)
.addBoolInput_(MessageIds.USE_PERSISTENT_LICENSES,
'offline.usePersistentLicense');
}
/** @private */
addStreamingSection_() {
const MessageIds = shakaDemo.MessageIds;
const docLink = this.resolveExternLink_('.StreamingConfiguration');
this.addSection_(MessageIds.STREAMING_SECTION_HEADER, docLink)
.addNumberInput_(MessageIds.GAP_DETECTION_THRESHOLD,
'streaming.gapDetectionThreshold',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.MAX_SMALL_GAP_SIZE,
'streaming.smallGapLimit',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.BUFFERING_GOAL,
'streaming.bufferingGoal',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.DURATION_BACKOFF,
'streaming.durationBackoff',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.REBUFFERING_GOAL,
'streaming.rebufferingGoal',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.BUFFER_BEHIND,
'streaming.bufferBehind',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.SAFE_SEEK_OFFSET,
'streaming.safeSeekOffset',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.STALL_THRESHOLD,
'streaming.stallThreshold',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.SAFE_SKIP_DISTANCE,
'streaming.stallSkip',
/* canBeDecimal= */ true)
.addNumberInput_(MessageIds.INACCURATE_MANIFEST_TOLERANCE,
'streaming.inaccurateManifestTolerance',
/* canBeDecimal= */ true)
.addBoolInput_(MessageIds.LOW_LATENCY,
'streaming.lowLatencyMode')
.addBoolInput_(MessageIds.AUTO_LOW_LATENCY,
'streaming.autoLowLatencyMode')
.addBoolInput_(MessageIds.FORCE_HTTPS,
'streaming.forceHTTPS')
.addBoolInput_(MessageIds.PREFER_NATIVE_HLS,
'streaming.preferNativeHls')
.addNumberInput_(MessageIds.UPDATE_INTERVAL_SECONDS,
'streaming.updateIntervalSeconds',
/* canBeDecimal= */ true);
if (!shakaDemoMain.getNativeControlsEnabled()) {
this.addBoolInput_(MessageIds.ALWAYS_STREAM_TEXT,
'streaming.alwaysStreamText');
} else {
// Add a fake custom fixed "input" that warns the users not to change it.
const noop = (input) => {};
this.addCustomBoolInput_(MessageIds.ALWAYS_STREAM_TEXT,
noop, MessageIds.ALWAYS_STREAM_TEXT_WARNING);
this.latestInput_.input().disabled = true;
this.latestInput_.input().checked = true;
}
this.addBoolInput_(MessageIds.JUMP_LARGE_GAPS,
'streaming.jumpLargeGaps')
.addBoolInput_(MessageIds.FORCE_TRANSMUX_TS,
'streaming.forceTransmuxTS')
.addBoolInput_(MessageIds.START_AT_SEGMENT_BOUNDARY,
'streaming.startAtSegmentBoundary')
.addBoolInput_(MessageIds.IGNORE_TEXT_FAILURES,
'streaming.ignoreTextStreamFailures')
.addBoolInput_(MessageIds.STALL_DETECTOR_ENABLED,
'streaming.stallEnabled')
.addBoolInput_(MessageIds.USE_NATIVE_HLS_SAFARI,
'streaming.useNativeHlsOnSafari');
this.addRetrySection_('streaming',
MessageIds.STREAMING_RETRY_SECTION_HEADER);
}
/** @private */
addLanguageSection_() {
const MessageIds = shakaDemo.MessageIds;
const docLink = this.resolveExternLink_('.PlayerConfiguration');
this.addSection_(MessageIds.LANGUAGE_SECTION_HEADER, docLink)
.addTextInput_(MessageIds.AUDIO_LANGUAGE, 'preferredAudioLanguage')
.addTextInput_(MessageIds.TEXT_LANGUAGE, 'preferredTextLanguage')
.addTextInput_(MessageIds.TEXT_ROLE, 'preferredTextRole');
const onChange = (input) => {
shakaDemoMain.setUILocale(input.value);
shakaDemoMain.remakeHash();
};
this.addCustomTextInput_(MessageIds.UI_LOCALE, onChange);
this.latestInput_.input().value = shakaDemoMain.getUILocale();
this.addNumberInput_(MessageIds.AUDIO_CHANNEL_COUNT,
'preferredAudioChannelCount');
this.addBoolInput_(MessageIds.PREFER_FORCED_SUBS,
'preferForcedSubs');
}
/** @private */
addMetaSection_() {
const MessageIds = shakaDemo.MessageIds;
this.addSection_(/* name= */ null, /* docLink= */ null);
this.addCustomBoolInput_(MessageIds.SHAKA_CONTROLS, (input) => {
shakaDemoMain.setNativeControlsEnabled(!input.checked);
if (input.checked) {
// Forcibly set |streaming.alwaysStreamText| to true.
shakaDemoMain.configure('streaming.alwaysStreamText', true);
shakaDemoMain.remakeHash();
}
// Enabling/disabling Shaka Controls will change how other controls in
// the config work, so reload the page.
this.reloadAndSaveState_();
});
// TODO: Re-add the tooltipMessage of 'Takes effect next load.' once we
// are ready to add ALL of the tooltip messages.
if (!shakaDemoMain.getNativeControlsEnabled()) {
this.latestInput_.input().checked = true;
}
if (!shakaDemoMain.getNativeControlsEnabled()) {
this.addCustomBoolInput_(MessageIds.TRICK_PLAY_CONTROLS, (input) => {
shakaDemoMain.setTrickPlayControlsEnabled(input.checked);
});
if (shakaDemoMain.getTrickPlayControlsEnabled()) {
this.latestInput_.input().checked = true;
}
} else {
// Add a fake custom fixed "input" that warns the users not to change it.
const noop = (input) => {};
this.addCustomBoolInput_(MessageIds.TRICK_PLAY_CONTROLS,
noop, MessageIds.TRICK_PLAY_CONTROLS_WARNING);
this.latestInput_.input().disabled = true;
this.latestInput_.input().checked = false;
}
// shaka.log is not set if logging isn't enabled.
// I.E. if using the release version of shaka.
if (!shaka['log']) {
return;
}
// Access shaka.log using bracket syntax because shaka.log is not exported.
// Exporting the logging methods proved to be a bad solution, both in terms
// of difficulty and in terms of what changes it would require of the
// architectural design of Shaka Player, so this non-type-safe solution is
// the best remaining way to get the Closure compiler to compile this
// method.
const Level = shaka['log']['Level'];
const setLevel = shaka['log']['setLevel'];
const localize = (name) => shakaDemoMain.getLocalizedString(name);
const logLevels = {
'info': localize(MessageIds.LOG_LEVEL_INFO),
'debug': localize(MessageIds.LOG_LEVEL_DEBUG),
'v': localize(MessageIds.LOG_LEVEL_V),
'vv': localize(MessageIds.LOG_LEVEL_VV),
};
const onChange = (input) => {
switch (input.value) {
case 'info':
setLevel(Level['INFO']);
break;
case 'debug':
setLevel(Level['DEBUG']);
break;
case 'vv':
setLevel(Level['V2']);
break;
case 'v':
setLevel(Level['V1']);
break;
}
shakaDemoMain.remakeHash();
};
this.addSelectInput_(MessageIds.LOG_LEVEL, logLevels, onChange);
const input = this.latestInput_.input();
switch (shaka['log']['currentLevel']) {
case Level['DEBUG']:
input.value = 'debug';
break;
case Level['V2']:
input.value = 'vv';
break;
case Level['V1']:
input.value = 'v';
break;
default:
input.value = 'info';
break;
}
}
/**
* @param {string} suffix
* @return {string}
* @private
*/
resolveExternLink_(suffix) {
return '../docs/api/shaka.extern.html#' + suffix;
}
/**
* @param {?shakaDemo.MessageIds} name
* @param {?string} docLink
* @return {!shakaDemo.Config}
* @private
*/
addSection_(name, docLink) {
const style = name ?
shakaDemo.InputContainer.Style.ACCORDION :
shakaDemo.InputContainer.Style.VERTICAL;
this.sections_.push(new shakaDemo.InputContainer(
this.container_, name, style, docLink));
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {string} valueName
* @param {shakaDemo.MessageIds=} tooltipMessage
* @return {!shakaDemo.Config}
* @private
*/
addBoolInput_(name, valueName, tooltipMessage) {
const onChange = (input) => {
shakaDemoMain.configure(valueName, input.checked);
shakaDemoMain.remakeHash();
};
this.addCustomBoolInput_(name, onChange, tooltipMessage);
if (shakaDemoMain.getCurrentConfigValue(valueName)) {
this.latestInput_.input().checked = true;
}
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {function(!HTMLInputElement)} onChange
* @param {shakaDemo.MessageIds=} tooltipMessage
* @return {!shakaDemo.Config}
* @private
*/
addCustomBoolInput_(name, onChange, tooltipMessage) {
this.createRow_(name, tooltipMessage);
const localized = shakaDemoMain.getLocalizedString(name);
this.latestInput_ = new shakaDemo.BoolInput(
this.getLatestSection_(), localized, onChange);
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {string} valueName
* @param {shakaDemo.MessageIds=} tooltipMessage
* @return {!shakaDemo.Config}
* @private
*/
addTextInput_(name, valueName, tooltipMessage) {
const onChange = (input) => {
shakaDemoMain.configure(valueName, input.value);
shakaDemoMain.remakeHash();
};
this.addCustomTextInput_(name, onChange, tooltipMessage);
this.latestInput_.input().value =
shakaDemoMain.getCurrentConfigValue(valueName);
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {function(!HTMLInputElement)} onChange
* @param {shakaDemo.MessageIds=} tooltipMessage
* @return {!shakaDemo.Config}
* @private
*/
addCustomTextInput_(name, onChange, tooltipMessage) {
this.createRow_(name, tooltipMessage);
const localized = shakaDemoMain.getLocalizedString(name);
this.latestInput_ = new shakaDemo.TextInput(
this.getLatestSection_(), localized, onChange);
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {string} valueName
* @param {boolean=} canBeDecimal
* @param {boolean=} canBeZero
* @param {boolean=} canBeUnset
* @param {shakaDemo.MessageIds=} tooltipMessage
* @return {!shakaDemo.Config}
* @private
*/
addNumberInput_(name, valueName, canBeDecimal = false, canBeZero = true,
canBeUnset = false, tooltipMessage) {
const onChange = (input) => {
shakaDemoMain.resetConfiguration(valueName);
shakaDemoMain.remakeHash();
if (input.value == 'Infinity') {
shakaDemoMain.configure(valueName, Infinity);
shakaDemoMain.remakeHash();
return;
}
if (input.value == '' && canBeUnset) {
return;
}
const valueAsNumber = Number(input.value);
if (valueAsNumber == 0 && !canBeZero) {
return;
}
if (!isNaN(valueAsNumber)) {
if (Math.floor(valueAsNumber) != valueAsNumber && !canBeDecimal) {
return;
}
shakaDemoMain.configure(valueName, valueAsNumber);
shakaDemoMain.remakeHash();
}
};
this.createRow_(name, tooltipMessage);
const localized = shakaDemoMain.getLocalizedString(name);
this.latestInput_ = new shakaDemo.NumberInput(
this.getLatestSection_(), localized, onChange, canBeDecimal, canBeZero,
canBeUnset);
this.latestInput_.input().value =
shakaDemoMain.getCurrentConfigValue(valueName);
if (isNaN(Number(this.latestInput_.input().value)) && canBeUnset) {
this.latestInput_.input().value = '';
}
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {!Array.<string>} values
* @param {function(!HTMLInputElement)} onChange
* @param {shakaDemo.MessageIds=} tooltipMessage
* @return {!shakaDemo.Config}
* @private
*/
addDatalistInput_(name, values, onChange, tooltipMessage) {
this.createRow_(name, tooltipMessage);
const localized = shakaDemoMain.getLocalizedString(name);
this.latestInput_ = new shakaDemo.DatalistInput(
this.getLatestSection_(), localized, onChange, values);
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {!Object.<string, string>} values
* @param {function(!HTMLInputElement)} onChange
* @param {shakaDemo.MessageIds=} tooltipMessage
* @return {!shakaDemo.Config}
* @private
*/
addSelectInput_(name, values, onChange, tooltipMessage) {
this.createRow_(name, tooltipMessage);
// The input is not provided a name, as (in this enclosed space) it makes
// the actual field unreadable.
this.latestInput_ = new shakaDemo.SelectInput(
this.getLatestSection_(), null, onChange, values);
return this;
}
/**
* @param {!shakaDemo.MessageIds} name
* @param {shakaDemo.MessageIds=} tooltipMessage
* @private
*/
createRow_(name, tooltipMessage) {
this.getLatestSection_().addRow(name, tooltipMessage || null);
}
/**
* Gets the latest section. Results in a failed assert if there is no latest
* section.
* @return {!shakaDemo.InputContainer}
* @private
*/
getLatestSection_() {
goog.asserts.assert(this.sections_.length > 0,
'Must have at least one section.');
return this.sections_[this.sections_.length - 1];
}
};
document.addEventListener('shaka-main-loaded', shakaDemo.Config.init);
document.addEventListener('shaka-main-cleanup', () => {
shakaDemoConfig = null;
});