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/**
6 * TS-TODO - Needs typing.
7 *
8 * This file contains type stubs for loading things from Gecko. All of these
9 * types should be used in the correct places eventually.
10 */
11
12/**
13 * Namespace anything that has its types mocked out here. These definitions are
14 * only "good enough" to get the type checking to pass in this directory.
15 * Eventually some more structured solution should be found. This namespace is
16 * global and makes sure that all the definitions inside do not clash with
17 * naming.
18 */
19declare namespace MockedExports {
20  /**
21   * This interface teaches ChromeUtils.import how to find modules.
22   */
23  interface KnownModules {
24    "resource://gre/modules/Services.jsm": typeof import("resource://gre/modules/Services.jsm");
25    Services: typeof import("Services");
26    chrome: typeof import("chrome");
27    "resource://gre/modules/osfile.jsm": typeof import("resource://gre/modules/osfile.jsm");
28    "resource://gre/modules/AppConstants.jsm": typeof import("resource://gre/modules/AppConstants.jsm");
29    "resource:///modules/CustomizableUI.jsm": typeof import("resource:///modules/CustomizableUI.jsm");
30    "resource:///modules/CustomizableWidgets.jsm": typeof import("resource:///modules/CustomizableWidgets.jsm");
31    "resource://devtools/shared/loader/Loader.jsm": typeof import("resource://devtools/shared/loader/Loader.jsm");
32    "resource://devtools/client/performance-new/popup/background.jsm.js": typeof import("resource://devtools/client/performance-new/popup/background.jsm.js");
33    "resource://devtools/shared/loader/browser-loader.js": any;
34    "resource://devtools/client/performance-new/popup/menu-button.jsm.js": typeof import("devtools/client/performance-new/popup/menu-button.jsm.js");
35    "resource://devtools/client/performance-new/typescript-lazy-load.jsm.js": typeof import("devtools/client/performance-new/typescript-lazy-load.jsm.js");
36    "resource://devtools/client/performance-new/popup/panel.jsm.js": typeof import("devtools/client/performance-new/popup/panel.jsm.js");
37    "resource://devtools/client/performance-new/symbolication.jsm.js": typeof import("resource://devtools/client/performance-new/symbolication.jsm.js");
38    "resource:///modules/PanelMultiView.jsm": typeof import("resource:///modules/PanelMultiView.jsm");
39  }
40
41  interface ChromeUtils {
42    /**
43     * This function reads the KnownModules and resolves which import to use.
44     * If you are getting the TS2345 error:
45     *
46     *  Argument of type '"resource:///.../file.jsm"' is not assignable to parameter
47     *  of type
48     *
49     * Then add the file path to the KnownModules above.
50     */
51    import: <S extends keyof KnownModules>(module: S) => KnownModules[S];
52    defineModuleGetter: (target: any, variable: string, path: string) => void;
53  }
54
55  interface MessageManager {
56    loadFrameScript(url: string, flag: boolean): void;
57    sendAsyncMessage: (event: string, data: any) => void;
58    addMessageListener: (event: string, listener: (event: any) => void) => void;
59  }
60
61  interface Browser {
62    addWebTab: (url: string, options: any) => BrowserTab;
63    contentPrincipal: any;
64    selectedTab: BrowserTab;
65    selectedBrowser?: ChromeBrowser;
66    messageManager: MessageManager;
67    ownerDocument?: ChromeDocument;
68  }
69
70  interface BrowserTab {
71    linkedBrowser: Browser;
72  }
73
74  interface ChromeWindow {
75    gBrowser: Browser;
76    focus(): void;
77    openWebLinkIn(
78      url: string,
79      where: "current" | "tab" | "window",
80      options: Partial<{
81        // Not all possible options are present, please add more if/when needed.
82        userContextId: number;
83        forceNonPrivate: boolean;
84        resolveOnContentBrowserCreated: (
85          contentBrowser: ChromeBrowser
86        ) => unknown;
87      }>
88    ): void;
89  }
90
91  interface ChromeBrowser {
92    browsingContext?: BrowsingContext;
93  }
94
95  interface BrowsingContext {
96    /**
97     * A unique identifier for the browser element that is hosting this
98     * BrowsingContext tree. Every BrowsingContext in the element's tree will
99     * return the same ID in all processes and it will remain stable regardless of
100     * process changes. When a browser element's frameloader is switched to
101     * another browser element this ID will remain the same but hosted under the
102     * under the new browser element.
103     * We are using this identifier for getting the active tab ID and passing to
104     * the profiler back-end. See `getActiveBrowserID` for the usage.
105     */
106    browserId: number;
107  }
108
109  type GetPref<T> = (prefName: string, defaultValue?: T) => T;
110  type SetPref<T> = (prefName: string, value?: T) => T;
111  type nsIPrefBranch = {
112    clearUserPref: (prefName: string) => void;
113    getStringPref: GetPref<string>;
114    setStringPref: SetPref<string>;
115    getCharPref: GetPref<string>;
116    setCharPref: SetPref<string>;
117    getIntPref: GetPref<number>;
118    setIntPref: SetPref<number>;
119    getBoolPref: GetPref<boolean>;
120    setBoolPref: SetPref<boolean>;
121    addObserver: (
122      aDomain: string,
123      aObserver: PrefObserver,
124      aHoldWeak?: boolean
125    ) => void;
126    removeObserver: (aDomain: string, aObserver: PrefObserver) => void;
127  };
128
129  type PrefObserverFunction = (
130    aSubject: nsIPrefBranch,
131    aTopic: "nsPref:changed",
132    aData: string
133  ) => unknown;
134  type PrefObserver = PrefObserverFunction | { observe: PrefObserverFunction };
135
136  interface nsIURI {}
137
138  interface SharedLibrary {
139    start: number;
140    end: number;
141    offset: number;
142    name: string;
143    path: string;
144    debugName: string;
145    debugPath: string;
146    breakpadId: string;
147    arch: string;
148  }
149
150  type Services = {
151    prefs: nsIPrefBranch;
152    profiler: {
153      StartProfiler: (
154        entryCount: number,
155        interval: number,
156        features: string[],
157        filters?: string[],
158        activeTabId?: number,
159        duration?: number
160      ) => void;
161      StopProfiler: () => void;
162      IsPaused: () => boolean;
163      Pause: () => void;
164      Resume: () => void;
165      IsSamplingPaused: () => boolean;
166      PauseSampling: () => void;
167      ResumeSampling: () => void;
168      GetFeatures: () => string[];
169      getProfileDataAsync: (sinceTime?: number) => Promise<object>;
170      getProfileDataAsArrayBuffer: (sinceTime?: number) => Promise<ArrayBuffer>;
171      getProfileDataAsGzippedArrayBuffer: (
172        sinceTime?: number
173      ) => Promise<ArrayBuffer>;
174      IsActive: () => boolean;
175      sharedLibraries: SharedLibrary[];
176    };
177    platform: string;
178    obs: {
179      addObserver: (observer: object, type: string) => void;
180      removeObserver: (observer: object, type: string) => void;
181    };
182    wm: {
183      getMostRecentWindow: (name: string) => ChromeWindow;
184      getMostRecentNonPBWindow: (name: string) => ChromeWindow;
185    };
186    focus: {
187      activeWindow: ChromeWindow;
188    };
189    io: {
190      newURI(url: string): nsIURI;
191    };
192    scriptSecurityManager: any;
193    startup: {
194      quit: (optionsBitmask: number) => void;
195      eForceQuit: number;
196      eRestart: number;
197    };
198  };
199
200  const ServicesJSM: {
201    Services: Services;
202  };
203
204  const EventEmitter: {
205    decorate: (target: object) => void;
206  };
207
208  const AppConstantsJSM: {
209    AppConstants: {
210      platform: string;
211    };
212  };
213
214  const osfileJSM: {
215    OS: {
216      Path: {
217        split: (
218          path: string
219        ) => {
220          absolute: boolean;
221          components: string[];
222          winDrive?: string;
223        };
224        join: (...pathParts: string[]) => string;
225      };
226      File: {
227        stat: (path: string) => Promise<{ isDir: boolean }>;
228        Error: any;
229      };
230    };
231  };
232
233  interface BrowsingContextStub {}
234  interface PrincipalStub {}
235
236  interface WebChannelTarget {
237    browsingContext: BrowsingContextStub;
238    browser: Browser;
239    eventTarget: null;
240    principal: PrincipalStub;
241  }
242
243  const WebChannelJSM: any;
244
245  // TS-TODO
246  const CustomizableUIJSM: any;
247  const CustomizableWidgetsJSM: any;
248  const PanelMultiViewJSM: any;
249
250  const LoaderJSM: {
251    require: (path: string) => any;
252  };
253
254  const Services: Services;
255
256  // This class is needed by the Cc importing mechanism. e.g.
257  // Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
258  class nsIFilePicker {}
259
260  interface FilePicker {
261    init: (window: Window, title: string, mode: number) => void;
262    open: (callback: (rv: number) => unknown) => void;
263    // The following are enum values.
264    modeGetFolder: number;
265    returnOK: number;
266    file: {
267      path: string;
268    };
269  }
270
271  // This class is needed by the Cc importing mechanism. e.g.
272  // Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
273  class nsIEnvironment {}
274
275  interface Environment {
276    exists(envName: string): boolean;
277    get(envName: string): string;
278    set(envName: string, value: string): void;
279  }
280
281  interface Cc {
282    "@mozilla.org/process/environment;1": {
283      getService(service: nsIEnvironment): Environment;
284    };
285    "@mozilla.org/filepicker;1": {
286      createInstance(instance: nsIFilePicker): FilePicker;
287    };
288  }
289
290  interface Ci {
291    nsIFilePicker: nsIFilePicker;
292    nsIEnvironment: nsIEnvironment;
293  }
294
295  interface Cu {
296    /**
297     * This function reads the KnownModules and resolves which import to use.
298     * If you are getting the TS2345 error:
299     *
300     *  Argument of type '"resource:///.../file.jsm"' is not assignable to parameter
301     *  of type
302     *
303     * Then add the file path to the KnownModules above.
304     */
305    import: <S extends keyof KnownModules>(module: S) => KnownModules[S];
306    exportFunction: (fn: Function, scope: object, options?: object) => void;
307    cloneInto: (value: any, scope: object, options?: object) => void;
308    isInAutomation: boolean;
309  }
310
311  const chrome: {
312    Cc: Cc;
313    Ci: Ci;
314    Cu: Cu;
315  };
316
317  interface FluentLocalization {
318    /**
319     * This function sets the attributes data-l10n-id and possibly data-l10n-args
320     * on the element.
321     */
322    setAttributes(
323      target: Element,
324      id?: string,
325      args?: Record<string, string>
326    ): void;
327  }
328}
329
330declare module "devtools/client/shared/vendor/react" {
331  import * as React from "react";
332  export = React;
333}
334
335declare module "devtools/client/shared/vendor/react-dom-factories" {
336  import * as ReactDomFactories from "react-dom-factories";
337  export = ReactDomFactories;
338}
339
340declare module "devtools/client/shared/vendor/redux" {
341  import * as Redux from "redux";
342  export = Redux;
343}
344
345declare module "devtools/client/shared/vendor/react-redux" {
346  import * as ReactRedux from "react-redux";
347  export = ReactRedux;
348}
349
350declare module "devtools/shared/event-emitter2" {
351  export = MockedExports.EventEmitter;
352}
353
354declare module "resource://gre/modules/Services.jsm" {
355  export = MockedExports.ServicesJSM;
356}
357
358declare module "Services" {
359  export = MockedExports.Services;
360}
361
362declare module "chrome" {
363  export = MockedExports.chrome;
364}
365
366declare module "ChromeUtils" {
367  export = ChromeUtils;
368}
369
370declare module "resource://gre/modules/osfile.jsm" {
371  export = MockedExports.osfileJSM;
372}
373
374declare module "resource://gre/modules/AppConstants.jsm" {
375  export = MockedExports.AppConstantsJSM;
376}
377
378declare module "resource://gre/modules/WebChannel.jsm" {
379  export = MockedExports.WebChannelJSM;
380}
381
382declare module "resource://devtools/client/performance-new/popup/background.jsm.js" {
383  import * as Background from "devtools/client/performance-new/popup/background.jsm.js";
384  export = Background;
385}
386
387declare module "resource://devtools/client/performance-new/symbolication.jsm.js" {
388  import * as PerfSymbolication from "devtools/client/performance-new/symbolication.jsm.js";
389  export = PerfSymbolication;
390}
391
392declare module "resource:///modules/CustomizableUI.jsm" {
393  export = MockedExports.CustomizableUIJSM;
394}
395
396declare module "resource:///modules/CustomizableWidgets.jsm" {
397  export = MockedExports.CustomizableWidgetsJSM;
398}
399
400declare module "resource:///modules/PanelMultiView.jsm" {
401  export = MockedExports.PanelMultiViewJSM;
402}
403
404declare module "resource://devtools/shared/loader/Loader.jsm" {
405  export = MockedExports.LoaderJSM;
406}
407
408declare var ChromeUtils: MockedExports.ChromeUtils;
409
410// These global objects can be used directly in JSM files only.
411// In a CommonJS context you need to import them with `require("chrome")`.
412declare var Cu: MockedExports.Cu;
413declare var Cc: MockedExports.Cc;
414declare var Ci: MockedExports.Ci;
415
416/**
417 * This is a variant on the normal Document, as it contains chrome-specific properties.
418 */
419declare interface ChromeDocument extends Document {
420  /**
421   * Create a XUL element of a specific type. Right now this function
422   * only refines iframes, but more tags could be added.
423   */
424  createXULElement: ((type: "iframe") => XULIframeElement) &
425    ((type: string) => XULElement);
426
427  /**
428   * This is a fluent instance connected to this document.
429   */
430  l10n: MockedExports.FluentLocalization;
431}
432
433/**
434 * This is a variant on the HTMLElement, as it contains chrome-specific properties.
435 */
436declare interface ChromeHTMLElement extends HTMLElement {
437  ownerDocument: ChromeDocument;
438}
439
440declare interface XULElement extends HTMLElement {
441  ownerDocument: ChromeDocument;
442}
443
444declare interface XULIframeElement extends XULElement {
445  contentWindow: ChromeWindow;
446  src: string;
447}
448
449declare interface ChromeWindow extends Window {
450  openWebLinkIn: (
451    url: string,
452    where: "current" | "tab" | "tabshifted" | "window" | "save",
453    // TS-TODO
454    params?: unknown
455  ) => void;
456  openTrustedLinkIn: (
457    url: string,
458    where: "current" | "tab" | "tabshifted" | "window" | "save",
459    // TS-TODO
460    params?: unknown
461  ) => void;
462}
463
464declare class ChromeWorker extends Worker {}
465
466declare interface MenuListElement extends XULElement {
467  value: string;
468  disabled: boolean;
469}
470
471declare interface XULCommandEvent extends Event {
472  target: XULElement;
473}
474
475declare interface XULElementWithCommandHandler {
476  addEventListener: (
477    type: "command",
478    handler: (event: XULCommandEvent) => void,
479    isCapture?: boolean
480  ) => void;
481  removeEventListener: (
482    type: "command",
483    handler: (event: XULCommandEvent) => void,
484    isCapture?: boolean
485  ) => void;
486}
487
488declare type nsIPrefBranch = MockedExports.nsIPrefBranch;
489