/** * 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(); } })();