Re: Client-side search providers

* Bjoern Hoehrmann wrote:
>  Fellow swhacker and www-archiver sbp and I are sick and tired of web
>search and services being hard and are returning the address bar to the
>user. As a first step we have designed a client side search provider for
>use in the address bar, starting with the collection of services we use
>a lot, would like to use more, or simply want to be easier to access.

After sending this, I made the following setup in Opera: Add as search
engine `data:text/html;charset=utf-8;secret=value,#%s` with `s` as key
word, then add the following user script (after configuring user scripts
and allowing it to use storage with an appropriate quota). The script
relies on a JSON-P service that provides the service list. The list has
entries like

  leo = http://dict.leo.org/ende?search=%s
  Bing Realtime Tweets = http://www.bing.com/social/search/updates?q=%s

which you can then use use by typing, say, `s tweets keyword` in the
address bar. If there are multiple matches for a word like "tweets", it
will generate a selection so you can manually choose which service to
go to. In this form it does not add all that much over just configuring
all the services manually, but the user interface for that is much more
difficult to use than just editing a text file. In any case this is a
good proof of concept that you could essentially do arbitrary things on
the user script generated page, especially if you were to configure a
proxy of some sort to get past cross-origin problems.

I have found this most useful even in the current buggy form (there are
problems like that it converts the search phrase to lower case which is
a problem with case-sensitive services). The script is roughly this:

  // ==UserScript==
  // @include data:text/html;charset=utf-8;secret=value,*
  // ==/UserScript==
  
  var store = opera.scriptStorage;
  
  // JSON-P callback
  function gotswhacktools(r) {
    for (var page in r.query.pages) {
      var text = r.query.pages[page].revisions[0]['*'];
  
      setTimeout(function() {
        store.setItem("swhack", text);
  
        if (window.location.hash != "#:update") {
          window.location.reload();
        } else {
          document.documentElement.innerHTML = "<p>Updated.</p>";
        }
  
      }, 1);
  
      break;
    }
  }
  
  (function(opera, hash) {
  
  var toolsText = store.getItem("swhack");
  
  if (hash == "#:update" || !toolsText) {
    var script = document.createElement("script");
    script.src = '...';
    document.documentElement.appendChild(script);
    return;
  }
  
  var encodedQuery = hash.substring(1).replace(/\+/g, "%20");
  var queryWords = decodeURIComponent(encodedQuery)
    .toLowerCase().split(/\s+/);
  
  var services = toolsText.split(/\n+/);
  var filtered = services.filter(function(elem){
    return elem.match(/\s+=\s+[a-z]+:/);
  });
  
  // find a list of services
  while (queryWords.length > 1) {
    var newlyFiltered = filtered.filter(function(elem) {
      var posWord = elem.toLowerCase().indexOf(queryWords[0]);
      var posColon = elem.indexOf(" = ")
      return posWord >= 0 && posWord < posColon;
    });
  
    if (newlyFiltered.length == 0) break;
  
    // continue filtering
    filtered = newlyFiltered;
    queryWords.shift();
  }
  
  // fill in the templates
  var ready = filtered.map(function(elem){
    return elem
    .replace(/(%s)/g, function(str, p){
      return encodeURIComponent(queryWords.join(" "));
    })
    .replace(/(%u)/g, function(str, p){
      return encodeURIComponent(queryWords.join(" "));
    });
  });
  
  if (ready.length == 1) {
    window.location.replace(ready[0].match(/\s+=\s+(\S+)/)[1]);
  } else {
    document.documentElement.innerHTML = "<li id='select'></li>";
    ready.forEach(function(elem){
      var link = document.createElement("a");
      var item = document.createElement("li");
      item.appendChild(link);
      var matches = elem.match(/(.*?)\s+=\s+(\S+)/);
      link.href = matches[2];
      link.textContent = matches[1];
      document.getElementById('select').appendChild(item);
    });
  }
  
  })(opera, window.location.hash);

regards,
-- 
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/ 

Received on Monday, 14 November 2011 01:51:22 UTC