|
|
| Line 1: |
Line 1: |
| /* Global handlers for verse UI */ | | /* ========================= |
| | COMMENTARY TOGGLE |
| | ========================= */ |
| | $(document).on('click', '.verse-action-commentary', function (e) { |
| | e.preventDefault(); |
| | e.stopPropagation(); |
|
| |
|
| mw.hook('wikipage.content').add(function ($content) {
| | var $btn = $(this); |
| | var verseId = $btn.data('verse'); |
| | if (!verseId) return; |
|
| |
|
| /* ========================= | | var $bodies = $('.commentary-body[data-verse="' + verseId + '"]'); |
| COMMENTARY TOGGLE
| |
| ========================= */
| |
| $content.off('click', '.verse-action-commentary').on('click', '.verse-action-commentary', function (e) {
| |
| e.preventDefault();
| |
|
| |
|
| var verseId = $(this).data('verse');
| | var isOpen = !$bodies.first().hasClass('open'); |
| if (!verseId) return;
| |
|
| |
|
| var $bodies = $('.commentary-body[data-verse="' + verseId + '"]');
| | // toggle commentary |
| | $bodies.toggleClass('open', isOpen); |
|
| |
|
| $bodies.toggleClass('commentary-hidden');
| | // highlight icon |
| | $btn.toggleClass('active', isOpen); |
| | }); |
|
| |
|
| // Optional active state
| |
| $(this).toggleClass('active');
| |
| });
| |
|
| |
|
| | /* ========================= |
| | COPY VERSE |
| | ========================= */ |
| | $(document).on('click', '.verse-action-copy', function (e) { |
| | e.preventDefault(); |
| | e.stopPropagation(); |
|
| |
|
| /* ========================= | | var $btn = $(this); |
| COPY VERSE (ICON BUTTON)
| | var line1 = $btn.data('line1') || ''; |
| ========================= */ | | var line2 = $btn.data('line2') || ''; |
| $content.off('click', '.verse-action-copy').on('click', '.verse-action-copy', function (e) {
| | var text = line2 ? line1 + '\n' + line2 : line1; |
| e.preventDefault();
| |
|
| |
|
| var $btn = $(this);
| | if (!text) return; |
| var line1 = $btn.data('line1') || '';
| |
| var line2 = $btn.data('line2') || '';
| |
| var text = line2 ? line1 + '\n' + line2 : line1;
| |
|
| |
|
| if (!text) return;
| | function feedback() { |
| | | $btn.addClass('copied'); |
| function showFeedback() {
| | setTimeout(function () { |
| $btn.addClass('copied');
| | $btn.removeClass('copied'); |
| | | }, 1500); |
| setTimeout(function () {
| | } |
| $btn.removeClass('copied');
| |
| }, 1500);
| |
| }
| |
| | |
| // Clipboard API
| |
| if (navigator.clipboard && window.isSecureContext) {
| |
| navigator.clipboard.writeText(text).then(showFeedback);
| |
| } else {
| |
| // fallback
| |
| var $temp = $('<textarea>').val(text).appendTo('body');
| |
| $temp[0].select();
| |
| document.execCommand('copy');
| |
| $temp.remove();
| |
| showFeedback();
| |
| }
| |
| });
| |
| | |
| | |
| /* =========================
| |
| COPY ID BUTTON (if used)
| |
| ========================= */ | |
| $content.off('click', '.copy-id-btn').on('click', '.copy-id-btn', function () {
| |
| var $btn = $(this); | |
| var id = $btn.data('copyid');
| |
| if (!id) return;
| |
| | |
| function showFeedback() {
| |
| $btn.addClass('copied').text('✓');
| |
| setTimeout(function () {
| |
| $btn.removeClass('copied').text('⧉');
| |
| }, 1800);
| |
| } | |
| | |
| if (navigator.clipboard && window.isSecureContext) {
| |
| navigator.clipboard.writeText(id).then(showFeedback);
| |
| } else {
| |
| var temp = $('<textarea>').val(id).appendTo('body');
| |
| temp[0].select();
| |
| document.execCommand('copy');
| |
| temp.remove();
| |
| showFeedback();
| |
| }
| |
| });
| |
| | |
| | |
| /* =========================
| |
| MENU (3 DOTS) SYSTEM
| |
| ========================= */
| |
| | |
| // Open/close menu
| |
| $content.off('click', '.verse-dots').on('click', '.verse-dots', function (e) {
| |
| e.stopPropagation();
| |
| | |
| var $menu = $(this).next('.verse-menu');
| |
| var isOpen = $menu.hasClass('open');
| |
| | |
| $('.verse-menu.open').removeClass('open');
| |
| $('.verse-dots.open').removeClass('open');
| |
| | |
| if (!isOpen) {
| |
| $menu.addClass('open');
| |
| $(this).addClass('open');
| |
| }
| |
| });
| |
| | |
| // Close on outside click
| |
| $(document).off('click.verseMenu').on('click.verseMenu', function () {
| |
| $('.verse-menu.open').removeClass('open');
| |
| $('.verse-dots.open').removeClass('open');
| |
| });
| |
| | |
| // Menu → Commentary
| |
| $content.off('click', '.verse-menu-commentary').on('click', '.verse-menu-commentary', function () {
| |
| var verseId = $(this).data('verse');
| |
| | |
| $('.commentary-body[data-verse="' + verseId + '"]').toggleClass('commentary-hidden');
| |
| | |
| $('.verse-menu.open').removeClass('open');
| |
| $('.verse-dots.open').removeClass('open');
| |
| });
| |
| | |
| // Menu → Copy
| |
| $content.off('click', '.verse-menu-copy').on('click', '.verse-menu-copy', function () {
| |
| var $dots = $(this).closest('.verse-menu').prev('.verse-dots');
| |
| | |
| var line1 = $dots.data('line1') || '';
| |
| var line2 = $dots.data('line2') || '';
| |
| var text = line2 ? line1 + '\n' + line2 : line1;
| |
| | |
| var $item = $(this);
| |
| | |
| function showFeedback() {
| |
| $item.html('<span class="verse-menu-icon">✓</span> Copied!');
| |
| setTimeout(function () {
| |
| $item.html('<span class="verse-menu-icon">⧉</span> Copy verse');
| |
| $('.verse-menu.open').removeClass('open');
| |
| $('.verse-dots.open').removeClass('open');
| |
| }, 1500);
| |
| }
| |
| | |
| if (navigator.clipboard && window.isSecureContext) {
| |
| navigator.clipboard.writeText(text).then(showFeedback);
| |
| } else {
| |
| var $t = $('<textarea>').val(text).appendTo('body');
| |
| $t[0].select();
| |
| document.execCommand('copy');
| |
| $t.remove();
| |
| showFeedback();
| |
| }
| |
| }); | |
| | |
| // Menu → Download
| |
| $content.off('click', '.verse-menu-download').on('click', '.verse-menu-download', function () {
| |
| var $dots = $(this).closest('.verse-menu').prev('.verse-dots');
| |
| | |
| var id = $dots.data('verse') || 'verse';
| |
| var line1 = $dots.data('line1') || '';
| |
| var line2 = $dots.data('line2') || '';
| |
| var text = line2 ? line1 + '\n' + line2 : line1;
| |
| | |
| var blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
| |
| var url = URL.createObjectURL(blob);
| |
| | |
| var $a = $('<a>').attr({ href: url, download: id + '.txt' }).appendTo('body');
| |
| $a[0].click();
| |
| $a.remove();
| |
| | |
| URL.revokeObjectURL(url);
| |
| | |
| $('.verse-menu.open').removeClass('open');
| |
| $('.verse-dots.open').removeClass('open');
| |
| });
| |
|
| |
|
| | if (navigator.clipboard && window.isSecureContext) { |
| | navigator.clipboard.writeText(text).then(feedback); |
| | } else { |
| | var $temp = $('<textarea>').val(text).appendTo('body'); |
| | $temp[0].select(); |
| | document.execCommand('copy'); |
| | $temp.remove(); |
| | feedback(); |
| | } |
| }); | | }); |