MediaWiki:Gadget-GrAnnotations.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 30: | Line 30: | ||
* STORAGE | * STORAGE | ||
* ─────── | * ─────── | ||
* Comments → MediaWiki page: <PageTitle>/ | * Comments → MediaWiki page: Talk:<PageTitle>/GrComments | ||
* Format: {{GrComment|id | * Talk namespace is excluded from XML/PDF exports and never | ||
* shown in the content editor — comments cannot affect exports. | |||
* Bookmarks → localStorage | * Format: {{GrComment|id=…|author=…|timestamp=…|quote=…|text=…}} | ||
* | * Bookmarks → localStorage (per-user, per-page — not shared across users) | ||
* Key: grantha_bm_<pageName> | |||
* | * | ||
* ADMIN NOTIFICATION | * ADMIN NOTIFICATION | ||
* ────────────────── | * ────────────────── | ||
* On new comment: | * On new comment: sends email via MW EmailUser API (action=emailuser). | ||
* | * Email contains the comment text and a direct anchor link to the passage. | ||
* Fallback: if admin has no email set, posts to User_talk:ADMIN_USER instead. | |||
* Requires $wgEnableEmail = true and $wgEnableUserEmail = true (MW defaults). | |||
* | * | ||
* DEPENDENCIES | * DEPENDENCIES | ||
| Line 66: | Line 69: | ||
var CMT_LS_KEY = 'grantha_cmt_' + ( ( window.mw && mw.config.get( 'wgPageName' ) ) || '' ); | var CMT_LS_KEY = 'grantha_cmt_' + ( ( window.mw && mw.config.get( 'wgPageName' ) ) || '' ); | ||
var pageTitle = ( window.mw && mw.config.get( 'wgPageName' ) ) || ''; | var pageTitle = ( window.mw && mw.config.get( 'wgPageName' ) ) || ''; | ||
var commentsPage = pageTitle + '/ | /* Comments stored on Talk:<PageTitle>/GrComments — talk namespace is | ||
* excluded from XML/PDF exports and never shown in the content editor, | |||
* so comments cannot tamper with document content or affect exports. */ | |||
var commentsPage = 'Talk:' + pageTitle + '/GrComments'; | |||
var currentUser = ( window.mw && mw.config.get( 'wgUserName' ) ) || ''; | var currentUser = ( window.mw && mw.config.get( 'wgUserName' ) ) || ''; | ||
var userInitial = currentUser ? currentUser.charAt( 0 ).toUpperCase() : '?'; | var userInitial = currentUser ? currentUser.charAt( 0 ).toUpperCase() : '?'; | ||
| Line 380: | Line 386: | ||
// Persist to wiki | // Persist to wiki | ||
saveCommentToWiki( id, quote, text, ts ); | saveCommentToWiki( id, quote, text, ts ); | ||
notifyAdmin( quote, text, ts ); | notifyAdmin( _activeId || '', quote, text, ts ); | ||
// Update panel | // Update panel | ||
| Line 411: | Line 417: | ||
api.postWithEditToken({ | api.postWithEditToken({ | ||
action:'edit', title:commentsPage, text:updated, | action:'edit', title:commentsPage, text:updated, | ||
summary:'New comment by ' + currentUser + ' on [[' + pageTitle + ']]', | summary:'New comment by ' + currentUser + ' on [[' + pageTitle + ']] (stored off-page)', | ||
bot:0, | bot:0, | ||
}).catch(function(){}); | }).catch(function(){}); | ||
| Line 417: | Line 423: | ||
} | } | ||
function notifyAdmin( quote, commentText, ts ) { | function notifyAdmin( anchorId, quote, commentText, ts ) { | ||
if ( !window.mw || !ADMIN_USER || !currentUser ) return; | /* Send a real email to the admin via MW's built-in EmailUser API. | ||
* This requires: | |||
* 1. The admin account (ADMIN_USER) has a confirmed email address set | |||
* in Special:Preferences. | |||
* 2. $wgEnableEmail and $wgEnableUserEmail are true in LocalSettings.php | |||
* (both are true by default in MW). | |||
* The email contains a direct scrollable anchor link to the passage. */ | |||
if ( !window.mw || !ADMIN_USER ) return; | |||
/* Build a deep-link URL with the anchor ID so the admin can jump | |||
* directly to the highlighted passage with one click. */ | |||
var articlePath = ( mw.config.get('wgArticlePath') || '/wiki/$1' ) | |||
.replace( '$1', pageTitle ); | |||
var anchorLink = window.location.origin + articlePath | |||
+ ( anchorId ? '#' + anchorId : '' ); | |||
var pageDisplay = pageTitle.replace( /_/g, ' ' ); | |||
var subject = '[Grantha] New comment on "' + pageDisplay + '"'; | |||
var body = 'A new comment has been posted on ' + pageDisplay + '. | |||
' | |||
+ 'Posted by : ' + ( currentUser || 'Anonymous' ) + ' | |||
' | |||
+ 'Time : ' + ts + ' | |||
' | |||
+ 'Passage : "' + quote + '" | |||
' | |||
+ 'Comment : | |||
' + commentText + ' | |||
' | |||
+ '────────────────────────────────── | |||
' | |||
+ 'Jump to passage: | |||
' + anchorLink + ' | |||
' | |||
+ 'View all comments: | |||
' | |||
+ window.location.origin | |||
+ ( mw.config.get('wgArticlePath') || '/wiki/$1' ) | |||
.replace( '$1', 'Talk:' + pageTitle + '/GrComments' ) | |||
+ ' | |||
'; | |||
new mw.Api().post({ | |||
action: 'emailuser', | |||
target: ADMIN_USER, | |||
subject: subject, | |||
text: body, | |||
token: mw.user.tokens.get( 'csrfToken' ), | |||
}).catch(function(){ | |||
/* EmailUser failed (e.g. admin has no email set) — fall back to | |||
* a talk-page notification so the admin still gets an Echo alert. */ | |||
if ( !currentUser ) return; | |||
var adminTalk = 'User_talk:' + ADMIN_USER; | |||
var wikimsg = '== New comment on [[' + pageDisplay + ']] == | |||
' | |||
+ '; By: ' + ( currentUser || 'Anonymous' ) + ' | |||
' | |||
+ '; Passage: //' + quote + '// | |||
' | |||
+ '; Link: ' + anchorLink + ' | |||
' | |||
+ commentText.slice(0,500) | |||
+ ( commentText.length > 500 ? ' | |||
…' : '' ) | |||
+ ' | |||
[[User:Chandrashekars|Chandrashekars]] ([[User talk:Chandrashekars|talk]]) 10:47, 24 April 2026 (UTC)'; | |||
new mw.Api().postWithEditToken({ | |||
action:'edit', title:adminTalk, section:'new', | |||
sectiontitle:'Comment on ' + pageDisplay, | |||
text:wikimsg, | |||
summary:'Comment notification from [[' + pageDisplay + ']]', | |||
bot:0, | |||
}).catch(function(){}); | |||
}); | |||
} | } | ||