Skip to content

Commit 84e511a

Browse files
committed
fix: renamed prefix-delay to prefix-setTimout
1 parent 44372d4 commit 84e511a

1 file changed

Lines changed: 174 additions & 1 deletion

File tree

src/index.js

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,26 @@ const CoCreateEvents = {
405405
}
406406

407407
for (let element of elements) {
408-
let delay = element.getAttribute(`${prefix}-delay`);
408+
// const requestAnimationFrameAttr = element.getAttribute(
409+
// `${prefix}-requestAnimationFrame`
410+
// );
411+
412+
// if (
413+
// requestAnimationFrameAttr !== null &&
414+
// requestAnimationFrameAttr !== "false"
415+
// ) {
416+
// // Double requestAnimationFrame
417+
// await new Promise((resolve) => {
418+
// requestAnimationFrame(() => {
419+
// requestAnimationFrame(() => {
420+
// resolve();
421+
// });
422+
// });
423+
// });
424+
// }
425+
426+
// TODO: Handle setInterval logic
427+
let delay = element.getAttribute(`${prefix}-setTimeout`);
409428

410429
if (delay) {
411430
delay = parseInt(delay, 10) || 0;
@@ -941,6 +960,160 @@ function parseNumberCondition(condition) {
941960
: condition;
942961
}
943962

963+
// Helper function for delay using Promises
964+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
965+
966+
/**
967+
* Waits for a specific element property to meet a readiness condition,
968+
* based on retry attributes defined on the element.
969+
* Incorporates optional exponential backoff for retry delays.
970+
* Returns a Promise that resolves to true if the condition is met within
971+
* the allowed attempts, and false otherwise.
972+
*
973+
* @param {HTMLElement} element The element with the onload-retry-* attributes.
974+
* @returns {Promise<boolean>} A Promise resolving to true if ready, false if timed out.
975+
*/
976+
async function checkElementReadinessWithBackoff(element) {
977+
const propertyName = element.getAttribute("onload-retry-property");
978+
979+
if (!propertyName) {
980+
return true; // No retry needed
981+
}
982+
983+
// --- Retry Parameters ---
984+
const maxAttempts =
985+
parseInt(element.getAttribute("onload-retry-attempts") || "3", 10) || 3;
986+
// Initial delay (used for the first wait and as the base for backoff)
987+
const initialDelayMs =
988+
parseInt(element.getAttribute("onload-retry-delay") || "100", 10) ||
989+
100;
990+
// Exponential backoff factor (e.g., 2 for doubling). <= 1 means fixed delay.
991+
// Default to 1 (no backoff) if missing or invalid.
992+
const backoffFactor =
993+
parseFloat(
994+
element.getAttribute("onload-retry-backoff-factor") || "1"
995+
) || 1;
996+
// Optional maximum delay cap. Use Infinity if missing, invalid, or <= 0.
997+
const maxDelayMs = parseInt(
998+
element.getAttribute("onload-retry-max-delay") || "0",
999+
10
1000+
);
1001+
const effectiveMaxDelay =
1002+
maxDelayMs && maxDelayMs > 0 ? maxDelayMs : Infinity;
1003+
1004+
console.log(
1005+
`Checking readiness for property "${propertyName}" on element ${
1006+
element.id || ""
1007+
}. Max attempts: ${maxAttempts}, Initial Delay: ${initialDelayMs}ms, Backoff Factor: ${backoffFactor}, Max Delay: ${
1008+
effectiveMaxDelay === Infinity ? "None" : effectiveMaxDelay + "ms"
1009+
}.`
1010+
);
1011+
1012+
// Initialize the delay to be used for the *first* wait.
1013+
let currentDelay = initialDelayMs;
1014+
1015+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
1016+
console.log(
1017+
`Attempt ${attempt}/${maxAttempts}: Checking "${propertyName}"...`
1018+
);
1019+
try {
1020+
const propertyValue = element[propertyName];
1021+
// Example check: Adjust condition as needed
1022+
if (propertyValue !== undefined && propertyValue > 0) {
1023+
console.log(
1024+
`Property "${propertyName}" ready on attempt ${attempt}. Value: ${propertyValue}`
1025+
);
1026+
return true; // Condition met
1027+
}
1028+
} catch (error) {
1029+
console.error(
1030+
`Error accessing property "${propertyName}" on attempt ${attempt}:`,
1031+
error
1032+
);
1033+
}
1034+
1035+
// If condition not met and more attempts remain:
1036+
if (attempt < maxAttempts) {
1037+
// Determine the actual delay for this wait, applying the cap
1038+
const delayForThisWait = Math.min(currentDelay, effectiveMaxDelay);
1039+
1040+
console.log(
1041+
`Waiting ${Math.round(
1042+
delayForThisWait
1043+
)}ms before next attempt...`
1044+
);
1045+
await delay(delayForThisWait);
1046+
1047+
// Calculate the delay for the *next* potential wait, only if backoff is active
1048+
if (backoffFactor > 1) {
1049+
currentDelay = currentDelay * backoffFactor;
1050+
// Note: We apply the cap just before the actual delay,
1051+
// but the base 'currentDelay' keeps growing exponentially.
1052+
// Alternatively, you could cap 'currentDelay' itself here:
1053+
// currentDelay = Math.min(currentDelay * backoffFactor, effectiveMaxDelay);
1054+
// Let's stick to capping just before delay() for now.
1055+
}
1056+
// If backoffFactor <= 1, currentDelay remains initialDelayMs (implicitly handled by initialization)
1057+
}
1058+
}
1059+
1060+
// If loop finishes without condition being met
1061+
console.warn(
1062+
`Readiness check failed for property "${propertyName}" on element ${
1063+
element.id || ""
1064+
} after ${maxAttempts} attempts.`
1065+
);
1066+
return false; // Timed out
1067+
}
1068+
1069+
// --- Example Usage (calling code doesn't change) ---
1070+
1071+
async function handleElementProcessingWithBackoff(element) {
1072+
// Call the function that now supports backoff
1073+
const isReady = await checkElementReadinessWithBackoff(element);
1074+
1075+
if (isReady) {
1076+
console.log(
1077+
`Element ${element.id || ""} is ready. Proceeding with actions.`
1078+
);
1079+
// --- Execute subsequent actions ---
1080+
if (element.hasAttribute("onload-attribute")) {
1081+
/* ... */
1082+
}
1083+
if (element.hasAttribute("onload-next")) {
1084+
/* ... */
1085+
}
1086+
} else {
1087+
console.warn(
1088+
`Skipping actions for element ${
1089+
element.id || ""
1090+
} because readiness check failed.`
1091+
);
1092+
}
1093+
}
1094+
1095+
// --- Example Elements ---
1096+
1097+
// With Backoff (Delays: 100, 200, 400, 800 - capped)
1098+
// <span id="elem1" onload-retry-property="scrollWidth"
1099+
// onload-retry-attempts="5" onload-retry-delay="100"
1100+
// onload-retry-backoff-factor="2" onload-retry-max-delay="500">
1101+
// Content 1
1102+
// </span>
1103+
// Waits would be: 100ms, 200ms, 400ms, 500ms (capped)
1104+
1105+
// No Backoff (factor missing/invalid/<=1)
1106+
// <span id="elem2" onload-retry-property="clientHeight"
1107+
// onload-retry-attempts="4" onload-retry-delay="300">
1108+
// Content 2
1109+
// </span>
1110+
// Waits would be: 300ms, 300ms, 300ms
1111+
1112+
// const element1 = document.getElementById('elem1');
1113+
// if (element1) handleElementProcessingWithBackoff(element1);
1114+
// const element2 = document.getElementById('elem2');
1115+
// if (element2) handleElementProcessingWithBackoff(element2);
1116+
9441117
CoCreateEvents.init();
9451118

9461119
export default CoCreateEvents;

0 commit comments

Comments
 (0)