1(function (root) { 2 'use strict'; 3 4 root.MKPwaUi = root.MKPwaUi || { layers: {} }; 5 6 root.MKPwaUi.layers.createInstallLayer = function createInstallLayer(context) { 7 var deferredInstallPrompt = null; 8 var installed = false; 9 var promptPending = false; 10 var nativeInstallAvailable = false; 11 var publishedMode; 12 13 var isIos = /iPad|iPhone|iPod/.test(root.navigator.userAgent) || (root.navigator.platform === 'MacIntel' && root.navigator.maxTouchPoints > 1); 14 var isStandalone = root.matchMedia('(display-mode: standalone)').matches || root.navigator.standalone === true; 15 var isIosSafari = isIos && /Safari/i.test(root.navigator.userAgent) && !/CriOS|FxiOS|EdgiOS|YaBrowser/i.test(root.navigator.userAgent); 16 17 if (isStandalone) { 18 trackYmGoal('use_pwa'); 19 } 20 21 22 function trackYmGoal(goalName) { 23 if (typeof root.ym !== 'function') { 24 return; 25 } 26 27 root.ym(1598573, 'reachGoal', goalName); 28 } 29 30 function getInstallMode() { 31 if (installed || isStandalone) { 32 return 'unavailable'; 33 } 34 // Keep the CTA visible after consuming an event, until installation. 35 // Click readiness is checked separately using deferredInstallPrompt. 36 if (nativeInstallAvailable) { 37 return 'native'; 38 } 39 if (isIosSafari) { 40 return 'ios-manual'; 41 } 42 return 'unavailable'; 43 } 44 45 function publishInstallState() { 46 var mode = getInstallMode(); 47 if (mode === publishedMode) { 48 return; 49 } 50 publishedMode = mode; 51 document.documentElement.toggleAttribute( 52 'data-pwa-install-available', 53 mode !== 'unavailable' 54 ); 55 root.dispatchEvent(new Event('mk:pwa-install-state-change')); 56 } 57 58 root.MKPwaUi.getInstallMode = getInstallMode; 59 60 function finishPrompt(choice) { 61 promptPending = false; 62 if (choice && choice.outcome === 'accepted') { 63 installed = true; 64 deferredInstallPrompt = null; 65 nativeInstallAvailable = false; 66 } 67 publishInstallState(); 68 } 69 70 function handleInstallButtonClick(button) { 71 var promptEvent; 72 var promptResult; 73 74 var mode = getInstallMode(); 75 if (mode === 'unavailable' || promptPending 76 || (mode === 'native' && !deferredInstallPrompt)) { 77 return; 78 } 79 80 var goalName = 'click_install_pwa'; 81 if (button.classList.contains('header-logo__button-pwa')) { 82 goalName = 'click_top_install_pwa'; 83 } else if (button.classList.contains('landing__button-pwa')) { 84 goalName = 'click_landing_install_pwa'; 85 } 86 trackYmGoal(goalName); 87 if (mode === 'ios-manual') { 88 root.alert('ЧÑÐ¾Ð±Ñ ÑÑÑановиÑÑ Ð¿Ñиложение на iPhone/iPad: нажмиÑе «ÐоделиÑÑÑÑ» в Safari и вÑбеÑиÑе «Ðа ÑкÑан Ðомой».'); 89 return; 90 } 91 92 promptEvent = deferredInstallPrompt; 93 deferredInstallPrompt = null; 94 promptPending = true; 95 96 try { 97 promptResult = promptEvent.prompt(); 98 } catch (error) { 99 finishPrompt(null); 100 context.logger.warn('[PWA]', 'install.prompt.failed', error); 101 return; 102 } 103 104 Promise.resolve(promptResult).then(function () { 105 return promptEvent.userChoice; 106 }).then(function (choice) { 107 finishPrompt(choice); 108 }).catch(function (error) { 109 finishPrompt(null); 110 context.logger.warn('[PWA]', 'install.choice.failed', error); 111 }); 112 } 113 114 document.addEventListener('click', function (event) { 115 var target = event.target; 116 if (target && target.nodeType !== 1) { 117 target = target.parentElement; 118 } 119 var button = target && target.closest(context.config.domInstallButtonSelector); 120 if (!button || button.disabled || button.getAttribute('aria-disabled') === 'true') { 121 return; 122 } 123 124 event.preventDefault(); 125 handleInstallButtonClick(button); 126 }); 127 128 root.addEventListener('beforeinstallprompt', function (event) { 129 context.trackPwaEvent('pwa_install_prompt_shown', { 130 mode: isStandalone ? 'standalone' : 'browser', 131 is_ios: isIos, 132 is_ios_safari: isIosSafari 133 }); 134 135 if (isStandalone || installed) { 136 return; 137 } 138 139 event.preventDefault(); 140 deferredInstallPrompt = event; 141 nativeInstallAvailable = true; 142 publishInstallState(); 143 context.logger.info('[PWA]', 'install.prompt.ready'); 144 }); 145 146 root.addEventListener('appinstalled', function () { 147 deferredInstallPrompt = null; 148 installed = true; 149 promptPending = false;
150 nativeInstallAvailable = false; 151 publishInstallState(); 152 153 trackYmGoal('install_pwa'); 154 155 context.trackPwaEvent('pwa_install_completed', { 156 mode: isStandalone ? 'standalone' : 'browser', 157 is_ios: isIos, 158 is_ios_safari: isIosSafari 159 }); 160 context.logger.info('[PWA]', 'install.completed'); 161 }); 162 163 publishInstallState(); 164 165 return { 166 isStandalone: function () { 167 return isStandalone; 168 } 169 }; 170 }; 171})(window);
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.