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