MediaWiki:Common.js: differenze tra le versioni
Nessun oggetto della modifica Etichetta: Annullato |
Nessun oggetto della modifica Etichetta: Annullato |
||
| Riga 1 040: | Riga 1 040: | ||
setTimeout(attachInviteButtons, 3000); | setTimeout(attachInviteButtons, 3000); | ||
setTimeout(attachInviteButtons, 6000); | setTimeout(attachInviteButtons, 6000); | ||
}); | |||
}); | |||
// === SCIENTIFIC COMMUNITY DECISION HANDLING === | |||
document.addEventListener("click", function (e) { | |||
if (!e.target.classList.contains("sc-com-button")) return; | |||
const decision = e.target.dataset.decision; | |||
const name = document.getElementById("sc_name")?.value || ""; | |||
const linkedin = document.getElementById("sc_linkedin")?.value || ""; | |||
const notes = document.getElementById("sc_notes")?.value || ""; | |||
if (!name) { | |||
alert("Please enter your full name before submitting."); | |||
return; | |||
} | |||
fetch("/MESB/community_decision_api.php", { | |||
method: "POST", | |||
headers: { "Content-Type": "application/x-www-form-urlencoded" }, | |||
body: | |||
`name=${encodeURIComponent(name)}` + | |||
`&linkedin_url=${encodeURIComponent(linkedin)}` + | |||
`&decision=${encodeURIComponent(decision)}` + | |||
`¬es=${encodeURIComponent(notes)}` | |||
}) | |||
.then(r => r.json()) | |||
.then(res => { | |||
if (res.status === 'ok') { | |||
alert("Thank you! Your decision has been recorded."); | |||
location.reload(); | |||
} else { | |||
alert("Error: " + res.msg); | |||
} | |||
}); | }); | ||
}); | }); | ||
Versione delle 12:25, 1 dic 2025
/* === DEBUG: chi richiama CommonDashboard.js === */
(function(){
// Traccia TUTTE le importScript(...)
const origImport = window.importScript;
if (typeof origImport === 'function') {
window.importScript = function(page){
if (String(page).trim() === 'MediaWiki:CommonDashboard.js') {
console.group('TRACE importScript → CommonDashboard.js');
console.log('page:', page);
console.trace('Call stack (importScript)');
console.groupEnd();
}
return origImport.apply(this, arguments);
};
}
// Traccia qualsiasi <script src=...CommonDashboard.js> iniettato nel DOM
const origAppend = Element.prototype.appendChild;
Element.prototype.appendChild = function(node){
if (node && node.tagName === 'SCRIPT' && typeof node.src === 'string' &&
node.src.includes('MediaWiki:CommonDashboard.js')) {
console.group('TRACE appendChild → <script src=CommonDashboard.js>');
console.log('SRC:', node.src);
console.trace('Append stack');
console.groupEnd();
}
return origAppend.call(this, node);
};
})();
// LOGGA chi inserisce <script src=...CommonDashboard.js> nel DOM
(function(){
const origAppend = Element.prototype.appendChild;
Element.prototype.appendChild = function(node){
try {
if (node && node.tagName === 'SCRIPT' && typeof node.src === 'string' &&
node.src.includes('MediaWiki:CommonDashboard.js')) {
console.group('TRACE appendChild → <script src=CommonDashboard.js>');
console.log('SRC:', node.src);
console.trace('Append stack');
console.groupEnd();
}
} catch(e){}
return origAppend.call(this, node);
};
})();
console.log("✅ Common.js è attivo");
if (mw.config.get('wgPageName') === 'Dashboard_Masticationpedia') {
mw.loader.load('/index.php?title=MediaWiki:CommonDashboard.js'
+ '&action=raw&ctype=text/javascript&maxage=0&smaxage=0'
+ '&from=commonjs' // <— etichetta
+ '&nocache=' + Date.now());
}
/* ====================== Language in Home page Linkedin =================*/
document.addEventListener("DOMContentLoaded", function () {
var trigger = document.querySelector(".language-trigger");
var dropdown = document.querySelector(".language-dropdown");
if (trigger && dropdown) {
trigger.addEventListener("click", function () {
dropdown.classList.toggle("open");
});
}
});
/* ======================= PULSANTE PURGE ======================= */
mw.loader.using('mediawiki.util').then(function () {if (mw.config.get('wgUserName'))
setTimeout(function () {
let menuAzioni = document.getElementById('p-cactions');
if (menuAzioni && !document.getElementById('ca-purge')) {
mw.util.addPortletLink(
'p-cactions',
mw.config.get('wgScript') + '?title=' + mw.config.get('wgPageName') + '&action=purge',
'🔄 Purga',
'ca-purge',
'Pulisci la cache della pagina'
);
console.log("✅ Pulsante 'Purge' aggiunto con successo!");
}
}, 2000);
});
/* ======================= PULSANTE SCROLL TO TOP (Sempre visibile) ======================= */
mw.loader.using('mediawiki.util').then(function () {
mw.hook('wikipage.content').add(function () {
if (!document.getElementById("go-to-top")) {
let goToTopBtn = document.createElement("button");
goToTopBtn.id = "go-to-top";
goToTopBtn.innerText = "⬆️ TOP";
goToTopBtn.style.position = "fixed";
goToTopBtn.style.bottom = "50px";
goToTopBtn.style.right = "20px";
goToTopBtn.style.background = "#3498db";
goToTopBtn.style.color = "#fff";
goToTopBtn.style.border = "none";
goToTopBtn.style.padding = "10px";
goToTopBtn.style.cursor = "pointer";
goToTopBtn.style.borderRadius = "5px";
goToTopBtn.style.zIndex = "1000";
goToTopBtn.style.display = "none";
document.body.appendChild(goToTopBtn);
window.addEventListener("scroll", function () {
goToTopBtn.style.display = window.scrollY > 200 ? "block" : "none";
});
goToTopBtn.addEventListener("click", function () {
window.scrollTo({ top: 0, behavior: "smooth" });
});
console.log("✅ Pulsante Scroll-to-Top aggiunto!");
}
});
});
/* ======================= PULSANTE SCROLL BACK TO LAST POSITION ======================= */
// 1. Crea il bottone dinamicamente
var scrollBackBtn = document.createElement("button");
scrollBackBtn.id = "scroll-back-btn";
scrollBackBtn.innerHTML = "🔙 TORNA";
scrollBackBtn.style.display = "none";
scrollBackBtn.style.position = "fixed";
scrollBackBtn.style.bottom = "6em";
scrollBackBtn.style.right = "1em";
scrollBackBtn.style.padding = "10px 16px";
scrollBackBtn.style.border = "none";
scrollBackBtn.style.borderRadius = "10px";
scrollBackBtn.style.backgroundColor = "#007bff";
scrollBackBtn.style.color = "white";
scrollBackBtn.style.fontSize = "16px";
scrollBackBtn.style.cursor = "pointer";
scrollBackBtn.style.zIndex = "999";
document.body.appendChild(scrollBackBtn);
// 2. Ricorda l'ultima posizione prima di cliccare su una citazione
var lastScrollPosition = null;
// Quando clicchi su un link <sup> come [1], [2], ecc.
document.addEventListener('click', function(e) {
if (e.target.closest('sup')) {
lastScrollPosition = window.scrollY;
}
});
// 3. Quando sei nella bibliografia, mostra il bottone "Torna"
window.addEventListener('scroll', function() {
if (lastScrollPosition !== null && window.scrollY > 500) {
document.getElementById('scroll-back-btn').style.display = 'block';
} else {
document.getElementById('scroll-back-btn').style.display = 'none';
}
});
// 4. Cosa fa il bottone se cliccato
document.getElementById('scroll-back-btn').addEventListener('click', function() {
if (lastScrollPosition !== null) {
window.scrollTo({ top: lastScrollPosition, behavior: 'smooth' });
}
});
/* ======================= AGGIUNGE I PULSANTI NEI TOOLS ======================= */
mw.loader.using('mediawiki.util').then(function () {
function aggiungiAiTools(id, label, action) {
let toolsMenu = document.getElementById("p-tb");
if (!toolsMenu) {
console.warn("⚠️ Menu 'Tools' non trovato!");
return;
}
// Rimuove il pulsante dalla pagina, se esiste già
let button = document.getElementById(id);
if (button) {
button.remove();
}
// Crea il link nei Tools
if (!document.getElementById(id + "-tools")) {
let newItem = document.createElement("li");
let link = document.createElement("a");
link.href = "#";
link.id = id + "-tools";
link.textContent = label;
link.addEventListener("click", function (e) {
e.preventDefault();
$.ajax({
url: action,
dataType: "script",
cache: false,
success: function () {
console.log(`✅ Script ${action} caricato ed eseguito.`);
// Avvia la funzione giusta in base al pulsante cliccato
if (id === "traduci-contenuto") {
if (typeof traduciTesto === "function") {
traduciTesto();
} else {
console.error("❌ Errore: traduciTesto non è definita.");
}
} else if (id === "translate-update") {
if (typeof traduciTestoUpdate === "function") {
traduciTestoUpdate();
} else {
console.error("❌ Errore: traduciTestoUpdate non è definita.");
}
} else if (id === "reload-js") {
location.reload(); // Ricarica la pagina
}
},
error: function () {
console.error(`❌ Errore nel caricamento di ${action}`);
}
});
});
newItem.appendChild(link);
toolsMenu.querySelector("ul").appendChild(newItem);
console.log(`✅ Pulsante "${label}" aggiunto nei Tools!`);
}
}
// ✅ Aggiunge i pulsanti SEMPRE nei Tools
setTimeout(function () {
aggiungiAiTools("traduci-contenuto", "🌍 Traduci contenuto", "/index.php?title=MediaWiki:CommonTranslate.js&action=raw&ctype=text/javascript");
aggiungiAiTools("translate-update", "🔄 Aggiorna Traduzione", "/index.php?title=MediaWiki:CommonTranslateUpdate.js&action=raw&ctype=text/javascript");
aggiungiAiTools("reload-js", "♻️ Ricarica JS", "/index.php?title=MediaWiki:Common.js&action=raw&ctype=text/javascript");
}, 2000);
});
/* ======================= NASCONDE I PULSANTI DALLA PAGINA ======================= */
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll("#traduci-contenuto-button, #translate-update-button").forEach(btn => btn.style.display = "none");
});
/* ======================= IMPORTA CommonTranslate.js ======================= */
/* importScript('MediaWiki:CommonTranslateUpdate.js');*/
mw.loader.load('/index.php?title=MediaWiki:CommonTranslateUpdate.js&action=raw&ctype=text/javascript');
// Carica Merriweather da Google Fonts
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://fonts.googleapis.com/css2?family=Merriweather&display=swap';
document.head.appendChild(link);
/* ======================= IMPORTA CitationPopup.js======================= */
/* ============ ESPANSIONE DINAMICA INLINE ================= */
// Inietta stile CSS
/*mw.loader.using('mediawiki.util').then(function () {
const style = document.createElement('style');
style.textContent = `
.expandible-block {
margin: 12px 0;
font-size: 95%;
}
.expand-trigger {
cursor: pointer;
color: #3366cc;
font-weight: bold;
display: inline-block;
}
.expand-content {
display: none;
margin-top: 8px;
padding: 10px;
background-color: #f8f8f8;
border: 1px solid #ccc;
border-radius: 8px;
}
.expandible-block.active .expand-content {
display: block;
}
`;
document.head.appendChild(style);
// Aggiunge interazione
document.querySelectorAll('.expandible-block .expand-trigger').forEach(trigger => {
trigger.addEventListener('click', function () {
const container = this.closest('.expandible-block');
container.classList.toggle('active');
});
});
});
function toggleExpandable(trigger) {
const content = trigger.nextElementSibling;
if (content && content.classList.contains("expandable-content")) {
content.style.display = (content.style.display === "none" || content.style.display === "") ? "block" : "none";
}
}
*/
/* ========= TRANSCLUSIONE ==========*/
window.caricaTranscluso = function(boxID, trigger) {
const containerID = 'contenuto-' + boxID;
const container = document.getElementById(containerID);
if (container.style.display === 'block') {
container.style.display = 'none';
return;
}
container.innerHTML = '⌛ Caricamento...';
container.style.display = 'block';
fetch('/mediawiki/index.php?title=Transcluso:' + boxID + '&action=render')
.then(res => res.text())
.then(html => {
container.innerHTML = html;
})
.catch(err => {
container.innerHTML = '<span style="color:red;">⚠ Errore nel caricamento.</span>';
console.error(err);
});
};
/* ===================== Differential Diagnostic protocol =========== */
// MediaWiki:Common.js
// Carica lo script CommonDDP.js SOLO quando si apre la pagina "Differential Diagnostic Protocol"
if (mw.config.get("wgPageName") === "Differential_Diagnostic_Protocol") {
importScript("MediaWiki:CommonDDP.js");
}
(function () {
// 1) Mappa titolo pagina → codice lingua (tutte le chiavi tra virgolette)
var langMap = {
'Main_Page': 'en', // Home in inglese
'Pagina_principale': 'it', // Home in italiano
'Page_d%27accueil': 'fr', // Home in francese (apostrofo codificato %27)
'Hauptseite': 'de', // Home in tedesco
'P%C3%A1gina_principal': 'es' // Home in spagnolo (accento percent-encoded)
};
var page = mw.config.get('wgPageName');
if ( !langMap.hasOwnProperty(page) ) return; // non siamo in home
// importa CSS e JS esterni
mw.loader.load('https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css');
mw.loader.load('https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js');
mw.loader.using('jquery', function () {
window.addEventListener('load', function() {
if (!window.cookieconsent) return;
var lang = langMap[page];
var texts = {
it: { message: 'Utilizziamo cookie essenziali, analitici e di marketing per migliorare il sito.', dismiss:'Accetto tutti', deny:'Solo essenziali', link:'Cookie Policy' },
en: { message: 'We use essential, analytics and marketing cookies to improve the site.', dismiss:'Accept all', deny:'Essential only', link:'Cookie Policy' },
fr: { message: 'Nous utilisons des cookies essentiels, analytiques et marketing pour améliorer le site.', dismiss:'Tout accepter', deny:'Seulement essentiels', link:'Politique de cookies' },
de: { message: 'Wir verwenden notwendige, analytische und Marketing-Cookies, um die Website zu verbessern.', dismiss:'Alle akzeptieren', deny:'Nur notwendige', link:'Cookie-Richtlinie' },
es: { message: 'Utilizamos cookies esenciales, analíticas y de marketing para mejorar el sitio.', dismiss:'Aceptar todo', deny:'Solo esenciales', link:'Política de cookies' }
};
var c = texts[lang];
window.cookieconsent.initialise({
palette: {
popup: { background: '#343a40', text: '#ffffff' },
button: { background: '#007BFF', text: '#ffffff' }
},
theme: 'classic',
content: {
message: c.message,
dismiss: c.dismiss,
deny: c.deny,
link: c.link,
href: mw.util.getUrl('Cookie_Policy')
},
revocable: true,
type: 'opt-in'
});
});
});
})();
/* ============= Scroll =====*/
document.addEventListener("DOMContentLoaded", function () {
var toggle = document.querySelector('.scroll-toggle');
var dropdown = document.querySelector('.scroll-dropdown');
if (toggle && dropdown) {
toggle.addEventListener('click', function () {
dropdown.classList.toggle('active');
});
}
});
// su tutti i link rimuovo il title…
$('a').not('.book-index-link').removeAttr('title');
// …ma lascio il title sul Book Index
function toggleHeroMenu() {
var menu = document.getElementById("heroMenu");
if (!menu) return;
if (menu.style.display === "block") {
menu.style.display = "none";
} else {
menu.style.display = "block";
}
}
mw.hook('wikipage.content').add(function () {
var burger = document.querySelector('.hamburger-icon');
var menu = document.getElementById('heroMenu');
if (burger && menu) {
burger.addEventListener('click', function () {
const isVisible = menu.style.display === 'block';
menu.style.display = isVisible ? 'none' : 'block';
});
}
});
console.log("✅ Bottone menu cliccato");
document.addEventListener('DOMContentLoaded', function () {
var lang = mw.config.get('wgUserLanguage') || 'en';
var langMap = {
'it': 'Registrazione_LinkedIn',
'en': 'Subscribe_LinkedIn',
'fr': 'Inscription_LinkedIn',
'de': 'Registrieren_LinkedIn',
'es': 'Suscripcion_LinkedIn'
};
var targetPage = langMap[lang] || 'Subscribe_LinkedIn';
var expertBtn = document.querySelector('.cta-button-expert');
if (expertBtn) {
expertBtn.setAttribute('href', '/wiki/Masticationpedia:' + targetPage);
}
});
// Aggiunge il footer personalizzato nella homepage
$(document).ready(function () {
if (mw.config.get('wgPageName') === 'Main_Page') {
var footerHtml = `
<div id="custom-footer" style="margin-top: 40px; font-family: sans-serif; font-size: 14px; color: #555; text-align: center; line-height: 1.6;">
<div>
© 2025 <strong>Masticationpedia</strong> — A nonprofit project in masticatory science.<br>
<em>Founded and curated by Dr. Gianni Frsardi, developed with the support of clinicians, researchers and open science advocates.</em>
</div>
<div style="margin-top: 10px;">
<a href="/wiki/Privacy_policy" style="color:#0077b5; text-decoration:none;">Privacy Policy</a>
•
<a href="/wiki/About_Masticationpedia" style="color:#0077b5; text-decoration:none;">About</a>
•
<a href="/wiki/Disclaimer" style="color:#0077b5; text-decoration:none;">Disclaimer</a>
</div>
</div>
`;
// Inserisce nel footer standard oppure in fondo al body
if ($('#footer').length) {
$('#footer').append(footerHtml);
} else if ($('.mw-footer').length) {
$('.mw-footer').append(footerHtml);
} else {
$('body').append(footerHtml);
}
}
});
// ✅ SSO DEBUG CONSOLE – visibile solo con ?debugsso=1
if (location.search.includes('debugsso=1')) {
const style = document.createElement('style');
style.textContent = `
#sso-debug-console {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: #222;
color: #0f0;
font-size: 12px;
font-family: monospace;
padding: 10px;
max-height: 200px;
overflow-y: auto;
z-index: 9999;
}
`;
document.head.appendChild(style);
const container = document.createElement('div');
container.id = 'sso-debug-console';
document.body.appendChild(container);
function fetchLog() {
fetch('/sso-log.json?ts=' + new Date().getTime())
.then(r => r.ok ? r.json() : [])
.then(data => {
container.innerHTML = '';
data.slice().reverse().forEach(entry => {
const div = document.createElement('div');
div.textContent = `🕓 ${new Date(entry.timestamp * 1000).toLocaleTimeString()} - ${entry.message}`;
container.appendChild(div);
});
});
}
setInterval(fetchLog, 3000);
fetchLog();
}
importScript('MediaWiki:Gadget-LinkedInRequests.js');
// ✅ Aggiunge la classe 'logged-in' se qualsiasi utente è autenticato (MediaWiki o LinkedIn)
$(function () {
if (mw.config.get('wgUserName')) {
document.body.classList.add('logged-in');
}
});
/* ========= Login Linkedin ======*/
/* $(function () {
if (mw.config.get('wgUserName') === null) {
const loginLink = $('a[href*="title=Speciale:Entra"]');
if (loginLink.length) {
loginLink.attr('href', mw.util.getUrl('Special:PluggableAuthLogin'));
loginLink.text('Login con LinkedIn');
}
}
});
*/
// ================= MASCHERAMENTO CONTENUTI =================
/*$(document).ready(function () {
if (!mw.config.get('wgUserName')) {
// Se NON loggato: aggiungi la classe per mascherare
$('.chapter-full').addClass('login-required');
} else {
// Se loggato: togli eventuale mascheramento e banner
$('.chapter-container').removeClass('login-required').show();
$('.login-banner').remove();
}
});
*/
$(document).ready(function () {
if (!mw.config.get('wgUserName')) {
// Se NON loggato: aggiungi la classe per mascherare
$('.chapter-full').addClass('login-required');
} else {
// Se loggato: togli la mascheratura
$('.chapter-full').removeClass('login-required');
$('.login-banner').remove(); // opzionale
}
});
// In MediaWiki:Common.js
if (!mw.config.get('wgUserGroups').includes('sysop')) {
document.querySelectorAll('.blurred-text').forEach(el => {
el.style.opacity = '0.3';
el.style.pointerEvents = 'none';
});
}
// ================= BLOCCO PAGE | DISCUSSION solo nei Capitoli (Minerva) =================
$(document).ready(function () {
if (mw.config.get('skin') !== 'minerva') return;
const pageTitle = mw.config.get('wgPageName');
if (!pageTitle.startsWith('Capitolo:')) return;
if (document.querySelector('.minerva-page-discussion')) return;
const discussionUrl = '/wiki/Discussione:' + encodeURIComponent(pageTitle);
const block = document.createElement('div');
block.className = 'minerva-page-discussion';
block.innerHTML = `
<span>📄 <a href="/wiki/${pageTitle}">Page</a></span> |
<span>💬 <a href="${discussionUrl}">Discussion</a></span>
`;
const content = document.getElementById('content') || document.querySelector('.mw-body');
if (content) {
const abstract = content.querySelector('.abstract, .abstract-section');
if (abstract) {
abstract.parentNode.insertBefore(block, abstract.nextSibling);
} else {
content.insertBefore(block, content.firstChild);
}
}
});
// ================= Accesso e ritorno capitoli (Minerva) =================
document.addEventListener("DOMContentLoaded", function () {
// Rende il pulsante LinkedIn dinamico
const button = document.querySelector(".button-linkedin a");
if (button) {
const currentPage = encodeURIComponent(window.location.pathname);
button.href = `/oauth/linkedin-login.php?returnTo=${currentPage}`;
}
});
// =========== Cancellazione Opacizzazione ==============
mw.loader.using(['mediawiki.user', 'mediawiki.util']).then(function () {
const groupEntry = mw.config.get('wgUserGroups') || [];
if (groupEntry.includes('entry')) {
document.body.classList.add('group-entry');
console.log("✅ Gruppo 'entry' rilevato - classe aggiunta a <body>");
} else {
console.log("ℹ️ Utente non nel gruppo 'entry'");
}
});
/*
// 🔄 Forza la capoccetta a puntare sempre a linkedin-login.php
$(document).ready(function () {
$('a[href*="Special:UserLogin"]').attr('href', '/oauth/linkedin-login.php');
});
*/
// Carica lo script della Dashboard SOLO nel namespace Dashboard
(function () {
var ns = mw.config.get('wgNamespaceNumber'); // es. 3000
var page = mw.config.get('wgPageName'); // es. "Dashboard:Main"
var isDashboard = (ns === 3000) && /^Dashboard:/.test(page);
if (page !== 'Dashboard:Main') return;
// ok, siamo in Dashboard → carico lo script dedicato
importScript('MediaWiki:CommonDashboard.js');
})();
// RICHIESTE LINKEDIN PENDENTI – PANNELLO ADMIN
mw.loader.using( 'mediawiki.util', function () {
jQuery( function ( $ ) {
// Esegui solo nella pagina "RichiesteAccesso_LinkedIn"
if ( mw.config.get( 'wgPageName' ) !== 'RichiesteAccesso_LinkedIn' ) {
return;
}
var $box = $( '#richiesteLinkedIn' );
if ( !$box.length ) {
return;
}
// Chiede a PHP la pagina con la tabella
$.get( '/sso-tools/list_pending.php' )
.done( function ( html ) {
// Sostituisce il "Caricamento richieste..." con la tabella vera
$box.html( html );
} )
.fail( function () {
$box.html( '<p>⚠️ Errore nel caricamento delle richieste LinkedIn.</p>' );
} );
} );
});
/* Pallino di notifica richieste LinkedIn in homepage */
mw.loader.using( 'mediawiki.util', function () {
jQuery(function ( $ ) {
var $wrapper = $('#linkedin-notify-wrapper');
if ( !$wrapper.length ) {
// Se il pallino non è presente nella pagina, non facciamo nulla
return;
}
// 1) Chiede al server quante richieste pendenti ci sono
$.getJSON('/sso-tools/pending_count.php')
.done(function (data) {
if ( data && data.pending && data.pending > 0 ) {
// Ci sono richieste → mostra il pallino lampeggiante
$wrapper.show();
}
})
.fail(function () {
// In caso di errore, teniamo il pallino nascosto
});
// 2) Click sul pallino → porta alla pagina delle richieste
$wrapper.on('click', function () {
window.location.href = '/wiki/RichiesteAccesso_LinkedIn';
});
});
});
/* Link rapido alle richieste LinkedIn nel menu "Strumenti" */
mw.loader.using( [ 'mediawiki.util', 'mediawiki.user' ], function () {
// Gruppi dell'utente (array, NON promise)
var groups = mw.user.getGroups();
// Mostra il link solo agli amministratori (sysop)
if ( groups.indexOf( 'sysop' ) === -1 ) {
return;
}
// Aggiunge "Richieste LinkedIn" nel portlet degli strumenti (p-tb)
mw.util.addPortletLink(
'p-tb', // id del portlet "Strumenti"
mw.util.getUrl( 'RichiesteAccesso_LinkedIn' ), // pagina di destinazione
'Richieste LinkedIn', // testo del link
't-linkedin-requests', // id interno del link
'Vai alla lista richieste via LinkedIn' // tooltip
);
});
/* === Rimozione forzata del link "Rispondi" in tutte le discussioni === */
mw.loader.using( 'jquery', function () {
$( function () {
// Rimuove tutti i link con testo "Rispondi"
$('a').filter(function () {
return $(this).text().trim() === 'Rispondi';
}).remove();
// Nel caso fosse un bottone invece che un link
$('button').filter(function () {
return $(this).text().trim() === 'Rispondi';
}).remove();
});
});
// MESB Accept/Decline buttons
mw.loader.using(['mediawiki.util'], function () {
var page = mw.config.get('wgPageName');
if (page !== 'MESB/Accept_Membership') {
return;
}
function sendDecision(action) {
var name = prompt("Please enter your full name:");
if (!name) {
return;
}
var comment = '';
var extraComment = confirm("Would you like to add a short comment?");
if (extraComment) {
comment = prompt("Optional comment (you may leave this empty):") || '';
}
var statusEl = document.getElementById('mesb-status');
if (statusEl) {
statusEl.textContent = 'Sending your response...';
}
fetch('/mesb_accept_api.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: name,
action: action,
comment: comment
})
})
.then(function (res) { return res.json(); })
.then(function (data) {
if (statusEl) {
statusEl.textContent = data.message || 'Response recorded.';
} else {
alert(data.message || 'Response recorded.');
}
})
.catch(function () {
if (statusEl) {
statusEl.textContent = 'Error submitting your response. Please use email or LinkedIn instead.';
} else {
alert('Error submitting your response. Please use email or LinkedIn instead.');
}
});
}
var acceptBtn = document.getElementById('mesb-accept-btn');
var declineBtn = document.getElementById('mesb-decline-btn');
if (acceptBtn) {
acceptBtn.addEventListener('click', function () {
sendDecision('ACCEPT');
});
}
if (declineBtn) {
declineBtn.addEventListener('click', function () {
sendDecision('DECLINE');
});
}
});
// Mostra pulsante "Change Password" nella pagina di login
mw.loader.using("mediawiki.util", function () {
if (mw.config.get("wgCanonicalSpecialPageName") === "Userlogin") {
var lang = mw.config.get("wgUserLanguage");
var text = (lang === "it")
? "Cambia la tua password personale"
: "Change your personal password";
var btn = document.createElement("a");
btn.className = "mw-ui-button mw-ui-progressive";
btn.href = "/wiki/Special:ChangeCredentials";
btn.style.display = "block";
btn.style.marginBottom = "20px";
btn.style.textAlign = "center";
btn.innerText = text;
var form = document.querySelector("form");
if (form) form.parentNode.insertBefore(btn, form);
}
});
// ==============================
// MESB – Gestione pulsanti ACCEPT / DECLINE
// Pagina: MESB/Accept_Membership
// ==============================
mw.loader.using(['mediawiki.util'], function () {
$(function () {
// Controlla che siamo sulla pagina giusta
if (mw.config.get('wgPageName') !== 'MESB/Accept_Membership') {
return;
}
function sendMesbDecision(decision) {
const name = prompt("Please type your full name to confirm:");
if (!name) {
return;
}
// Per ora usiamo un LinkedIn ID di test (il tuo).
// Dopo lo cambiamo per ogni persona se serve.
const payload = {
decision: decision,
name: name,
linkedin: "TEST-GIANNI"
};
const statusBox = document.getElementById("mesb-status");
if (statusBox) {
statusBox.innerHTML = "Sending your decision…";
}
fetch("/MESB/mesb_decision_api.php", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
})
.then(function (response) { return response.json(); })
.then(function (data) {
if (statusBox) {
statusBox.innerHTML = data.message || "Decision saved.";
} else {
alert(data.message || "Decision saved.");
}
})
.catch(function (error) {
console.error("MESB decision error:", error);
if (statusBox) {
statusBox.innerHTML = "Error saving your decision. Please try again.";
} else {
alert("Error saving your decision. Please try again.");
}
});
}
// Aggancia i pulsanti se esistono
$("#mesb-accept-btn").on("click", function () {
sendMesbDecision("accept");
});
$("#mesb-decline-btn").on("click", function () {
sendMesbDecision("decline");
});
});
});
// Aggiunge una classe al body se l'utente è admin (sysop)
mw.loader.using('mediawiki.user', function () {
mw.user.getGroups().then(function (groups) {
if (groups.includes('sysop')) {
document.body.classList.add('user-is-sysop');
}
});
});
/* ============================
* Copia messaggio LinkedIn per invitati MESB
* ============================ */
document.addEventListener('click', function (e) {
var el = e.target.closest('.linkedin-mesb-msg');
if (!el) return;
e.preventDefault();
var name = el.getAttribute('data-name') || 'colleague';
var text =
`Dear ${name},
thank you again for your kind openness to Masticationpedia.
As anticipated, I have now created your account on Masticationpedia so that you can access the Scientific Community area.
🔹 Login page: https://masticationpedia.org
🔹 Access method: “Sign in with LinkedIn”
If you encounter any difficulty, please let me know and I will be happy to assist you personally.
With gratitude and warm regards,
Gianni Frisardi
Founder, Masticationpedia`;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text)
.then(function () {
alert('✅ Messaggio copiato negli appunti.\nOra apri LinkedIn, clicca su "Messaggio" e incolla (CTRL+V / CMD+V).');
})
.catch(function () {
alert('⚠️ Non sono riuscito a copiare automaticamente.\nSe vuoi dopo ti preparo una versione da copiare a mano.');
});
} else {
alert('⚠️ Il browser non supporta la copia automatica.\nTi preparo io un sistema alternativo se serve.');
}
});
/****************************************************
* RICHIESTE LINKEDIN – GESTIONE INVITATI (MESB)
****************************************************/
mw.loader.using('mediawiki.util', function () {
$(function () {
// Attivo solo sulla pagina RichiesteAccesso_LinkedIn
if (mw.config.get('wgPageName') !== 'RichiesteAccesso_LinkedIn') {
return;
}
// 1) Carica elenco invitati
function loadInvitedUsers() {
fetch('/MESB/linkedin_invited_view.php')
.then(function (r) { return r.text(); })
.then(function (html) {
$('#linkedinInvitedContainer').html(html);
})
.catch(function () {
$('#linkedinInvitedContainer').html(
'<p style="color:red;">Errore nel caricamento dell’elenco invitati.</p>'
);
});
}
// 2) Aggiunge il pulsante "➕ Aggiungi alla lista invitati"
function attachInviteButtons() {
// Prendi la PRIMA tabella dentro #richiesteLinkedIn, qualunque classe abbia
var $table = $('#richiesteLinkedIn').find('table').first();
if (!$table.length) {
return;
}
// Aggiungi intestazione "Azione" se non c'è
var $headerRow = $table.find('thead tr').last();
if ($headerRow.find('th.mesb-invite-col').length === 0) {
$('<th class="mesb-invite-col">Azione</th>').appendTo($headerRow);
}
// Per ogni riga del corpo, aggiungi la cella con il pulsante
$table.find('tbody tr').each(function () {
var $row = $(this);
// Evita di aggiungere più volte
if ($row.find('td.mesb-invite-cell').length) {
return;
}
// ATTENZIONE: qui uso le stesse colonne che vedi a video:
// 0 = #
// 1 = Sub (LinkedIn)
// 2 = Nome
// 3 = Email
var name = $.trim($row.find('td').eq(2).text() || '');
var email = $.trim($row.find('td').eq(3).text() || '');
// Se non c'è un nome, non ha senso mostrare il pulsante
if (!name) {
var $emptyCell = $('<td class="mesb-invite-cell">—</td>');
$row.append($emptyCell);
return;
}
var $cell = $('<td class="mesb-invite-cell"></td>');
var $btn = $('<button type="button" class="mw-ui-button mw-ui-progressive mw-ui-quiet">➕ Aggiungi alla lista invitati</button>');
$btn.on('click', function () {
if (!confirm('Aggiungere "' + name + '" alla lista degli invitati?')) {
return;
}
var formData = new FormData();
formData.append('name', name);
formData.append('email', email);
formData.append('country', '');
formData.append('specialization', '');
formData.append('linkedin', '');
formData.append('note', 'Richiesta LinkedIn pendente');
formData.append('created_by', mw.config.get('wgUserName') || 'admin');
fetch('/MESB/linkedin_invited_api.php', {
method: 'POST',
body: formData
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data && data.success) {
alert('Invitato aggiunto correttamente.');
loadInvitedUsers();
} else {
alert('Errore: ' + (data && data.message ? data.message : 'sconosciuto'));
}
})
.catch(function (err) {
console.error(err);
alert('Errore di rete durante la chiamata all’API.');
});
});
$cell.append($btn);
$row.append($cell);
});
}
// 3) Avvio: carico gli invitati e poi provo ad agganciare i pulsanti
loadInvitedUsers();
// La tabella delle richieste viene generata da PHP/JS separato:
// facciamo un paio di tentativi con timeout per essere sicuri.
setTimeout(attachInviteButtons, 1000);
setTimeout(attachInviteButtons, 3000);
setTimeout(attachInviteButtons, 6000);
});
});
// === SCIENTIFIC COMMUNITY DECISION HANDLING ===
document.addEventListener("click", function (e) {
if (!e.target.classList.contains("sc-com-button")) return;
const decision = e.target.dataset.decision;
const name = document.getElementById("sc_name")?.value || "";
const linkedin = document.getElementById("sc_linkedin")?.value || "";
const notes = document.getElementById("sc_notes")?.value || "";
if (!name) {
alert("Please enter your full name before submitting.");
return;
}
fetch("/MESB/community_decision_api.php", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body:
`name=${encodeURIComponent(name)}` +
`&linkedin_url=${encodeURIComponent(linkedin)}` +
`&decision=${encodeURIComponent(decision)}` +
`¬es=${encodeURIComponent(notes)}`
})
.then(r => r.json())
.then(res => {
if (res.status === 'ok') {
alert("Thank you! Your decision has been recorded.");
location.reload();
} else {
alert("Error: " + res.msg);
}
});
});