1/** 2 * linksBox targets the UL element designed to contain offline page links 3 * @type {*|jQuery|HTMLElement} 4 */ 5const linksBox = $( 'body.offline ul' ) ; 6 7/** 8 * offlineLocations: Store locations and URLs to these locations we wish to 9 * show the user when offline. These links will not show if the page is not cached. 10 * @type {*[]} 11 */ 12const offlineLocations = [ 13 { 14 urls: [ "/home/dashboard", "/home" , "/ilp" ] , 15 label: "CEDAR Dashboard" 16 } , 17 18 /* Student/Parent pages */ 19 20 { 21 urls: [ "/ilp/details/QRCode" ] , 22 label: "Your QR Code" 23 } , 24 { 25 urls: [ "/ilp/markbook" ] , 26 label: "Markbook Summary" 27 } , 28 { 29 urls: [ "/ilp/markbook/btec" ] , 30 label: "BTEC Summary" 31 } , 32 { 33 urls: [ "/ilp/exams/timetable" ] , 34 label: "Exam Timetable" 35 } , 36 { 37 urls: [ "/ilp/exams/mocktimetable" ] , 38 label: "Other Exams Timetable" 39 } , 40 { 41 urls: [ "/ilp/exam/results" ] , 42 label: "Exams Results" 43 } , 44 { 45 urls: [ "/ilp/learningplan" ] , 46 label: "Learning Plan" 47 } , 48 { 49 urls: [ "/ilp/timetable" ] , 50 label: "Student Timetable" 51 } , 52 53 /* Staff pages */ 54 55 { 56 urls: [ "/home/my/timetable" ] , 57 label: "Lesson Timetable" 58 } , 59 { 60 urls: [ "/home/notepad" ] , 61 label: "Notepad" 62 } 63] ; 64 65// Prevent animations kicking off immediately to initial positions 66setTimeout( () => $('body').addClass( 'loaded' ), 250 ); 67 68// Setup the timer to check for our connection status every few seconds 69setInterval( () => checkConnection() , 5000 ) ; 70 71// Kick off the offline links population, filling in links only if we have them cached 72populateOfflineLinks() ; 73 74// If the user taps/clicks CEDAR, we attempt the current location again 75$('#offline-logo-badge').on( 'mousedown', function(){ 76 77 location.reload() ; 78 79 if( $(this).hasClass('reloading') ) { 80 $(this).removeClass( 'tapped' ) ; 81 $(this).removeClass( 'reloading' ) ; 82 } else { 83 $(this).addClass( 'tapped' ) ; 84 $(this).addClass('reloading'); 85 } 86 87}) 88 89/** 90 * Check the connection. If online, show the online message. Else, show the offline message. 91 * The logo will animate to feedback an attempt to connect, and change colour when connected. 92 */ 93function checkConnection() { 94 // If offline, flip the logo every few seconds 95 var badge = $('#offline-logo-badge') ; 96 var offlineMsg = $( '#message-offline' ) ; 97 var onlineMsg = $( '#message-online' ) ; 98 99 var slideOptions = { 100 duration: 1000 , 101 easing: 'easeOutCubic' 102 } ; 103 104 if( navigator.onLine ) { 105 badge.addClass( 'online' ) ; 106 onlineMsg.slideDown( slideOptions ) ; 107 offlineMsg.slideUp( slideOptions ) ; 108 109 } else { 110 badge.removeClass( 'online' ) ; 111 badge.addClass( 'check' ) ; 112 113 offlineMsg.slideDown( slideOptions ) ; 114 onlineMsg.slideUp( slideOptions ) ; 115 116 setTimeout( function(){ 117 flipOfflineLogo() ; 118 }, 500 ) ; 119 } 120} 121 122/** 123 * Spin the logo when attempting a connection. Spin it back pretty soon after 124 * to indicate a block in connection. 125 */ 126function flipOfflineLogo() { 127 var logo = $('#offline-logo') ; 128 var badge = $('#offline-logo-badge') ; 129 130 logo.addClass( 'flip' ) ; 131 132 setTimeout(function(){ 133 badge.removeClass( 'check' ) ; 134 },500); 135 136 setTimeout(function(){ 137 logo.removeClass( 'flip' ) ; 138 },1000); 139} 140 141/** 142 * populateOfflineLinks 143 */ 144function populateOfflineLinks() { 145 if( !caches ){ 146 return ; 147 } 148 149 for( var item in offlineLocations ) { 150 var offlineLocation = offlineLocations[ item ] ; 151 152 // Iterate over the offline locations url collection 153 // and check for presence in the cache 154 searchCache( offlineLocation ) 155 .then( provideLink ) 156 .catch( err => err ) 157 ; 158 } 159} 160 161/** 162 * searchCache accepts a location object and matches on the first URL in its urls collection. 163 * On matching, the cached resource will be added to the location as a 'resource' property value 164 * and returned. 165 * @param location 166 * @returns {Promise<any>} 167 */ 168function searchCache( location ){
169 return new Promise( (resolve, reject)=>{ 170 for( var i = 0; i < location.urls.length; i++ ) { 171 caches.match( location.urls[ i ] ) 172 .then( res => { 173 location.resource = res ; 174 resolve( location ) ; 175 }) ; 176 return ; 177 } 178 reject( new Error( 'No URLs matching ' + location.label ) ) ; 179 }) ; 180} 181 182/** 183 * provideLink accepts a location object, generating a link from the resources full URL 184 * and using the label from the location.label property. The link is added to the cached pages list. 185 * @param location 186 * @returns {Promise<any>} 187 */ 188function provideLink( location ) { 189 return new Promise( (resolve)=>{ 190 if( location.resource ) { 191 192 // Generate link ID 193 var id = linksBox.find( 'li').length ; 194 195 $( '#offline-pages-intro' ).parent().parent().fadeIn() ; 196 197 var liStyle = 'display:none' ; 198 var liScript = '$("#linkScript_' + id + '").parent().fadeIn() ;' ; 199 200 var li = '<li style="' + liStyle + '">' 201 + '<a class="action" href="' + location.resource.url + '">' 202 + location.label + '</a>' 203 + '<script id="linkScript_' + id + '">' + liScript + '</script>' 204 + '</li>' ; 205 206 linksBox.append(li); 207 resolve(location); 208 } 209 }) ; 210}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.