User:Gryllida/common.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | The accompanying .css page for this skin is at User:Gryllida/common.css. |
/*//importScript( 'User:Equazcion/ScriptInstaller.js' ); // Backlink: [[User:Equazcion/ScriptInstaller.js]]
//importScript( 'User:Gryllida/js/ajaxSectionUpdateOnDoubleClick.js' ); // Backlink: [[User:Gryllida/js/ajaxSectionUpdateOnDoubleClick.js]]
//importScript( 'User:Gryllida/js/truncateEditSummaryWithClickableEllipsisv2.js' ); // Backlink: [[User:Gryllida/js/truncateEditSummaryWithClickableEllipsisv2.js]]
//importScript( 'User:APerson/req-helper.js' ); // Backlink: [[User:APerson/req-helper.js]]
//importScript( 'User:Gryllida/gadgets/rater.js' ); // Backlink: [[User:Gryllida/gadgets/rater.js]]
if(mw.config.get('wgNamespaceNumber')==118){
var href='http://en.wikipedia.org/wiki/'+mw.config.get('wgPageName')+'?action=edit&editintro=User:Gryllida/draft-review/editintro';
$('#ca-edit a').attr('href', href);
}
importScript( 'User:Equazcion/ScriptInstaller.js' ); // Backlink: [[User:Equazcion/ScriptInstaller.js]]
importScript('User:MusikAnimal/customWatchlists.js'); //Linkback: [[User:MusikAnimal/customWatchlists.js]] Added by Script installer
importScript('User:Equazcion/ReverseMarked.js'); //Linkback: [[User:Equazcion/ReverseMarked.js]] Added by Script installer
//importScript( 'User:Gryllida/js/draft-rater.js' ); //Linkback: [[User:Gryllida/js/draft-rater.js]] Added by Script installer
*/
// Citation tool with web2cit integration
// Add this code to your common.js page on Wikipedia
mw.loader.using(['ext.visualEditor.desktopArticleTarget']).then(function() {
mw.hook('ve.activationComplete').add(function() {
console.log('CitationTool: VE activation hook fired');
// Wait a bit for the toolbar to fully initialize
setTimeout(function() {
addCitationButton();
}, 1000);
// Also add the button when the surface is ready
if (typeof ve !== 'undefined' && ve.init && ve.init.target) {
ve.init.target.on('surfaceReady', function() {
console.log('CitationTool: Surface ready event fired');
addCitationButton();
});
}
});
// Also support source editor mode
mw.hook('ve.wikitextInteractive').add(function() {
console.log('CitationTool: wikitext interactive hook fired');
setTimeout(function() {
addCitationButton();
}, 1000);
});
});
// Format date function
function formatDate(dateString) {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return "Invalid date";
}
return new Intl.DateTimeFormat('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric'
}).format(date);
}
// Function to get Web2Cit URL
function getWeb2CitUrl(url) {
let server = "https://web2cit.toolforge.org/";
if (typeof window.web2cit !== 'undefined' && window.web2cit.server) {
server = window.web2cit.server;
}
return server + "translate?citoid=true&format=mediawiki&url=" + encodeURIComponent(url);
}
// Process citation data
function processData(err, data) {
if (err !== null) {
console.log('Something went wrong: ' + err);
return null;
}
if (!Array.isArray(data) || data.length === 0) {
console.log('No citation data received');
return null;
}
// Check if we have Web2Cit data
let web2CitData = null;
let citoidData = null;
// Separate Web2Cit and Citoid data
for (const citation of data) {
let { source } = citation;
if (source !== undefined) {
if (!Array.isArray(source)) source = [source];
if (source.includes('Web2Cit')) {
web2CitData = citation;
} else if (source.includes('Zotero')) {
citoidData = citation;
}
}
}
console.log('Web2Cit data available: ' + (web2CitData !== null));
// Prefer Web2Cit data, fall back to Citoid data for missing fields
let citation = web2CitData || citoidData;
// If we have both, merge them with Web2Cit taking precedence
if (web2CitData && citoidData) {
// Use Web2Cit data preferentially, but fall back to Citoid for missing fields
let mergedCitation = {...citoidData, ...web2CitData};
// For specific fields that might be in one but not the other
if (!web2CitData.publicationTitle && citoidData.websiteTitle) {
mergedCitation.publicationTitle = citoidData.websiteTitle;
}
// Use the merged citation
citation = mergedCitation;
}
if (!citation) {
console.log('No valid citation data found');
return null;
}
// Extract and format date if available
let date = "";
if (citation.date) {
date = formatDate(citation.date);
}
// Extract publication title or website title if available
let pub = "";
if (citation.publicationTitle) {
pub = citation.publicationTitle;
} else if (citation.websiteTitle) {
pub = citation.websiteTitle;
}
// Extract title if available
let title = citation.title || "";
// Extract URL if available
let url = citation.url || "";
// Create the citation markup
var markup = "*{{source\r\n|url=" + url + "\r\n|title=" + title + "\r\n|publisher=" + pub + "\r\n|date=" + date + "\r\n}}";
// Copy to clipboard
navigator.clipboard.writeText(markup);
console.log('Copied citation markup to clipboard:');
console.log(markup);
return markup;
}
// HTTP request function
function getJSON(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status === 200) {
callback(null, xhr.response);
} else {
callback(status, xhr.response);
}
};
xhr.send();
}
// Add the citation button
function addCitationButton() {
console.log('Attempting to add Citation button');
// Check if our button already exists to avoid duplicates
if ($('.oo-ui-tool-name-citationTool').length) {
console.log('Citation button already exists');
return;
}
// Create a proper new group for our button
var $toolGroup = $('<div>')
.addClass('ve-ui-toolbar-group-citation oo-ui-widget oo-ui-toolGroup oo-ui-barToolGroup oo-ui-widget-enabled')
.attr('title', 'Citation Tools');
var $toolsContainer = $('<div>')
.addClass('oo-ui-toolGroup-tools oo-ui-barToolGroup-tools oo-ui-toolGroup-enabled-tools')
.appendTo($toolGroup);
// Create the button itself matching other buttons' structure
var $button = $('<span>')
.addClass('oo-ui-widget oo-ui-iconElement oo-ui-tool-with-icon oo-ui-tool oo-ui-tool-name-citationTool oo-ui-widget-enabled')
.appendTo($toolsContainer);
// Create the link element
var $link = $('<a>')
.addClass('oo-ui-tool-link')
.attr('role', 'button')
.attr('tabindex', '0')
.attr('title', 'Add Citation')
.appendTo($button);
// Add the icon structure
$('<span>')
.addClass('oo-ui-tool-checkIcon oo-ui-widget oo-ui-widget-enabled oo-ui-iconElement oo-ui-iconElement-icon oo-ui-icon-check oo-ui-labelElement-invisible oo-ui-iconWidget')
.appendTo($link);
$('<span>')
.addClass('oo-ui-iconElement-icon oo-ui-icon-star')
.appendTo($link);
$('<span>')
.addClass('oo-ui-tool-title')
.text('Citation')
.appendTo($link);
// Add click event to handle citation insertion
$button.on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var url = prompt('URL');
if (!url) {
return;
}
// Make a single call to Web2Cit with citoid=true
getJSON(getWeb2CitUrl(url), function(err, data) {
const markup = processData(err, data);
if (!markup) return;
// Get the current editor surface
var surface = ve.init.target.getSurface();
var mode = surface.getMode();
if (mode === 'source') {
// In source mode, insert the text at cursor position
var surfaceModel = surface.getModel();
var fragment = surfaceModel.getFragment();
fragment.insertContent(markup, true);
console.log('Inserted citation at cursor position in source mode');
} else if (mode === 'visual') {
// In visual mode, use the most basic approach to insert a reference
try {
// Prepare the reference content (without the leading *)
var referenceContent = markup.startsWith('*') ? markup.substring(1) : markup;
// Store citation in clipboard as fallback
navigator.clipboard.writeText(referenceContent);
// Insert a basic <ref> tag at cursor position
var surfaceModel = surface.getModel();
var fragment = surfaceModel.getFragment();
// Simply insert the ref tag as text
// This approach is crude but should work in most cases
fragment.insertContent('<ref>' + referenceContent + '</ref>', true);
console.log('Inserted basic reference tag at cursor position');
} catch (e) {
console.error('Failed to insert reference in visual mode:', e);
alert('Could not insert reference. The citation was copied to clipboard instead.');
}
}
});
});
// Insert our group at an appropriate location in the toolbar
// Try to find the cite group first, then fall back to other positions
var $insertPosition = $('.ve-ui-toolbar-group-cite');
if ($insertPosition.length) {
// Add to existing cite group if available
$insertPosition.find('.oo-ui-toolGroup-tools').append($button);
console.log('Button added to cite group');
} else {
// Try to find another good position
$insertPosition = $('.ve-ui-toolbar-group-structure, .ve-ui-toolbar-group-format').last();
if ($insertPosition.length) {
$toolGroup.insertAfter($insertPosition);
console.log('Button added successfully after', $insertPosition.attr('class'));
} else {
// Fallback: add to main toolbar
$('.oo-ui-toolbar-tools').first().append($toolGroup);
console.log('Button added to main toolbar');
}
}
}
// Export function for console testing
window.getCitation = function(url) {
if (!url) {
console.log('Please provide a URL to test');
return;
}
console.log('Testing with URL:', url);
getJSON(getWeb2CitUrl(url), processData);
};
// Log that we've loaded
console.log('Citation tool initialized. Use window.getCitation("URL") to test from console.');
importScript('User:Enterprisey/draft-sorter.js'); //Linkback: [[User:Enterprisey/draft-sorter.js]] Added by Script installer
importScript('User:Evad37/rater.js'); // [[User:Evad37/rater]]
importScript('User:Gryllida/WikiEditorEmoticons.js'); //Linkback: [[User:Gryllida/WikiEditorEmoticons.js]] Added by Script installer
importScript('User:Gryllida/js/addInstantSaveToCodeEditor.js' ); // Backlink: [[User:Gryllida/js/addInstantSaveToCodeEditor.js]]
importScript('User:Gryllida/js/draft-rater.js' ); //Linkback: [[User:Gryllida/js/draft-rater.js]] Added by Script installer
importScript('User:Gryllida/js/draft-review.js' ); // Backlink: [[User:Gryllida/js/draft-review.js]]
// Refill
mw.loader.load( "https://meta.wikimedia.org/w/index.php?title=User:Zhaofeng_Li/Reflinks.js&action=raw&ctype=text/javascript" );
var topStyle = 'width: 30px; height: 30px; opacity: 0.5; border-radius: 30px;';
topStyle = topStyle + 'background-color: #dddddd; position: fixed; bottom: 5px; right: 5px;';
topStyle = topStyle + 'margin:10px; align: center; padding:15px;font-size:15pt;';
topStyle = topStyle + 'cursor:pointer; color:black;';
topStyle = topStyle + 'background-image: url("/media/wikipedia/commons/thumb/9/9c/Black_Arrow_Up.svg/24px-Black_Arrow_Up.svg.png");';
topStyle = topStyle + 'background-repeat: no-repeat;';
topStyle = topStyle + 'background-position: center;';
$('body').append($('<a></a>', {href: '#top', style: topStyle}));