easter-egg-quest 1.0.24 → 1.0.25
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.
|
@@ -662,12 +662,9 @@ class HiddenEntry {
|
|
|
662
662
|
const navEls = sorted.filter(
|
|
663
663
|
(el) => el.closest("nav") !== null || el.closest("header") !== null
|
|
664
664
|
);
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
...bodyEls.slice(0, offset),
|
|
669
|
-
...navEls
|
|
670
|
-
];
|
|
665
|
+
const rotated = this._shuffleCandidates(bodyEls, visitCount).concat(
|
|
666
|
+
this._shuffleCandidates(navEls, visitCount + 17)
|
|
667
|
+
);
|
|
671
668
|
const rotatedPrints = rotated.map(
|
|
672
669
|
(el) => {
|
|
673
670
|
var _a3;
|
|
@@ -682,22 +679,28 @@ class HiddenEntry {
|
|
|
682
679
|
const ordered = unused.length > 0 ? [...unused, ...rotated.filter((_, i) => usedSet.has(rotatedPrints[i]))] : rotated;
|
|
683
680
|
for (const candidate of ordered) {
|
|
684
681
|
const host = candidate;
|
|
682
|
+
if (!this._canHostInjectedTrigger(host)) continue;
|
|
685
683
|
const isInline = host.tagName === "A" || host.tagName === "BUTTON" || host.tagName === "LI" || host.closest("nav") !== null;
|
|
686
684
|
const span = document.createElement("span");
|
|
687
685
|
span.textContent = isInline ? " · start hunt" : " start hunt";
|
|
688
686
|
span.setAttribute("data-eeq", "trigger");
|
|
687
|
+
span.classList.add("eeq-inline-trigger");
|
|
689
688
|
span.style.cssText = `
|
|
690
689
|
font: inherit;
|
|
691
690
|
color: inherit;
|
|
692
691
|
letter-spacing: inherit;
|
|
693
692
|
cursor: pointer;
|
|
693
|
+
white-space: nowrap;
|
|
694
|
+
transition: filter 0.18s ease, opacity 0.18s ease, text-shadow 0.18s ease;
|
|
694
695
|
`;
|
|
695
696
|
const inserted = !isInline && this._tryInsertBetweenWords(host, span);
|
|
696
697
|
if (!inserted) {
|
|
697
698
|
const heightBefore = host.getBoundingClientRect().height;
|
|
699
|
+
const widthBefore = host.getBoundingClientRect().width;
|
|
698
700
|
host.appendChild(span);
|
|
699
701
|
const heightAfter = host.getBoundingClientRect().height;
|
|
700
|
-
|
|
702
|
+
const widthAfter = host.getBoundingClientRect().width;
|
|
703
|
+
if (Math.abs(heightAfter - heightBefore) > 2 || Math.abs(widthAfter - widthBefore) > 24 || this._isTriggerClipped(host, span)) {
|
|
701
704
|
host.removeChild(span);
|
|
702
705
|
continue;
|
|
703
706
|
}
|
|
@@ -814,9 +817,53 @@ class HiddenEntry {
|
|
|
814
817
|
if (childElementCount > 12) return false;
|
|
815
818
|
const rect = el.getBoundingClientRect();
|
|
816
819
|
if (rect.width < 18 || rect.height < 12) return false;
|
|
820
|
+
if (!this._canHostInjectedTrigger(el)) return false;
|
|
817
821
|
return true;
|
|
818
822
|
});
|
|
819
823
|
}
|
|
824
|
+
_shuffleCandidates(candidates, seed) {
|
|
825
|
+
if (candidates.length < 2) return [...candidates];
|
|
826
|
+
const arr = [...candidates];
|
|
827
|
+
let state = (seed || 1) ^ Date.now() & 65535;
|
|
828
|
+
const rand = () => {
|
|
829
|
+
state ^= state << 13;
|
|
830
|
+
state ^= state >>> 17;
|
|
831
|
+
state ^= state << 5;
|
|
832
|
+
return (state >>> 0) % 1e4 / 1e4;
|
|
833
|
+
};
|
|
834
|
+
for (let i = arr.length - 1; i > 0; i--) {
|
|
835
|
+
const j = Math.floor(rand() * (i + 1));
|
|
836
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
837
|
+
}
|
|
838
|
+
return arr;
|
|
839
|
+
}
|
|
840
|
+
_canHostInjectedTrigger(host) {
|
|
841
|
+
const style = getComputedStyle(host);
|
|
842
|
+
const textOverflow = style.textOverflow;
|
|
843
|
+
const whiteSpace = style.whiteSpace;
|
|
844
|
+
const overflowX = style.overflowX;
|
|
845
|
+
const overflow = style.overflow;
|
|
846
|
+
if (textOverflow === "ellipsis") return false;
|
|
847
|
+
if (whiteSpace === "nowrap" && ["hidden", "clip"].includes(overflowX || overflow)) return false;
|
|
848
|
+
if (host.scrollWidth > host.clientWidth + 2 && host.clientWidth > 0) return false;
|
|
849
|
+
if (host.scrollHeight > host.clientHeight + 2 && host.clientHeight > 0 && whiteSpace === "nowrap") return false;
|
|
850
|
+
return true;
|
|
851
|
+
}
|
|
852
|
+
_isTriggerClipped(host, span) {
|
|
853
|
+
if (!document.body.contains(span)) return true;
|
|
854
|
+
const hostRect = host.getBoundingClientRect();
|
|
855
|
+
const spanRect = span.getBoundingClientRect();
|
|
856
|
+
const style = getComputedStyle(host);
|
|
857
|
+
const clipsHorizontally = ["hidden", "clip"].includes(style.overflowX || style.overflow);
|
|
858
|
+
const clipsVertically = ["hidden", "clip"].includes(style.overflowY || style.overflow);
|
|
859
|
+
if (host.scrollWidth > host.clientWidth + 2 && host.clientWidth > 0) return true;
|
|
860
|
+
if (style.textOverflow === "ellipsis") return true;
|
|
861
|
+
if (clipsHorizontally && spanRect.right > hostRect.right - 1) return true;
|
|
862
|
+
if (clipsHorizontally && spanRect.left < hostRect.left + 1) return true;
|
|
863
|
+
if (clipsVertically && spanRect.bottom > hostRect.bottom - 1) return true;
|
|
864
|
+
if (clipsVertically && spanRect.top < hostRect.top + 1) return true;
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
820
867
|
_startBootstrapWatch() {
|
|
821
868
|
this._stopBootstrapWatch();
|
|
822
869
|
const root = this._getSearchRoot();
|
|
@@ -982,8 +1029,8 @@ class HiddenEntry {
|
|
|
982
1029
|
const walker = document.createTreeWalker(host, NodeFilter.SHOW_TEXT, {
|
|
983
1030
|
acceptNode: (node) => {
|
|
984
1031
|
var _a2;
|
|
985
|
-
const
|
|
986
|
-
if (
|
|
1032
|
+
const text = ((_a2 = node.textContent) == null ? void 0 : _a2.trim()) ?? "";
|
|
1033
|
+
if (text.length <= 5) return NodeFilter.FILTER_REJECT;
|
|
987
1034
|
const parent = node.parentElement;
|
|
988
1035
|
if (!parent) return NodeFilter.FILTER_REJECT;
|
|
989
1036
|
if (parent.closest("[data-eeq], script, style, noscript")) return NodeFilter.FILTER_REJECT;
|
|
@@ -996,33 +1043,50 @@ class HiddenEntry {
|
|
|
996
1043
|
current = walker.nextNode();
|
|
997
1044
|
}
|
|
998
1045
|
if (!textNodes.length) return false;
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1046
|
+
const textNodesOrdered = this._shuffleCandidates(
|
|
1047
|
+
textNodes.map((node) => node.parentElement).filter((el) => !!el),
|
|
1048
|
+
Date.now()
|
|
1049
|
+
);
|
|
1050
|
+
const uniqueTextNodes = textNodesOrdered.map((parent) => textNodes.find((node) => node.parentElement === parent)).filter((node) => !!node);
|
|
1051
|
+
for (const textNode of uniqueTextNodes) {
|
|
1052
|
+
const text = textNode.textContent ?? "";
|
|
1053
|
+
const parent = textNode.parentElement;
|
|
1054
|
+
if (!parent) continue;
|
|
1055
|
+
const spacePositions = [];
|
|
1056
|
+
for (let i = 1; i < text.length - 1; i++) {
|
|
1057
|
+
if (text[i] === " ") spacePositions.push(i);
|
|
1058
|
+
}
|
|
1059
|
+
if (spacePositions.length < 2) continue;
|
|
1060
|
+
const start = Math.floor(spacePositions.length * 0.2);
|
|
1061
|
+
const end = Math.ceil(spacePositions.length * 0.8);
|
|
1062
|
+
const candidateBreaks = this._shuffleNumbers(
|
|
1063
|
+
spacePositions.slice(start, Math.max(start + 1, end))
|
|
1064
|
+
);
|
|
1065
|
+
for (const splitAt of candidateBreaks) {
|
|
1066
|
+
const before = text.slice(0, splitAt);
|
|
1067
|
+
const after = text.slice(splitAt);
|
|
1068
|
+
const rectBefore = host.getBoundingClientRect();
|
|
1069
|
+
const afterNode = document.createTextNode(after);
|
|
1070
|
+
textNode.textContent = before;
|
|
1071
|
+
parent.insertBefore(span, textNode.nextSibling);
|
|
1072
|
+
parent.insertBefore(afterNode, span.nextSibling);
|
|
1073
|
+
const rectAfter = host.getBoundingClientRect();
|
|
1074
|
+
const invalid = Math.abs(rectAfter.height - rectBefore.height) > 8 || Math.abs(rectAfter.width - rectBefore.width) > 24 || this._isTriggerClipped(host, span);
|
|
1075
|
+
if (!invalid) return true;
|
|
1076
|
+
span.remove();
|
|
1077
|
+
afterNode.remove();
|
|
1078
|
+
textNode.textContent = text;
|
|
1079
|
+
}
|
|
1024
1080
|
}
|
|
1025
|
-
return
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
_shuffleNumbers(values) {
|
|
1084
|
+
const arr = [...values];
|
|
1085
|
+
for (let i = arr.length - 1; i > 0; i--) {
|
|
1086
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
1087
|
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
1088
|
+
}
|
|
1089
|
+
return arr;
|
|
1026
1090
|
}
|
|
1027
1091
|
// ─── Shared ───────────────────────────────────────────────────────────
|
|
1028
1092
|
_attachToElement(el) {
|
|
@@ -1214,6 +1278,11 @@ class HiddenEntry {
|
|
|
1214
1278
|
.eeq-entry-target {
|
|
1215
1279
|
animation: eeq-shimmer 3s ease-in-out infinite !important;
|
|
1216
1280
|
}
|
|
1281
|
+
.eeq-inline-trigger:hover {
|
|
1282
|
+
filter: brightness(1.35);
|
|
1283
|
+
opacity: 1;
|
|
1284
|
+
text-shadow: 0 0 10px rgba(255, 248, 220, 0.35);
|
|
1285
|
+
}
|
|
1217
1286
|
@keyframes eeq-shimmer {
|
|
1218
1287
|
0%, 100% { opacity: 1; }
|
|
1219
1288
|
50% { opacity: 0.55; }
|