summaryrefslogtreecommitdiffstats
path: root/devtools/server/actors/webconsole/listeners/console-file-activity.js
blob: 7e5ae0d1a82e59cf019f558de382d71e5c0fddfa (plain)
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
/* 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";

/**
 * A WebProgressListener that listens for file loads.
 *
 * @constructor
 * @param object window
 *        The window for which we need to track file loads.
 * @param object owner
 *        The listener owner which needs to implement:
 *        - onFileActivity(aFileURI)
 */
function ConsoleFileActivityListener(window, owner) {
  this.window = window;
  this.owner = owner;
}
exports.ConsoleFileActivityListener = ConsoleFileActivityListener;

ConsoleFileActivityListener.prototype = {
  /**
   * Tells if the console progress listener is initialized or not.
   * @private
   * @type boolean
   */
  _initialized: false,

  _webProgress: null,

  QueryInterface: ChromeUtils.generateQI([
    "nsIWebProgressListener",
    "nsISupportsWeakReference",
  ]),

  /**
   * Initialize the ConsoleFileActivityListener.
   * @private
   */
  _init() {
    if (this._initialized) {
      return;
    }

    this._webProgress = this.window.docShell.QueryInterface(Ci.nsIWebProgress);
    this._webProgress.addProgressListener(
      this,
      Ci.nsIWebProgress.NOTIFY_STATE_ALL
    );

    this._initialized = true;
  },

  /**
   * Start a monitor/tracker related to the current nsIWebProgressListener
   * instance.
   */
  startMonitor() {
    this._init();
  },

  /**
   * Stop monitoring.
   */
  stopMonitor() {
    this.destroy();
  },

  onStateChange(progress, request, state, status) {
    if (!this.owner) {
      return;
    }

    this._checkFileActivity(progress, request, state, status);
  },

  /**
   * Check if there is any file load, given the arguments of
   * nsIWebProgressListener.onStateChange. If the state change tells that a file
   * URI has been loaded, then the remote Web Console instance is notified.
   * @private
   */
  _checkFileActivity(progress, request, state, status) {
    if (!(state & Ci.nsIWebProgressListener.STATE_START)) {
      return;
    }

    let uri = null;
    if (request instanceof Ci.imgIRequest) {
      const imgIRequest = request.QueryInterface(Ci.imgIRequest);
      uri = imgIRequest.URI;
    } else if (request instanceof Ci.nsIChannel) {
      const nsIChannel = request.QueryInterface(Ci.nsIChannel);
      uri = nsIChannel.URI;
    }

    if (!uri || (!uri.schemeIs("file") && !uri.schemeIs("ftp"))) {
      return;
    }

    this.owner.onFileActivity(uri.spec);
  },

  /**
   * Destroy the ConsoleFileActivityListener.
   */
  destroy() {
    if (!this._initialized) {
      return;
    }

    this._initialized = false;

    try {
      this._webProgress.removeProgressListener(this);
    } catch (ex) {
      // This can throw during browser shutdown.
    }

    this._webProgress = null;
    this.window = null;
    this.owner = null;
  },
};