var lensUIUtils = { _pageURL: null, setPageUrl: function setPageUrl(url) { this._pageURL = url; // store the URL we use to redirect to the lenses page }, showFindWhichDisplayByCol: function showFindWhichDisplayByCol() { const logHeader = 'lensUIUtils.showFindWhichDisplayByCol: '; log(logHeader + 'enter'); const theElem = $('#divColFindWhichGroupBy'); theElem.addClass("column"); theElem.addClass("col-auto"); theElem.css('display', ''); // show the column log(logHeader + 'leave'); }, hideFindWhichDisplayByCol: function hideFindWhichDisplayByCol() { const logHeader = 'lensUIUtils.hideFindWhichDisplayByCol: '; log(logHeader + 'enter'); const theElem = $('#divColFindWhichGroupBy'); theElem.removeClass("column"); theElem.removeClass("col-auto"); theElem.css('display', 'none'); // hide the column log(logHeader + 'leave'); }, showHideFindWhichDisplayByColAsNec: function showHideFindWhichDisplayByColAsNec() { const logHeader = 'lensUIUtils.showHideFindWhichDisplayByColAsNec: '; log(logHeader + 'enter'); const findWhichVisible = findWhichGroupUtils.isFindWhichVisible(); // is the "find which" group visible? log(logHeader + 'findWhichVisible=' + findWhichVisible); if (findWhichVisible) { // if so this.showFindWhichDisplayByCol(); // show the column log(logHeader + 'leave'); return; } const displayByVisible = displayByUtils.isDisplayByVisible(); // is the "display by" group visible? log(logHeader + 'displayByVisible=' + displayByVisible); if (displayByVisible) { // if so this.showFindWhichDisplayByCol(); // show the column log(logHeader + 'leave'); return; } this.hideFindWhichDisplayByCol(); // hide the column log(logHeader + 'leave'); }, _handleVideoClick: function _handleVideoClick(evt) { const logHdr = 'lensUIUtils._handleVideoClick: '; log(logHdr + 'enter'); //const videoElem = evt.target; //// get the video element //const paused = videoElem.paused; //// is the video paused? //log(logHdr + 'paused=' + paused); //if (paused) { // log(logHdr + 'playing the video'); // videoElem.play(); // // if the video is paused, play it //} //else { // log('pausing the video'); // videoElem.pause(); // // if the video is playing, pause it //} log(logHdr + 'leave'); }, _getVideoElemSize: function _getVideoElemSize(viewWidth, viewHeight) { const logHdr = 'lensUIUtils._getVideoElemSize: '; log(logHdr + 'enter'); log(logHdr + 'viewWidth=' + viewWidth); log(logHdr + 'viewHeight=' + viewHeight); var sizeObj = {}; var elemWidth = 260; var elemHeight = 146; // default to smallest size if (viewWidth > 320) { elemWidth = 300; elemHeight = 168; } if (viewWidth > 425) { if (viewHeight > 414) { // if the view is taller than iPhone 6 in landscape mode elemWidth = 565; elemHeight = 317; } } sizeObj.width = elemWidth; sizeObj.height = elemHeight; log(logHdr + 'elemWidth=' + elemWidth); log(logHdr + 'elemHeight=' + elemHeight); log(logHdr + 'leave'); return sizeObj; }, _addVideoElemToTabIfNecAsync: async function _addVideoElemToTabIfNecAsync(lensId) { const logHdr = 'lensUIUtils._addVideoElemToTabIfNecAsync: '; log(logHdr + 'enter'); log(logHdr + 'lensId=' + lensId); const videoType = videoUtils.getVideoType(lensId); // what is the video type for this lens? log(logHdr + 'videoType=' + videoType); var targetId = ''; if (videoType === videoUtils.VIDEO_TYPE_BLOB) { // if the video for the lens is a video element targetId = elemIdUtils.getVideoElemId(lensId); // get the id of the video element } else { // if the video for the lens is an iFrame targetId = elemIdUtils.getVideoIFrameParentElemId(lensId); // get the id of the div parent of the video iFrame } log(logHdr + 'targetId=' + targetId); const videoSelector = '#' + targetId; const vidCount = $(videoSelector).length; // how many elements for the lens are on the page? log(logHdr + 'vidCount=' + vidCount); if (vidCount > 0) { // if there is already one on the page log(logHdr + 'there is already a video element on the page for this lens so we are done'); log(logHdr + 'leave'); return; } // if we need to add the video element log(logHdr + 'we need to add the video element'); const videoElemSize = lensUIUtils._getVideoElemSize(viewWidth, viewHeight); // get the desired size of the video element given the view dimensions const videoElemWidth = videoElemSize.width; const videoElemHeight = videoElemSize.height; log(logHdr + 'viewWidth=' + viewWidth); log(logHdr + 'viewHeight=' + viewHeight); log(logHdr + 'video element size is ' + videoElemWidth + ' x ' + videoElemHeight); const vId = elemIdUtils.getElemId(lensId, elemIdUtils.TAB_PANE_VIDEO_PREFIX, undefined); // get the id of the element to which we will append the video HTML // undefined => there is only one of these elements for each lens log(logHdr + 'vId=' + vId); var videoHtml = ''; if (videoType === videoUtils.VIDEO_TYPE_BLOB) { // if the video for the lens is a video element const blubUrl = videoUtils.getVideoUrl(lensId); // get the URL of the video blob videoHtml = videoUtils.getVideoHtml_video(lensId, videoElemWidth, videoElemHeight, blubUrl); // get the html for the video element log('videoHtml=' + videoHtml); $('#' + vId).append(videoHtml); // add the HTML for the video element to the page const videoElemId = elemIdUtils.getVideoElemId(lensId); // get the id of the video element lensUIUtils.subscribeToEventsForVideoElem(videoElemId); // subscribe to the events for the video element } else { // if the video for the lens is an iFrame const iFrameSourceUrl = videoUtils.getIFrameUrl(lensId); // get the URL for the iFrame source log(logHdr + 'iFrameSourceUrl=' + iFrameSourceUrl); videoHtml = videoUtils.getVideoHtml_iFrame(lensId, videoElemWidth, videoElemHeight, iFrameSourceUrl); // get the html for the iFrame element log(logHdr + 'videoHtml=' + videoHtml); $('#' + vId).append(videoHtml); // add the HTML for the iFrame element to the page await lensUIUtils.subscribeToEventsForIFrameVideoAsync(lensId); // subscribe to video events for the video in the iFrame } log(logHdr + 'leave'); }, _shouldShowCloseAlert: function _shouldShowCloseAlert() { const logHdr = 'lensUIUtils._shouldShowCloseAlert: '; log(logHdr + 'enter'); const shownCount = userStateUtils.getHideAlertCount(); // how many times have we shown the hide alert? if (shownCount < 2) { // if fewer than two log(logHdr + 'shownCount=' + shownCount + ', so we will return true'); log(logHdr + 'leave'); return true; } //const alertDate = userStateUtils.getHideAlertDate(); //// get the date we last showed the "hide lens" alert //// may be undefined if we have not yet showed the alert //log('_shouldShowCloseAlert: alertDate=' + alertDate); //const shownToday = userStateUtils.isDateWithinHoursOfNow(alertDate, 24);. //// have we shown this alert in the past 24 hours? //log('_shouldShowCloseAlert: shownToday=' + shownToday); //const show = (!shownToday); //// if there are 25 lenses showing and we have NOT shown the alert today, show it const show = false; // otherwise, don't show it log(logHdr + 'show=' + show); log(logHdr + 'leave'); return show; }, _handleFullscreenChange: function _handleFullscreenChange(e) { const logHdr = 'lensUIUtils._handleFullscreenChange'; log(logHdr + 'enter'); const now = new Date(); userStateUtils.setFullscreenDate(now); // store the date and time when a video was set to fullscreen log(logHdr + 'leave'); }, _handleVideoPlay: function _handleVideoPlay(e) { // called when the video plays const logHdr = 'lensUIUtils._handleVideoPlay: '; log(logHdr + 'enter'); // NOTE: vides on the leses page use videoUtils, not userStateUtils to track // whether a video is playing const sender = this; // the object that fired the event for this handler const senderName = sender.constructor.name; // get the name of the type of object that called this handler log(logHdr + 'senderName=' + senderName); if (senderName !== "Player") { // if the sender is not a Vimeo player log(logHdr + 'the sender is NOT a Vimeo video player, so we are done'); log(logHdr + 'leave'); return; } log(logHdr + 'the sender is a Vimeo video player'); const eventPlayer = sender; // the sender is a Vimeo video player const elemId = eventPlayer.element.id; // get the DOM element id of the Player object log(logHdr + 'event video elemId=' + elemId); const lensId = elemIdUtils.getLensIdFromVideoIFrameElemId(elemId); // get the lens id from the iFrame DOM element id log(logHdr + 'atc videoPlayers.stopPlayingVideosExcept'); videoPlayers.stopPlayingVideosExcept(lensId); // stop any videos other than the event video (the one that fired this event) log(logHdr + 'bf videoPlayers.stopPlayingVideosExcept'); videoPlayers.setPlayerPlaying(lensId, eventPlayer); // remember that this video is playing log(logHdr + 'leave'); }, _handleVideoStopped: function _handleVideoStopped(e) { // called when the video is stopped for any reason const logHdr = 'lensUIUtils._handleVideoStopped: '; log(logHdr + 'enter'); const senderName = caller.constructor.name; // get the name of the type of object that called this handler log(logHdr + 'senderName=' + senderName); if (senderName === "Player") { // if it's a Vimeo player log(logHdr + 'the caller is a Vimeo video player'); const elemId = eventPlayer.element.id; // get the DOM element id of the current player object log(logHdr + 'elemId=' + elemId); var lensId = elemIdUtils.getLensIdFromVideoIFrameElemId(elemId); // extract the lens id log(logHdr + 'lensId=' + lensId); log(logHdr + 'atc videoPlayers.setPlayerStopped'); videoPlayers.setPlayerStopped(lensId); log(logHdr + 'bf videoPlayers.setPlayerStopped'); } else { // otherwise log(logHdr + 'the caller is NOT a Vimeo video player'); } //const now = new Date(); //userStateUtils.setVideoStoppedDate(now); //// store the date and time the video was stopped //// we use this value as explained in the header comment for this function //userStateUtils.clearVideoPlayingFlag(); //// clear the flag that indicates that a video is playing log(logHdr + 'leave'); }, subscribeToEventsForIFrameVideoAsync: async function subscribeToEventsForIFrameVideoAsync(lensId) { // subscribe to events for a single iFrame video element const logHdr = 'subscribeToEventsForIFrameVideoAsync: '; log(logHdr + 'enter'); log(logHdr + 'lensId=' + lensId); const iFrameId = elemIdUtils.getVideoIFrameElemId(lensId); // get the id of the iFrame element log(logHdr + 'iFrameId=' + iFrameId); const iFrameJQ = $('#' + iFrameId); // get a jQuery object for the iFrame element const count = iFrameJQ.length; // how many did we find? log(logHdr + 'count=' + count); if (count < 1) { // if we didn't find any log(logHdr + 'we did NOT find the video iFrame element. this may be an error.'); log(logHdr + 'leave'); return; } log(logHdr + 'found the video iFrame element'); const iFrameObj = iFrameJQ[0]; // get the iFrame DOM object from the jQuery object log(logHdr + 'read the DOM object from the jQuery object'); const player = new Vimeo.Player(iFrameObj); // allocate a Vimeo player object for the iFrame log(logHdr + 'allocated the Vimeo player'); videoPlayers.setPlayer(lensId, player); // store the player so we can use it later //player.getVideoTitle().then(function (title) { log(logHdr + 'videoTitle=' + title); }).catch(function (error) { log(logHdr + 'ERROR: ' + error.name); }); //// get the title of the video, to make sure the player was allocated successfully //NOTE: the code for video elements subscribes to the following events that the Video player does NOT have // fullscreenchange // webkitfullscreenchange // mozfullscreenchange // msfullscreenchange // stalled (which we don't subscribe to for video elements) // NOTE: at least on iOS, the "stalled" event gets sent fairly often while the video plays. // more important, no event is sent when the video continues to play, // so if we take the stalled event to mean that the video has stopped we will be incorrect. // so for now we don't subscribe to the stalled event. // abort log(logHdr + 'about to subscribe to video events for the Vimeo player'); player.on('play', lensUIUtils._handleVideoPlay); // call this method when the video plays player.on('ended', lensUIUtils._handleVideoStopped); player.on('error', lensUIUtils._handleVideoStopped); player.on('pause', lensUIUtils._handleVideoStopped); // subscribe to events where we consider the video not playing log(logHdr + 'subscribed to video events for the Vimeo player'); log(logHdr + 'leave'); }, subscribeToEventsForVideoElem: function subscribeToEventsForVideoElem(videoElemId) { // subscribe to events for a single video element const logHdr = 'subscribeToEventsForVideoElem: '; log(logHdr + 'enter'); log(logHdr + 'videoElemId=' + videoElemId); const videoJQ = $('#' + videoElemId); // get a jQuery object for the video element videoJQ.on("fullscreenchange", this._handleFullscreenChange); videoJQ.on("webkitfullscreenchange", this._handleFullscreenChange); videoJQ.on("mozfullscreenchange", this._handleFullscreenChange); videoJQ.on("msfullscreenchange", this._handleFullscreenChange); // depending on platform, any of these 4 events might occur when the user enters or exits fullscreen on a video videoJQ.on("play", this._handleVideoPlay); // call this method when the video plays // NOTE: at least on iOS, the "stalled" event gets sent fairly often while the video plays. // more important, no event is sent when the video continues to play, // so if we take the stalled event to mean that the video has stopped we will be incorrect. // so for now we don't subscribe to the stalled event. videoJQ.on("abort", this._handleVideoStopped); videoJQ.on("ended", this._handleVideoStopped); videoJQ.on("error", this._handleVideoStopped); videoJQ.on("pause", this._handleVideoStopped); // subscribe to events where we consider the video not playing log(logHdr + 'leave'); }, _subscribeToEventsForVideoElems: function _subscribeToEventsForVideoElems() { // subscribe to events for <video> elements const logHdr = '_subscribeToEventsForVideoElems: '; log(logHdr + 'enter'); const videosJQ = $('video'); // get a jQuery object for all the video elements on the page videosJQ.on("fullscreenchange", this._handleFullscreenChange); videosJQ.on("webkitfullscreenchange", this._handleFullscreenChange); videosJQ.on("mozfullscreenchange", this._handleFullscreenChange); videosJQ.on("msfullscreenchange", this._handleFullscreenChange); // depending on platform, any of these 4 events might occur when the user enters or exits fullscreen on a video videosJQ.on("play", this._handleVideoPlay); // call this method when the video plays videosJQ.on("abort", this._handleVideoStopped); videosJQ.on("ended", this._handleVideoStopped); videosJQ.on("error", this._handleVideoStopped); videosJQ.on("pause", this._handleVideoStopped); videosJQ.on("stalled", this._handleVideoStopped); // subscribe to events where we consider the video NOT playing //$('video').each(function () { // enableInlineVideo(this); //}); //// enable the iphone-inline-video functionality for all videos //$('video').on("click", function (evt) { lensUIUtils._handleVideoClick(evt); }); //// called when the user clicks the video log(logHdr + 'leave'); }, _subscribeToEventsForIFrameVideos: function _subscribeToEventsForIFrameVideos() { // subscribe to events for iFrame videos const logHdr = '_subscribeToEventsForIFrameVideos: '; log(logHdr + 'enter'); const iFramesJQ = $('.vimeo-iframe'); // get a jQuery object for all video iFrames on the page const count = iFramesJQ.length; // how many? log(logHdr + 'count=' + count); if (count < 1) { // if none log(logHdr + 'NO iFrame videos found, so we are done'); log(logHdr + 'leave'); return; } iFramesJQ.each(function () { var iFrameObj = this; var iFrameId = iFrameObj.id; // get the DOM element id of the iFrame var lensId = elemIdUtils.getLensIdFromVideoIFrameElemId(iFrameId); // extract the lens id var player = new Vimeo.Player(iFrameObj); // allocate a Vimeo player object for the iFrame log(logHdr + 'allocated the Vimeo player'); videoPlayers.setPlayer(lensId, player); // store the player so we can use it later //player.getVideoTitle().then(function (title) { log(logHdr + 'videoTitle=' + title); }).catch(function (error) { log(logHdr + 'ERROR: ' + error.name); }); //// get the title of the video, to make sure the player was allocated successfully //NOTE: the code for video elements subscribes to the following events that the Video player does NOT have // fullscreenchange // webkitfullscreenchange // mozfullscreenchange // msfullscreenchange // stalled (which we don't subscribe to for video elements) // NOTE: at least on iOS, the "stalled" event gets sent fairly often while the video plays. // more important, no event is sent when the video continues to play, // so if we take the stalled event to mean that the video has stopped we will be incorrect. // so for now we don't subscribe to the stalled event. // abort log(logHdr + 'about to subscribe to video events for the Vimeo player'); player.on('play', lensUIUtils._handleVideoPlay); // call this method when the video plays player.on('ended', lensUIUtils._handleVideoStopped); player.on('error', lensUIUtils._handleVideoStopped); player.on('pause', lensUIUtils._handleVideoStopped); // subscribe to events where we consider the video not playing }); //$('video').on("click", function (evt) { lensUIUtils._handleVideoClick(evt); }); //// called when the user clicks the video log(logHdr + 'leave'); }, _subscribeToEventsForLensCards: function _subscribeToEventsForLensCards(pageURL) { log('_subscribeToEventsForLensCards: enter'); log('_subscribeToEventsForLensCards: pageURL=' + pageURL); lensUIUtils._subscribeToEventsForVideoElems(); // subscribe to events for video elements lensUIUtils._subscribeToEventsForIFrameVideos(); // subscribe to events for iFrame videos $('button.load-video').on("click", function (evt) { const lensId = lensUIUtils.getLensIdFromElemId(this.id); lensClickUtils.handleLoadVideoClick(lensId); }); // subscribe to the click event for the "Load Video" buttons $('.s-more-tabs').on("click", function (evt) { const lensId = lensUIUtils.getLensIdFromElemId(this.id); moreLessClickUtils.handleMoreClick_Tabs(lensId); }); // subscribe to the click event for the "more..." spans in cards with tabs $('.s-less-tabs').on("click", function (evt) { const lensId = lensUIUtils.getLensIdFromElemId(this.id); moreLessClickUtils.handleLessClick_Tabs(lensId); }); // subscribe to the click event for the "less..." spans in cards with tabs $('.s-more').on("click", function (evt) { const lensId = lensUIUtils.getLensIdFromElemId(this.id); moreLessClickUtils.handleMoreClick_NoTabs(lensId); }); // subscribe to the click event for the "more..." spans in cards without tabs $('.s-less').on("click", function (evt) { const lensId = lensUIUtils.getLensIdFromElemId(this.id); moreLessClickUtils.handleLessClick_NoTabs(lensId, true); }); // subscribe to the click event for the "less..." spans in cards without tabs // true => scroll the lens card into view $('.card-hdr-close-btn').on("click", async function (evt) { await lensClickUtils.handleCloseBtnClickAsync(evt); }); // subscribe to the click event for card caption close buttons $('.when-tab').on("click", function (evt) { lensClickUtils.handleTabClickAsync(evt); }); $('.how-tab').on("click", function (evt) { lensClickUtils.handleTabClickAsync(evt); }); $('.examples-tab').on("click", function (evt) { lensClickUtils.handleTabClickAsync(evt); }); $('.video-tab').on("click", function (evt) { lensClickUtils.handleTabClickAsync(evt); }); // subscribe click handlers for the tabs alloyFingerUtils.subscribeToAlloyFingerEvts(); // subscribe to gesture events for the cards if (enableBookmarkFeatures) { $('.empty-bookmark').click(function () { bookmarkUIUtils.handleBookmarkClickAsync(this.id, pageURL); }); } log('_subscribeToEventsForLensCards: leave'); }, getTabNameFromElemId: function getTabNameFromElemId(elemId) { const header = 'getTabNameFromElemId: '; log(header + 'enter'); log(header + 'elemId=' + elemId); // examples // liWhenTab1 // liHowTab1 // liExamplesTab1 // liVideoTab1 var tabName = ''; if (elemId.startsWith('liWhenTab')) { tabName = 'when'; } if (elemId.startsWith('liHowTab')) { tabName = 'how'; } if (elemId.startsWith('liExamplesTab')) { tabName = 'examples'; } if (elemId.startsWith('liVideoTab')) { tabName = 'video'; } log(header + 'tabName=' + tabName); log(header + 'leave'); return tabName; }, getLensIdFromElemId: function getLensIdFromElemId(elemId) { //const header = 'getLensIdFromElemId: '; //log(header + 'enter'); //log(header + 'elemId=' + elemId); // examples // cardTextP1 // lensNameS1 // how1 // examples1 // video1 var idStr = ''; var lensId = 0; const newFormat = elemId.includes('-'); // is the id a new format id? if (newFormat) { const where = elemId.lastIndexOf('-'); // find the last hyphen in the string idStr = elemId.substring(where + 1); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('btnLoadVideo')) { idStr = elemId.substring(12); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('liWhenTab')) { idStr = elemId.substring(9); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('liHowTab')) { idStr = elemId.substring(8); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('liExamplesTab')) { idStr = elemId.substring(13); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('liVideoTab')) { idStr = elemId.substring(10); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('videoTab')) { idStr = elemId.substring(8); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('sLess')) { idStr = elemId.substring(5); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('sMore')) { idStr = elemId.substring(5); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('btnCloseCardHdr')) { idStr = elemId.substring(15); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('cardTextP')) { idStr = elemId.substring(9); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('cardHdr')) { idStr = elemId.substring(7); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('imgBk')) { idStr = elemId.substring(5); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('lensNameS')) { idStr = elemId.substring(9); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('when')) { idStr = elemId.substring(4); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('how')) { idStr = elemId.substring(3); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('examples')) { idStr = elemId.substring(8); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } if (elemId.startsWith('video')) { idStr = elemId.substring(5); //log(header + 'idStr=' + idStr); lensId = parseInt(idStr, 10); //log(header + 'leave'); return lensId; } //log(header + 'NOT FOUND'); //log(header + 'leave'); return -1; }, doesLensCardHaveTabs: function doesLensCardHaveTabs(lensId) { log('doesLensCardHaveTabs: enter'); const tabContentId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_TAB_CONTENT_PREFIX, undefined); // get the id of the tab content element log('doesLensCardHaveTabs: tabContentId=' + tabContentId); const count = $('#' + tabContentId).length; // how many tab content elements for the lens are contained on the page? const hasTabs = (count > 0); // if any, the card has tabs log('doesLensCardHaveTabs: hasTabs=' + hasTabs); log('doesLensCardHaveTabs: leave'); return hasTabs; }, isLensCardExpanded: function isLensCardExpanded(lensId, hasTabs) { log('isLensCardExpanded: enter'); log('isLensCardExpanded: lensId=' + lensId); log('isLensCardExpanded: hasTabs=' + hasTabs); var expanded = false; if (hasTabs) { expanded = tabsCardExpStorageUtils.isCardExpanded(lensId); } else { expanded = noTabsCardExpStorageUtils.isCardExpanded(lensId); } log('isLensCardExpanded: expanded=' + expanded); log('isLensCardExpanded: leave'); return expanded; }, toggleLessMore: function toggleLessMore(lensId, scrollIntoView) { // lensId: id of the target lens // scrollIntoView: if true, scroll the lens into view after collapsing log('toggleLessMore: enter'); log('toggleLessMore: lensId=' + lensId); const hasTabs = lensUIUtils.doesLensCardHaveTabs(lensId); // does the lens card have tabs? log('toggleLessMore: hasTabs=' + hasTabs); const expanded = lensUIUtils.isLensCardExpanded(lensId, hasTabs); // is the lens card expanded? log('toggleLessMore: expanded=' + expanded); if (hasTabs) { // if the lens card has tabs if (expanded) { moreLessClickUtils.handleLessClick_Tabs(lensId); // collapse the lens card which has tabs } else { moreLessClickUtils.handleMoreClick_Tabs(lensId); // expand the lens card which has tabs } } else { // if the lens card doesn't have tabs if (expanded) { moreLessClickUtils.handleLessClick_NoTabs(lensId, scrollIntoView); // collapse the lens card which doesn't have tabs } else { moreLessClickUtils.handleMoreClick_NoTabs(lensId); // expand the lens card which doesn't have tabs } } log('toggleLessMore: leave'); }, displayCurrentLensesAsync: async function displayCurrentLensesAsync() { // display the current set of lenses // the current set of lenses depends on // 1) the selected button in the "which to find" button group (all or bookmarked) // 2) hidden lenses // 3) display: alphabetically or by groups const logHdr = 'lensUIUtils.displayCurrentLensesAsync: '; log(logHdr + 'enter'); var targetLenses = []; var targetCount = 0; var lensesHtml = ''; // NOTE: for now, the Find Lens feature overrides other search-related values const toFindCount = lensesToFindStorageUtils.count(); log(logHdr + 'toFindCount=' + toFindCount); if (toFindCount > 0) { // if any lenses are specified to find log(logHdr + 'the user specified at least one lens to find'); const findLensIds = lensesToFindStorageUtils.getLensIds(); // get the ids of the lenses to find const foundCount = findLensIds.length; log(logHdr + 'foundCount=' + foundCount); if (foundCount > 0) { targetLenses = lensUtils.getLensesByIds(findLensIds); // get the lenses to display targetCount = targetLenses.length; log(logHdr + 'targetCount=' + targetCount); log(logHdr + 'calculating HTML to display found lenses alphabetically'); lensesHtml = await lensHtmlUtils.getHtmlForLensesByAlphaAsync(targetLenses); // get HTML for the array of lenses // arrange lenses alphabetically, not by group $('#divResults').html(lensesHtml); // NOTE: don't change the cache this._subscribeToEventsForLensCards(lensUIUtils._pageURL); log(logHdr + 'leave'); return; } } const findAll = findWhichGroupStateUtils.getFindAll(); // are we set to find all lenses? // true => find all // false => find bookmarked log(logHdr + 'findAll=' + findAll + ', (true => find all, false => find bookmarked)'); var byAlpha = displayByStateUtils.getDisplayAlpha(); // are we displaying lenses alphabetically? // true => alphabetically, false => by group log(logHdr + 'byAlpha=' + byAlpha + ', (true => alphabetically, false => by group)'); var cached = false; if (findAll) { // if we need to find all lenses except hidden (as opposed to bookmarked) if (byAlpha) { // if displaying alphabetically cached = displayCurrentLensesCache.hasAllAlphaValue(); } else { // if displaying by category cached = displayCurrentLensesCache.hasAllGroupedValue(); } log(logHdr + 'cached=' + cached); if (cached) { // if we have the HTML for this scenario cached log(logHdr + 'we need all lenses and we have them cached'); if (byAlpha) { lensesHtml = displayCurrentLensesCache.getAllAlphaHtml(); } else { lensesHtml = displayCurrentLensesCache.getAllGroupedHtml(); } $('#divResults').html(lensesHtml); // even though the HTML was cached, the cached is only a string, not elements in the DOM // after we create elements in the DOM, we need to subscribe to events this._subscribeToEventsForLensCards(lensUIUtils._pageURL); } else { // if we need all lenses and we don't have them cached log(logHdr + 'we need all lenses and we do NOT have them cached'); log(logHdr + 'creating the HTML for all lenses'); targetLenses = lensUtils.getLensDTOsToDisplay(); // get the lenses to display targetCount = targetLenses.length; log(logHdr + 'targetCount=' + targetCount); if (byAlpha) { // if we are displaying lenses alphabetically lensesHtml = await lensHtmlUtils.getHtmlForLensesByAlphaAsync(targetLenses); // get HTML for the array of lenses // arrange lenses alphabetically, not by group displayCurrentLensesCache.setAllAlphaHtml(lensesHtml); // cache the HTML } else { // otherwise lensesHtml = await lensHtmlUtils.getHtmlForLensesByGroupAsync(targetLenses); // get HTML for the array of lenses // arrange lenses by group displayCurrentLensesCache.setAllGroupedHtml(lensesHtml); // cache the HTML } $('#divResults').html(lensesHtml); this._subscribeToEventsForLensCards(lensUIUtils._pageURL); } } else { // if we need to find bookmarked lenses if (byAlpha) { // if displaying alphabetically cached = displayCurrentLensesCache.hasBkAlphaValue(); } else { // if displaying by category cached = displayCurrentLensesCache.hasBkGroupedValue(); } log(logHdr + 'cached=' + cached); if (cached) { // if we need bookmarked lenses and we have them cached log(logHdr + 'we need bookmarked lenses and we have them cached'); if (byAlpha) { // if we are displaying bookmarked lenses alphabetically and we have them cached lensesHtml = displayCurrentLensesCache.getBkAlphaHtml(); // get the HTML for bookmarked lenses displayed alphabetically } else { // if we are displaying bookmarked lenses by group and we have them cached lensesHtml = displayCurrentLensesCache.getBkGroupedHtml(); // get the HTML for bookmarked lenses displayed by group } $('#divResults').html(lensesHtml); // even though the HTML was cached, the cached is only a string, not elements in the DOM // after we create elements in the DOM, we need to subscribe to events this._subscribeToEventsForLensCards(lensUIUtils._pageURL); } else { // if we need bookmarked lenses and we don't have them cached log(logHdr + 'we need bookmarked lenses and we do NOT have them cached'); log(logHdr + 'creating the HTML for bookmarked lenses'); targetLenses = lensUtils.getLensDTOsToDisplay(); // get the lenses to display targetCount = targetLenses.length; log(logHdr + 'targetCount=' + targetCount); if (byAlpha) { // if we are displaying lenses alphabetically log(logHdr + 'calculating HTML to display bookmarked lenses alphabetically'); lensesHtml = await lensHtmlUtils.getHtmlForLensesByAlphaAsync(targetLenses); // get HTML for the array of lenses // arrange lenses alphabetically, not by group displayCurrentLensesCache.setBkAlphaHtml(lensesHtml); // cache the HTML } else { // otherwise log(logHdr + 'calculating HTML to display bookmarked lenses by group'); lensesHtml = await lensHtmlUtils.getHtmlForLensesByGroupAsync(targetLenses); // get HTML for the array of lenses // arrange lenses by group displayCurrentLensesCache.setBkGroupedHtml(lensesHtml); // cache the HTML } $('#divResults').html(lensesHtml); this._subscribeToEventsForLensCards(lensUIUtils._pageURL); } } log(logHdr + 'leave'); }, setLensDivWidth: function setLensDivWidth(lensId, widthStr) { // set the width attribute of the parent div for the specified lens to the given string // width value can be of the form // 90% // 100px const logHeader = 'lensUIUtils.setLensDivWidth: '; log(logHeader + 'enter'); log(logHeader + 'lensId=' + lensId); log(logHeader + 'widthStr=' + widthStr); const cardElemId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_PREFIX, undefined); // get the id of the card div const cardJQ = $('#' + cardElemId); // get a jQuery object for the card cardJQ.css('width', widthStr); // set the width of the card log(logHeader + 'leave'); }, clearLensDivWidth: function clearLensDivWidth(lensId) { // remove the width attribute of the parent div for the specified lens const logHeader = 'lensUIUtils.clearLensDivWidth: '; log(logHeader + 'enter'); log(logHeader + 'lensId=' + lensId); const cardElemId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_PREFIX, undefined); // get the id of the card div const cardJQ = $('#' + cardElemId); // get a jQuery object for the card cardJQ.css('width', ''); // remove the width log(logHeader + 'leave'); } };