MCPcopy
hub / github.com/darkreader/darkreader / watchForNodePosition

Function watchForNodePosition

src/inject/utils/dom.ts:76–182  ·  view source on GitHub ↗
(
    node: T,
    mode: 'head' | 'prev-sibling',
    onRestore = Function.prototype,
)

Source from the content-addressed store, hash-verified

74}
75
76export function watchForNodePosition<T extends Node>(
77 node: T,
78 mode: 'head' | 'prev-sibling',
79 onRestore = Function.prototype,
80): NodePosetionWatcher {
81 const MAX_ATTEMPTS_COUNT = 10;
82 const RETRY_TIMEOUT = getDuration({seconds: 2});
83 const ATTEMPTS_INTERVAL = getDuration({seconds: 10});
84 let prevSibling = node.previousSibling;
85 let parent = node.parentNode;
86 if (!parent) {
87 throw new Error('Unable to watch for node position: parent element not found');
88 }
89 if (mode === 'prev-sibling' && !prevSibling) {
90 throw new Error('Unable to watch for node position: there is no previous sibling');
91 }
92 let attempts = 0;
93 let start: number | null = null;
94 let timeoutId: ReturnType<typeof setTimeout> | null = null;
95 const restore = throttle(() => {
96 if (timeoutId) {
97 return;
98 }
99 attempts++;
100 const now = Date.now();
101 if (start == null) {
102 start = now;
103 } else if (attempts >= MAX_ATTEMPTS_COUNT) {
104 if (now - start < ATTEMPTS_INTERVAL) {
105 logWarn(`Node position watcher paused: retry in ${RETRY_TIMEOUT}ms`, node, prevSibling);
106 timeoutId = setTimeout(() => {
107 start = null;
108 attempts = 0;
109 timeoutId = null;
110 restore();
111 }, RETRY_TIMEOUT);
112 return;
113 }
114 start = now;
115 attempts = 1;
116 }
117
118 if (mode === 'head') {
119 if (prevSibling && prevSibling.parentNode !== parent) {
120 logWarn('Sibling moved, moving node to the head end', node, prevSibling, parent);
121 prevSibling = document.head.lastChild;
122 }
123 }
124
125 if (mode === 'prev-sibling') {
126 if (prevSibling!.parentNode == null) {
127 logWarn('Unable to restore node position: sibling was removed', node, prevSibling, parent);
128 stop();
129 return;
130 }
131 if (prevSibling!.parentNode !== parent) {
132 logWarn('Style was moved to another parent', node, prevSibling, parent);
133 updateParent(prevSibling!.parentNode);

Callers 2

setupNodePositionWatcherFunction · 0.90
prepareOverridesSheetFunction · 0.90

Calls 7

getDurationFunction · 0.90
throttleFunction · 0.90
logWarnFunction · 0.90
restoreFunction · 0.85
updateParentFunction · 0.85
stopFunction · 0.70
runFunction · 0.70

Tested by

no test coverage detected