// VERSION 1.33 function initializeVideoPlaylist(inputData, elementRoot) { // ALL VIDEO PLAYLIST API WIDGET CODE WRAPPED IN FUNCTION SO ALL VARIABLES ARE LOCALLY SCOPED TO AVOID ERRORS WITH UTILIZING THE WIDGET MORE THAN ONCE ON THE SAME PAGE // ALL HTML, CSS, JAVASCRIPT CODE FOR THE VIDEO PLAYLIST WIDGET API IS PRESENT HERE, MINUS THE ROOT WIDGET HTML CONTAINER. A CONTAINER MUST BE PRESENT IN THE HTML WITH THE ID OF THE WIDGET FOR THE "widgetRoot" DOM SELECTOR TO INITIATE THE WIDGET. // DOM ROOT DIV CREATION FOR CODE INSERTION. inputData ARGUMENT MUST CONTAIN AN id KEY AND MUST HAVE ITS CORRESPONDING PARENT SCRIPT TAG WITH A data-playlist-id ATTRIBUTE SET TO IT ALSO const existingWidgetsLength = document.querySelectorAll('[data-type="video-playlist-widget"]').length; const widgetId = `video-playlist-${existingWidgetsLength}`; const widgetIdSelector = `#${widgetId}`; const createdDiv = document.createElement('div'); createdDiv.id = widgetId; elementRoot.outerHTML = createdDiv.outerHTML; // Variable Declarations // Value Declarations. Elementors Unlimited Elements Widget Creator Inserts User Input Values Into Variables With Curly Bracket Surroundings. // API Keys function backupAPIKeys() { let apiKeyPicked; if (playlistService === 'youtube') { const youtubeAPIKeys = ['AIzaSyAGeChuN2jmAVvINB7aJv-ZzU_a2bnNGio']; apiKeyPicked = youtubeAPIKeys[Math.floor(Math.random() * youtubeAPIKeys.length)]; } return apiKeyPicked } // Input Data Variables Declarations const resultLimitPerRequest = typeof inputData.resultLimitPerRequest === 'number' ? inputData.resultLimitPerRequest : 50; // Youtube API Has A Limit Of 50 Results Per Request. const limitVideos = typeof inputData.limitVideos === 'boolean' ? inputData.limitVideos : true; // Limit Videos Displayed. Default Value Is: true const maxResults = typeof inputData.maxResults === 'number' ? inputData.maxResults : 6; // If limitVideos Is Set To: true, Limit Number Of Videos Displayed. Default Value Is: 6 const showAllVideoTypes = typeof inputData.showAllVideoTypes === 'boolean' ? inputData.showAllVideoTypes : false; // Determins If All Video Types Whether It Has An Episode Number Or Not Should Be Displayed const filterByName = typeof inputData.filterByName === 'boolean' ? inputData.filterByName : false; // Filter Video Results Based On Characters In Title. Default Value Is: false const filterNameParameters = typeof inputData.filterNameParameters === 'string' ? inputData.filterNameParameters.toLowerCase() : ''; // If filterByName Is Set To: true, Filter String Parameters For filterByName. Default Value Is: '' const sortVideosBy = typeof inputData.sortVideosBy === 'string' ? inputData.sortVideosBy : 'number-descending'; // How Video Items Should Be Sorted. Default Value Is: 'number-descending' const listByRange = typeof inputData.listByRange === 'boolean' ? inputData.listByRange : true; // Show Specific Range Of Videos By Episode Number. Default Value Is: false const fromEpisodeNumber = typeof inputData.fromEpisodeNumber === 'number' ? inputData.fromEpisodeNumber : 1; // If listByRange Is Set To: true, Set Starting Episode Number To Filter From. Default Value Is: 1 const toEpisodeNumber = typeof inputData.toEpisodeNumber === 'number' ? inputData.toEpisodeNumber : 2000; // If listByRange Is Set To: true, Set Starting Episode Number To Filter From. Default Value Is: 1 const showNonNumberedEpisodesOnly = typeof inputData.showNonNumberedEpisodesOnly === 'boolean' ? inputData.showNonNumberedEpisodesOnly : false; // Shows Videos That Do Not Have An Episode Number Only. Default Value Is: false const hideNonNumberedVideos = typeof inputData.hideNonNumberedVideos === 'boolean' ? inputData.hideNonNumberedVideos : true; // Hides Non-Numbered Videos In Playlist. Default Value Is: true const timeStorageInterval = typeof inputData.timeStorageInterval === 'number' ? inputData.timeStorageInterval * 60000 : 21600000; // Sets Time Interval That Another API Call Request Can Be Made Instead Of Loading From Local Storage In Minutes That Is Multiplied By 60000 To Convert Minutes To Milliseconds. Default Value is 60 const showPlayButtons = typeof inputData.showPlayButtons === 'boolean' ? inputData.showPlayButtons : true; // Sets If Play Button Icons Should Be Shown Over Video Thumbnails. Default Value Is: true let showVideoInfo = typeof inputData.showVideoInfo === 'boolean' ? inputData.showVideoInfo : true; // Sets If Text Information About Video Should Be Displayed Below Video Thumbnail. Default Value Is: false const showDescriptionText = typeof inputData.showDescriptionText === 'boolean' ? inputData.showDescriptionText : true; // If showVideoInfo Is Set To True, Sets If Video Description Text Should Be Displayed. Default Value Is: false const showTitleText = typeof inputData.showTitleText === 'boolean' ? inputData.showTitleText : false; // If showTitle Is Set To True, Sets If Video Title Text Should Be Displayed. Default Value Is: false const showAllInLightbox = typeof inputData.showAllInLightbox === 'boolean' ? inputData.showAllInLightbox : false; // Determines If Lightbox Will Allow User To See All Videos On PlayList If True. If False, User Can Only View Videos Shown On Page const fastForwardSpeed = typeof inputData.fastForwardSpeed === 'number' ? inputData.fastForwardSpeed : 150; // Set The Speed That Frames Should Be Fast Forwarded Through On Carousel And Lightbox When User Holds Down Arrow. const showLogoImgUrl = typeof inputData.showLogoImgUrl === 'string' ? inputData.showLogoImgUrl : ''; // Show Logo Image URL For Playlist Heading. If Nothing, Then TV Episodes Text Will Be Shown let playlistButton = typeof inputData.playlistButton === 'boolean' ? inputData.playlistButton : true; // Sets If Playlist Button Will Be Shown On Page. Default Value Is: true const playlistLayout = typeof inputData.playlistLayout === 'grid' ? 'grid' : inputData.playlistLayout === 'carousel' ? 'carousel' : inputData.playlistLayout === 'carousel-multi' ? 'carousel-multi' : 'grid'; // Determines The Layout Of Videos On Page. Default value is 'grid'. Other value is 'carousel' const playlistService = typeof inputData.playlistService === 'youtube' ? 'youtube' : inputData.playlistService === 'vimeo' ? 'vimeo' : 'youtube'; // Determines If Video Playlist Is Coming From. Default Value Is 'youtube' const apiKey = typeof inputData.apiKey === 'string' ? inputData.apiKey : backupAPIKeys(); // API Key. Loads Backup Keys If No Key Is Passed In const playlistId = inputData.playlistId; // Playlist Id. REQUIRED FOR WIDGET TO WORK. // Input CSS Variable Declarations const fontFamily = typeof inputData.fontFamily === 'string' ? inputData.fontFamily : 'Roboto'; // Sets Font Family Style For All Text In Widget. Default Value Is: 'Roboto' const thumbnailFontHeadingSize = typeof inputData.thumbnailFontHeadingSize === 'string' ? inputData.thumbnailFontHeadingSize : '2.25rem'; // Sets Font Size Of Video Thumbnail Episode Heading Text. Default Value is: 2rem const fontBodySize = typeof inputData.fontBodySize === 'string' ? inputData.fontBodySize : '1.375rem'; // Sets Font Size Of Video Thumbnail Instruction Text. Default Value is: 1.5rem const playButtonColor = typeof inputData.playButtonColor === 'string' ? inputData.playButtonColor : '#ffffff'; // Sets Color Of Play Button Icon Over Video Thumbnail. Default Value IS: '#ffffff' const gapBetweenGridVideos = typeof inputData.gapBetweenGridVideos === 'number' ? inputData.gapBetweenGridVideos : 48; // Sets Spacing Between Video Items In Grid Layout In Pixels. Default Value Is: 48 const gapBetweenPlaylistVideos = typeof inputData.gapBetweenPlaylistVideos === 'number' ? inputData.gapBetweenPlaylistVideos : 48; // Sets Spacing Between Video Items In Playlist Layout In Pixels. Default Value Is: 48 const videoContainerBorderThickness = typeof inputData.videoContainerBorderThickness === 'string' ? inputData.videoContainerBorderThickness : '0px'; // Sets Video Container Border Thickness: Default Value Is: '0px' const videoContainerBorderColor = typeof inputData.videoContainerBorderColor === 'string' ? inputData.videoContainerBorderColor : '#000000'; // Sets Video Container Border Color: Default Value Is: '#000000' const dropShadowValues = typeof inputData.dropShadowValues === 'string' ? inputData.dropShadowValues: '4px 4px 12px'; // Sets Drop-Shadow Values For Video Container. Default Value Is: 0px 0px 0px const dropShadowColor = typeof inputData.dropShadowColor === 'string' ? inputData.dropShadowColor : '#01010147'; // Sets Drop-Shadow Color For Video Container. Default Value Is: '#00000036' const textBelowThumbnailTopMargin = typeof inputData.textBelowThumbnailTopMargin === 'string' ? inputData.textBelowThumbnailTopMargin : '20px'; // Sets Text Below Video Thumbnail Margins On Top And Bottom. Default Value Is: '24px' const titleTextColorBelowThumbnail = typeof inputData.titleTextColorBelowThumbnail === 'string' ? inputData.titleTextColorBelowThumbnail : '#000000'; // Sets Color Of Video Title Text Below Video Thumbnail. Default Value Is: '#000000' const spaceBetweenTitleAndDescriptionBelowThumbnail = typeof inputData.spaceBetweenTitleAndDescriptionBelowThumbnail === 'string' ? inputData.spaceBetweenTitleAndDescriptionBelowThumbnail : '0px'; // Sets Vertical Space Gap Between Title Text And Description Text Below Video Thumbnail. Default Value Is: '24px' const descriptionTextColorBelowThumbnail = typeof inputData.descriptionTextColorBelowThumbnail === 'string' ? inputData.descriptionTextColorBelowThumbnail : '#00000090'; // Sets Color Of Description Text Below Video Thumbnail. Default Value Is: '#000000' const imageDarkeningOpacity = typeof inputData.imageDarkeningOpacity === 'string' ? inputData.imageDarkeningOpacity : '20'; // Sets How Dark The Video Thumbnail Should Get Opacity On Mouse Hover. Default Value Is: '20' const textOverThumbnailColor = typeof inputData.textOverThumbnailColor === 'string' ? inputData.textOverThumbnailColor : '#ffffff'; // Sets Color Of Text Over Video Thumbnail On Mouse Hover. Default Value Is: '#ffffff' const textContainerMargin = typeof inputData.textContainerMargin === 'string' ? inputData.textContainerMargin : '24px'; // Sets Padding Of Text Container That Cover Over Video Thumbnail For Text On Mouse Hover. Default Value Is: '24px' const spaceBetweenTitleAndClickToPlayText = typeof inputData.spaceBetweenTitleAndClickToPlayText === 'string' ? inputData.spaceBetweenTitleAndClickToPlayText : '2.25rem'; // Sets Vertical Spacing Between Episode Number Or Video Title Text And Instruction Text On Mouse Hover Over Thumbnail. Default Value Is: '40px' const playButtonSizing = typeof inputData.playButtonSizing === 'string' ? inputData.playButtonSizing : '32%'; // Sets Sizing Of Play Button Icon Over Video Thumbnail Relative To The HEight Of The Video Thumbnail In Percentage. Default Value Is: '35%' const playButtonOpacity = typeof inputData.playButtonOpacity === 'number' ? inputData.playButtonOpacity / 100 : .6; // Sets Opacity Of Play Button Icon Over Video Thumbnail. Divides Number By 100 To Convert Percentage To Decimal. Default Value Is: 75 const minimumWidthOfEachGridVideoItem = typeof inputData.minimumWidthOfEachGridVideoItem === 'number' ? inputData.minimumWidthOfEachGridVideoItem : 400; // Sets Minimun Width Size Of Each Video. Default Value Is: 480 const frameTransition = typeof inputData.frameTransition === 'number' ? inputData.frameTransition : 500; // Sets Transition Time Of LightBox Carousel Frame Transitioning In Milliseconds const carouselTransition = typeof inputData.carouselTransition === 'number' ? inputData.carouselTransition : 1000; // Sets Transition Time Of Carousel Layout Frame Transitioning In Milliseconds const carouselDelay = typeof inputData.carouselDelay === 'number' ? inputData.carouselDelay : 7000; // Sets Delay Carousel Layout Between Transitioning In Milliseconds const carouselWidth = typeof inputData.carouselWidth === 'number' ? inputData.carouselWidth : 40 // Set Width Of Carousel Layout Thumbnails In REMs const carouselArrowsColor = typeof inputData.carouselArrowsColor === 'string' ? inputData.carouselArrowsColor : '#949494' // Sets Color Of Carousel Layout Arrows And Text Overlay During Fast Forward const showThemeColor = typeof inputData.showThemeColor === 'string' ? inputData.showThemeColor : '#949494' // Sets Theme Color For LightBox Playlist Outline const playlistButtonColor = typeof inputData.playlistButtonColor === 'string' ? inputData.playlistButtonColor : '#FFF' // Sets Playlist Button Text Color const playlistButtonBackgroundColor = typeof inputData.playlistButtonBackgroundColor === 'string' ? inputData.playlistButtonBackgroundColor : typeof inputData.showThemeColor === 'string' ? inputData.showThemeColor : '#949494'; const playlistButtonPadding = typeof inputData.playlistButtonPadding === 'string' ? inputData.playlistButtonPadding : '0.75em 1.5em' // Sets Playlist Button Padding. Default Value is: '1em 2em' const playlistButtonFontWeight = typeof inputData.playlistButtonFontWeight === 'string' ? inputData.playlistButtonFontWeight : '700' // Sets Font Weight Of Playlist Button On Page const playlistButtonBorderRadius = typeof inputData.playlistButtonBorderRadius === 'string' ? inputData.playlistButtonBorderRadius : '0em' // Sets Border-Radius Of Playlist Button const carouselArrowSize = typeof inputData.carouselArrowSize === 'string' ? inputData.carouselArrowSize : '48px' ; // Sets Arrows Size On Carousel Layout In Percentage const thumbnailAspectRatio = typeof inputData.thumbnailAspectRatio === 'string' ? inputData.thumbnailAspectRatio : '1.777 / 1' // Sets Aspect Ratio Of Video Thumbnails. Default Value Is '1.777 / 1' const lightboxPlayerIconSize = typeof inputData.lightboxPlayerIconSize === 'number' ? inputData.lightboxPlayerIconSize : 4.75; // Sets Size Of Lightbox Arrows In Viewport Height. Default Value Is 4.75 const showLogoWhiteOut = typeof inputData.showLogoWhiteOut === 'boolean' ? inputData.showLogoWhiteOut : false; // Determines If Show Logo Image Should Become All White In Color const playlistButtonText = typeof inputData.playlistButtonText === 'string' ? inputData.playlistButtonText : window.innerWidth > 1200 ? 'Click Here For More Episodes' : 'Tap Here For More Episodes' // Playlist Button Text // Programming Variables Declarations let storedPlaylistRetrieved = false; // Determines If Data Was Loaded From Local Storage. Utilized In getPlaylistItems Function. Default Staring Value Is: false const instructionMessage = window.innerWidth > 1200 ? 'Click Here To Watch' : 'Tap Here To Watch'; // Instruction Message Text. Default Value is: 'Click Here To Watch' let playListSorted = []; // Captures All Videos After Filtering And Sorting Before They're Reduced To Output Amount For Showing All Videos When Navigating Through Lightbox let pageOutputList = []; // The Actual List Of Video That Will Be Shown On The Page (Grid Or Carousel Layout) let lightboxToggled = false; // Used To Determine If Lightbox Is Toggled let showPlaylist = false; // Toggles Lightbox Playlist On And Off const lightboxFrameVideoBaseUrl = playlistService === 'youtube' ? 'https://www.youtube.com/embed/' : ''; // Video Base Url For Lightbox Video Iframes const baseUrl = playlistService === 'youtube' ? `https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=` : ``; const fullPath = playlistService === 'youtube' ? `${baseUrl}${playlistId}&key=${apiKey}&maxResults=1000` : ``; // CSS Programming Variable Declarations const mediaQueryMobileBreakpoint = (minimumWidthOfEachGridVideoItem * 2) + (gapBetweenGridVideos * 1.5); // Sets Media Query Break Point Of When Video Containers Should Stack In One Column. Calculation Based Upon minimumWidthOfEachVideo Number. Default Value Is: minimumWidthOfEachGridVideoItem * 2 // Error Handling Variables const apiErrMsg = `An error occured during the ${playlistService} playlist API call. The same ${playlistService} playlist was found in local storage and has been loaded instead.`; let failedItemTally = 0; // Initialization Loading Spinner const loadingSpinner = ` `; // HTML Base Container Initialization. Loading Spinner Is Included On Initialization const widgetRoot = document.querySelector(`${widgetIdSelector}`); widgetRoot.innerHTML = `
${instructionMessage}
`}${instructionMessage}
`}${instructionMessage}
`}${instructionMessage}
`}