Butun axtardiqlarinizi tapmaq ucun buraya: DAXIL OLUN
  Mp4 Mp3 Axtar Yukle
  Video Axtar Yukle
  Shekil Axtar Yukle
  Informasiya Melumat Axtar
  Hazir Inshalar Toplusu
  AZERI CHAT + Tanishliq
  1-11 Sinif Derslikler Yukle
  Saglamliq Tibbi Melumat
  Whatsapp Plus Yukle(Yeni)

  • Ana səhifə
  • Təsadüfi
  • Yaxınlıqdakılar
  • Daxil ol
  • Nizamlamalar
İndi ianə et Əgər Vikipediya sizin üçün faydalıdırsa, bu gün ianə edin.

İstifadəçi:Toghrul R/tag.js

  • İstifadəçi səhifəsi
  • Müzakirə
  • Mənbəyə bax
< İstifadəçi:Toghrul R

Qeyd: Dəyişiklikləri yayımladıqdan sonra etdiyiniz dəyişikliklərin görünməsi üçün brauzerinizin keşinin təmizlənməsi lazım ola bilər.

  • Firefox / Safari: Reload düyməsinə basılı tutarkən Shift düyməsinə basın, və ya Ctrl+F5 və ya Ctrl+R (Mac üçün ⌘-R )
  • Google Chrome: Ctrl-Shift-R (Mac üçün ⌘-Shift-R)
  • Edge: Ctrl düyməsini basılı tutarkən Refresh düyməsinə basın, və ya sadəcə Ctrl+F5.
/* <nowiki> */

mw.loader.using(['mediawiki.api', 'mediawiki.util', '@wikimedia/codex'], require => {
	const { createMwApp, h } = require('vue');
	const {
	  CdxDialog,
	  CdxCheckbox,
	  CdxField,
	  CdxSearchInput,
	  CdxTabs,
	  CdxTab,
	  CdxButton,
	  CdxToggleSwitch
	} = require('@wikimedia/codex');
	const api = new mw.Api();
	const ns = mw.config.get('wgNamespaceNumber');
	const pageTitle = mw.config.get('wgPageName').replaceAll('_', ' ');
	if (![0, 4].includes(ns)) return;

	const tagList = {
		'Formatlaşdırma və vikiləşdirmə': {
			'Ümumi': [ 
				{ tag: 'Vikiləşdirmək', description: "bu məqaləni vikiləşdirmək lazımdır" },
				{ tag: 'Qaralama', description: 'məqalə qaralama halındadır' },
				{ tag: 'Təkmilləşdirmə', description: 'məqalə Vikipediya meyarlarına uyğunlaşdırılmalıdır' },
				{ tag: 'Daxili keçid azlığı', description: 'məqalədə daxili keçidlərin artırılmasına ehtiyac var', alias: 'Underlinked' },
				{ tag: 'Stil kitabçasına uyğun olmayan', description: 'məqalə stil kitabçasına uyğun deyil' },
				{ tag: 'Yarımçıq', description: 'məqalə yarımçıqdır və genişləndirilməlidir' },
				{ tag: 'Preambulasız', description: 'məqalənin giriş hissəsi yoxdur' },
				{ tag: 'Qısa preambula', description: 'məqalənin giriş hissəsi çox qısadır' },
				{ tag: 'Uzun preambula', description: 'məqalənin giriş hissəsi çox uzundur' }
			],
			'Texniki': [ 
				{ tag: 'İş gedir', description: 'məqalədə iş davam etməkdədir', alias: 'iş gedir' },
				{ tag: 'Silinməyə namizəd', description: 'səhifə silinməyə namizəddir' }
			]
		},
		'Ümumi məzmun': {
			'Əhəmiyyət və ensiklopediklik': [
				{ tag: 'Əhəmiyyət', description: 'məqalənin ensiklopedik tələblərə cavab vermədiyinə dair şübhələr var' }
			],
			'Yazı üslubu': [
				{ tag: 'Reklam', description: 'bu məqalə reklam xarakteri daşıyır.' },
				{ tag: 'Üslub', description: 'bu məqalənin üslubu və ya stili Vikipediyada istifadə olunan ensiklopedik tərzdə olmaya bilər.' }
			],
			'Məlumat və detallar': [
				{ tag: 'Mütəxəssis', description: 'məqalənin təkmilləşdirilməsi üçün mütəxəssislərə ehtiyac var' },
				{ tag: 'Qloballaşdır', description: 'məqalədəki nümunələr və perspektivlər mövzuya dünya miqyasında baxışı əks etdirmir'},
			],
			'Aktuallıq': [
				{ tag: 'Aktual', description: 'məqalədə davam edən aktual hadisələrlə bağlı məlumat var' },
				{ tag: 'Yeniləmə', description: 'məqalədəki məlumatlar köhnədir' },
				{ tag: 'Güncəl əlaqəli', description: 'məzmun başqa məqalədəki hadisələr ilə əlaqəli olduğu üçün tez-tez dəyişə bilər' },
				{ tag: 'Yaxınlarda ölən', description: 'məqalə son vaxtlarda vəfat etmiş insan haqqındadır' },
				{ tag: 'Davam edən döyüş', description: 'hadisələr davam etdiyi üçün məqalə tez-tez dəyişikliyə məruz qala bilər' },
				{ tag: 'Gözlənilən oyun', description: 'məqalə istehsal prosesində olan və buraxılması gözlənilən video oyun haqqındadır' },
			],
			'Neytrallıq, qərəzlilik və faktiki dəqiqlik': [
				{ tag: 'Tərəfli', description: 'məqalənin neytrallığı şübhə doğurur' },
				{ tag: 'Faktları yoxla', description: 'məqalədə verilən faktların dəqiqliyini yoxlamaq lazımdır' },
				{ tag: 'Maraq toqquşması', description: 'məqalənin əsas müəllifinin mövzu ilə sıx əlaqəsi var' },
			],
			'Mənbələr və istinadlar': [
				{ tag: 'Mənbə azlığı', description: 'məlumatların yoxlanıla bilməsi üçün əlavə mənbələrə ehtiyac var' },
				{ tag: 'Mənbəsiz', description: 'məqalədəki heç bir məlumatın mənbəsi göstərilməyib' },
				{ tag: 'İlkin mənbələr', description: 'yalnız ilkin və ya onunla əlaqəli mənbələrdən istifadə olunur', alias: 'ilkin mənbələr' },
				{ tag: 'İstinadsız', description: 'mənbələr göstərilsə də, mətndaxili istinadlar yoxdur', alias: 'istinadsız' },
				{ tag: 'Tək mənbə', description: 'məqalə böyük ölçüdə və ya tamamilə tək mənbəyə əsaslanır' },
				{ tag: 'Orijinal tədqiqat', description: 'məqalədə orijinal tədqiqata yer verilib' },
				{ tag: 'Müəllif mənbələri', description: 'məqalənin müəllifi tərəfindən yayımlanan mənbələrdən istifadə edilib' },
			],
			'Layihələrə köçürmələr': [
				{ tag: 'Vikimənbəyə köçür', description: 'məqaləni Vikimənbəyə köçürmək lazımdır)' },
				{ tag: 'Vikisitata köçür', description: 'məqaləni Vikisitata köçürmək lazımdır' },
				{ tag: 'Vikikitaba köçür', description: 'məqaləni Vikikitaba köçürmək lazımdır' },
				{ tag: 'Vikilüğətə köçür', description: 'məqaləni Vikilüğətə köçürmək lazımdır' },
			]
		},
		'Spesifik məzmun problemləri': {
			'Dil': [
				{ tag: 'Azərbaycanca deyil', description: 'məqalə Azərbaycan dilində yazılmayıb və tərcüməyə ehtiyac var' },
				{ tag: 'Yanlış transliterasiyalar', description: 'Azərbaycan dilinə yanlış şəkildə transliterasiya edilmiş xüsusi adlar var' },
				{ tag: 'Yanlış adlandırma', description: 'Azərbaycan dilində düzgün verilməmiş məqalə adı' }
			],
			'Kateqoriyalar': [
				{ tag: 'Kateqoriyasız', description: 'səhifəyə hansısa kateqoriya əlavə edilməyib' },
				{ tag: 'Kateqoriya əlavə et', description: 'əlavə və ya daha spesifik kateqoriyalara ehtiyac var' },
				{ tag: 'Kateqoriya çıxar', description: 'səhifə həm əsas, həm də alt kateqoriyalara əlavə edilib' }
			],
			'Keçidlər': [
				{ tag: 'Tənha', description: 'hansısa məqalədən bu məqaləyə verilmiş keçid yoxdur', alias: ['Orphan', 'Tənha məqalə', 'Tənha səhifə'] }
			],
			'İstinad formaları': [
				{ tag: 'İstinad stili', description: 'istinadlar müvafiq istinad şablonları ilə göstərilməlidir', alias: 'istinad stili' },
			],
		}
	};

	const portletLink = mw.util.addPortletLink(
		'p-ap',
		'javascript:void(0);',
		'Bildiriş2',
		't-ap-tag',
		'Bildiriş şablonu əlavə və ya çıxar'
	);

	const App = {
	data: () => ({
		tagList,
		monthNames: [
			'yanvar', 'fevral', 'mart', 'aprel', 'may', 'iyun',
			'iyul', 'avqust', 'sentyabr', 'oktyabr', 'noyabr', 'dekabr'
		],
		dialogShown: false,
		selectedTags: [],
		existingTags: [],
		searchQuery: '',
		status: 'form',
		progressText: '',
		summary: 'Səhifəyə bildiriş şablonu əlavə olunur',
		currentStep: 0,
		activeTab: 'add',
		wrapInBox: false,
		tabsData: [
			{ name: 'add', label: 'Şablon əlavə et' },
			{ name: 'remove', label: 'Şablon çıxar' }
		]
	}),
	computed: {
		filteredTagList() {
			if (!this.searchQuery.trim()) return this.tagList;
	
			const query = this.searchQuery.toLowerCase();
			const result = {};
	
			for (const [categoryName, groups] of Object.entries(this.tagList)) {
				const filteredGroups = {};
				for (const [groupName, tags] of Object.entries(groups)) {
				const matchedTags = tags.filter(tag =>
					!this.existingTags.includes(tag.tag) && (
						tag.tag.toLowerCase().includes(query) ||
						tag.description.toLowerCase().includes(query)
					)
				);
					if (matchedTags.length > 0) {
						filteredGroups[groupName] = matchedTags;
					}
				}
				if (Object.keys(filteredGroups).length > 0) {
					result[categoryName] = filteredGroups;
				}
			}
			return result;
		},
		existingTagList() {
			const query = this.searchQuery.toLowerCase();
			const existing = this.existingTags.map(tag => {
				const tagObj = Object.values(this.tagList)
					.flatMap(group => Object.values(group).flat())
					.find(t => t.tag === tag);
				return tagObj && (
					!query || tagObj.tag.toLowerCase().includes(query) || tagObj.description.toLowerCase().includes(query)
				) ? tagObj : null;
			}).filter(Boolean);
			return existing;
		},
		showWrapToggle() {
		  const removedCount = this.selectedTags.filter(t => this.existingTags.includes(t)).length;
		  const addedCount   = this.selectedTags.filter(t => !this.existingTags.includes(t)).length;
		  const finalCount   = this.existingTags.length - removedCount + addedCount;
		  return finalCount > 1;
		},
		selectedMode() {
			const selected = this.selectedTags;
			const allExisting = selected.length > 0 && selected.every(tag => this.existingTags.includes(tag));
			const allNew = selected.length > 0 && selected.every(tag => !this.existingTags.includes(tag));
			if (allExisting) return 'remove';
			if (allNew) return 'add';
			if (selected.length > 0) return 'update';
			return 'none';
		},
		highlightedText() {
			const query = this.searchQuery.toLowerCase();
			if (!query) return t => t;
			return text =>
				text.replace(
					new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi'),
					'<span style="text-decoration: underline;">$1</span>'
				)
		}
	},
	methods: {
		async toggleDialog() {
			this.dialogShown = !this.dialogShown;
			if (this.dialogShown) {
				await this.fetchExistingTags();
			} else {
				this.status = 'form';
				this.selectedTags = [];
				this.searchQuery = '';
			}
		},
		async fetchExistingTags() {
			const response = await api.get({
				action: 'query',
				prop: 'revisions',
				titles: pageTitle,
				rvprop: 'content',
				format: 'json',
				formatversion: 2
			});
		
			const content =
				response.query &&
				response.query.pages &&
				response.query.pages[0] &&
				response.query.pages[0].revisions &&
				response.query.pages[0].revisions[0] &&
				response.query.pages[0].revisions[0].content || '';
				
			const hasProblemBox = /{{\s*Məqalə[\s_]+problemləri\s*\|/i.test(content);
			this.wrapInBox = hasProblemBox;
		
			const allTags = Object.values(this.tagList)
				.flatMap(groups => Object.values(groups).flat());
			
			const tagTitles = allTags.flatMap(tag => {
				const aliases = Array.isArray(tag.alias) ? tag.alias : tag.alias ? [tag.alias] : [];
				return [tag.tag, ...aliases].map(name => `Şablon:${name}`);
			});
		
			const redirectsRes = await api.get({
				action: 'query',
				titles: tagTitles.join('|'),
				redirects: 1,
				format: 'json'
			});
		
			const redirectMap = {};
			if (redirectsRes.query && redirectsRes.query.redirects) {
				for (const redir of redirectsRes.query.redirects) {
					const from = redir.from.replace(/^Şablon:/, '').trim();
					const to = redir.to.replace(/^Şablon:/, '').trim();
					redirectMap[from] = to;
				}
			}
		
			const tagNameMap = {};
			this.aliasMap = {};
			
			for (const t of allTags) {
				const aliases = Array.isArray(t.alias) ? t.alias : t.alias ? [t.alias] : [];
				tagNameMap[t.tag] = t.tag;
				this.aliasMap[t.tag] = [t.tag, ...aliases];
			
				for (const alias of aliases) {
					tagNameMap[alias] = t.tag;
				}
			}
		
			const detectionTags = Object.keys(tagNameMap);
		
			this.existingTags = detectionTags
				.filter(name => new RegExp(`{{\\s*${name}(\\s*\\||\\s*}})`, 'i').test(content))
				.map(name => tagNameMap[name]);
		
			this.selectedTags = [];
			this.searchQuery = this.searchQuery;
		},
		
updateProblemBox(content, tagsToAdd = [], tagsToRemove = [], monthYear = '', keepIfEmpty = false, wrapInBox = false, allPossibleTags = []) {
	const openTag = '{{Məqalə problemləri|';
	const startIdx = content.indexOf(openTag);

	let existingLines = [];
	let cleanedContent = content;

	if (startIdx !== -1) {
		let idx = startIdx + openTag.length;
		let braceDepth = 2;
		let endIdx = idx;

		while (endIdx < content.length) {
			if (content.slice(endIdx, endIdx + 2) === '{{') {
				braceDepth += 2;
				endIdx += 2;
			} else if (content.slice(endIdx, endIdx + 2) === '}}') {
				braceDepth -= 2;
				endIdx += 2;
				if (braceDepth <= 0) break;
			} else {
				endIdx++;
			}
		}

		const fullBlock = content.slice(startIdx, endIdx).trim();

		const normalizedInner = fullBlock
			.replace(openTag, '')
			.replace(/}}(?={{)/g, '}}\n')
			.split('\n')
			.map(l => l.trim())
			.filter(line =>
				line.startsWith('{{') &&
				line.endsWith('}}') &&
				!line.includes('Məqalə problemləri')
			);

		for (const line of normalizedInner) {
			const tagMatch = line.match(/^{{\s*(.*?)\b/);
			if (tagMatch) {
				const tag = tagMatch[1].trim();
				if (!tagsToRemove.includes(tag)) {
					existingLines.push(line);
				}
			}
		}

		cleanedContent = content.slice(0, startIdx) + content.slice(endIdx);
		cleanedContent = cleanedContent.replace(/^\s*}}+\s*/gm, '').trim();
	}

	const finalTagSet = new Set();
	const finalLines = [];

	for (const line of existingLines) {
		const tagMatch = line.match(/^{{\s*(.*?)\b/);
		if (tagMatch) {
			const tag = tagMatch[1].trim();
			finalTagSet.add(tag);
			finalLines.push(line);
		}
	}

	for (const tag of tagsToAdd) {
		if (!finalTagSet.has(tag)) {
			finalLines.push(`{{${tag}|tarix=${monthYear}}}`);
			finalTagSet.add(tag);
		}
	}

	if (wrapInBox && allPossibleTags.length > 0) {
		for (const tag of allPossibleTags) {
			if (tagsToRemove.includes(tag) || finalTagSet.has(tag)) continue;
			const regex = new RegExp(`{{\\s*${tag}\\s*\\|[^}]*}}`, 'gi');
			let match;
			while ((match = regex.exec(cleanedContent)) !== null) {
				cleanedContent = cleanedContent.replace(match[0], '');
				finalLines.push(`{{${tag}|tarix=${monthYear}}}`);
				finalTagSet.add(tag);
			}
		}
	}

	const showBlock = keepIfEmpty || finalLines.length >= 2;
	let newWikitext = showBlock ? `${openTag}\n${finalLines.join('\n')}\n}}` : finalLines.join('\n');

	if (newWikitext) {
		cleanedContent = `${newWikitext}\n${cleanedContent}`;
	}

	return {
		content: cleanedContent.trim(),
		finalTags: finalLines
	};
},
		
		addProgressLog(tag, action) {
			this.progressText = `"${tag} şablonu" ${action}…`;
		},
		
		onPrimaryAction() {
			if (this.currentStep === 0) {
				this.currentStep = 1;
			} else if (this.currentStep === 1) {
				this.onSubmit();
			}
		},
		
		onBack() {
			if (this.currentStep > 0) this.currentStep--;
		},
		
		async onSubmit() {
		this.status = 'sending';
		if (this.selectedMode === 'update') {
			this.progressText = 'Şablonlar yenilənir…';
		
			const response = await api.get({
				action: 'query',
				prop: 'revisions',
				titles: pageTitle,
				rvprop: 'content',
				format: 'json',
				formatversion: 2
			});
		
			let content = (
				response.query &&
				response.query.pages &&
				response.query.pages[0] &&
				response.query.pages[0].revisions &&
				response.query.pages[0].revisions[0] &&
				response.query.pages[0].revisions[0].content
			) || '';
		
			const now = new Date();
			const monthYear = `${this.monthNames[now.getMonth()]} ${now.getFullYear()}`;
		
			for (const tag of this.selectedTags.filter(t => this.existingTags.includes(t))) {
				this.addProgressLog(tag, 'çıxarılır');
				await new Promise(r => setTimeout(r, 250));
			
				const aliases = (this.aliasMap && this.aliasMap[tag]) ? this.aliasMap[tag] : [tag];
				for (const alias of aliases) {
					const regex = new RegExp(`\\s*{{\\s*${alias}(\\|[^}]*)?}}\\s*\\n?`, 'gi');
					content = content.replace(regex, '');
				}
			}
			
			const addedTags = this.selectedTags.filter(t => !this.existingTags.includes(t));
			
			for (const tag of addedTags) {
				this.addProgressLog(tag, 'əlavə edilir');
				await new Promise(r => setTimeout(r, 250));
			}
			
			let technicalTags = [];
			if (
				tagList['Formatlaşdırma və vikiləşdirmə'] &&
				tagList['Formatlaşdırma və vikiləşdirmə']['Texniki']
			) {
				technicalTags = tagList['Formatlaşdırma və vikiləşdirmə']['Texniki'].map(t => t.tag);
			}
			
			const problemTagsToAdd = addedTags.filter(tag => !technicalTags.includes(tag));
			const nonProblemTagsToAdd = addedTags.filter(tag => technicalTags.includes(tag));
			
			for (const tag of [...this.existingTags, ...addedTags]) {
				const aliases = this.aliasMap?.[tag] || [tag];
				for (const alias of aliases) {
					const regex = new RegExp(`\\s*{{\\s*${alias}(\\|[^}]*)?}}\\s*\\n?`, 'gi');
					content = content.replace(regex, '');
				}
			}
			
			const { content: updatedContent } = this.updateProblemBox(
				content,
				this.wrapInBox ? problemTagsToAdd : [],
				[],
				monthYear
			);
			content = updatedContent;
			
			if (!this.wrapInBox && problemTagsToAdd.length) {
				content = `${problemTagsToAdd.map(t => `{{${t}|tarix=${monthYear}}}`).join('\n')}\n` + content;
			}
			if (nonProblemTagsToAdd.length) {
				content = `${nonProblemTagsToAdd.map(t => `{{${t}|tarix=${monthYear}}}`).join('\n')}\n` + content;
			}
		
			const removedTags = this.selectedTags.filter(t => this.existingTags.includes(t));
			
			const linkify = tag => `{{[[Şablon:${tag}|${tag}]]}}`;
			const removedLinked = removedTags.map(linkify);
			const addedLinked = addedTags.map(linkify);
			
			const joinTags = arr => {
				if (arr.length === 1) return arr[0];
				if (arr.length === 2) return `${arr[0]} və ${arr[1]}`;
				return arr.slice(0, -1).join(', ') + ' və ' + arr.slice(-1);
			};
			
			let summaryParts = [];
			if (removedLinked.length) summaryParts.push(`${joinTags(removedLinked)} çıxarıldı`);
			if (addedLinked.length) summaryParts.push(`${joinTags(addedLinked)} əlavə edildi`);
			const summaryText = summaryParts.join(', ') + '.';
			
			await api.postWithEditToken({
				action: 'edit',
				title: pageTitle,
				text: content,
				summary: summaryText,
				format: 'json'
			});
		
			this.status = 'done';
			setTimeout(() => location.reload(), 2000);
			return;
		}
		
		if (this.selectedMode === 'remove') {
			this.progressText = 'Şablonlar çıxarılır…';
		
			const response = await api.get({
				action: 'query',
				prop: 'revisions',
				titles: pageTitle,
				rvprop: 'content',
				format: 'json',
				formatversion: 2
			});
		
			let content = (
				response.query &&
				response.query.pages &&
				response.query.pages[0] &&
				response.query.pages[0].revisions &&
				response.query.pages[0].revisions[0] &&
				response.query.pages[0].revisions[0].content
			) || '';
		
			for (const tag of this.selectedTags) {
				this.addProgressLog(tag, 'çıxarılır');
				await new Promise(r => setTimeout(r, 250));
			}
		
			let technicalTags = [];
			if (
				tagList['Formatlaşdırma və vikiləşdirmə'] &&
				tagList['Formatlaşdırma və vikiləşdirmə']['Texniki']
			) {
				technicalTags = tagList['Formatlaşdırma və vikiləşdirmə']['Texniki'].map(t => t.tag);
			}
		
			const problemTagsToRemove = this.selectedTags.filter(tag => !technicalTags.includes(tag));
			const nonProblemTagsToRemove = this.selectedTags.filter(tag => technicalTags.includes(tag));
		
			for (const tag of this.selectedTags) {
				const aliases = this.aliasMap?.[tag] || [tag];
				for (const alias of aliases) {
					const regex = new RegExp(`\\s*{{\\s*${alias}(\\|[^}]*)?}}\\s*\\n?`, 'gi');
					content = content.replace(regex, '');
				}
			}
		
			const { content: updatedContent } = this.updateProblemBox(
				content,
				[],
				problemTagsToRemove,
				'',
				false
			);
			content = updatedContent;
		
			const linked = this.selectedTags.map(tag =>
				`{{[[Şablon:${tag}|${tag}]]}}`
			);
		
			let summaryText = '';
			if (linked.length === 1) {
				summaryText = `${linked[0]} çıxarıldı.`;
			} else if (linked.length === 2) {
				summaryText = `${linked[0]} və ${linked[1]} çıxarıldı.`;
			} else {
				summaryText = linked.slice(0, -1).join(', ') + ' və ' + linked.slice(-1) + ' çıxarıldı.';
			}
		
			await api.postWithEditToken({
				action: 'edit',
				title: pageTitle,
				text: content,
				summary: summaryText,
				format: 'json'
			});
		
			this.status = 'done';
			setTimeout(() => location.reload(), 2000);
			return;
		}
		
			if (this.selectedMode === 'add') {
				const now = new Date();
				const monthYear = `${this.monthNames[now.getMonth()]} ${now.getFullYear()}`;
			
				const response = await api.get({
					action: 'query',
					prop: 'revisions',
					titles: pageTitle,
					rvprop: 'content',
					format: 'json',
					formatversion: 2
				});
			
				let content = (
					response.query &&
					response.query.pages &&
					response.query.pages[0] &&
					response.query.pages[0].revisions &&
					response.query.pages[0].revisions[0] &&
					response.query.pages[0].revisions[0].content
				) || '';
			
				const newTags = this.selectedTags.filter(t => {
					const regex = new RegExp(`{{\\s*${t}\\b`, 'i');
					return !regex.test(content);
				});
			
				if (newTags.length === 0) {
					this.progressText = 'Seçilmiş şablonlar artıq mövcuddur!';
					setTimeout(() => { this.status = 'form'; }, 2500);
					return;
				}
			
				for (const tag of newTags) {
					this.addProgressLog(tag, 'əlavə edilir');
					await new Promise(r => setTimeout(r, 250));
				}
			
				let technicalTags = [];
				if (
					tagList['Formatlaşdırma və vikiləşdirmə'] &&
					tagList['Formatlaşdırma və vikiləşdirmə']['Texniki']
				) {
					technicalTags = tagList['Formatlaşdırma və vikiləşdirmə']['Texniki'].map(t => t.tag);
				}
			
				const problemTagsToAdd = newTags.filter(t => !technicalTags.includes(t));
				const nonProblemTagsToAdd = newTags.filter(t => technicalTags.includes(t));
			
				const { content: updatedContent } = this.updateProblemBox(
					content,
					this.wrapInBox ? problemTagsToAdd : [],
					[],
					monthYear
				);
				content = updatedContent;
			
				const prependLines = [];
			
				if (!this.wrapInBox && problemTagsToAdd.length > 0) {
					prependLines.push(...problemTagsToAdd.map(t => `{{${t}|tarix=${monthYear}}}`));
				}
			
				if (nonProblemTagsToAdd.length > 0) {
					prependLines.push(...nonProblemTagsToAdd.map(t => `{{${t}|tarix=${monthYear}}}`));
				}
			
				if (prependLines.length > 0) {
					content = `${prependLines.join('\n')}\n${content}`;
				}
			
				const linked = newTags.map(tag => `{{[[Şablon:${tag}|${tag}]]}}`);
				let summaryText = '';
				if (linked.length === 1) {
					summaryText = `${linked[0]} əlavə edildi.`;
				} else if (linked.length === 2) {
					summaryText = `${linked[0]} və ${linked[1]} əlavə edildi.`;
				} else {
					summaryText = linked.slice(0, -1).join(', ') + ' və ' + linked.slice(-1) + ' əlavə edildi.';
				}
			
				await api.postWithEditToken({
					action: 'edit',
					title: pageTitle,
					text: content,
					summary: summaryText,
					format: 'json'
				});
			
				this.status = 'done';
				setTimeout(() => location.reload(), 2000);
				return;
			}
		}
	},
		template: `
		<cdx-dialog
			v-model:open="dialogShown"
			title="Şablon əlavə et"
			:subtitle="''"
			use-close-button
			close-button-label="Bağla"
			:primary-action="status === 'form' ? {
				label:
					selectedMode === 'remove'
						? (selectedTags.length === 1 ? 'Şablonu çıxar' : 'Şablonları çıxar')
						: selectedMode === 'add'
							? 'Əlavə et'
							: 'Yenilə',
				actionType:
					selectedMode === 'remove'
						? 'destructive'
						: selectedMode === 'add'
							? 'progressive'
							: 'default',
				disabled: selectedTags.length === 0
			} : undefined"
			@primary="onPrimaryAction"
		>
			<template #default>
				<div v-if="currentStep === 0" style="padding-top: 0.5em;">
					<cdx-tabs v-model="activeTab">
						<cdx-tab
							v-for="tab in tabsData"
							:key="tab.name"
							:name="tab.name"
							:label="tab.label"
						>
							<div v-if="tab.name === 'remove'">
								<div style="margin: 1em 0;">
									<cdx-field :is-fieldset="true" v-if="existingTagList.length">
										<cdx-checkbox
											v-for="tag in existingTagList"
											:key="'existing-' + tag.tag"
											v-model="selectedTags"
											:input-value="tag.tag"
										>
											{{ tag.tag }} – {{ tag.description }}
										</cdx-checkbox>
									</cdx-field>
									<p v-else style="padding: 1em; font-style: italic; color: #555;">
										Səhifədə yerləşdirilmiş bildiriş şablonu tapılmadı.
									</p>
								</div>
							</div>
					
							<div v-else>
								<cdx-search-input
									v-model="searchQuery"
									aria-label="Şablon axtar"
									placeholder="Şablon və ya təsvir axtar…"
									style="margin: 0.75em 0 1em; width: 100%;"
								/>
					
								<div v-for="(groups, categoryName) in filteredTagList" :key="categoryName">
									<h4>{{ categoryName }}</h4>
									<cdx-field :is-fieldset="true">
										<cdx-checkbox
											v-for="tag in Object.values(groups).flat()"
											:key="tag.tag"
											v-model="selectedTags"
											:input-value="tag.tag"
											:disabled="existingTags.includes(tag.tag)"
										>
											<span v-html="highlightedText(tag.tag)"></span> – <span v-html="highlightedText(tag.description)"></span>
										</cdx-checkbox>
									</cdx-field>
								</div>
							</div>
						</cdx-tab>
					</cdx-tabs>
				</div>
				
				<div v-else-if="currentStep===1" style="padding:1em 1.5em; font-size:90%;">
				  <div v-if="selectedTags.filter(t => !existingTags.includes(t)).length">
				    <p><strong>Əlavə olunacaq şablonlar:</strong></p>
				    <ul>
				      <li v-for="tag in selectedTags.filter(t => !existingTags.includes(t))" :key="tag">
				        {{ tag }}
				      </li>
				    </ul>
				  </div>
				
				  <div v-if="selectedTags.filter(t => existingTags.includes(t)).length">
				    <p><strong>Silinəcək şablonlar:</strong></p>
				    <ul>
				      <li v-for="tag in selectedTags.filter(t => existingTags.includes(t))" :key="tag">
				        {{ tag }}
				      </li>
				    </ul>
				  </div>
				
					<cdx-toggle-switch
					  v-if="showWrapToggle"
					  v-model="wrapInBox"
					  style="margin:1em 0;"
					>
					  Şablonları Məqalə problemləri daxilində yerləşdir
					  <template #description>Bu seçim yalnız uyğun şablonlara tətbiq olunacaq.</template>
					</cdx-toggle-switch>
				</div>
				
				<div v-else style="padding: 1em 1.5em; font-size: 90%;">
					<div class="cdx-progress-indicator">
						<div class="cdx-progress-indicator__indicator">
							<progress
								class="cdx-progress-indicator__indicator__progress"
								id="cdx-template-progress"
								v-if="status === 'sending'"
							></progress>
						</div>
						<div class="cdx-label cdx-progress-indicator__label">
							<label class="cdx-label__label" for="cdx-template-progress">
								<span class="cdx-label__label__text">
									{{ status === 'sending' ? progressText : (selectedMode === 'remove' ? 'Şablonlar çıxarıldı!' : (selectedMode === 'update' ? 'Şablonlar yeniləndi!' : 'Şablonlar əlavə olundu!')) }}
								</span>
							</label>
						</div>
					</div>
				</div>
			</template>
			
			<template #footer>
				<div
				  :style="{
				    display: 'flex',
				    justifyContent: currentStep===0 ? 'flex-end' : 'space-between',
				    alignItems: 'center',
				    width: '100%'
				  }"
				>
					<div style="display: flex; gap: 0.5em;">
						<cdx-button v-if="currentStep > 0" @click="onBack">Geri</cdx-button>
						<cdx-button
							:action="currentStep === 1 ? 'progressive' : 'default'"
							:weight="currentStep === 1 ? 'primary' : 'default'"
							:disabled="currentStep === 0 && selectedTags.length === 0"
							@click="onPrimaryAction"
						>
							{{ currentStep === 0 ? 'Davam et' : 'Təsdiqlə və tətbiq et' }}
						</cdx-button>
					</div>
				</div>
			</template>
			
		</cdx-dialog>
		`,
		mounted() {
			portletLink.addEventListener('click', this.toggleDialog);
		},
		unmounted() {
			portletLink.removeEventListener('click', this.toggleDialog);
		}
	};
	
	const root = document.createElement('div');
	document.body.appendChild(root);
	
	createMwApp({
	  render: () => h(App)
	})
	  .component('cdx-dialog',       CdxDialog)
	  .component('cdx-checkbox',     CdxCheckbox)
	  .component('cdx-field',        CdxField)
	  .component('cdx-search-input', CdxSearchInput)
	  .component('cdx-tabs',         CdxTabs)
	  .component('cdx-tab',          CdxTab)
	  .component('cdx-button',       CdxButton)
	  .component('cdx-toggle-switch',CdxToggleSwitch)
	  .mount(root);
});

/* </nowiki> */
Mənbə — "https://az.wikipedia.org/w/index.php?title=İstifadəçi:Toghrul_R/tag.js&oldid=8213344"
Informasiya Melumat Axtar