PageSourceSearch

https://www.toronto.ca/cot/script.js?ver=1.0.0

js toronto.ca collected 2026-09-24 07:02:11 UTC 9,334 bytes, 263 lines download raw bytes

1// Fix galleries
2
3jQuery(document).ready(function($) {
4
5  // Check if required CSS and JS assets exist in the DOM
6  const hasStylesheet = document.getElementById('cot-gallery-style-css') !== null;
7  const hasScript = document.getElementById('cot-gallery-js-js') !== null;
8
9  function addStylesheet(id, href, version = '6.8.2', media = 'all') {
10
11    // Check if stylesheet already exists
12
13    if ( hasStylesheet ) return
14
15    const link = document.createElement('link');
16    link.id = id;
17    link.rel = 'stylesheet';
18    link.href = href + '?ver=' + version;
19    link.media = media;
20    document.head.appendChild(link);
21
22  }
23    
24  function addScript(id, src, version = '6.8.2') {
25      
26    // Check if script already exists
27    if ( hasScript ) return
28
29    const script = document.createElement('script');
30    script.id = id;
31    script.src = src + '?ver=' + version;
32    document.body.appendChild(script);
33
34    script.onload = function() {
35
36        $('.cotImageGallery').each(function() {
37            if (typeof window.CotImageGallery === 'function') {
38
39                const imagesConfig = this.id.replace('cotImageGallery_', 'imagesgalleryJSON_');
40                let galleryConfig = {
41                    'id': this.id,
42                    'title': 'Image Gallery - Photo Gallery ',
43                    'images': window[imagesConfig],
44                    'url': ''
45                }
46                new window.CotImageGallery( galleryConfig );
47            }
48        });
49
50    }
51
52  }
53    
54  // Only add assets if .cotImageGallery element exists on the page
55  if ($('.cotImageGallery').length > 0) {
56    addStylesheet(
57      'cot-gallery-style-css',
58      'https://www.toronto.ca/resources/cot_imagegallery/cotimagegallery.css'
59    );
60    
61    addScript(
62      'cot-gallery-js-js',
63      'https://www.toronto.ca/resources/cot_imagegallery/cotimagegallery.js'
64    );
65  }
66
67
68  function extractQuotedValue(str, quoteStartIndex) {
69    // quoteStartIndex points to the opening quote char (either ' or ")
70    const quote = str[quoteStartIndex];
71    let i = quoteStartIndex + 1;
72    let out = '';
73    let escaped = false;
74    while (i < str.length) {
75      const ch = str[i];
76      if (escaped) {
77        out += ch;
78        escaped = false;
79      } else if (ch === '\\') {
80        escaped = true;
81      } else if (ch === quote) {
82        return { value: out, endIndex: i };
83      } else {
84        out += ch;
85      }
86      i++;
87    }
88    return null; // unterminated string
89  }
90
91  $('.cotImageGallery').each(function (index, el) {
92
93    const $el = $(el);
94    const oldScript = $el.next('script')[0];
95    const galleryId = el.id || ('cotImageGallery_' + index);
96    const imagesConfig = galleryId.replace('cotImageGallery_', 'imagesgalleryJSON_');
97
98    // Default title if none found
99    let titleValue = 'Image Gallery - Photo Gallery';
100    let imagesJsonData = '[]'; // Default empty array
101
102    if (oldScript && oldScript.textContent) {
103      const txt = oldScript.textContent;
104      
105      // Extract the imagesgalleryJSON_ variable declaration
106      const jsonVarMatch = txt.match(new RegExp(`var\\s+${imagesConfig}\\s*=\\s*(\\[.*?\\]);`, 's'));
107      if (jsonVarMatch) {
108        try {
109          // Parse the JSON data to escape alt and caption properties
110          const parsedData = JSON.parse(jsonVarMatch[1]);
111          
112          // Process each image object to escape alt and caption
113          const processedData = parsedData.map(image => {
114            if (image.alt && typeof image.alt === 'string') {
115              // Escape single quotes and backslashes in alt text
116              //image.alt = image.alt.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
117              image.alt = image.alt.replace(/&amp;/g, "&'");
118            }
119            if (image.caption && typeof image.caption === 'string') {
120              // Escape single quotes and backslashes in caption text
121              //image.caption = image.caption.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
122              image.caption = image.caption.replace(/&amp;/g, "&'");
123            }
124            return image;
125          });
126          
127          imagesJsonData = JSON.stringify(processedData);
128        } catch (e) {
129          // If parsing fails, use original data
130          imagesJsonData = jsonVarMatch[1];
131        }
132      }
133      
134      // Find "title" key (with either single or double quotes)
135      const keyMatch = txt.match(/['"]title['"]\s*:/);
136      if (keyMatch) {
137        // position of colon after the key
138        const colonIndex = txt.indexOf(':', keyMatch.index + keyMatch[0].length - 1);
139        if (colonIndex !== -1) {
140          // skip whitespace to find opening quote
141          let i = colonIndex + 1;
142          while (i < txt.length && /\s/.test(txt[i])) i++;
143          if (i < txt.length && (txt[i] === '\'' || txt[i] === '"')) {
144            const extracted = extractQuotedValue(txt, i);
145            if (extracted) {
146              titleValue = extracted.value;
147            }
148          } else {
149            // title may be unquoted (rare). Attempt to read until comma/})
150            const m = txt.slice(i).match(/([^\r\n,}]+)/);
151            if (m) {
152              titleValue = m[1].trim().replace(/[,}]+$/, '').trim();
153            }
154          }
155        }
156      }
157    }
158
159    // Use JSON.stringify to safely produce a JS string literal (includes surrounding quotes)
160    const safeTitleLiteral = JSON.stringify(titleValue);
161
162    // Build new script content including the JSON data variable
163    const scriptContent = (
164      `var ${imagesConfig} = ${imagesJsonData};
165      window.addEventListener('DOMContentLoaded', function(){
166        try {
167          var ${galleryId} = new CotImageGallery({
168            id: '${galleryId}',
169            autorefresh: false,
170            title: ${safeTitleLiteral},
171            images: ${imagesConfig},
172            url: ''
173          });
174        } catch (e) {
175          console && console.error && console.error('Failed to init CotImageGallery for ${galleryId}:', e);
176        }
177      });`
178    );
179
180    // Create new script and replace
181    const newScript = document.createElement('script');
182    newScript.textContent = scriptContent;
183
184    if (oldScript && oldScript.parentNode) {
185      oldScript.parentNode.replaceChild(newScript, oldScript);
186    } else {
187      // append near the element if no old script found
188      $el.after(newScript);
189    }
190
191    // Optionally initialize immediately if CotImageGallery constructor is already available
192    if (typeof window.CotImageGallery === 'function') {
193      try {
194        new window.CotImageGallery({
195          id: galleryId,
196          title: titleValue,
197          images: window[imagesConfig],
198          url: ''
199        });
200      } catch (e) {
201        /* ignore init error; script will run on DOMContentLoaded */
202      }
203    }
204  });
205    
206});
207
208// Add top bar for older versions
209
210jQuery( document ).ready( function( $ ) {
211
212if ( !$( 'body' ).hasClass( 'cot-ver-v1-5-0a' ) ) return;
213
214// Top Bar - Added by Kevin
215
216const addContact311 = () => {
217
218    if (  jQuery( 'body' ).hasClass( 'event-template' )  ) return false;
219
220    $( '#top-bar' ).append( '<div class="top-bar--contact-311"><a href="/311" data-wt_params="WT.link_type=calltoaction">Contact 311</a></div>' )
221    
222    setTimeout( function() {
223    
224        $( '#main-nav > ul > li.menu-list-item:last-of-type .dropdown a:first-of-type' ).attr( 'data-wt_params', 'WT.link_type=calltoaction' )
225    
226        $( '#main-nav > ul > li.menu-list-item:last-of-type button' ).removeAttr( 'aria-expanded' ).text( 'Contact 311' ).click( (event) => {
227    
228            event.stopPropagation()
229        
230            const dropdown = $( event.target ).parent().next()
231            
232            $( 'a:first-of-type', dropdown )[0].click()
233            
234        })
235        
236    }, 1000 )
237
238}
239
240addContact311();
241
242})
243
244setTimeout( function() {
245    if ( $( 'body' ).hasClass( 'event-template' ) ) {
246        const excludedPageIDs = [ 1005453, 946390 ];
247        const isExcluded = excludedPageIDs.some( id => $( 'body' ).hasClass( 'page-id-' + id ) );
248
249        if ( !isExcluded ) {
250            const jqueryScript = $( 'script[src*="/wp-content/themes/cot/js/jquery-2.2.4.min.js"]' );
251            const newJqueryScript = $( '<script type="text/javascript" src="/wp-content/themes/cot/js/jquery-3.6.0.min.js"></script>' );
252            jqueryScript.replaceWith( newJqueryScript );
253            const bootstrapScript = $( 'script[src*="/wp-content/themes/cot/js/bootstrap.3.4.1.min.js"]' );
254            const newBootstrapScript = $( '<script type="text/javascript" src="/wp-content/themes/cot/js/bootstrap.min.js"></script>' );
255            bootstrapScript.replaceWith( newBootstrapScript );
256        }
257        if ( $( '#fepe_nuit_blanche_archive_container' ).length ) {
258            const appScript = $( 'script[src="/resources/fepe_nuit_blanche_archive/scripts/main1.3.1.js"]' );
259            const newAppScript = $( '<script type="text/javascript" src="/resources/fepe_nuit_blanche_archive/scripts/main1.3.1.js"></script>' );
260            appScript.replaceWith( newAppScript );
261        }
262    }
263}, 500 );

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.