Merge fx-team to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 29 Apr 2014 23:08:08 -0400
changeset 181316 db8043427ac20c7f1a200000316d450b5c9dbd50
parent 181284 de19c62cbc6b583b04f8458e7e8b281c88551b3a (current diff)
parent 181315 6eed9c67a1e37b1681c94c3234ce25343d6abbae (diff)
child 181317 429d4d1f49e1dce7eaa9dc20354dd4c79824ab48
child 181335 e19812f5695283848e15b9b98fc06f4f97a7d79b
child 181396 79cd3d6e0c520d3fe7eb77ff55673c36df09dd8c
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
milestone32.0a1
Merge fx-team to m-c.
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6945,16 +6945,22 @@ var TabContextMenu = {
     this.contextTab = aPopupMenu.triggerNode.localName == "tab" ?
                       aPopupMenu.triggerNode : gBrowser.selectedTab;
     let disabled = gBrowser.tabs.length == 1;
 
     var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
     for (let menuItem of menuItems)
       menuItem.disabled = disabled;
 
+#ifdef NIGHTLY_BUILD
+    menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-remote");
+    for (let menuItem of menuItems)
+      menuItem.hidden = !gMultiProcessBrowser;
+#endif
+
     disabled = gBrowser.visibleTabs.length == 1;
     menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple-visible");
     for (let menuItem of menuItems)
       menuItem.disabled = disabled;
 
     // Session store
     document.getElementById("context_undoCloseTab").disabled =
       SessionStore.getClosedTabCount(window) == 0;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -96,16 +96,20 @@
           <menuitem id="context_tabViewNewGroup" label="&moveToNewGroup.label;"
                     oncommand="TabView.moveTabTo(TabContextMenu.contextTab, null);"/>
         </menupopup>
       </menu>
       <menuitem id="context_openTabInWindow" label="&moveToNewWindow.label;"
                 accesskey="&moveToNewWindow.accesskey;"
                 tbattr="tabbrowser-multiple"
                 oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
+      <menuitem id="context_openNonRemoteWindow" label="Open in new non-e10s window"
+                tbattr="tabbrowser-remote"
+                hidden="true"
+                oncommand="gBrowser.openNonRemoteWindow(TabContextMenu.contextTab);"/>
       <menuseparator/>
       <menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
                 tbattr="tabbrowser-multiple-visible"
                 oncommand="gBrowser.reloadAllTabs();"/>
       <menuitem id="context_bookmarkAllTabs"
                 label="&bookmarkAllTabs.label;"
                 accesskey="&bookmarkAllTabs.accesskey;"
                 command="Browser:BookmarkAllTabs"/>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2515,16 +2515,27 @@
               options += "," + name + "=" + aOptions[name];
 
             // tell a new window to take the "dropped" tab
             return window.openDialog(getBrowserURL(), "_blank", options, aTab);
           ]]>
         </body>
       </method>
 
+      <!-- Opens a given tab to a non-remote window. -->
+      <method name="openNonRemoteWindow">
+        <parameter name="aTab"/>
+        <body>
+          <![CDATA[
+            let url = aTab.linkedBrowser.currentURI.spec;
+            return window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no,non-remote", url);
+          ]]>
+        </body>
+      </method>
+
       <method name="moveTabTo">
         <parameter name="aTab"/>
         <parameter name="aIndex"/>
         <body>
         <![CDATA[
           var oldPosition = aTab._tPos;
           if (oldPosition == aIndex)
             return;
--- a/mobile/android/base/InputMethods.java
+++ b/mobile/android/base/InputMethods.java
@@ -58,29 +58,16 @@ final public class InputMethods {
         return Build.VERSION.SDK_INT >= 17 && (METHOD_ANDROID_LATINIME.equals(inputMethod) ||
                                                METHOD_GOOGLE_LATINIME.equals(inputMethod));
     }
 
     public static boolean shouldCommitCharAsKey(String inputMethod) {
         return METHOD_HTC_TOUCH_INPUT.equals(inputMethod);
     }
 
-    @RobocopTarget
-    public static boolean shouldDisableUrlBarUpdate(Context context) {
-        String inputMethod = getCurrentInputMethod(context);
-        // HTC Touch Input does not react well to restarting during input (bug 909940)
-        return METHOD_HTC_TOUCH_INPUT.equals(inputMethod);
-    }
-
-    public static boolean shouldDelayUrlBarUpdate(Context context) {
-        String inputMethod = getCurrentInputMethod(context);
-        return METHOD_SAMSUNG.equals(inputMethod) ||
-               METHOD_SWIFTKEY.equals(inputMethod);
-    }
-
     public static boolean isGestureKeyboard(Context context) {
         // SwiftKey is a gesture keyboard, but it doesn't seem to need any special-casing
         // to do AwesomeBar auto-spacing.
         String inputMethod = getCurrentInputMethod(context);
         return (Build.VERSION.SDK_INT >= 17 && (METHOD_ANDROID_LATINIME.equals(inputMethod) ||
                                                 METHOD_GOOGLE_LATINIME.equals(inputMethod))) ||
                METHOD_SWYPE.equals(inputMethod) ||
                METHOD_SWYPE_BETA.equals(inputMethod) ||
--- a/mobile/android/base/toolbar/ToolbarEditText.java
+++ b/mobile/android/base/toolbar/ToolbarEditText.java
@@ -53,38 +53,33 @@ public class ToolbarEditText extends Cus
     interface OnTextTypeChangeListener {
         public void onTextTypeChange(ToolbarEditText editText, TextType textType);
     }
 
     private final Context mContext;
 
     // Type of the URL bar go/search button
     private TextType mToolbarTextType;
-    // Type of the keyboard go/search button (cannot be EMPTY)
-    private TextType mKeyboardTextType;
 
     private OnCommitListener mCommitListener;
     private OnDismissListener mDismissListener;
     private OnFilterListener mFilterListener;
     private OnTextTypeChangeListener mTextTypeListener;
 
     // The previous autocomplete result returned to us
     private String mAutoCompleteResult = "";
 
     // The user typed part of the autocomplete result
     private String mAutoCompletePrefix = null;
 
-    private boolean mDelayRestartInput;
-
     public ToolbarEditText(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
 
         mToolbarTextType = TextType.EMPTY;
-        mKeyboardTextType = TextType.URL;
     }
 
     void setOnCommitListener(OnCommitListener listener) {
         mCommitListener = listener;
     }
 
     void setOnDismissListener(OnDismissListener listener) {
         mDismissListener = listener;
@@ -153,33 +148,16 @@ public class ToolbarEditText extends Cus
         updateTextTypeFromText(getText().toString());
     }
 
     private void resetAutocompleteState() {
         mAutoCompleteResult = "";
         mAutoCompletePrefix = null;
     }
 
-    private void updateKeyboardInputType() {
-        // If the user enters a space, then we know they are entering
-        // search terms, not a URL. We can then switch to text mode so,
-        //   1) the IME auto-inserts spaces between words
-        //   2) the IME doesn't reset input keyboard to Latin keyboard.
-        final String text = getText().toString();
-        final int currentInputType = getInputType();
-
-        final int newInputType = StringUtils.isSearchQuery(text, false)
-                                 ? (currentInputType & ~InputType.TYPE_TEXT_VARIATION_URI) // Text mode
-                                 : (currentInputType | InputType.TYPE_TEXT_VARIATION_URI); // URL mode
-
-        if (newInputType != currentInputType) {
-            setRawInputType(newInputType);
-        }
-    }
-
     private static boolean hasCompositionString(Editable content) {
         Object[] spans = content.getSpans(0, content.length(), Object.class);
 
         if (spans != null) {
             for (Object span : spans) {
                 if ((content.getSpanFlags(span) & Spanned.SPAN_COMPOSING) != 0) {
                     // Found composition string.
                     return true;
@@ -188,82 +166,34 @@ public class ToolbarEditText extends Cus
         }
 
         return false;
     }
 
     private void setTextType(TextType textType) {
         mToolbarTextType = textType;
 
-        if (textType != TextType.EMPTY) {
-            mKeyboardTextType = textType;
-        }
         if (mTextTypeListener != null) {
             mTextTypeListener.onTextTypeChange(this, textType);
         }
     }
 
     private void updateTextTypeFromText(String text) {
         if (text.length() == 0) {
             setTextType(TextType.EMPTY);
             return;
         }
 
-        if (InputMethods.shouldDisableUrlBarUpdate(mContext)) {
-            // Set button type to match the previous keyboard type
-            setTextType(mKeyboardTextType);
-            return;
-        }
-
-        final int actionBits = getImeOptions() & EditorInfo.IME_MASK_ACTION;
-
-        final int imeAction;
-        if (StringUtils.isSearchQuery(text, actionBits == EditorInfo.IME_ACTION_SEARCH)) {
-            imeAction = EditorInfo.IME_ACTION_SEARCH;
+        final TextType newType;
+        if (StringUtils.isSearchQuery(text, mToolbarTextType == TextType.SEARCH_QUERY)) {
+            newType = TextType.SEARCH_QUERY;
         } else {
-            imeAction = EditorInfo.IME_ACTION_GO;
-        }
-
-        InputMethodManager imm = InputMethods.getInputMethodManager(mContext);
-        if (imm == null) {
-            return;
+            newType = TextType.URL;
         }
-
-        boolean restartInput = false;
-        if (actionBits != imeAction) {
-            int optionBits = getImeOptions() & ~EditorInfo.IME_MASK_ACTION;
-            setImeOptions(optionBits | imeAction);
-
-            mDelayRestartInput = (imeAction == EditorInfo.IME_ACTION_GO) &&
-                                 (InputMethods.shouldDelayUrlBarUpdate(mContext));
-
-            if (!mDelayRestartInput) {
-                restartInput = true;
-            }
-        } else if (mDelayRestartInput) {
-            // Only call delayed restartInput when actionBits == imeAction
-            // so if there are two restarts in a row, the first restarts will
-            // be discarded and the second restart will be properly delayed
-            mDelayRestartInput = false;
-            restartInput = true;
-        }
-
-        if (!restartInput) {
-            // If the text content was previously empty, the toolbar text type
-            // is empty as well. Since the keyboard text type cannot be empty,
-            // the two text types are now inconsistent. Reset the toolbar text
-            // type here to the keyboard text type to ensure consistency.
-            setTextType(mKeyboardTextType);
-            return;
-        }
-        updateKeyboardInputType();
-        imm.restartInput(ToolbarEditText.this);
-
-        setTextType(imeAction == EditorInfo.IME_ACTION_GO ?
-                    TextType.URL : TextType.SEARCH_QUERY);
+        setTextType(newType);
     }
 
     private class TextChangeListener implements TextWatcher {
         @Override
         public void afterTextChanged(final Editable s) {
             if (!isEnabled()) {
                 return;
             }
@@ -296,21 +226,17 @@ public class ToolbarEditText extends Cus
 
                 mAutoCompletePrefix = text;
 
                 if (reuseAutocomplete) {
                     onAutocomplete(mAutoCompleteResult);
                 }
             }
 
-            // If the edit text has a composition string, don't call updateGoButton().
-            // That method resets IME and composition state will be broken.
-            if (!hasCompositionString(s) || InputMethods.isGestureKeyboard(mContext)) {
-                updateTextTypeFromText(text);
-            }
+            updateTextTypeFromText(text);
         }
 
         @Override
         public void beforeTextChanged(CharSequence s, int start, int count,
                                       int after) {
             // do nothing
         }
 
--- a/toolkit/components/feeds/FeedProcessor.js
+++ b/toolkit/components/feeds/FeedProcessor.js
@@ -458,21 +458,25 @@ Entry.prototype = {
       this._atomLinksToEnclosures();
 
     // Add RSS2 enclosure to enclosures
     if (bagHasKey(this.fields, "enclosure"))
       this._enclosureToEnclosures();
 
     // Add media:content to enclosures
     if (bagHasKey(this.fields, "mediacontent"))
-      this._mediacontentToEnclosures();
+      this._mediaToEnclosures("mediacontent");
+
+    // Add media:thumbnail to enclosures
+    if (bagHasKey(this.fields, "mediathumbnail"))
+      this._mediaToEnclosures("mediathumbnail");
 
     // Add media:content in media:group to enclosures
     if (bagHasKey(this.fields, "mediagroup"))
-      this._mediagroupToEnclosures();
+      this._mediaToEnclosures("mediagroup", "mediacontent");
   },
 
   __enclosure_map: null,
 
   _addToEnclosures: function Entry_addToEnclosures(new_enc) {
     // items we add to the enclosures array get displayed in the FeedWriter and
     // they must have non-empty urls.
     if (!bagHasKey(new_enc, "url") || new_enc.getPropertyAsAString("url") == "")
@@ -534,60 +538,42 @@ Entry.prototype = {
     var enc = this.fields.getPropertyAsInterface("enclosure", Ci.nsIPropertyBag2);
 
     if (!(enc.getProperty("url")))
       return;
 
     this._addToEnclosures(enc);
   },
 
-  _mediacontentToEnclosures: function Entry_mediacontentToEnclosures() {
-    var mediacontent = this.fields.getPropertyAsInterface("mediacontent", Ci.nsIArray);
+  _mediaToEnclosures: function Entry_mediaToEnclosures(mediaType, contentType) {
+    var content = this.fields.getPropertyAsInterface(mediaType, Ci.nsIArray);
 
-    for (var i = 0; i < mediacontent.length; ++i) {
-      var contentElement = mediacontent.queryElementAt(i, Ci.nsIWritablePropertyBag2);
+    if (contentType)
+      content = content.getPropertyAsInterface(contentType, Ci.nsIArray);
+
+    for (var i = 0; i < content.length; ++i) {
+      var contentElement = content.queryElementAt(i, Ci.nsIWritablePropertyBag2);
 
       // media:content don't require url, but if it's not there, we should
       // skip it.
       if (!bagHasKey(contentElement, "url"))
         continue;
 
       var enc = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
 
       // copy media:content bits over to equivalent enclosure bits
       enc.setPropertyAsAString("url", contentElement.getPropertyAsAString("url"));
       if (bagHasKey(contentElement, "type")) {
         enc.setPropertyAsAString("type", contentElement.getPropertyAsAString("type"));
-      }
-      if (bagHasKey(contentElement, "fileSize")) {
-        enc.setPropertyAsAString("length", contentElement.getPropertyAsAString("fileSize"));
+      } else if (mediaType == "mediathumbnail") {
+        // thumbnails won't have a type, but default to image types
+        enc.setPropertyAsAString("type", "image/*");
+        enc.setPropertyAsBool("thumbnail", true);
       }
 
-      this._addToEnclosures(enc);
-    }
-  },
-
-  _mediagroupToEnclosures: function Entry_mediagroupToEnclosures() {
-    var group = this.fields.getPropertyAsInterface("mediagroup", Ci.nsIPropertyBag2);
-
-    var content = group.getPropertyAsInterface("mediacontent", Ci.nsIArray);
-    for (var i = 0; i < content.length; ++i) {
-      var contentElement = content.queryElementAt(i, Ci.nsIWritablePropertyBag2);
-      // media:content don't require url, but if it's not there, we should
-      // skip it.
-      if (!bagHasKey(contentElement, "url"))
-        continue;
-
-      var enc = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
-
-      // copy media:content bits over to equivalent enclosure bits
-      enc.setPropertyAsAString("url", contentElement.getPropertyAsAString("url"));
-      if (bagHasKey(contentElement, "type")) {
-        enc.setPropertyAsAString("type", contentElement.getPropertyAsAString("type"));
-      }
       if (bagHasKey(contentElement, "fileSize")) {
         enc.setPropertyAsAString("length", contentElement.getPropertyAsAString("fileSize"));
       }
 
       this._addToEnclosures(enc);
     }
   },
 
@@ -1132,29 +1118,31 @@ function FeedProcessor() {
       "dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
                                    rssAuthor, true),
       "dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
                                          rssAuthor, true),
       "category": new ElementInfo("categories", null, rssCatTerm, true),
       "enclosure": new ElementInfo("enclosure", null, null, false),
       "media:content": new ElementInfo("mediacontent", null, null, true),
       "media:group": new ElementInfo("mediagroup", null, null, false),
+      "media:thumbnail": new ElementInfo("mediathumbnail", null, null, true),
       "guid": new ElementInfo("guid", null, rssGuid, false)
     },
 
     "IN_SKIPDAYS": {
       "day": new ElementInfo("days", null, rssArrayElement, true)
     },
 
     "IN_SKIPHOURS":{
       "hour": new ElementInfo("hours", null, rssArrayElement, true)
     },
 
     "IN_MEDIAGROUP": {
-      "media:content": new ElementInfo("mediacontent", null, null, true)
+      "media:content": new ElementInfo("mediacontent", null, null, true),
+      "media:thumbnail": new ElementInfo("mediathumbnail", null, null, true)
     },
  
     /********* RSS1 **********/
     "IN_RDF": {
       // If we hit a rss1:channel, we can verify that we have RSS1
       "rss1:channel": new FeedElementInfo("rdf_channel", "rss1"),
       "rss1:image": new ElementInfo("image", null, null, false),
       "rss1:textinput": new ElementInfo("textInput", null, null, false),
--- a/toolkit/components/feeds/test/xml/rss2/mrss_content.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_content.xml
@@ -4,17 +4,18 @@
 Description: mrss content works
 Expect: var enc = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getPropertyAsInterface('mediacontent', Components.interfaces.nsIArray).queryElementAt(0, Components.interfaces.nsIPropertyBag); ((enc.getProperty('fileSize') == '24986239') && (enc.getProperty('type') == 'video/mpeg') && (enc.getProperty('url') == 'http://dallas.example.com/joebob_050689.mpeg') && (feed.type == 4) && (feed.enclosureCount == 1));
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 <item>
 
-<media:content fileSize="24986239" type="video/mpeg" url="http://dallas.example.com/joebob_050689.mpeg" /> 
+<media:content fileSize="24986239" type="video/mpeg" url="http://dallas.example.com/joebob_050689.mpeg" />
+<media:thumbnail url="http://dallas.example.com/joebob_050689.jpg"  width="75" height="50"/>
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <comments>http://example.org</comments>
 <title>test</title>
 
 <category domain="foo">bar</category>
 
 <description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
 </channel>
--- a/toolkit/devtools/server/actors/root.js
+++ b/toolkit/devtools/server/actors/root.js
@@ -1,18 +1,19 @@
 /* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript 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/. */
 
 "use strict";
 
-let devtools_ = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
-let { createExtraActors, appendExtraActors } = devtools_.require("devtools/server/actors/common");
+const Services = require("Services");
+const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/server/actors/common");
+const { DebuggerServer } = require("devtools/server/main");
 
 /* Root actor for the remote debugging protocol. */
 
 /**
  * Create a remote debugging protocol root actor.
  *
  * @param aConnection
  *     The DebuggerServerConnection whose root actor we are constructing.
@@ -333,8 +334,10 @@ RootActor.prototype = {
 };
 
 RootActor.prototype.requestTypes = {
   "listTabs": RootActor.prototype.onListTabs,
   "listAddons": RootActor.prototype.onListAddons,
   "echo": RootActor.prototype.onEcho,
   "protocolDescription": RootActor.prototype.onProtocolDescription
 };
+
+exports.RootActor = RootActor;
--- a/toolkit/devtools/server/actors/webbrowser.js
+++ b/toolkit/devtools/server/actors/webbrowser.js
@@ -4,16 +4,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/. */
 
 "use strict";
 
 let { Ci, Cu } = require("chrome");
 let Services = require("Services");
 let { createExtraActors, appendExtraActors } = require("devtools/server/actors/common");
+let { RootActor } = require("devtools/server/actors/root");
 let { AddonThreadActor, ThreadActor } = require("devtools/server/actors/script");
 let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
 
 let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
 
--- a/toolkit/devtools/server/main.js
+++ b/toolkit/devtools/server/main.js
@@ -214,17 +214,16 @@ var DebuggerServer = {
    */
   init: function DS_init(aAllowConnectionCallback) {
     if (this.initialized) {
       return;
     }
 
     this.xpcInspector = Cc["@mozilla.org/jsinspector;1"].getService(Ci.nsIJSInspector);
     this.initTransport(aAllowConnectionCallback);
-    this.addActors("resource://gre/modules/devtools/server/actors/root.js");
 
     this._initialized = true;
   },
 
   protocol: require("devtools/server/protocol"),
 
   /**
    * Initialize the debugger server's transport variables.  This can be
--- a/toolkit/devtools/server/tests/unit/head_dbg.js
+++ b/toolkit/devtools/server/tests/unit/head_dbg.js
@@ -29,16 +29,17 @@ function tryImport(url) {
   }
 }
 
 tryImport("resource://gre/modules/devtools/dbg-server.jsm");
 tryImport("resource://gre/modules/devtools/dbg-client.jsm");
 tryImport("resource://gre/modules/devtools/Loader.jsm");
 tryImport("resource://gre/modules/devtools/Console.jsm");
 
+let { RootActor } = devtools.require("devtools/server/actors/root");
 let { BreakpointStore, LongStringActor, ThreadActor } = devtools.require("devtools/server/actors/script");
 
 function testExceptionHook(ex) {
   try {
     do_report_unexpected_exception(ex);
   } catch(ex) {
     return {throw: ex}
   }
@@ -178,26 +179,24 @@ function attachTestTabAndResume(aClient,
   });
 }
 
 /**
  * Initialize the testing debugger server.
  */
 function initTestDebuggerServer()
 {
-  DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/root.js");
   DebuggerServer.registerModule("devtools/server/actors/script");
   DebuggerServer.addActors("resource://test/testactors.js");
   // Allow incoming connections.
   DebuggerServer.init(function () { return true; });
 }
 
 function initTestTracerServer()
 {
-  DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/root.js");
   DebuggerServer.registerModule("devtools/server/actors/script");
   DebuggerServer.addActors("resource://test/testactors.js");
   DebuggerServer.registerModule("devtools/server/actors/tracer");
   // Allow incoming connections.
   DebuggerServer.init(function () { return true; });
 }
 
 function finishClient(aClient)
--- a/toolkit/devtools/server/tests/unit/test_forwardingprefix.js
+++ b/toolkit/devtools/server/tests/unit/test_forwardingprefix.js
@@ -32,17 +32,17 @@ function run_test()
  * |aPrefix| is optional; if present, it's the prefix (minus the ':') for
  * actors in the new connection.
  */
 function newConnection(aPrefix)
 {
   var conn;
   DebuggerServer.createRootActor = function (aConn) {
     conn = aConn;
-    return new DebuggerServer.RootActor(aConn, {});
+    return new RootActor(aConn, {});
   };
 
   var transport = DebuggerServer.connectPipe(aPrefix);
 
   return { conn: conn, transport: transport };
 }
 
 /* Create the main connection for these tests. */
--- a/toolkit/devtools/server/tests/unit/testactors.js
+++ b/toolkit/devtools/server/tests/unit/testactors.js
@@ -1,13 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const Cu = Components.utils;
 const devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
+const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/server/actors/common");
+const { RootActor } = devtools.require("devtools/server/actors/root");
 const { ThreadActor } = devtools.require("devtools/server/actors/script");
 
 var gTestGlobals = [];
 DebuggerServer.addTestGlobal = function(aGlobal) {
   gTestGlobals.push(aGlobal);
 };
 
 // A mock tab list, for use by tests. This simply presents each global in