Skip to content

Commit

Permalink
Deploy preview for PR 19 🛫
Browse files Browse the repository at this point in the history
  • Loading branch information
rossjrw committed Sep 10, 2024
1 parent cf924de commit 6a5b6c2
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 11 deletions.
2 changes: 1 addition & 1 deletion pr-preview/pr-19/scp-3211/en/3211@2.0.3.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pr-preview/pr-19/scp-3211/jp/3211@2.0.3.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pr-preview/pr-19/scp-3211/zh/3211@2.0.3.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 102 additions & 8 deletions pr-preview/pr-19/scp-head/controller@0.0.0.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
window.debug =
(new URLSearchParams(location.search).get("debug") || "") === "true";

// TODO: Predict what the next resize request will be and prefetch it

/**
* @typedef {Object} scoutReport
* @property {string} eventName
* @property {string} scoutName
* @property {boolean} isIntersecting
* @property {string | null} direction
Expand Down Expand Up @@ -58,6 +57,9 @@

/** @type {number} */
this.#activeAssertion = this.minId;

/** @type {Set.<number>} */
this.knownUpcomingStages = new Set();
}

/** @param {number} value */
Expand All @@ -73,6 +75,15 @@
get activeAssertion() {
return this.#activeAssertion;
}

/** @returns {number | null} */
get expectedNextAssertion() {
const upcomingAssertions = [...this.knownUpcomingStages].filter(
(n) => n > this.#activeAssertion
);
if (upcomingAssertions.length === 0) return null;
return Math.min(...upcomingAssertions);
}
};

/** @type {Object.<string, AssertionChannel>} */
Expand Down Expand Up @@ -194,24 +205,107 @@
}

function sendAssertionState(resize) {
const message = [
// Remove all preloaders
document
.querySelectorAll(".preload-iframe")
.forEach((iframe) => iframe.remove());

const assertionState = [
assertionChannels["A"].activeAssertion,
".",
assertionChannels["B"].activeAssertion,
"0",
assertionChannels["C"].activeAssertion,
].join("");
console.debug("Updating assertion state to", message);
resize(message);
console.debug("Updating assertion state to", assertionState);
resize(assertionState);

preloadNextAssertionState();
}

function preloadNextAssertionState() {
// Work out each of the possible next assertion states, assuming that each channel is equally likely to advance to its next stage
const possibleAssertionStates = [];
for (const [channelName, channel] of Object.entries(
assertionChannels
)) {
if (channel.expectedNextAssertion) {
possibleAssertionStates.push(
[
assertionChannels["A"][
channelName === "A"
? "activeAssertion"
: "expectedNextAssertion"
],
".",
assertionChannels["B"][
channelName === "B"
? "activeAssertion"
: "expectedNextAssertion"
],
"0",
assertionChannels["C"][
channelName === "C"
? "activeAssertion"
: "expectedNextAssertion"
],
].join("")
);
}
}
for (const possibleAssertionState of possibleAssertionStates) {
console.debug(`Preloading assertion state ${possibleAssertionState}`);
const preloadIframe = document.createElement("iframe");
// Iframe is fully sandboxed - allow-same-origin being implicitly false should prevent the controller being resized
preloadIframe.sandbox = true;
preloadIframe.classList.add("preload-iframe");
document.body.appendChild(preloadIframe);
preloadIframe.src =
document.referrer +
"/common--javascript/resize-iframe.html?" +
"#" +
possibleAssertionState +
"/" +
location.href.replace(/^.*\//, "/");
}
}

/**
* @param {MessageEvent<scoutReport>} message
* @param {function} resize
*/
function processScoutReport(message, resize) {
if (message.origin !== location.origin) return;
if (!message.data.scoutName) return;

/** @type {scoutReport} */
const scoutReport = message.data;
if (!scoutReport.scoutName) return;

switch (scoutReport.eventName) {
case "ScoutRegistration":
processScoutRegistrationEvent(scoutReport);
break;
case "ScoutIntersectionStateChange":
processScoutIntersectionEvent(scoutReport, resize);
break;
default:
throw new Error(`Unknown event: ${scoutReport.eventName}`);
}
}

/**
* @param {scoutReport} scoutReport
*/
function processScoutRegistrationEvent(scoutReport) {
// Store contradiction IDs in the corresponding channel to be used for preloading
for (const c of scoutReport.contradictions) {
assertionChannels[c.channelName].knownUpcomingStages.push(c.id);
}
}

/**
* @param {scoutReport} scoutReport
* @param {function} resize
*/
function processScoutIntersectionEvent(scoutReport, resize) {
// Receive list of assertions
const scoutAssertions = scoutReport.assertions;

Expand Down
9 changes: 9 additions & 0 deletions pr-preview/pr-19/scp-head/scout@0.0.0.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@
if (!controller)
throw new Error(`Scout ${scoutName} failed to get controller`);

// Let the controller know that this scout exists
controller.postMessage({
eventName: "ScoutRegistration",
scoutName,
assertions,
contradictions,
});

// Scout is split into two, like poles of a magnet, for direction detection
const poleTop = {
element: document.querySelector(".scout__top"),
Expand Down Expand Up @@ -173,6 +181,7 @@
if (entries.length === 2) {
if (window.debug) console.debug(`${scoutName} sending`);
controller.postMessage({
eventName: "ScoutIntersectionStateChange",
scoutName,
isIntersecting:
poleTop.intersectionRatio + poleBottom.intersectionRatio >= 1,
Expand Down

0 comments on commit 6a5b6c2

Please sign in to comment.