Firefox/Projects/PlacesQueryAPISketches
From MozillaWiki
Contents
Places Query Api Redesign
Project Page: [1]
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 = { phrase:'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 chunked
Use Cases
Location Bar bookmarks navigation:
screenshot: [2]
// set up defaults for the operations at hand: var query = { bookmarks: true, history: true }; // add the string to search query.phrase = '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; }
This pattern of using a callback will require a closure, something like this:
var myUiCallback = function (results) { this.document = document; // pull in a reference to the current chrome or content let resultsList = this.document.getElementById("history-results"); for (let item in results){ let node = this.document.createElement("li"); node.innerHTML = results.title; // simplistic example // note: when dealing with chrome we may want to figure out a way to work with templates: [https://developer.mozilla.org/en/XUL%3aTemplate_Guide%3aSQLite_Templates] } }
Location Bar History Ranges
screenshot: [3]
// 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.phrase = '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; }
Anatomy of a 'bookmark Item':
{ title: 'Mozilla.org', url: 'https://www.mozilla.org' path: 'Bookmarks/Software/OpenSource/Mozilla.org', node: 'item', id: 354, type: 'bookmark', children: null, silblings: (property), // returns Iterator Obj siblingCount (property) // returns Number parent: (property), // returns folderItem 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 'bookmark folderItem':
{ 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 icon: (property), // returns icon uri traversal: (property), // returns a 'traversal' object or iterator }
Anatomy of a 'traversal' object:
A Traversal is a browsing session that can be reconstructed like a tree:
// Work in progress - I would like to be able to describe the traversal // path or browsing session as a tree like object that shows what urls // you visit, how you got there, and if and when new tabs or windows were // spawned. Visualizing this effectively would be a very powerful tool in // helping users understand how they get to urls and why. // The questions are "how did I get here" and "where did I go on my way", // "where did I get sidetracked", etc... { // more fleshing out is needed here. placeIdIndex: [ 345, 567, 987, 234, 992, 534, ], placeIndex: { 345: (property), // returns 'Place' object 567: (property), ... } // start returns a traversalItem start: { url: (property), // returns 'Place' object newTab: true, dateTime: '2009-11-05 11:05:06', referrer: null, next: (property), // returns 'history' object } }
Faceted Searches
// 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.narrow({ tagged:'News' }); qResultObj.narrow({ keyword:'bug' }); // narrow on keywords qResultObj.narrow({ month:11 }); qResultObj.widen('month', 'year'); qResultObj.widen(); // removes all facets // What are all of the facets? // // times, dates, referringDomain, referringFragment, isBookmarked, // inTraversal, tagged, keyword // // '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