1LevadaAnalytics = (() => { 2 const _listenersByName = {}; 3 const _listenersGlobal = []; 4 let _muted = false; 5 let _logging = false; 6 7 const _fire = (name, data) => { 8 if (_logging) { 9 console.log(`LevadaAnalytics | Name: ${name} | Data: `, data); 10 } 11 if (_muted) { 12 return; 13 } 14 for (const callback of (_listenersByName[name] || [])) { 15 callback(data); 16 } 17 for (const callback of _listenersGlobal) { 18 callback(name, data); 19 } 20 }; 21 22 const _emit = (name, data) => { 23 if (name === 'User') { 24 LevadaAnalytics.User = data; 25 } 26 if (name === 'Page') { 27 LevadaAnalytics.Page = data; 28 } 29 _fire(name, data); 30 }; 31 32 const _readElement = (element) => { 33 const name = element.getAttribute('levada-analytics-name'); 34 const raw = element.getAttribute('levada-analytics-data'); 35 return { name, data: raw ? JSON.parse(raw) : {} }; 36 }; 37 38 return { 39 User: null, 40 Page: null, 41 42 Subscribe: (name, callback) => { 43 if (!_listenersByName[name]) { 44 _listenersByName[name] = []; 45 } 46 _listenersByName[name].push(callback); 47 }, 48 49 SubscribeAll: (callback) => { 50 _listenersGlobal.push(callback); 51 }, 52 53 Publish: (name, data) => { 54 _emit(name, data); 55 }, 56 57 El: (element, event, data) => { 58 if (event && event.preventDefault) { 59 event.preventDefault(); 60 } 61 const el = _readElement(element); 62 _emit(el.name, Object.assign({}, el.data, data)); 63 if (element.href) { 64 window.location.href = element.href; 65 } 66 }, 67 68 Init: () => { 69 document.addEventListener('DOMContentLoaded', () => { 70 const page = LevadaAnalytics.Page || {}; 71 if (!page.title) { 72 page.title = document.title; 73 } 74 if (!page.url) { 75 page.url = window.location.pathname; 76 } 77 _emit('User', LevadaAnalytics.User || {}); 78 _emit('Page', page); 79 }); 80 }, 81 82 Debug: { 83 Log: (enabled) => { 84 _logging = enabled; 85 }, 86 87 Names: () => { 88 const domNames = Array.from( 89 document.querySelectorAll('[levada-analytics-name]'), 90 el => el.getAttribute('levada-analytics-name') 91 ); 92 return [...new Set(['User', 'Page', ...domNames])]; 93 }, 94 95 Event: (name) => { 96 if (name === 'User') { 97 console.log(`LevadaAnalytics | Name: User | Data: `, LevadaAnalytics.User || {}); 98 _fire('User', LevadaAnalytics.User || {}); 99 } else if (name === 'Page') { 100 console.log(`LevadaAnalytics | Name: Page | Data: `, LevadaAnalytics.Page || {}); 101 _fire('Page', LevadaAnalytics.Page || {}); 102 } else { 103 document.querySelectorAll('[levada-analytics-name="' + name + '"]').forEach(el => { 104 const raw = el.getAttribute('levada-analytics-data'); 105 const data = raw ? JSON.parse(raw) : {}; 106 console.log(`LevadaAnalytics | Name: ${name} | Data: `, data); 107 _fire(name, data); 108 }); 109 } 110 }, 111 112 Events: () => { 113 for (const name of LevadaAnalytics.Debug.Names()) { 114 LevadaAnalytics.Debug.Event(name); 115 } 116 }, 117 118 Mute: (enabled) => { 119 _muted = enabled; 120 }, 121 }, 122 }; 123})(); 124 125LevadaAnalytics.Init();
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.