Skip to content

Commit da19cb3

Browse files
committed
feat: enhance checkout board mutation handling and add related tests
1 parent d821639 commit da19cb3

3 files changed

Lines changed: 489 additions & 23 deletions

File tree

dist/autodarts-xconfig.user.js

Lines changed: 172 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8597,6 +8597,150 @@
85978597
var FEATURE_KEY2 = "checkout-board-targets";
85988598
var OBSERVER_KEY2 = `${FEATURE_KEY2}:dom-observer`;
85998599
var TRANSIENT_ROUTE_RETENTION_MS = 1500;
8600+
var CHECKOUT_SEMANTIC_ATTRIBUTE_SELECTORS = Object.freeze([
8601+
"#ad-ext-game-variant",
8602+
".suggestion",
8603+
"#ad-ext-turn",
8604+
".ad-ext-turn-throw",
8605+
".ad-ext-turn-points"
8606+
]);
8607+
var CHECKOUT_SEMANTIC_TEXT_SELECTORS = Object.freeze([
8608+
...CHECKOUT_SEMANTIC_ATTRIBUTE_SELECTORS,
8609+
".ad-ext-player-score"
8610+
]);
8611+
var CHECKOUT_SEMANTIC_CHILDLIST_SELECTORS = Object.freeze([
8612+
...CHECKOUT_SEMANTIC_TEXT_SELECTORS
8613+
]);
8614+
var BOARD_STRUCTURE_CHILDLIST_SELECTORS = Object.freeze([
8615+
"svg.ad-ext-theme-board-svg",
8616+
".ad-ext-theme-board-viewport svg",
8617+
".ad-ext-theme-board-canvas svg",
8618+
".ad-ext-tv-board-zoom-host svg",
8619+
".showAnimations svg",
8620+
".css-aiihgx svg",
8621+
".css-79elbk svg"
8622+
]);
8623+
function resolveMutationType(mutation) {
8624+
if (mutation?.type) {
8625+
return String(mutation.type);
8626+
}
8627+
if (mutation?.attributeName) {
8628+
return "attributes";
8629+
}
8630+
if (mutation?.addedNodes || mutation?.removedNodes) {
8631+
return "childList";
8632+
}
8633+
return "";
8634+
}
8635+
function toNodeArray2(value) {
8636+
if (!value || typeof value[Symbol.iterator] !== "function") {
8637+
return [];
8638+
}
8639+
return Array.from(value).filter(Boolean);
8640+
}
8641+
function getTouchedMutationNodes(mutation) {
8642+
return [
8643+
mutation?.target || null,
8644+
...toNodeArray2(mutation?.addedNodes),
8645+
...toNodeArray2(mutation?.removedNodes)
8646+
].filter(Boolean);
8647+
}
8648+
function nodeOrAncestorMatchesAnySelector(node, selectors = []) {
8649+
if (!node || !Array.isArray(selectors) || !selectors.length) {
8650+
return false;
8651+
}
8652+
return selectors.some((selector) => {
8653+
try {
8654+
return Boolean(node.closest?.(selector));
8655+
} catch (_) {
8656+
return false;
8657+
}
8658+
});
8659+
}
8660+
function nodesAreRelated(leftNode, rightNode) {
8661+
if (!leftNode || !rightNode) {
8662+
return false;
8663+
}
8664+
if (leftNode === rightNode) {
8665+
return true;
8666+
}
8667+
if (typeof leftNode.contains === "function" && leftNode.contains(rightNode)) {
8668+
return true;
8669+
}
8670+
if (typeof rightNode.contains === "function" && rightNode.contains(leftNode)) {
8671+
return true;
8672+
}
8673+
return false;
8674+
}
8675+
function shouldInvalidateBoardSurfaceForMutation(mutation, watchedNodes = []) {
8676+
if (resolveMutationType(mutation) !== "childList") {
8677+
return false;
8678+
}
8679+
const touchedNodes = getTouchedMutationNodes(mutation);
8680+
if (watchedNodes.some(
8681+
(watchedNode) => touchedNodes.some((touchedNode) => nodesAreRelated(touchedNode, watchedNode))
8682+
)) {
8683+
return true;
8684+
}
8685+
return touchedNodes.some(
8686+
(node) => nodeOrAncestorMatchesAnySelector(node, BOARD_STRUCTURE_CHILDLIST_SELECTORS)
8687+
);
8688+
}
8689+
function resolveCheckoutBoardMutationReaction(mutations = [], context = {}) {
8690+
if (!Array.isArray(mutations) || !mutations.length) {
8691+
return {
8692+
shouldSchedule: false,
8693+
shouldInvalidateBoardCache: false
8694+
};
8695+
}
8696+
const watchedNodes = [context.board?.svg || null, context.board?.group || null].filter(Boolean);
8697+
let shouldSchedule = false;
8698+
let shouldInvalidateBoardCache = false;
8699+
mutations.forEach((mutation) => {
8700+
if (shouldInvalidateBoardCache) {
8701+
return;
8702+
}
8703+
if (!mutation || typeof mutation !== "object") {
8704+
return;
8705+
}
8706+
const mutationType = resolveMutationType(mutation);
8707+
if (mutationType === "attributes") {
8708+
if (nodeOrAncestorMatchesAnySelector(
8709+
mutation.target,
8710+
CHECKOUT_SEMANTIC_ATTRIBUTE_SELECTORS
8711+
)) {
8712+
shouldSchedule = true;
8713+
}
8714+
return;
8715+
}
8716+
if (mutationType === "characterData") {
8717+
if (nodeOrAncestorMatchesAnySelector(mutation.target, CHECKOUT_SEMANTIC_TEXT_SELECTORS)) {
8718+
shouldSchedule = true;
8719+
}
8720+
return;
8721+
}
8722+
if (mutationType === "childList") {
8723+
const touchedNodes = getTouchedMutationNodes(mutation);
8724+
const touchesSemanticSurface = touchedNodes.some(
8725+
(node) => nodeOrAncestorMatchesAnySelector(node, CHECKOUT_SEMANTIC_CHILDLIST_SELECTORS)
8726+
);
8727+
const invalidatesBoardSurface = shouldInvalidateBoardSurfaceForMutation(
8728+
mutation,
8729+
watchedNodes
8730+
);
8731+
if (touchesSemanticSurface || invalidatesBoardSurface) {
8732+
shouldSchedule = true;
8733+
}
8734+
if (invalidatesBoardSurface) {
8735+
shouldInvalidateBoardCache = true;
8736+
}
8737+
}
8738+
});
8739+
return {
8740+
shouldSchedule,
8741+
shouldInvalidateBoardCache
8742+
};
8743+
}
86008744
function resolveDartsRemaining2(gameState) {
86018745
const throws = Array.isArray(gameState?.getActiveThrows?.()) ? gameState.getActiveThrows() : [];
86028746
const throwCount = Math.max(0, Math.min(3, throws.length));
@@ -9124,7 +9268,15 @@
91249268
if (!hasExternalDomMutation(mutations, isManagedNode)) {
91259269
return;
91269270
}
9127-
invalidateBoardCache();
9271+
const mutationReaction = resolveCheckoutBoardMutationReaction(mutations, {
9272+
board: boardCache.value
9273+
});
9274+
if (!mutationReaction.shouldSchedule) {
9275+
return;
9276+
}
9277+
if (mutationReaction.shouldInvalidateBoardCache) {
9278+
invalidateBoardCache();
9279+
}
91289280
scheduler.schedule();
91299281
},
91309282
observeOptions: createTurnSurfaceObserveOptions(),
@@ -10632,7 +10784,7 @@
1063210784
}
1063310785
return current || null;
1063410786
}
10635-
function nodeOrAncestorMatchesAnySelector(node, selectors = []) {
10787+
function nodeOrAncestorMatchesAnySelector2(node, selectors = []) {
1063610788
const elementNode = toElementNode(node);
1063710789
if (!elementNode || typeof elementNode.closest !== "function") {
1063810790
return false;
@@ -10645,7 +10797,7 @@
1064510797
}
1064610798
});
1064710799
}
10648-
function getTouchedMutationNodes(mutation) {
10800+
function getTouchedMutationNodes2(mutation) {
1064910801
const nodes = [];
1065010802
const pushNode = (node) => {
1065110803
if (node) {
@@ -10661,13 +10813,13 @@
1066110813
if (!Array.isArray(watchedNodes) || !watchedNodes.length) {
1066210814
return false;
1066310815
}
10664-
return getTouchedMutationNodes(mutation).some((node) => watchedNodes.includes(node));
10816+
return getTouchedMutationNodes2(mutation).some((node) => watchedNodes.includes(node));
1066510817
}
1066610818
function isDescendantWatchedNodeMutation(mutation, watchedNodes = []) {
1066710819
if (!Array.isArray(watchedNodes) || !watchedNodes.length) {
1066810820
return false;
1066910821
}
10670-
return getTouchedMutationNodes(mutation).some((touchedNode) => {
10822+
return getTouchedMutationNodes2(mutation).some((touchedNode) => {
1067110823
return watchedNodes.some((watchedNode) => {
1067210824
if (!watchedNode || touchedNode === watchedNode) {
1067310825
return touchedNode === watchedNode;
@@ -10698,15 +10850,15 @@
1069810850
if (!mutation || typeof mutation !== "object") {
1069910851
return false;
1070010852
}
10701-
const mutationType = resolveMutationType(mutation);
10853+
const mutationType = resolveMutationType2(mutation);
1070210854
if (mutationType !== "childList") {
1070310855
return false;
1070410856
}
1070510857
if (isDescendantWatchedNodeMutation(mutation, watchedNodes)) {
1070610858
return true;
1070710859
}
10708-
return getTouchedMutationNodes(mutation).some(
10709-
(node) => nodeOrAncestorMatchesAnySelector(node, ZOOM_STRUCTURE_CHILDLIST_SELECTORS)
10860+
return getTouchedMutationNodes2(mutation).some(
10861+
(node) => nodeOrAncestorMatchesAnySelector2(node, ZOOM_STRUCTURE_CHILDLIST_SELECTORS)
1071010862
);
1071110863
}
1071210864
function resolveTvBoardZoomMutationReaction(mutations = [], context = {}) {
@@ -10733,15 +10885,15 @@
1073310885
if (!mutation || typeof mutation !== "object") {
1073410886
return;
1073510887
}
10736-
const mutationType = resolveMutationType(mutation);
10888+
const mutationType = resolveMutationType2(mutation);
1073710889
if (mutationType === "attributes") {
10738-
if (isDirectWatchedNodeMutation(mutation, watchedNodes) || nodeOrAncestorMatchesAnySelector(mutation.target, ZOOM_SEMANTIC_CONTAINER_SELECTORS)) {
10890+
if (isDirectWatchedNodeMutation(mutation, watchedNodes) || nodeOrAncestorMatchesAnySelector2(mutation.target, ZOOM_SEMANTIC_CONTAINER_SELECTORS)) {
1073910891
shouldSchedule = true;
1074010892
}
1074110893
return;
1074210894
}
1074310895
if (mutationType === "characterData") {
10744-
if (nodeOrAncestorMatchesAnySelector(mutation.target, ZOOM_SEMANTIC_CONTAINER_SELECTORS)) {
10896+
if (nodeOrAncestorMatchesAnySelector2(mutation.target, ZOOM_SEMANTIC_CONTAINER_SELECTORS)) {
1074510897
shouldSchedule = true;
1074610898
}
1074710899
return;
@@ -10751,8 +10903,8 @@
1075110903
mutation,
1075210904
watchedNodes
1075310905
);
10754-
const touchesSemanticSurface = getTouchedMutationNodes(mutation).some(
10755-
(node) => nodeOrAncestorMatchesAnySelector(node, ZOOM_SEMANTIC_CONTAINER_SELECTORS)
10906+
const touchesSemanticSurface = getTouchedMutationNodes2(mutation).some(
10907+
(node) => nodeOrAncestorMatchesAnySelector2(node, ZOOM_SEMANTIC_CONTAINER_SELECTORS)
1075610908
);
1075710909
if (touchesSemanticSurface || invalidatesBoardSurface) {
1075810910
shouldSchedule = true;
@@ -10767,7 +10919,7 @@
1076710919
shouldInvalidateBoardCache
1076810920
};
1076910921
}
10770-
function resolveMutationType(mutation) {
10922+
function resolveMutationType2(mutation) {
1077110923
if (mutation?.type) {
1077210924
return String(mutation.type);
1077310925
}
@@ -18434,21 +18586,21 @@
1843418586
}
1843518587
return typeof parentNode.contains === "function" ? parentNode.contains(childNode) : false;
1843618588
}
18437-
function toNodeArray2(value) {
18589+
function toNodeArray3(value) {
1843818590
if (!value || typeof value[Symbol.iterator] !== "function") {
1843918591
return [];
1844018592
}
1844118593
return Array.from(value).filter(isNodeLike);
1844218594
}
1844318595
function normalizeWatchNodes(nodes = []) {
18444-
return toNodeArray2(nodes).filter((node) => node.isConnected !== false);
18596+
return toNodeArray3(nodes).filter((node) => node.isConnected !== false);
1844518597
}
1844618598
function collectMutationNodes(mutation) {
1844718599
const targetNode = mutation?.target || null;
1844818600
return [
1844918601
...targetNode ? [targetNode] : [],
18450-
...toNodeArray2(mutation?.addedNodes),
18451-
...toNodeArray2(mutation?.removedNodes)
18602+
...toNodeArray3(mutation?.addedNodes),
18603+
...toNodeArray3(mutation?.removedNodes)
1845218604
];
1845318605
}
1845418606
function watchNodeTouchesCandidate(watchNode, candidateNode) {
@@ -18458,7 +18610,7 @@
1845818610
return watchNode === candidateNode || containsNode2(watchNode, candidateNode) || containsNode2(candidateNode, watchNode);
1845918611
}
1846018612
function isAttributeOnlyMutation(mutation) {
18461-
return String(mutation?.type || "") === "attributes" && toNodeArray2(mutation?.addedNodes).length === 0 && toNodeArray2(mutation?.removedNodes).length === 0;
18613+
return String(mutation?.type || "") === "attributes" && toNodeArray3(mutation?.addedNodes).length === 0 && toNodeArray3(mutation?.removedNodes).length === 0;
1846218614
}
1846318615
function createCricketSurfaceWatchState() {
1846418616
return {
@@ -18501,7 +18653,7 @@
1850118653
}
1850218654
});
1850318655
}
18504-
nodes.push(...toNodeArray2(extraNodes));
18656+
nodes.push(...toNodeArray3(extraNodes));
1850518657
return normalizeWatchNodes(nodes);
1850618658
}
1850718659
function hasTrackedCricketSurfaceMutation(mutations = [], watchState = null) {

0 commit comments

Comments
 (0)