nodebb-plugin-ezoic-infinite 1.6.4 → 1.6.6
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.
- package/package.json +1 -1
- package/public/client.js +194 -155
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1347,55 +1347,62 @@ function buildOrdinalMap(items) {
|
|
|
1347
1347
|
|
|
1348
1348
|
|
|
1349
1349
|
|
|
1350
|
+
|
|
1351
|
+
|
|
1350
1352
|
// ===== CLEAN REFRACTOR: visibility manager for Ezoic wraps =====
|
|
1351
1353
|
(function () {
|
|
1352
|
-
// v2.
|
|
1353
|
-
//
|
|
1354
|
-
//
|
|
1355
|
-
//
|
|
1354
|
+
// v2.4 (anchor-guard):
|
|
1355
|
+
// Issue reported: when scrolling back up, ad wraps accumulate before the first post.
|
|
1356
|
+
// Root cause (most likely): some script/virtualization detaches ad nodes from their original place and
|
|
1357
|
+
// re-inserts them near the top, without their original context.
|
|
1358
|
+
//
|
|
1359
|
+
// Fix:
|
|
1360
|
+
// - On creation of each wrap, insert a hidden "anchor" node right before it and tag the wrap with that anchor id.
|
|
1361
|
+
// - Periodically validate: if a wrap is no longer immediately preceded by its anchor, remove the wrap.
|
|
1362
|
+
// (We do NOT recreate here; the normal injector will insert correct wraps as needed.)
|
|
1363
|
+
//
|
|
1364
|
+
// We also keep v2.3 no-redefine rules:
|
|
1365
|
+
// - no wrap deletion for cleanup except for misplaced wraps / duplicate placeholders
|
|
1366
|
+
// - showAds only once per placeholder id
|
|
1356
1367
|
|
|
1357
1368
|
var BETWEEN_SELECTOR = '.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1358
1369
|
var MESSAGE_SELECTOR = '.nodebb-ezoic-wrap.ezoic-ad-message';
|
|
1359
1370
|
var WRAP_SELECTOR = BETWEEN_SELECTOR + ', ' + MESSAGE_SELECTOR;
|
|
1360
1371
|
|
|
1361
|
-
var
|
|
1362
|
-
var KEEP_MARGIN_BETWEEN_MOBILE = 1900;
|
|
1372
|
+
var MAX_SHOW_PER_TICK = 4;
|
|
1363
1373
|
|
|
1364
|
-
//
|
|
1365
|
-
var
|
|
1366
|
-
var
|
|
1374
|
+
// validation throttles
|
|
1375
|
+
var VALIDATE_COOLDOWN_MS = 260;
|
|
1376
|
+
var lastValidate = 0;
|
|
1367
1377
|
|
|
1368
|
-
//
|
|
1369
|
-
var
|
|
1370
|
-
var lastWalk = 0;
|
|
1371
|
-
var WALK_STEPS = 28; // siblings in each direction
|
|
1372
|
-
var WALK_POINTS = 2; // sample top & bottom area of viewport
|
|
1373
|
-
|
|
1374
|
-
function isMobile() {
|
|
1375
|
-
try { return window.matchMedia && window.matchMedia('(max-width: 767px)').matches; } catch (e) { return false; }
|
|
1376
|
-
}
|
|
1377
|
-
function keepMarginBetween() { return isMobile() ? KEEP_MARGIN_BETWEEN_MOBILE : KEEP_MARGIN_BETWEEN_DESKTOP; }
|
|
1378
|
-
|
|
1379
|
-
var lastShowById = Object.create(null);
|
|
1378
|
+
// internal state
|
|
1379
|
+
var activatedById = Object.create(null);
|
|
1380
1380
|
var showQueue = [];
|
|
1381
1381
|
var showTicking = false;
|
|
1382
1382
|
|
|
1383
|
-
function
|
|
1383
|
+
function getIdFromWrap(w) {
|
|
1384
1384
|
try { return w.getAttribute('data-ezoic-wrapid'); } catch (e) { return null; }
|
|
1385
1385
|
}
|
|
1386
|
-
function
|
|
1386
|
+
function getIdFromPlaceholder(w) {
|
|
1387
1387
|
try {
|
|
1388
1388
|
var ph = w.querySelector('[data-ezoic-id]');
|
|
1389
1389
|
return ph ? ph.getAttribute('data-ezoic-id') : null;
|
|
1390
1390
|
} catch (e) { return null; }
|
|
1391
1391
|
}
|
|
1392
|
+
function getId(w) { return getIdFromWrap(w) || getIdFromPlaceholder(w); }
|
|
1393
|
+
|
|
1394
|
+
function isFilled(w) {
|
|
1395
|
+
try {
|
|
1396
|
+
if (w.querySelector('iframe')) return true;
|
|
1397
|
+
if (w.querySelector('[id^="google_ads_iframe"]')) return true;
|
|
1398
|
+
if (w.querySelector('.ezoic-ad')) return true;
|
|
1399
|
+
} catch (e) {}
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1392
1402
|
|
|
1393
1403
|
function enqueueShow(id) {
|
|
1394
1404
|
if (!id) return;
|
|
1395
|
-
|
|
1396
|
-
var last = lastShowById[id] || 0;
|
|
1397
|
-
if (now - last < SHOW_COOLDOWN_MS) return;
|
|
1398
|
-
|
|
1405
|
+
if (activatedById[id]) return;
|
|
1399
1406
|
for (var i = 0; i < showQueue.length; i++) if (showQueue[i] === id) return;
|
|
1400
1407
|
showQueue.push(id);
|
|
1401
1408
|
scheduleShowTick();
|
|
@@ -1410,9 +1417,9 @@ function buildOrdinalMap(items) {
|
|
|
1410
1417
|
while (showQueue.length && n < MAX_SHOW_PER_TICK) {
|
|
1411
1418
|
var id = showQueue.shift();
|
|
1412
1419
|
try {
|
|
1413
|
-
if (window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
|
|
1420
|
+
if (!activatedById[id] && window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
|
|
1414
1421
|
window.ezstandalone.showAds(String(id));
|
|
1415
|
-
|
|
1422
|
+
activatedById[id] = Date.now();
|
|
1416
1423
|
}
|
|
1417
1424
|
} catch (e) {}
|
|
1418
1425
|
n++;
|
|
@@ -1421,28 +1428,103 @@ function buildOrdinalMap(items) {
|
|
|
1421
1428
|
});
|
|
1422
1429
|
}
|
|
1423
1430
|
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1431
|
+
// --- Anchor guard ---
|
|
1432
|
+
function ensureAnchor(w) {
|
|
1433
|
+
try {
|
|
1434
|
+
if (!w || !w.parentNode) return;
|
|
1435
|
+
if (w.getAttribute('data-ezoic-anchored') === '1') return;
|
|
1429
1436
|
|
|
1430
|
-
|
|
1431
|
-
if (
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1437
|
+
var wrapUid = w.getAttribute('data-ezoic-wrapuid');
|
|
1438
|
+
if (!wrapUid) {
|
|
1439
|
+
wrapUid = String(Date.now()) + '-' + Math.floor(Math.random() * 1e9);
|
|
1440
|
+
w.setAttribute('data-ezoic-wrapuid', wrapUid);
|
|
1441
|
+
}
|
|
1435
1442
|
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1443
|
+
// If already preceded by matching anchor, mark anchored.
|
|
1444
|
+
var prev = w.previousSibling;
|
|
1445
|
+
if (prev && prev.nodeType === 1 && prev.classList && prev.classList.contains('nodebb-ezoic-anchor')) {
|
|
1446
|
+
if (prev.getAttribute('data-anchor-for') === wrapUid) {
|
|
1447
|
+
w.setAttribute('data-ezoic-anchored', '1');
|
|
1448
|
+
return;
|
|
1440
1449
|
}
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
// Create anchor node
|
|
1453
|
+
var a = document.createElement('span');
|
|
1454
|
+
a.className = 'nodebb-ezoic-anchor';
|
|
1455
|
+
a.setAttribute('data-anchor-for', wrapUid);
|
|
1456
|
+
a.style.display = 'none';
|
|
1457
|
+
|
|
1458
|
+
w.parentNode.insertBefore(a, w);
|
|
1459
|
+
w.setAttribute('data-ezoic-anchored', '1');
|
|
1460
|
+
} catch (e) {}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
function validateAnchors() {
|
|
1464
|
+
var now = Date.now();
|
|
1465
|
+
if (now - lastValidate < VALIDATE_COOLDOWN_MS) return;
|
|
1466
|
+
lastValidate = now;
|
|
1467
|
+
|
|
1468
|
+
try {
|
|
1469
|
+
// Remove wraps that lost their anchor adjacency (they have been moved)
|
|
1470
|
+
var wraps = document.querySelectorAll('.nodebb-ezoic-wrap');
|
|
1471
|
+
for (var i = 0; i < wraps.length; i++) {
|
|
1472
|
+
var w = wraps[i];
|
|
1473
|
+
try {
|
|
1474
|
+
var uid = w.getAttribute('data-ezoic-wrapuid');
|
|
1475
|
+
if (!uid) {
|
|
1476
|
+
// If it's an old wrap with no uid, anchor it once.
|
|
1477
|
+
ensureAnchor(w);
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1480
|
+
var prev = w.previousSibling;
|
|
1481
|
+
if (!(prev && prev.nodeType === 1 && prev.classList && prev.classList.contains('nodebb-ezoic-anchor') && prev.getAttribute('data-anchor-for') === uid)) {
|
|
1482
|
+
// Misplaced wrap -> remove it (prevents pile-up before first post)
|
|
1483
|
+
w.remove();
|
|
1484
|
+
}
|
|
1485
|
+
} catch (e) {}
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// Remove orphan anchors (anchor without following wrap)
|
|
1489
|
+
var anchors = document.querySelectorAll('.nodebb-ezoic-anchor');
|
|
1490
|
+
for (var j = 0; j < anchors.length; j++) {
|
|
1491
|
+
var a = anchors[j];
|
|
1492
|
+
try {
|
|
1493
|
+
var next = a.nextSibling;
|
|
1494
|
+
if (!(next && next.nodeType === 1 && next.classList && next.classList.contains('nodebb-ezoic-wrap'))) {
|
|
1495
|
+
a.remove();
|
|
1496
|
+
}
|
|
1497
|
+
} catch (e) {}
|
|
1498
|
+
}
|
|
1499
|
+
} catch (e) {}
|
|
1443
1500
|
}
|
|
1444
1501
|
|
|
1445
|
-
//
|
|
1502
|
+
// --- De-dupe placeholders to avoid Ezoic warnings ---
|
|
1503
|
+
function dedupePlaceholders() {
|
|
1504
|
+
var seen = Object.create(null);
|
|
1505
|
+
try {
|
|
1506
|
+
document.querySelectorAll('.nodebb-ezoic-wrap [data-ezoic-id]').forEach(function (ph) {
|
|
1507
|
+
try {
|
|
1508
|
+
var id = ph.getAttribute('data-ezoic-id');
|
|
1509
|
+
if (!id) return;
|
|
1510
|
+
var wrap = ph.closest('.nodebb-ezoic-wrap');
|
|
1511
|
+
if (!wrap) return;
|
|
1512
|
+
|
|
1513
|
+
// ensure anchor for any wrap we touch
|
|
1514
|
+
ensureAnchor(wrap);
|
|
1515
|
+
|
|
1516
|
+
if (seen[id]) {
|
|
1517
|
+
// remove duplicates; keep first occurrence
|
|
1518
|
+
wrap.remove();
|
|
1519
|
+
} else {
|
|
1520
|
+
seen[id] = true;
|
|
1521
|
+
}
|
|
1522
|
+
} catch (e) {}
|
|
1523
|
+
});
|
|
1524
|
+
} catch (e) {}
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// --- Visibility: trigger show once if empty ---
|
|
1446
1528
|
var io = null;
|
|
1447
1529
|
function installIO() {
|
|
1448
1530
|
if (io || typeof IntersectionObserver === 'undefined') return;
|
|
@@ -1451,24 +1533,36 @@ function buildOrdinalMap(items) {
|
|
|
1451
1533
|
try {
|
|
1452
1534
|
entries.forEach(function (e) {
|
|
1453
1535
|
if (!e || !e.target) return;
|
|
1536
|
+
|
|
1537
|
+
// Always ensure anchor while visible/near
|
|
1538
|
+
ensureAnchor(e.target);
|
|
1539
|
+
|
|
1454
1540
|
if (e.isIntersecting) {
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1541
|
+
var id = getId(e.target);
|
|
1542
|
+
if (!id) return;
|
|
1543
|
+
|
|
1544
|
+
if (isFilled(e.target)) {
|
|
1545
|
+
activatedById[id] = activatedById[id] || Date.now();
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
enqueueShow(id);
|
|
1458
1549
|
}
|
|
1459
1550
|
});
|
|
1460
1551
|
} catch (e) {}
|
|
1461
1552
|
}, { root: null, rootMargin: '1200px 0px 1200px 0px', threshold: 0.01 });
|
|
1462
1553
|
|
|
1463
|
-
try { document.querySelectorAll(WRAP_SELECTOR).forEach(function (w) { try { io.observe(w); } catch(e) {} }); } catch (e) {}
|
|
1554
|
+
try { document.querySelectorAll(WRAP_SELECTOR).forEach(function (w) { try { ensureAnchor(w); io.observe(w); } catch(e) {} }); } catch (e) {}
|
|
1464
1555
|
}
|
|
1465
1556
|
|
|
1557
|
+
// Observe newly added wraps and anchor them
|
|
1466
1558
|
var moInstalled = false;
|
|
1467
1559
|
function installMO() {
|
|
1468
1560
|
if (moInstalled || typeof MutationObserver === 'undefined') return;
|
|
1469
1561
|
moInstalled = true;
|
|
1470
1562
|
|
|
1471
1563
|
var mo = new MutationObserver(function (muts) {
|
|
1564
|
+
try { dedupePlaceholders(); } catch (e) {}
|
|
1565
|
+
|
|
1472
1566
|
if (!io) return;
|
|
1473
1567
|
try {
|
|
1474
1568
|
for (var i = 0; i < muts.length; i++) {
|
|
@@ -1479,12 +1573,15 @@ function buildOrdinalMap(items) {
|
|
|
1479
1573
|
if (!n || n.nodeType !== 1) continue;
|
|
1480
1574
|
|
|
1481
1575
|
if (n.matches && n.matches(WRAP_SELECTOR)) {
|
|
1576
|
+
ensureAnchor(n);
|
|
1482
1577
|
try { io.observe(n); } catch (e) {}
|
|
1483
|
-
var id =
|
|
1484
|
-
if (id) enqueueShow(id);
|
|
1578
|
+
var id = getId(n);
|
|
1579
|
+
if (id && !isFilled(n)) enqueueShow(id);
|
|
1580
|
+
else if (id) activatedById[id] = activatedById[id] || Date.now();
|
|
1485
1581
|
} else if (n.querySelectorAll) {
|
|
1486
1582
|
var inner = n.querySelectorAll(WRAP_SELECTOR);
|
|
1487
1583
|
for (var k = 0; k < inner.length; k++) {
|
|
1584
|
+
ensureAnchor(inner[k]);
|
|
1488
1585
|
try { io.observe(inner[k]); } catch (e) {}
|
|
1489
1586
|
}
|
|
1490
1587
|
}
|
|
@@ -1496,122 +1593,62 @@ function buildOrdinalMap(items) {
|
|
|
1496
1593
|
try { mo.observe(document.documentElement || document.body, { childList: true, subtree: true }); } catch (e) {}
|
|
1497
1594
|
}
|
|
1498
1595
|
|
|
1499
|
-
function
|
|
1596
|
+
function init() {
|
|
1597
|
+
// anchor + dedupe existing
|
|
1500
1598
|
try {
|
|
1501
|
-
|
|
1502
|
-
if (el.classList && el.classList.contains('nodebb-ezoic-wrap')) return el;
|
|
1503
|
-
el = el.parentElement;
|
|
1504
|
-
}
|
|
1599
|
+
document.querySelectorAll('.nodebb-ezoic-wrap').forEach(function (w) { ensureAnchor(w); });
|
|
1505
1600
|
} catch (e) {}
|
|
1506
|
-
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
function enqueueWrap(w) {
|
|
1510
|
-
if (!w) return;
|
|
1511
|
-
var id = getWrapId(w) || getPlaceholderId(w);
|
|
1512
|
-
if (id) enqueueShow(id);
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
// Viewport-walk: find content near viewport and walk siblings to pick nearby wraps.
|
|
1516
|
-
function viewportWalkEnqueue() {
|
|
1517
|
-
var now = Date.now();
|
|
1518
|
-
if (now - lastWalk < WALK_COOLDOWN_MS) return;
|
|
1519
|
-
lastWalk = now;
|
|
1520
|
-
|
|
1521
|
-
if (typeof document.elementFromPoint !== 'function') return;
|
|
1522
|
-
|
|
1523
|
-
var vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
1524
|
-
if (!vh) return;
|
|
1601
|
+
dedupePlaceholders();
|
|
1525
1602
|
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
if (WALK_POINTS === 1) ys = [Math.min(vh - 10, 180)];
|
|
1529
|
-
|
|
1530
|
-
for (var p = 0; p < ys.length; p++) {
|
|
1531
|
-
var y = ys[p];
|
|
1532
|
-
var el = null;
|
|
1533
|
-
try { el = document.elementFromPoint(10, y); } catch (e) {}
|
|
1534
|
-
if (!el) continue;
|
|
1535
|
-
|
|
1536
|
-
// ascend to a stable list item, then traverse siblings
|
|
1537
|
-
var cursor = el;
|
|
1538
|
-
// try to find an item container to traverse in topic lists
|
|
1539
|
-
for (var i = 0; i < 8 && cursor && cursor.parentElement; i++) {
|
|
1540
|
-
if (cursor.classList && (cursor.classList.contains('topic-item') || cursor.classList.contains('posts-list') || cursor.classList.contains('category-item'))) break;
|
|
1541
|
-
cursor = cursor.parentElement;
|
|
1542
|
-
}
|
|
1543
|
-
// if cursor isn't traversable, just use the element itself
|
|
1544
|
-
cursor = cursor || el;
|
|
1545
|
-
|
|
1546
|
-
// find nearest wrap around this point
|
|
1547
|
-
enqueueWrap(closestWrap(el));
|
|
1548
|
-
|
|
1549
|
-
// walk next/prev siblings and enqueue wraps found
|
|
1550
|
-
var forward = cursor;
|
|
1551
|
-
for (var s = 0; s < WALK_STEPS; s++) {
|
|
1552
|
-
if (!forward) break;
|
|
1553
|
-
// check within forward node for wraps
|
|
1554
|
-
try {
|
|
1555
|
-
if (forward.matches && forward.matches(WRAP_SELECTOR)) enqueueWrap(forward);
|
|
1556
|
-
if (forward.querySelectorAll) {
|
|
1557
|
-
var w1 = forward.querySelectorAll(WRAP_SELECTOR);
|
|
1558
|
-
for (var wi = 0; wi < w1.length; wi++) enqueueWrap(w1[wi]);
|
|
1559
|
-
}
|
|
1560
|
-
} catch (e) {}
|
|
1561
|
-
forward = forward.nextElementSibling;
|
|
1562
|
-
}
|
|
1603
|
+
installIO();
|
|
1604
|
+
installMO();
|
|
1563
1605
|
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1606
|
+
// initial eager show for empty visible-ish wraps (bounded)
|
|
1607
|
+
try {
|
|
1608
|
+
var vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
1609
|
+
var margin = 900;
|
|
1610
|
+
var wraps = document.querySelectorAll(WRAP_SELECTOR);
|
|
1611
|
+
var budget = 12;
|
|
1612
|
+
for (var i = 0; i < wraps.length && budget > 0; i++) {
|
|
1613
|
+
var w = wraps[i];
|
|
1614
|
+
ensureAnchor(w);
|
|
1615
|
+
var r = w.getBoundingClientRect();
|
|
1616
|
+
if (r.bottom >= -margin && r.top <= (vh + margin)) {
|
|
1617
|
+
var id = getId(w);
|
|
1618
|
+
if (id) {
|
|
1619
|
+
if (isFilled(w)) activatedById[id] = activatedById[id] || Date.now();
|
|
1620
|
+
else enqueueShow(id);
|
|
1572
1621
|
}
|
|
1573
|
-
|
|
1574
|
-
|
|
1622
|
+
budget--;
|
|
1623
|
+
}
|
|
1575
1624
|
}
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
|
|
1579
|
-
var sweepPending = false;
|
|
1580
|
-
var lastSweep = 0;
|
|
1581
|
-
var SWEEP_COOLDOWN_MS = 600;
|
|
1582
|
-
|
|
1583
|
-
function scheduleSweep() {
|
|
1584
|
-
var now = Date.now();
|
|
1585
|
-
if (now - lastSweep < SWEEP_COOLDOWN_MS) return;
|
|
1586
|
-
if (sweepPending) return;
|
|
1587
|
-
sweepPending = true;
|
|
1588
|
-
requestAnimationFrame(function () {
|
|
1589
|
-
sweepPending = false;
|
|
1590
|
-
lastSweep = Date.now();
|
|
1591
|
-
removeFarBetweenWraps();
|
|
1592
|
-
});
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
function onScroll() {
|
|
1596
|
-
scheduleSweep();
|
|
1597
|
-
viewportWalkEnqueue();
|
|
1598
|
-
scheduleShowTick();
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
function init() {
|
|
1602
|
-
installIO();
|
|
1603
|
-
installMO();
|
|
1625
|
+
} catch (e) {}
|
|
1604
1626
|
|
|
1605
|
-
|
|
1606
|
-
window.addEventListener('
|
|
1627
|
+
// validate regularly on scroll/resize (cheap)
|
|
1628
|
+
window.addEventListener('scroll', function () {
|
|
1629
|
+
validateAnchors();
|
|
1630
|
+
scheduleShowTick();
|
|
1631
|
+
}, { passive: true });
|
|
1632
|
+
window.addEventListener('resize', function () {
|
|
1633
|
+
validateAnchors();
|
|
1634
|
+
scheduleShowTick();
|
|
1635
|
+
}, { passive: true });
|
|
1607
1636
|
|
|
1608
1637
|
if (window.jQuery) {
|
|
1609
1638
|
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function () {
|
|
1610
|
-
setTimeout(function () {
|
|
1639
|
+
setTimeout(function () {
|
|
1640
|
+
try { document.querySelectorAll('.nodebb-ezoic-wrap').forEach(function (w) { ensureAnchor(w); }); } catch (e) {}
|
|
1641
|
+
dedupePlaceholders();
|
|
1642
|
+
validateAnchors();
|
|
1643
|
+
scheduleShowTick();
|
|
1644
|
+
}, 0);
|
|
1611
1645
|
});
|
|
1612
1646
|
}
|
|
1613
1647
|
|
|
1614
|
-
|
|
1648
|
+
// periodic validate safety net
|
|
1649
|
+
setInterval(validateAnchors, 1200);
|
|
1650
|
+
|
|
1651
|
+
setTimeout(function () { validateAnchors(); scheduleShowTick(); }, 0);
|
|
1615
1652
|
}
|
|
1616
1653
|
|
|
1617
1654
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
@@ -1622,3 +1659,5 @@ function buildOrdinalMap(items) {
|
|
|
1622
1659
|
|
|
1623
1660
|
|
|
1624
1661
|
|
|
1662
|
+
|
|
1663
|
+
|