Firefox/Projects/PlacesQueryAPIRedesign

From MozillaWiki
Jump to navigation Jump to search

Summary

Create a sensible, easy to use Query API for Places for Firefox 3.7/4.0

Current Status

Beginning stages - examining faaborg's mockups and blogposts

Next Steps

  • Figure out if we are going to ride on top of the existing query API or not. The main goal is a sensible api.

Related Bugs

bug 522572

Team

  • API: ddahl + places team
  • UX/UI: faaborg
  • Llama wrangling: dolske

Designs

Faaborg has been mocking up designs and putting a lot pf thought into the UX: http://blog.mozilla.com/faaborg/2009/10/13/browsing-your-personal-web/


Places Query Api Redesign

Priciples:

Query API redesign is for the new direction/design of Places for Fx 3.7 +

This design should not take into account existing Places implementation

Design in a nutshell:


   // queryObj is an object that configures the current query

   queryObj = { param:'cnn', 

                // the following 'bookmarks' and 'history' are not 

                // required, defaults are true for both

                bookmarks:true, // search bookmarks - yes (default)

                history:true,   // search bookmarks - yes (default)

                // UI Callback function

                uiCallback: function (results){ // results is an Iterator } 
              };

   // qResultObj is returned by the QueryProcessor and is 

   // an object that has a 'fetch' method used as a callback

   // this object has parsed the queryObj, built the SQL, 

   // and contains an (optional)  UI callback to update the UI. 

   // (all queries are performed asynchronously)

   qResultObj = new QueryProcessor(queryObj);
   
   qResultObj.fetch();

   // fetch will trigger the search in the database and 

   // fire the UI callback, with the results chunk

Use Cases

Location Bar bookmarks navigation:

screenshot: [1]


   // set up defaults for the operations at hand: 

   var query = { bookmarks: true, history: true };

   // add the string to search

   query.param = 'Bill';
   
   // optional UI callback registration:

   function uiCallbk(results){

     results.length // 1
   
     for (let item in results) {

       item.title;  // 'Bills, Resolutions Libary of Congress'
       item.url;    // 'thomas.loc.gov/home/bills_res.html'
       item.id;     // 123897
       item.path;   // 'Bookmarks/Government'
       ...
     }
   }

   query.uiCallback = uiCallbk;
   
   // feed the query object into the Places QueryProcessor

   var qResultObj = new QueryProcessor(query);
   
   qResultObj.fetch; // function that returns an iterator, used as a callback
   
   // Usage in the wild: 'caller()' is a consumer of the QueryProcessor
   
   function caller(qResultObj) {
     ...
     qResultObj.fetch(); // triggers async query and uiCallback

     // fetch() will throw if anything goes awry

     return true;
   }

Anatomy of a (bookmark folder) 'Item':


   { title:        'Bills',
     url:          'bookmark://Apartment/Bills'
     path:         'Bookmarks/Apartment/Bills', 
     node:         'folder',
     id:           34678,
     type:         'bookmark',
     children:     (property), // returns a resultTree or 
                               // Iterator of top-level siblings
     silblings:    (property), // returns Iterator Obj
     siblingCount  (property) // returns Number
     parent:       (property), // returns Item
     lastVisit:    '2009-11-04 12:00:01',    
     firstVist:    '2009-10-31 15:00:23',
     visits:       (property), // returns ordered list of visitItems
     icon:         (property), // returns faviconItem object
   }

Anatomy of a (history) 'Item':


   { title:        "Hurricane Bill's winds weaken",
     url:          'news.yahoo.com/s/ap/...'
     path:         'news.yahoo.com/s/ap/...', 
     node:         'item',
     id:           34678,
     type:         'history',
     children:     null,
     silblings:    null,
     siblingCount: null,
     parent:       null,
     lastVisit:    '2009-11-04 12:00:01',
     firstVist:    '2009-10-31 15:00:23',
     visits:       (property) // returns ordered list of 'visitItem' objects
   }

Location Bar History Ranges

screenshot: [2]


  // taken the above 'default' query object, we add a historyRange property: 
  
  query.historyRangeKeyword = 'Today'; 
  
  // also, phrases like: 'Last Week', 'This Month', 'Last Year', etc...
  
  // - or - 

  // (in reality, these are the internally-called methods to 
  // handle the parsed 'historyRangeKeyword')

  query.historyRangeFrom = new Date();
  query.historyRangeTo = new Date();  

  // optionally, we can filter the results with a keyword

  query.param = 'news';

  query.uiCallback = function (results){

    for (let item in results.next()){

      displayInUserInterface(item);

    }   

  };

  // perhaps we have a negative filter as well: 
  query.exclude = 'cnn';
  
  // feed the query object into the Places QueryProcessor
  var qResultObj = new QueryProcessor(query);
  
  // here it is in the wild:

  function caller(qResultObj) {
           
    qResultObj.fetch();

    return true;
  }
 

Faceted Searches - Perhaps this is for '4.0'?


  // I have seen faceted search apis that do things like:
  
  qResultObj.narrow({referrer:'mozilla.com'});
  
  qResultObj.fetch();

  // the 'narrow' call will return a new qResultObject that 
  // can be narrowed futher:
  
  qResultObj.narrow({ year:2009 });
  
  qResultObj.fetch();

  qResultObj.narrow({ tagged:'News' });
  
  qResultObj.fetch();

  qResultObj.narrow({ month:11 });

  qResultObj.fetch();
  
  qResultObj.widen('month', 'year');
  
  qResultObj.widen(); // removes all facets

  // What are all of the facets?        
  //  
  // times, dates, referringDomain, referringFragment, isBookmarked, 
  // inTraversal, tagged
  //
  // 'inTraversal' is any historyItem or bookmark in the traversed path 
  // that was taken to get to the target url/bookmark
  //  
  // 'inTraversal' will require that we store a more comprehensive 
  // "browsing path" data

Goals/Use Cases

  • An elegant and easy to use API. Fx devs, Jetpack and extension developers will all benefit.
  • allows us to prototype the new ui for 3.7
  • 'Pluggable' results handling
  • Focus on JS usage

Non Goals

  • Tailoring the API to tree views
  • Creating the perfect API (lets iterate)
  • Intended as a snap-in replacement of the current API