Jump to content

User:Polygnotus/Scripts/Fragment.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <nowiki>
// Add "Link to selected text" to Tools menu
$(function() {
    mw.util.addPortletLink(
        'p-tb',
        '#',
        'Link to selected text',
        't-linktotext',
        'Create a URL fragment linking to the selected text'
    );
    
    $('#t-linktotext').on('click', function(e) {
        e.preventDefault();
        
        var selection = window.getSelection();
        
        if (!selection || selection.rangeCount === 0 || selection.toString().trim() === '') {
            mw.notify('No text selected', { type: 'error' });
            return;
        }
        
        var range = selection.getRangeAt(0);
        
        // Get the selected text
        var selectedText = selection.toString().replace(/\s+/g, ' ').trim();
        
        // Get text before selection for prefix
        var beforeRange = range.cloneRange();
        beforeRange.collapse(true);
        beforeRange.setStart(beforeRange.startContainer.parentElement || beforeRange.startContainer, 0);
        var beforeText = beforeRange.toString().replace(/\s+/g, ' ').trim();
        
        // Get text after selection for suffix
        var afterRange = range.cloneRange();
        afterRange.collapse(false);
        var endContainer = range.endContainer;
        var endParent = endContainer.parentElement || endContainer;
        afterRange.setEndAfter(endParent);
        var afterText = afterRange.toString().replace(/\s+/g, ' ').trim();
        
        // Extract prefix (last few words before selection)
        var beforeWords = beforeText.split(' ').filter(w => w.length > 0);
        var prefix = beforeWords.slice(-3).join(' ');
        
        // Extract suffix (first few words after selection)
        var afterWords = afterText.split(' ').filter(w => w.length > 0);
        var suffix = afterWords.slice(0, 3).join(' ');
        
        // Build text fragment
        var words = selectedText.split(' ').filter(w => w.length > 0);
        var textFragment = '';
        
        if (prefix) {
            textFragment += encodeURIComponent(prefix) + '-,';
        }
        
        if (words.length > 5) {
            var textStart = words.slice(0, 3).join(' ');
            var textEnd = words.slice(-3).join(' ');
            textFragment += encodeURIComponent(textStart) + ',' + encodeURIComponent(textEnd);
        } else {
            textFragment += encodeURIComponent(selectedText);
        }
        
        if (suffix) {
            textFragment += ',-' + encodeURIComponent(suffix);
        }
        
        // Store fragment and reload with a flag
        sessionStorage.setItem('pendingTextFragment', textFragment);
        var reloadUrl = window.location.origin + window.location.pathname + 
                       window.location.search + (window.location.search ? '&' : '?') + '_clearhighlight=1';
        window.location.href = reloadUrl;
    });
    
    // On page load, check if we're coming back from a reload
    var urlParams = new URLSearchParams(window.location.search);
    if (urlParams.has('_clearhighlight')) {
        var textFragment = sessionStorage.getItem('pendingTextFragment');
        if (textFragment) {
            sessionStorage.removeItem('pendingTextFragment');
            // Remove the flag from URL and add text fragment
            urlParams.delete('_clearhighlight');
            var cleanSearch = urlParams.toString();
            var newUrl = window.location.origin + window.location.pathname + 
                        (cleanSearch ? '?' + cleanSearch : '') + '#:~:text=' + textFragment;
            window.location.replace(newUrl);
        }
    }
});
// </nowiki>