Blogger del.icio.us post categorizing helper

By Johan Sundström Last update Nov 11, 2005 — Installed 1,591 times.
// ==UserScript==
// @name          Blogger del.icio.us post categorizing helper
// @namespace     http://www.lysator.liu.se/~jhs/userscript
// @description   Adds a tags field for Blogger posts and helps keep your notes in sync with your Del.icio.us categories according to the tags you used.
// @include       http://www.blogger.com/post-*
// @include       http://blogger.com/post-*
// @include       http://blogger.com/publish-body*
// @include       http://www.blogger.com/publish-body*
// ==/UserScript==

// make post: http://www.blogger.com/post-create.g?blogID=\d{8,}
// post page: http://www.blogger.com/post-edit.g?blogID=\d+&postID=\d{18}
// post done: http://www.blogger.com/publish-body.g?blogID=\d+&inprogress=true

// Blogger id. Used to store data between posting and publishing page, and to
// keep track of which Del.icio.us user stores tagged posts for us. Also used
// when deciding what text to prepend the <div class="tags"></div> data with.
var myid = getBlogId();

// The name of our blog, as listed in the page header. Default guess the first
// time we ask the user for her Del.icio.us account name (N/A when publishing)
var name = $( 'blogname' ) && $( 'blogname' ).textContent.replace( /\s/g, '' );

var site = 'http://del.icio.us/'+ name +'/'+ name +'+${tag}';
window.sites = [ new Site( 'Del.icio.us', GM_getValue( 'url-'+myid, site )) ];
//new Site( 'Technorati', 'http://www.technorati.com/tag/${tag}' ),

if( location.pathname.match( 'publish-body.g' ) )
  linkDelicious();
else
  moveTagsToHeader();

function $( id ){ return document.getElementById( id ); };

function getBlogId()
{
  return /blogid=(\d+)/i.exec( location.search )[1];
}

function Site( name, link )
{
  this.name = name;
  this.link = '<a href="'+ link +'" rel="tag">${tag}</a>';
}

function getLinkByText( pattern )
{
  var i, l = document.links;
  for( i=0; i<l.length; i++ )
    if( l[i].textContent.match( pattern ) )
      return l[i].href;
}

// Fetch data from storePostData() for Delicious link on the publishing page,
// http://www.blogger.com/publish-body.g?blogID=*&inprogress=true
function linkDelicious()
{
  var done = $( 'verboseStatus' );
  if(!done )
  { // reddish debug flashing:
    // $('body').style.background = '#F' + pad(parseInt(100*Math.random()));
    return setTimeout( linkDelicious, 200 );
  }
  var base = getLinkByText( /View Blog/i );
  var urls = done.innerHTML.split( /\s*<br *\/?>\s*/i );
  var keep = /^([^:]*:..[^\/]*.[^\/]*).*/; // keeps the first path segment
  var icio = GM_getValue( 'url-'+myid, site ).replace( keep, '$1' );
  var url, i;
  for( i=0; i<urls.length; i++ )
    if( urls[i].match( '/' ) )
      url = base.replace(/\/$/,'') +'/'+ urls[i].replace( /^\//, '' );
  if( url )
  {
    var img = document.createElement( 'img' );
    img.src = 'http://del.icio.us/static/img/delicious.small.gif';
    img.alt = 'Del.icio.us icon';
    var tag = document.createElement( 'a' );
    tag.href = icio +'?v=3&url='+ url + GM_getValue( 'postdata-'+myid, '' );
    tag.title = 'Tag this post at Del.icio.us';
    var node = done.nextSibling;
    if( node.nodeName == '#text' )
      node = node.nextSibling; // the <p> tag containing View Blog
    var perm = document.createElement( 'a' );
    perm.href = url;
    perm.appendChild( document.createTextNode( 'View Post' ) );
    node.insertBefore( perm, node.firstChild );
    node.insertBefore( document.createTextNode( ' ' ), node.firstChild );
    node.insertBefore( tag, node.firstChild );
    img.style.paddingRight = '4px';
    tag.appendChild( img );
    tag.appendChild( document.createTextNode( 'Link at Del.icio.us' ) );
  }
}

// Store away title, datestamp and tags from create/edit post page, located at
// http://www.blogger.com/post-create.g?blogID=* to be picked up on publishing
function storePostData()
{
  var blog = GM_getValue( 'extra-'+myid, name );
  var myid = getBlogId();
  var tags = $( 'tags' ).value.replace( /\s*,\s*/g, ' ' );
  if( blog ) tags = blog +' '+ tags;
  var head = $( 'f-title' ).value;
  var form = document.forms.namedItem( 'stuffform' ).elements;
  var date = form.namedItem( 'postYear' ).value +'-'+
	       pad( parseInt(form.namedItem( 'postMonth' ).value, 10)+1 ) +'-'+
	       pad( form.namedItem( 'postDay' ).value ) + ' ';
  var hour = form.namedItem( 'postHour' ).value % 12;
  var ampm = form.namedItem( 'postAMPM' ).value;
  if( ampm ) hour += 12;
  var time = pad( hour ) +':'+ pad( form.namedItem( 'postMinute' ).value );
  var data = { title:head, extended:date+time, tags:tags };
  var save = '';
  for( var i in data )
    save += '&'+ i +'='+ encodeURIComponent( data[i] );
  GM_setValue( 'postdata-'+myid, save );
}

// Zero pad number to two decimals
function pad( n )
{
  return (n < 10 ? '0' : '') + n;
}

// Let the user set up his script the way she wants to:
function configure()
{
  var myid = getBlogId();
  var had = GM_getValue( 'url-'+myid, '' ); // first time: false
  var last = GM_getValue( 'title-'+myid, 'Tags:' );
  var title = prompt( 'Title for listed tags:', last );
  if( title != last )
    GM_setValue( 'title-'+myid, title );
  last = GM_getValue( 'extra-'+myid, name );
  var extraTags = prompt( 'Tags (space separated) that you want ' +
			  'on all your blog posts:', last );
  GM_setValue( 'extra-'+myid, extraTags );
  last = GM_getValue( 'url-'+myid, 'http://del.icio.us/'+ name +'/'+
		      extraTags + '+${tag}' );
  var links = prompt( 'Tag URL to link to (where ${tag} gets replaced ' +
		      'with the tag name): ', last );
  if( links != last )
    GM_setValue( 'url-'+myid, links );
  if( !had )
    alert( 'To change this configuration later, click on the Tags: label.' );
}

// Puts all tags into the post body and stores away data in a GM variable.
function saveData()
{
  var myid = getBlogId();
  if( !GM_getValue( 'extra-'+myid, '' ) ) configure();
  storePostData();
  var text = $( 'textarea' ), sites=window.sites, html='';
  var tags = $( 'tags' ).value.split( /\s*[, ]\s*/ ), tag;
  if( tags[0] != '' )
  {
    html = '';
    for( var i=0; i<sites.length; i++ )
    {
      html += '<div class="tags">';
      if( sites.length > 1 ) html += sites[i].name +' ';
      html += GM_getValue( 'title-'+myid, 'Tags:' ) + '<ul>';
      for( var j=0; j<tags.length; j++ )
        html += '<li>'+ sites[i].link.replace(/\$\{tag\}/g, tags[j]) +'</li> ';
      html += '</ul></div>';
    }
    text.value += html;
  }
}

// Parses and removes all added <div class="tags"></div> tags from the post
// body and puts them in the header.
function moveTagsToHeader()
{
  var tags = '';
  var post = document.createElement( 'div' );
  post.innerHTML = $( 'textarea' ).value; // just to let us parse it easier:
  try
  {
    var divs = post.getElementsByTagName( 'div' );
    for( var i=0; i<divs.length; i++ )
      if( divs[i].className == 'tags' )
      {
	var tagAs = divs[i].getElementsByTagName( 'a' );
	for( var j=0; j<tagAs.length; j++ )
	{
	  tags += tagAs[j].text;
	  if( j+1 < tagAs.length ) tags += ', ';
	}
	break;
      }
  } catch(e) {}

  var re = /\n*<div class="tags">(.|\n)+<\/div>/mi;
  $( 'textarea' ).value = $( 'textarea' ).value.replace( re, '\n' );

  var tagRow = document.createElement( 'tr' );
  var link = $( 'titles' ).getElementsByTagName( 'tbody' ).item( 0 ).
	       getElementsByTagName( 'tr' ).item( 1 );
  link.parentNode.insertBefore( tagRow, link );
  tagRow.innerHTML = '<th><label id="TConfig" for="tags">Tags:</label></th>' +
    '<td><div class="errorbox-good">' +
    '<input id="tags" class="text" style="width:657px" tabindex="1" ' +
    ' value="'+ tags +'"></div></td>';
  $( 'TConfig' ).addEventListener( 'click', configure, false );
  $( 'f-title' ).style.width = '657px';
  link = $( 'f-address' );
  if( link ) link.style.width = '455px';
  $( 'saveDraft' ).addEventListener( 'click', saveData, false );
  $( 'publishPost' ).addEventListener( 'click', saveData, false );
}