Jump to content

User:Njd-de/safeharbor.js

From Meta, a Wikimedia project coordination wiki

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// Backlink: [[:en:User:NguoiDungKhongDinhDanh/CopyvioChecker.js]]

/* This script adds CopyvioCheck tab to all pages, except for Special ones. Vector skin only.
Originally written by NguoiDungKhongDinhDanh.

Installing this script: Try using Enterprisey's ScriptInstaller, or paste the following line into your vector.js or common.js/global.js (not recommended for non-Vector user):
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:NguoiDungKhongDinhDanh/CopyvioChecker.js&action=raw&ctype=text/javascript');

Since I'm not very active and 'scripty', should the gadget have glitches, well, my apologise for being irresponsible. */

mw.loader.using( ['mediawiki.util', 'mediawiki.Uri'], function () {
	"use strict";
	var CvCkTabUrl;

	function setDefault( option, val ) {
		if ( window[option] === undefined ) {
			window[option] = val;
		}
	}
	setDefault( 'CvCkTabName', 'CopyvioCheck' );
	setDefault( 'CvCkTab', true );	
	
	if ( mw.config.get( 'wgNamespaceNumber' ) == -1 ) {
		return;
	}

	if ( window.CvCkTab ) {
		CvCkTabUrl = new mw.Uri( '//copyvios.toolforge.org/' )
			.extend( {
				lang: mw.config.get( 'wgServer' ).replace(/\//g, '').split('.')[0],
				project: mw.config.get( 'wgServer' ).replace(/\//g, '').split('.')[1],
				oldid: (mw.config.get( 'wgRevisionId' )===0) ? (mw.config.get( 'wgCurRevisionId' )) : (mw.config.get( 'wgRevisionId' )),
				action: 'search',
				use_engine: '1',
				use_links: '1',
				turnitin: '1',
			} )
			.toString();

		mw.util.addPortletLink(
			'p-cactions',
			CvCkTabUrl,
			window.CvCkTabName,
			'CopyvioCheck',
			'Submit a query to copyvios.toolforge.org',
			null,
			null
		);
	}
} );

// Backlink: [[User:Bradv/Scripts/ExpandDiffs.js]]
(function( $, mw ) {
    'use strict';
    if (mw.config.get('wgAction')==='history' 
    || mw.config.get('wgCanonicalSpecialPageName')=='Contributions' 
      || mw.config.get('wgCanonicalSpecialPageName')=='Watchlist' 
    || (mw.config.get('wgCanonicalSpecialPageName') || '').startsWith('Recentchanges')) {
        const api = new mw.Api();
        const app = {
            styleSheet: mw.util.addCSS(`
                .diff-addedline, .diff-deletedline, .diff-context {
                    font-size: 0.9em;
                }
                .diff > tr.hidden {
                    display:none;
                }
                .difftoggle {
                    background-image: url(/w/resources/src/mediawiki.icon/images/arrow-expanded.svg?d0685);
                    background-repeat: no-repeat;
                    background-position: left bottom;
                    width: 15px;
                    height: 15px;
                    display: inline-block;
                    cursor: pointer;
                }
                .difftoggle.diffcollapsed {
                    background-image: url(/w/resources/src/mediawiki.icon/images/arrow-collapsed-ltr.svg?40e9a);
                }
                .diff.diffcollapsed {
                    display:none;
                }
                .mw-changeslist-line:hover, li[data-mw-revid]:hover {
                    outline:1px dashed #a2a9b1 !important;
                }
                .diff .diff-addedline a:not(:hover), .diff .diff-deletedline a:not(:hover) {
                    color: inherit;
                }
                .diff a:hover, .diff a:active, .diff a:focus {
                    text-decoration:none;
                }
                
                .mw-rcfilters-ui-highlights {
                display:none;
                }
            `),
            observer: null,
            init: function () {
                app.makelinks();

                mw.loader.using(['mediawiki.util', 'mediawiki.diff.styles']).then(function () {
                    var $link = $(mw.util.addPortletLink('p-views', '', 'Expand diffs', 'ca-expand', '', '', '#ca-history'))
                    .click(function(e) {
                        e.preventDefault();
                        if (!$link.hasClass('selected')) {
                            $link.addClass('selected');
                            $link.find('a').text('Collapse diffs');
                            app.expandAll();
                            app.expanding=true;
                        } else {
                            $link.removeClass('selected');
                            $link.find('a').text('Expand diffs');
                            app.collapseAll();
                            app.expanding=false;
                        }
                    });

                    if ($('.mw-changeslist').length) {
                        app.observer = new MutationObserver(app.makelinks);
                        app.observer.observe($('.mw-changeslist').get(0), {childList: true});
                    } else if ($('.mw-contributions-list').length) {
                        app.observer = new MutationObserver(app.makelinks);
                        app.observer.observe($('.mw-contributions-list').get(0), {childList: true});
                    }
                });
            },
            makelinks: function () {
                console.log('making links');
                $('*[data-mw-revid]').each(function() {
                    if ($(this).find('.difftoggle').length==0) {
                        $('<span>', {'class': 'difftoggle diffcollapsed'})
                            .prependTo($(this))
                            .click(app.toggle);
                    }
                    $(this).click(app.toggle);
                    if (app.expanding) {
                        $(this).click();
                    }
                });
            },
            diffcache: [],
            load: function ($row) {
                console.log($row);
                var deferred = new $.Deferred();
                if ($row.attr('diffloaded')===undefined) {
                    $row.attr('diffloaded', '');
                    $row.find('.difftoggle').removeClass('diffcollapsed');
                    var revid = $row.attr('data-mw-revid');

                    if (app.diffcache[revid]===undefined) {                    
                        api.get({
                            action: 'compare',
                            format: 'json',
                            fromrev: revid,
                            torelative: 'prev',
                            prop: 'diff'
                        }).done(function (response, data) {
                            var diff = data.responseJSON.compare['*'];
                            var $diff = $('<table>', {'class':'diff diff-contentalign-left diff-editfont-monospace'})
                                .append($('<colgroup><col class="diff-marker"/><col class="diff-content"/><col class="diff-marker"/><col class="diff-content"/></colgroup>'))
                                .append(diff)
                                .appendTo($row);
                            $row.find('tr:has(td.diff-context), tr:has(td.diff-lineno)').addClass('hidden');
                            app.linkify($diff);
                            app.diffcache[revid] == $diff.get(0).outerHTML;
                            deferred.resolve($row);
                        });
                    } else {
                        $(app.diffcache[revid]).appendTo($row);
                        deferred.resolve($row);
                    }
                } else {
                    $row.find('.diff, .difftoggle').removeClass('diffcollapsed');
                    deferred.resolve($row);
                }
                return deferred.promise();
            },
            expandAll: function () {
                var counter = 0;

                function loop($row) {
                    if ($row.attr('data-mw-revid')===undefined) {
                        var $next = $row.next();
                        if ($next) {
                            loop($next);
                        }
                    } else {
                        app.load($row)
                        .then(function($row) {
                            var $next = $row.next();
                            counter++;
                            if ($next && counter<50) {
                                loop($next);
                            }
                        });
                    }
                }

                loop($('*[data-mw-revid]').first());
            },
            collapseAll: function () {
                $('.diff, .difftoggle').addClass('diffcollapsed');
            },
            toggle: function (e) {
                var $row;
                if ($(e.target).hasClass('difftoggle')) {
                    $row = $(e.target).parent();
                } else if ($(e.target).attr('data-mw-revid')) {
                    $row = $(e.target);
                } else {
                    return;
                }          
                e.stopPropagation();
                if ($row.attr('diffloaded')===undefined) {
                    app.load($row);
                } else {
                    console.log($row);
                    $row.find('.diff, .difftoggle').toggleClass('diffcollapsed');
                }
            },
            linkify: function ($diff) {
                try {
                    function makelinks(text, regex1, regex2, urlprefix) {
                        var out = text;
                        var arr = text.match(regex1);
                        if (arr) {
                            for (var i=0;i<arr.length;i++) {
                                var s = arr[i];
                                var slink;
                                if (regex2) {
                                    slink = s.match(regex2)[0].replaceAll(' ', '_');
                                } else {
                                    slink = s.replace(' ', '_');
                                }
                                var snew = "<a href='" + (urlprefix ? urlprefix : '') + slink + "'>" + s + "</a>";
                                out = out.replace(s, snew);
                            }
                        }
                        return out;
                    }

                    $.each($diff.find('div'), function () {
                        var html = $(this).html();
                        //console.log(html);

                        try {
                          html = makelinks(html, /https?:\/\/.*?(?=[\s\<\]\|]|&lt;)/gi);
                          html = makelinks(html, /\[\[.*?\]\]/g, /(?<=\[\[).*?(?=\||\]\])/, '/wiki/');
                          html = makelinks(html, /\{\{.*?\}\}/g, /(?<=\{\{).*?(?=\||\}\})/, '/wiki/Template:');
                        } catch (e) {
                          // https://stackoverflow.com/questions/51568821/works-in-chrome-but-breaks-in-safari-invalid-regular-expression-invalid-group/51568859
                        }

                        $(this).html(html);
                    });
                } catch (e) {
                    console.log(e);
                }
            }
        }
        app.init();
    }
}(jQuery, mediaWiki ));