Sunday, March 6, 2011

A little help with DOM manip and GreaseMonkey

I'm not a JS guy so I'm kinda stumbling around in the dark. Basically, I wanted something that would add a link to a twitter search for @replies to a particular user while on that person's page.

Two things I am trying to figure out:

  1. how to extract the user name from the page so that I can construct the right URL. ie. if I am on http://twitter.com/ev , I should get "ev" back.
  2. how to manipulate the DOM to insert things at the right place

Here's the HTML fragment I'm targetting:

<ul id="tabMenu">
  <li>
    <a href="/ev" id="updates_tab">Updates</a>  </li>
  <li>
    <a href="/ev/favourites" id="favorites_tab">Favorites</a>  </li>
  </ul>

And here is the script (so far):

// ==UserScript==
// @name         Twitter Replies Search
// @namespace    http://jauderho.com/
// @description  Find all the replies for a particular user
// @include      http://twitter.com/*
// @include      https://twitter.com/*
// @exclude      http://twitter.com/home
// @exclude      https://twitter.com/home
// @author       Jauder Ho
// ==/UserScript==

var menuNode = document.getElementById('tabMenu');
if (typeof(menuNode) != "undefined" && menuNode != null)
{
    var html = [];
    html[html.length] = '<li>';
    html[html.length] = '<a href="http://search.twitter.com/search?q=to:ev" class="section-links" id="replies_search_tab">@Replies Search</a>';
    html[html.length] = '</li>';

    // this is obviously wrong
        var div = document.createElement('div');
    div.className = 'section last';
    div.innerHTML = html.join('');
    followingNode = menuNode.parentNode;
    followingNode.parentNode.insertBefore(div, followingNode);
}
From stackoverflow
  • Here is a way to do it, not really tested (no twitter account).

    var userName = window.location.href.match(/^http:\/\/twitter\.com\/(\w+)/)
    if (userName == null)
      return; // Problem?
    userName = userName[1];
    var menuNode = document.getElementById('tabMenu');
    if (menuNode != null)
    {
      var html = '<a href="http://search.twitter.com/search?q=to:' +
          userName +
          '" class="section-links" id="replies_search_tab">@Replies Search</a>';
    
      var li = document.createElement('li');
      li.className = 'section last';
      li.innerHTML = html;
      menuNode.appendChild(li);
    }
    

    It adds the li to the end, and I dropped the div because I doubt it is correct to put a li in a div. If you really need to put the li at the start of the ul, try menuNode.insertBefore(li, menuNode.firstChild)

  • Here's a pure-DOM method of the above -- and for kicks, I played with the extraction of the username as well:

    var menuNode = document.getElementById('tabMenu');
    if (menuNode!=null)
    {
        // extract username from URL; matches /ev and /ev/favourites
        var username = document.location.pathname.split("/")[1];
    
        // create the link
        var link = document.createElement('a');
        link.setAttribute('href', 'http://search.twitter.com/search?q=to:'+username);
        link.setAttribute('id', 'replies_search_tab');
        link.appendChild(document.createTextNode('@Replies Search'));
    
        // create the list element
        var li = document.createElement('li');
    
        // add link to the proper location
        li.appendChild(link);
        menuNode.appendChild(li);    
    }
    

    This is equivalent to (based on the original code snippet):

      <ul id="tabMenu">
      <li>
        <a href="/ev" id="updates_tab">Updates</a>  </li>
      <li>
        <a href="/ev/favourites" id="favorites_tab">Favorites</a>  </li>
      <li>
        <a href="http://search.twitter.com/search?q=to:ev" id="replies_search_tab">@Replies Search</a></li>
      </ul>
    

    If you want the added link to show up in a different location, you'll need to futz around with insertBefore a bit.

    PS. Took the liberty of ignoring the "section-links" class, as that's formatting for x following, y followers, z updates links.

  • Just tried it out and it works nicely! Thanks!

  • Writing JavaScript without a library is a hell I can never return to.

    Here is a script skeleton that enables jQuery:

    // ==UserScript==
    // @name           MyScript
    // @namespace      http://example.com
    // @description    Example
    // @include        *
    //
    // @require     http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js
    // ==/UserScript==
    
    var menuNode = $('#tabMenu');
    if (menuNode!=null)
    {
        // extract username from URL; matches /ev and /ev/favourites
        var username = document.location.pathname.split("/")[1];
    
        // create the link
        var link = $('<a id="replies_search_tab">@Replies Search</a>');
        link.href = 'http://search.twitter.com/search?q=to:'+username;
    
        // create the list element
        var li = $('<li />');
    
        // add link to the proper location
        li.append(link);
        menuNode.append(li);    
    }
    

0 comments:

Post a Comment