Jump to content

User:Gryllida/common.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*//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}));