User:Njd-de/safeharbor.js
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\<\]\|]|<)/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 ));