github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/docs/assets/js/examples.js (about) 1 --- 2 --- 3 $(document).ready(function () { 4 5 const CODE_LINE_HEIGHT = 22 6 const CODE_BLOCK_PADDING = 10 7 8 window.examples = { 9 tags: {}, 10 nav: {} 11 } 12 13 initExamplesNav() 14 15 $(window).resize($.debounce(250, function() { 16 buildExamplesNav() 17 })) 18 19 // Activate first example 20 $('.examples__container').each(function (i, ec) { 21 // Find first element: 22 const firstElementId = $(ec).find('.examples__nav-item').data('id') 23 // Open first element: 24 openExample($(ec).attr('id'), firstElementId) 25 26 // Open example when user clicks on tab 27 $('.navs').on('click', '.examples__nav-item:not(.static-link)', function() { 28 openExample($(ec).attr('id'), $(this).data('id')) 29 $('.navs__dropdown-menu').removeClass('active') 30 }) 31 }) 32 33 // Open example and scroll to examples section when user clicks on 34 // tech in the header 35 $('.link-to-test-with-terratest').on('click', function() { 36 // Find any containting the keyword from data-target 37 const found = $('.navs .examples__nav-item[data-id*="'+$(this).data('target')+'"]') 38 if (found && found.length > 0) { 39 openExample('index_page', $(found[0]).data('id')) 40 } else { 41 // RESCUE: If none found, open any (first available): 42 openExample('index_page', $($('.navs .examples__nav-item')[0]).data('id')) 43 } 44 scrollToTests() 45 }) 46 47 // Switch between code snippets (files) 48 $('.examples__tabs .tab').on('click', function() { 49 $(this).parents('.examples__tabs').find('.tab').removeClass('active') 50 $(this).addClass('active') 51 52 $(this).parents('.examples__block').find('.examples__code').removeClass('active') 53 $($(this).data('target')).addClass('active') 54 55 loadCodeSnippet() 56 }) 57 58 // Open dropdown of technologies to select 59 $('.navs__dropdown-arrow').on('click', function() { 60 $('.navs__dropdown-menu').toggleClass('active') 61 }) 62 63 // Open popup when user click on circle with the number 64 $('.examples__container').on('click', '.code-popup-handler', function() { 65 const isActive = $(this).hasClass('active') 66 $('.code-popup-handler').removeClass('active') 67 if (!isActive) { 68 $(this).addClass('active') 69 } 70 }) 71 72 function scrollToTests() { 73 $([document.documentElement, document.body]).animate({ 74 scrollTop: $('#index-page__test-with-terratest').offset().top 75 }, 500) 76 } 77 78 function openExample(exampleContainerId, target) { 79 // Change active nav in window state and rebuild navigation first 80 const $ecId = $('#'+exampleContainerId) 81 window.examples.nav[exampleContainerId].current = target 82 buildExamplesNav() 83 84 // Change active tab in navigation 85 $ecId.find('.examples__nav-item').removeClass('active') 86 const jTarget = $('.navs .examples__nav-item[data-id="'+target+'"]') 87 jTarget.addClass('active') 88 89 // Change the block below navigation (with code snippets) 90 $ecId.find('.examples__block').removeClass('active') 91 $ecId.find('#example__block-' + target).addClass('active') 92 93 // Set current tab 94 $ecId.find('.examples__nav .navs').removeClass('active') 95 96 loadCodeSnippet() 97 } 98 99 function loadCodeSnippet() { 100 $('.examples__block.active .examples__code.active').each(async function (i, activeCodeSnippet) { 101 const $activeCodeSnippet = $(activeCodeSnippet) 102 const exampleTarget = $(this).data('example') 103 const fileId = $(this).data('target') 104 const snippetId = $(this).data('snippet-id') 105 if (!$activeCodeSnippet.data('loaded')) { 106 try { 107 const response = await fetch($activeCodeSnippet.data('url')) 108 let content = await response.text() 109 $activeCodeSnippet.attr('data-loaded', true) 110 if ($activeCodeSnippet.data('skip-tags')) { 111 // Remove the website::tag::xxx:: prefix from the code snippet 112 content = content.replace(/website::tag::.*?:: ?/mg, '') 113 } else { 114 findTags(content, exampleTarget, fileId) 115 // Remove the website::tag::xxx:: comment entirely from the code snippet 116 content = content.replace(/^.*website::tag.*\n?/mg, '') 117 } 118 // Find the range specified by range-id if specified 119 if (snippetId) { 120 snippet = extractSnippet(content, snippetId) 121 $activeCodeSnippet.find('code').text(snippet) 122 } else { 123 $activeCodeSnippet.find('code').text(content) 124 } 125 126 Prism.highlightAll() 127 } catch(err) { 128 $activeCodeSnippet.find('code').text('Resource could not be loaded.') 129 console.error(err) 130 } 131 } 132 updatePopups() 133 openPopup(exampleTarget, 1) 134 }) 135 } 136 137 function extractSnippet(content, snippetId) { 138 // Split the content into an array of lines 139 lines = content.split('\n') 140 // Search the array for "snippet-tag-start::{id}" - save location 141 const startLine = searchTagInLines(`snippet-tag-start::${snippetId}`, lines) 142 // Search the array for "snippet-tag-end::{id}" - save location 143 const endLine = searchTagInLines(`snippet-tag-end::${snippetId}`, lines) 144 145 // If you have both a start and end, slice as below 146 if (startLine >= 0 && endLine >= 0) { 147 const range = lines.slice(startLine + 2, endLine) 148 return range.join('\n') 149 } else { 150 console.error('Could not find specified range.') 151 return content 152 } 153 } 154 155 function searchTagInLines (tagRegExp, lines) { 156 return lines.findIndex(line => line.match(tagRegExp)) 157 } 158 159 function findTags(content, exampleTarget, fileId) { 160 let tags = [] 161 let regexpTags = /website::tag::(\d)::\s*(.*)/mg 162 let match = regexpTags.exec(content) 163 do { 164 if (match && match.length > 0) { 165 tags.push({ 166 text: match[2], 167 tag: match[0], 168 step: match[1], 169 line: findLineNumber(content, match[0]) 170 }) 171 } 172 } while((match = regexpTags.exec(content)) !== null) 173 window.examples.tags[exampleTarget] = Object.assign({ 174 [fileId]: tags 175 }, 176 window.examples.tags[exampleTarget] 177 ) 178 } 179 180 function findLineNumber(content, text) { 181 let tagIndex = content.indexOf(text) 182 let tempString = content.substring(0, tagIndex) 183 let lineNumber = tempString.split('\n').length 184 return lineNumber 185 } 186 187 function updatePopups() { 188 $('.code-popup-handler').remove() 189 const activeCode = $('.examples__block.active .examples__code.active') 190 const exampleTarget = activeCode.data('example') 191 const fileId = activeCode.data('target') 192 const exampleTargetTags = window.examples.tags[exampleTarget] || {}; 193 const fileTags = exampleTargetTags[fileId]; 194 195 if (fileTags) { 196 const tagsLen = fileTags.length 197 198 fileTags.map( function(v,k) { 199 const top = (CODE_LINE_HEIGHT * (v.line - k)) + CODE_BLOCK_PADDING; 200 201 // If two pop-ups are close to each other, add CSS class that will scale them down 202 let scaleClass = '' 203 if ( 204 (k > 0 && Math.abs(v.line - fileTags[k-1].line) < 3 ) 205 || (k < tagsLen - 1 && Math.abs(v.line - fileTags[k+1].line) < 3 ) 206 ) { 207 scaleClass = 'sm-scale' 208 } 209 210 const elToAppend = 211 '<div class="code-popup-handler '+scaleClass+'" style="top: '+top+'px" data-step="'+v.step+'">' + 212 '<span class="number">' + v.step + '</span>' + 213 '<div class="shadow-bg-1"></div><div class="shadow-bg-2"></div>' + 214 '<div class="popup">' + 215 '<div class="left-border"></div>' + 216 '<div class="content">' + 217 '<p class="text">' + v.text + '</p>' + 218 '</div>' + 219 '</div>' 220 const code = $("#example__code-"+exampleTarget+"-"+fileId) 221 code.append(elToAppend) 222 }) 223 } 224 225 openPopup(exampleTarget, 0) 226 } 227 228 function openPopup(techName, step) { 229 $('.code-popup-handler').removeClass('active') 230 $('#example__block-'+techName).find('.code-popup-handler[data-step="'+step+'"]').addClass('active') 231 } 232 233 function loadExampleDescription(name) { 234 return $('#index-page__examples').find('#example__block-'+name+' .description').html() 235 } 236 237 function initExamplesNav() { 238 window.examples.nav = {} 239 $('.examples__container').each(function(eci, ec) { 240 $(ec).find('.examples__nav .hidden-navs').each(function(rni, refNavs) { 241 let navsArr = [] 242 let currentNav 243 $(refNavs).find('.examples__nav-item').each( function(ni, nav) { 244 if ($(nav).hasClass('active')) { 245 currentNav = $(nav).data('id') 246 } 247 navsArr.push($(nav)) 248 }) 249 window.examples.nav = Object.assign({ 250 [$(ec).attr('id')]: { 251 current: currentNav, 252 items: navsArr 253 } 254 }, window.examples.nav) 255 }) 256 }) 257 } 258 259 function buildExamplesNav() { 260 $('.examples__container').each(function(eci, ec) { 261 const ecId = $(ec).attr('id') 262 const containerWidth = $(ec).width() 263 const NAV_WIDTH = 150 264 const ARROW_SLOT_WIDTH = 100 265 266 const noOfVisible = Math.floor((containerWidth - NAV_WIDTH - ARROW_SLOT_WIDTH) / 150) 267 268 const $visibleBar = $($(ec).find('.navs__visible-bar')) 269 const $dropdownInput = $($(ec).find('.navs__dropdown-input')) 270 const $dropdownMenu = $($(ec).find('.navs__dropdown-menu')) 271 272 $visibleBar.html('') 273 $dropdownInput.html('') 274 $dropdownMenu.html('') 275 276 let settingCurrent = false 277 278 // Build initial a navigation bar 279 if (window.examples.nav 280 && ecId in window.examples.nav 281 && window.examples.nav[ecId].items) { 282 283 // Visible elements 284 let breakSlice = noOfVisible > window.examples.nav[ecId].items.length ? window.examples.nav[ecId].items.length : noOfVisible 285 let visibleEls = window.examples.nav[ecId].items.slice(0, breakSlice) 286 let hiddenEls = window.examples.nav[ecId].items.slice(breakSlice, window.examples.nav[ecId].items.length) 287 288 let visibleNavIsActive = false 289 let hiddenNavIsActive = -1 290 291 if (window.examples.nav[ecId].current) { 292 visibleEls.map( function(x,i) { 293 if(x.data('id') === window.examples.nav[ecId].current) { 294 visibleNavIsActive = true 295 x.addClass('active') 296 } 297 }) 298 hiddenEls.map( function(x,i) { 299 if(x.data('id') === window.examples.nav[ecId].current) { 300 hiddenNavIsActive = i 301 x.addClass('active') 302 } 303 }) 304 } 305 306 visibleEls.map(function(nav,i) { 307 $visibleBar.append($(nav).clone()) 308 }) 309 310 if (hiddenNavIsActive > -1) { 311 const sliced = hiddenEls.splice(hiddenNavIsActive, 1) 312 $dropdownInput.append($(sliced[0]).clone()) 313 } else { 314 $dropdownInput.append($(hiddenEls.shift()).clone()) 315 } 316 317 hiddenEls.map(function(nav,i) { 318 $dropdownMenu.append($(nav).clone()) 319 }) 320 321 // Add static links 322 $dropdownMenu.append($(ec).find('.hidden-navs__static-links').html()) 323 } 324 }) 325 } 326 327 })