nodebb-plugin-ezoic-infinite 1.6.77 → 1.6.78

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.6.77",
3
+ "version": "1.6.78",
4
4
  "description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -1508,187 +1508,3 @@ function buildOrdinalMap(items) {
1508
1508
  insertHeroAdEarly().catch(() => {});
1509
1509
  requestBurst();
1510
1510
  })();
1511
-
1512
-
1513
-
1514
- // ===== V17 minimal pile-fix (no insert hooks) =====
1515
- (function () {
1516
- // Goal: keep ad injection intact. Only repair when we detect "pile-up" of between wraps.
1517
- var TOPIC_LI_SEL = 'li[component="category/topic"]';
1518
- var BETWEEN_WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
1519
- var HOST_CLASS = 'nodebb-ezoic-host';
1520
-
1521
- var scheduled = false;
1522
- var lastRun = 0;
1523
- var COOLDOWN = 180;
1524
-
1525
- function getTopicList() {
1526
- try {
1527
- var li = document.querySelector(TOPIC_LI_SEL);
1528
- if (!li) return null;
1529
- return li.closest ? li.closest('ul,ol') : null;
1530
- } catch (e) { return null; }
1531
- }
1532
-
1533
- function isHost(node) {
1534
- return !!(node && node.nodeType === 1 && node.tagName === 'LI' && node.classList && node.classList.contains(HOST_CLASS));
1535
- }
1536
-
1537
- function ensureHostForWrap(wrap, ul) {
1538
- try {
1539
- if (!wrap || wrap.nodeType !== 1) return null;
1540
- if (!(wrap.matches && wrap.matches(BETWEEN_WRAP_SEL))) return null;
1541
-
1542
- var host = wrap.closest ? wrap.closest('li.' + HOST_CLASS) : null;
1543
- if (host) return host;
1544
-
1545
- if (!ul) ul = wrap.closest ? wrap.closest('ul,ol') : null;
1546
- if (!ul || !(ul.tagName === 'UL' || ul.tagName === 'OL')) return null;
1547
-
1548
- // Only wrap if direct child of list (invalid / fragile)
1549
- if (wrap.parentElement === ul) {
1550
- host = document.createElement('li');
1551
- host.className = HOST_CLASS;
1552
- host.setAttribute('role', 'listitem');
1553
- host.style.listStyle = 'none';
1554
- host.style.width = '100%';
1555
- ul.insertBefore(host, wrap);
1556
- host.appendChild(wrap);
1557
- try { wrap.style.width = '100%'; } catch (e) {}
1558
- return host;
1559
- }
1560
- } catch (e) {}
1561
- return null;
1562
- }
1563
-
1564
- function previousTopicLi(node) {
1565
- try {
1566
- var prev = node.previousElementSibling;
1567
- while (prev) {
1568
- if (prev.matches && prev.matches(TOPIC_LI_SEL)) return prev;
1569
- // skip other hosts/wraps
1570
- prev = prev.previousElementSibling;
1571
- }
1572
- } catch (e) {}
1573
- return null;
1574
- }
1575
-
1576
- function detectPileUp(ul) {
1577
- // Pile-up signature: 2+ between wraps/hosts adjacent with no topics between, often near top.
1578
- try {
1579
- var kids = ul.children;
1580
- var run = 0;
1581
- var maxRun = 0;
1582
- for (var i = 0; i < kids.length; i++) {
1583
- var el = kids[i];
1584
- var isBetween = false;
1585
- if (isHost(el)) {
1586
- isBetween = !!(el.querySelector && el.querySelector(BETWEEN_WRAP_SEL));
1587
- } else if (el.matches && el.matches(BETWEEN_WRAP_SEL)) {
1588
- isBetween = true;
1589
- }
1590
- if (isBetween) {
1591
- run++;
1592
- if (run > maxRun) maxRun = run;
1593
- } else if (el.matches && el.matches(TOPIC_LI_SEL)) {
1594
- run = 0;
1595
- } else {
1596
- // other nodes reset lightly
1597
- run = 0;
1598
- }
1599
- }
1600
- return maxRun >= 2;
1601
- } catch (e) {}
1602
- return false;
1603
- }
1604
-
1605
- function redistribute(ul) {
1606
- try {
1607
- if (!ul) return;
1608
-
1609
- // Step 1: wrap any direct child between DIVs into LI hosts (makes list stable)
1610
- ul.querySelectorAll(':scope > ' + BETWEEN_WRAP_SEL).forEach(function(w){ ensureHostForWrap(w, ul); });
1611
-
1612
- // Step 2: only act if we see pile-up (avoid touching infinite scroll during normal flow)
1613
- if (!detectPileUp(ul)) return;
1614
-
1615
- // Move each host to immediately after the closest previous topic LI at its current position.
1616
- var hosts = ul.querySelectorAll(':scope > li.' + HOST_CLASS);
1617
- hosts.forEach(function(host){
1618
- try {
1619
- var wrap = host.querySelector && host.querySelector(BETWEEN_WRAP_SEL);
1620
- if (!wrap) return;
1621
-
1622
- var anchor = previousTopicLi(host);
1623
- if (!anchor) return; // if none, don't move (prevents yanking to top/bottom)
1624
-
1625
- if (host.previousElementSibling !== anchor) {
1626
- anchor.insertAdjacentElement('afterend', host);
1627
- }
1628
- } catch (e) {}
1629
- });
1630
- } catch (e) {}
1631
- }
1632
-
1633
- function schedule(reason) {
1634
- var now = Date.now();
1635
- if (now - lastRun < COOLDOWN) return;
1636
- if (scheduled) return;
1637
- scheduled = true;
1638
- requestAnimationFrame(function () {
1639
- scheduled = false;
1640
- lastRun = Date.now();
1641
- try {
1642
- var ul = getTopicList();
1643
- if (!ul) return;
1644
- redistribute(ul);
1645
- } catch (e) {}
1646
- });
1647
- }
1648
-
1649
- function init() {
1650
- schedule('init');
1651
-
1652
- // Observe only the topic list once available
1653
- try {
1654
- if (typeof MutationObserver !== 'undefined') {
1655
- var observeList = function(ul){
1656
- if (!ul) return;
1657
- var mo = new MutationObserver(function(muts){
1658
- // schedule on any change; redistribute() itself is guarded by pile-up detection
1659
- schedule('mo');
1660
- });
1661
- mo.observe(ul, { childList: true, subtree: true });
1662
- };
1663
-
1664
- var ul = getTopicList();
1665
- if (ul) observeList(ul);
1666
- else {
1667
- var mo2 = new MutationObserver(function(){
1668
- var u2 = getTopicList();
1669
- if (u2) {
1670
- try { observeList(u2); } catch(e){}
1671
- try { mo2.disconnect(); } catch(e){}
1672
- }
1673
- });
1674
- mo2.observe(document.documentElement || document.body, { childList: true, subtree: true });
1675
- }
1676
- }
1677
- } catch (e) {}
1678
-
1679
- // NodeBB events: run after infinite scroll batches
1680
- if (window.jQuery) {
1681
- try {
1682
- window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
1683
- setTimeout(function(){ schedule('event'); }, 50);
1684
- setTimeout(function(){ schedule('event2'); }, 400);
1685
- });
1686
- } catch (e) {}
1687
- }
1688
- }
1689
-
1690
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
1691
- else init();
1692
- })();
1693
- // ===== /V17 =====
1694
-
package/public/style.css CHANGED
@@ -79,10 +79,3 @@
79
79
  position: static !important;
80
80
  top: auto !important;
81
81
  }
82
-
83
-
84
- /* ===== V17 host styling ===== */
85
- li.nodebb-ezoic-host { list-style: none; width: 100%; display: block; }
86
- li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width: 100%; display: block; }
87
- /* ===== /V17 ===== */
88
-