PageSourceSearch

https://cedar.carmel.ac.uk/Static/Lib/ops_jQ/ops_offline.js

js carmel.ac.uk collected 2026-10-04 13:34:21 UTC 5,841 bytes, 210 lines download raw bytes

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.