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