events.js 3.5 KB

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