Bug 1427419 - Part 1: Add an InspectorUtils chrome-only IDL namespace. r=bz,tromey draft
authorCameron McCormack <cam@mcc.id.au>
Sat, 06 Jan 2018 15:08:13 +0800
changeset 716746 1c5cb6ecca60ce21ba63f004c1b0c36b5db20a21
parent 716638 9099a6ed993f0113c47c0d9e800bf0ff6e1a1dc1
child 716747 27c2c20a1c5b9825871532da9027910fdb3e7a17
push id94496
push userbmo:cam@mcc.id.au
push dateSat, 06 Jan 2018 07:08:40 +0000
reviewersbz, tromey
bugs1427419
milestone59.0a1
Bug 1427419 - Part 1: Add an InspectorUtils chrome-only IDL namespace. r=bz,tromey Also add a way to access it from SpecialPowers for tests and from importGlobalProperties for system JS scopes. MozReview-Commit-ID: IewEs0Gf2M9
devtools/shared/builtin-modules.js
dom/webidl/InspectorUtils.webidl
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/xpcprivate.h
layout/inspector/InspectorUtils.h
layout/inspector/moz.build
testing/specialpowers/content/specialpowersAPI.js
--- a/devtools/shared/builtin-modules.js
+++ b/devtools/shared/builtin-modules.js
@@ -18,19 +18,19 @@ const promise = Cu.import("resource://gr
 const jsmScope = Cu.import("resource://gre/modules/Services.jsm", {});
 const { Services } = jsmScope;
 // Steal various globals only available in JSM scope (and not Sandbox one)
 const { PromiseDebugging, ChromeUtils, HeapSnapshot,
         atob, btoa, TextEncoder, TextDecoder } = Cu.getGlobalForObject(jsmScope);
 
 // Create a single Sandbox to access global properties needed in this module.
 // Sandbox are memory expensive, so we should create as little as possible.
-const { CSS, FileReader, indexedDB, URL } =
+const { CSS, FileReader, indexedDB, InspectorUtils, URL } =
     Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), {
-      wantGlobalProperties: ["CSS", "FileReader", "indexedDB", "URL"]
+      wantGlobalProperties: ["CSS", "FileReader", "indexedDB", "InspectorUtils", "URL"]
     });
 
 /**
  * Defines a getter on a specified object that will be created upon first use.
  *
  * @param object
  *        The object to define the lazy getter on.
  * @param name
@@ -174,16 +174,17 @@ exports.modules = {
   promise,
   // Expose "chrome" Promise, which aren't related to any document
   // and so are never frozen, even if the browser loader module which
   // pull it is destroyed. See bug 1402779.
   Promise,
   PromiseDebugging,
   ChromeUtils,
   HeapSnapshot,
+  InspectorUtils,
   FileReader,
 };
 
 defineLazyGetter(exports.modules, "Debugger", () => {
   // addDebuggerToGlobal only allows adding the Debugger object to a global. The
   // this object is not guaranteed to be a global (in particular on B2G, due to
   // compartment sharing), so add the Debugger object to a sandbox instead.
   let sandbox = Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")());
--- a/dom/webidl/InspectorUtils.webidl
+++ b/dom/webidl/InspectorUtils.webidl
@@ -1,13 +1,21 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  */
+
+/**
+ * A collection of utility methods for use by devtools.
+ */
+[ChromeOnly]
+namespace InspectorUtils {
+};
+
 dictionary InspectorRGBTriple {
   /*
    * NOTE: Using octet for RGB components is not generally OK, because
    * they can be outside the 0-255 range, but for backwards-compatible
    * named colors (which is what we use this dictionary for) the 0-255
    * assumption is fine.
    */
   octet r = 0;
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -30,16 +30,17 @@
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/BlobBinding.h"
 #include "mozilla/dom/cache/CacheStorage.h"
 #include "mozilla/dom/CSSBinding.h"
 #include "mozilla/dom/DirectoryBinding.h"
 #include "mozilla/dom/IndexedDatabaseManager.h"
 #include "mozilla/dom/Fetch.h"
 #include "mozilla/dom/FileBinding.h"
+#include "mozilla/dom/InspectorUtilsBinding.h"
 #include "mozilla/dom/MessageChannelBinding.h"
 #include "mozilla/dom/MessagePortBinding.h"
 #include "mozilla/dom/PromiseBinding.h"
 #include "mozilla/dom/RequestBinding.h"
 #include "mozilla/dom/ResponseBinding.h"
 #ifdef MOZ_WEBRTC
 #include "mozilla/dom/RTCIdentityProviderRegistrar.h"
 #endif
@@ -939,16 +940,18 @@ xpc::GlobalProperties::Parse(JSContext* 
         } else if (!strcmp(name.ptr(), "fetch")) {
             fetch = true;
         } else if (!strcmp(name.ptr(), "caches")) {
             caches = true;
         } else if (!strcmp(name.ptr(), "FileReader")) {
             fileReader = true;
         } else if (!strcmp(name.ptr(), "MessageChannel")) {
             messageChannel = true;
+        } else if (!strcmp(name.ptr(), "InspectorUtils")) {
+            inspectorUtils = true;
         } else {
             JS_ReportErrorUTF8(cx, "Unknown property name: %s", name.ptr());
             return false;
         }
     }
     return true;
 }
 
@@ -1021,16 +1024,20 @@ xpc::GlobalProperties::Define(JSContext*
     if (fileReader && !dom::FileReaderBinding::GetConstructorObject(cx))
         return false;
 
     if (messageChannel &&
         (!dom::MessageChannelBinding::GetConstructorObject(cx) ||
          !dom::MessagePortBinding::GetConstructorObject(cx)))
         return false;
 
+    if (inspectorUtils &&
+        !dom::InspectorUtilsBinding::GetConstructorObject(cx))
+        return false;
+
     return true;
 }
 
 bool
 xpc::GlobalProperties::DefineInXPCComponents(JSContext* cx, JS::HandleObject obj)
 {
     if (indexedDB &&
         !IndexedDatabaseManager::DefineIndexedDB(cx, obj))
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2692,16 +2692,17 @@ struct GlobalProperties {
     bool Directory : 1;
     bool File : 1;
     bool crypto : 1;
     bool rtcIdentityProvider : 1;
     bool fetch : 1;
     bool caches : 1;
     bool fileReader: 1;
     bool messageChannel: 1;
+    bool inspectorUtils : 1;
 private:
     bool Define(JSContext* cx, JS::HandleObject obj);
 };
 
 // Infallible.
 already_AddRefed<nsIXPCComponents_utils_Sandbox>
 NewSandboxConstructor();
 
new file mode 100644
--- /dev/null
+++ b/layout/inspector/InspectorUtils.h
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/.
+ */
+
+#ifndef mozilla_dom_InspectorUtils_h
+#define mozilla_dom_InspectorUtils_h
+
+namespace mozilla {
+namespace dom {
+
+/**
+ * A collection of utility methods for use by devtools.
+ */
+class InspectorUtils
+{
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_InspectorUtils_h
--- a/layout/inspector/moz.build
+++ b/layout/inspector/moz.build
@@ -25,16 +25,20 @@ EXPORTS += [
     'nsFontFace.h',
     'nsFontFaceList.h',
 ]
 
 EXPORTS.mozilla += [
     'ServoStyleRuleMap.h',
 ]
 
+EXPORTS.mozilla.dom += [
+    'InspectorUtils.h',
+]
+
 UNIFIED_SOURCES += [
     'inCSSValueSearch.cpp',
     'inDeepTreeWalker.cpp',
     'inDOMUtils.cpp',
     'inLayoutUtils.cpp',
     'nsFontFace.cpp',
     'nsFontFaceList.cpp',
     'ServoStyleRuleMap.cpp',
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -25,17 +25,17 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/NetUtil.jsm");
 
 // We're loaded with "this" not set to the global in some cases, so we
 // have to play some games to get at the global object here.  Normally
 // we'd try "this" from a function called with undefined this value,
 // but this whole file is in strict mode.  So instead fall back on
 // returning "this" from indirect eval, which returns the global.
 if (!(function() { var e = eval; return e("this"); })().File) { // eslint-disable-line no-eval
-    Cu.importGlobalProperties(["File"]);
+    Cu.importGlobalProperties(["File", "InspectorUtils"]);
 }
 
 // Allow stuff from this scope to be accessed from non-privileged scopes. This
 // would crash if used outside of automation.
 Cu.forcePermissiveCOWs();
 
 function SpecialPowersAPI() {
   this._consoleListeners = [];
@@ -665,16 +665,18 @@ SpecialPowersAPI.prototype = {
 
   getDOMWindowUtils(aWindow) {
     if (aWindow == this.window.get() && this.DOMWindowUtils != null)
       return this.DOMWindowUtils;
 
     return bindDOMWindowUtils(aWindow);
   },
 
+  get InspectorUtils() { return wrapPrivileged(InspectorUtils); },
+
   waitForCrashes(aExpectingProcessCrash) {
     return new Promise((resolve, reject) => {
       if (!aExpectingProcessCrash) {
         resolve();
       }
 
       var crashIds = this._encounteredCrashDumpFiles.filter((filename) => {
         return ((filename.length === 40) && filename.endsWith(".dmp"));