Hides edit entry points (edit tabs, section edit links, "Add topic", and any action=edit/veaction=edit links) from the rendered page across all Wikimedia Foundation wikis. Cosmetic only — doesn't restrict access via direct URL.
// ==UserScript==
// @name WikiNoEdit
// @namespace https://RoyZuo.cc
// @version 1.0-HE12026-08-10
// @description Hides edit entry points (edit tabs, section edit links, "Add topic", and any action=edit/veaction=edit links) from the rendered page across all Wikimedia Foundation wikis. Cosmetic only — doesn't restrict access via direct URL.
// @author Roy Zuo
// @license CC BY-NC-SA 4.0
// @match *://*.wikipedia.org/*
// @match *://*.wiktionary.org/*
// @match *://*.wikibooks.org/*
// @match *://*.wikinews.org/*
// @match *://*.wikiquote.org/*
// @match *://*.wikisource.org/*
// @match *://*.wikiversity.org/*
// @match *://*.wikivoyage.org/*
// @match *://*.wikidata.org/*
// @match *://*.wikimedia.org/*
// @match *://*.wikifunctions.org/*
// @match *://*.mediawiki.org/*
// @run-at document-idle
// @grant none
// ==/UserScript==
( function () {
'use strict';
// --- Step 1: hide known edit UI via CSS (fast, non-destructive, ---
// --- applies to future/AJAX-inserted elements automatically). ---
var css = [
'#ca-edit',
'#ca-ve-edit',
'#ca-editsource',
'#ca-addsection',
'.mw-editsection'
].join( ', ' ) + ' { display: none !important; }';
var style = document.createElement( 'style' );
style.textContent = css;
( document.head || document.documentElement ).appendChild( style );
// --- Step 2: neutralize stray action=edit / veaction=edit / ---
// --- action=formedit links that aren't part of the toolbar above, ---
// --- WITHOUT touching unrelated links such as redlinks. ---
function isRedlinkOrContentLink( el ) {
return el.classList.contains( 'new' ) ||
( el.getAttribute( 'href' ) || '' ).indexOf( 'redlink=1' ) !== -1;
}
function disableStrayEditLinks( root ) {
var scope = root || document;
var editLinks = scope.querySelectorAll(
'a[href*="action=edit"], a[href*="action=formedit"], a[href*="veaction=edit"]'
);
editLinks.forEach( function ( el ) {
// Leave "View source" alone.
if ( el.closest( '#ca-viewsource' ) ) {
return;
}
// Leave redlinks / content links alone entirely.
if ( isRedlinkOrContentLink( el ) ) {
return;
}
// Already hidden via the CSS above (inside one of the known containers)? Skip.
if ( el.closest( '#ca-edit, #ca-ve-edit, #ca-editsource, #ca-addsection, .mw-editsection' ) ) {
return;
}
// Disable in place rather than removing the element.
if ( el.hasAttribute( 'href' ) ) {
el.removeAttribute( 'href' );
el.style.pointerEvents = 'none';
el.setAttribute( 'aria-disabled', 'true' );
}
// If it can't be meaningfully disabled, it's simply left as-is.
} );
}
function run() {
disableStrayEditLinks( document );
}
if ( document.readyState === 'loading' ) {
document.addEventListener( 'DOMContentLoaded', run );
} else {
run();
}
// Re-check only for stray links on content updates (cheap; the CSS
// rule already handles the toolbar/section-edit elements on its own).
if ( window.mw && mw.hook ) {
mw.hook( 'wikipage.content' ).add( function ( $content ) {
disableStrayEditLinks( $content && $content[ 0 ] ? $content[ 0 ] : document );
} );
}
}() );