میڈیاویکی:Common.js
یاد دہانی: محفوظ کرنے کے بعد ان تبدیلیوں کو دیکھنے کے لیے آپ کو اپنے براؤزر کا کیش (cache) صاف کرنا ہوگا۔
- فائرفاکس/ سفاری: جب Reload پر کلک کریں تو Shift دباکر رکھیں، یا Ctrl-F5 یا Ctrl-R دبائیں (Mac پر R-⌘)
- گوگل کروم: Ctrl-Shift-R دبائیں (Mac پر Shift-R-⌘)
- انٹرنیٹ ایکسپلورر: جب Refresh پر کلک کریں تو Ctrl یا Ctrl-F5 دبائیں
- اوپیرا: Tools → Preferences میں جائیں اور کیش (cache) صاف کریں
// Refresh an outdated Approved Revs page restored from browser history.
( function () {
'use strict';
window.addEventListener( 'pageshow', function ( event ) {
if (
event.persisted &&
document.getElementById( 'approvedrevs-approve-latest-notice' )
) {
window.location.reload();
}
} );
}() );
// Open rendered content links and category links in a new tab, without changing page controls.
( function () {
'use strict';
function applyArticleLinkTargets( $content ) {
$content.find( '.mw-parser-output a, #catlinks a' ).each( function () {
var $link = $( this );
if ( $link.closest( '.toc, .mw-editsection, .reference, .mw-references-wrap' ).length ) {
return;
}
$link.attr( {
target: '_blank',
rel: 'noopener noreferrer'
} );
} );
}
$( function () {
applyArticleLinkTargets( $( document ) );
} );
mw.hook( 'wikipage.content' ).add( applyArticleLinkTargets );
}() );
// Search direct page members of Category:کتب from the decorated category page.
( function () {
'use strict';
function normaliseSearchText( value ) {
return ( value || '' ).replace( /\s+/g, ' ' ).trim().toLowerCase();
}
function renderResults( root, results, query ) {
var list = root.querySelector( '#nk-book-category-search-results' );
var status = root.querySelector( '#nk-book-category-search-status' );
list.textContent = '';
if ( !query ) {
status.textContent = 'کتاب کے عنوان کا کوئی لفظ لکھیں۔';
return;
}
if ( !results.length ) {
status.textContent = 'اس لفظ سے کوئی کتاب نہیں ملی۔';
return;
}
status.textContent = results.length + ' عنوان ملے';
results.slice( 0, 60 ).forEach( function ( title ) {
var item = document.createElement( 'li' );
var link = document.createElement( 'a' );
link.href = mw.util.getUrl( title );
link.textContent = title;
item.appendChild( link );
list.appendChild( item );
} );
if ( results.length > 60 ) {
var more = document.createElement( 'li' );
more.textContent = 'مزید نتائج کے لیے تلاش کو مخصوص کریں۔';
list.appendChild( more );
}
}
function loadBookTitles( api, cmcontinue, collected ) {
var params = {
action: 'query',
list: 'categorymembers',
cmtitle: 'Category:کتب',
cmtype: 'page',
cmprop: 'title',
cmlimit: 'max',
formatversion: 2
};
if ( cmcontinue ) {
params.cmcontinue = cmcontinue;
}
return nkHomepageApiGet( api, params ).then( function ( data ) {
var members = data.query && data.query.categorymembers ?
data.query.categorymembers : [];
members.forEach( function ( member ) {
collected.push( member.title );
} );
if ( data.continue && data.continue.cmcontinue ) {
return loadBookTitles( api, data.continue.cmcontinue, collected );
}
return collected.sort( function ( a, b ) {
return a.localeCompare( b, 'ur' );
} );
} );
}
$( function () {
var root = document.getElementById( 'nk-book-category-search' );
if ( !root ) {
return;
}
mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).then( function () {
var api = new mw.Api();
var controls = root.querySelector( '#nk-book-category-search-controls' );
var input = document.createElement( 'input' );
var button = document.createElement( 'button' );
var status = root.querySelector( '#nk-book-category-search-status' );
var titlesPromise = null;
var debounceTimer = null;
input.id = 'nk-book-category-search-input';
input.type = 'search';
input.placeholder = 'کتاب کے عنوان کا کوئی لفظ لکھیں';
input.setAttribute( 'aria-label', 'کتاب تلاش کریں' );
button.id = 'nk-book-category-search-button';
button.type = 'button';
button.textContent = 'تلاش';
if ( controls ) {
controls.textContent = '';
controls.appendChild( input );
controls.appendChild( button );
}
function search() {
var query = normaliseSearchText( input.value );
if ( !titlesPromise ) {
status.textContent = 'کتابوں کی فہرست لوڈ ہو رہی ہے۔';
titlesPromise = loadBookTitles( api, null, [] );
}
titlesPromise.then( function ( titles ) {
var results = query ? titles.filter( function ( title ) {
return normaliseSearchText( title ).indexOf( query ) !== -1;
} ) : [];
renderResults( root, results, query );
}, function () {
status.textContent = 'فہرست لوڈ نہیں ہو سکی۔';
} );
}
input.addEventListener( 'input', function () {
clearTimeout( debounceTimer );
debounceTimer = setTimeout( search, 180 );
} );
button.addEventListener( 'click', search );
} );
} );
}() );
// Automatically list Category:کتب subcategories that are not yet placed in custom category panels.
// Revision marker: refresh ResourceLoader after adding the automatic new-categories panel.
( function () {
'use strict';
function cleanCategoryName( value ) {
return ( value || '' )
.replace( /^زمرہ\s*:/, '' )
.replace( /^Category\s*:/i, '' )
.replace( /_/g, ' ' )
.replace( /\s+/g, ' ' )
.trim();
}
function categoryNameFromLink( link ) {
var titleAttr = link.getAttribute( 'title' ) || '';
var title = cleanCategoryName( titleAttr );
if ( /^(زمرہ|Category)\s*:/i.test( titleAttr ) && title ) {
return title;
}
try {
var url = new URL( link.href, location.href );
var path = decodeURIComponent( url.pathname || '' );
var queryTitle = url.searchParams.get( 'title' );
if ( queryTitle && /^(زمرہ|Category)\s*:/i.test( queryTitle ) ) {
return cleanCategoryName( queryTitle );
}
var marker = '/زمرہ:';
var markerIndex = path.indexOf( marker );
if ( markerIndex !== -1 ) {
return cleanCategoryName( path.slice( markerIndex + marker.length ) );
}
} catch ( e ) {}
return '';
}
function collectClassifiedCategories( root ) {
var classified = Object.create( null );
var panels = root.querySelectorAll( '.nk-home-panel' );
Array.prototype.forEach.call( panels, function ( panel ) {
if ( panel.id === 'nk-book-category-new-categories' ) {
return;
}
Array.prototype.forEach.call( panel.querySelectorAll( 'a[href]' ), function ( link ) {
var category = categoryNameFromLink( link );
if ( category ) {
classified[category] = true;
}
} );
} );
return classified;
}
function ensureOtherCategoriesPanel( root ) {
var existing = document.getElementById( 'nk-book-category-new-categories' );
if ( existing ) {
return existing;
}
var columns = root.querySelector( '.nk-home-columns-bottom' ) || root;
var panel = document.createElement( 'div' );
var headingWrapper = document.createElement( 'div' );
var heading = document.createElement( 'h2' );
var body = document.createElement( 'div' );
var list = document.createElement( 'ul' );
panel.id = 'nk-book-category-new-categories';
panel.className = 'nk-home-panel nk-home-panel-dyk';
headingWrapper.className = 'mw-heading mw-heading2';
heading.textContent = 'نئے زمرہ جات';
body.className = 'nk-home-panel-body';
list.id = 'nk-book-category-new-categories-list';
headingWrapper.appendChild( heading );
body.appendChild( list );
panel.appendChild( headingWrapper );
panel.appendChild( body );
columns.appendChild( panel );
return panel;
}
function renderOtherCategories( root, categories ) {
var existing = document.getElementById( 'nk-book-category-new-categories' );
if ( !categories.length ) {
if ( existing && existing.parentNode ) {
existing.parentNode.removeChild( existing );
}
return;
}
var panel = ensureOtherCategoriesPanel( root );
var list = panel.querySelector( '#nk-book-category-new-categories-list' );
list.textContent = '';
categories.forEach( function ( category ) {
var item = document.createElement( 'li' );
var link = document.createElement( 'a' );
link.href = mw.util.getUrl( 'زمرہ:' + category );
link.textContent = category;
item.appendChild( link );
list.appendChild( item );
} );
}
function loadBookSubcategories( api, cmcontinue, collected ) {
var params = {
action: 'query',
list: 'categorymembers',
cmtitle: 'Category:کتب',
cmtype: 'subcat',
cmprop: 'title',
cmlimit: 'max',
formatversion: 2
};
if ( cmcontinue ) {
params.cmcontinue = cmcontinue;
}
return nkHomepageApiGet( api, params ).then( function ( data ) {
var members = data.query && data.query.categorymembers ?
data.query.categorymembers : [];
members.forEach( function ( member ) {
collected.push( cleanCategoryName( member.title ) );
} );
if ( data.continue && data.continue.cmcontinue ) {
return loadBookSubcategories( api, data.continue.cmcontinue, collected );
}
return collected.sort( function ( a, b ) {
return a.localeCompare( b, 'ur' );
} );
} );
}
$( function () {
var root = document.querySelector( '.nk-home' );
if (
!root ||
(
mw.config.get( 'wgPageName' ) !== 'زمرہ:کتب' &&
!root.querySelector( '#nk-book-category-search' ) &&
!root.querySelector( '#nk-book-category-new-categories' )
)
) {
return;
}
mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).then( function () {
var api = new mw.Api();
return loadBookSubcategories( api, null, [] ).then( function ( subcategories ) {
var classified = collectClassifiedCategories( root );
var others = subcategories.filter( function ( category ) {
return category && !classified[category];
} );
renderOtherCategories( root, others );
} );
} );
} );
}() );
var nkHomepageApiActive = 0;
var nkHomepageApiPending = [];
var nkHomepageApiConcurrency = 3;
function nkHomepageApiRunNext() {
if (
nkHomepageApiActive >= nkHomepageApiConcurrency ||
!nkHomepageApiPending.length
) {
return;
}
var job = nkHomepageApiPending.shift();
nkHomepageApiActive++;
function complete() {
nkHomepageApiActive--;
nkHomepageApiRunNext();
}
job.run().then( function ( data ) {
job.resolve( data );
complete();
}, function ( error ) {
job.reject( error );
complete();
} );
}
function nkHomepageApiGet( api, params ) {
function request( attempt ) {
return api.get( params ).catch( function ( error ) {
if ( attempt >= 2 ) {
return Promise.reject( error );
}
return new Promise( function ( resolve ) {
setTimeout( resolve, 250 * ( attempt + 1 ) );
} ).then( function () {
return request( attempt + 1 );
} );
} );
}
return new Promise( function ( resolve, reject ) {
nkHomepageApiPending.push( {
run: function () {
return request( 0 );
},
resolve: resolve,
reject: reject
} );
nkHomepageApiRunNext();
} );
}
function nkLoadApprovedPage( api, title ) {
return nkHomepageApiGet( api, {
action: 'nkapprovedrevision',
title: title
} ).then( function ( data ) {
var approvedPage = data.nkapprovedrevision;
if ( !approvedPage || !approvedPage.revid ) {
return Promise.reject( new Error( 'Page has no approved revision: ' + title ) );
}
return nkHomepageApiGet( api, {
action: 'parse',
oldid: approvedPage.revid,
prop: 'text',
disableeditsection: true,
disabletoc: true,
formatversion: 2
} ).then( function ( parsed ) {
return {
page: approvedPage,
html: parsed.parse.text
};
} );
} );
}
function nkApprovedThumbnailFromHtml( html, defaultSize ) {
var parsed = new DOMParser().parseFromString( html, 'text/html' );
var parserOutput = parsed.querySelector( '.mw-parser-output' );
var image = parserOutput && parserOutput.querySelector( 'img' );
if ( !image ) {
return null;
}
var source = image.getAttribute( 'src' );
if ( !source ) {
return null;
}
return {
source: new URL( source, mw.config.get( 'wgServer' ) ).href,
width: Number( image.getAttribute( 'width' ) ) || defaultSize,
height: Number( image.getAttribute( 'height' ) ) || defaultSize
};
}
// Six most recently edited or created article pages.
( function () {
'use strict';
if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
return;
}
// Urdu display names for non-human editor accounts.
var nkEditorDisplayNames = {
'Maintenance script': 'سکرپٹ'
};
function renderRecentChanges( container, changes, admins ) {
container.replaceChildren();
var table = document.createElement( 'table' );
var body = document.createElement( 'tbody' );
table.className = 'nk-home-recent-table';
table.appendChild( body );
changes.forEach( function ( change ) {
var row = document.createElement( 'tr' );
var cell = document.createElement( 'td' );
var titleLink = document.createElement( 'a' );
var editor = document.createElement( 'div' );
var editorLink = document.createElement( 'a' );
var editorLabel =
admins[ change.user ] || /^ADMIN(?:\s|$)/i.test( change.user )
? 'مدیر: '
: 'معاون: ';
titleLink.href = mw.util.getUrl( change.title );
titleLink.textContent = change.title;
editorLink.href = mw.util.getUrl( 'User:' + change.user );
editorLink.textContent =
nkEditorDisplayNames[ change.user ] || change.user;
editor.appendChild( document.createTextNode( editorLabel ) );
editor.appendChild( editorLink );
cell.appendChild( titleLink );
cell.appendChild( editor );
row.appendChild( cell );
body.appendChild( row );
} );
container.appendChild( table );
}
function isMaintenanceRevision( revision ) {
var comment = revision.comment || '';
return comment ===
'تمام موجود تاریخوں اور سالوں کے صفحات کے روابط شامل کیے' ||
comment === 'تاریخ اور سال کے روابط درست کیے' ||
comment === 'تاریخ اور سال کے صفحے کا ربط شامل کیا';
}
function loadRecentChanges( api, continuation, state ) {
var params = {
action: 'query',
list: 'allrevisions',
arvnamespace: 0,
arvprop: 'ids|flags|title|timestamp|user|comment',
arvdir: 'older',
arvlimit: 'max',
formatversion: 2
};
if ( continuation ) {
params.arvcontinue = continuation;
}
return nkHomepageApiGet( api, params ).then( function ( data ) {
data.query.allrevisions.some( function ( page ) {
if ( state.resolved[ page.title ] ) {
return false;
}
if (
page.title === 'صفحۂ اول' ||
/[\u0400-\u052f]/.test( page.title )
) {
state.resolved[ page.title ] = true;
return false;
}
var revisions = page.revisions || [];
for ( var index = 0; index < revisions.length; index++ ) {
var revision = revisions[ index ];
if ( isMaintenanceRevision( revision ) ) {
continue;
}
var editor = revision.user;
state.resolved[ page.title ] = true;
if (
( revision.anon && !/[.:]/.test( editor ) ) ||
( state.editorCounts[ editor ] || 0 ) >= 2
) {
return false;
}
state.editorCounts[ editor ] =
( state.editorCounts[ editor ] || 0 ) + 1;
state.changes.push( {
title: page.title,
user: editor
} );
return state.changes.length === 6;
}
return false;
} );
if (
state.changes.length === 6 ||
!data.continue ||
!data.continue.arvcontinue
) {
return state.changes;
}
return loadRecentChanges(
api, data.continue.arvcontinue, state
);
} );
}
mw.loader.using( 'mediawiki.api' ).then( function () {
var container = document.getElementById( 'nk-home-recent-changes' );
if ( !container ) {
return;
}
var api = new mw.Api();
return nkHomepageApiGet( api, {
action: 'query',
list: 'allusers',
augroup: 'sysop',
auprop: 'groups',
aulimit: 'max',
formatversion: 2
} ).then( function ( result ) {
var admins = {};
result.query.allusers.forEach( function ( user ) {
admins[ user.name ] = true;
} );
return loadRecentChanges( api, null, {
changes: [],
resolved: {},
editorCounts: {}
} ).then( function ( changes ) {
if (
changes.length > 1 &&
( admins[ changes[ 0 ].user ] ||
/^ADMIN(?:\s|$)/i.test( changes[ 0 ].user ) )
) {
var firstNonAdmin = changes.findIndex( function ( change ) {
return !admins[ change.user ] &&
!/^ADMIN(?:\s|$)/i.test( change.user );
} );
if ( firstNonAdmin > 0 ) {
var firstChange = changes[ 0 ];
changes[ 0 ] = changes[ firstNonAdmin ];
changes[ firstNonAdmin ] = firstChange;
}
}
renderRecentChanges( container, changes, admins );
} );
} );
} ).catch( function ( error ) {
mw.log.error( 'Could not load recent homepage changes:', error );
} );
}() );
// Daily featured article and Naat Khawan on the main page.
( function () {
'use strict';
if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
return;
}
var dateValues = {};
new Intl.DateTimeFormat( 'en-US', {
timeZone: 'Asia/Karachi',
year: 'numeric',
month: 'numeric',
day: 'numeric'
} ).formatToParts( new Date() ).forEach( function ( part ) {
dateValues[ part.type ] = part.value;
} );
var dailyDay = Math.floor( Date.UTC(
Number( dateValues.year ),
Number( dateValues.month ) - 1,
Number( dateValues.day )
) / 86400000 );
function dailyIndex( key, length ) {
var hash = 2166136261;
for ( var index = 0; index < key.length; index++ ) {
hash ^= key.charCodeAt( index );
hash = Math.imul( hash, 16777619 );
}
return ( ( hash >>> 0 ) + dailyDay ) % length;
}
function preferredParagraphFromHtml( html ) {
var parsed = new DOMParser().parseFromString( html, 'text/html' );
var paragraphs = Array.prototype.slice.call(
parsed.querySelectorAll( '.mw-parser-output p' )
).filter( function ( paragraph ) {
return paragraph.textContent.trim();
} );
var firstParagraph = Array.prototype.slice.call(
parsed.querySelectorAll( '.mw-parser-output > p' )
).filter( function ( paragraph ) {
return paragraph.textContent.trim();
} )[ 0 ] || paragraphs[ 0 ];
if ( !firstParagraph || paragraphWordCount( firstParagraph ) > 100 ) {
return firstParagraph || null;
}
var cleanParagraphs = paragraphs.filter( function ( paragraph ) {
return paragraph !== firstParagraph &&
isCleanProseParagraph( paragraph );
} );
if ( !cleanParagraphs.length ) {
return firstParagraph;
}
return cleanParagraphs.reduce( function ( longest, paragraph ) {
return paragraphWordCount( paragraph ) >
paragraphWordCount( longest ) ? paragraph : longest;
} );
}
function paragraphWordCount( paragraph ) {
return paragraph.textContent.trim().split( /\s+/ ).filter( Boolean ).length;
}
function isCleanProseParagraph( paragraph ) {
if (
paragraph.closest( 'li, table, dl, blockquote, pre, .poem' ) ||
paragraph.querySelector( 'br' )
) {
return false;
}
var text = paragraph.textContent.replace( /\s+/g, ' ' ).trim();
var wordCount = paragraphWordCount( paragraph );
var links = Array.prototype.slice.call(
paragraph.querySelectorAll( 'a' )
);
var linkedWordCount = links.reduce( function ( total, link ) {
return total + link.textContent.trim().split( /\s+/ )
.filter( Boolean ).length;
}, 0 );
if (
wordCount < 25 ||
text.indexOf( '؎' ) !== -1 ||
text.indexOf( '|' ) !== -1 ||
links.length > 8 ||
linkedWordCount / wordCount > 0.35
) {
return false;
}
return text.split( /[۔؟?!]+|\.(?:\s|$)/ )
.some( function ( sentence ) {
return sentence.trim().split( /\s+/ )
.filter( Boolean ).length >= 12;
} );
}
function limitedParagraph( paragraph, maximumWords ) {
var clone = paragraph.cloneNode( true );
if ( !maximumWords ) {
return clone;
}
var walker = document.createTreeWalker(
clone, NodeFilter.SHOW_TEXT
);
var remaining = maximumWords;
var textNode;
while ( ( textNode = walker.nextNode() ) ) {
var words = textNode.nodeValue.match( /\S+/g ) || [];
if ( words.length <= remaining ) {
remaining -= words.length;
continue;
}
textNode.nodeValue = words.slice( 0, remaining ).join( ' ' ) + '…';
while ( ( textNode = walker.nextNode() ) ) {
textNode.nodeValue = '';
}
break;
}
Array.prototype.slice.call( clone.querySelectorAll( '*' ) )
.reverse()
.forEach( function ( element ) {
if ( !element.textContent.trim() ) {
element.remove();
}
} );
return clone;
}
function loadPreferredParagraph( api, title ) {
return nkHomepageApiGet( api, {
action: 'parse',
page: title,
prop: 'text',
disableeditsection: true,
disabletoc: true,
formatversion: 2
} ).then( function ( data ) {
return preferredParagraphFromHtml( data.parse.text );
} );
}
function renderDailyFeature( api, options, memberTitles ) {
var container = document.getElementById( options.containerId );
if ( !container ) {
return Promise.resolve();
}
if ( !memberTitles.length ) {
return Promise.reject( new Error(
options.category + ' has no members with usable pictures.'
) );
}
return findUsablePage(
api,
options,
memberTitles,
dailyIndex( options.seed, memberTitles.length ),
0
)
.then( function ( page ) {
var link = document.createElement( 'a' );
var name = document.createElement( 'strong' );
var imageLink = link.cloneNode();
var image = document.createElement( 'img' );
link.href = page.fullurl;
link.textContent = page.title;
name.appendChild( link );
image.src = page.thumbnail.source;
image.alt = page.title;
image.width = page.thumbnail.width;
image.height = page.thumbnail.height;
imageLink.href = page.fullurl;
imageLink.appendChild( image );
container.replaceChildren();
container.appendChild( imageLink );
container.appendChild( name );
if ( page.selectedParagraph ) {
container.appendChild( limitedParagraph(
page.selectedParagraph, options.maximumWords
) );
}
var more = document.createElement( 'div' );
var moreLink = link.cloneNode();
more.className = 'nk-home-more';
moreLink.textContent = options.moreLabel;
more.appendChild( moreLink );
container.appendChild( more );
} );
}
function findUsablePage( api, options, members, startIndex, attempt ) {
if ( attempt >= members.length ) {
return Promise.reject( new Error(
options.category + ' has no eligible pages.'
) );
}
var selected = members[ ( startIndex + attempt ) % members.length ];
return nkLoadApprovedPage( api, selected ).then( function ( approved ) {
var page = approved.page;
page.selectedParagraph = preferredParagraphFromHtml( approved.html );
page.thumbnail = nkApprovedThumbnailFromHtml(
approved.html, options.thumbnailSize
);
if ( !page.thumbnail || !page.selectedParagraph ) {
return findUsablePage(
api, options, members, startIndex, attempt + 1
);
}
if (
options.minimumWords &&
paragraphWordCount( page.selectedParagraph ) <
options.minimumWords
) {
return findUsablePage(
api, options, members, startIndex, attempt + 1
);
}
return new Promise( function ( resolve ) {
var testImage = new Image();
testImage.onload = function () {
resolve( page );
};
testImage.onerror = function () {
resolve( findUsablePage(
api, options, members, startIndex, attempt + 1
) );
};
testImage.src = page.thumbnail.source;
} );
} ).catch( function () {
return findUsablePage(
api, options, members, startIndex, attempt + 1
);
} );
}
mw.loader.using( 'mediawiki.api' ).then( function () {
var api = new mw.Api();
return nkHomepageApiGet( api, {
action: 'query',
prop: 'revisions',
titles: 'MediaWiki:NKDailyPicturedPages.json',
rvprop: 'content',
rvslots: 'main',
formatversion: 2
} ).then( function ( data ) {
var revision = data.query.pages[ 0 ].revisions[ 0 ];
var pools = JSON.parse( revision.slots.main.content );
return Promise.all( [
renderDailyFeature( api, {
containerId: 'nk-daily-article',
category: 'زمرہ:مضامین و مقالات، زمرہ:کتب، ' +
'زمرہ:مجموعہ کلام، زمرہ:کتابوں پر تبصرہ',
seed: 'article',
maximumWords: 350,
thumbnailSize: 440,
moreLabel: 'مکمل مضمون پڑھیے ←'
}, pools.articles ),
renderDailyFeature( api, {
containerId: 'nk-daily-poet',
category: 'زمرہ:شعراء، زمرہ:نعت گو شعراء',
seed: 'poet',
maximumWords: 60,
thumbnailSize: 280,
moreLabel: 'مزید پڑھیے ←'
}, pools.poets ),
renderDailyFeature( api, {
containerId: 'nk-random-naatkhawan',
category: 'زمرہ:نعت خواں',
seed: 'naatkhawan',
maximumWords: 60,
thumbnailSize: 280,
moreLabel: 'مزید پڑھیے ←'
}, pools.reciters )
] );
} );
} ).catch( function ( error ) {
mw.log.error( 'Could not load the daily main-page features:', error );
} );
}() );
// Daily Khadim-e-Naat and Did You Know articles on the main page.
( function () {
'use strict';
if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
return;
}
var dateValues = {};
new Intl.DateTimeFormat( 'en-US', {
timeZone: 'Asia/Karachi',
year: 'numeric',
month: 'numeric',
day: 'numeric'
} ).formatToParts( new Date() ).forEach( function ( part ) {
dateValues[ part.type ] = part.value;
} );
var dailyDay = Math.floor( Date.UTC(
Number( dateValues.year ),
Number( dateValues.month ) - 1,
Number( dateValues.day )
) / 86400000 );
function seedValue( key ) {
var hash = 2166136261;
for ( var index = 0; index < key.length; index++ ) {
hash ^= key.charCodeAt( index );
hash = Math.imul( hash, 16777619 );
}
return hash >>> 0;
}
function preferredParagraphFromHtml( html ) {
var parsed = new DOMParser().parseFromString( html, 'text/html' );
var paragraphs = Array.prototype.slice.call(
parsed.querySelectorAll( '.mw-parser-output p' )
).filter( function ( paragraph ) {
return paragraph.textContent.trim();
} );
var firstParagraph = Array.prototype.slice.call(
parsed.querySelectorAll( '.mw-parser-output > p' )
).filter( function ( paragraph ) {
return paragraph.textContent.trim();
} )[ 0 ] || paragraphs[ 0 ];
if ( !firstParagraph || paragraphWordCount( firstParagraph ) > 100 ) {
return firstParagraph || null;
}
var cleanParagraphs = paragraphs.filter( function ( paragraph ) {
return paragraph !== firstParagraph &&
isCleanProseParagraph( paragraph );
} );
if ( !cleanParagraphs.length ) {
return firstParagraph;
}
return cleanParagraphs.reduce( function ( longest, paragraph ) {
return paragraphWordCount( paragraph ) >
paragraphWordCount( longest ) ? paragraph : longest;
} );
}
function paragraphWordCount( paragraph ) {
return paragraph.textContent.trim().split( /\s+/ ).filter( Boolean ).length;
}
function isCleanProseParagraph( paragraph ) {
if (
paragraph.closest( 'li, table, dl, blockquote, pre, .poem' ) ||
paragraph.querySelector( 'br' )
) {
return false;
}
var text = paragraph.textContent.replace( /\s+/g, ' ' ).trim();
var wordCount = paragraphWordCount( paragraph );
var links = Array.prototype.slice.call(
paragraph.querySelectorAll( 'a' )
);
var linkedWordCount = links.reduce( function ( total, link ) {
return total + link.textContent.trim().split( /\s+/ )
.filter( Boolean ).length;
}, 0 );
if (
wordCount < 25 ||
text.indexOf( '؎' ) !== -1 ||
text.indexOf( '|' ) !== -1 ||
links.length > 8 ||
linkedWordCount / wordCount > 0.35
) {
return false;
}
return text.split( /[۔؟?!]+|\.(?:\s|$)/ )
.some( function ( sentence ) {
return sentence.trim().split( /\s+/ )
.filter( Boolean ).length >= 12;
} );
}
function limitedParagraph( paragraph, maximumWords ) {
var clone = paragraph.cloneNode( true );
if ( !maximumWords ) {
return clone;
}
var walker = document.createTreeWalker(
clone, NodeFilter.SHOW_TEXT
);
var remaining = maximumWords;
var textNode;
while ( ( textNode = walker.nextNode() ) ) {
var words = textNode.nodeValue.match( /\S+/g ) || [];
if ( words.length <= remaining ) {
remaining -= words.length;
continue;
}
textNode.nodeValue = words.slice( 0, remaining ).join( ' ' ) + '…';
while ( ( textNode = walker.nextNode() ) ) {
textNode.nodeValue = '';
}
break;
}
Array.prototype.slice.call( clone.querySelectorAll( '*' ) )
.reverse()
.forEach( function ( element ) {
if ( !element.textContent.trim() ) {
element.remove();
}
} );
return clone;
}
function loadPreferredParagraph( api, title ) {
return nkHomepageApiGet( api, {
action: 'parse',
page: title,
prop: 'text',
disableeditsection: true,
disabletoc: true,
formatversion: 2
} ).then( function ( data ) {
return preferredParagraphFromHtml( data.parse.text );
} );
}
function renderDailyArticle( api, options, candidates ) {
var container = document.getElementById( options.containerId );
if ( !container ) {
return Promise.resolve();
}
if ( !candidates.length ) {
return Promise.reject( new Error(
options.seed + ' has no eligible articles.'
) );
}
function loadCandidate( candidate ) {
if ( typeof candidate !== 'string' ) {
return Promise.resolve( {
title: candidate.title || '',
fullurl: mw.config.get( 'wgScript' ) + '?title=' +
encodeURIComponent( candidate.page.replace( / /g, '_' ) ),
extract: candidate.text
} );
}
return nkLoadApprovedPage( api, candidate ).then( function ( approved ) {
return {
title: approved.page.title,
fullurl: approved.page.fullurl,
thumbnail: nkApprovedThumbnailFromHtml(
approved.html, options.thumbnailSize
),
selectedParagraph: preferredParagraphFromHtml( approved.html )
};
} );
}
var count = Math.min( options.count || 1, candidates.length );
var startIndex =
( seedValue( options.seed ) + dailyDay * count ) % candidates.length;
// Per the homepage picture-requirement rule, every daily-content panel
// must show a picture except کیا آپ جانتے ہیں؟ (did-you-know); callers opt in
// with options.requireThumbnail (verified the same way picture panels
// verify theirs: an actual Image() load, not just a thumbnail URL).
function isTextEligible( page ) {
var wordCount = page.selectedParagraph ?
paragraphWordCount( page.selectedParagraph ) :
( page.extract || '' ).trim().split( /\s+/ )
.filter( Boolean ).length;
return ( page.selectedParagraph || page.extract ) &&
( !options.minimumWords || wordCount >= options.minimumWords );
}
function isEligible( page ) {
if ( !isTextEligible( page ) ) {
return Promise.resolve( false );
}
if ( !options.requireThumbnail ) {
return Promise.resolve( true );
}
if ( !page.thumbnail ) {
return Promise.resolve( false );
}
return new Promise( function ( resolve ) {
var testImage = new Image();
testImage.onload = function () {
resolve( true );
};
testImage.onerror = function () {
resolve( false );
};
testImage.src = page.thumbnail.source;
} );
}
function loadEligiblePages( attempt, pages ) {
if ( pages.length >= count || attempt >= candidates.length ) {
return Promise.resolve( pages );
}
var candidate = candidates[
( startIndex + attempt ) % candidates.length
];
return loadCandidate( candidate ).then( function ( page ) {
return isEligible( page ).then( function ( eligible ) {
if ( eligible ) {
pages.push( page );
}
return loadEligiblePages( attempt + 1, pages );
} );
} ).catch( function () {
return loadEligiblePages( attempt + 1, pages );
} );
}
return loadEligiblePages( 0, [] ).then( function ( pages ) {
container.replaceChildren();
pages.forEach( function ( page ) {
var item = document.createElement( 'div' );
var more = document.createElement( 'div' );
var moreLink = document.createElement( 'a' );
item.className = 'nk-home-daily-item';
more.className = 'nk-home-more';
moreLink.href = page.fullurl;
moreLink.textContent = 'مزید پڑھیے ←';
more.appendChild( moreLink );
if ( page.thumbnail ) {
var imageLink = document.createElement( 'a' );
var image = document.createElement( 'img' );
imageLink.href = page.fullurl;
image.src = page.thumbnail.source;
image.alt = page.title;
image.width = page.thumbnail.width;
image.height = page.thumbnail.height;
imageLink.appendChild( image );
item.appendChild( imageLink );
}
if ( page.title ) {
var titleLink = document.createElement( 'a' );
var title = document.createElement( 'strong' );
titleLink.href = page.fullurl;
titleLink.textContent = page.title;
title.appendChild( titleLink );
item.appendChild( title );
}
if ( page.selectedParagraph ) {
item.appendChild( limitedParagraph(
page.selectedParagraph, options.maximumWords
) );
} else if ( page.extract ) {
var description = document.createElement( 'p' );
var extract = page.extract.replace( /={2,}/g, '' ).trim();
if ( options.maximumWords ) {
var words = extract.split( /\s+/ );
if ( words.length > options.maximumWords ) {
extract = words.slice(
0, options.maximumWords
).join( ' ' ) + '…';
}
}
description.textContent = extract;
item.appendChild( description );
}
item.appendChild( more );
container.appendChild( item );
} );
} );
}
mw.loader.using( 'mediawiki.api' ).then( function () {
var api = new mw.Api();
function loadJsonPage( title ) {
return nkHomepageApiGet( api, {
action: 'query',
prop: 'revisions',
titles: title,
rvprop: 'content',
rvslots: 'main',
formatversion: 2
} ).then( function ( data ) {
return JSON.parse(
data.query.pages[ 0 ].revisions[ 0 ].slots.main.content
);
} );
}
return Promise.all( [
loadJsonPage( 'MediaWiki:NKDailyTextPages.json' ),
loadJsonPage( 'MediaWiki:NKDidYouKnowEntries.json' )
] ).then( function ( data ) {
var pools = data[ 0 ];
var customEntries = ( data[ 1 ].entries || [] ).filter(
function ( entry ) {
return entry && typeof entry.text === 'string' &&
entry.text.trim() &&
typeof entry.page === 'string' &&
entry.page.trim();
}
);
return Promise.all( [
renderDailyArticle( api, {
containerId: 'nk-daily-khadim',
seed: 'khadim',
maximumWords: 250,
thumbnailSize: 280,
requireThumbnail: true
}, pools.khadim ),
renderDailyArticle( api, {
containerId: 'nk-daily-dyk',
seed: 'did-you-know',
thumbnailSize: 440,
maximumWords: 40,
count: 3
}, pools.dyk.concat( customEntries ) )
] );
} );
} ).catch( function ( error ) {
mw.log.error( 'Could not load daily text panels:', error );
} );
}() );
// Daily naat video on the main page, picked from زمرہ:وڈیو نعتیں.
( function () {
'use strict';
if ( mw.config.get( 'wgPageName' ) !== 'صفحۂ_اول' ) {
return;
}
var dateValues = {};
new Intl.DateTimeFormat( 'en-US', {
timeZone: 'Asia/Karachi',
year: 'numeric',
month: 'numeric',
day: 'numeric'
} ).formatToParts( new Date() ).forEach( function ( part ) {
dateValues[ part.type ] = part.value;
} );
var dailyDay = Math.floor( Date.UTC(
Number( dateValues.year ),
Number( dateValues.month ) - 1,
Number( dateValues.day )
) / 86400000 );
function seedValue( key ) {
var hash = 2166136261;
for ( var index = 0; index < key.length; index++ ) {
hash ^= key.charCodeAt( index );
hash = Math.imul( hash, 16777619 );
}
return hash >>> 0;
}
// Accepts a watch?v=, youtu.be/, /embed/, or bare 11-char video id.
function extractYoutubeId( param ) {
param = param.trim();
var match = param.match( /[?&]v=([A-Za-z0-9_-]{11})/ );
if ( match ) {
return match[ 1 ];
}
match = param.match( /youtu\.be\/([A-Za-z0-9_-]{11})/ );
if ( match ) {
return match[ 1 ];
}
match = param.match( /\/embed\/([A-Za-z0-9_-]{11})/ );
if ( match ) {
return match[ 1 ];
}
if ( /^[A-Za-z0-9_-]{11}$/.test( param ) ) {
return param;
}
return null;
}
function loadVideoId( api, title ) {
return nkHomepageApiGet( api, {
action: 'query',
titles: title,
prop: 'revisions',
rvprop: 'content',
rvslots: 'main',
formatversion: 2
} ).then( function ( data ) {
var page = data.query.pages[ 0 ];
var revision = page && page.revisions && page.revisions[ 0 ];
var content = revision ? revision.slots.main.content : '';
var match = content.match( /\{\{#ev:youtube\|([^|}]+)/i );
return match ? extractYoutubeId( match[ 1 ] ) : null;
} );
}
function findUsableVideo( api, members, startIndex, attempt ) {
if ( attempt >= members.length ) {
return Promise.reject( new Error( 'زمرہ:وڈیو نعتیں has no eligible videos.' ) );
}
var member = members[ ( startIndex + attempt ) % members.length ];
return loadVideoId( api, member.title ).then( function ( videoId ) {
if ( !videoId ) {
return findUsableVideo( api, members, startIndex, attempt + 1 );
}
return { title: member.title, videoId: videoId };
} );
}
mw.loader.using( 'mediawiki.api' ).then( function () {
var container = document.getElementById( 'nk-daily-video' );
if ( !container ) {
return;
}
var api = new mw.Api();
return nkHomepageApiGet( api, {
action: 'query',
list: 'categorymembers',
cmtitle: 'زمرہ:وڈیو نعتیں',
cmlimit: 'max',
formatversion: 2
} ).then( function ( data ) {
var members = data.query.categorymembers;
if ( !members.length ) {
return Promise.reject( new Error( 'زمرہ:وڈیو نعتیں has no members.' ) );
}
return findUsableVideo(
api, members, seedValue( 'video' ) + dailyDay, 0
);
} ).then( function ( video ) {
container.replaceChildren();
var wrapper = document.createElement( 'div' );
wrapper.className = 'nk-video-embed';
var iframe = document.createElement( 'iframe' );
iframe.src = 'https://www.youtube-nocookie.com/embed/' + video.videoId;
iframe.title = video.title;
iframe.loading = 'lazy';
iframe.allow =
'accelerometer; autoplay; clipboard-write; encrypted-media; ' +
'gyroscope; picture-in-picture; web-share';
iframe.allowFullscreen = true;
wrapper.appendChild( iframe );
container.appendChild( wrapper );
var caption = document.createElement( 'strong' );
var captionLink = document.createElement( 'a' );
captionLink.href = mw.util.getUrl( video.title );
captionLink.textContent = video.title;
caption.appendChild( captionLink );
container.appendChild( caption );
var more = document.createElement( 'div' );
var moreLink = document.createElement( 'a' );
more.className = 'nk-home-more';
moreLink.href = mw.util.getUrl( 'زمرہ:وڈیو نعتیں' );
moreLink.textContent = 'مزید نعتیہ ویڈیوز ←';
more.appendChild( moreLink );
container.appendChild( more );
} );
} ).catch( function ( error ) {
mw.log.error( 'Could not load the daily naat video:', error );
} );
}() );
( function () {
'use strict';
var measurementId = 'G-YX4H2XLR38';
var storageKey = 'naatkainaat-analytics-consent-v1';
var analyticsLoaded = false;
var consentCountries = [
'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',
'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL',
'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB'
];
if (
mw.config.get( 'wgUserName' ) !== null ||
location.hostname === 'localhost' ||
location.hostname === '127.0.0.1'
) {
return;
}
function getConsent() {
try {
return localStorage.getItem( storageKey );
} catch ( e ) {
return null;
}
}
function setConsent( value ) {
try {
localStorage.setItem( storageKey, value );
} catch ( e ) {
// The current page can still honor the visitor's choice.
}
}
function requiresConsent( countryCode ) {
return consentCountries.indexOf( countryCode ) !== -1;
}
function detectCountry() {
var lookup = fetch( 'https://api.country.is/', {
cache: 'no-store',
credentials: 'omit',
referrerPolicy: 'no-referrer'
} ).then( function ( response ) {
if ( !response.ok ) {
throw new Error( 'Country lookup failed.' );
}
return response.json();
} ).then( function ( data ) {
if ( !data || typeof data.country !== 'string' ) {
throw new Error( 'Country lookup returned invalid data.' );
}
return data.country.toUpperCase();
} );
var timeout = new Promise( function ( resolve, reject ) {
setTimeout( function () {
reject( new Error( 'Country lookup timed out.' ) );
}, 4000 );
} );
return Promise.race( [ lookup, timeout ] );
}
function gtag() {
window.dataLayer.push( arguments );
}
function loadAnalytics() {
var script;
if ( analyticsLoaded ) {
return;
}
analyticsLoaded = true;
window.dataLayer = window.dataLayer || [];
gtag( 'consent', 'default', {
analytics_storage: 'denied',
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
wait_for_update: 500
} );
gtag( 'consent', 'update', {
analytics_storage: 'granted'
} );
gtag( 'js', new Date() );
gtag( 'config', measurementId, {
cookie_flags: 'SameSite=Lax;Secure'
} );
script = document.createElement( 'script' );
script.async = true;
script.src = 'https://www.googletagmanager.com/gtag/js?id=' +
encodeURIComponent( measurementId );
document.head.appendChild( script );
}
function expireCookie( name, domain ) {
var cookie = name + '=; Max-Age=0; path=/; SameSite=Lax; Secure';
if ( domain ) {
cookie += '; domain=' + domain;
}
document.cookie = cookie;
}
function revokeAnalytics() {
var cookieNames = [ '_ga', '_ga_' + measurementId.substring( 2 ) ];
var domains = [ '', location.hostname, '.' + location.hostname ];
if ( window.dataLayer ) {
gtag( 'consent', 'update', {
analytics_storage: 'denied'
} );
}
cookieNames.forEach( function ( cookieName ) {
domains.forEach( function ( domain ) {
expireCookie( cookieName, domain );
} );
} );
}
function addStyles() {
mw.util.addCSS(
'#nk-consent{position:fixed;z-index:10000;right:1rem;bottom:1rem;' +
'max-width:32rem;padding:1rem 1.25rem;background:#fff;color:#202122;' +
'border:1px solid #a2a9b1;border-radius:.5rem;box-shadow:0 4px 18px ' +
'rgba(0,0,0,.2);font-size:16px;line-height:1.8;text-align:right;' +
'direction:rtl}#nk-consent[hidden]{display:none}#nk-consent p{' +
'margin:0 0 .75rem}#nk-consent-actions{display:flex;gap:.5rem;' +
'flex-wrap:wrap}#nk-consent button{font:inherit;padding:.35rem .9rem;' +
'border:1px solid #3366cc;border-radius:.25rem;cursor:pointer}' +
'#nk-consent-accept{background:#3366cc;color:#fff}' +
'#nk-consent-reject{background:#fff;color:#202122}' +
'#nk-privacy-settings{position:fixed;z-index:9999;left:.75rem;' +
'bottom:.75rem;padding:.25rem .6rem;border:1px solid #72777d;' +
'border-radius:.25rem;background:#fff;color:#202122;cursor:pointer;' +
'font-size:13px}#nk-privacy-settings[hidden]{display:none}' +
'@media(max-width:600px){#nk-consent{right:.5rem;left:.5rem;' +
'bottom:.5rem;max-width:none}}'
);
}
function createInterface() {
var banner = document.createElement( 'section' );
var text = document.createElement( 'p' );
var actions = document.createElement( 'div' );
var accept = document.createElement( 'button' );
var reject = document.createElement( 'button' );
var settings = document.createElement( 'button' );
banner.id = 'nk-consent';
banner.setAttribute( 'role', 'dialog' );
banner.setAttribute( 'aria-label', 'تجزیاتی کوکیز کی اجازت' );
text.textContent =
'ہم ویب سائٹ کے استعمال کو سمجھنے اور اسے بہتر بنانے کے لیے ' +
'Google Analytics استعمال کرنا چاہتے ہیں۔ آپ کی اجازت کے بغیر ' +
'تجزیاتی کوکیز یا Google Analytics لوڈ نہیں ہوں گے۔';
actions.id = 'nk-consent-actions';
accept.id = 'nk-consent-accept';
accept.type = 'button';
accept.textContent = 'اجازت دیں';
reject.id = 'nk-consent-reject';
reject.type = 'button';
reject.textContent = 'اجازت نہ دیں';
settings.id = 'nk-privacy-settings';
settings.type = 'button';
settings.textContent = 'رازداری کی ترتیبات';
settings.hidden = true;
accept.addEventListener( 'click', function () {
setConsent( 'granted' );
banner.hidden = true;
settings.hidden = false;
loadAnalytics();
} );
reject.addEventListener( 'click', function () {
var shouldReload = analyticsLoaded;
setConsent( 'denied' );
revokeAnalytics();
banner.hidden = true;
settings.hidden = false;
if ( shouldReload ) {
location.reload();
}
} );
settings.addEventListener( 'click', function () {
banner.hidden = false;
settings.hidden = true;
} );
actions.appendChild( accept );
actions.appendChild( reject );
banner.appendChild( text );
banner.appendChild( actions );
document.body.appendChild( banner );
document.body.appendChild( settings );
if ( getConsent() === 'granted' ) {
banner.hidden = true;
settings.hidden = false;
loadAnalytics();
} else if ( getConsent() === 'denied' ) {
banner.hidden = true;
settings.hidden = false;
}
}
$( function () {
detectCountry().then( function ( countryCode ) {
if ( requiresConsent( countryCode ) ) {
addStyles();
createInterface();
} else {
loadAnalytics();
}
} ).catch( function () {
addStyles();
createInterface();
} );
} );
}() );
/* Auto-wrap naat poetry under the standard naat heading: centered at widest natural line, then justified. */
(function () {
function stylePoetryBlock(block) {
block.classList.add('nk-poetry');
block.style.display = 'table';
block.style.width = 'max-content';
block.style.maxWidth = '100%';
block.style.margin = '0 auto';
block.style.direction = 'rtl';
var lines = block.querySelectorAll('p');
for (var i = 0; i < lines.length; i++) {
lines[i].style.width = '100%';
lines[i].style.textAlign = 'justify';
lines[i].style.textAlignLast = 'justify';
lines[i].style.textJustify = 'inter-word';
lines[i].style.marginTop = '8px';
lines[i].style.marginBottom = '8px';
}
}
function isHeadingElement(element) {
return !!element && (
( element.classList && element.classList.contains('mw-heading') ) ||
/^H[1-6]$/.test(element.tagName)
);
}
function autoWrapNaatPoetry(root) {
var container = root && root.querySelector ? root : document;
var headings = container.querySelectorAll('.mw-heading, h2, h3, h4, h5, h6');
for (var i = 0; i < headings.length; i++) {
if (headings[i].textContent.indexOf('نعتِ رسولِ آخر صلی اللہ علیہ وآلہ وسلم') === -1) {
continue;
}
var node = headings[i].nextElementSibling;
if (node && node.classList && node.classList.contains('nk-poetry')) {
stylePoetryBlock(node);
continue;
}
var lines = [];
while (node && !isHeadingElement(node)) {
var next = node.nextElementSibling;
if (node.tagName === 'P' && node.textContent.trim() !== '') {
lines.push(node);
} else if (lines.length) {
break;
}
node = next;
}
if (lines.length < 2) {
continue;
}
var wrapper = document.createElement('div');
wrapper.className = 'nk-poetry';
lines[0].parentNode.insertBefore(wrapper, lines[0]);
for (var j = 0; j < lines.length; j++) {
wrapper.appendChild(lines[j]);
}
stylePoetryBlock(wrapper);
}
}
if (window.mw && mw.hook) {
mw.hook('wikipage.content').add(function ($content) {
autoWrapNaatPoetry($content && $content[0] ? $content[0] : document);
});
} else if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function () {
autoWrapNaatPoetry(document);
});
} else {
autoWrapNaatPoetry(document);
}
}());