easter-egg-quest 1.0.25 → 1.0.26
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.
|
@@ -567,6 +567,8 @@ class HiddenEntry {
|
|
|
567
567
|
this.clickHandler = null;
|
|
568
568
|
this.fallbackButton = null;
|
|
569
569
|
this._injectedElement = null;
|
|
570
|
+
this._replacedTextNode = null;
|
|
571
|
+
this._replacedTextContent = "";
|
|
570
572
|
this._destroyed = false;
|
|
571
573
|
this._hintVisibleElapsed = 0;
|
|
572
574
|
this._hintVisibleStart = 0;
|
|
@@ -610,6 +612,7 @@ class HiddenEntry {
|
|
|
610
612
|
}
|
|
611
613
|
this._stopWatchdog();
|
|
612
614
|
this._stopBootstrapWatch();
|
|
615
|
+
this._restoreReplacedText();
|
|
613
616
|
(_a2 = this._injectedElement) == null ? void 0 : _a2.remove();
|
|
614
617
|
this._injectedElement = null;
|
|
615
618
|
(_b2 = this.hintContainer) == null ? void 0 : _b2.remove();
|
|
@@ -680,31 +683,8 @@ class HiddenEntry {
|
|
|
680
683
|
for (const candidate of ordered) {
|
|
681
684
|
const host = candidate;
|
|
682
685
|
if (!this._canHostInjectedTrigger(host)) continue;
|
|
683
|
-
const
|
|
684
|
-
|
|
685
|
-
span.textContent = isInline ? " · start hunt" : " start hunt";
|
|
686
|
-
span.setAttribute("data-eeq", "trigger");
|
|
687
|
-
span.classList.add("eeq-inline-trigger");
|
|
688
|
-
span.style.cssText = `
|
|
689
|
-
font: inherit;
|
|
690
|
-
color: inherit;
|
|
691
|
-
letter-spacing: inherit;
|
|
692
|
-
cursor: pointer;
|
|
693
|
-
white-space: nowrap;
|
|
694
|
-
transition: filter 0.18s ease, opacity 0.18s ease, text-shadow 0.18s ease;
|
|
695
|
-
`;
|
|
696
|
-
const inserted = !isInline && this._tryInsertBetweenWords(host, span);
|
|
697
|
-
if (!inserted) {
|
|
698
|
-
const heightBefore = host.getBoundingClientRect().height;
|
|
699
|
-
const widthBefore = host.getBoundingClientRect().width;
|
|
700
|
-
host.appendChild(span);
|
|
701
|
-
const heightAfter = host.getBoundingClientRect().height;
|
|
702
|
-
const widthAfter = host.getBoundingClientRect().width;
|
|
703
|
-
if (Math.abs(heightAfter - heightBefore) > 2 || Math.abs(widthAfter - widthBefore) > 24 || this._isTriggerClipped(host, span)) {
|
|
704
|
-
host.removeChild(span);
|
|
705
|
-
continue;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
686
|
+
const span = this._replaceTextCandidate(host);
|
|
687
|
+
if (!span) continue;
|
|
708
688
|
const idx = sorted.indexOf(candidate);
|
|
709
689
|
if (idx >= 0) {
|
|
710
690
|
usedSet.add(prints[idx]);
|
|
@@ -1009,6 +989,7 @@ class HiddenEntry {
|
|
|
1009
989
|
if (this._injectedElement && document.body.contains(this._injectedElement)) {
|
|
1010
990
|
this._injectedElement.remove();
|
|
1011
991
|
}
|
|
992
|
+
this._restoreReplacedText();
|
|
1012
993
|
this._injectedElement = null;
|
|
1013
994
|
this.targetElement = null;
|
|
1014
995
|
this._startBootstrapWatch();
|
|
@@ -1067,6 +1048,7 @@ class HiddenEntry {
|
|
|
1067
1048
|
const after = text.slice(splitAt);
|
|
1068
1049
|
const rectBefore = host.getBoundingClientRect();
|
|
1069
1050
|
const afterNode = document.createTextNode(after);
|
|
1051
|
+
this._applyTriggerTypography(span, parent);
|
|
1070
1052
|
textNode.textContent = before;
|
|
1071
1053
|
parent.insertBefore(span, textNode.nextSibling);
|
|
1072
1054
|
parent.insertBefore(afterNode, span.nextSibling);
|
|
@@ -1088,6 +1070,90 @@ class HiddenEntry {
|
|
|
1088
1070
|
}
|
|
1089
1071
|
return arr;
|
|
1090
1072
|
}
|
|
1073
|
+
_replaceTextCandidate(host) {
|
|
1074
|
+
const target = this._findReplacementTextTarget(host);
|
|
1075
|
+
if (!target) return null;
|
|
1076
|
+
const span = document.createElement("span");
|
|
1077
|
+
span.textContent = "start hunt";
|
|
1078
|
+
span.setAttribute("data-eeq", "trigger");
|
|
1079
|
+
span.classList.add("eeq-inline-trigger");
|
|
1080
|
+
this._applyTriggerTypography(span, target.parent);
|
|
1081
|
+
const rectBefore = host.getBoundingClientRect();
|
|
1082
|
+
target.textNode.textContent = "";
|
|
1083
|
+
target.parent.insertBefore(span, target.textNode.nextSibling);
|
|
1084
|
+
const rectAfter = host.getBoundingClientRect();
|
|
1085
|
+
const invalid = Math.abs(rectAfter.height - rectBefore.height) > 6 || Math.abs(rectAfter.width - rectBefore.width) > 20 || this._isTriggerClipped(host, span);
|
|
1086
|
+
if (invalid) {
|
|
1087
|
+
span.remove();
|
|
1088
|
+
target.textNode.textContent = target.text;
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
this._replacedTextNode = target.textNode;
|
|
1092
|
+
this._replacedTextContent = target.text;
|
|
1093
|
+
return span;
|
|
1094
|
+
}
|
|
1095
|
+
_findReplacementTextTarget(host) {
|
|
1096
|
+
const triggerLength = "start hunt".length;
|
|
1097
|
+
const textTargets = [];
|
|
1098
|
+
const walker = document.createTreeWalker(host, NodeFilter.SHOW_TEXT, {
|
|
1099
|
+
acceptNode: (node) => {
|
|
1100
|
+
const parent = node.parentElement;
|
|
1101
|
+
const text = this._normalizeComparableText(node.textContent ?? "");
|
|
1102
|
+
if (!parent || text.length === 0) return NodeFilter.FILTER_REJECT;
|
|
1103
|
+
if (parent.closest("[data-eeq], script, style, noscript")) return NodeFilter.FILTER_REJECT;
|
|
1104
|
+
if (!isElementVisible(parent)) return NodeFilter.FILTER_REJECT;
|
|
1105
|
+
if (Math.abs(text.length - triggerLength) > 10) return NodeFilter.FILTER_REJECT;
|
|
1106
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
1107
|
+
}
|
|
1108
|
+
});
|
|
1109
|
+
let current = walker.nextNode();
|
|
1110
|
+
while (current) {
|
|
1111
|
+
const textNode = current;
|
|
1112
|
+
const parent = textNode.parentElement;
|
|
1113
|
+
const text = textNode.textContent ?? "";
|
|
1114
|
+
if (parent) {
|
|
1115
|
+
textTargets.push({ textNode, parent, text });
|
|
1116
|
+
}
|
|
1117
|
+
current = walker.nextNode();
|
|
1118
|
+
}
|
|
1119
|
+
if (!textTargets.length) return null;
|
|
1120
|
+
const shuffled = this._shuffleTextTargets(textTargets);
|
|
1121
|
+
return shuffled[0] ?? null;
|
|
1122
|
+
}
|
|
1123
|
+
_shuffleTextTargets(values) {
|
|
1124
|
+
const arr = [...values];
|
|
1125
|
+
for (let i = arr.length - 1; i > 0; i--) {
|
|
1126
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
1127
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
1128
|
+
}
|
|
1129
|
+
return arr;
|
|
1130
|
+
}
|
|
1131
|
+
_normalizeComparableText(text) {
|
|
1132
|
+
return text.replace(/\s+/g, " ").trim();
|
|
1133
|
+
}
|
|
1134
|
+
_restoreReplacedText() {
|
|
1135
|
+
if (this._replacedTextNode) {
|
|
1136
|
+
this._replacedTextNode.textContent = this._replacedTextContent;
|
|
1137
|
+
}
|
|
1138
|
+
this._replacedTextNode = null;
|
|
1139
|
+
this._replacedTextContent = "";
|
|
1140
|
+
}
|
|
1141
|
+
_applyTriggerTypography(span, source) {
|
|
1142
|
+
const style = getComputedStyle(source);
|
|
1143
|
+
span.style.cssText = `
|
|
1144
|
+
font-family: ${style.fontFamily};
|
|
1145
|
+
font-size: ${style.fontSize};
|
|
1146
|
+
font-weight: ${style.fontWeight};
|
|
1147
|
+
font-style: ${style.fontStyle};
|
|
1148
|
+
line-height: ${style.lineHeight};
|
|
1149
|
+
letter-spacing: ${style.letterSpacing};
|
|
1150
|
+
text-transform: ${style.textTransform};
|
|
1151
|
+
color: ${style.color};
|
|
1152
|
+
cursor: pointer;
|
|
1153
|
+
white-space: nowrap;
|
|
1154
|
+
transition: color 0.18s ease;
|
|
1155
|
+
`;
|
|
1156
|
+
}
|
|
1091
1157
|
// ─── Shared ───────────────────────────────────────────────────────────
|
|
1092
1158
|
_attachToElement(el) {
|
|
1093
1159
|
this.clickHandler = (e) => {
|
|
@@ -1279,9 +1345,7 @@ class HiddenEntry {
|
|
|
1279
1345
|
animation: eeq-shimmer 3s ease-in-out infinite !important;
|
|
1280
1346
|
}
|
|
1281
1347
|
.eeq-inline-trigger:hover {
|
|
1282
|
-
|
|
1283
|
-
opacity: 1;
|
|
1284
|
-
text-shadow: 0 0 10px rgba(255, 248, 220, 0.35);
|
|
1348
|
+
color: ${this.config.theme.accent};
|
|
1285
1349
|
}
|
|
1286
1350
|
@keyframes eeq-shimmer {
|
|
1287
1351
|
0%, 100% { opacity: 1; }
|