@prefetchru/prefetch 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -137,7 +137,7 @@ ESM версия автоматически определяет `nonce` чер
137
137
  // Доступен объект window.Prefetch после загрузки скрипта
138
138
 
139
139
  // Версия библиотеки
140
- console.log(Prefetch.version) // "1.0.8"
140
+ console.log(Prefetch.version) // "1.0.10"
141
141
 
142
142
  // Программная предзагрузка URL
143
143
  Prefetch.preload('/catalog/product-123')
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * prefetch.ru v1.0.8 (ESM) - Мгновенная загрузка страниц
2
+ * prefetch.ru v1.0.10 (ESM) - Мгновенная загрузка страниц
3
3
  * © 2026 Сергей Макаров | MIT License
4
4
  * https://prefetch.ru | https://github.com/prefetch-ru
5
5
  */
6
- var e="undefined"!=typeof window&&window.Prefetch?window.Prefetch:function(e){if("undefined"==typeof window||"undefined"==typeof document)return{version:"1.0.8",preload:function(){}};var t=new Set,n=new WeakMap,r=0,i=0,o=null,a=!1,c=!1,u=null,l=null,s=!1,f=null,d=null,h=!1,m=65,p=80,v=50,g=!1,w=!1,y=!1,x=!1,b="none",L=!1,E=!1,T=!1,S=!1;function O(){var e=document.body;if(e){l=void 0!==window.BX?"bitrix":void 0!==window.B24||void 0!==window.BX24?"bitrix24":document.querySelector(".t-records")||void 0!==window.Tilda?"tilda":null;var t=e.dataset;if(g="prefetchAllowQueryString"in t||"instantAllowQueryString"in t,w="prefetchAllowExternalLinks"in t||"instantAllowExternalLinks"in t,y="prefetchWhitelist"in t||"instantWhitelist"in t,t.prefetchNonce&&(d=t.prefetchNonce),!d&&t.instantNonce&&(d=t.instantNonce),!c&&("prefetchSpecrules"in t||"instantSpecrules"in t)&&HTMLScriptElement.supports&&HTMLScriptElement.supports("speculationrules")){var n=t.prefetchSpecrules||t.instantSpecrules;"prerender"===n?(b="prerender",x=!0):"no"!==n&&(b="prefetch",x=!0)}L="prefetchPrerenderAll"in t||"instantPrerenderAll"in t;var r=t.prefetchIntensity||t.instantIntensity;if("mousedown"===r)E=!0;else if("viewport"===r||"viewport-all"===r)("viewport-all"===r||a&&A())&&(T=!0);else if(r){var i=parseInt(r,10);!isNaN(i)&&i>=0&&(m=i)}a&&(p=Math.max(60,Math.min(m||0,150))),(S="prefetchObserveDom"in t)||"bitrix"!==l&&"tilda"!==l||(S=!0),"tilda"===l&&m<100&&(m=100);var o={capture:!0,passive:!0};if(document.addEventListener("touchstart",P,o),E?document.addEventListener("mousedown",C,o):document.addEventListener("mouseover",N,o),T)(window.requestIdleCallback||function(e){setTimeout(e,1)})(U,{timeout:1500});S&&function(){if(H)return;(H=new MutationObserver(function(e){e.some(function(e){return Array.from(e.addedNodes).some(function(e){return 1===e.nodeType&&("A"===e.tagName||e.querySelectorAll&&e.querySelectorAll("a").length)})})&&R&&(clearTimeout(Q),Q=setTimeout(z,100))})).observe(document.body,{childList:!0,subtree:!0})}()}}function A(){return!s&&("slow-2g"!==f&&"2g"!==f)}function k(e){return e?(e.nodeType&&1!==e.nodeType&&(e=e.parentElement),e&&"function"==typeof e.closest?e.closest("a"):null):null}function P(e){r=e.timeStamp||Date.now();var t=k(e.target);if(I(t)){i&&(clearTimeout(i),i=0),o&&(document.removeEventListener("touchmove",o,!0),document.removeEventListener("scroll",o,!0),o=null);var n=!1;o=function(){n=!0,i&&(clearTimeout(i),i=0),document.removeEventListener("touchmove",o,!0),document.removeEventListener("scroll",o,!0),o=null},document.addEventListener("touchmove",o,{capture:!0,passive:!0,once:!0}),document.addEventListener("scroll",o,{capture:!0,passive:!0,once:!0}),i=setTimeout(function(){o&&(document.removeEventListener("touchmove",o,!0),document.removeEventListener("scroll",o,!0),o=null),i=0,n||q(t.href,t)},p)}}function N(e){if(!(r&&e.timeStamp&&e.timeStamp-r<2500)){var t=k(e.target);if(I(t)&&!n.has(t)){t.addEventListener("mouseleave",M,{passive:!0,once:!0});var i=setTimeout(function(){q(t.href,t),n.delete(t)},m);n.set(t,i)}}}function M(e){var t=e.currentTarget;if(t){var r=n.get(t);r&&(clearTimeout(r),n.delete(t))}}function C(e){if(!("number"==typeof e.button&&2===e.button||r&&e.timeStamp&&e.timeStamp-r<2500)){var t=k(e.target);I(t)&&q(t.href,t)}}function I(e){if(!e)return!1;var n=e.getAttribute("href");if(null===n||""===n.trim())return!1;if(!e.href)return!1;if(e.target&&"_self"!==e.target)return!1;if(e.hasAttribute("download"))return!1;if("noPrefetch"in e.dataset||"prefetchNo"in e.dataset)return!1;if(y&&!("prefetch"in e.dataset)&&!("instant"in e.dataset))return!1;if("http:"!==e.protocol&&"https:"!==e.protocol)return!1;if("http:"===e.protocol&&"https:"===location.protocol)return!1;if(e.origin!==location.origin){if(!w&&!("prefetch"in e.dataset)&&!("instant"in e.dataset))return!1;if(!u)return!1}if(e.search&&!g&&!("prefetch"in e.dataset)&&!("instant"in e.dataset))return!1;if(e.hash&&e.pathname+e.search===location.pathname+location.search)return!1;if(W(e.href)===W(location.href))return!1;var r=W(e.href);return!t.has(r)&&(!!function(e){var t=e.href,n="",r="";try{var i=new URL(t,location.href);n=i.pathname||"",r=i.hash||""}catch(e){n="",r=""}if("bitrix"===l||"bitrix24"===l){if(-1!==t.indexOf("/bitrix/")||-1!==t.indexOf("sessid="))return!1;if(e.classList.contains("bx-ajax"))return!1}if("tilda"===l&&(-1!==r.indexOf("#popup:")||-1!==r.indexOf("#rec")))return!1;var o=/(^|\/)(add|delete|remove)(\/|$|\.)/i.test(n);return-1===t.indexOf("/login")&&-1===t.indexOf("/logout")&&-1===t.indexOf("/auth")&&-1===t.indexOf("/register")&&-1===t.indexOf("/cart")&&-1===t.indexOf("/basket")&&!o&&!/\.(pdf|doc|docx|xls|xlsx|zip|rar|exe)($|\?)/i.test(t)}(e)&&!!function(e){var t=e.href,n=e.className||"",r="";try{r=new URL(t,location.href).hostname}catch(e){r=""}return-1===n.indexOf("ym-")&&("mc.yandex.ru"!==r&&"metrika.yandex.ru"!==r&&(-1===n.indexOf("ga-")&&-1===n.indexOf("gtm-")&&("google-analytics.com"!==r&&!r.endsWith(".google-analytics.com")&&("googletagmanager.com"!==r&&!r.endsWith(".googletagmanager.com")&&(-1===n.indexOf("piwik")&&-1===n.indexOf("matomo")&&("matomo.org"!==r&&!r.endsWith(".matomo.org")&&"piwik.org"!==r&&!r.endsWith(".piwik.org")))))))}(e))}function W(e){try{var t=new URL(e,location.href);return t.origin+t.pathname+t.search}catch(t){return e}}function q(e,n){if(A()){var r=function(e){try{var t=new URL(e,location.href);return t.hash="",t.href}catch(t){return e}}(e),i=W(r);if(!t.has(i)){t.size>=v&&t.delete(t.values().next().value),t.add(i);var o=function(e){return x&&"none"!==b?"prerender"!==b?b:L||y||e&&e.dataset&&("prefetchPrerender"in e.dataset||"instantPrerender"in e.dataset)?"prerender":"prefetch":"none"}(n);if("none"!==o)return function(e,t){var n=document.head;if(!n)return;var r=document.createElement("script");r.type="speculationrules",d&&(r.nonce=d);var i={};i[t]=[{source:"list",urls:[e]}],r.textContent=JSON.stringify(i),n.appendChild(r)}(r,o),void(c||!h?D(r,i):B(r,i));c||!h?D(r,i):B(r,i)}}}function B(e,n){var r=document.head;if(r){var i=document.createElement("link");i.rel="prefetch",i.href=e,i.as="document";try{i.fetchPriority="low"}catch(e){}i.onerror=function(){t.delete(n)},r.appendChild(i)}}function D(e,n){if("function"==typeof fetch){var r=null,i=0;"undefined"!=typeof AbortController&&(r=new AbortController,i=setTimeout(function(){try{r.abort()}catch(e){}},5e3));var o={method:"GET",credentials:"same-origin",cache:"force-cache",headers:{Purpose:"prefetch"}};r&&(o.signal=r.signal);try{fetch(e,o).then(function(e){i&&clearTimeout(i),e&&e.ok||t.delete(n)}).catch(function(){i&&clearTimeout(i),t.delete(n)})}catch(e){i&&clearTimeout(i),t.delete(n)}}}!function(){if(!(d=function(e){try{if(!e)return null;for(var t=document.getElementsByTagName("script"),n=0;n<t.length;n++){var r=t[n];if(r&&r.src&&r.src===e){var i=r.nonce||r.getAttribute("nonce")||null;if(i)return i;break}}}catch(e){}return null}(e)))try{var t=document.currentScript;t&&t.nonce&&(d=t.nonce)}catch(e){}try{var n=document.createElement("link");n.relList&&"function"==typeof n.relList.supports&&(h=n.relList.supports("prefetch"))}catch(e){}var r=navigator.userAgent;c=/iPad|iPhone/.test(r)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;var i=/Android/.test(r);(a=(c||i)&&Math.min(screen.width,screen.height)<768)&&(v=20);var o=r.match(/Chrome\/(\d+)/);o&&(u=parseInt(o[1],10));var l=navigator.connection;l&&(f=l.effectiveType,s=l.saveData||!1),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",O):O()}();var R=null;function U(){R||(R=new IntersectionObserver(function(e){e.forEach(function(e){e.isIntersecting&&(R.unobserve(e.target),I(e.target)&&q(e.target.href,e.target))})},{rootMargin:a?"100px":"200px"}),z())}function z(){R&&document.querySelectorAll("a").forEach(function(e){I(e)&&R.observe(e)})}var H=null,Q=null,X={version:"1.0.8",preload:function(e){q(e)}};return window.Prefetch=X,X}(import.meta.url);export{e as Prefetch};export default e;
6
+ var e="undefined"!=typeof window&&window.Prefetch&&window.Prefetch.__prefetchRu?window.Prefetch:function(e){if("undefined"==typeof window||"undefined"==typeof document)return{__prefetchRu:!0,version:"1.0.10",preload:function(){}};var t=new Set,n=new WeakMap,r=0,o=0,i=null,a=!1,c=!1,u=null,l=null,s=!1,f=null,d=null,h=!1,p=65,m=80,v=50,g=!1,w=!1,y=!1,x=!1,b="none",L=!1,E=!1,T=!1,A=!1;function O(){var e=document.body;if(e){l=void 0!==window.BX?"bitrix":void 0!==window.B24||void 0!==window.BX24?"bitrix24":document.querySelector(".t-records")||void 0!==window.Tilda?"tilda":null;var t=e.dataset;if(g="prefetchAllowQueryString"in t||"instantAllowQueryString"in t,w="prefetchAllowExternalLinks"in t||"instantAllowExternalLinks"in t,y="prefetchWhitelist"in t||"instantWhitelist"in t,t.prefetchNonce&&(d=t.prefetchNonce),!d&&t.instantNonce&&(d=t.instantNonce),!c&&("prefetchSpecrules"in t||"instantSpecrules"in t)&&HTMLScriptElement.supports&&HTMLScriptElement.supports("speculationrules")){var n=t.prefetchSpecrules||t.instantSpecrules;"prerender"===n?(b="prerender",x=!0):"no"!==n&&(b="prefetch",x=!0)}L="prefetchPrerenderAll"in t||"instantPrerenderAll"in t;var r=t.prefetchIntensity||t.instantIntensity;if("mousedown"===r)E=!0;else if("viewport"===r||"viewport-all"===r)("viewport-all"===r||a&&S())&&(T=!0);else if(r){var o=parseInt(r,10);!isNaN(o)&&o>=0&&(p=o)}a&&(m=Math.max(60,Math.min(p||0,150))),(A="prefetchObserveDom"in t)||"bitrix"!==l&&"tilda"!==l||(A=!0),"tilda"===l&&p<100&&(p=100);var i={capture:!0,passive:!0};if(document.addEventListener("touchstart",P,i),E?document.addEventListener("mousedown",C,i):document.addEventListener("mouseover",k,i),T&&"undefined"==typeof IntersectionObserver&&(T=!1),T)(window.requestIdleCallback||function(e){setTimeout(e,1)})(B,{timeout:1500});A&&T&&"undefined"!=typeof MutationObserver&&function(){if(U)return;(U=new MutationObserver(function(e){e.some(function(e){return Array.from(e.addedNodes).some(function(e){return 1===e.nodeType&&("A"===e.tagName||e.querySelectorAll&&e.querySelectorAll("a").length)})})&&q&&(clearTimeout(z),z=setTimeout(K,100))})).observe(document.body,{childList:!0,subtree:!0})}()}}function S(){return!s&&("slow-2g"!==f&&"2g"!==f)}function N(e){return e?(e.nodeType&&1!==e.nodeType&&(e=e.parentElement),e&&"function"==typeof e.closest?e.closest("a"):null):null}function P(e){r=Date.now();var t=N(e.target);if(I(t)){o&&(clearTimeout(o),o=0),i&&(document.removeEventListener("touchmove",i,!0),document.removeEventListener("scroll",i,!0),i=null);var n=!1;i=function(){n=!0,o&&(clearTimeout(o),o=0),document.removeEventListener("touchmove",i,!0),document.removeEventListener("scroll",i,!0),i=null},document.addEventListener("touchmove",i,{capture:!0,passive:!0,once:!0}),document.addEventListener("scroll",i,{capture:!0,passive:!0,once:!0}),o=setTimeout(function(){i&&(document.removeEventListener("touchmove",i,!0),document.removeEventListener("scroll",i,!0),i=null),o=0,n||W(t.href,t)},m)}}function k(e){if(!(r&&Date.now()-r<2500)){var t=N(e.target);if(I(t)&&!n.has(t)){t.addEventListener("mouseleave",M,{passive:!0,once:!0});var o=setTimeout(function(){W(t.href,t),n.delete(t)},p);n.set(t,o)}}}function M(e){var t=e.currentTarget;if(t){var r=n.get(t);r&&(clearTimeout(r),n.delete(t))}}function C(e){if(("number"!=typeof e.button||2!==e.button)&&!(e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||r&&Date.now()-r<2500)){var t=N(e.target);I(t)&&W(t.href,t)}}function I(e){if(!e)return!1;var n=e.getAttribute("href");if(null===n||""===n.trim())return!1;if(!e.href)return!1;if(e.target&&"_self"!==e.target)return!1;if(e.hasAttribute("download"))return!1;if("noPrefetch"in e.dataset||"prefetchNo"in e.dataset)return!1;if(y&&!("prefetch"in e.dataset)&&!("instant"in e.dataset))return!1;if("http:"!==e.protocol&&"https:"!==e.protocol)return!1;if("http:"===e.protocol&&"https:"===location.protocol)return!1;if(e.origin!==location.origin){if(!w&&!("prefetch"in e.dataset)&&!("instant"in e.dataset))return!1;if(!u)return!1}if(e.search&&!g&&!("prefetch"in e.dataset)&&!("instant"in e.dataset))return!1;if(e.hash&&e.pathname+e.search===location.pathname+location.search)return!1;if(R(e.href)===R(location.href))return!1;var r=R(e.href);return!t.has(r)&&(!!function(e){var t=e.href,n="",r="";try{var o=new URL(t,location.href);n=o.pathname||"",r=o.hash||""}catch(e){n="",r=""}if("bitrix"===l||"bitrix24"===l){if(-1!==t.indexOf("/bitrix/")||-1!==t.indexOf("sessid="))return!1;if(e.classList.contains("bx-ajax"))return!1}if("tilda"===l&&(-1!==r.indexOf("#popup:")||-1!==r.indexOf("#rec")))return!1;return!/(^|\/)(login|logout|auth|register|cart|basket|add|delete|remove)(\/|$|\.)/i.test(n)&&!/\.(pdf|doc|docx|xls|xlsx|zip|rar|exe)($|\?)/i.test(t)}(e)&&!!function(e){var t=e.href,n=e.className||"",r="";try{r=new URL(t,location.href).hostname}catch(e){r=""}return-1===n.indexOf("ym-")&&("mc.yandex.ru"!==r&&"metrika.yandex.ru"!==r&&(-1===n.indexOf("ga-")&&-1===n.indexOf("gtm-")&&("google-analytics.com"!==r&&!r.endsWith(".google-analytics.com")&&("googletagmanager.com"!==r&&!r.endsWith(".googletagmanager.com")&&(-1===n.indexOf("piwik")&&-1===n.indexOf("matomo")&&("matomo.org"!==r&&!r.endsWith(".matomo.org")&&"piwik.org"!==r&&!r.endsWith(".piwik.org")))))))}(e))}function R(e){try{var t=new URL(e,location.href);return t.origin+t.pathname+t.search}catch(t){return e}}function W(e,n){if(S()){var r=function(e){try{var t=new URL(e,location.href);return t.hash="",t.href}catch(t){return e}}(e),o=R(r);if(!t.has(o)){t.size>=v&&t.delete(t.values().next().value),t.add(o);var i=function(e){return x&&"none"!==b?"prerender"!==b?b:L||y||e&&e.dataset&&("prefetchPrerender"in e.dataset||"instantPrerender"in e.dataset)?"prerender":"prefetch":"none"}(n);if("none"!==i)return function(e,t){var n=document.head;if(!n)return;var r=document.createElement("script");r.type="speculationrules",d&&(r.nonce=d);var o={};o[t]=[{source:"list",urls:[e]}],r.textContent=JSON.stringify(o),n.appendChild(r)}(r,i),void(c||!h?D(r,o):_(r,o));c||!h?D(r,o):_(r,o)}}}function _(e,n){var r=document.head;if(r){var o=document.createElement("link");o.rel="prefetch",o.href=e,o.as="document";try{o.fetchPriority="low"}catch(e){}o.onload=i,o.onerror=function(){t.delete(n),i()},r.appendChild(o)}else t.delete(n);function i(){o.onload=o.onerror=null,o.parentNode&&o.parentNode.removeChild(o)}}function D(e,n){if("function"==typeof fetch){var r=null,o=0;"undefined"!=typeof AbortController&&(r=new AbortController,o=setTimeout(function(){try{r.abort()}catch(e){}},5e3));var i={method:"GET",credentials:"same-origin",cache:"force-cache",headers:{Purpose:"prefetch"}};r&&(i.signal=r.signal);try{fetch(e,i).then(function(e){o&&clearTimeout(o),e&&e.ok||t.delete(n)}).catch(function(){o&&clearTimeout(o),t.delete(n)})}catch(e){o&&clearTimeout(o),t.delete(n)}}else t.delete(n)}!function(){if(!(d=function(e){try{if(!e)return null;for(var t=document.getElementsByTagName("script"),n=0;n<t.length;n++){var r=t[n];if(r&&r.src&&r.src===e){var o=r.nonce||r.getAttribute("nonce")||null;if(o)return o;break}}}catch(e){}return null}(e)))try{var t=document.currentScript;t&&t.nonce&&(d=t.nonce)}catch(e){}try{var n=document.createElement("link");n.relList&&"function"==typeof n.relList.supports&&(h=n.relList.supports("prefetch"))}catch(e){}var r=navigator.userAgent;c=/iPad|iPhone/.test(r)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;var o=/Android/.test(r);(a=(c||o)&&Math.min(screen.width,screen.height)<768)&&(v=20);var i=r.match(/Chrome\/(\d+)/);i&&(u=parseInt(i[1],10));var l=navigator.connection;l&&(f=l.effectiveType,s=l.saveData||!1),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",O):O()}();var q=null;function B(){q||(q=new IntersectionObserver(function(e){e.forEach(function(e){e.isIntersecting&&(q.unobserve(e.target),I(e.target)&&W(e.target.href,e.target))})},{rootMargin:a?"100px":"200px"}),K())}function K(){q&&document.querySelectorAll("a").forEach(function(e){I(e)&&q.observe(e)})}var U=null,z=null,H={__prefetchRu:!0,version:"1.0.10",preload:function(e){W(e)}};return window.Prefetch=H,H}(import.meta.url);export{e as Prefetch};export default e;
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * prefetch.ru v1.0.8 - Мгновенная загрузка страниц
2
+ * prefetch.ru v1.0.10 - Мгновенная загрузка страниц
3
3
  * © 2026 Сергей Макаров | MIT License
4
4
  * https://prefetch.ru | https://github.com/prefetch-ru
5
5
  */
6
- !function(){"use strict";var e=new Set,t=new WeakMap,n=0,r=0,i=null,o=!1,a=!1,c=null,u=null,s=!1,l=null,f=null,d=!1,h=65,m=80,p=50,v=!1,g=!1,w=!1,x=!1,y="none",L=!1,b=!1,E=!1,T=!1;function S(){var e=document.body;if(e){u=void 0!==window.BX?"bitrix":void 0!==window.B24||void 0!==window.BX24?"bitrix24":document.querySelector(".t-records")||void 0!==window.Tilda?"tilda":null;var t=e.dataset;if(v="prefetchAllowQueryString"in t||"instantAllowQueryString"in t,g="prefetchAllowExternalLinks"in t||"instantAllowExternalLinks"in t,w="prefetchWhitelist"in t||"instantWhitelist"in t,t.prefetchNonce&&(f=t.prefetchNonce),!f&&t.instantNonce&&(f=t.instantNonce),!a&&("prefetchSpecrules"in t||"instantSpecrules"in t)&&HTMLScriptElement.supports&&HTMLScriptElement.supports("speculationrules")){var n=t.prefetchSpecrules||t.instantSpecrules;"prerender"===n?(y="prerender",x=!0):"no"!==n&&(y="prefetch",x=!0)}L="prefetchPrerenderAll"in t||"instantPrerenderAll"in t;var r=t.prefetchIntensity||t.instantIntensity;if("mousedown"===r)b=!0;else if("viewport"===r||"viewport-all"===r)("viewport-all"===r||o&&O())&&(E=!0);else if(r){var i=parseInt(r,10);!isNaN(i)&&i>=0&&(h=i)}o&&(m=Math.max(60,Math.min(h||0,150))),(T="prefetchObserveDom"in t)||"bitrix"!==u&&"tilda"!==u||(T=!0),"tilda"===u&&h<100&&(h=100);var c={capture:!0,passive:!0};if(document.addEventListener("touchstart",k,c),b?document.addEventListener("mousedown",M,c):document.addEventListener("mouseover",N,c),E)(window.requestIdleCallback||function(e){setTimeout(e,1)})(U,{timeout:1500});T&&function(){if(z)return;(z=new MutationObserver(function(e){e.some(function(e){return Array.from(e.addedNodes).some(function(e){return 1===e.nodeType&&("A"===e.tagName||e.querySelectorAll&&e.querySelectorAll("a").length)})})&&R&&(clearTimeout(H),H=setTimeout(B,100))})).observe(document.body,{childList:!0,subtree:!0})}()}}function O(){return!s&&("slow-2g"!==l&&"2g"!==l)}function A(e){return e?(e.nodeType&&1!==e.nodeType&&(e=e.parentElement),e&&"function"==typeof e.closest?e.closest("a"):null):null}function k(e){n=e.timeStamp||Date.now();var t=A(e.target);if(C(t)){r&&(clearTimeout(r),r=0),i&&(document.removeEventListener("touchmove",i,!0),document.removeEventListener("scroll",i,!0),i=null);var o=!1;i=function(){o=!0,r&&(clearTimeout(r),r=0),document.removeEventListener("touchmove",i,!0),document.removeEventListener("scroll",i,!0),i=null},document.addEventListener("touchmove",i,{capture:!0,passive:!0,once:!0}),document.addEventListener("scroll",i,{capture:!0,passive:!0,once:!0}),r=setTimeout(function(){i&&(document.removeEventListener("touchmove",i,!0),document.removeEventListener("scroll",i,!0),i=null),r=0,o||W(t.href,t)},m)}}function N(e){if(!(n&&e.timeStamp&&e.timeStamp-n<2500)){var r=A(e.target);if(C(r)&&!t.has(r)){r.addEventListener("mouseleave",P,{passive:!0,once:!0});var i=setTimeout(function(){W(r.href,r),t.delete(r)},h);t.set(r,i)}}}function P(e){var n=e.currentTarget;if(n){var r=t.get(n);r&&(clearTimeout(r),t.delete(n))}}function M(e){if(!("number"==typeof e.button&&2===e.button||n&&e.timeStamp&&e.timeStamp-n<2500)){var t=A(e.target);C(t)&&W(t.href,t)}}function C(t){if(!t)return!1;var n=t.getAttribute("href");if(null===n||""===n.trim())return!1;if(!t.href)return!1;if(t.target&&"_self"!==t.target)return!1;if(t.hasAttribute("download"))return!1;if("noPrefetch"in t.dataset||"prefetchNo"in t.dataset)return!1;if(w&&!("prefetch"in t.dataset)&&!("instant"in t.dataset))return!1;if("http:"!==t.protocol&&"https:"!==t.protocol)return!1;if("http:"===t.protocol&&"https:"===location.protocol)return!1;if(t.origin!==location.origin){if(!g&&!("prefetch"in t.dataset)&&!("instant"in t.dataset))return!1;if(!c)return!1}if(t.search&&!v&&!("prefetch"in t.dataset)&&!("instant"in t.dataset))return!1;if(t.hash&&t.pathname+t.search===location.pathname+location.search)return!1;if(I(t.href)===I(location.href))return!1;var r=I(t.href);return!e.has(r)&&(!!function(e){var t=e.href,n="",r="";try{var i=new URL(t,location.href);n=i.pathname||"",r=i.hash||""}catch(e){n="",r=""}if("bitrix"===u||"bitrix24"===u){if(-1!==t.indexOf("/bitrix/")||-1!==t.indexOf("sessid="))return!1;if(e.classList.contains("bx-ajax"))return!1}if("tilda"===u&&(-1!==r.indexOf("#popup:")||-1!==r.indexOf("#rec")))return!1;var o=/(^|\/)(add|delete|remove)(\/|$|\.)/i.test(n);return-1===t.indexOf("/login")&&-1===t.indexOf("/logout")&&-1===t.indexOf("/auth")&&-1===t.indexOf("/register")&&-1===t.indexOf("/cart")&&-1===t.indexOf("/basket")&&!o&&!/\.(pdf|doc|docx|xls|xlsx|zip|rar|exe)($|\?)/i.test(t)}(t)&&!!function(e){var t=e.href,n=e.className||"",r="";try{r=new URL(t,location.href).hostname}catch(e){r=""}return-1===n.indexOf("ym-")&&("mc.yandex.ru"!==r&&"metrika.yandex.ru"!==r&&(-1===n.indexOf("ga-")&&-1===n.indexOf("gtm-")&&("google-analytics.com"!==r&&!r.endsWith(".google-analytics.com")&&("googletagmanager.com"!==r&&!r.endsWith(".googletagmanager.com")&&(-1===n.indexOf("piwik")&&-1===n.indexOf("matomo")&&("matomo.org"!==r&&!r.endsWith(".matomo.org")&&"piwik.org"!==r&&!r.endsWith(".piwik.org")))))))}(t))}function I(e){try{var t=new URL(e,location.href);return t.origin+t.pathname+t.search}catch(t){return e}}function W(t,n){if(O()){var r=function(e){try{var t=new URL(e,location.href);return t.hash="",t.href}catch(t){return e}}(t),i=I(r);if(!e.has(i)){e.size>=p&&e.delete(e.values().next().value),e.add(i);var o=function(e){return x&&"none"!==y?"prerender"!==y?y:L||w||e&&e.dataset&&("prefetchPrerender"in e.dataset||"instantPrerender"in e.dataset)?"prerender":"prefetch":"none"}(n);if("none"!==o)return function(e,t){var n=document.head;if(!n)return;var r=document.createElement("script");r.type="speculationrules",f&&(r.nonce=f);var i={};i[t]=[{source:"list",urls:[e]}],r.textContent=JSON.stringify(i),n.appendChild(r)}(r,o),void(a||!d?D(r,i):q(r,i));a||!d?D(r,i):q(r,i)}}}function q(t,n){var r=document.head;if(r){var i=document.createElement("link");i.rel="prefetch",i.href=t,i.as="document";try{i.fetchPriority="low"}catch(e){}i.onerror=function(){e.delete(n)},r.appendChild(i)}}function D(t,n){if("function"==typeof fetch){var r=null,i=0;"undefined"!=typeof AbortController&&(r=new AbortController,i=setTimeout(function(){try{r.abort()}catch(e){}},5e3));var o={method:"GET",credentials:"same-origin",cache:"force-cache",headers:{Purpose:"prefetch"}};r&&(o.signal=r.signal);try{fetch(t,o).then(function(t){i&&clearTimeout(i),t&&t.ok||e.delete(n)}).catch(function(){i&&clearTimeout(i),e.delete(n)})}catch(t){i&&clearTimeout(i),e.delete(n)}}}!function(){try{var e=document.currentScript;e&&e.nonce&&(f=e.nonce)}catch(e){}try{var t=document.createElement("link");t.relList&&"function"==typeof t.relList.supports&&(d=t.relList.supports("prefetch"))}catch(e){}var n=navigator.userAgent;a=/iPad|iPhone/.test(n)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;var r=/Android/.test(n);(o=(a||r)&&Math.min(screen.width,screen.height)<768)&&(p=20);var i=n.match(/Chrome\/(\d+)/);i&&(c=parseInt(i[1],10));var u=navigator.connection;u&&(l=u.effectiveType,s=u.saveData||!1),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",S):S()}();var R=null;function U(){R||(R=new IntersectionObserver(function(e){e.forEach(function(e){e.isIntersecting&&(R.unobserve(e.target),C(e.target)&&W(e.target.href,e.target))})},{rootMargin:o?"100px":"200px"}),B())}function B(){R&&document.querySelectorAll("a").forEach(function(e){C(e)&&R.observe(e)})}var z=null,H=null;window.Prefetch={version:"1.0.8",preload:function(e){W(e)}}}();
6
+ !function(){"use strict";if(!window.Prefetch||!window.Prefetch.__prefetchRu){var e=new Set,t=new WeakMap,n=0,r=0,o=null,i=!1,a=!1,c=null,u=null,s=!1,l=null,d=null,f=!1,h=65,p=80,m=50,v=!1,g=!1,w=!1,y=!1,x="none",b=!1,L=!1,E=!1,T=!1;!function(){try{var e=document.currentScript;e&&e.nonce&&(d=e.nonce)}catch(e){}try{var t=document.createElement("link");t.relList&&"function"==typeof t.relList.supports&&(f=t.relList.supports("prefetch"))}catch(e){}var n=navigator.userAgent;a=/iPad|iPhone/.test(n)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;var r=/Android/.test(n);(i=(a||r)&&Math.min(screen.width,screen.height)<768)&&(m=20);var o=n.match(/Chrome\/(\d+)/);o&&(c=parseInt(o[1],10));var u=navigator.connection;u&&(l=u.effectiveType,s=u.saveData||!1),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",N):N()}();var A=null,O=null,S=null;window.Prefetch={__prefetchRu:!0,version:"1.0.10",preload:function(e){q(e)}}}function N(){var e=document.body;if(e){u=void 0!==window.BX?"bitrix":void 0!==window.B24||void 0!==window.BX24?"bitrix24":document.querySelector(".t-records")||void 0!==window.Tilda?"tilda":null;var t=e.dataset;if(v="prefetchAllowQueryString"in t||"instantAllowQueryString"in t,g="prefetchAllowExternalLinks"in t||"instantAllowExternalLinks"in t,w="prefetchWhitelist"in t||"instantWhitelist"in t,t.prefetchNonce&&(d=t.prefetchNonce),!d&&t.instantNonce&&(d=t.instantNonce),!a&&("prefetchSpecrules"in t||"instantSpecrules"in t)&&HTMLScriptElement.supports&&HTMLScriptElement.supports("speculationrules")){var n=t.prefetchSpecrules||t.instantSpecrules;"prerender"===n?(x="prerender",y=!0):"no"!==n&&(x="prefetch",y=!0)}b="prefetchPrerenderAll"in t||"instantPrerenderAll"in t;var r=t.prefetchIntensity||t.instantIntensity;if("mousedown"===r)L=!0;else if("viewport"===r||"viewport-all"===r)("viewport-all"===r||i&&P())&&(E=!0);else if(r){var o=parseInt(r,10);!isNaN(o)&&o>=0&&(h=o)}i&&(p=Math.max(60,Math.min(h||0,150))),(T="prefetchObserveDom"in t)||"bitrix"!==u&&"tilda"!==u||(T=!0),"tilda"===u&&h<100&&(h=100);var c={capture:!0,passive:!0};if(document.addEventListener("touchstart",M,c),L?document.addEventListener("mousedown",W,c):document.addEventListener("mouseover",C,c),E&&"undefined"==typeof IntersectionObserver&&(E=!1),E)(window.requestIdleCallback||function(e){setTimeout(e,1)})(U,{timeout:1500});T&&E&&"undefined"!=typeof MutationObserver&&function(){if(O)return;(O=new MutationObserver(function(e){e.some(function(e){return Array.from(e.addedNodes).some(function(e){return 1===e.nodeType&&("A"===e.tagName||e.querySelectorAll&&e.querySelectorAll("a").length)})})&&A&&(clearTimeout(S),S=setTimeout(B,100))})).observe(document.body,{childList:!0,subtree:!0})}()}}function P(){return!s&&("slow-2g"!==l&&"2g"!==l)}function k(e){return e?(e.nodeType&&1!==e.nodeType&&(e=e.parentElement),e&&"function"==typeof e.closest?e.closest("a"):null):null}function M(e){n=Date.now();var t=k(e.target);if(D(t)){r&&(clearTimeout(r),r=0),o&&(document.removeEventListener("touchmove",o,!0),document.removeEventListener("scroll",o,!0),o=null);var i=!1;o=function(){i=!0,r&&(clearTimeout(r),r=0),document.removeEventListener("touchmove",o,!0),document.removeEventListener("scroll",o,!0),o=null},document.addEventListener("touchmove",o,{capture:!0,passive:!0,once:!0}),document.addEventListener("scroll",o,{capture:!0,passive:!0,once:!0}),r=setTimeout(function(){o&&(document.removeEventListener("touchmove",o,!0),document.removeEventListener("scroll",o,!0),o=null),r=0,i||q(t.href,t)},p)}}function C(e){if(!(n&&Date.now()-n<2500)){var r=k(e.target);if(D(r)&&!t.has(r)){r.addEventListener("mouseleave",I,{passive:!0,once:!0});var o=setTimeout(function(){q(r.href,r),t.delete(r)},h);t.set(r,o)}}}function I(e){var n=e.currentTarget;if(n){var r=t.get(n);r&&(clearTimeout(r),t.delete(n))}}function W(e){if(("number"!=typeof e.button||2!==e.button)&&!(e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||n&&Date.now()-n<2500)){var t=k(e.target);D(t)&&q(t.href,t)}}function D(t){if(!t)return!1;var n=t.getAttribute("href");if(null===n||""===n.trim())return!1;if(!t.href)return!1;if(t.target&&"_self"!==t.target)return!1;if(t.hasAttribute("download"))return!1;if("noPrefetch"in t.dataset||"prefetchNo"in t.dataset)return!1;if(w&&!("prefetch"in t.dataset)&&!("instant"in t.dataset))return!1;if("http:"!==t.protocol&&"https:"!==t.protocol)return!1;if("http:"===t.protocol&&"https:"===location.protocol)return!1;if(t.origin!==location.origin){if(!g&&!("prefetch"in t.dataset)&&!("instant"in t.dataset))return!1;if(!c)return!1}if(t.search&&!v&&!("prefetch"in t.dataset)&&!("instant"in t.dataset))return!1;if(t.hash&&t.pathname+t.search===location.pathname+location.search)return!1;if(R(t.href)===R(location.href))return!1;var r=R(t.href);return!e.has(r)&&(!!function(e){var t=e.href,n="",r="";try{var o=new URL(t,location.href);n=o.pathname||"",r=o.hash||""}catch(e){n="",r=""}if("bitrix"===u||"bitrix24"===u){if(-1!==t.indexOf("/bitrix/")||-1!==t.indexOf("sessid="))return!1;if(e.classList.contains("bx-ajax"))return!1}if("tilda"===u&&(-1!==r.indexOf("#popup:")||-1!==r.indexOf("#rec")))return!1;return!/(^|\/)(login|logout|auth|register|cart|basket|add|delete|remove)(\/|$|\.)/i.test(n)&&!/\.(pdf|doc|docx|xls|xlsx|zip|rar|exe)($|\?)/i.test(t)}(t)&&!!function(e){var t=e.href,n=e.className||"",r="";try{r=new URL(t,location.href).hostname}catch(e){r=""}return-1===n.indexOf("ym-")&&("mc.yandex.ru"!==r&&"metrika.yandex.ru"!==r&&(-1===n.indexOf("ga-")&&-1===n.indexOf("gtm-")&&("google-analytics.com"!==r&&!r.endsWith(".google-analytics.com")&&("googletagmanager.com"!==r&&!r.endsWith(".googletagmanager.com")&&(-1===n.indexOf("piwik")&&-1===n.indexOf("matomo")&&("matomo.org"!==r&&!r.endsWith(".matomo.org")&&"piwik.org"!==r&&!r.endsWith(".piwik.org")))))))}(t))}function R(e){try{var t=new URL(e,location.href);return t.origin+t.pathname+t.search}catch(t){return e}}function q(t,n){if(P()){var r=function(e){try{var t=new URL(e,location.href);return t.hash="",t.href}catch(t){return e}}(t),o=R(r);if(!e.has(o)){e.size>=m&&e.delete(e.values().next().value),e.add(o);var i=function(e){return y&&"none"!==x?"prerender"!==x?x:b||w||e&&e.dataset&&("prefetchPrerender"in e.dataset||"instantPrerender"in e.dataset)?"prerender":"prefetch":"none"}(n);if("none"!==i)return function(e,t){var n=document.head;if(!n)return;var r=document.createElement("script");r.type="speculationrules",d&&(r.nonce=d);var o={};o[t]=[{source:"list",urls:[e]}],r.textContent=JSON.stringify(o),n.appendChild(r)}(r,i),void(a||!f?K(r,o):_(r,o));a||!f?K(r,o):_(r,o)}}}function _(t,n){var r=document.head;if(r){var o=document.createElement("link");o.rel="prefetch",o.href=t,o.as="document";try{o.fetchPriority="low"}catch(e){}o.onload=i,o.onerror=function(){e.delete(n),i()},r.appendChild(o)}else e.delete(n);function i(){o.onload=o.onerror=null,o.parentNode&&o.parentNode.removeChild(o)}}function K(t,n){if("function"==typeof fetch){var r=null,o=0;"undefined"!=typeof AbortController&&(r=new AbortController,o=setTimeout(function(){try{r.abort()}catch(e){}},5e3));var i={method:"GET",credentials:"same-origin",cache:"force-cache",headers:{Purpose:"prefetch"}};r&&(i.signal=r.signal);try{fetch(t,i).then(function(t){o&&clearTimeout(o),t&&t.ok||e.delete(n)}).catch(function(){o&&clearTimeout(o),e.delete(n)})}catch(t){o&&clearTimeout(o),e.delete(n)}}else e.delete(n)}function U(){A||(A=new IntersectionObserver(function(e){e.forEach(function(e){e.isIntersecting&&(A.unobserve(e.target),D(e.target)&&q(e.target.href,e.target))})},{rootMargin:i?"100px":"200px"}),B())}function B(){A&&document.querySelectorAll("a").forEach(function(e){D(e)&&A.observe(e)})}}();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prefetchru/prefetch",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Мгновенная загрузка страниц для российского веба. Instant page loading for Russian web.",
5
5
  "main": "prefetch.js",
6
6
  "module": "prefetch.esm.js",
package/prefetch.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * prefetch.ru v1.0.8 (ESM) - Мгновенная загрузка страниц
2
+ * prefetch.ru v1.0.10 (ESM) - Мгновенная загрузка страниц
3
3
  * © 2026 Сергей Макаров | MIT License
4
4
  * https://prefetch.ru | https://github.com/prefetch-ru
5
5
  */
@@ -8,7 +8,7 @@ function createPrefetch(importMetaUrl) {
8
8
 
9
9
  // SSR/Non-browser guard
10
10
  if (typeof window === 'undefined' || typeof document === 'undefined') {
11
- return { version: '1.0.8', preload: function () {} }
11
+ return { __prefetchRu: true, version: '1.0.10', preload: function () {} }
12
12
  }
13
13
 
14
14
  // Состояние
@@ -193,13 +193,17 @@ function createPrefetch(importMetaUrl) {
193
193
  }
194
194
 
195
195
  // Viewport observer
196
+ // v1.0.10: feature-detection — если IntersectionObserver недоступен, отключаем viewport режим
197
+ if (viewportMode && typeof IntersectionObserver === 'undefined') viewportMode = false
198
+
196
199
  if (viewportMode) {
197
200
  var rIC = window.requestIdleCallback || function (cb) { setTimeout(cb, 1) }
198
201
  rIC(startViewportObserver, { timeout: 1500 })
199
202
  }
200
203
 
201
- // Mutation observer
202
- if (observeDom) startMutationObserver()
204
+ // v1.0.9: MutationObserver нужен только для viewport режима (отслеживать новые ссылки)
205
+ // v1.0.10: feature-detection — если MutationObserver недоступен, не запускаем
206
+ if (observeDom && viewportMode && typeof MutationObserver !== 'undefined') startMutationObserver()
203
207
  }
204
208
 
205
209
  function detectPlatform() {
@@ -223,7 +227,8 @@ function createPrefetch(importMetaUrl) {
223
227
  }
224
228
 
225
229
  function onTouchStart(e) {
226
- lastTouchTime = e.timeStamp || Date.now()
230
+ // v1.0.9: используем Date.now() для единой шкалы времени
231
+ lastTouchTime = Date.now()
227
232
 
228
233
  var a = getAnchorFromEventTarget(e.target)
229
234
  if (!canPreload(a)) return
@@ -266,7 +271,8 @@ function createPrefetch(importMetaUrl) {
266
271
  }
267
272
 
268
273
  function onMouseOver(e) {
269
- if (lastTouchTime && e.timeStamp && e.timeStamp - lastTouchTime < 2500) return
274
+ // v1.0.9: единая шкала времени Date.now()
275
+ if (lastTouchTime && Date.now() - lastTouchTime < 2500) return
270
276
 
271
277
  var a = getAnchorFromEventTarget(e.target)
272
278
  if (!canPreload(a)) return
@@ -297,7 +303,10 @@ function createPrefetch(importMetaUrl) {
297
303
 
298
304
  function onMouseDown(e) {
299
305
  if (typeof e.button === 'number' && e.button === 2) return
300
- if (lastTouchTime && e.timeStamp && e.timeStamp - lastTouchTime < 2500) return
306
+ // v1.0.10: при модификаторах (Ctrl/Meta/Shift/Alt) открывается новая вкладка префетч бессмысленен
307
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return
308
+ // v1.0.9: единая шкала времени Date.now()
309
+ if (lastTouchTime && Date.now() - lastTouchTime < 2500) return
301
310
 
302
311
  var a = getAnchorFromEventTarget(e.target)
303
312
  if (canPreload(a)) preload(a.href, a)
@@ -375,18 +384,11 @@ function createPrefetch(importMetaUrl) {
375
384
  if (hash.indexOf('#popup:') !== -1 || hash.indexOf('#rec') !== -1) return false
376
385
  }
377
386
 
378
- // v1.0.7: /add /delete /remove только как отдельный сегмент пути (или имя файла типа /delete.php)
379
- var isActionPath = /(^|\/)(add|delete|remove)(\/|$|\.)/i.test(pathname)
387
+ // v1.0.9: все опасные пути проверяем по сегментам pathname, не по подстроке href
388
+ // Это исправляет ложные блокировки /author, /cartoon, /authentication и т.д.
389
+ var isDangerousPath = /(^|\/)(login|logout|auth|register|cart|basket|add|delete|remove)(\/|$|\.)/i.test(pathname)
380
390
 
381
- if (
382
- href.indexOf('/login') !== -1 ||
383
- href.indexOf('/logout') !== -1 ||
384
- href.indexOf('/auth') !== -1 ||
385
- href.indexOf('/register') !== -1 ||
386
- href.indexOf('/cart') !== -1 ||
387
- href.indexOf('/basket') !== -1 ||
388
- isActionPath
389
- ) return false
391
+ if (isDangerousPath) return false
390
392
 
391
393
  if (/\.(pdf|doc|docx|xls|xlsx|zip|rar|exe)($|\?)/i.test(href)) return false
392
394
 
@@ -498,7 +500,8 @@ function createPrefetch(importMetaUrl) {
498
500
 
499
501
  function preloadLink(url, key) {
500
502
  var head = document.head
501
- if (!head) return
503
+ // v1.0.10: если head недоступен, откатываем ключ
504
+ if (!head) { preloaded.delete(key); return }
502
505
 
503
506
  var l = document.createElement('link')
504
507
  l.rel = 'prefetch'
@@ -506,12 +509,20 @@ function createPrefetch(importMetaUrl) {
506
509
  l.as = 'document'
507
510
  try { l.fetchPriority = 'low' } catch (e) {}
508
511
 
509
- l.onerror = function () { preloaded.delete(key) }
512
+ // v1.0.9: удаляем link после загрузки, чтобы не раздувать DOM
513
+ function cleanup() {
514
+ l.onload = l.onerror = null
515
+ if (l.parentNode) l.parentNode.removeChild(l)
516
+ }
517
+
518
+ l.onload = cleanup
519
+ l.onerror = function () { preloaded.delete(key); cleanup() }
510
520
  head.appendChild(l)
511
521
  }
512
522
 
513
523
  function preloadFetch(url, key) {
514
- if (typeof fetch !== 'function') return
524
+ // v1.0.10: если fetch недоступен, откатываем ключ
525
+ if (typeof fetch !== 'function') { preloaded.delete(key); return }
515
526
 
516
527
  var ctrl = null
517
528
  var tid = 0
@@ -598,7 +609,8 @@ function createPrefetch(importMetaUrl) {
598
609
 
599
610
  // Минимальный публичный API
600
611
  var api = {
601
- version: '1.0.8',
612
+ __prefetchRu: true,
613
+ version: '1.0.10',
602
614
  preload: function (url) { preload(url) }
603
615
  }
604
616
 
@@ -606,9 +618,11 @@ function createPrefetch(importMetaUrl) {
606
618
  return api
607
619
  }
608
620
 
609
- // Guard от двойной инициализации (если уже есть window.Prefetch — используем его)
621
+ // v1.0.9: Guard от двойной инициализации (проверяем маркер __prefetchRu)
610
622
  var Prefetch =
611
- (typeof window !== 'undefined' && window.Prefetch) ? window.Prefetch : createPrefetch(import.meta.url)
623
+ (typeof window !== 'undefined' && window.Prefetch && window.Prefetch.__prefetchRu)
624
+ ? window.Prefetch
625
+ : createPrefetch(import.meta.url)
612
626
 
613
627
  export { Prefetch }
614
628
  export default Prefetch
package/prefetch.js CHANGED
@@ -1,11 +1,14 @@
1
1
  /*!
2
- * prefetch.ru v1.0.8 - Мгновенная загрузка страниц
2
+ * prefetch.ru v1.0.10 - Мгновенная загрузка страниц
3
3
  * © 2026 Сергей Макаров | MIT License
4
4
  * https://prefetch.ru | https://github.com/prefetch-ru
5
5
  */
6
6
  ;(function () {
7
7
  'use strict'
8
8
 
9
+ // v1.0.9: guard от двойной инициализации
10
+ if (window.Prefetch && window.Prefetch.__prefetchRu) return
11
+
9
12
  // Состояние
10
13
  var preloaded = new Set()
11
14
  var hoverTimers = new WeakMap()
@@ -165,13 +168,17 @@
165
168
  }
166
169
 
167
170
  // Viewport observer
171
+ // v1.0.10: feature-detection — если IntersectionObserver недоступен, отключаем viewport режим
172
+ if (viewportMode && typeof IntersectionObserver === 'undefined') viewportMode = false
173
+
168
174
  if (viewportMode) {
169
175
  var rIC = window.requestIdleCallback || function (cb) { setTimeout(cb, 1) }
170
176
  rIC(startViewportObserver, { timeout: 1500 })
171
177
  }
172
178
 
173
- // Mutation observer
174
- if (observeDom) startMutationObserver()
179
+ // v1.0.9: MutationObserver нужен только для viewport режима (отслеживать новые ссылки)
180
+ // v1.0.10: feature-detection — если MutationObserver недоступен, не запускаем
181
+ if (observeDom && viewportMode && typeof MutationObserver !== 'undefined') startMutationObserver()
175
182
  }
176
183
 
177
184
  function detectPlatform() {
@@ -195,7 +202,8 @@
195
202
  }
196
203
 
197
204
  function onTouchStart(e) {
198
- lastTouchTime = e.timeStamp || Date.now()
205
+ // v1.0.9: используем Date.now() для единой шкалы времени
206
+ lastTouchTime = Date.now()
199
207
 
200
208
  var a = getAnchorFromEventTarget(e.target)
201
209
  if (!canPreload(a)) return
@@ -238,7 +246,8 @@
238
246
  }
239
247
 
240
248
  function onMouseOver(e) {
241
- if (lastTouchTime && e.timeStamp && e.timeStamp - lastTouchTime < 2500) return
249
+ // v1.0.9: единая шкала времени Date.now()
250
+ if (lastTouchTime && Date.now() - lastTouchTime < 2500) return
242
251
 
243
252
  var a = getAnchorFromEventTarget(e.target)
244
253
  if (!canPreload(a)) return
@@ -269,7 +278,10 @@
269
278
 
270
279
  function onMouseDown(e) {
271
280
  if (typeof e.button === 'number' && e.button === 2) return
272
- if (lastTouchTime && e.timeStamp && e.timeStamp - lastTouchTime < 2500) return
281
+ // v1.0.10: при модификаторах (Ctrl/Meta/Shift/Alt) открывается новая вкладка префетч бессмысленен
282
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return
283
+ // v1.0.9: единая шкала времени Date.now()
284
+ if (lastTouchTime && Date.now() - lastTouchTime < 2500) return
273
285
 
274
286
  var a = getAnchorFromEventTarget(e.target)
275
287
  if (canPreload(a)) preload(a.href, a)
@@ -348,18 +360,11 @@
348
360
  if (hash.indexOf('#popup:') !== -1 || hash.indexOf('#rec') !== -1) return false
349
361
  }
350
362
 
351
- // v1.0.7: /add /delete /remove только как отдельный сегмент пути (или имя файла типа /delete.php)
352
- var isActionPath = /(^|\/)(add|delete|remove)(\/|$|\.)/i.test(pathname)
363
+ // v1.0.9: все опасные пути проверяем по сегментам pathname, не по подстроке href
364
+ // Это исправляет ложные блокировки /author, /cartoon, /authentication и т.д.
365
+ var isDangerousPath = /(^|\/)(login|logout|auth|register|cart|basket|add|delete|remove)(\/|$|\.)/i.test(pathname)
353
366
 
354
- if (
355
- href.indexOf('/login') !== -1 ||
356
- href.indexOf('/logout') !== -1 ||
357
- href.indexOf('/auth') !== -1 ||
358
- href.indexOf('/register') !== -1 ||
359
- href.indexOf('/cart') !== -1 ||
360
- href.indexOf('/basket') !== -1 ||
361
- isActionPath
362
- ) return false
367
+ if (isDangerousPath) return false
363
368
 
364
369
  if (/\.(pdf|doc|docx|xls|xlsx|zip|rar|exe)($|\?)/i.test(href)) return false
365
370
 
@@ -471,7 +476,8 @@
471
476
 
472
477
  function preloadLink(url, key) {
473
478
  var head = document.head
474
- if (!head) return
479
+ // v1.0.10: если head недоступен, откатываем ключ
480
+ if (!head) { preloaded.delete(key); return }
475
481
 
476
482
  var l = document.createElement('link')
477
483
  l.rel = 'prefetch'
@@ -479,12 +485,20 @@
479
485
  l.as = 'document'
480
486
  try { l.fetchPriority = 'low' } catch (e) {}
481
487
 
482
- l.onerror = function () { preloaded.delete(key) }
488
+ // v1.0.9: удаляем link после загрузки, чтобы не раздувать DOM
489
+ function cleanup() {
490
+ l.onload = l.onerror = null
491
+ if (l.parentNode) l.parentNode.removeChild(l)
492
+ }
493
+
494
+ l.onload = cleanup
495
+ l.onerror = function () { preloaded.delete(key); cleanup() }
483
496
  head.appendChild(l)
484
497
  }
485
498
 
486
499
  function preloadFetch(url, key) {
487
- if (typeof fetch !== 'function') return
500
+ // v1.0.10: если fetch недоступен, откатываем ключ
501
+ if (typeof fetch !== 'function') { preloaded.delete(key); return }
488
502
 
489
503
  var ctrl = null
490
504
  var tid = 0
@@ -571,7 +585,8 @@
571
585
 
572
586
  // Минимальный публичный API
573
587
  window.Prefetch = {
574
- version: '1.0.8',
588
+ __prefetchRu: true,
589
+ version: '1.0.10',
575
590
  preload: function (url) { preload(url) }
576
591
  }
577
592
  })()