补充主题静态资源与归档模板
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
/**
|
||||
* AKSRT Post Share
|
||||
*
|
||||
* Handles share dropdowns, social share targets, copy link,
|
||||
* and WeChat bridge handoff with QR fallback.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function notify(message, type) {
|
||||
if (!message) return;
|
||||
if (typeof window.AksrtToast === 'function') {
|
||||
window.AksrtToast(message, type || 'info');
|
||||
return;
|
||||
}
|
||||
if (typeof window.showToast === 'function') {
|
||||
window.showToast(message, type || 'info');
|
||||
return;
|
||||
}
|
||||
if (typeof window.aksrtToast === 'function') {
|
||||
window.aksrtToast(message, type || 'info');
|
||||
return;
|
||||
}
|
||||
window.alert(message);
|
||||
}
|
||||
|
||||
function getMetaContent(selectors) {
|
||||
for (var i = 0; i < selectors.length; i += 1) {
|
||||
var node = document.querySelector(selectors[i]);
|
||||
var content = node ? node.getAttribute('content') : '';
|
||||
if (content) return content;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function getPlatform(node) {
|
||||
if (!node) return '';
|
||||
return node.getAttribute('data-share-platform') || node.getAttribute('data-platform') || '';
|
||||
}
|
||||
|
||||
function resolvePayload(node) {
|
||||
// Unified payload via the shared builder; fall back to local resolution
|
||||
// only if the builder script is unavailable.
|
||||
if (window.AksrtShareData && typeof window.AksrtShareData.resolve === 'function') {
|
||||
return window.AksrtShareData.resolve(node);
|
||||
}
|
||||
|
||||
var dropdown = document.getElementById('share-dropdown');
|
||||
var source = node && typeof node.closest === 'function'
|
||||
? node.closest('[data-share-url], [data-share-title], [data-share-desc], [data-share-image]')
|
||||
: null;
|
||||
var context = source || dropdown;
|
||||
|
||||
function readAttr(name) {
|
||||
return (node && node.getAttribute(name)) || (context && context.getAttribute(name)) || '';
|
||||
}
|
||||
|
||||
return {
|
||||
title: readAttr('data-share-title') || document.title,
|
||||
url: readAttr('data-share-url') || window.location.href,
|
||||
desc: readAttr('data-share-desc') || getMetaContent(['meta[property="og:description"]', 'meta[name="description"]']),
|
||||
text: readAttr('data-share-text') || '',
|
||||
image: readAttr('data-share-image') || getMetaContent(['meta[property="og:image"]']),
|
||||
qrcode: readAttr('data-share-qrcode') || ''
|
||||
};
|
||||
}
|
||||
|
||||
function openWindow(url) {
|
||||
if (!url) return;
|
||||
window.open(url, '_blank', 'width=640,height=560,scrollbars=yes,resizable=yes');
|
||||
}
|
||||
|
||||
function buildShareUrl(platform, payload) {
|
||||
switch (platform) {
|
||||
case 'weibo':
|
||||
return 'https://service.weibo.com/share/share.php?url=' + encodeURIComponent(payload.url) + '&title=' + encodeURIComponent(payload.title + (payload.text ? ' ' + payload.text : ''));
|
||||
case 'qq':
|
||||
return 'https://connect.qq.com/widget/shareqq/index.html?url=' + encodeURIComponent(payload.url) + '&title=' + encodeURIComponent(payload.title) + '&desc=' + encodeURIComponent(payload.desc || payload.text || '');
|
||||
case 'twitter':
|
||||
return 'https://x.com/intent/tweet?url=' + encodeURIComponent(payload.url) + '&text=' + encodeURIComponent(payload.title);
|
||||
case 'telegram':
|
||||
return 'https://t.me/share/url?url=' + encodeURIComponent(payload.url) + '&text=' + encodeURIComponent(payload.title);
|
||||
case 'linkedin':
|
||||
return 'https://www.linkedin.com/sharing/share-offsite/?url=' + encodeURIComponent(payload.url);
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function fallbackCopy(text) {
|
||||
var textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
textarea.style.cssText = 'position:fixed;left:-9999px;top:-9999px;opacity:0;';
|
||||
textarea.setAttribute('readonly', '');
|
||||
document.body.appendChild(textarea);
|
||||
try {
|
||||
textarea.select();
|
||||
textarea.setSelectionRange(0, textarea.value.length);
|
||||
if (!document.execCommand('copy')) {
|
||||
throw new Error('copy command failed');
|
||||
}
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
}
|
||||
|
||||
function copyLink(text) {
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
return navigator.clipboard.writeText(text).catch(function () {
|
||||
fallbackCopy(text);
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
fallbackCopy(text);
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
function initShareDropdown() {
|
||||
var trigger = document.getElementById('action-share-trigger');
|
||||
var dropdown = document.getElementById('share-dropdown');
|
||||
if (!trigger || !dropdown || dropdown.dataset.aksrtShareBound === '1') return;
|
||||
|
||||
dropdown.dataset.aksrtShareBound = '1';
|
||||
|
||||
var qrBox = document.getElementById('share-qrcode-box');
|
||||
var qrImage = document.getElementById('share-qrcode-image');
|
||||
|
||||
function closeDropdown() {
|
||||
dropdown.setAttribute('aria-hidden', 'true');
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
if (window.AksrtShare && typeof window.AksrtShare.hideQrFallback === 'function') {
|
||||
window.AksrtShare.hideQrFallback(qrBox);
|
||||
} else if (qrBox) {
|
||||
qrBox.classList.remove('is-visible');
|
||||
qrBox.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
function toggleDropdown() {
|
||||
var isOpen = dropdown.getAttribute('aria-hidden') === 'false';
|
||||
if (isOpen) {
|
||||
closeDropdown();
|
||||
return;
|
||||
}
|
||||
|
||||
dropdown.setAttribute('aria-hidden', 'false');
|
||||
trigger.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
|
||||
trigger.addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
toggleDropdown();
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (event) {
|
||||
if (!trigger.contains(event.target) && !dropdown.contains(event.target)) {
|
||||
closeDropdown();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Escape') {
|
||||
closeDropdown();
|
||||
}
|
||||
});
|
||||
|
||||
dropdown.addEventListener('click', function (event) {
|
||||
var item = event.target.closest('.share-item');
|
||||
if (!item) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
handleShareAction(item, {
|
||||
qrBox: qrBox,
|
||||
qrImage: qrImage,
|
||||
closeDropdown: closeDropdown,
|
||||
withinDropdown: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleWeixinShare(node, payload, options) {
|
||||
options = options || {};
|
||||
|
||||
var share = window.AksrtShare;
|
||||
if (!share || typeof share.openWeixinShare !== 'function') {
|
||||
notify('微信分享模块未加载', 'error');
|
||||
return Promise.resolve({ mode: 'error' });
|
||||
}
|
||||
|
||||
if (
|
||||
options.qrBox &&
|
||||
options.qrBox.classList.contains('is-visible') &&
|
||||
(!share.isWeixinEnv || !share.isWeixinEnv())
|
||||
) {
|
||||
share.hideQrFallback(options.qrBox);
|
||||
return Promise.resolve({ mode: 'closed' });
|
||||
}
|
||||
|
||||
return share.openWeixinShare({
|
||||
title: payload.title,
|
||||
url: payload.url,
|
||||
desc: payload.desc || payload.text || '',
|
||||
image: payload.image,
|
||||
qrBox: options.qrBox || null,
|
||||
qrImage: options.qrImage || null
|
||||
}).then(function (result) {
|
||||
if (result && result.message) {
|
||||
notify(result.message, result.mode === 'error' ? 'error' : (result.mode === 'bridge' ? 'success' : 'info'));
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
function handleShareAction(node, options) {
|
||||
var platform = getPlatform(node);
|
||||
if (!platform) return Promise.resolve({ mode: 'noop' });
|
||||
|
||||
var payload = resolvePayload(node);
|
||||
if (!payload.url) return Promise.resolve({ mode: 'noop' });
|
||||
|
||||
if (platform === 'copy') {
|
||||
return copyLink(payload.url).then(function () {
|
||||
notify('链接已复制', 'success');
|
||||
if (options && typeof options.closeDropdown === 'function') {
|
||||
options.closeDropdown();
|
||||
}
|
||||
return { mode: 'copy' };
|
||||
}).catch(function () {
|
||||
notify('复制失败,请手动复制链接', 'error');
|
||||
return { mode: 'error' };
|
||||
});
|
||||
}
|
||||
|
||||
if (platform === 'wechat') {
|
||||
return handleWeixinShare(node, payload, options).then(function (result) {
|
||||
if (result && result.mode !== 'qr' && result.mode !== 'error' && options && typeof options.closeDropdown === 'function') {
|
||||
options.closeDropdown();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
if (platform === 'poster') {
|
||||
if (window.AksrtPosterShare && typeof window.AksrtPosterShare.open === 'function') {
|
||||
window.AksrtPosterShare.open(payload);
|
||||
if (options && typeof options.closeDropdown === 'function') options.closeDropdown();
|
||||
return Promise.resolve({ mode: 'poster' });
|
||||
}
|
||||
notify('海报模块未加载', 'error');
|
||||
return Promise.resolve({ mode: 'error' });
|
||||
}
|
||||
|
||||
var shareUrl = buildShareUrl(platform, payload);
|
||||
if (!shareUrl) {
|
||||
return Promise.resolve({ mode: 'noop' });
|
||||
}
|
||||
|
||||
openWindow(shareUrl);
|
||||
if (options && typeof options.closeDropdown === 'function') {
|
||||
options.closeDropdown();
|
||||
}
|
||||
|
||||
return Promise.resolve({ mode: 'window' });
|
||||
}
|
||||
|
||||
function bindGenericShareButtons() {
|
||||
document.addEventListener('click', function (event) {
|
||||
var node = event.target.closest('[data-share-platform]');
|
||||
if (!node || node.closest('#share-dropdown')) return;
|
||||
|
||||
event.preventDefault();
|
||||
handleShareAction(node, {});
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (event) {
|
||||
var node = event.target.closest('[data-share-copy]');
|
||||
if (!node) return;
|
||||
|
||||
event.preventDefault();
|
||||
var url = node.getAttribute('data-share-url') || window.location.href;
|
||||
copyLink(url).then(function () {
|
||||
notify('链接已复制', 'success');
|
||||
}).catch(function () {
|
||||
notify('复制失败,请手动复制链接', 'error');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
initShareDropdown();
|
||||
bindGenericShareButtons();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user