feat(widgets): complete phase 3 atomic integration
This commit is contained in:
@@ -1,337 +0,0 @@
|
||||
/**
|
||||
* AKSRT Widget Set
|
||||
*
|
||||
* Handles widget-local interactions and floating QR widgets.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function restHeaders() {
|
||||
var headers = { Accept: 'application/json' };
|
||||
if (window.aksrtData && aksrtData.restNonce) {
|
||||
headers['X-WP-Nonce'] = aksrtData.restNonce;
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
function initWidgetTabs() {
|
||||
document.querySelectorAll('.widget-tab-posts[data-aksrt-tab-posts]').forEach(function (widget) {
|
||||
if (widget.dataset.aksrtWidgetTabsBound === '1') return;
|
||||
widget.dataset.aksrtWidgetTabsBound = '1';
|
||||
|
||||
var tabs = widget.querySelectorAll('.widget-tab-posts__tab');
|
||||
var panels = widget.querySelectorAll('.widget-tab-posts__panel');
|
||||
if (!tabs.length || !panels.length) return;
|
||||
var rest = widget.getAttribute('data-rest') || '';
|
||||
var defaultCount = widget.getAttribute('data-count') || '5';
|
||||
|
||||
function loadPanel(panel, tab) {
|
||||
if (!panel || panel.getAttribute('data-loaded') === '1' || !rest) return;
|
||||
var orderby = tab.getAttribute('data-orderby') || 'date';
|
||||
var cat = tab.getAttribute('data-cat') || '0';
|
||||
var tabCount = tab.getAttribute('data-tab-count') || '0';
|
||||
var style = widget.getAttribute('data-style') || 'mini';
|
||||
var paginate = widget.getAttribute('data-paginate') || 'none';
|
||||
var qs = new URLSearchParams({
|
||||
count: defaultCount,
|
||||
orderby: orderby,
|
||||
cat: cat,
|
||||
tab_count: tabCount,
|
||||
style: style,
|
||||
paginate: paginate,
|
||||
limit_day: tab.getAttribute('data-limit-day') || '0',
|
||||
pay_type: tab.getAttribute('data-pay-type') || '',
|
||||
});
|
||||
var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + qs.toString();
|
||||
panel.classList.add('is-ajax-loading');
|
||||
fetch(url, { credentials: 'same-origin', headers: restHeaders() })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (j) {
|
||||
var d = (j && j.data) || j || {};
|
||||
var html = d.html || '';
|
||||
var pag = d.paginate_html || d.paginateHtml || '';
|
||||
panel.innerHTML = (html || '<p class="widget-empty">暂无文章</p>') + (pag || '');
|
||||
panel.setAttribute('data-loaded', '1');
|
||||
panel.classList.remove('is-ajax-loading');
|
||||
})
|
||||
.catch(function () {
|
||||
panel.classList.remove('is-ajax-loading');
|
||||
});
|
||||
}
|
||||
|
||||
tabs.forEach(function (tab) {
|
||||
tab.addEventListener('click', function () {
|
||||
var target = tab.getAttribute('data-tab');
|
||||
tabs.forEach(function (item) {
|
||||
var active = item === tab;
|
||||
item.classList.toggle('active', active);
|
||||
item.classList.toggle('is-active', active);
|
||||
item.setAttribute('aria-selected', active ? 'true' : 'false');
|
||||
});
|
||||
panels.forEach(function (panel) {
|
||||
var active = panel.getAttribute('data-tab-panel') === target;
|
||||
panel.classList.toggle('active', active);
|
||||
panel.classList.toggle('is-active', active);
|
||||
if (active) {
|
||||
panel.removeAttribute('hidden');
|
||||
loadPanel(panel, tab);
|
||||
} else {
|
||||
panel.setAttribute('hidden', '');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Homepage category tabs (was inline in CategoryTabsWidget).
|
||||
function initCategoryTabs() {
|
||||
document.querySelectorAll('[data-aksrt-home-cat-tabs]').forEach(function (section) {
|
||||
if (section.dataset.aksrtCatTabsBound === '1') return;
|
||||
section.dataset.aksrtCatTabsBound = '1';
|
||||
var rest = section.getAttribute('data-rest') || '';
|
||||
var count = section.getAttribute('data-count') || '6';
|
||||
var layout = section.getAttribute('data-layout') || 'card';
|
||||
var columns = section.getAttribute('data-columns') || '3';
|
||||
var context = section.getAttribute('data-context') || 'homepage';
|
||||
var showMore = section.getAttribute('data-show-more') === '1';
|
||||
var tabs = [].slice.call(section.querySelectorAll('.widget-tab-posts__tab'));
|
||||
var panels = [].slice.call(section.querySelectorAll('.widget-tab-posts__panel'));
|
||||
if (!tabs.length || !panels.length || !rest) return;
|
||||
|
||||
function load(panel) {
|
||||
if (!panel || panel.getAttribute('data-loaded') === '1') return;
|
||||
var cat = panel.getAttribute('data-cat') || '0';
|
||||
var more = panel.getAttribute('data-more') || '';
|
||||
var qs = new URLSearchParams({
|
||||
cat: cat,
|
||||
count: String(count),
|
||||
layout: layout,
|
||||
columns: String(columns),
|
||||
context: context,
|
||||
});
|
||||
var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + qs.toString();
|
||||
panel.classList.add('is-ajax-loading');
|
||||
fetch(url, { credentials: 'same-origin', headers: restHeaders() })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (j) {
|
||||
var d = (j && j.data) || j || {};
|
||||
var html = d.html || '';
|
||||
if (showMore && more) {
|
||||
html += '<div class="aksrt-home-widget__footer"><a class="aksrt-home-widget__more" href="' + more + '">查看更多</a></div>';
|
||||
}
|
||||
panel.innerHTML = html || '<div class="ajax-item widget-empty muted-2-color">暂无文章</div>';
|
||||
panel.setAttribute('data-loaded', '1');
|
||||
panel.classList.remove('is-ajax-loading');
|
||||
})
|
||||
.catch(function () {
|
||||
panel.classList.remove('is-ajax-loading');
|
||||
});
|
||||
}
|
||||
|
||||
tabs.forEach(function (tab) {
|
||||
tab.addEventListener('click', function () {
|
||||
var target = tab.getAttribute('data-tab');
|
||||
tabs.forEach(function (item) {
|
||||
var active = item === tab;
|
||||
item.classList.toggle('active', active);
|
||||
item.setAttribute('aria-selected', active ? 'true' : 'false');
|
||||
});
|
||||
panels.forEach(function (panel) {
|
||||
var active = panel.getAttribute('data-tab-panel') === target;
|
||||
panel.classList.toggle('active', active);
|
||||
if (active) {
|
||||
panel.removeAttribute('hidden');
|
||||
load(panel);
|
||||
} else {
|
||||
panel.setAttribute('hidden', '');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Product multi-tab.
|
||||
function initProductTabs() {
|
||||
document.querySelectorAll('[data-aksrt-product-tab]').forEach(function (root) {
|
||||
if (root.dataset.aksrtProductTabBound === '1') return;
|
||||
root.dataset.aksrtProductTabBound = '1';
|
||||
var rest = root.getAttribute('data-rest') || '';
|
||||
var per = root.getAttribute('data-per-page') || '8';
|
||||
var style = root.getAttribute('data-style') || 'default';
|
||||
var paginate = root.getAttribute('data-paginate') || 'ajax';
|
||||
|
||||
function skeleton(n) {
|
||||
n = Math.max(1, Math.min(12, parseInt(n, 10) || 4));
|
||||
var html = '<div class="aksrt-product-tab__skeleton">';
|
||||
for (var i = 0; i < n; i++) {
|
||||
html += '<div class="placeholder-row product-card-placeholder"><div class="placeholder thumb"></div><div class="placeholder k1"></div><div class="placeholder s1"></div></div>';
|
||||
}
|
||||
return html + '</div>';
|
||||
}
|
||||
|
||||
function loadPanel(panel, btn) {
|
||||
if (!panel || panel.getAttribute('data-loaded') === '1' || !rest) return;
|
||||
var grid = panel.querySelector('[data-aksrt-ajaxpager]');
|
||||
if (!grid) return;
|
||||
var qs = new URLSearchParams({
|
||||
page: '1',
|
||||
per_page: per,
|
||||
style: style,
|
||||
paginate: paginate,
|
||||
orderby: btn.getAttribute('data-orderby') || 'date',
|
||||
order: 'DESC',
|
||||
cat_ids: btn.getAttribute('data-cat-ids') || '',
|
||||
tag_ids: btn.getAttribute('data-tag-ids') || '',
|
||||
discount_ids: btn.getAttribute('data-discount-ids') || '',
|
||||
});
|
||||
var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + qs.toString();
|
||||
grid.classList.add('is-ajax-loading');
|
||||
if (!grid.querySelector('.aksrt-product-tab__skeleton') && !grid.querySelector('.ajax-item')) {
|
||||
grid.insertAdjacentHTML('afterbegin', skeleton(per));
|
||||
}
|
||||
fetch(url, { credentials: 'same-origin', headers: restHeaders() })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (j) {
|
||||
var d = (j && j.data && (j.data.data || j.data)) || j || {};
|
||||
var html = d.html || '';
|
||||
var pag = d.paginate_html || d.paginateHtml || '';
|
||||
var loader = grid.querySelector('[data-aksrt-ajax-loader]');
|
||||
grid.innerHTML = '';
|
||||
if (html) grid.insertAdjacentHTML('beforeend', html);
|
||||
else grid.insertAdjacentHTML('beforeend', '<p class="widget-empty ajax-item">暂无商品</p>');
|
||||
if (pag) grid.insertAdjacentHTML('beforeend', pag);
|
||||
if (loader) grid.appendChild(loader);
|
||||
panel.setAttribute('data-loaded', '1');
|
||||
grid.classList.remove('is-ajax-loading');
|
||||
})
|
||||
.catch(function () {
|
||||
grid.classList.remove('is-ajax-loading');
|
||||
});
|
||||
}
|
||||
|
||||
root.querySelectorAll('.aksrt-product-tab__header').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
root.querySelectorAll('.aksrt-product-tab__header').forEach(function (b) {
|
||||
b.classList.remove('is-active');
|
||||
});
|
||||
root.querySelectorAll('.aksrt-product-tab__panel').forEach(function (p) {
|
||||
p.style.display = 'none';
|
||||
p.classList.remove('is-active');
|
||||
});
|
||||
btn.classList.add('is-active');
|
||||
var idx = btn.getAttribute('data-tab-index');
|
||||
var panel = root.querySelector('.aksrt-product-tab__panel[data-tab-index="' + idx + '"]');
|
||||
if (panel) {
|
||||
panel.style.display = '';
|
||||
panel.classList.add('is-active');
|
||||
loadPanel(panel, btn);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Main posts load_mode=ajax first paint.
|
||||
function initMainPostsLazy() {
|
||||
document.querySelectorAll('.aksrt-main-posts[data-load-mode="ajax"]').forEach(function (root) {
|
||||
if (root.dataset.aksrtMainLazyBound === '1') return;
|
||||
root.dataset.aksrtMainLazyBound = '1';
|
||||
if (root.getAttribute('data-loaded') === '1') return;
|
||||
var rest = root.getAttribute('data-aksrt-ajax-url') || root.getAttribute('data-rest') || '';
|
||||
if (!rest) return;
|
||||
var qs = root.getAttribute('data-query') || '';
|
||||
var url = rest + (rest.indexOf('?') > -1 ? '&' : '?') + (qs || 'page=1');
|
||||
root.classList.add('is-ajax-loading');
|
||||
fetch(url, { credentials: 'same-origin', headers: restHeaders() })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (j) {
|
||||
var d = (j && j.data) || j || {};
|
||||
var html = d.html || '';
|
||||
var pag = d.paginate_html || d.paginateHtml || '';
|
||||
var loader = root.querySelector('[data-aksrt-ajax-loader]');
|
||||
// Remove skeleton rows.
|
||||
root.querySelectorAll('.aksrt-main-posts__skeleton, .posts-mini.placeholder-row, .placeholder-row').forEach(function (n) {
|
||||
n.remove();
|
||||
});
|
||||
if (html) {
|
||||
root.insertAdjacentHTML('afterbegin', html);
|
||||
} else {
|
||||
root.insertAdjacentHTML('afterbegin', '<p class="widget-empty ajax-item">暂无文章</p>');
|
||||
}
|
||||
// Replace/append paginate.
|
||||
var oldPag = root.querySelector('.ajax-pag, .pagenav.ajax-pag');
|
||||
if (oldPag) oldPag.remove();
|
||||
if (pag) {
|
||||
if (loader) loader.insertAdjacentHTML('beforebegin', pag);
|
||||
else root.insertAdjacentHTML('beforeend', pag);
|
||||
}
|
||||
root.setAttribute('data-loaded', '1');
|
||||
root.classList.remove('is-ajax-loading');
|
||||
})
|
||||
.catch(function () {
|
||||
root.classList.remove('is-ajax-loading');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initFloatingQRCodes() {
|
||||
var wrap = document.querySelector('.float-right');
|
||||
if (!wrap) return;
|
||||
|
||||
wrap.querySelectorAll('.service-wechat .hover-show-con p, .service-qq .hover-show-con p').forEach(function (node) {
|
||||
node.remove();
|
||||
});
|
||||
|
||||
if (typeof window.kjua !== 'function') return;
|
||||
|
||||
wrap.querySelectorAll('.float-btn-qrcode').forEach(function (node) {
|
||||
if (node.dataset.qrReady === '1') return;
|
||||
|
||||
// footer.php uses data-qrcode-url; keep data-qr-text as fallback alias
|
||||
var qrText =
|
||||
node.getAttribute('data-qrcode-url') ||
|
||||
node.getAttribute('data-qr-text') ||
|
||||
window.location.href;
|
||||
var qrSize = parseInt(node.getAttribute('data-qr-size') || '120', 10);
|
||||
if (!qrText || !qrSize) return;
|
||||
|
||||
try {
|
||||
node.innerHTML = '';
|
||||
node.appendChild(window.kjua({
|
||||
render: 'svg',
|
||||
text: qrText,
|
||||
size: qrSize,
|
||||
ecLevel: 'H',
|
||||
fill: '#15171A',
|
||||
back: '#FFFFFF',
|
||||
quiet: 0,
|
||||
crisp: true
|
||||
}));
|
||||
node.style.width = qrSize + 'px';
|
||||
node.style.height = qrSize + 'px';
|
||||
node.dataset.qrReady = '1';
|
||||
} catch (error) {
|
||||
node.dataset.qrReady = '0';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
initWidgetTabs();
|
||||
initCategoryTabs();
|
||||
initProductTabs();
|
||||
initMainPostsLazy();
|
||||
initFloatingQRCodes();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user