|
|
@@ -27,6 +27,9 @@
|
|
|
|
|
|
const LOAD_DEFERRED_IMAGES_START_EVENT = "single-file-load-deferred-images-start";
|
|
|
const LOAD_DEFERRED_IMAGES_END_EVENT = "single-file-load-deferred-images-end";
|
|
|
+ const LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_START_EVENT = "single-file-load-deferred-images-keep-zoom-level-start";
|
|
|
+ const LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_END_EVENT = "single-file-load-deferred-images-keep-zoom-level-end";
|
|
|
+ const LOAD_DEFERRED_IMAGES_RESET_ZOOM_LEVEL_END_EVENT = "single-file-load-deferred-images-keep-zoom-level-reset";
|
|
|
const BLOCK_COOKIES_START_EVENT = "single-file-block-cookies-start";
|
|
|
const BLOCK_COOKIES_END_EVENT = "single-file-block-cookies-end";
|
|
|
const BLOCK_STORAGE_START_EVENT = "single-file-block-storage-start";
|
|
|
@@ -60,36 +63,41 @@
|
|
|
const observers = new Map();
|
|
|
const observedElements = new Map();
|
|
|
|
|
|
- addEventListener.call(window, LOAD_DEFERRED_IMAGES_START_EVENT, () => {
|
|
|
+ addEventListener.call(window, LOAD_DEFERRED_IMAGES_START_EVENT, () => loadDeferredImagesStart());
|
|
|
+ addEventListener.call(window, LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_START_EVENT, () => loadDeferredImagesStart(true));
|
|
|
+
|
|
|
+ function loadDeferredImagesStart(keepZoomLevel) {
|
|
|
const scrollingElement = document.scrollingElement || document.documentElement;
|
|
|
const clientHeight = scrollingElement.clientHeight;
|
|
|
const clientWidth = scrollingElement.clientWidth;
|
|
|
const scrollHeight = Math.max(scrollingElement.scrollHeight - clientHeight, clientHeight);
|
|
|
const scrollWidth = Math.max(scrollingElement.scrollWidth - clientWidth, clientWidth);
|
|
|
- scrollingElement.__defineGetter__("clientHeight", () => scrollHeight);
|
|
|
- scrollingElement.__defineGetter__("clientWidth", () => scrollWidth);
|
|
|
- screen.__defineGetter__("height", () => scrollHeight);
|
|
|
- screen.__defineGetter__("width", () => scrollWidth);
|
|
|
document.querySelectorAll("[loading=lazy]").forEach(element => {
|
|
|
element.loading = "eager";
|
|
|
element.setAttribute(LAZY_LOAD_ATTRIBUTE, "");
|
|
|
});
|
|
|
- if (!window._singleFile_getBoundingClientRect) {
|
|
|
- window._singleFile_getBoundingClientRect = Element.prototype.getBoundingClientRect;
|
|
|
- Element.prototype.getBoundingClientRect = function () {
|
|
|
- const boundingRect = window._singleFile_getBoundingClientRect.call(this);
|
|
|
- if (this == scrollingElement) {
|
|
|
- boundingRect.__defineGetter__("height", () => scrollHeight);
|
|
|
- boundingRect.__defineGetter__("bottom", () => scrollHeight + boundingRect.top);
|
|
|
- boundingRect.__defineGetter__("width", () => scrollWidth);
|
|
|
- boundingRect.__defineGetter__("right", () => scrollWidth + boundingRect.left);
|
|
|
- }
|
|
|
- return boundingRect;
|
|
|
- };
|
|
|
- window._singleFile_innerHeight = window.innerHeight;
|
|
|
- window._singleFile_innerWidth = window.innerWidth;
|
|
|
- window.__defineGetter__("innerHeight", () => scrollHeight);
|
|
|
- window.__defineGetter__("innerWidth", () => scrollWidth);
|
|
|
+ if (!keepZoomLevel) {
|
|
|
+ scrollingElement.__defineGetter__("clientHeight", () => scrollHeight);
|
|
|
+ scrollingElement.__defineGetter__("clientWidth", () => scrollWidth);
|
|
|
+ screen.__defineGetter__("height", () => scrollHeight);
|
|
|
+ screen.__defineGetter__("width", () => scrollWidth);
|
|
|
+ if (!window._singleFile_getBoundingClientRect) {
|
|
|
+ window._singleFile_getBoundingClientRect = Element.prototype.getBoundingClientRect;
|
|
|
+ Element.prototype.getBoundingClientRect = function () {
|
|
|
+ const boundingRect = window._singleFile_getBoundingClientRect.call(this);
|
|
|
+ if (this == scrollingElement) {
|
|
|
+ boundingRect.__defineGetter__("height", () => scrollHeight);
|
|
|
+ boundingRect.__defineGetter__("bottom", () => scrollHeight + boundingRect.top);
|
|
|
+ boundingRect.__defineGetter__("width", () => scrollWidth);
|
|
|
+ boundingRect.__defineGetter__("right", () => scrollWidth + boundingRect.left);
|
|
|
+ }
|
|
|
+ return boundingRect;
|
|
|
+ };
|
|
|
+ window._singleFile_innerHeight = window.innerHeight;
|
|
|
+ window._singleFile_innerWidth = window.innerWidth;
|
|
|
+ window.__defineGetter__("innerHeight", () => scrollHeight);
|
|
|
+ window.__defineGetter__("innerWidth", () => scrollWidth);
|
|
|
+ }
|
|
|
}
|
|
|
if (!window._singleFileImage) {
|
|
|
const Image = window.Image;
|
|
|
@@ -123,8 +131,14 @@
|
|
|
};
|
|
|
});
|
|
|
}
|
|
|
- const zoomFactorX = (clientHeight + window.scrollY) / scrollHeight;
|
|
|
- const zoomFactorY = (clientWidth + window.scrollX) / scrollWidth;
|
|
|
+ let zoomFactorX, zoomFactorY;
|
|
|
+ if (keepZoomLevel) {
|
|
|
+ zoomFactorX = clientHeight / scrollHeight;
|
|
|
+ zoomFactorY = clientWidth / scrollWidth;
|
|
|
+ } else {
|
|
|
+ zoomFactorX = (clientHeight + window.scrollY) / scrollHeight;
|
|
|
+ zoomFactorY = (clientWidth + window.scrollX) / scrollWidth;
|
|
|
+ }
|
|
|
const zoomFactor = Math.min(zoomFactorX, zoomFactorY);
|
|
|
if (zoomFactor < 1) {
|
|
|
const transform = document.documentElement.style.getPropertyValue("transform");
|
|
|
@@ -135,54 +149,78 @@
|
|
|
document.documentElement.style.setProperty("transform", "scale3d(" + zoomFactor + ", " + zoomFactor + ", 1)", "important");
|
|
|
dispatchEvent.call(window, new UIEvent("resize"));
|
|
|
dispatchEvent.call(window, new UIEvent("scroll"));
|
|
|
- document.documentElement.style.setProperty("transform", transform, transformPriority);
|
|
|
- document.documentElement.style.setProperty("transform-origin", transformOrigin, transformOriginPriority);
|
|
|
- }
|
|
|
- dispatchEvent.call(window, new UIEvent("resize"));
|
|
|
- dispatchEvent.call(window, new UIEvent("scroll"));
|
|
|
- const docBoundingRect = scrollingElement.getBoundingClientRect();
|
|
|
- [...observers].forEach(([intersectionObserver, observer]) => {
|
|
|
- const rootBoundingRect = observer.options && observer.options.root && observer.options.root.getBoundingClientRect();
|
|
|
- const targetElements = observedElements.get(intersectionObserver);
|
|
|
- if (targetElements) {
|
|
|
- observer.callback(targetElements.map(target => {
|
|
|
- const boundingClientRect = target.getBoundingClientRect();
|
|
|
- const isIntersecting = true;
|
|
|
- const intersectionRatio = 1;
|
|
|
- const rootBounds = observer.options && observer.options.root ? rootBoundingRect : docBoundingRect;
|
|
|
- const time = 0;
|
|
|
- return { target, intersectionRatio, boundingClientRect, intersectionRect: boundingClientRect, isIntersecting, rootBounds, time };
|
|
|
- }), intersectionObserver);
|
|
|
+ if (keepZoomLevel) {
|
|
|
+ document.documentElement.style.setProperty("-sf-transform", transform, transformPriority);
|
|
|
+ document.documentElement.style.setProperty("-sf-transform-origin", transformOrigin, transformOriginPriority);
|
|
|
+ } else {
|
|
|
+ document.documentElement.style.setProperty("transform", transform, transformPriority);
|
|
|
+ document.documentElement.style.setProperty("transform-origin", transformOrigin, transformOriginPriority);
|
|
|
}
|
|
|
- });
|
|
|
+ }
|
|
|
+ if (!keepZoomLevel) {
|
|
|
+ dispatchEvent.call(window, new UIEvent("resize"));
|
|
|
+ dispatchEvent.call(window, new UIEvent("scroll"));
|
|
|
+ const docBoundingRect = scrollingElement.getBoundingClientRect();
|
|
|
+ [...observers].forEach(([intersectionObserver, observer]) => {
|
|
|
+ const rootBoundingRect = observer.options && observer.options.root && observer.options.root.getBoundingClientRect();
|
|
|
+ const targetElements = observedElements.get(intersectionObserver);
|
|
|
+ if (targetElements) {
|
|
|
+ observer.callback(targetElements.map(target => {
|
|
|
+ const boundingClientRect = target.getBoundingClientRect();
|
|
|
+ const isIntersecting = true;
|
|
|
+ const intersectionRatio = 1;
|
|
|
+ const rootBounds = observer.options && observer.options.root ? rootBoundingRect : docBoundingRect;
|
|
|
+ const time = 0;
|
|
|
+ return { target, intersectionRatio, boundingClientRect, intersectionRect: boundingClientRect, isIntersecting, rootBounds, time };
|
|
|
+ }), intersectionObserver);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ addEventListener.call(window, LOAD_DEFERRED_IMAGES_END_EVENT, () => loadDeferredImagesEnd());
|
|
|
+ addEventListener.call(window, LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_END_EVENT, () => loadDeferredImagesEnd(true));
|
|
|
+ addEventListener.call(window, LOAD_DEFERRED_IMAGES_RESET_ZOOM_LEVEL_END_EVENT, () => {
|
|
|
+ const transform = document.documentElement.style.getPropertyValue("-sf-transform");
|
|
|
+ const transformPriority = document.documentElement.style.getPropertyPriority("-sf-transform");
|
|
|
+ const transformOrigin = document.documentElement.style.getPropertyValue("-sf-transform-origin");
|
|
|
+ const transformOriginPriority = document.documentElement.style.getPropertyPriority("-sf-transform-origin");
|
|
|
+ document.documentElement.style.setProperty("transform", transform, transformPriority);
|
|
|
+ document.documentElement.style.setProperty("transform-origin", transformOrigin, transformOriginPriority);
|
|
|
+ document.documentElement.style.removeProperty("-sf-transform");
|
|
|
+ document.documentElement.style.removeProperty("-sf-transform-origin");
|
|
|
});
|
|
|
|
|
|
- addEventListener.call(window, LOAD_DEFERRED_IMAGES_END_EVENT, () => {
|
|
|
+ function loadDeferredImagesEnd(keepZoomLevel) {
|
|
|
const scrollingElement = document.scrollingElement || document.documentElement;
|
|
|
document.querySelectorAll("[" + LAZY_LOAD_ATTRIBUTE + "]").forEach(element => {
|
|
|
element.loading = "lazy";
|
|
|
element.removeAttribute(LAZY_LOAD_ATTRIBUTE);
|
|
|
});
|
|
|
- delete scrollingElement.clientHeight;
|
|
|
- delete scrollingElement.clientWidth;
|
|
|
- delete screen.height;
|
|
|
- delete screen.width;
|
|
|
- if (window._singleFile_getBoundingClientRect) {
|
|
|
- Element.prototype.getBoundingClientRect = window._singleFile_getBoundingClientRect;
|
|
|
- window.innerHeight = window._singleFile_innerHeight;
|
|
|
- window.innerWidth = window._singleFile_innerWidth;
|
|
|
- delete window._singleFile_getBoundingClientRect;
|
|
|
- delete window._singleFile_innerHeight;
|
|
|
- delete window._singleFile_innerWidth;
|
|
|
+ if (!keepZoomLevel) {
|
|
|
+ delete scrollingElement.clientHeight;
|
|
|
+ delete scrollingElement.clientWidth;
|
|
|
+ delete screen.height;
|
|
|
+ delete screen.width;
|
|
|
+ if (window._singleFile_getBoundingClientRect) {
|
|
|
+ Element.prototype.getBoundingClientRect = window._singleFile_getBoundingClientRect;
|
|
|
+ window.innerHeight = window._singleFile_innerHeight;
|
|
|
+ window.innerWidth = window._singleFile_innerWidth;
|
|
|
+ delete window._singleFile_getBoundingClientRect;
|
|
|
+ delete window._singleFile_innerHeight;
|
|
|
+ delete window._singleFile_innerWidth;
|
|
|
+ }
|
|
|
}
|
|
|
if (window._singleFileImage) {
|
|
|
delete window.Image;
|
|
|
window.Image = window._singleFileImage;
|
|
|
delete window._singleFileImage;
|
|
|
}
|
|
|
- dispatchEvent.call(window, new UIEvent("resize"));
|
|
|
- dispatchEvent.call(window, new UIEvent("scroll"));
|
|
|
- });
|
|
|
+ if (!keepZoomLevel) {
|
|
|
+ dispatchEvent.call(window, new UIEvent("resize"));
|
|
|
+ dispatchEvent.call(window, new UIEvent("scroll"));
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
addEventListener.call(window, BLOCK_COOKIES_START_EVENT, () => {
|
|
|
try {
|