MediaWiki:Gadget-GrAnnotations.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 60: | Line 60: | ||
var $fbComposer, $fbIssueType, $fbText, $fbEmail, $fbSubmit, $fbQuote; | var $fbComposer, $fbIssueType, $fbText, $fbEmail, $fbSubmit, $fbQuote; | ||
// CHANGED: added $tabFootnotes / $paneFootnotes alongside the existing | // CHANGED: added $tabFootnotes / $paneFootnotes alongside the existing | ||
// Notes/Bookmarks tab+pane refs, for the | // Notes/Bookmarks tab+pane refs, for the Footnotes tab. NEW: now also | ||
var $tabNotes, $tabBookmarks, $tabFootnotes, $paneNotes, $paneBookmarks, $paneFootnotes; | // $tabSandarbha / $paneSandarbha, for References. | ||
var $tabNotes, $tabBookmarks, $tabFootnotes, $tabSandarbha, $paneNotes, $paneBookmarks, $paneFootnotes, $paneSandarbha; | |||
function buildDom() { | function buildDom() { | ||
| Line 168: | Line 169: | ||
' <button class="gra-tab" id="gra-tab-footnotes">', | ' <button class="gra-tab" id="gra-tab-footnotes">', | ||
' <span class="gra-icon gra-icon-footnote" aria-hidden="true"></span> Footnotes', | ' <span class="gra-icon gra-icon-footnote" aria-hidden="true"></span> Footnotes', | ||
' </button>', | |||
' <button class="gra-tab" id="gra-tab-sandarbha">', | |||
' <span class="gra-icon gra-icon-sandarbha" aria-hidden="true"></span> References', | |||
' </button>', | ' </button>', | ||
' </div>', | ' </div>', | ||
| Line 174: | Line 178: | ||
' <div class="gra-pane" id="gra-pane-bookmarks"></div>', | ' <div class="gra-pane" id="gra-pane-bookmarks"></div>', | ||
' <div class="gra-pane" id="gra-pane-footnotes"></div>', | ' <div class="gra-pane" id="gra-pane-footnotes"></div>', | ||
' <div class="gra-pane" id="gra-pane-sandarbha"></div>', | |||
' </div>', | ' </div>', | ||
'</div>', | '</div>', | ||
| Line 197: | Line 202: | ||
$tabBookmarks = $('#gra-tab-bookmarks'); | $tabBookmarks = $('#gra-tab-bookmarks'); | ||
$tabFootnotes = $('#gra-tab-footnotes'); | $tabFootnotes = $('#gra-tab-footnotes'); | ||
$tabSandarbha = $('#gra-tab-sandarbha'); | |||
$paneNotes = $('#gra-pane-notes'); | $paneNotes = $('#gra-pane-notes'); | ||
$paneBookmarks= $('#gra-pane-bookmarks'); | $paneBookmarks= $('#gra-pane-bookmarks'); | ||
$paneFootnotes= $('#gra-pane-footnotes'); | $paneFootnotes= $('#gra-pane-footnotes'); | ||
$paneSandarbha= $('#gra-pane-sandarbha'); | |||
$ntInput = $('#gra-nt-input'); | $ntInput = $('#gra-nt-input'); | ||
$ntSubmit = $('#gra-nt-submit'); | $ntSubmit = $('#gra-nt-submit'); | ||
| Line 464: | Line 471: | ||
$tabBookmarks.toggleClass('gra-tab-active', tab==='bookmarks'); | $tabBookmarks.toggleClass('gra-tab-active', tab==='bookmarks'); | ||
$tabFootnotes.toggleClass('gra-tab-active', tab==='footnotes'); | $tabFootnotes.toggleClass('gra-tab-active', tab==='footnotes'); | ||
$tabSandarbha.toggleClass('gra-tab-active', tab==='sandarbha'); | |||
$paneNotes.toggleClass('gra-pane-active', tab==='notes'); | $paneNotes.toggleClass('gra-pane-active', tab==='notes'); | ||
$paneBookmarks.toggleClass('gra-pane-active', tab==='bookmarks'); | $paneBookmarks.toggleClass('gra-pane-active', tab==='bookmarks'); | ||
$paneFootnotes.toggleClass('gra-pane-active', tab==='footnotes'); | $paneFootnotes.toggleClass('gra-pane-active', tab==='footnotes'); | ||
$paneSandarbha.toggleClass('gra-pane-active', tab==='sandarbha'); | |||
if (tab==='notes') renderNoteCards(); | if (tab==='notes') renderNoteCards(); | ||
else if (tab==='bookmarks') renderBookmarkCards(); | else if (tab==='bookmarks') renderBookmarkCards(); | ||
else renderFootnoteCards(); | else if (tab==='footnotes') renderFootnoteCards(); | ||
else renderSandarbhaCards(); | |||
} | } | ||
| Line 570: | Line 580: | ||
}); | }); | ||
$paneFootnotes.html(html); | $paneFootnotes.html(html); | ||
} | |||
// NEW: References (Sandarbha) tab. Simpler than footnotes — reads | |||
// straight off .gra-qe-sandarbha-highlight elements, no separate list | |||
// to scan. The highlighted text itself is the primary line (matching | |||
// how Notes/Bookmarks already identify themselves by quote); the | |||
// reference content stored in the hidden nested span is secondary. | |||
// Deliberately excludes that hidden span's own text when computing the | |||
// quote — el.textContent alone would include it too, regardless of its | |||
// display:none. | |||
function renderSandarbhaCards() { | |||
var items = document.querySelectorAll(CONTENT_SEL + ' .gra-qe-sandarbha-highlight'); | |||
if (!items.length) { | |||
$paneSandarbha.html('<div class="gra-empty-state">No references on this page.</div>'); | |||
return; | |||
} | |||
var html = ''; | |||
Array.prototype.forEach.call(items, function (el) { | |||
var contentSpan = el.querySelector('.gra-qe-sandarbha-content'); | |||
var refText = contentSpan ? contentSpan.textContent : ''; | |||
var quote = ''; | |||
Array.prototype.forEach.call(el.childNodes, function (node) { | |||
if (node === contentSpan) return; | |||
quote += node.textContent || ''; | |||
}); | |||
var id = el.getAttribute('data-gra-id') || ''; | |||
html += '<div class="gra-bookmark-card gra-sandarbha-card" data-gra-id="'+esc(id)+'">' | |||
+ '<span class="gra-icon gra-icon-sandarbha" aria-hidden="true"></span>' | |||
+ '<div class="gra-bookmark-info">' | |||
+ '<div class="gra-bookmark-name">'+esc(quote)+'</div>' | |||
+ (refText ? '<div class="gra-bookmark-quote">'+esc(refText)+'</div>' : '') | |||
+ '</div>' | |||
+ '</div>'; | |||
}); | |||
$paneSandarbha.html(html); | |||
} | } | ||
| Line 751: | Line 796: | ||
// NEW: third tab. | // NEW: third tab. | ||
$tabFootnotes.on('click', function(){ switchTab('footnotes'); }); | $tabFootnotes.on('click', function(){ switchTab('footnotes'); }); | ||
// NEW: fourth tab. | |||
$tabSandarbha.on('click', function(){ switchTab('sandarbha'); }); | |||
$paneNotes.on('click', '.gra-note-card', function(e){ | $paneNotes.on('click', '.gra-note-card', function(e){ | ||
| Line 778: | Line 825: | ||
// that broke every time the marker format changed. | // that broke every time the marker format changed. | ||
$paneFootnotes.on('click', '.gra-footnote-card', function(){ | $paneFootnotes.on('click', '.gra-footnote-card', function(){ | ||
var id = $(this).attr('data-gra-id'); | |||
if (id) { closePanel(); scrollToHighlight(id); } | |||
}); | |||
// NEW: same reuse for Sandarbha - it was designed from the start to | |||
// carry data-gra-id for exactly this reason. | |||
$paneSandarbha.on('click', '.gra-sandarbha-card', function(){ | |||
var id = $(this).attr('data-gra-id'); | var id = $(this).attr('data-gra-id'); | ||
if (id) { closePanel(); scrollToHighlight(id); } | if (id) { closePanel(); scrollToHighlight(id); } | ||
| Line 811: | Line 864: | ||
setTimeout(function(){ | setTimeout(function(){ | ||
var $card = $paneFootnotes.find('[data-gra-id="'+id+'"]'); | var $card = $paneFootnotes.find('[data-gra-id="'+id+'"]'); | ||
if ($card.length) { | |||
$card.addClass('gra-card-active'); | |||
$card[0].scrollIntoView({behavior:'smooth', block:'nearest'}); | |||
setTimeout(function(){ $card.removeClass('gra-card-active'); }, 2000); | |||
} | |||
}, 100); | |||
}); | |||
// NEW: same pattern for Sandarbha highlights. | |||
$(CONTENT_SEL).on('click', '.gra-qe-sandarbha-highlight', function(){ | |||
var id = $(this).attr('data-gra-id'); | |||
openPanel('sandarbha'); | |||
setTimeout(function(){ | |||
var $card = $paneSandarbha.find('[data-gra-id="'+id+'"]'); | |||
if ($card.length) { | if ($card.length) { | ||
$card.addClass('gra-card-active'); | $card.addClass('gra-card-active'); | ||