1/* Based on SqueezeBox for MooTools (http://digitarald.de/project/squeezebox/) */ 2(function () { 3 'use strict'; 4 5 var $overlay, 6 $winwrapper, 7 $win, 8 $content, 9 $close, 10 $body, 11 root, 12 scrollOffset; 13 14 /** 15 * @param {string} tag 16 * @param {object} attributes 17 * @returns {HTMLElement} 18 */ 19 function $createNode(tag, attributes = {}) { 20 var node = document.createElement(tag); 21 for (var attrName in attributes) { 22 node.setAttribute(attrName, attributes[attrName]); 23 } 24 return node; 25 } 26 27 function initialize() { 28 $overlay = $createNode('div', { 29 'id': 'sbox-overlay', 30 'aria-hidden': 'true', 31 'tabindex': '-1', 32 'style': 'z-index:65555;opacity:0.7' 33 }); 34 $winwrapper = $createNode('div', { 35 'id': 'sbox-window-wrapper', 36 'role': 'dialog', 37 'aria-hidden': 'true', 38 'style': 'z-index:65557' 39 }); 40 $win = $createNode('div', { 41 'id': 'sbox-window', 42 'aria-hidden': 'true', 43 'class': 'shadow', 44 }); 45 $content = $createNode('div', {'id': 'sbox-content'}); 46 $close = $createNode('a', { 47 'id': 'sbox-btn-close', 48 'href': '#', 49 'role': 'button', 50 'aria-controls': 'sbox-window' 51 }); 52 $body = document.body; 53 root = document.documentElement || document.body; 54 55 $win.append($content, $close); 56 $winwrapper.append($win); 57 $body.append($overlay, $winwrapper); 58 59 $overlay.addEventListener('click', close); 60 $close.addEventListener('click', close); 61 62 document.addEventListener('sbox-iframe-focus-keyboard', onFocus); 63 document.addEventListener('sbox-iframe-blur-keyboard', onBlur); 64 65 $body.addEventListener('submit', function (e) { 66 var form = e.target.closest('[data-popup]'); 67 if (form) { 68 open(form); 69 e.preventDefault(); 70 } 71 }); 72 } 73 74 var keyboard_mode = false;
75 function onFocus() { 76 keyboard_mode = true; 77// document.body.classList.add('sbox-keyboard'); 78 } 79 80 function onBlur() { 81 keyboard_mode = false; 82// document.body.classList.remove('sbox-keyboard'); 83// reposition(); 84 $win.scrollIntoView({block: 'nearest'}); 85 } 86 87 /** 88 * @param {Element} form 89 */ 90 function open(form) { 91 var url = form.action + '?' + (new URLSearchParams(new FormData(form))).toString(); 92 var size = { 93 x: Math.min(600, document.documentElement.clientWidth - 16), 94 y: 490 // Math.min(490, document.documentElement.clientHeight - 16) 95 }; 96 97 var $iframe = $createNode('iframe', {'frameborder': '0'}); 98 $iframe.setAttribute('src', url); 99 $iframe.setAttribute('width', size.x); 100 $iframe.setAttribute('height', size.y); 101 102 $content.innerHTML = ''; 103 $content.append($iframe); 104 105 toggleOverlay(true); 106 107 reposition(); 108 109 document.addEventListener('keydown', onKey); 110 document.addEventListener('mousewheel', checkTarget); 111 window.addEventListener('resize', reposition); 112 window.addEventListener('scroll', reposition); 113 } 114 115 /** 116 * @param {UIEvent} e 117 */ 118 function close(e) { 119 $content.innerHTML = ''; 120 121 toggleOverlay(false); 122 123 document.removeEventListener('keydown', onKey); 124 document.removeEventListener('mousewheel', checkTarget); 125 window.removeEventListener('resize', reposition); 126 window.removeEventListener('scroll', reposition); 127 128 e.preventDefault(); 129 } 130 131 /** 132 * @param {boolean} state 133 */ 134 function toggleOverlay(state) { 135 var full = root.offsetWidth; 136 $overlay.setAttribute('aria-hidden', state ? 'false' : 'true'); 137 $winwrapper.setAttribute('aria-hidden', state ? 'false' : 'true'); 138 $win.setAttribute('aria-hidden', state ? 'false' : 'true'); 139 if (state) { 140 $body.classList.add('body-overlayed'); 141 scrollOffset = root.offsetWidth - full; 142 } else { 143 $body.classList.remove('body-overlayed'); 144 } 145 } 146 147 function reposition() { 148 if (keyboard_mode) return; 149 var j = parseInt($overlay.style.height); 150 if (root.scrollHeight > j && root.offsetHeight >= j) { 151 $overlay.style.width = root.scrollWidth + 'px'; 152 $overlay.style.height = root.scrollHeight + 'px'; 153 } 154 $winwrapper.style.left = Math.round(root.scrollLeft + (document.documentElement.clientWidth - $win.offsetWidth) / 2 - scrollOffset) + 'px'; 155 $winwrapper.style.top = Math.round(root.scrollTop + (document.documentElement.clientHeight - $win.offsetHeight) / 2) + 'px'; 156 } 157 158 /** 159 * @param {KeyboardEvent} e 160 */ 161 function onKey(e) { 162 switch (e.key) { 163 case 'esc': 164 close(e); 165 break; 166 case 'up': 167 case 'down': 168 e.preventDefault(); 169 break; 170 } 171 } 172 173 /** 174 * @param {MouseEvent} e 175 */ 176 function checkTarget(e) { 177 if (!$content.contains(e.target)) { 178 e.preventDefault(); 179 } 180 } 181 182 document.addEventListener('DOMContentLoaded', initialize); 183 184})();
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.