|
|
| (11 גרסאות ביניים של אותו משתמש אינן מוצגות) |
| שורה 1: |
שורה 1: |
| // ==UserScript== // @name בודק קישורים // @description מציג אזהרות על קישורים בעייתיים בעריכת קוד מקור (פירושונים, הפניות, ערכים חסרים) // @version 1.0 // @match https://chabadpedia.co.il/* // @grant none // ==/UserScript==
| |
|
| |
|
| (function () { if (!['edit', 'submit'].includes(mw.config.get('wgAction'))) return; const textbox = document.getElementById('wpTextbox1'); if (!textbox) return;
| |
|
| |
| const linkRegex = /)/g; const linkPositions = []; const linkCache = new Set(); let match;
| |
|
| |
| while ((match = linkRegex.exec(textbox.value)) !== null) { const start = match.index; const end = start + match[0].length; const fullLink = match[1].trim(); const target = fullLink.split('#')[0].split('/')[0]; if (linkCache.has(target)) continue; linkCache.add(target); linkPositions.push({ start, end, full: match[0], target }); }
| |
|
| |
| linkPositions.forEach(({ target }) => checkLink(target));
| |
|
| |
| function checkLink(title) { const url = /w/api.php?action=query&format=json&titles=${encodeURIComponent(title)}&redirects=1&origin=*; fetch(url).then(r => r.json()).then(data => { const pages = data.query.pages; const pageId = Object.keys(pages)[0]; const page = pages[pageId]; const realTitle = page?.title || title;
| |
|
| |
| if (pageId === '-1') {
| |
| showPopup(title, '🔴 דף זה אינו קיים.', 'red');
| |
| } else if (realTitle.includes('(פירושונים)')) {
| |
| fetchPiros(title);
| |
| } else if (title !== realTitle) {
| |
| showPopup(title, `🔵 הפניה ל־[[${realTitle}]]`, 'lightblue', realTitle);
| |
| }
| |
| });
| |
|
| |
| }
| |
|
| |
| function fetchPiros(title) { const url = /w/api.php?action=parse&format=json&page=${encodeURIComponent(title)}&origin=*; fetch(url).then(r => r.json()).then(data => { const html = data.parse.text['*']; const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const links = [...doc.querySelectorAll('ul li a')] .map(a => a.title) .filter(t => t && !t.includes('(פירושונים)'));
| |
|
| |
| showPopup(title, '🟡 דף פירושונים: בחר פירוש מתאים:', 'gold', null, links);
| |
| });
| |
|
| |
| }
| |
|
| |
| function showPopup(originalTitle, message, color, replaceTo = null, options = []) { const marker = document.createElement('span'); marker.textContent = '⧉'; marker.style.cursor = 'pointer'; marker.style.marginLeft = '4px'; marker.style.color = color;
| |
|
| |
| const popup = document.createElement('div');
| |
| popup.style.position = 'absolute';
| |
| popup.style.background = color;
| |
| popup.style.border = '1px solid black';
| |
| popup.style.padding = '6px';
| |
| popup.style.zIndex = 9999;
| |
| popup.style.maxWidth = '240px';
| |
| popup.style.fontSize = '90%';
| |
| popup.textContent = message;
| |
|
| |
| if (replaceTo) {
| |
| const btn = document.createElement('button');
| |
| btn.textContent = 'החלף ליעד';
| |
| btn.onclick = () => {
| |
| replaceAllLinks(originalTitle, replaceTo);
| |
| popup.remove();
| |
| };
| |
| popup.appendChild(document.createElement('br'));
| |
| popup.appendChild(btn);
| |
| }
| |
|
| |
| if (options.length) {
| |
| options.slice(0, 5).forEach(opt => {
| |
| const btn = document.createElement('button');
| |
| btn.textContent = 'בחר ב־' + opt;
| |
| btn.style.display = 'block';
| |
| btn.style.marginTop = '4px';
| |
| btn.onclick = () => {
| |
| replaceAllLinks(originalTitle, opt);
| |
| popup.remove();
| |
| };
| |
| popup.appendChild(btn);
| |
| });
| |
| }
| |
|
| |
| const skipBtn = document.createElement('button');
| |
| skipBtn.textContent = 'דלג';
| |
| skipBtn.style.marginTop = '4px';
| |
| skipBtn.onclick = () => popup.remove();
| |
| popup.appendChild(document.createElement('br'));
| |
| popup.appendChild(skipBtn);
| |
|
| |
| marker.onclick = (e) => {
| |
| popup.style.left = e.pageX + 'px';
| |
| popup.style.top = e.pageY + 'px';
| |
| document.body.appendChild(popup);
| |
| };
| |
|
| |
| // הוספה ליד כל מופע
| |
| const lines = textbox.value.split('\n');
| |
| const newLines = lines.map(line =>
| |
| line.replace(new RegExp(`(${escapeRegex(originalTitle)})([\|])`, 'g'),
| |
| (m, p1, p2) => `[[${p1}${p2}<span class="link-marker" data-title="${originalTitle}"></span>`)
| |
| );
| |
| textbox.value = newLines.join('\n');
| |
|
| |
| setTimeout(() => {
| |
| const spans = document.querySelectorAll('.link-marker[data-title="' + originalTitle + '"]');
| |
| spans.forEach(span => span.replaceWith(marker.cloneNode(true)));
| |
| }, 100);
| |
|
| |
| }
| |
|
| |
| function replaceAllLinks(from, to) { const re = new RegExp(${escapeRegex(from)}(\||), 'g'); textbox.value = textbox.value.replace(re, [[${to}$1); }
| |
|
| |
| function escapeRegex(s) { return s.replace(/[.*+?^${}()|[/g, '\$&'); } })();
| |