1/* Global functionality for the <head> element. 2 3 developer: marionm 4 requires: nothing 5 ========================================================================== */ 6 7/* ========================================================================== 8 functions 9 ========================================================================== */ 10 11/* Limit the rate at which a function is permitted to trigger. 12 13 params: func (function, no default) function to throttle 14 threshold (integer, default=100ms) maximum rate at which function is permitted to trigger 15 scope (object, no default) scope to use if different from "this" 16 returns: function 17 ========================================================================== */ 18 19function _throttle(func, threshold, scope) { 20 threshold || (threshold = 100); 21 var last, deferTimer; 22 return function () { 23 var context = scope || this; 24 var now = +new Date, args = arguments; 25 if (last && now < last + threshold) { 26 clearTimeout(deferTimer); 27 deferTimer = setTimeout(function() { 28 last = now; 29 func.apply(context, args); 30 }, threshold); 31 } else { 32 last = now; 33 func.apply(context, args); 34 } 35 }; 36} 37 38/* Delay a function from triggering when within a specific threshold. 39 40 params: func (function, no default) function to delay 41 threshold (integer, default=100ms) maximum time permitted to delay the function from triggering 42 immediate (boolean, default=true) if true, immediately trigger the function then begin the delay; if false, only trigger the function after the delay 43 returns: function 44 ========================================================================== */ 45 46function _debounce(func, threshold, immediate) { 47 threshold || (threshold = 100); 48 var timeout; 49 return function() { 50 var context = this; 51 var args = arguments; 52 var later = function() { 53 timeout = null; 54 if (!immediate) func.apply(context, args); 55 }; 56 var callNow = immediate && !timeout; 57 clearTimeout(timeout); 58 timeout = setTimeout(later, threshold); 59 if (callNow) func.apply(context, args); 60 }; 61} 62 63/* Limit a function to triggering at most once per animation frame. 64 65 params: func (function, no default) function to throttle 66 scope (object, no default) scope to use if different from "this" 67 returns: function 68 ========================================================================== */ 69 70function _raf(func, scope) { 71 var pending = false; 72 return function() { 73 var context = scope || this; 74 var args = arguments; 75 if (pending) return; 76 pending = true; 77 window.requestAnimationFrame(function() { 78 func.apply(context, args); 79 pending = false; 80 }); 81 }; 82} 83 84/* ========================================================================== 85 variables 86 ========================================================================== */ 87 88var _html = document.documentElement; 89 90/* ========================================================================== 91 actions 92 ========================================================================== */ 93 94_html.classList.add('js-enabled'); 95 96// detect touch-enabled devices 97if (window.matchMedia('(hover: none) and (pointer: coarse)').matches) { 98 _html.classList.add('touch-enabled'); 99 // enable :active pseudo styles on iOS Safari 100 window.addEventListener('touchstart', function() {}, { passive: true }); 101} 102 103// detect dark mode preference 104if (window.matchMedia('(prefers-color-scheme: dark)').matches) { 105 _html.classList.add('dark-mode'); 106} else { 107 _html.classList.add('light-mode'); 108} 109 110// detect reduced motion preference 111if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { 112 _html.classList.add('reduced-motion'); 113} 114 115/* breakpoints 116 ========================================================================== */ 117 118// manage breakpoint class indicators on the html element 119var _breakpoints = function() { 120 var width = document.documentElement.clientWidth; 121 var classes = ['__320', '__600', '__900', '__1200', '__full']; 122 var current; 123 124 // determine class indicator for current screen size 125 if (width >= 1201) { 126 current = '__full'; 127 } else if (width >= 901) { 128 current = '__1200'; 129 } else if (width >= 601) { 130 current = '__900'; 131 } else if (width >= 321) { 132 current = '__600'; 133 } else { 134 current = '__320'; 135 } 136 137 _html.classList.remove.apply(_html.classList, classes.filter(function(c) { return c !== current; })); 138 _html.classList.add(current); 139} 140 141_breakpoints(); 142window.addEventListener('pageshow', _breakpoints); 143window.addEventListener('load', _breakpoints); 144window.addEventListener('resize', _raf(_breakpoints));
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.