1/* popupwindow â vanilla replacement for jquery.popupwindow + the jQuery 2 * autobinder that used to sit here. 3 * 4 * Surface (kept the same as before, so call sites don't change): 5 * window.popupWindow(url, opts) â opens a child window via window.open 6 * $.popupWindow(url, opts) â jQuery shim alias 7 * class="popupwindow" â clicking such an anchor opens its href 8 * in a popup, sized by the named profile 9 * in its rel="..." attribute 10 * 11 * Profiles are the same as the legacy plugin: 12 * windowCenter / windowCenterLarge / windowCenterVLarge / windowMedia 13 */ 14(function() { 15 const profiles = { 16 windowCenter: { height: 450, width: 600, scrollbars: 1, center: 'parent' }, 17 windowCenterLarge: { height: 800, width: 768, scrollbars: 1, center: 'parent' }, 18 windowCenterVLarge: { height: 800, width: 1024, scrollbars: 1, center: 'parent' }, 19 windowMedia: { height: 150, width: 450, scrollbars: 0, center: 'parent' }, 20 }; 21 22 const defaults = { 23 center: 'screen', 24 createNew: true, 25 height: 500, 26 width: 500, 27 location: false, 28 menubar: false, 29 resizable: false, 30 scrollbars: false, 31 status: false, 32 toolbar: false, 33 name: null, 34 }; 35 36 function popupWindow(url, opts) { 37 const cfg = Object.assign({}, defaults, opts || {}); 38 39 let top, left; 40 if (cfg.center === 'parent') { 41 top = window.screenY + Math.round((window.innerHeight - cfg.height) / 2); 42 left = window.screenX + Math.round((window.innerWidth - cfg.width) / 2); 43 } else { 44 const sl = (typeof window.screenLeft !== 'undefined') ? window.screenLeft : screen.left; 45 top = (screen.height - cfg.height) / 2 - 50; 46 left = sl + (screen.width - cfg.width) / 2; 47 } 48 49 const features = [ 50 'location=' + (cfg.location ? 'yes' : 'no'), 51 'menubar=' + (cfg.menubar ? 'yes' : 'no'), 52 'toolbar=' + (cfg.toolbar ? 'yes' : 'no'), 53 'scrollbars=' + (cfg.scrollbars ? 'yes' : 'no'), 54 'status=' + (cfg.status ? 'yes' : 'no'), 55 'resizable=' + (cfg.resizable ? 'yes' : 'no'), 56 'height=' + cfg.height, 57 'width=' + cfg.width, 58 'left=' + left, 59 'top=' + top, 60 ].join(','); 61 62 const name = cfg.name || (cfg.createNew ? 'popup_window_' + Date.now() : 'popup_window'); 63 const win = window.open(url, name, features); 64 65 if (typeof cfg.onUnload === 'function') { 66 const t = setInterval(() => { 67 if (!win || win.closed) { 68 clearInterval(t); 69 cfg.onUnload(); 70 } 71 }, 50); 72 } 73 74 if (win && win.focus) win.focus(); 75 return win; 76 } 77 78 window.popupWindow = popupWindow; 79 if (window.jQuery) jQuery.popupWindow = popupWindow; 80 81 /* Auto-bind class="popupwindow" anchors. Body-level event delegation so 82 * htmx-loaded / dynamically-inserted links are picked up automatically. */ 83 document.addEventListener('click', function(e) { 84 const a = e.target.closest('.popupwindow'); 85 if (!a) return; 86 e.preventDefault(); 87 e.stopPropagation(); 88 const profileName = a.getAttribute('rel'); 89 popupWindow(a.getAttribute('href'), profiles[profileName]); 90 }); 91})();
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.