nodebb-plugin-ezoic-infinite 0.5.3 → 0.5.4
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 +51 -40
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* globals ajaxify */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
window.ezoicInfiniteLoaded = true;
|
|
5
|
+
|
|
4
6
|
let cachedConfig;
|
|
5
7
|
let lastFetch = 0;
|
|
6
8
|
let debounceTimer;
|
|
@@ -22,14 +24,30 @@ function parsePool(raw) {
|
|
|
22
24
|
));
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Harmony: the real post wrapper is usually [component="post"][data-pid]
|
|
29
|
+
* We must avoid counting nested nodes like component="post/parent" or other elements
|
|
30
|
+
* that can also carry data-pid in some setups.
|
|
31
|
+
*/
|
|
25
32
|
function getTopicPosts() {
|
|
26
|
-
const $
|
|
27
|
-
if ($
|
|
33
|
+
const $primary = $('[component="post"][data-pid]');
|
|
34
|
+
if ($primary.length) return $primary.not('.ezoic-ad-post');
|
|
35
|
+
|
|
36
|
+
// Fallback: top-level nodes with data-pid that contain the post content,
|
|
37
|
+
// excluding nodes nested inside another data-pid container.
|
|
38
|
+
const $top = $('[data-pid]').filter(function () {
|
|
39
|
+
const $el = $(this);
|
|
40
|
+
const hasContent = $el.find('[component="post/content"]').length > 0;
|
|
41
|
+
const nested = $el.parents('[data-pid]').length > 0;
|
|
42
|
+
return hasContent && !nested;
|
|
43
|
+
});
|
|
44
|
+
if ($top.length) return $top.not('.ezoic-ad-post');
|
|
45
|
+
|
|
28
46
|
return $('.posts .post').not('.ezoic-ad-post');
|
|
29
47
|
}
|
|
30
48
|
|
|
31
|
-
function
|
|
32
|
-
return ($el && $el.length
|
|
49
|
+
function tagName($el) {
|
|
50
|
+
return ($el && $el.length ? (($el.prop('tagName') || '').toUpperCase()) : '');
|
|
33
51
|
}
|
|
34
52
|
|
|
35
53
|
function removePlaceholdersByPool(pool) {
|
|
@@ -42,43 +60,25 @@ function removeAdWrappers() {
|
|
|
42
60
|
}
|
|
43
61
|
|
|
44
62
|
function computeWindowSlots(totalItems, interval, poolSize) {
|
|
63
|
+
// totalItems posts -> number of ad slots at positions interval, 2*interval, ...
|
|
45
64
|
const slots = Math.floor(totalItems / interval);
|
|
46
65
|
if (slots <= 0) return [];
|
|
66
|
+
|
|
67
|
+
// IMPORTANT:
|
|
68
|
+
// We cannot display more than poolSize ads at once because Ezoic placeholder IDs
|
|
69
|
+
// must be unique on the page. If slots > poolSize, we only render the latest poolSize slots.
|
|
47
70
|
const start = Math.max(1, slots - poolSize + 1);
|
|
48
71
|
const out = [];
|
|
49
72
|
for (let s = start; s <= slots; s++) out.push(s);
|
|
50
73
|
return out;
|
|
51
74
|
}
|
|
52
75
|
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
'<div id="ezoic-pub-ad-placeholder-' + placeholderId + '"></div>' +
|
|
58
|
-
'</li>'
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
return '<div class="ezoic-ad-between" id="ezoic-pub-ad-placeholder-' + placeholderId + '"></div>';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function makeAdMessageWrapper($targetPost, placeholderId) {
|
|
65
|
-
if (isLi($targetPost)) {
|
|
66
|
-
return (
|
|
67
|
-
'<li class="post ezoic-ad-post" data-ezoic-ad="1">' +
|
|
68
|
-
'<div class="content">' +
|
|
69
|
-
'<div id="ezoic-pub-ad-placeholder-' + placeholderId + '"></div>' +
|
|
70
|
-
'</div>' +
|
|
71
|
-
'</li>'
|
|
72
|
-
);
|
|
76
|
+
function makeWrapperLike($target, classes, innerHtml) {
|
|
77
|
+
const t = tagName($target);
|
|
78
|
+
if (t === 'LI') {
|
|
79
|
+
return '<li class="' + classes + ' list-unstyled" data-ezoic-ad="1">' + innerHtml + '</li>';
|
|
73
80
|
}
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
'<div class="post ezoic-ad-post" data-ezoic-ad="1">' +
|
|
77
|
-
'<div class="content">' +
|
|
78
|
-
'<div id="ezoic-pub-ad-placeholder-' + placeholderId + '"></div>' +
|
|
79
|
-
'</div>' +
|
|
80
|
-
'</div>'
|
|
81
|
-
);
|
|
81
|
+
return '<div class="' + classes + '" data-ezoic-ad="1">' + innerHtml + '</div>';
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function insertBetweenPosts($posts, pool, interval) {
|
|
@@ -89,12 +89,13 @@ function insertBetweenPosts($posts, pool, interval) {
|
|
|
89
89
|
const activeIds = [];
|
|
90
90
|
for (let i = 0; i < slotsToRender.length; i++) {
|
|
91
91
|
const slotNumber = slotsToRender[i];
|
|
92
|
-
const id = pool[i];
|
|
93
|
-
const index = slotNumber * interval - 1;
|
|
92
|
+
const id = pool[i]; // map latest slots to pool in order
|
|
93
|
+
const index = slotNumber * interval - 1; // 0-based index of the post after which we insert
|
|
94
94
|
const $target = $posts.eq(index);
|
|
95
95
|
if (!$target.length) continue;
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
const html = makeWrapperLike($target, 'ezoic-ad-between', '<div id="ezoic-pub-ad-placeholder-' + id + '"></div>');
|
|
98
|
+
$target.after(html);
|
|
98
99
|
activeIds.push(id);
|
|
99
100
|
}
|
|
100
101
|
return activeIds;
|
|
@@ -113,14 +114,17 @@ function insertAdMessagesBetweenReplies($posts, pool, interval) {
|
|
|
113
114
|
const $target = $posts.eq(index);
|
|
114
115
|
if (!$target.length) continue;
|
|
115
116
|
|
|
116
|
-
|
|
117
|
+
const inner = '<div class="content"><div id="ezoic-pub-ad-placeholder-' + id + '"></div></div>';
|
|
118
|
+
const html = makeWrapperLike($target, 'post ezoic-ad-post', inner);
|
|
119
|
+
$target.after(html);
|
|
117
120
|
activeIds.push(id);
|
|
118
121
|
}
|
|
119
122
|
return activeIds;
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
async function refreshAds() {
|
|
123
|
-
|
|
126
|
+
let cfg;
|
|
127
|
+
try { cfg = await fetchConfig(); } catch (e) { return; }
|
|
124
128
|
if (!cfg || cfg.excluded) return;
|
|
125
129
|
|
|
126
130
|
const betweenPool = parsePool(cfg.placeholderIds);
|
|
@@ -132,6 +136,7 @@ async function refreshAds() {
|
|
|
132
136
|
const $posts = getTopicPosts();
|
|
133
137
|
if (!$posts.length) return;
|
|
134
138
|
|
|
139
|
+
// Clean first
|
|
135
140
|
removeAdWrappers();
|
|
136
141
|
removePlaceholdersByPool(betweenPool);
|
|
137
142
|
removePlaceholdersByPool(messagePool);
|
|
@@ -146,18 +151,24 @@ async function refreshAds() {
|
|
|
146
151
|
activeIds.push(...insertAdMessagesBetweenReplies($posts, messagePool, messageInterval));
|
|
147
152
|
}
|
|
148
153
|
|
|
154
|
+
// Ezoic render
|
|
149
155
|
if (activeIds.length && window.ezstandalone && typeof window.ezstandalone.destroyPlaceholders === 'function') {
|
|
150
156
|
try { window.ezstandalone.destroyPlaceholders(); } catch (e) {}
|
|
151
157
|
}
|
|
152
158
|
activeIds.forEach(id => {
|
|
153
|
-
try {
|
|
159
|
+
try {
|
|
160
|
+
if (window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
|
|
161
|
+
window.ezstandalone.showAds(id);
|
|
162
|
+
}
|
|
163
|
+
} catch (e) {}
|
|
154
164
|
});
|
|
155
165
|
}
|
|
156
166
|
|
|
157
167
|
function debounceRefresh() {
|
|
158
168
|
clearTimeout(debounceTimer);
|
|
159
|
-
debounceTimer = setTimeout(refreshAds,
|
|
169
|
+
debounceTimer = setTimeout(refreshAds, 150);
|
|
160
170
|
}
|
|
161
171
|
|
|
172
|
+
$(document).ready(debounceRefresh);
|
|
162
173
|
$(window).on('action:ajaxify.end action:posts.loaded action:topic.loaded', debounceRefresh);
|
|
163
|
-
setTimeout(debounceRefresh,
|
|
174
|
+
setTimeout(debounceRefresh, 1500);
|