|
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/. */ |
|
4 |
|
5 'use strict'; |
|
6 |
|
7 module.metadata = { |
|
8 'stability': 'experimental', |
|
9 'engines': { |
|
10 'Firefox': '*' |
|
11 } |
|
12 }; |
|
13 |
|
14 const { Cc, Ci } = require('chrome'); |
|
15 const { Unknown } = require('../platform/xpcom'); |
|
16 const { Class } = require('../core/heritage'); |
|
17 const { merge } = require('../util/object'); |
|
18 const bookmarkService = Cc['@mozilla.org/browser/nav-bookmarks-service;1'] |
|
19 .getService(Ci.nsINavBookmarksService); |
|
20 const historyService = Cc['@mozilla.org/browser/nav-history-service;1'] |
|
21 .getService(Ci.nsINavHistoryService); |
|
22 const { mapBookmarkItemType } = require('./utils'); |
|
23 const { EventTarget } = require('../event/target'); |
|
24 const { emit } = require('../event/core'); |
|
25 |
|
26 const emitter = EventTarget(); |
|
27 |
|
28 let HISTORY_ARGS = { |
|
29 onBeginUpdateBatch: [], |
|
30 onEndUpdateBatch: [], |
|
31 onClearHistory: [], |
|
32 onDeleteURI: ['url'], |
|
33 onDeleteVisits: ['url', 'visitTime'], |
|
34 onPageChanged: ['url', 'property', 'value'], |
|
35 onTitleChanged: ['url', 'title'], |
|
36 onVisit: [ |
|
37 'url', 'visitId', 'time', 'sessionId', 'referringId', 'transitionType' |
|
38 ] |
|
39 }; |
|
40 |
|
41 let HISTORY_EVENTS = { |
|
42 onBeginUpdateBatch: 'history-start-batch', |
|
43 onEndUpdateBatch: 'history-end-batch', |
|
44 onClearHistory: 'history-start-clear', |
|
45 onDeleteURI: 'history-delete-url', |
|
46 onDeleteVisits: 'history-delete-visits', |
|
47 onPageChanged: 'history-page-changed', |
|
48 onTitleChanged: 'history-title-changed', |
|
49 onVisit: 'history-visit' |
|
50 }; |
|
51 |
|
52 let BOOKMARK_ARGS = { |
|
53 onItemAdded: [ |
|
54 'id', 'parentId', 'index', 'type', 'url', 'title', 'dateAdded' |
|
55 ], |
|
56 onItemChanged: [ |
|
57 'id', 'property', null, 'value', 'lastModified', 'type', 'parentId' |
|
58 ], |
|
59 onItemMoved: [ |
|
60 'id', 'previousParentId', 'previousIndex', 'currentParentId', |
|
61 'currentIndex', 'type' |
|
62 ], |
|
63 onItemRemoved: ['id', 'parentId', 'index', 'type', 'url'], |
|
64 onItemVisited: ['id', 'visitId', 'time', 'transitionType', 'url', 'parentId'] |
|
65 }; |
|
66 |
|
67 let BOOKMARK_EVENTS = { |
|
68 onItemAdded: 'bookmark-item-added', |
|
69 onItemChanged: 'bookmark-item-changed', |
|
70 onItemMoved: 'bookmark-item-moved', |
|
71 onItemRemoved: 'bookmark-item-removed', |
|
72 onItemVisited: 'bookmark-item-visited', |
|
73 }; |
|
74 |
|
75 function createHandler (type, propNames) { |
|
76 propNames = propNames || []; |
|
77 return function (...args) { |
|
78 let data = propNames.reduce((acc, prop, i) => { |
|
79 if (prop) |
|
80 acc[prop] = formatValue(prop, args[i]); |
|
81 return acc; |
|
82 }, {}); |
|
83 |
|
84 emit(emitter, 'data', { |
|
85 type: type, |
|
86 data: data |
|
87 }); |
|
88 }; |
|
89 } |
|
90 |
|
91 /* |
|
92 * Creates an observer, creating handlers based off of |
|
93 * the `events` names, and ordering arguments from `propNames` hash |
|
94 */ |
|
95 function createObserverInstance (events, propNames) { |
|
96 let definition = Object.keys(events).reduce((prototype, eventName) => { |
|
97 prototype[eventName] = createHandler(events[eventName], propNames[eventName]); |
|
98 return prototype; |
|
99 }, {}); |
|
100 |
|
101 return Class(merge(definition, { extends: Unknown }))(); |
|
102 } |
|
103 |
|
104 /* |
|
105 * Formats `data` based off of the value of `type` |
|
106 */ |
|
107 function formatValue (type, data) { |
|
108 if (type === 'type') |
|
109 return mapBookmarkItemType(data); |
|
110 if (type === 'url' && data) |
|
111 return data.spec; |
|
112 return data; |
|
113 } |
|
114 |
|
115 let historyObserver = createObserverInstance(HISTORY_EVENTS, HISTORY_ARGS); |
|
116 historyService.addObserver(historyObserver, false); |
|
117 |
|
118 let bookmarkObserver = createObserverInstance(BOOKMARK_EVENTS, BOOKMARK_ARGS); |
|
119 bookmarkService.addObserver(bookmarkObserver, false); |
|
120 |
|
121 exports.events = emitter; |