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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 browserHistory = Cc["@mozilla.org/browser/nav-history-service;1"].
    16                        getService(Ci.nsIBrowserHistory);
    17 const asyncHistory = Cc["@mozilla.org/browser/history;1"].
    18                      getService(Ci.mozIAsyncHistory);
    19 const bmsrv = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
    20                         getService(Ci.nsINavBookmarksService);
    21 const taggingService = Cc["@mozilla.org/browser/tagging-service;1"].
    22                        getService(Ci.nsITaggingService);
    23 const ios = Cc['@mozilla.org/network/io-service;1'].
    24             getService(Ci.nsIIOService);
    25 const { query } = require('./host-query');
    26 const {
    27   defer, all, resolve, promised, reject
    28 } = require('../../core/promise');
    29 const { request, response } = require('../../addon/host');
    30 const { send } = require('../../addon/events');
    31 const { on, emit } = require('../../event/core');
    32 const { filter } = require('../../event/utils');
    33 const { URL, isValidURI } = require('../../url');
    34 const { newURI } = require('../../url/utils');
    36 const DEFAULT_INDEX = bmsrv.DEFAULT_INDEX;
    37 const UNSORTED_ID = bmsrv.unfiledBookmarksFolder;
    38 const ROOT_FOLDERS = [
    39   bmsrv.unfiledBookmarksFolder, bmsrv.toolbarFolder,
    40   bmsrv.tagsFolder, bmsrv.bookmarksMenuFolder
    41 ];
    43 const EVENT_MAP = {
    44   'sdk-places-bookmarks-create': createBookmarkItem,
    45   'sdk-places-bookmarks-save': saveBookmarkItem,
    46   'sdk-places-bookmarks-last-updated': getBookmarkLastUpdated,
    47   'sdk-places-bookmarks-get': getBookmarkItem,
    48   'sdk-places-bookmarks-remove': removeBookmarkItem,
    49   'sdk-places-bookmarks-get-all': getAllBookmarks,
    50   'sdk-places-bookmarks-get-children': getChildren
    51 };
    53 function typeMap (type) {
    54   if (typeof type === 'number') {
    55     if (bmsrv.TYPE_BOOKMARK === type) return 'bookmark';
    56     if (bmsrv.TYPE_FOLDER === type) return 'group';
    57     if (bmsrv.TYPE_SEPARATOR === type) return 'separator';
    58   } else {
    59     if ('bookmark' === type) return bmsrv.TYPE_BOOKMARK;
    60     if ('group' === type) return bmsrv.TYPE_FOLDER;
    61     if ('separator' === type) return bmsrv.TYPE_SEPARATOR;
    62   }
    63 }
    65 function getBookmarkLastUpdated ({id})
    66   resolve(bmsrv.getItemLastModified(id))
    67 exports.getBookmarkLastUpdated;
    69 function createBookmarkItem (data) {
    70   let error;
    72   if (data.group == null) data.group = UNSORTED_ID;
    73   if (data.index == null) data.index = DEFAULT_INDEX;
    75   if (data.type === 'group')
    76     data.id = bmsrv.createFolder(
    77       data.group, data.title, data.index
    78     );
    79   else if (data.type === 'separator')
    80     data.id = bmsrv.insertSeparator(
    81       data.group, data.index
    82     );
    83   else
    84     data.id = bmsrv.insertBookmark(
    85       data.group, newURI(data.url), data.index, data.title
    86     );
    88   // In the event where default or no index is provided (-1),
    89   // query the actual index for the response
    90   if (data.index === -1)
    91     data.index = bmsrv.getItemIndex(data.id);
    93   data.updated = bmsrv.getItemLastModified(data.id);
    95   return tag(data, true).then(() => data);
    96 }
    97 exports.createBookmarkItem = createBookmarkItem;
    99 function saveBookmarkItem (data) {
   100   let id = data.id;
   101   if (!id)
   102     reject('Item is missing id');
   104   let group = bmsrv.getFolderIdForItem(id);
   105   let index = bmsrv.getItemIndex(id);
   106   let type = bmsrv.getItemType(id);
   107   let title = typeMap(type) !== 'separator' ?
   108     bmsrv.getItemTitle(id) :
   109     undefined;
   110   let url = typeMap(type) === 'bookmark' ?
   111     bmsrv.getBookmarkURI(id).spec :
   112     undefined;
   114   if (url != data.url)
   115     bmsrv.changeBookmarkURI(id, newURI(data.url));
   116   else if (typeMap(type) === 'bookmark')
   117     data.url = url;
   119   if (title != data.title)
   120     bmsrv.setItemTitle(id, data.title);
   121   else if (typeMap(type) !== 'separator')
   122     data.title = title;
   124   if (data.group && data.group !== group)
   125     bmsrv.moveItem(id, data.group, data.index || -1);
   126   else if (data.index != null && data.index !== index) {
   127     // We use moveItem here instead of setItemIndex
   128     // so we don't have to manage the indicies of the siblings
   129     bmsrv.moveItem(id, group, data.index);
   130   } else if (data.index == null)
   131     data.index = index;
   133   data.updated = bmsrv.getItemLastModified(data.id);
   135   return tag(data).then(() => data);
   136 }
   137 exports.saveBookmarkItem = saveBookmarkItem;
   139 function removeBookmarkItem (data) {
   140   let id = data.id;
   142   if (!id)
   143     reject('Item is missing id');
   145   bmsrv.removeItem(id);
   146   return resolve(null);
   147 }
   148 exports.removeBookmarkItem = removeBookmarkItem;
   150 function getBookmarkItem (data) {
   151   let id = data.id;
   153   if (!id)
   154     reject('Item is missing id');
   156   let type = bmsrv.getItemType(id);
   158   data.type = typeMap(type);
   160   if (type === bmsrv.TYPE_BOOKMARK || type === bmsrv.TYPE_FOLDER)
   161     data.title = bmsrv.getItemTitle(id);
   163   if (type === bmsrv.TYPE_BOOKMARK) {
   164     data.url = bmsrv.getBookmarkURI(id).spec;
   165     // Should be moved into host-tags as a method
   166     data.tags = taggingService.getTagsForURI(newURI(data.url), {});
   167   }
   169   data.group = bmsrv.getFolderIdForItem(id);
   170   data.index = bmsrv.getItemIndex(id);
   171   data.updated = bmsrv.getItemLastModified(data.id);
   173   return resolve(data);
   174 }
   175 exports.getBookmarkItem = getBookmarkItem;
   177 function getAllBookmarks () {
   178   return query({}, { queryType: 1 }).then(bookmarks =>
   179     all(bookmarks.map(getBookmarkItem)));
   180 }
   181 exports.getAllBookmarks = getAllBookmarks;
   183 function getChildren ({ id }) {
   184   if (typeMap(bmsrv.getItemType(id)) !== 'group') return [];
   185   let ids = [];
   186   for (let i = 0; ids[ids.length - 1] !== -1; i++)
   187     ids.push(bmsrv.getIdForItemAt(id, i));
   188   ids.pop();
   189   return all(ids.map(id => getBookmarkItem({ id: id })));
   190 }
   191 exports.getChildren = getChildren;
   193 /*
   194  * Hook into host
   195  */
   197 let reqStream = filter(request, function (data) /sdk-places-bookmarks/.test(data.event));
   198 on(reqStream, 'data', function ({event, id, data}) {
   199   if (!EVENT_MAP[event]) return;
   201   let resData = {
   202     id: id,
   203     event: event
   204   };
   206   promised(EVENT_MAP[event])(data).then(res => {
   207     resData.data = res;
   208     respond(resData);
   209   }, reason => {
   210     resData.error = reason;
   211     respond(resData);
   212   });
   213 });
   215 function respond (data) {
   216   emit(response, 'data', data);
   217 }
   219 function tag (data, isNew) {
   220   // If a new item, we can skip checking what other tags
   221   // are on the item
   222   if (data.type !== 'bookmark') {
   223     return resolve();
   224   } else if (!isNew) {
   225     return send('sdk-places-tags-get-tags-by-url', { url: data.url })
   226       .then(tags => {
   227         return send('sdk-places-tags-untag', {
   228           tags: tags.filter(tag => !~data.tags.indexOf(tag)),
   229           url: data.url
   230         });
   231       }).then(() => send('sdk-places-tags-tag', {
   232         url: data.url, tags: data.tags
   233       }));
   234   }
   235   else if (data.tags && data.tags.length) {
   236     return send('sdk-places-tags-tag', { url: data.url, tags: data.tags });
   237   }
   238   else
   239     return resolve();
   240 }

mercurial