DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (04da00a61c6d)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var EXPORTED_SYMBOLS = ["AboutNewTab"];

const { XPCOMUtils } = ChromeUtils.import(
  "resource://gre/modules/XPCOMUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");

XPCOMUtils.defineLazyModuleGetters(this, {
  ActivityStream: "resource://activity-stream/lib/ActivityStream.jsm",
  RemotePages:
    "resource://gre/modules/remotepagemanager/RemotePageManagerParent.jsm",
});

const BROWSER_READY_NOTIFICATION = "sessionstore-windows-restored";

var AboutNewTab = {
  QueryInterface: ChromeUtils.generateQI([
    Ci.nsIObserver,
    Ci.nsISupportsWeakReference,
  ]),

  // AboutNewTab

  pageListener: null,

  isOverridden: false,

  activityStream: null,

  /**
   * init - Initializes an instance of Activity Stream if one doesn't exist already
   *        and creates the instance of Remote Page Manager which Activity Stream
   *        uses for message passing.
   *
   * @param {obj} pageListener - Optional argument. An existing instance of RemotePages
   *                             which Activity Stream has previously made, and we
   *                             would like to re-use.
   */
  init(pageListener) {
    if (this.isOverridden) {
      return;
    }

    // Since `init` can be called via `reset` at a later time with an existing
    // pageListener, we want to only add the observer if we are initializing
    // without this pageListener argument. This means it was the first call to `init`
    if (!pageListener) {
      Services.obs.addObserver(this, BROWSER_READY_NOTIFICATION);
    }

    this.pageListener =
      pageListener ||
      new RemotePages(["about:home", "about:newtab", "about:welcome"]);
  },

  /**
   * onBrowserReady - Continues the initialization of Activity Stream after browser is ready.
   */
  onBrowserReady() {
    if (this.activityStream && this.activityStream.initialized) {
      return;
    }

    this.activityStream = new ActivityStream();
    try {
      this.activityStream.init();
    } catch (e) {
      Cu.reportError(e);
    }
  },

  /**
   * uninit - Uninitializes Activity Stream if it exists, and destroys the pageListener
   *        if it exists.
   */
  uninit() {
    if (this.activityStream) {
      this.activityStream.uninit();
      this.activityStream = null;
    }

    if (this.pageListener) {
      this.pageListener.destroy();
      this.pageListener = null;
    }
  },

  override(shouldPassPageListener) {
    this.isOverridden = true;
    const pageListener = this.pageListener;
    if (!pageListener) {
      return null;
    }
    if (shouldPassPageListener) {
      this.pageListener = null;
      return pageListener;
    }
    this.uninit();
    return null;
  },

  reset(pageListener) {
    this.isOverridden = false;
    this.init(pageListener);
  },

  getTopSites() {
    return this.activityStream
      ? this.activityStream.store.getState().TopSites.rows
      : [];
  },

  // nsIObserver implementation

  observe(subject, topic, data) {
    switch (topic) {
      case BROWSER_READY_NOTIFICATION:
        Services.obs.removeObserver(this, BROWSER_READY_NOTIFICATION);
        // Avoid running synchronously during this event that's used for timing
        Services.tm.dispatchToMainThread(() => this.onBrowserReady());
        break;
    }
  },
};