addon-sdk/source/lib/sdk/places/host/host-query.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict";
michael@0 6
michael@0 7 module.metadata = {
michael@0 8 "stability": "experimental",
michael@0 9 "engines": {
michael@0 10 "Firefox": "*"
michael@0 11 }
michael@0 12 };
michael@0 13
michael@0 14 const { Cc, Ci } = require('chrome');
michael@0 15 const { defer, all, resolve } = require('../../core/promise');
michael@0 16 const { safeMerge, omit } = require('../../util/object');
michael@0 17 const historyService = Cc['@mozilla.org/browser/nav-history-service;1']
michael@0 18 .getService(Ci.nsINavHistoryService);
michael@0 19 const bookmarksService = Cc['@mozilla.org/browser/nav-bookmarks-service;1']
michael@0 20 .getService(Ci.nsINavBookmarksService);
michael@0 21 const { request, response } = require('../../addon/host');
michael@0 22 const { newURI } = require('../../url/utils');
michael@0 23 const { send } = require('../../addon/events');
michael@0 24 const { on, emit } = require('../../event/core');
michael@0 25 const { filter } = require('../../event/utils');
michael@0 26
michael@0 27 const ROOT_FOLDERS = [
michael@0 28 bookmarksService.unfiledBookmarksFolder, bookmarksService.toolbarFolder,
michael@0 29 bookmarksService.bookmarksMenuFolder
michael@0 30 ];
michael@0 31
michael@0 32 const EVENT_MAP = {
michael@0 33 'sdk-places-query': queryReceiver
michael@0 34 };
michael@0 35
michael@0 36 // Properties that need to be manually
michael@0 37 // copied into a nsINavHistoryQuery object
michael@0 38 const MANUAL_QUERY_PROPERTIES = [
michael@0 39 'uri', 'folder', 'tags', 'url', 'folder'
michael@0 40 ];
michael@0 41
michael@0 42 const PLACES_PROPERTIES = [
michael@0 43 'uri', 'title', 'accessCount', 'time'
michael@0 44 ];
michael@0 45
michael@0 46 function execute (queries, options) {
michael@0 47 let deferred = defer();
michael@0 48 let root = historyService
michael@0 49 .executeQueries(queries, queries.length, options).root;
michael@0 50
michael@0 51 let items = collect([], root);
michael@0 52 deferred.resolve(items);
michael@0 53 return deferred.promise;
michael@0 54 }
michael@0 55
michael@0 56 function collect (acc, node) {
michael@0 57 node.containerOpen = true;
michael@0 58 for (let i = 0; i < node.childCount; i++) {
michael@0 59 let child = node.getChild(i);
michael@0 60 acc.push(child);
michael@0 61 if (child.type === child.RESULT_TYPE_FOLDER) {
michael@0 62 let container = child.QueryInterface(Ci.nsINavHistoryContainerResultNode);
michael@0 63 collect(acc, container);
michael@0 64 }
michael@0 65 }
michael@0 66 node.containerOpen = false;
michael@0 67 return acc;
michael@0 68 }
michael@0 69
michael@0 70 function query (queries, options) {
michael@0 71 queries = queries || [];
michael@0 72 options = options || {};
michael@0 73 let deferred = defer();
michael@0 74 let optionsObj, queryObjs;
michael@0 75
michael@0 76 try {
michael@0 77 optionsObj = historyService.getNewQueryOptions();
michael@0 78 queryObjs = [].concat(queries).map(createQuery);
michael@0 79 if (!queryObjs.length) {
michael@0 80 queryObjs = [historyService.getNewQuery()];
michael@0 81 }
michael@0 82 safeMerge(optionsObj, options);
michael@0 83 } catch (e) {
michael@0 84 deferred.reject(e);
michael@0 85 return deferred.promise;
michael@0 86 }
michael@0 87
michael@0 88 /*
michael@0 89 * Currently `places:` queries are not supported
michael@0 90 */
michael@0 91 optionsObj.excludeQueries = true;
michael@0 92
michael@0 93 execute(queryObjs, optionsObj).then(function (results) {
michael@0 94 if (optionsObj.queryType === 0) {
michael@0 95 return results.map(normalize);
michael@0 96 } else if (optionsObj.queryType === 1) {
michael@0 97 // Formats query results into more standard
michael@0 98 // data structures for returning
michael@0 99 return all(results.map(({itemId}) =>
michael@0 100 send('sdk-places-bookmarks-get', { id: itemId })));
michael@0 101 }
michael@0 102 }).then(deferred.resolve, deferred.reject);
michael@0 103
michael@0 104 return deferred.promise;
michael@0 105 }
michael@0 106 exports.query = query;
michael@0 107
michael@0 108 function createQuery (query) {
michael@0 109 query = query || {};
michael@0 110 let queryObj = historyService.getNewQuery();
michael@0 111
michael@0 112 safeMerge(queryObj, omit(query, MANUAL_QUERY_PROPERTIES));
michael@0 113
michael@0 114 if (query.tags && Array.isArray(query.tags))
michael@0 115 queryObj.tags = query.tags;
michael@0 116 if (query.uri || query.url)
michael@0 117 queryObj.uri = newURI(query.uri || query.url);
michael@0 118 if (query.folder)
michael@0 119 queryObj.setFolders([query.folder], 1);
michael@0 120 return queryObj;
michael@0 121 }
michael@0 122
michael@0 123 function queryReceiver (message) {
michael@0 124 let queries = message.data.queries || message.data.query;
michael@0 125 let options = message.data.options;
michael@0 126 let resData = {
michael@0 127 id: message.id,
michael@0 128 event: message.event
michael@0 129 };
michael@0 130
michael@0 131 query(queries, options).then(results => {
michael@0 132 resData.data = results;
michael@0 133 respond(resData);
michael@0 134 }, reason => {
michael@0 135 resData.error = reason;
michael@0 136 respond(resData);
michael@0 137 });
michael@0 138 }
michael@0 139
michael@0 140 /*
michael@0 141 * Converts a nsINavHistoryResultNode into a plain object
michael@0 142 *
michael@0 143 * https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryResultNode
michael@0 144 */
michael@0 145 function normalize (historyObj) {
michael@0 146 return PLACES_PROPERTIES.reduce((obj, prop) => {
michael@0 147 if (prop === 'uri')
michael@0 148 obj.url = historyObj.uri;
michael@0 149 else if (prop === 'time') {
michael@0 150 // Cast from microseconds to milliseconds
michael@0 151 obj.time = Math.floor(historyObj.time / 1000)
michael@0 152 } else if (prop === 'accessCount')
michael@0 153 obj.visitCount = historyObj[prop];
michael@0 154 else
michael@0 155 obj[prop] = historyObj[prop];
michael@0 156 return obj;
michael@0 157 }, {});
michael@0 158 }
michael@0 159
michael@0 160 /*
michael@0 161 * Hook into host
michael@0 162 */
michael@0 163
michael@0 164 let reqStream = filter(request, function (data) /sdk-places-query/.test(data.event));
michael@0 165 on(reqStream, 'data', function (e) {
michael@0 166 if (EVENT_MAP[e.event]) EVENT_MAP[e.event](e);
michael@0 167 });
michael@0 168
michael@0 169 function respond (data) {
michael@0 170 emit(response, 'data', data);
michael@0 171 }

mercurial