Add Copyexempt footer attribution control
Fix Copyexempt comment wording in footer script
Line 137: Line 137:
/* Copyexempt: keep the plain Bharatpedia copyright line, with no
/* Copyexempt: keep the plain Bharatpedia copyright line, with no
   imported-article attribution line, on (1) pages that use
   imported-article attribution line, on (1) pages that use
   {{Copyexempt}} or are in Category:Copyexempt, (2) pages named in
   the Copyexempt template or are in its category, (2) pages
  the central list on Bharatpedia:Copyexempt, and (3) articles
  named in the central list on the Copyexempt register page,
  created on or after 2 November 2026, including articles created
  and (3) articles created on or after 2 November 2026, including
   by moving a draft into the main namespace on or after that date. */
   by moving a draft into the main namespace on or after that date. */
( function () {
( function () {

Revision as of 06:34, 2 November 2026

mw.loader.using(['mediawiki.util']).then(function () {
	if (mw.config.get('wgUserGroups').indexOf('autoconfirmed') === -1 &&
		mw.config.get('wgUserGroups').indexOf('confirmed') === -1) {
		return;
	}

	var ITEMS = [
		{ id: 'twinkle-tag', label: 'Tag', icon: 'ri-price-tag-3-line' },
		{ id: 'twinkle-csd', label: 'CSD', icon: 'ri-delete-bin-6-line' },
		{ id: 'twinkle-warn', label: 'Warn', icon: 'ri-alarm-warning-line' },
		{ id: 'twinkle-block', label: 'Block', icon: 'ri-user-unfollow-line' },
		{ id: 'twinkle-protect', label: 'Protect', icon: 'ri-shield-line' },
		{ id: 'twinkle-unlink', label: 'Unlink', icon: 'ri-link-unlink' },
		{ id: 'twinkle-xfd', label: 'XfD', icon: 'ri-chat-delete-line' },
		{ id: 'twinkle-lastdiff', label: 'Last diff', icon: 'ri-git-branch-line' }
	];

	function ready() {
		if (document.getElementById('bpneo-tw-wrap')) {
			return true;
		}
		if (typeof Twinkle !== 'object') {
			return false;
		}
		var bar = document.querySelector('.bpneo-title-actions');
		if (!bar) {
			return false;
		}

		var wrap = document.createElement('div');
		wrap.id = 'bpneo-tw-wrap';
		wrap.className = 'bpneo-action-wrap';
		wrap.style.position = 'relative';

		var btn = document.createElement('button');
		btn.type = 'button';
		btn.className = 'bpneo-title-btn';
		btn.title = 'Twinkle';
		btn.innerHTML = '<i class="ri-sparkling-2-line"></i>';

		var menu = document.createElement('div');
		menu.id = 'bpneo-tw-menu';
		menu.className = 'bpneo-action-menu';
		menu.style.display = 'none';

		var added = 0;
		ITEMS.forEach(function (item) {
			var src = document.getElementById(item.id);
			if (!src) {
				return;
			}
			var a = document.createElement('a');
			a.href = '#';
			a.innerHTML = '<i class="' + item.icon + '"></i> ' + item.label;
			a.addEventListener('click', function (e) {
				e.preventDefault();
				menu.style.display = 'none';
				src.click();
			});
			menu.appendChild(a);
			added++;
		});
		if (!added) {
			return false;
		}

		btn.addEventListener('click', function (e) {
			e.preventDefault();
			e.stopPropagation();
			menu.style.display = menu.style.display === 'none' ? 'block' : 'none';
		});
		document.addEventListener('click', function (e) {
			if (!wrap.contains(e.target)) {
				menu.style.display = 'none';
			}
		});

		wrap.appendChild(btn);
		wrap.appendChild(menu);
		bar.appendChild(wrap);
		return true;
	}

	var n = 0;
	var t = setInterval(function () {
		n++;
		if (ready()) {
			clearInterval(t);
		}
		if (n > 60) {
			clearInterval(t);
		}
	}, 250);
});


/* Mobile view switch: BharatpediaNeo does not render the
   MobileFrontend footer toggle, so add a Mobile view link.
   Articles: under the footer's Follow Us section. The main
   page's remix footer: in the links row, after Contact. */
$( function () {
	if ( document.getElementById( 'bpneo-mobile-view-link' ) ) {
		return;
	}
	var a = document.createElement( 'a' );
	a.id = 'bpneo-mobile-view-link';
	a.textContent = 'Mobile view';
	a.href = '/w/index.php?title=' +
		encodeURIComponent( mw.config.get( 'wgPageName' ) ) +
		'&mobileaction=toggle_view_mobile';
	var social = document.querySelector( '.bp-footer-social' );
	if ( social && social.parentNode ) {
		var box = document.createElement( 'div' );
		box.style.marginTop = '1em';
		box.appendChild( a );
		social.parentNode.appendChild( box );
		return;
	}
	var links = document.querySelector( '.bpneo-remix-footer-links' );
	if ( links ) {
		a.style.marginLeft = '1em';
		links.appendChild( a );
		return;
	}
	var footer = document.querySelector( 'footer' );
	if ( !footer ) {
		return;
	}
	var wrap = document.createElement( 'div' );
	wrap.style.textAlign = 'center';
	wrap.style.width = '100%';
	wrap.style.marginTop = '0.5em';
	wrap.appendChild( a );
	footer.appendChild( wrap );
} );

/* Copyexempt: keep the plain Bharatpedia copyright line, with no
   imported-article attribution line, on (1) pages that use
   the Copyexempt template or are in its category, (2) pages
   named in the central list on the Copyexempt register page,
   and (3) articles created on or after 2 November 2026, including
   by moving a draft into the main namespace on or after that date. */
( function () {
	if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ||
		mw.config.get( 'wgAction' ) !== 'view' ) {
		return;
	}
	var CUTOFF = '2026-11-01T18:30:00Z';
	var done = false;

	function clean() {
		var slot = document.querySelector( '.bp-import-attrib' );
		if ( slot && slot.textContent ) {
			slot.textContent = '';
		}
		var fb = document.querySelector( '.bp-footer-bottom' );
		if ( !fb || fb.textContent.indexOf( 'may use material' ) === -1 ) {
			return;
		}
		var deleting = false;
		Array.prototype.slice.call( fb.childNodes ).forEach( function ( n ) {
			if ( n.nodeType === 1 && n.classList &&
				n.classList.contains( 'bp-import-attrib' ) ) {
				n.textContent = '';
				return;
			}
			if ( !deleting && n.nodeType === 3 &&
				n.textContent.indexOf( 'This article may use material' ) !== -1 ) {
				var i = n.textContent.indexOf( 'This article may use material' );
				n.textContent = n.textContent.slice( 0, i );
				deleting = true;
				return;
			}
			if ( deleting ) {
				if ( n.nodeType === 3 && n.textContent.indexOf( ').' ) !== -1 ) {
					n.textContent = n.textContent.slice( n.textContent.indexOf( ').' ) + 2 );
					deleting = false;
				} else if ( n.nodeType === 3 ) {
					n.textContent = '';
				} else if ( n.nodeType === 1 ) {
					n.remove();
				}
			}
		} );
	}

	function suppress() {
		if ( done ) {
			clean();
			return;
		}
		done = true;
		if ( !document.getElementById( 'bp-copyexempt-style' ) ) {
			var st = document.createElement( 'style' );
			st.id = 'bp-copyexempt-style';
			st.textContent = '.bp-import-attrib{display:none!important}';
			document.head.appendChild( st );
		}
		clean();
		var slot = document.querySelector( '.bp-import-attrib' );
		if ( slot && window.MutationObserver ) {
			var ob = new MutationObserver( function () { clean(); } );
			ob.observe( slot, { childList: true, subtree: true } );
			setTimeout( function () { ob.disconnect(); }, 20000 );
		}
		var fb = document.querySelector( '.bp-footer-bottom' );
		if ( fb && window.MutationObserver ) {
			var ob2 = new MutationObserver( function () { clean(); } );
			ob2.observe( fb, { childList: true, subtree: true } );
			setTimeout( function () { ob2.disconnect(); }, 20000 );
		}
	}

	var cats = mw.config.get( 'wgCategories' ) || [];
	if ( cats.indexOf( 'Copyexempt' ) !== -1 ) {
		suppress();
		return;
	}
	$( function () {
		if ( document.querySelector( '.bp-copyexempt-marker' ) ) {
			suppress();
		}
	} );

	function norm( s ) {
		s = String( s || '' ).replace( /_/g, ' ' ).trim();
		return s ? s.charAt( 0 ).toUpperCase() + s.slice( 1 ) : s;
	}
	var current = norm( mw.config.get( 'wgPageName' ) );
	mw.loader.using( [ 'mediawiki.api' ] ).then( function () {
	var api = new mw.Api();

	api.get( {
		action: 'query',
		prop: 'revisions',
		titles: mw.config.get( 'wgPageName' ),
		rvlimit: 1,
		rvdir: 'newer',
		rvprop: 'timestamp',
		formatversion: 2
	} ).then( function ( data ) {
		try {
			var rev = data.query.pages[ 0 ].revisions[ 0 ];
			if ( rev && rev.timestamp >= CUTOFF ) {
				suppress();
			}
		} catch ( e ) {}
	} ).catch( function () {} );

	api.get( {
		action: 'query',
		prop: 'revisions',
		titles: 'Bharatpedia:Copyexempt',
		rvprop: 'content',
		rvslots: 'main',
		formatversion: 2
	} ).then( function ( data ) {
		try {
			var text = data.query.pages[ 0 ].revisions[ 0 ].slots.main.content;
			var start = text.indexOf( 'COPYEXEMPT-LIST-START' );
			var end = text.indexOf( 'COPYEXEMPT-LIST-END' );
			if ( start === -1 || end === -1 || end <= start ) {
				return;
			}
			var part = text.slice( start, end );
			var m;
			var re = /\[\[([^\]|#]+)/g;
			while ( ( m = re.exec( part ) ) !== null ) {
				if ( norm( m[ 1 ] ) === current ) {
					suppress();
					return;
				}
			}
		} catch ( e ) {}
	} ).catch( function () {} );
	} );
}() );