Skip to content

Commit

Permalink
Refine strategy to include more edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
calinoracation committed Mar 1, 2024
1 parent 4f99a6f commit 5f62c88
Showing 1 changed file with 39 additions and 12 deletions.
51 changes: 39 additions & 12 deletions src/scroll-timeline-css.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,32 @@ import { ScrollTimeline, ViewTimeline, getScrollParent, calculateRange,
calculateRelativePosition, measureSubject, measureSource } from "./scroll-timeline-base";

const parser = new StyleParser();
let hasFetchedRemoteStylesheets = false;
const ObserverState = {
allowedOrigins: '*',
initialized: false,
shouldFetchLinkedStylesheets: true,
sheetObserver: null,
}

/**
* @param {'*' | string | RegExp | Array<string | RegExp>} allowedOrigins
*/
function initMutationObserver(allowedOrigins) {
const sheetObserver = new MutationObserver((entries) => {
function initMutationObserver(configuredAllowedOrigins) {
// If called with the same parameters as on startup, we don't need to reinitialize.
if (ObserverState.initialized && ObserverState.allowedOrigins === configuredAllowedOrigins) {
return;
}

if (configuredAllowedOrigins !== undefined && ObserverState.allowedOrigins !== configuredAllowedOrigins) {
ObserverState.shouldFetchLinkedStylesheets = true;
}

if (ObserverState.sheetObserver) {
ObserverState.sheetObserver.disconnect();
}

ObserverState.allowedOrigins = configuredAllowedOrigins;
ObserverState.sheetObserver = new MutationObserver((entries) => {
for (const entry of entries) {
for (const addedNode of entry.addedNodes) {
if (addedNode instanceof HTMLStyleElement) {
Expand All @@ -26,7 +45,7 @@ function initMutationObserver(allowedOrigins) {
// We accomplish this by swapping out Element.prototype.style.
});

sheetObserver.observe(document.documentElement, {
ObserverState.sheetObserver.observe(document.documentElement, {
childList: true,
subtree: true,
});
Expand All @@ -46,6 +65,7 @@ function initMutationObserver(allowedOrigins) {
}

function isAllowedOrigin(href) {
const allowedOrigins = ObserverState.allowedOrigins;
if (allowedOrigins == '*') return true;
const url = new URL(href, document.baseURI);
// If specified as false or anything not truthy, default to same origin.
Expand All @@ -65,11 +85,12 @@ function initMutationObserver(allowedOrigins) {

function handleLinkedStylesheet(linkElement) {
// Filter only css links to external stylesheets.
if (linkElement.type != 'text/css' && linkElement.rel != 'stylesheet' || !linkElement.href) {
if (linkElement.type != 'text/css' && linkElement.rel != 'stylesheet' || !linkElement.href || linkElement.href.startsWith('blob:')) {
return;
}
if (!isAllowedOrigin(linkElement.href)) {
// Don't attempt to fetch resources from regions not in the allowlist.
// Don't attempt to fetch resources from regions not in the allowlist or
// ones already parsed into a blob.
return;
}
fetch(linkElement.getAttribute('href')).then(async (response) => {
Expand All @@ -85,13 +106,19 @@ function initMutationObserver(allowedOrigins) {
}

document.querySelectorAll("style").forEach((tag) => handleStyleTag(tag));
if (!hasFetchedRemoteStylesheets) {
hasFetchedRemoteStylesheets = true;
Promise.resolve().then(() => {
if (ObserverState.shouldFetchLinkedStylesheets) {
if (!ObserverState.initialized) {
ObserverState.initialized = true;
Promise.resolve().then(() => {
document
.querySelectorAll("link")
.forEach((tag) => handleLinkedStylesheet(tag));
});
} else {
document
.querySelectorAll("link")
.forEach((tag) => handleLinkedStylesheet(tag));
});
.querySelectorAll("link")
.forEach((tag) => handleLinkedStylesheet(tag));
}
}
}

Expand Down

0 comments on commit 5f62c88

Please sign in to comment.