Backed out 6 changesets (bug 1489301) for Linting opt failure at /builds/worker/checkouts/gecko/dom/bindings/parser/WebIDL.py
authorDaniel Varga <dvarga@mozilla.com>
Tue, 23 Oct 2018 03:49:00 +0300
changeset 490734 77f4c84bebf05b7fddb3f5bdb8e7de0d2eb3ebd6
parent 490733 a3fad30f081a0bcd4aeae913942fc360dbdbf30e
child 490735 99bd9a8c917c23dad65f2853a2c7a6c9be58957c
child 490847 cc96d514beb84065d58268555e4f988269fe772a
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
bugs1489301
milestone65.0a1
backs out1c0823540b44ff83a6319a363aab6e017faddaf4
529524df76a62485a06367438281b9a1155b9b42
f34bc8a40bec4df77ca477793a8932f6683baa8c
168cf9cea716ac599dc594db4dd410bdaefd70ff
19ca10fa37725e9b1a52d05bf2ed479e2a8d4a73
ff8fb091198ee6f4c86ffd4625089dd9751630a0
Backed out 6 changesets (bug 1489301) for Linting opt failure at /builds/worker/checkouts/gecko/dom/bindings/parser/WebIDL.py Backed out changeset 1c0823540b44 (bug 1489301) Backed out changeset 529524df76a6 (bug 1489301) Backed out changeset f34bc8a40bec (bug 1489301) Backed out changeset 168cf9cea716 (bug 1489301) Backed out changeset 19ca10fa3772 (bug 1489301) Backed out changeset ff8fb091198e (bug 1489301)
dom/base/nsGlobalWindowInner.cpp
dom/base/test/chrome/file_bug1139964.xul
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/parser/WebIDL.py
dom/chrome-webidl/BrowsingContext.webidl
dom/chrome-webidl/ChannelWrapper.webidl
dom/chrome-webidl/ChromeUtils.webidl
dom/chrome-webidl/DominatorTree.webidl
dom/chrome-webidl/HeapSnapshot.webidl
dom/chrome-webidl/MatchGlob.webidl
dom/chrome-webidl/MatchPattern.webidl
dom/chrome-webidl/MozDocumentObserver.webidl
dom/chrome-webidl/PlacesEvent.webidl
dom/chrome-webidl/PlacesObservers.webidl
dom/chrome-webidl/PrecompiledScript.webidl
dom/chrome-webidl/PrioEncoder.webidl
dom/chrome-webidl/PromiseDebugging.webidl
dom/chrome-webidl/StructuredCloneHolder.webidl
dom/chrome-webidl/WebExtensionContentScript.webidl
dom/chrome-webidl/WebExtensionPolicy.webidl
dom/webidl/AbortController.webidl
dom/webidl/AbortSignal.webidl
dom/webidl/AbstractWorker.webidl
dom/webidl/AddonManager.webidl
dom/webidl/Console.webidl
dom/webidl/DOMError.webidl
dom/webidl/DOMException.webidl
dom/webidl/DOMRequest.webidl
dom/webidl/DOMStringList.webidl
dom/webidl/ErrorEvent.webidl
dom/webidl/Event.webidl
dom/webidl/EventTarget.webidl
dom/webidl/FileReader.webidl
dom/webidl/IDBCursor.webidl
dom/webidl/IDBDatabase.webidl
dom/webidl/IDBFactory.webidl
dom/webidl/IDBFileHandle.webidl
dom/webidl/IDBFileRequest.webidl
dom/webidl/IDBIndex.webidl
dom/webidl/IDBKeyRange.webidl
dom/webidl/IDBMutableFile.webidl
dom/webidl/IDBObjectStore.webidl
dom/webidl/IDBOpenDBRequest.webidl
dom/webidl/IDBRequest.webidl
dom/webidl/IDBTransaction.webidl
dom/webidl/IDBVersionChangeEvent.webidl
dom/webidl/IdleDeadline.webidl
dom/webidl/LegacyQueryInterface.webidl
dom/webidl/MessageChannel.webidl
dom/webidl/MessageEvent.webidl
dom/webidl/MessagePort.webidl
dom/webidl/Promise.webidl
dom/webidl/StreamFilter.webidl
dom/webidl/StreamFilterDataEvent.webidl
dom/webidl/TCPServerSocket.webidl
dom/webidl/TCPServerSocketEvent.webidl
dom/webidl/TCPSocket.webidl
dom/webidl/TCPSocketErrorEvent.webidl
dom/webidl/TCPSocketEvent.webidl
dom/webidl/TextDecoder.webidl
dom/webidl/TextEncoder.webidl
dom/webidl/URLSearchParams.webidl
dom/webidl/Worker.webidl
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -3090,18 +3090,17 @@ nsGlobalWindowInner::GetOwnPropertyNames
     aRv.NoteJSContextException(aCx);
   }
 }
 
 /* static */ bool
 nsGlobalWindowInner::IsPrivilegedChromeWindow(JSContext* aCx, JSObject* aObj)
 {
   // For now, have to deal with XPConnect objects here.
-  nsGlobalWindowInner* win = xpc::WindowOrNull(aObj);
-  return win && win->IsChromeWindow() &&
+  return xpc::WindowOrNull(aObj)->IsChromeWindow() &&
          nsContentUtils::ObjectPrincipal(aObj) == nsContentUtils::GetSystemPrincipal();
 }
 
 /* static */ bool
 nsGlobalWindowInner::OfflineCacheAllowedForContext(JSContext* aCx, JSObject* aObj)
 {
   return IsSecureContextOrObjectIsFromSecureContext(aCx, aObj) ||
          Preferences::GetBool("browser.cache.offline.insecure.enable");
--- a/dom/base/test/chrome/file_bug1139964.xul
+++ b/dom/base/test/chrome/file_bug1139964.xul
@@ -27,27 +27,27 @@ https://bugzilla.mozilla.org/show_bug.cg
                        hasWindow: ("Window" in this),
                      });
   }
 
   function processListener(m) {
     ppm.removeMessageListener(msgName, processListener);
     ok(m.data.hasPromise, "ProcessGlobal should have Promise object in the global scope!");
     ok(m.data.hasTextEncoder, "ProcessGlobal should have TextEncoder object in the global scope!");
-    ok(m.data.hasWindow, "ProcessGlobal should have Window object in the global scope!");
+    ok(!m.data.hasWindow, "ProcessGlobal should not have Window object in the global scope!");
 
     messageManager.addMessageListener(msgName, tabListener)
     messageManager.loadFrameScript("data:,(" + mmScriptForPromiseTest.toString() + ")()", true);
   }
 
   function tabListener(m) {
     messageManager.removeMessageListener(msgName, tabListener);
     ok(m.data.hasPromise, "TabChildGlobal should have Promise object in the global scope!");
     ok(m.data.hasTextEncoder, "TabChildGlobal should have TextEncoder object in the global scope!");
-    ok(m.data.hasWindow, "TabChildGlobal should have Window object in the global scope!");
+    ok(!m.data.hasWindow, "TabChildGlobal should not have Window object in the global scope!");
 
     opener.setTimeout("done()", 0);
     window.close();
   }
 
   function run() {
     ppm.addMessageListener(msgName, processListener)
     ppm.loadProcessScript("data:,(" + mmScriptForPromiseTest.toString() + ")()", true);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -17194,17 +17194,17 @@ class GlobalGenRoots():
         # Done.
         return curr
 
     @staticmethod
     def ResolveSystemBinding(config):
         curr = CGList([], "\n")
 
         descriptors = config.getDescriptors(hasInterfaceObject=True,
-                                            isExposedInWindow=True,
+                                            isExposedInSystemGlobals=True,
                                             register=True)
         properties = [desc.name for desc in descriptors]
 
         curr.append(CGStringTable("IdString", properties, static=True))
 
         initValues = []
         for desc in descriptors:
             bindingNS = toBindingNamespace(desc.name)
@@ -17239,17 +17239,17 @@ class GlobalGenRoots():
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, post='\n'))
         curr = CGWrapper(curr, post='\n')
 
         # Add the includes
         defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
                           for desc in config.getDescriptors(hasInterfaceObject=True,
                                                             register=True,
-                                                            isExposedInWindow=True)]
+                                                            isExposedInSystemGlobals=True)]
         defineIncludes.append("nsThreadUtils.h")  # For NS_IsMainThread
         defineIncludes.append("js/Id.h")  # For jsid
         defineIncludes.append("mozilla/dom/WebIDLGlobalNameHash.h")
 
         curr = CGHeaders([], [], [], [], [], defineIncludes,
                          'ResolveSystemBinding', curr)
 
         # Add include guards.
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -245,16 +245,18 @@ class Configuration(DescriptorProvider):
             elif key == 'isNavigatorProperty':
                 getter = lambda x: x.interface.isNavigatorProperty()
             elif key == 'isExposedInAnyWorker':
                 getter = lambda x: x.interface.isExposedInAnyWorker()
             elif key == 'isExposedInWorkerDebugger':
                 getter = lambda x: x.interface.isExposedInWorkerDebugger()
             elif key == 'isExposedInAnyWorklet':
                 getter = lambda x: x.interface.isExposedInAnyWorklet()
+            elif key == 'isExposedInSystemGlobals':
+                getter = lambda x: x.interface.isExposedInSystemGlobals()
             elif key == 'isExposedInWindow':
                 getter = lambda x: x.interface.isExposedInWindow()
             else:
                 # Have to watch out: just closing over "key" is not enough,
                 # since we're about to mutate its value
                 getter = (lambda attrName: lambda x: getattr(x, attrName))(key)
             tofilter.append((getter, val))
         for f in tofilter:
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -322,23 +322,16 @@ class IDLScope(IDLObject):
     def _lookupIdentifier(self, identifier):
         return self._dict[identifier.name]
 
     def lookupIdentifier(self, identifier):
         assert isinstance(identifier, IDLIdentifier)
         assert identifier.scope == self
         return self._lookupIdentifier(identifier)
 
-    def addIfaceGlobalNames(self, interfaceName, globalNames):
-        """Record the global names (from |globalNames|) that can be used in
-        [Exposed] to expose things in a global named |interfaceName|"""
-        self.globalNames.update(globalNames)
-        for name in globalNames:
-            self.globalNameMapping[name].add(interfaceName)
-
 
 class IDLIdentifier(IDLObject):
     def __init__(self, location, scope, name):
         IDLObject.__init__(self, location)
 
         self.name = name
         assert isinstance(scope, IDLScope)
         self.scope = scope
@@ -506,30 +499,31 @@ class IDLExposureMixins():
 
         globalNameSetToExposureSet(scope, self._exposureGlobalNames,
                                    self.exposureSet)
 
     def isExposedInWindow(self):
         return 'Window' in self.exposureSet
 
     def isExposedOnMainThread(self):
-        return self.isExposedInWindow()
-
-    def isExposedOffMainThread(self):
-        return len(self.exposureSet - {'Window'}) > 0
+        return (self.isExposedInWindow() or
+                self.isExposedInSystemGlobals())
 
     def isExposedInAnyWorker(self):
         return len(self.getWorkerExposureSet()) > 0
 
     def isExposedInWorkerDebugger(self):
         return len(self.getWorkerDebuggerExposureSet()) > 0
 
     def isExposedInAnyWorklet(self):
         return len(self.getWorkletExposureSet()) > 0
 
+    def isExposedInSystemGlobals(self):
+        return 'BackstagePass' in self.exposureSet
+
     def isExposedInSomeButNotAllWorkers(self):
         """
         Returns true if the Exposed extended attribute for this interface
         exposes it in some worker globals but not others.  The return value does
         not depend on whether the interface is exposed in Window or System
         globals.
         """
         if not self.isExposedInAnyWorker():
@@ -1324,19 +1318,20 @@ class IDLInterfaceOrNamespace(IDLObjectW
 
             # Check that the name of a [BindingAlias] doesn't conflict with an
             # interface member.
             if member.isAttr():
                 for bindingAlias in member.bindingAliases:
                     checkDuplicateNames(member, bindingAlias, "BindingAlias")
 
 
-        if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
-            raise WebIDLError("[Pref] used on an interface that is not "
-                              "main-thread-only",
+        if (self.getExtendedAttribute("Pref") and
+            self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
+            raise WebIDLError("[Pref] used on an interface that is not %s-only" %
+                              self.parentScope.primaryGlobalName,
                               [self.location])
 
         # Conditional exposure makes no sense for interfaces with no
         # interface object, unless they're navigator properties.
         # And SecureContext makes sense for interfaces with no interface object,
         # since it is also propagated to interface members.
         if (self.isExposedConditionally(exclusions=["SecureContext"]) and
             not self.hasInterfaceObject() and
@@ -1710,32 +1705,33 @@ class IDLInterface(IDLInterfaceOrNamespa
                                       [attr.location, self.location])
             elif identifier == "Global":
                 if attr.hasValue():
                     self.globalNames = [attr.value()]
                 elif attr.hasArgs():
                     self.globalNames = attr.args()
                 else:
                     self.globalNames = [self.identifier.name]
-                self.parentScope.addIfaceGlobalNames(self.identifier.name,
-                                                     self.globalNames)
+                self.parentScope.globalNames.update(self.globalNames)
+                for globalName in self.globalNames:
+                    self.parentScope.globalNameMapping[globalName].add(self.identifier.name)
                 self._isOnGlobalProtoChain = True
             elif identifier == "PrimaryGlobal":
                 if not attr.noArguments():
                     raise WebIDLError("[PrimaryGlobal] must take no arguments",
                                       [attr.location])
                 if self.parentScope.primaryGlobalAttr is not None:
                     raise WebIDLError(
                         "[PrimaryGlobal] specified twice",
                         [attr.location,
                          self.parentScope.primaryGlobalAttr.location])
                 self.parentScope.primaryGlobalAttr = attr
                 self.parentScope.primaryGlobalName = self.identifier.name
-                self.parentScope.addIfaceGlobalNames(self.identifier.name,
-                                                     [self.identifier.name])
+                self.parentScope.globalNames.add(self.identifier.name)
+                self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
                 self._isOnGlobalProtoChain = True
             elif identifier == "SecureContext":
                 if not attr.noArguments():
                     raise WebIDLError("[%s] must take no arguments" % identifier,
                                       [attr.location])
                 # This gets propagated to all our members.
                 for member in self.members:
                     if member.getExtendedAttribute("SecureContext"):
@@ -3571,19 +3567,20 @@ class IDLInterfaceMember(IDLObjectWithId
     def finish(self, scope):
         # We better be exposed _somewhere_.
         if (len(self._exposureGlobalNames) == 0):
             print self.identifier.name
         assert len(self._exposureGlobalNames) != 0
         IDLExposureMixins.finish(self, scope)
 
     def validate(self):
-        if self.getExtendedAttribute("Pref") and self.isExposedOffMainThread():
+        if (self.getExtendedAttribute("Pref") and
+            self.exposureSet != set([self._globalScope.primaryGlobalName])):
             raise WebIDLError("[Pref] used on an interface member that is not "
-                              "main-thread-only",
+                              "%s-only" % self._globalScope.primaryGlobalName,
                               [self.location])
 
         if self.isAttr() or self.isMethod():
             if self.affects == "Everything" and self.dependsOn != "Everything":
                 raise WebIDLError("Interface member is flagged as affecting "
                                   "everything but not depending on everything. "
                                   "That seems rather unlikely.",
                                   [self.location])
@@ -6894,23 +6891,26 @@ class Parser(Tokenizer):
                                     # We're not pickling for now, until it
                                     # becomes a speedup again.
                                     # , picklefile='WebIDLGrammar.pkl'
             )
         finally:
             logger.reportGrammarErrors()
 
         self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
-
         # To make our test harness work, pretend like we have a primary global already.
         # Note that we _don't_ set _globalScope.primaryGlobalAttr,
         # so we'll still be able to detect multiple PrimaryGlobal extended attributes.
         self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
-        self._globalScope.addIfaceGlobalNames("FakeTestPrimaryGlobal", ["FakeTestPrimaryGlobal"])
-
+        self._globalScope.globalNames.add("FakeTestPrimaryGlobal")
+        self._globalScope.globalNameMapping["FakeTestPrimaryGlobal"].add("FakeTestPrimaryGlobal")
+        # And we add the special-cased "System" global name, which
+        # doesn't have any corresponding interfaces.
+        self._globalScope.globalNames.add("System")
+        self._globalScope.globalNameMapping["System"].add("BackstagePass")
         self._installBuiltins(self._globalScope)
         self._productions = []
 
         self._filename = "<builtin>"
         self.lexer.input(Parser._builtins)
         self._filename = None
 
         self.parser.parse(lexer=self.lexer, tracking=True)
--- a/dom/chrome-webidl/BrowsingContext.webidl
+++ b/dom/chrome-webidl/BrowsingContext.webidl
@@ -1,16 +1,16 @@
 /* -*- 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/. */
 
 interface nsIDocShell;
 
-[Exposed=Window, ChromeOnly]
+[Exposed=(Window, System), ChromeOnly]
 interface BrowsingContext {
   readonly attribute BrowsingContext? parent;
 
   sequence<BrowsingContext> getChildren();
 
   readonly attribute nsIDocShell? docShell;
 
   readonly attribute unsigned long long id;
--- a/dom/chrome-webidl/ChannelWrapper.webidl
+++ b/dom/chrome-webidl/ChannelWrapper.webidl
@@ -36,17 +36,17 @@ enum MozContentPolicyType {
   "speculative",
   "other"
 };
 
 /**
  * A thin wrapper around nsIChannel and nsIHttpChannel that allows JS
  * callers to access them without XPConnect overhead.
  */
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=System]
 interface ChannelWrapper : EventTarget {
   /**
    * Returns the wrapper instance for the given channel. The same wrapper is
    * always returned for a given channel.
    */
   static ChannelWrapper get(MozChannel channel);
 
   /**
--- a/dom/chrome-webidl/ChromeUtils.webidl
+++ b/dom/chrome-webidl/ChromeUtils.webidl
@@ -9,28 +9,28 @@
  *
  * For JS callers, this behaves like a normal QueryInterface function. When
  * called with a supported interface, it returns its `this` object. When
  * called with an unsupported interface, it throws NS_ERROR_NO_INTERFACE.
  *
  * C++ callers use a fast path, and never call the JSAPI or WebIDL methods of
  * this object.
  */
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 interface MozQueryInterface {
   [Throws]
   legacycaller any (IID aIID);
 };
 
 /**
  * A collection of static utility methods that are only exposed to system code.
  * This is exposed in all the system globals where we can expose stuff by
  * default, so should only include methods that are **thread-safe**.
  */
-[ChromeOnly, Exposed=(Window,Worker)]
+[ChromeOnly, Exposed=(Window,System,Worker)]
 namespace ChromeUtils {
   /**
    * Serialize a snapshot of the heap graph, as seen by |JS::ubi::Node| and
    * restricted by |boundaries|, and write it to the provided file path.
    *
    * @param boundaries        The portion of the heap graph to write.
    *
    * @returns                 The path to the file the heap snapshot was written
@@ -143,17 +143,17 @@ namespace ChromeUtils {
    * IF YOU ADD NEW METHODS HERE, MAKE SURE THEY ARE THREAD-SAFE.
    */
 };
 
 /**
  * Additional ChromeUtils methods that are _not_ thread-safe, and hence not
  * exposed in workers.
  */
-[Exposed=Window]
+[Exposed=(Window,System)]
 partial namespace ChromeUtils {
   /**
    * A helper that converts OriginAttributesDictionary to a opaque suffix string.
    *
    * @param originAttrs       The originAttributes from the caller.
    */
   ByteString
   originAttributesToSuffix(optional OriginAttributesDictionary originAttrs);
--- a/dom/chrome-webidl/DominatorTree.webidl
+++ b/dom/chrome-webidl/DominatorTree.webidl
@@ -33,17 +33,17 @@ typedef unsigned long long NodeSize;
  *     the original node wasn't (directly or indirectly) referencing them. In
  *     other words, the retained size is the shallow size of a node plus the
  *     shallow sizes of every other node it dominates. For example, the root
  *     node in a binary tree might have a small shallow size that does not take
  *     up much space itself, but it dominates the rest of the binary tree and
  *     its retained size is therefore significant (assuming no external
  *     references into the tree).
  */
-[ChromeOnly, Exposed=(Window,Worker)]
+[ChromeOnly, Exposed=(Window,System,Worker)]
 interface DominatorTree {
   /**
    * The `NodeId` for the root of the dominator tree. This is a "meta-root" in
    * that it has an edge to each GC root in the heap snapshot this dominator
    * tree was created from.
    */
   readonly attribute NodeId root;
 
--- a/dom/chrome-webidl/HeapSnapshot.webidl
+++ b/dom/chrome-webidl/HeapSnapshot.webidl
@@ -2,17 +2,17 @@
 /* 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 HeapSnapshot represents a snapshot of the heap graph
  */
-[ChromeOnly, Exposed=(Window,Worker)]
+[ChromeOnly, Exposed=(Window,System,Worker)]
 interface HeapSnapshot {
   /**
    * A time stamp of when the heap snapshot was taken, if available. Units are
    * microseconds since midnight (00:00:00) 1 January 1970 UTC.
    */
   readonly attribute unsigned long long? creationTime;
 
   /**
--- a/dom/chrome-webidl/MatchGlob.webidl
+++ b/dom/chrome-webidl/MatchGlob.webidl
@@ -4,17 +4,17 @@
 
 /**
  * Represents a simple glob pattern matcher. Any occurrence of "*" in the glob
  * pattern matches any literal string of characters in the string being
  * compared. Additionally, if created with `allowQuestion = true`, any
  * occurrence of "?" in the glob matches any single literal character.
  */
 [Constructor(DOMString glob, optional boolean allowQuestion = true),
- ChromeOnly, Exposed=Window]
+ ChromeOnly, Exposed=(Window,System)]
 interface MatchGlob {
   /**
    * Returns true if the string matches the glob.
    */
   boolean matches(DOMString string);
 
   /**
    * The glob string this MatchGlob represents.
--- a/dom/chrome-webidl/MatchPattern.webidl
+++ b/dom/chrome-webidl/MatchPattern.webidl
@@ -25,17 +25,17 @@ interface URI;
  *      or a subdomain pattern, with "*." followed by a domain name, to match
  *      that domain name or any subdomain thereof.
  *    - <path>
  *      A glob pattern for paths to match. A "*" may appear anywhere within
  *      the path, and will match any string of characters. If no "*" appears,
  *      the URL path must exactly match the pattern path.
  */
 [Constructor(DOMString pattern, optional MatchPatternOptions options),
- ChromeOnly, Exposed=Window]
+ ChromeOnly, Exposed=(Window,System)]
 interface MatchPattern {
   /**
    * Returns true if the given URI matches the pattern.
    *
    * If explicit is true, only explicit domain matches, without wildcards, are
    * considered.
    */
   [Throws]
@@ -69,17 +69,17 @@ interface MatchPattern {
   readonly attribute DOMString pattern;
 };
 
 /**
  * A set of MatchPattern objects, which implements the MatchPattern API and
  * matches when any of its sub-patterns matches.
  */
 [Constructor(sequence<(DOMString or MatchPattern)> patterns, optional MatchPatternOptions options),
- ChromeOnly, Exposed=Window]
+ ChromeOnly, Exposed=(Window,System)]
 interface MatchPatternSet {
   /**
    * Returns true if the given URI matches any sub-pattern.
    *
    * If explicit is true, only explicit domain matches, without wildcards, are
    * considered.
    */
   [Throws]
--- a/dom/chrome-webidl/MozDocumentObserver.webidl
+++ b/dom/chrome-webidl/MozDocumentObserver.webidl
@@ -4,14 +4,14 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 callback interface MozDocumentCallback {
   void onNewDocument(MozDocumentMatcher matcher, WindowProxy window);
   void onPreloadDocument(MozDocumentMatcher matcher, LoadInfo loadInfo);
 };
 
-[ChromeOnly, Constructor(MozDocumentCallback callbacks), Exposed=Window]
+[ChromeOnly, Constructor(MozDocumentCallback callbacks), Exposed=System]
 interface MozDocumentObserver {
   [Throws]
   void observe(sequence<MozDocumentMatcher> matchers);
   void disconnect();
 };
--- a/dom/chrome-webidl/PlacesEvent.webidl
+++ b/dom/chrome-webidl/PlacesEvent.webidl
@@ -7,22 +7,22 @@ enum PlacesEventType {
   "page-visited",
   /**
    * data: PlacesBookmarkAddition. Fired whenever a bookmark
    * (or a bookmark folder/separator) is created.
    */
   "bookmark-added",
 };
 
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 interface PlacesEvent {
   readonly attribute PlacesEventType type;
 };
 
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 interface PlacesVisit : PlacesEvent {
   /**
    * URL of the visit.
    */
   readonly attribute DOMString url;
 
   /**
    * Id of the visit.
@@ -71,17 +71,17 @@ interface PlacesVisit : PlacesEvent {
    * and might be null if it is not known.
    */
   readonly attribute DOMString? lastKnownTitle;
 };
 
 /**
  * Base class for properties that are common to all bookmark events.
  */
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 interface PlacesBookmark : PlacesEvent {
   /**
    * The id of the item.
    */
   readonly attribute long long id;
 
   /**
    * The id of the folder to which the item belongs.
@@ -130,17 +130,17 @@ dictionary PlacesBookmarkAdditionInit {
   required ByteString parentGuid;
   required unsigned short source;
   required long index;
   required DOMString title;
   required unsigned long long dateAdded;
   required boolean isTagging;
 };
 
-[ChromeOnly, Exposed=Window, Constructor(PlacesBookmarkAdditionInit initDict)]
+[ChromeOnly, Exposed=(Window,System), Constructor(PlacesBookmarkAdditionInit initDict)]
 interface PlacesBookmarkAddition : PlacesBookmark {
   /**
    * The item's index in the folder.
    */
   readonly attribute long index;
 
   /**
    * The title of the added item.
--- a/dom/chrome-webidl/PlacesObservers.webidl
+++ b/dom/chrome-webidl/PlacesObservers.webidl
@@ -1,23 +1,23 @@
 /* -*- 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/.
  */
 
 callback PlacesEventCallback = void (sequence<PlacesEvent> events);
 
-[ChromeOnly, Exposed=Window,
+[ChromeOnly, Exposed=(Window,System),
  Constructor(PlacesEventCallback callback)]
 interface PlacesWeakCallbackWrapper {
 };
 
 // Global singleton which should handle all events for places.
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 namespace PlacesObservers {
   [Throws]
   void addListener(sequence<PlacesEventType> eventTypes,
                    PlacesEventCallback listener);
   [Throws]
   void addListener(sequence<PlacesEventType> eventTypes,
                    PlacesWeakCallbackWrapper listener);
   [Throws]
--- a/dom/chrome-webidl/PrecompiledScript.webidl
+++ b/dom/chrome-webidl/PrecompiledScript.webidl
@@ -3,17 +3,17 @@
  * 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/.
  */
 
 /**
  * Represents a pre-compiled JS script, which can be repeatedly executed in
  * different globals without being re-parsed.
  */
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 interface PrecompiledScript {
   /**
    * Executes the script in the context of, and with the security principal
    * of, the given object's global. If compiled with a return value, returns
    * the value of the script's last expression. Otherwise returns undefined.
    */
   [Throws]
   any executeInGlobal(object global);
--- a/dom/chrome-webidl/PrioEncoder.webidl
+++ b/dom/chrome-webidl/PrioEncoder.webidl
@@ -1,15 +1,15 @@
 /* -*- 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/.
  */
 
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 namespace PrioEncoder {
   [Throws, NewObject]
   PrioEncodedData encode(ByteString batchID, PrioParams params);
 };
 
 dictionary PrioParams {
   required boolean browserIsUserDefault;
   required boolean newTabPageEnabled;
--- a/dom/chrome-webidl/PromiseDebugging.webidl
+++ b/dom/chrome-webidl/PromiseDebugging.webidl
@@ -45,17 +45,17 @@ callback interface UncaughtRejectionObse
    * chain anymore.
    *
    * @param p A Promise that was previously left in uncaught state is
    * now caught, i.e. it is not the last in its chain anymore.
    */
   void onConsumed(object p);
 };
 
-[ChromeOnly, Exposed=Window]
+[ChromeOnly, Exposed=(Window,System)]
 interface PromiseDebugging {
   /**
    * The various functions on this interface all expect to take promises but
    * don't want the WebIDL behavior of assimilating random passed-in objects
    * into promises.  They also want to treat Promise subclass instances as
    * promises instead of wrapping them in a vanilla Promise, which is what the
    * IDL spec says to do.  So we list all our arguments as "object" instead of
    * "Promise" and check for them being a Promise internally.
--- a/dom/chrome-webidl/StructuredCloneHolder.webidl
+++ b/dom/chrome-webidl/StructuredCloneHolder.webidl
@@ -3,17 +3,17 @@
  * 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 holder for structured-clonable data which can itself be cloned with
  * little overhead, and deserialized into an arbitrary global.
  */
-[ChromeOnly, Exposed=(Window,Worker),
+[ChromeOnly, Exposed=(Window,System,Worker),
  /**
   * Serializes the given value to an opaque structured clone blob, and
   * returns the result.
   *
   * The serialization happens in the compartment of the given global or, if no
   * global is provided, the compartment of the data value.
   */
  Constructor(any data, optional object? global = null)]
--- a/dom/chrome-webidl/WebExtensionContentScript.webidl
+++ b/dom/chrome-webidl/WebExtensionContentScript.webidl
@@ -4,17 +4,17 @@
 
 interface LoadInfo;
 interface URI;
 interface WindowProxy;
 
 typedef (MatchPatternSet or sequence<DOMString>) MatchPatternSetOrStringSequence;
 typedef (MatchGlob or DOMString) MatchGlobOrString;
 
-[Constructor(MozDocumentMatcherInit options), ChromeOnly, Exposed=Window]
+[Constructor(MozDocumentMatcherInit options), ChromeOnly, Exposed=System]
 interface MozDocumentMatcher {
   /**
    * Returns true if the script's match and exclude patterns match the given
    * URI, without reference to attributes such as `allFrames`.
    */
   boolean matchesURI(URI uri);
 
   /**
@@ -127,17 +127,17 @@ enum ContentScriptRunAt {
   /**
    * The first point after the page and all of its resources has fully loaded
    * when the event loop is idle, and can run scripts without delaying a paint
    * event.
    */
   "document_idle",
 };
 
-[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=Window]
+[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=System]
 interface WebExtensionContentScript : MozDocumentMatcher {
   /**
    * The earliest point in the load cycle at which this script should run. For
    * static content scripts, in extensions which were present at browser
    * startup, the browser makes every effort to make sure that the script runs
    * no later than this point in the load cycle. For dynamic content scripts,
    * and scripts from extensions installed during this session, the scripts
    * may run at a later point.
--- a/dom/chrome-webidl/WebExtensionPolicy.webidl
+++ b/dom/chrome-webidl/WebExtensionPolicy.webidl
@@ -6,17 +6,17 @@ interface URI;
 interface WindowProxy;
 
 callback WebExtensionLocalizeCallback = DOMString (DOMString unlocalizedText);
 
 /**
  * Defines the platform-level policies for a WebExtension, including its
  * permissions and the characteristics of its moz-extension: URLs.
  */
-[Constructor(WebExtensionInit options), ChromeOnly, Exposed=Window]
+[Constructor(WebExtensionInit options), ChromeOnly, Exposed=System]
 interface WebExtensionPolicy {
   /**
    * The add-on's internal ID, as specified in its manifest.json file or its
    * XPI signature.
    */
   [Constant, StoreInSlot]
   readonly attribute DOMString id;
 
--- a/dom/webidl/AbortController.webidl
+++ b/dom/webidl/AbortController.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is
  * https://dom.spec.whatwg.org/#abortcontroller
  */
 
-[Constructor(), Exposed=(Window,Worker)]
+[Constructor(), Exposed=(Window,Worker,System)]
 interface AbortController {
   readonly attribute AbortSignal signal;
 
   void abort();
 };
--- a/dom/webidl/AbortSignal.webidl
+++ b/dom/webidl/AbortSignal.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is
  * https://dom.spec.whatwg.org/#abortsignal
  */
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface AbortSignal : EventTarget {
   readonly attribute boolean aborted;
 
   attribute EventHandler onabort;
 };
--- a/dom/webidl/AbstractWorker.webidl
+++ b/dom/webidl/AbstractWorker.webidl
@@ -1,10 +1,10 @@
 /* -*- 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/.
  */
 
-[NoInterfaceObject, Exposed=(Window,Worker)]
+[NoInterfaceObject, Exposed=(Window,Worker,System)]
 interface AbstractWorker {
     attribute EventHandler onerror;
 };
--- a/dom/webidl/AddonManager.webidl
+++ b/dom/webidl/AddonManager.webidl
@@ -77,13 +77,13 @@ interface AddonManager : EventTarget {
    * @return A promise that resolves to an instance of AddonInstall.
    */
   Promise<AddonInstall> createInstall(optional addonInstallOptions options);
 
   // Indicator to content whether permissions prompts are enabled
   readonly attribute boolean permissionPromptsEnabled;
 };
 
-[ChromeOnly,Exposed=Window,HeaderFile="mozilla/AddonManagerWebAPI.h"]
+[ChromeOnly,Exposed=System,HeaderFile="mozilla/AddonManagerWebAPI.h"]
 interface AddonManagerPermissions {
   static boolean isHostPermitted(DOMString host);
 };
 
--- a/dom/webidl/Console.webidl
+++ b/dom/webidl/Console.webidl
@@ -3,17 +3,17 @@
 /* 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/.
  *
  * For more information on this interface, please see
  * https://console.spec.whatwg.org/#console-namespace
  */
 
-[Exposed=(Window,Worker,WorkerDebugger,Worklet),
+[Exposed=(Window,Worker,WorkerDebugger,Worklet,System),
  ClassString="Console",
  ProtoObjectHack]
 namespace console {
 
   // NOTE: if you touch this namespace, remember to update the ConsoleInstance
   // interface as well!
 
   // Logging
@@ -141,17 +141,17 @@ dictionary ConsoleCounter {
 };
 
 dictionary ConsoleCounterError {
   DOMString label = "";
   DOMString error = "";
 };
 
 [ChromeOnly,
- Exposed=(Window,Worker,WorkerDebugger,Worklet)]
+ Exposed=(Window,Worker,WorkerDebugger,Worklet,System)]
 // This is basically a copy of the console namespace.
 interface ConsoleInstance {
   // Logging
   void assert(optional boolean condition = false, any... data);
   void clear();
   void count(optional DOMString label = "default");
   void countReset(optional DOMString label = "default");
   void debug(any... data);
--- a/dom/webidl/DOMError.webidl
+++ b/dom/webidl/DOMError.webidl
@@ -6,16 +6,16 @@
  * The origin of this IDL file is
  * http://dom.spec.whatwg.org/#domerror
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Constructor(DOMString name, optional DOMString message = ""),
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface DOMError {
   [Constant, UseCounter]
   readonly attribute DOMString name;
 
   [Constant, UseCounter]
   readonly attribute DOMString message;
 };
--- a/dom/webidl/DOMException.webidl
+++ b/dom/webidl/DOMException.webidl
@@ -11,17 +11,17 @@
  */
 
 
 // This is the WebIDL version of nsIException.  This is mostly legacy stuff.
 
 interface StackFrame;
 
 [NoInterfaceObject,
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface ExceptionMembers
 {
   // The nsresult associated with this exception.
   readonly attribute unsigned long           result;
 
   // Filename location.  This is the location that caused the
   // error, which may or may not be a source file location.
   // For example, standard language errors would generally have
@@ -61,17 +61,17 @@ interface Exception {
   stringifier;
 };
 
 Exception implements ExceptionMembers;
 
 // XXXkhuey this is an 'exception', not an interface, but we don't have any
 // parser or codegen mechanisms for dealing with exceptions.
 [ExceptionClass,
- Exposed=(Window, Worker),
+ Exposed=(Window, Worker,System),
  Constructor(optional DOMString message = "", optional DOMString name)]
 interface DOMException {
   // The name of the error code (ie, a string repr of |result|).
   readonly attribute DOMString               name;
   // A custom message set by the thrower.
   readonly attribute DOMString               message;
   readonly attribute unsigned short code;
 
--- a/dom/webidl/DOMRequest.webidl
+++ b/dom/webidl/DOMRequest.webidl
@@ -1,27 +1,27 @@
 /* -*- 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/. */
 
 enum DOMRequestReadyState { "pending", "done" };
 
-[Exposed=(Window,Worker), NoInterfaceObject]
+[Exposed=(Window,Worker,System), NoInterfaceObject]
 interface DOMRequestShared {
   readonly attribute DOMRequestReadyState readyState;
 
   readonly attribute any result;
   readonly attribute DOMException? error;
 
   attribute EventHandler onsuccess;
   attribute EventHandler onerror;
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface DOMRequest : EventTarget {
   // The [TreatNonCallableAsNull] annotation is required since then() should do
   // nothing instead of throwing errors when non-callable arguments are passed.
   // See documentation for Promise.then to see why we return "any".
   [NewObject, Throws]
   any then([TreatNonCallableAsNull] optional AnyCallback? fulfillCallback = null,
            [TreatNonCallableAsNull] optional AnyCallback? rejectCallback = null);
 
--- a/dom/webidl/DOMStringList.webidl
+++ b/dom/webidl/DOMStringList.webidl
@@ -5,14 +5,14 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface DOMStringList {
   readonly attribute unsigned long length;
   getter DOMString? item(unsigned long index);
   boolean contains(DOMString string);
 };
--- a/dom/webidl/ErrorEvent.webidl
+++ b/dom/webidl/ErrorEvent.webidl
@@ -1,15 +1,15 @@
 /* -*- 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/. */
 
 [Constructor(DOMString type, optional ErrorEventInit eventInitDict),
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface ErrorEvent : Event
 {
   readonly attribute DOMString message;
   readonly attribute DOMString filename;
   readonly attribute unsigned long lineno;
   readonly attribute unsigned long colno;
   readonly attribute any error;
 };
--- a/dom/webidl/Event.webidl
+++ b/dom/webidl/Event.webidl
@@ -6,17 +6,17 @@
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Constructor(DOMString type, optional EventInit eventInitDict),
- Exposed=(Window,Worker), ProbablyShortLivingWrapper]
+ Exposed=(Window,Worker,System), ProbablyShortLivingWrapper]
 interface Event {
   [Pure]
   readonly attribute DOMString type;
   [Pure, BindingAlias="srcElement"]
   readonly attribute EventTarget? target;
   [Pure]
   readonly attribute EventTarget? currentTarget;
 
--- a/dom/webidl/EventTarget.webidl
+++ b/dom/webidl/EventTarget.webidl
@@ -21,17 +21,17 @@ dictionary EventListenerOptions {
 dictionary AddEventListenerOptions : EventListenerOptions {
   boolean passive;
   boolean once = false;
   [ChromeOnly]
   boolean wantUntrusted;
 };
 
 [Constructor,
- Exposed=(Window,Worker,WorkerDebugger,AudioWorklet)]
+ Exposed=(Window,Worker,WorkerDebugger,AudioWorklet,System)]
 interface EventTarget {
   /* Passing null for wantsUntrusted means "default behavior", which
      differs in content and chrome.  In content that default boolean
      value is true, while in chrome the default boolean value is
      false. */
   [Throws]
   void addEventListener(DOMString type,
                         EventListener? listener,
@@ -60,11 +60,11 @@ partial interface EventTarget {
   [ChromeOnly]
   EventHandler getEventHandler(DOMString type);
 };
 
 // Mozilla extension to make firing events on event targets from
 // chrome easier.  This returns the window which can be used to create
 // events to fire at this EventTarget, or null if there isn't one.
 partial interface EventTarget {
-  [ChromeOnly, Exposed=Window, BinaryName="ownerGlobalForBindings"]
+  [ChromeOnly, Exposed=(Window,System), BinaryName="ownerGlobalForBindings"]
   readonly attribute WindowProxy? ownerGlobal;
 };
--- a/dom/webidl/FileReader.webidl
+++ b/dom/webidl/FileReader.webidl
@@ -6,17 +6,17 @@
  * The origin of this IDL file is
  * https://w3c.github.io/FileAPI/#APIASynch
  *
  * Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Constructor,
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface FileReader : EventTarget {
   // async read methods
   [Throws]
   void readAsArrayBuffer(Blob blob);
   [Throws]
   void readAsBinaryString(Blob filedata);
   [Throws]
   void readAsText(Blob blob, optional DOMString label);
--- a/dom/webidl/IDBCursor.webidl
+++ b/dom/webidl/IDBCursor.webidl
@@ -9,17 +9,17 @@
 
 enum IDBCursorDirection {
     "next",
     "nextunique",
     "prev",
     "prevunique"
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBCursor {
     readonly    attribute (IDBObjectStore or IDBIndex) source;
 
     readonly    attribute IDBCursorDirection           direction;
 
     [Throws]
     readonly    attribute any                          key;
 
@@ -37,13 +37,13 @@ interface IDBCursor {
 
     [Throws]
     void       continuePrimaryKey(any key, any primaryKey);
 
     [Throws]
     IDBRequest delete ();
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBCursorWithValue : IDBCursor {
     [Throws]
     readonly    attribute any value;
 };
--- a/dom/webidl/IDBDatabase.webidl
+++ b/dom/webidl/IDBDatabase.webidl
@@ -5,17 +5,17 @@
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBObjectStoreParameters
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBDatabase : EventTarget {
     readonly    attribute DOMString          name;
     readonly    attribute unsigned long long version;
 
     readonly    attribute DOMStringList      objectStoreNames;
 
     [Throws]
     IDBObjectStore createObjectStore (DOMString name, optional IDBObjectStoreParameters optionalParameters);
--- a/dom/webidl/IDBFactory.webidl
+++ b/dom/webidl/IDBFactory.webidl
@@ -18,17 +18,17 @@ dictionary IDBOpenDBOptions
   StorageType storage;
 };
 
 /**
  * Interface that defines the indexedDB property on a window.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
  * for more information.
  */
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBFactory {
   [Throws, NeedsCallerType]
   IDBOpenDBRequest
   open(DOMString name,
        [EnforceRange] unsigned long long version);
 
   [Throws, NeedsCallerType]
   IDBOpenDBRequest
--- a/dom/webidl/IDBFileHandle.webidl
+++ b/dom/webidl/IDBFileHandle.webidl
@@ -3,17 +3,17 @@
  * You can obtaone at http://mozilla.org/MPL/2.0/. */
 
 dictionary IDBFileMetadataParameters
 {
   boolean size = true;
   boolean lastModified = true;
 };
 
-[Exposed=(Window)]
+[Exposed=(Window,System)]
 interface IDBFileHandle : EventTarget
 {
   readonly attribute IDBMutableFile? mutableFile;
   // this is deprecated due to renaming in the spec
   readonly attribute IDBMutableFile? fileHandle; // now mutableFile
   readonly attribute FileMode mode;
   readonly attribute boolean active;
   attribute unsigned long long? location;
--- a/dom/webidl/IDBFileRequest.webidl
+++ b/dom/webidl/IDBFileRequest.webidl
@@ -1,14 +1,14 @@
 /* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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/. */
 
-[Exposed=Window]
+[Exposed=(Window,System)]
 interface IDBFileRequest : DOMRequest {
   readonly attribute IDBFileHandle? fileHandle;
   // this is deprecated due to renaming in the spec
   readonly attribute IDBFileHandle? lockedFile; // now fileHandle
 
   attribute EventHandler onprogress;
 };
--- a/dom/webidl/IDBIndex.webidl
+++ b/dom/webidl/IDBIndex.webidl
@@ -13,17 +13,17 @@ dictionary IDBIndexParameters {
     // <null>:   Not locale-aware, uses normal JS sorting.
     // <string>: Always sorted based on the rules of the specified
     //           locale (e.g. "en-US", etc.).
     // "auto":   Sorted by the platform default, may change based on
     //           user agent options.
     DOMString? locale = null;
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBIndex {
     [SetterThrows]
     attribute DOMString name;
 
     readonly    attribute IDBObjectStore objectStore;
 
     [Throws]
     readonly    attribute any            keyPath;
--- a/dom/webidl/IDBKeyRange.webidl
+++ b/dom/webidl/IDBKeyRange.webidl
@@ -4,17 +4,17 @@
 /*
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBKeyRange {
   [Throws]
   readonly attribute any     lower;
   [Throws]
   readonly attribute any     upper;
   [Constant]
   readonly attribute boolean lowerOpen;
   [Constant]
@@ -28,14 +28,14 @@ interface IDBKeyRange {
   [NewObject, Throws]
   static IDBKeyRange lowerBound (any lower, optional boolean open = false);
   [NewObject, Throws]
   static IDBKeyRange upperBound (any upper, optional boolean open = false);
   [NewObject, Throws]
   static IDBKeyRange bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
 };
 
-[Exposed=(Window,Worker),
+[Exposed=(Window,Worker,System),
  Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
 interface IDBLocaleAwareKeyRange : IDBKeyRange {
   [NewObject, Throws]
   static IDBLocaleAwareKeyRange bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
 };
--- a/dom/webidl/IDBMutableFile.webidl
+++ b/dom/webidl/IDBMutableFile.webidl
@@ -1,14 +1,14 @@
 /* -*- 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/. */
 
-[Exposed=Window]
+[Exposed=(Window,System)]
 interface IDBMutableFile : EventTarget {
   readonly attribute DOMString name;
   readonly attribute DOMString type;
 
   readonly attribute IDBDatabase database;
 
   [Throws, UseCounter]
   IDBFileHandle open(optional FileMode mode = "readonly");
--- a/dom/webidl/IDBObjectStore.webidl
+++ b/dom/webidl/IDBObjectStore.webidl
@@ -7,17 +7,17 @@
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBObjectStore
  */
 
 dictionary IDBObjectStoreParameters {
     (DOMString or sequence<DOMString>)? keyPath = null;
     boolean                             autoIncrement = false;
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBObjectStore {
     [SetterThrows]
     attribute DOMString name;
 
     [Throws]
     readonly    attribute any            keyPath;
 
     readonly    attribute DOMStringList  indexNames;
--- a/dom/webidl/IDBOpenDBRequest.webidl
+++ b/dom/webidl/IDBOpenDBRequest.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBOpenDBRequest
  */
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBOpenDBRequest : IDBRequest {
                 attribute EventHandler onblocked;
 
                 attribute EventHandler onupgradeneeded;
 };
--- a/dom/webidl/IDBRequest.webidl
+++ b/dom/webidl/IDBRequest.webidl
@@ -8,17 +8,17 @@
  * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBRequestReadyState
  */
 
 enum IDBRequestReadyState {
     "pending",
     "done"
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBRequest : EventTarget {
     [Throws]
     readonly    attribute any                  result;
 
     [Throws]
     readonly    attribute DOMException?        error;
 
     readonly    attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
--- a/dom/webidl/IDBTransaction.webidl
+++ b/dom/webidl/IDBTransaction.webidl
@@ -14,17 +14,17 @@ enum IDBTransactionMode {
     // The "readwriteflush" mode is only available when the
     // |IndexedDatabaseManager::ExperimentalFeaturesEnabled()| function returns
     // true. This mode is not yet part of the standard.
     "readwriteflush",
     "cleanup",
     "versionchange"
 };
 
-[Exposed=(Window,Worker)]
+[Exposed=(Window,Worker,System)]
 interface IDBTransaction : EventTarget {
     [Throws]
     readonly    attribute IDBTransactionMode mode;
     readonly    attribute IDBDatabase        db;
 
     readonly    attribute DOMException?      error;
 
     [Throws]
--- a/dom/webidl/IDBVersionChangeEvent.webidl
+++ b/dom/webidl/IDBVersionChangeEvent.webidl
@@ -11,14 +11,14 @@
  */
 
 dictionary IDBVersionChangeEventInit : EventInit {
     unsigned long long  oldVersion = 0;
     unsigned long long? newVersion = null;
 };
 
 [Constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict),
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface IDBVersionChangeEvent : Event {
     readonly    attribute unsigned long long  oldVersion;
     readonly    attribute unsigned long long? newVersion;
 };
 
--- a/dom/webidl/IdleDeadline.webidl
+++ b/dom/webidl/IdleDeadline.webidl
@@ -2,14 +2,14 @@
 /* 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/.
  *
  * The origin of this IDL file is:
  * https://w3c.github.io/requestidlecallback/
  */
 
-[Exposed=Window,
+[Exposed=(Window,System),
  Func="nsGlobalWindowInner::IsRequestIdleCallbackEnabled"]
 interface IdleDeadline {
   DOMHighResTimeStamp timeRemaining();
   readonly attribute boolean didTimeout;
 };
--- a/dom/webidl/LegacyQueryInterface.webidl
+++ b/dom/webidl/LegacyQueryInterface.webidl
@@ -5,20 +5,20 @@
  */
 
 interface nsISupports;
 interface IID;
 
 [NoInterfaceObject,
  // Need Exposed here, because this is a mixin onto things like Event
  // that are exposed in workers.
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface LegacyQueryInterface {
   // Legacy QueryInterface, only exposed to chrome code on the main thread.
-  [Exposed=Window, ChromeOnly]
+  [Exposed=(Window,System), ChromeOnly]
   nsISupports QueryInterface(IID iid);
 };
 
 DOMParser implements LegacyQueryInterface;
 Document implements LegacyQueryInterface;
 DocumentFragment implements LegacyQueryInterface;
 Element implements LegacyQueryInterface;
 Event implements LegacyQueryInterface;
--- a/dom/webidl/MessageChannel.webidl
+++ b/dom/webidl/MessageChannel.webidl
@@ -2,13 +2,13 @@
 /* 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/.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#channel-messaging
  */
 
-[Constructor, Exposed=(Window,Worker)]
+[Constructor, Exposed=(Window,Worker,System)]
 interface MessageChannel {
   readonly attribute MessagePort port1;
   readonly attribute MessagePort port2;
 };
--- a/dom/webidl/MessageEvent.webidl
+++ b/dom/webidl/MessageEvent.webidl
@@ -3,17 +3,17 @@
  * 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/.
  *
  * For more information on this interface, please see
  * https://html.spec.whatwg.org/#messageevent
  */
 
 [Constructor(DOMString type, optional MessageEventInit eventInitDict),
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface MessageEvent : Event {
   /**
    * Custom data associated with this event.
    */
   [GetterThrows]
   readonly attribute any data;
 
   /**
--- a/dom/webidl/MessagePort.webidl
+++ b/dom/webidl/MessagePort.webidl
@@ -2,17 +2,17 @@
 /* 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/.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#channel-messaging
  */
 
-[Exposed=(Window,Worker,AudioWorklet)]
+[Exposed=(Window,Worker,AudioWorklet,System)]
 interface MessagePort : EventTarget {
   [Throws]
   void postMessage(any message, optional sequence<object> transferable = []);
 
   void start();
   void close();
 
   // event handlers
--- a/dom/webidl/Promise.webidl
+++ b/dom/webidl/Promise.webidl
@@ -9,11 +9,12 @@
 
 callback PromiseJobCallback = void();
 
 [TreatNonCallableAsNull]
 callback AnyCallback = any (any value);
 
 // Hack to allow us to have JS owning and properly tracing/CCing/etc a
 // PromiseNativeHandler.
-[NoInterfaceObject, Exposed=(Window,Worker)]
+[NoInterfaceObject,
+ Exposed=(Window,Worker,System)]
 interface PromiseNativeHandler {
 };
--- a/dom/webidl/StreamFilter.webidl
+++ b/dom/webidl/StreamFilter.webidl
@@ -52,17 +52,17 @@ enum StreamFilterStatus {
    */
   "failed",
 };
 
 /**
  * An interface which allows an extension to intercept, and optionally modify,
  * response data from an HTTP request.
  */
-[Exposed=Window,
+[Exposed=(Window,System),
  Func="mozilla::extensions::StreamFilter::IsAllowedInContext"]
 interface StreamFilter : EventTarget {
   /**
    * Creates a stream filter for the given add-on and the given extension ID.
    */
   [ChromeOnly]
   static StreamFilter create(unsigned long long requestId, DOMString addonId);
 
--- a/dom/webidl/StreamFilterDataEvent.webidl
+++ b/dom/webidl/StreamFilterDataEvent.webidl
@@ -8,17 +8,17 @@
  * content. It allows monitoring and filtering of HTTP response stream data.
  *
  * This API should currently be considered experimental, and is not defined by
  * any standard.
  */
 
 [Constructor(DOMString type, optional StreamFilterDataEventInit eventInitDict),
  Func="mozilla::extensions::StreamFilter::IsAllowedInContext",
- Exposed=Window]
+ Exposed=(Window,System)]
 interface StreamFilterDataEvent : Event {
   /**
    * Contains a chunk of data read from the input stream.
    */
   [Pure]
   readonly attribute ArrayBuffer data;
 };
 
--- a/dom/webidl/TCPServerSocket.webidl
+++ b/dom/webidl/TCPServerSocket.webidl
@@ -10,17 +10,17 @@
  */
 
 dictionary ServerSocketOptions {
   TCPSocketBinaryType binaryType = "string";
 };
 
 [Constructor(unsigned short port, optional ServerSocketOptions options, optional unsigned short backlog = 0),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=Window]
+ Exposed=(Window,System)]
 interface TCPServerSocket : EventTarget {
   /**
    * The port of this server socket object.
    */
   readonly attribute unsigned short localPort;
 
   /**
    * The "connect" event is dispatched when a client connection is accepted.
--- a/dom/webidl/TCPServerSocketEvent.webidl
+++ b/dom/webidl/TCPServerSocketEvent.webidl
@@ -1,15 +1,15 @@
 /* -*- 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/. */
 
 [Constructor(DOMString type, optional TCPServerSocketEventInit eventInitDict),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=Window]
+ Exposed=(Window,System)]
 interface TCPServerSocketEvent : Event {
   readonly attribute TCPSocket socket;
 };
 
 dictionary TCPServerSocketEventInit : EventInit {
   TCPSocket? socket = null;
 };
--- a/dom/webidl/TCPSocket.webidl
+++ b/dom/webidl/TCPSocket.webidl
@@ -36,17 +36,17 @@ interface LegacyMozTCPSocket {
   TCPSocket open(DOMString host, unsigned short port, optional SocketOptions options);
 
   [Throws]
   TCPServerSocket listen(unsigned short port, optional ServerSocketOptions options, optional unsigned short backlog = 0);
 };
 
 [Constructor(DOMString host, unsigned short port, optional SocketOptions options),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=Window]
+ Exposed=(Window,System)]
 interface TCPSocket : EventTarget {
   /**
    * Upgrade an insecure connection to use TLS. Throws if the ready state is not OPEN.
    */
   [Throws] void upgradeToSecure();
 
   /**
    * The UTF16 host of this socket object.
--- a/dom/webidl/TCPSocketErrorEvent.webidl
+++ b/dom/webidl/TCPSocketErrorEvent.webidl
@@ -6,17 +6,17 @@
 /* Dispatched as part of the "error" event in the following situations:
 * - if there's an error detected when the TCPSocket closes
 * - if there's an internal error while sending data
 * - if there's an error connecting to the host
 */
 
 [Constructor(DOMString type, optional TCPSocketErrorEventInit eventInitDict),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=Window]
+ Exposed=(Window,System)]
 interface TCPSocketErrorEvent : Event {
   readonly attribute DOMString name;
   readonly attribute DOMString message;
 };
 
 dictionary TCPSocketErrorEventInit : EventInit
 {
   DOMString name = "";
--- a/dom/webidl/TCPSocketEvent.webidl
+++ b/dom/webidl/TCPSocketEvent.webidl
@@ -6,17 +6,17 @@
 /**
  * TCPSocketEvent is the event dispatched for all of the events described by TCPSocket,
  * except the "error" event. It contains the socket that was associated with the event,
  * the type of event, and the data associated with the event if the event is a "data" event.
  */
 
 [Constructor(DOMString type, optional TCPSocketEventInit eventInitDict),
  Func="mozilla::dom::TCPSocket::ShouldTCPSocketExist",
- Exposed=Window]
+ Exposed=(Window,System)]
 interface TCPSocketEvent : Event {
   /**
    * If the event is a "data" event, data will be the bytes read from the network;
    * if the binaryType of the socket was "arraybuffer", this value will be of type
    * ArrayBuffer, otherwise, it will be a ByteString.
    *
    * For other events, data will be an empty string.
    */
--- a/dom/webidl/TextDecoder.webidl
+++ b/dom/webidl/TextDecoder.webidl
@@ -6,17 +6,17 @@
  * The origin of this IDL file is
  * http://encoding.spec.whatwg.org/#interface-textdecoder
  *
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 [Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options),
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker,System)]
 interface TextDecoder {
   [Constant]
   readonly attribute DOMString encoding;
   [Constant]
   readonly attribute boolean fatal;
   [Constant]
   readonly attribute boolean ignoreBOM;
   [Throws]
--- a/dom/webidl/TextEncoder.webidl
+++ b/dom/webidl/TextEncoder.webidl
@@ -5,17 +5,18 @@
  *
  * The origin of this IDL file is
  * http://encoding.spec.whatwg.org/#interface-textencoder
  *
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-[Constructor, Exposed=(Window,Worker)]
+[Constructor,
+ Exposed=(Window,Worker,System)]
 interface TextEncoder {
   [Constant]
   readonly attribute DOMString encoding;
   /*
    * This is spec-wise USVString but marking it as
    * DOMString to avoid duplicate work. Since the
    * UTF-16 to UTF-8 converter performs processing
    * that's equivalent to first converting a
--- a/dom/webidl/URLSearchParams.webidl
+++ b/dom/webidl/URLSearchParams.webidl
@@ -9,17 +9,17 @@
  * To the extent possible under law, the editors have waived all copyright
  * and related or neighboring rights to this work. In addition, as of 17
  * February 2013, the editors have made this specification available under
  * the Open Web Foundation Agreement Version 1.0, which is available at
  * http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
  */
 
 [Constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = ""),
- Exposed=(Window,Worker,WorkerDebugger)]
+ Exposed=(Window,Worker,WorkerDebugger,System)]
 interface URLSearchParams {
   void append(USVString name, USVString value);
   void delete(USVString name);
   USVString? get(USVString name);
   sequence<USVString> getAll(USVString name);
   boolean has(USVString name);
   void set(USVString name, USVString value);
 
--- a/dom/webidl/Worker.webidl
+++ b/dom/webidl/Worker.webidl
@@ -8,17 +8,17 @@
  *
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera
  * Software ASA.
  * You are granted a license to use, reproduce and create derivative works of
  * this document.
  */
 
 [Constructor(USVString scriptURL, optional WorkerOptions options),
- Exposed=(Window,DedicatedWorker,SharedWorker)]
+ Exposed=(Window,DedicatedWorker,SharedWorker,System)]
 interface Worker : EventTarget {
   void terminate();
 
   [Throws]
   void postMessage(any message, optional sequence<object> transfer = []);
 
   attribute EventHandler onmessage;
   attribute EventHandler onmessageerror;
@@ -29,11 +29,11 @@ Worker implements AbstractWorker;
 dictionary WorkerOptions {
   // WorkerType type = "classic"; TODO: Bug 1247687
   // RequestCredentials credentials = "omit"; // credentials is only used if type is "module" TODO: Bug 1247687
   DOMString name = "";
 };
 
 [Constructor(USVString scriptURL),
  Func="mozilla::dom::ChromeWorker::WorkerAvailable",
- Exposed=(Window,DedicatedWorker,SharedWorker)]
+ Exposed=(Window,DedicatedWorker,SharedWorker,System)]
 interface ChromeWorker : Worker {
 };