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.

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

mercurial