var lensHtmlUtils = { showTabsOrNot: function showTabsOrNot() { const logHdr = 'showTabsOrNot: '; log(logHdr + 'enter'); log(logHdr + 'viewWidth=' + viewWidth); const showTabs = (viewWidth > 375); // if the view is wide enough to show tabs in the lens cards log(logHdr + 'showTabs=' + showTabs); log(logHdr + 'leave'); return showTabs; }, _getHtmlForLensCardWithTabsAsync: async function _getHtmlForLensCardWithTabs(lens, expanded, explicitWidthStr) { // this function returns HTML for a lens card with 4 tabs: // When, How, Examples, Video // // expanded: true if we should create the card in expanded mode // explicitWidthStr: undefined or empty string: do nothing // otherwise, this string is a CSS width value for the lens card div // for example: // 600px // 90% const logHdr = '_getHtmlForLensCardWithTabsAsync: '; log(logHdr + 'enter'); log(logHdr + 'lens name=' + lens.LensName); log(logHdr + 'expanded=' + expanded); log(logHdr + 'explicitWidthStr=' + explicitWidthStr); var widthStr = explicitWidthStr; if (typeof widthStr === "undefined") { widthStr = ''; } if (widthStr === null) widthStr = ''; // lens: a lens DTO // expanded: if true, show the card in expanded mode, with tabs revealed // otherwise, show card in collpased mode, with tabs hidden. // NOTE: we could use // '
' + lens.LensName + '
' // for a large card title at the top of the card var lensId = lens.LensId; log(logHdr + 'lensId=' + lensId); const bookmarked = bookmarkStorageUtils.isLensBookmarked(lensId); log(logHdr + 'bookmarked=' + bookmarked); const descrHtml = lens.DescriptionHtml; log(logHdr + 'descrHtml=' + descrHtml); var styleStr = ''; if (widthStr.length > 0) { styleStr = ' style="width: ' + widthStr + '" '; } var aWhen = ''; var aHow = ''; var aExamples = ''; var aVideo = ''; // clear var divWhen = ''; var divHow = ''; var divExamples = ''; var divVideo = ''; // clear const selTab = selectedTabUtils.getSelectedTab(lensId); // get the name of the selected tab, or empty string if none selected log(logHdr + 'selTab=' + selTab); switch (selTab) { case '': aWhen = 'active'; divWhen = 'active show'; break; case 'when': aWhen = 'active'; divWhen = 'active show'; break; case 'how': aHow = 'active'; divHow = 'active show'; break; case 'examples': aExamples = 'active'; divExamples = 'active show'; break; case 'video': aVideo = 'active'; divVideo = 'active show'; break; } const cardId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_PREFIX, undefined); // get the id of the card div // this div itself doesn't show/hide, so the third parameter is undefined var lensHtml = '
'; const cardHdrId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_HEADER_PREFIX, undefined); lensHtml += '
'; const nameSpanId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_LENS_NAME_PREFIX, undefined); lensHtml += '' + lens.LensName + ''; const btnId = elemIdUtils.getElemId(lensId, elemIdUtils.BUTTON_CLOSE_CARD_HEADER_PREFIX, expanded); lensHtml += ''; const showBk = bookmarkUIUtils.showBookmarks(); // should we show bookmark icons? log('getHtmlForLensCard: showBk=' + showBk); if (showBk) { // if we should show bookmarks var wImgPath = ''; var bkClass = ''; if (viewWide) { // if the user is using a wider screen, we show smaller bookmarks bkClass = 'bk-sm'; if (bookmarked) { // if the lens is bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkfilled-sm.png'); } else { // if the lens is not bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkempty-sm.png'); } } else { // if the user is on a smaller screen, we show larger bookmarks bkClass = 'bk-lg'; if (bookmarked) { // if the lens is bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkfilled.png'); } else { // if the lens is not bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkempty.png'); } } const imgBkId = elemIdUtils.getElemId(lensId, elemIdUtils.IMAGE_BOOKMARK_PREFIX, expanded); lensHtml += ''; // add the bookmark image to the lens markup } lensHtml += '
'; lensHtml += '
'; const spanId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_LENS_NAME_PREFIX, undefined); const pDescr = descrHtml.replace('' + pDescr; lensHtml += '   '; var moreStyle = ''; var lessStyle = ''; if (expanded) { // if the caller wants the card created in expanded mode moreStyle = ' style="display: none;"'; // mode is already more, so hide the more link lessStyle = ''; } else { // if the caller wants the card created in collapsed mode moreStyle = ''; lessStyle = ' style="display: none;"'; // mode is already less, so hide the less link } const spanMoreId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_MORE_PREFIX, undefined); const spanLessId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_LESS_PREFIX, undefined); // the "more..." link which allows the user to expand the card // NOTE: s-more-tabs is the class for "more" links in cards with tabs // NOTE: s-less-tabs is the class for "less" links in cards with tabs lensHtml += ' '; lensHtml += 'more...'; lensHtml += ''; // the "less..." link which allows the user to collapse the card lensHtml += ' '; lensHtml += 'less...'; lensHtml += ''; lensHtml += '

'; var displayStyle = 'display: none;'; if (expanded) { // if the caller wants the tabs displayed displayStyle = 'display: block;'; } const collapseId = elemIdUtils.getElemId(lensId, elemIdUtils.COLLAPSE_TABS_PREFIX, undefined); // while the tabs do show/hide, there is a max of one set of tabs per card // so the expanded flag is undefined lensHtml += '
'; const cardTabId = elemIdUtils.getElemId(lensId, elemIdUtils.LIST_PREFIX, expanded); // this code uses Bootstrap and
    /
  • elements to display the tabs lensHtml += ''; const tcId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_TAB_CONTENT_PREFIX, undefined); lensHtml += '
    '; lensHtml += '
    ' + lens.WhenToUse + '
    '; lensHtml += '
    ' + lens.HowToUse + '
    '; const lensExamples = lensExampleUtils.getExamplesForLens(lensId); const exCount = lensExamples.length; log(logHdr + 'exCount=' + exCount); var examplesHtml = ''; for (var zIndex = 0; zIndex < exCount; zIndex++) { // once for each example var lensExample = lensExamples[zIndex]; var exTitle = lensExample.Name; var exText = lensExample.Text; var exTitleHtml = '
    ' + exTitle + '
    ' var exTextHtml = '
    ' + exText + '
    ' examplesHtml += exTitleHtml; examplesHtml += exTextHtml; // append example title and text to the HTML } lensHtml += '
    ' + examplesHtml + '
    '; lensHtml += '
    '; // this is where we append the video element // TAB_PANE_VIDEO_PREFIX if (aVideo.length > 0) { // if the Video tab will be selected, we need to add the video element now const videoType = videoUtils.getVideoType(lensId); // what is the video type for this lens? log(logHdr + 'videoType=' + videoType); log(logHdr + 'we need to add the video element'); const videoElemSize = videoUtils.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); 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(logHdr + 'computed the HTML 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 + 'computed the HTML for the iFrame video element'); } log('videoHTML=' + videoHTML); lensHtml += videoHTML; // add it to the markup // NOTE: code elsewhere will have to subscribe to video events for this video element } lensHtml += '
    '; lensHtml += '
    '; // add markup for the tabs lensHtml += '
'; // card-body lensHtml += '
'; // card-hdr lensHtml += '
'; // card log(logHdr + ' leave'); return lensHtml; }, _getHtmlForLensCardNoTabs: function _getHtmlForLensCardNoTabs(lens, videoBtn, explicitWidthStr) { // this function returns HTML for a lens card without tabs. // instead of tabs, the HTML returned by this function contains 4 sections: // When, How, Examples, Video // separated by section headers, which are simply text captions. // // lens: a lens DTO // videoBtn: if true, add a button the user can click to load the video. // if false, add the video element // explicitWidthStr: undefined or empty string: do nothing // otherwise, this string is a CSS width value for the lens card div // for example: // 600px // 90% // NOTE: as of 2/27/20 we hard-code to not show the Load Video button // All videos are loaded. // We plan on moving to all streaming (Vimeo) videos soon. const logHeader = '_getHtmlForLensCardNoTabs: '; log(logHeader + 'enter'); log(logHeader + 'lens name=' + lens.LensName); log(logHeader + 'videoBtn=' + videoBtn + ' (IGNORED for now)'); log(logHeader + 'explicitWidthStr=' + explicitWidthStr); var widthStr = explicitWidthStr; if (typeof widthStr === "undefined") { widthStr = ''; } if (widthStr === null) widthStr = ''; var lensId = lens.LensId; log(logHeader + 'lensId=' + lensId); const bookmarked = bookmarkStorageUtils.isLensBookmarked(lensId); log(logHeader + 'bookmarked=' + bookmarked); const descrHtml = lens.DescriptionHtml; log(logHeader + 'descrHtml=' + descrHtml); var styleStr = ''; if (widthStr.length > 0) { styleStr = ' style="width: ' + widthStr + '" '; } const cardId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_PREFIX, undefined); // get an id for the card // don't pass the expanded flag // the card has expandable contents but the card div itself is not expandable var lensHtml = '
'; const cardHdrId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_HEADER_PREFIX, undefined); lensHtml += '
'; const nameSpanId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_LENS_NAME_PREFIX, undefined); lensHtml += '' + lens.LensName + ''; const btnId = elemIdUtils.getElemId(lensId, elemIdUtils.BUTTON_CLOSE_CARD_HEADER_PREFIX, undefined); lensHtml += ''; const showBk = bookmarkUIUtils.showBookmarks(); // should we show bookmark icons? log('getHtmlForLensCard: showBk=' + showBk); if (showBk) { // if we should show bookmarks var wImgPath = ''; var bkClass = ''; if (viewWide) { // if the user is using a wider screen, we show smaller bookmarks bkClass = 'bk-sm'; if (bookmarked) { // if the lens is bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkfilled-sm.png'); } else { // if the lens is not bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkempty-sm.png'); } } else { // if the user is on a smaller screen, we show larger bookmarks bkClass = 'bk-lg'; if (bookmarked) { // if the lens is bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkfilled.png'); } else { // if the lens is not bookmarked wImgPath = urlUtils.getUrl('/images/bookmarkempty.png'); } } const imgId = elemIdUtils.getElemId(lensId, elemIdUtils.IMAGE_BOOKMARK_PREFIX, undefined); lensHtml += ''; // add the bookmark image to the lens markup } lensHtml += '
'; // #cardHdr lensHtml += '
'; const lensNameSpanId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_LENS_NAME_PREFIX, undefined); const pDescr = descrHtml.replace('' + pDescr + '

'; // NOTE: at this point in the code, we create two sets of content: collapsed and expanded var expHtml = ''; // the HTML for the expanded contents if (true) { // create the code for the expanded content const eContentId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_TEXT_PREFIX, true); expHtml += '
'; expHtml += '
When to Use
'; const eWhenId = elemIdUtils.getElemId(lensId, elemIdUtils.WHEN_CONTENT_PREFIX, true); expHtml += '
' + lens.WhenToUse + '
'; expHtml += '
How to Use
'; const eHowId = elemIdUtils.getElemId(lensId, elemIdUtils.HOW_CONTENT_PREFIX, true); expHtml += '
' + lens.HowToUse + '
'; expHtml += '
Examples
'; const lensExamples = lensExampleUtils.getExamplesForLens(lensId); const exCount = lensExamples.length; log(logHeader + 'exCount=' + exCount); var examplesHtml = ''; for (var zIndex = 0; zIndex < exCount; zIndex++) { // once for each example var lensExample = lensExamples[zIndex]; var exTitle = lensExample.Name; var exText = lensExample.Text; var exTitleHtml = '
' + exTitle + '
'; var exTextHtml = '
' + exText + '
'; examplesHtml += exTitleHtml; examplesHtml += exTextHtml; // append example title and text to the HTML } const eExId = elemIdUtils.getElemId(lensId, elemIdUtils.EXAMPLES_CONTENT_PREFIX, true); expHtml += '
' + examplesHtml + '
'; expHtml += '
Video
'; const eVideoId = elemIdUtils.getElemId(lensId, elemIdUtils.VIDEO_CONTENT_PREFIX, true); expHtml += '
'; // NOTE: for now, we don't show the Load Video button //if (videoBtn) { // log(logHeader + 'add the "Load Video" button'); // const eBtnLoadVideoId = elemIdUtils.getElemId(lensId, elemIdUtils.BUTTON_LOAD_VIDEO_PREFIX, undefined); // log(logHeader + 'eBtnLoadVideoId=' + eBtnLoadVideoId); // const buttonHTML = ''; // expHtml += buttonHTML; //} log(logHeader + 'add the video markup to the HTML'); var videoElemSize = lensUIUtils._getVideoElemSize(viewWidth, viewHeight); // get the desired size of the video element given the view dimensions var videoElemWidth = videoElemSize.width; var videoElemHeight = videoElemSize.height; const videoType = videoUtils.getVideoType(lensId); // what type of video will we create? log(logHeader + 'videoType=' + videoType); var videoHtml = ''; var videoUrl = ''; var videoElemId; videoElemId = elemIdUtils.getVideoElemId(lensId); // get the id of the video element log(logHeader + 'videoElemId=' + videoElemId); if (videoType === videoUtils.VIDEO_TYPE_BLOB) { // if blob video videoUrl = videoUtils.getVideoUrl(lensId); // get the URL of the blob videoHTML = videoUtils.getVideoHtml_video(lensId, videoElemWidth, videoElemHeight, videoUrl); // get html for the video } else { // if Vimeo video videoUrl = videoUtils.getIFrameUrl(lensId); // get the URL of the iFrame source videoHTML = videoUtils.getVideoHtml_iFrame(lensId, videoElemWidth, videoElemHeight, videoUrl); // get html for the Vimeo video in an iFrame } expHtml += videoHTML; // add the video HTML to the markup expHtml += '
'; // #videoContent const spanLessId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_LESS_PREFIX, true); // the "less..." link which allows the user to collapse the card // NOTE: s-less is the class for "less" links in cards without tabs expHtml += ' '; expHtml += 'less...'; expHtml += ''; expHtml += '
'; // #cardContent } const expElemId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_EXPANDED_CONTENT_PREFIX, undefined); const expanded = noTabsCardExpStorageUtils.isCardExpanded(lensId); // is this no tabs card expanded? log(logHeader + 'expanded=' + expanded); var expStyle = ''; if (!expanded) { // if the current card is not expanded expStyle = ' style="display: none;" '; } lensHtml += '
' + expHtml + '
'; // add the expanded contents inside a div to the lens HTML var collHtml = ''; // the HTML for the collapsed contents if (true) { // add the collapsed content here var whenIntro = lens.WhenToUse; // default to the full when text const periodIndex = whenIntro.indexOf('.'); // find the first period if (periodIndex >= 0) { // if we found one whenIntro = whenIntro.substr(0, periodIndex + 1); // get the first sentence of the when text } const eContentIdC = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_TEXT_PREFIX, false); collHtml += '
'; collHtml += '
When to Use
'; const eWhenIdC = elemIdUtils.getElemId(lensId, elemIdUtils.WHEN_CONTENT_PREFIX, false); collHtml += '
' + whenIntro + '
'; const spanMoreId = elemIdUtils.getElemId(lensId, elemIdUtils.SPAN_MORE_PREFIX, false); // the "more..." link which allows the user to expand the card // NOTE: s-more is the class for "more" links in cards without tabs collHtml += ' '; collHtml += 'more...'; collHtml += ''; collHtml += '
'; } const collElemId = elemIdUtils.getElemId(lensId, elemIdUtils.CARD_COLLAPSED_CONTENT_PREFIX, undefined); var collStyle = ''; if (expanded) { // if the current card is expanded collStyle = ' style="display: none;" '; } lensHtml += '
' + collHtml + '
'; // add the collapsed contents inside a div to the lens HTML lensHtml += '
'; // .card-body lensHtml += '
'; // #card log(logHeader + ' leave'); return lensHtml; }, getHtmlForLensCardAsync: async function getHtmlForLensCardAsync(lens, showTabs, expanded, cardIndex, explicitWidthStr) { // showTabs: true => create the card with tabs // false => create the cards with all info (when, how, etc.) visible, with headers and content in each section // expanded: true => create the card in expanded mode // false => created the card in collapsed mode // cardIndex: zero-based index to the card on the web page // explicitWidthStr: undefined or empty string: do nothing // otherwise, this string is a CSS width value for the lens card div // for example: // 600px // 90% const logHdr = 'getHtmlForLensCardAsync: '; log(logHdr + 'enter'); log(logHdr + 'lens name=' + lens.LensName); log(logHdr + 'showTabs=' + showTabs); log(logHdr + 'expanded=' + expanded); log(logHdr + 'cardIndex=' + cardIndex); log(logHdr + 'explicitWidthStr=' + explicitWidthStr); var lensHtml = ''; if (showTabs) { // if we should show tabs lensHtml = await lensHtmlUtils._getHtmlForLensCardWithTabsAsync(lens, expanded, explicitWidthStr); // get HTML for the lens, with tabs } else { // if no tabs // NOTE: on iOS, if we add