匿名
未登录
中文(简体)
登录
Dhamma.cn
搜索
有觉性 以安住且中立的心 照见身心的实相
查看“︁MediaWiki:QuoteCopy.js”︁的源代码
来自Dhamma.cn
命名空间
系统消息
讨论
更多
更多
页面操作
阅读
查看源代码
历史
刷新
←
MediaWiki:QuoteCopy.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
管理员
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
/* ========================================================= Dhamma.cn QuoteCopy.js 功能: 选中文字 ↓ 松开鼠标 ↓ 出现引用工具 ↓ 复制原文 / 复制出处 / 复制学术脚注 MediaWiki 1.43 使用现有 UrlShortener ========================================================= */ (function () { 'use strict'; /* ===================================================== 基本设置 ===================================================== */ var MIN_LENGTH = 8; var MAX_LENGTH = 8000; var popup = null; var selectedText = ''; /* * 当前页面短网址。 * * 同一个页面只请求一次。 */ var pageShortUrl = null; var shortUrlPromise = null; /* ===================================================== 1. 判断是否启用 ===================================================== */ function shouldEnable() { /* * 只在 Main namespace */ if ( mw.config.get('wgNamespaceNumber') !== 0 ) { return false; } /* * 只在普通阅读页面 */ if ( mw.config.get('wgAction') !== 'view' ) { return false; } /* * 如果明确存在引用元数据, * 启用。 */ if ( document.getElementById( 'dhamma-quote-metadata' ) ) { return true; } /* * 如果属于: * * 分类:隆波帕默尊者 * * 自动启用。 */ var categories = mw.config.get('wgCategories') || []; return categories.indexOf( '隆波帕默尊者' ) !== -1; } /* ===================================================== 2. 获取引用信息 ===================================================== */ function getMetadata() { var metadata = document.getElementById( 'dhamma-quote-metadata' ); /* * 默认设置 */ var result = { author: '', source: 'Dhamma.cn', title: '', date: '' }; /* * 如果页面有 metadata */ if (metadata) { result.author = metadata.getAttribute( 'data-author' ) || ''; result.source = metadata.getAttribute( 'data-source' ) || 'Dhamma.cn'; result.title = metadata.getAttribute( 'data-title' ) || ''; result.date = metadata.getAttribute( 'data-date' ) || ''; return result; } /* * 没有 metadata 时, * 如果是隆波分类, * 自动判断作者。 */ var categories = mw.config.get('wgCategories') || []; if ( categories.indexOf( '隆波帕默尊者' ) !== -1 ) { result.author = '隆波帕默尊者'; } return result; } /* ===================================================== 3. 获取页面标题 ===================================================== */ function getPageTitle() { var metadata = getMetadata(); /* * metadata 中指定标题 * 优先使用。 */ if (metadata.title) { return metadata.title; } /* * MediaWiki 页面标题 */ var title = mw.config.get('wgTitle'); if (title) { return title; } /* * 后备方案 */ var heading = document.querySelector( '#firstHeading, .mw-page-title-main' ); if (heading) { return heading.textContent.trim(); } /* * 最终后备 */ return document.title .replace(/\s*-\s*.*$/, '') .trim(); } /* ===================================================== 4. 标题格式处理 ===================================================== */ function formatTitle(title) { if (!title) { return ''; } /* * 如果本身已经有《》 * 不重复添加。 */ if ( title.charAt(0) === '《' && title.charAt( title.length - 1 ) === '》' ) { return title; } return '《' + title + '》'; } /* ===================================================== 5. 创建引用 Popup ===================================================== */ function createPopup() { if (popup) { return popup; } popup = document.createElement('div'); popup.id = 'dhamma-quote-popup'; popup.setAttribute( 'role', 'dialog' ); popup.setAttribute( 'aria-label', 'Dhamma.cn 引用工具' ); popup.innerHTML = '<div class="dhamma-quote-popup-inner">' + '<div class="dhamma-quote-popup-label">' + '引用此段开示' + '</div>' + '<div class="dhamma-quote-popup-buttons">' + '<button type="button" ' + 'class="dhamma-quote-button" ' + 'data-action="copy">' + '复制原文' + '</button>' + '<button type="button" ' + 'class="dhamma-quote-button dhamma-quote-primary" ' + 'data-action="source">' + '复制并附出处' + '</button>' + '<button type="button" ' + 'class="dhamma-quote-button" ' + 'data-action="footnote">' + '复制学术脚注' + '</button>' + '</div>' + '</div>'; document.body.appendChild( popup ); /* * 不让点击 Popup 时 * 改变当前选区。 */ popup.addEventListener( 'mousedown', function (event) { event.preventDefault(); } ); /* * 按钮事件 */ popup.addEventListener( 'click', function (event) { var button = event.target.closest( '.dhamma-quote-button' ); if (!button) { return; } var action = button.getAttribute( 'data-action' ); if ( action === 'copy' ) { copyPlainText(); } if ( action === 'source' ) { copyWithSource(); } if ( action === 'footnote' ) { copyFootnote(); } } ); return popup; } /* ===================================================== 6. 获取选中文字 ===================================================== */ function getSelectionData() { var selection = window.getSelection(); if ( !selection || selection.rangeCount === 0 ) { return null; } var text = selection.toString().trim(); if (!text) { return null; } if ( text.length < MIN_LENGTH ) { return null; } if ( text.length > MAX_LENGTH ) { return null; } var range = selection.getRangeAt(0); var container = range.commonAncestorContainer; if ( container.nodeType === Node.TEXT_NODE ) { container = container.parentElement; } if (!container) { return null; } /* * 必须来自正文。 */ var content = container.closest( '#mw-content-text .mw-parser-output' ); if (!content) { return null; } return { text: normalizeText(text), range: range.cloneRange() }; } /* ===================================================== 7. 清理选中文字 ===================================================== */ function normalizeText(text) { return text .replace( /\u00a0/g, ' ' ) .replace( /\r\n/g, '\n' ) .replace( /[ \t]+\n/g, '\n' ) .replace( /\n[ \t]+/g, '\n' ) .replace( /\n{3,}/g, '\n\n' ) .trim(); } /* ===================================================== 8. 获取 Canonical URL ===================================================== */ function getCanonicalUrl() { var url = mw.config.get( 'wgCanonicalUrl' ); if (url) { return url; } /* * 后备 */ var pageName = mw.config.get( 'wgPageName' ); if ( pageName && mw.util && mw.util.getUrl ) { return mw.util.getUrl( pageName ); } return window.location.href; } /* ===================================================== 9. 获取短网址 ===================================================== */ function getShortUrl() { /* * 当前页面已经取得。 */ if (pageShortUrl) { return Promise.resolve( pageShortUrl ); } /* * 已经正在请求。 */ if (shortUrlPromise) { return shortUrlPromise; } /* * 调用 MediaWiki UrlShortener */ shortUrlPromise = new mw.Api().post({ action: 'shortenurl', url: getCanonicalUrl() }).then( function (data) { if ( data && data.shortenurl && data.shortenurl.shorturl ) { pageShortUrl = data.shortenurl.shorturl; return pageShortUrl; } throw new Error( 'UrlShortener 未返回短网址' ); } ).catch( function (error) { shortUrlPromise = null; throw error; } ); return shortUrlPromise; } /* ===================================================== 10. 获取日期 ===================================================== */ function getAccessDate() { var now = new Date(); var year = now.getFullYear(); var month = String( now.getMonth() + 1 ).padStart( 2, '0' ); var day = String( now.getDate() ).padStart( 2, '0' ); return ( year + '-' + month + '-' + day ); } /* ===================================================== 11. Clipboard ===================================================== */ function copyText( text, successMessage ) { /* * 现代浏览器 */ if ( navigator.clipboard && window.isSecureContext ) { navigator.clipboard .writeText(text) .then( function () { showMessage( successMessage ); } ) .catch( function () { fallbackCopy( text, successMessage ); } ); return; } /* * 后备 */ fallbackCopy( text, successMessage ); } /* ===================================================== 12. 备用复制 ===================================================== */ function fallbackCopy( text, successMessage ) { var textarea = document.createElement( 'textarea' ); textarea.value = text; textarea.setAttribute( 'readonly', '' ); textarea.style.position = 'fixed'; textarea.style.left = '-9999px'; textarea.style.top = '0'; document.body.appendChild( textarea ); textarea.focus(); textarea.select(); var success = false; try { success = document.execCommand( 'copy' ); } catch (error) { success = false; } document.body.removeChild( textarea ); if (success) { showMessage( successMessage ); } else { showMessage( '复制失败,请使用 Ctrl+C。' ); } } /* ===================================================== 13. 复制原文 ===================================================== */ function copyPlainText() { if (!selectedText) { return; } copyText( selectedText, '已复制选中的法谈内容' ); hidePopup(); } /* ===================================================== 14. 复制并附出处 ===================================================== */ function copyWithSource() { if (!selectedText) { return; } showMessage( '正在生成 Dhamma.cn 短网址……' ); getShortUrl() .then( function (shortUrl) { var metadata = getMetadata(); var title = formatTitle( getPageTitle() ); var output = selectedText + '\n\n' + '----------------------------------------' + '\n' + '法谈摘自:' + metadata.source + ' ' + title + '\n' + '该篇网址:' + shortUrl + '\n' + '转载请保持原文,随喜分享,Sadhu!'; copyText( output, '已复制法谈内容及出处' ); hidePopup(); } ) .catch( function (error) { console.error( 'Dhamma.cn UrlShortener:', error ); /* * 短网址失败时, * 不复制长 URL。 */ var metadata = getMetadata(); var title = formatTitle( getPageTitle() ); var output = selectedText + '\n\n' + '----------------------------------------' + '\n' + '法谈摘自:' + metadata.source + ' ' + title + '\n' + '转载请保持原文,随喜分享,Sadhu!'; copyText( output, '短网址暂时无法生成,已复制出处' ); hidePopup(); } ); } /* ===================================================== 15. 学术脚注 ===================================================== */ function copyFootnote() { if (!selectedText) { return; } showMessage( '正在生成 Dhamma.cn 短网址……' ); getShortUrl() .then( function (shortUrl) { var metadata = getMetadata(); var author = metadata.author || '隆波帕默尊者'; var source = metadata.source || 'Dhamma.cn'; var title = getPageTitle(); var output = author + ':《' + title + '》,' + source + ',' + shortUrl + '(访问日期:' + getAccessDate() + ')。'; copyText( output, '已复制学术脚注' ); hidePopup(); } ) .catch( function (error) { console.error( 'Dhamma.cn UrlShortener:', error ); var metadata = getMetadata(); var author = metadata.author || '隆波帕默尊者'; var source = metadata.source || 'Dhamma.cn'; var title = getPageTitle(); var output = author + ':《' + title + '》,' + source + '(访问日期:' + getAccessDate() + ')。'; copyText( output, '短网址生成失败,已复制脚注' ); hidePopup(); } ); } /* ===================================================== 16. Popup 定位 ===================================================== */ function positionPopup(range) { if ( !popup || !range ) { return; } var rect = range.getBoundingClientRect(); if ( rect.width === 0 && rect.height === 0 ) { return; } popup.style.display = 'block'; var popupRect = popup.getBoundingClientRect(); var left = rect.left + rect.width / 2 - popupRect.width / 2; var top = rect.bottom + 10; var margin = 10; /* * 左边界 */ if ( left < margin ) { left = margin; } /* * 右边界 */ if ( left + popupRect.width > window.innerWidth - margin ) { left = window.innerWidth - popupRect.width - margin; } /* * 底部空间不足 */ if ( top + popupRect.height > window.innerHeight - margin ) { top = rect.top - popupRect.height - 10; } /* * 顶部边界 */ if ( top < margin ) { top = margin; } popup.style.left = Math.round( left + window.scrollX ) + 'px'; popup.style.top = Math.round( top + window.scrollY ) + 'px'; } /* ===================================================== 17. 显示 Popup ===================================================== */ function showPopup(range) { createPopup(); popup.style.display = 'block'; positionPopup(range); } /* ===================================================== 18. 隐藏 Popup ===================================================== */ function hidePopup() { if (!popup) { return; } popup.style.display = 'none'; } /* ===================================================== 19. MediaWiki 提示 ===================================================== */ function showMessage(message) { if ( typeof mw.notify === 'function' ) { mw.notify( message, { type: 'info', autoHide: true } ); } else { console.log( message ); } } /* ===================================================== 20. 鼠标松开 ===================================================== */ function handleMouseUp() { setTimeout( function () { var data = getSelectionData(); if (!data) { return; } selectedText = data.text; showPopup( data.range ); }, 20 ); } /* ===================================================== 21. 点击页面其他位置 ===================================================== */ function handleDocumentMouseDown( event ) { if (!popup) { return; } if ( popup.contains( event.target ) ) { return; } hidePopup(); } /* ===================================================== 22. ESC ===================================================== */ function handleKeyDown(event) { if ( event.key === 'Escape' ) { hidePopup(); } } /* ===================================================== 23. 页面滚动 ===================================================== */ function handleScroll() { hidePopup(); } /* ===================================================== 24. 初始化 ===================================================== */ function init() { if (!shouldEnable()) { return; } createPopup(); document.addEventListener( 'mouseup', handleMouseUp ); document.addEventListener( 'mousedown', handleDocumentMouseDown ); document.addEventListener( 'keydown', handleKeyDown ); window.addEventListener( 'scroll', handleScroll, { passive: true } ); window.addEventListener( 'resize', handleScroll ); } /* ===================================================== 25. 启动 ===================================================== */ if ( document.readyState === 'loading' ) { document.addEventListener( 'DOMContentLoaded', init ); } else { init(); } })();
返回
MediaWiki:QuoteCopy.js
。
导航
导航
首页
随机页面
wiki工具
wiki工具
上传文件
特殊页面
获取短链接
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志