Merge fx-team to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 14 Aug 2013 17:04:38 -0400
changeset 142619 a8daa428ccbc16c9c5701035b83715740efd1e8f
parent 142611 bb3674e352889b3eea40125b30b741fd90f0e7da (current diff)
parent 142618 919119a88080a7642cdc6f3609766cb84b642e1a (diff)
child 142680 300a1c4246f84db5ed982df5a011becf45cd7ceb
child 142715 9607ca638f6a6d6b44e5c5a6e4ca8ba22a5a58b0
child 142726 b1b4704784b6770fac51e8c9512b77a4a26dfb32
push id25103
push userryanvm@gmail.com
push dateWed, 14 Aug 2013 21:09:44 +0000
treeherdermozilla-central@a8daa428ccbc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
a8daa428ccbc / 26.0a1 / 20130814141812 / files
nightly linux64
a8daa428ccbc / 26.0a1 / 20130814141812 / files
nightly mac
a8daa428ccbc / 26.0a1 / 20130814141812 / files
nightly win32
a8daa428ccbc / 26.0a1 / 20130814141812 / files
nightly win64
a8daa428ccbc / 26.0a1 / 20130814141812 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge fx-team to m-c.
--- a/addon-sdk/source/python-lib/cuddlefish/runner.py
+++ b/addon-sdk/source/python-lib/cuddlefish/runner.py
@@ -30,17 +30,17 @@ PARSEABLE_TEST_NAME = re.compile(r'TEST-
 # The purpose of this timeout is to recover from infinite loops.  It should be
 # longer than the amount of time any test run takes, including those on slow
 # machines running slow (debug) versions of Firefox.
 RUN_TIMEOUT = 1.5 * 60 * 60 # 1.5 Hour
 
 # Maximum time we'll wait for tests to emit output, in seconds.
 # The purpose of this timeout is to recover from hangs.  It should be longer
 # than the amount of time any test takes to report results.
-OUTPUT_TIMEOUT = 60 # one minute
+OUTPUT_TIMEOUT = 60 * 5 # five minutes
 
 def follow_file(filename):
     """
     Generator that yields the latest unread content from the given
     file, or None if no new content is available.
 
     For example:
 
--- a/addon-sdk/source/test/addons/simple-prefs/lib/main.js
+++ b/addon-sdk/source/test/addons/simple-prefs/lib/main.js
@@ -25,37 +25,47 @@ exports.testOptionsType = function(asser
 }
 
 if (app.is('Firefox')) {
   exports.testAOM = function(assert, done) {
       tabs.open({
       	url: 'about:addons',
       	onReady: function(tab) {
           tab.attach({
-          	contentScript: 'AddonManager.getAddonByID("' + self.id + '", function(aAddon) {\n' +
-          		             'unsafeWindow.gViewController.viewObjects.detail.node.addEventListener("ViewChanged", function whenViewChanges() {\n' +
-          		               'unsafeWindow.gViewController.viewObjects.detail.node.removeEventListener("ViewChanged", whenViewChanges, false);\n' +
-          		               'setTimeout(function() {\n' + // TODO: figure out why this is necessary..
-                                 'self.postMessage({\n' +
-                                   'somePreference: getAttributes(unsafeWindow.document.querySelector("setting[title=\'some-title\']")),\n' +
-                                   'myInteger: getAttributes(unsafeWindow.document.querySelector("setting[title=\'my-int\']")),\n' +
-                                   'myHiddenInt: getAttributes(unsafeWindow.document.querySelector("setting[title=\'hidden-int\']"))\n' +
-                                 '});\n' +
-          		               '}, 250);\n' +
-          		             '}, false);\n' +
-                             'unsafeWindow.gViewController.commands.cmd_showItemDetails.doCommand(aAddon, true);\n' +
-                           '});\n' + 
-                           'function getAttributes(ele) {\n' +
-                             'if (!ele) return {};\n' +
-                             'return {\n' +
-                               'pref: ele.getAttribute("pref"),\n' +
-                               'type: ele.getAttribute("type"),\n' +
-                               'title: ele.getAttribute("title"),\n' +
-                               'desc: ele.getAttribute("desc")\n' +
+            contentScriptWhen: 'end',
+          	contentScript: 'function onLoad() {\n' +
+                             'unsafeWindow.removeEventListener("load", onLoad, false);\n' +
+                             'AddonManager.getAddonByID("' + self.id + '", function(aAddon) {\n' +
+                               'unsafeWindow.gViewController.viewObjects.detail.node.addEventListener("ViewChanged", function whenViewChanges() {\n' +
+                                 'unsafeWindow.gViewController.viewObjects.detail.node.removeEventListener("ViewChanged", whenViewChanges, false);\n' +
+                                 'setTimeout(function() {\n' + // TODO: figure out why this is necessary..
+                                     'self.postMessage({\n' +
+                                       'somePreference: getAttributes(unsafeWindow.document.querySelector("setting[title=\'some-title\']")),\n' +
+                                       'myInteger: getAttributes(unsafeWindow.document.querySelector("setting[title=\'my-int\']")),\n' +
+                                       'myHiddenInt: getAttributes(unsafeWindow.document.querySelector("setting[title=\'hidden-int\']"))\n' +
+                                     '});\n' +
+                                 '}, 250);\n' +
+                               '}, false);\n' +
+                               'unsafeWindow.gViewController.commands.cmd_showItemDetails.doCommand(aAddon, true);\n' +
+                             '});\n' +
+                             'function getAttributes(ele) {\n' +
+                               'if (!ele) return {};\n' +
+                               'return {\n' +
+                                 'pref: ele.getAttribute("pref"),\n' +
+                                 'type: ele.getAttribute("type"),\n' +
+                                 'title: ele.getAttribute("title"),\n' +
+                                 'desc: ele.getAttribute("desc")\n' +
+                               '}\n' +
                              '}\n' +
+                           '}\n' +
+                           // Wait for the load event ?
+                           'if (document.readyState == "complete") {\n' +
+                             'onLoad()\n' +
+                           '} else {\n' +
+                             'unsafeWindow.addEventListener("load", onLoad, false);\n' +
                            '}\n',
             onMessage: function(msg) {
               // test somePreference
               assert.equal(msg.somePreference.type, 'string', 'some pref is a string');
               assert.equal(msg.somePreference.pref, 'extensions.'+self.id+'.somePreference', 'somePreference path is correct');
               assert.equal(msg.somePreference.title, 'some-title', 'somePreference title is correct');
               assert.equal(msg.somePreference.desc, 'Some short description for the preference', 'somePreference description is correct');
 
--- a/addon-sdk/source/test/tabs/test-firefox-tabs.js
+++ b/addon-sdk/source/test/tabs/test-firefox-tabs.js
@@ -829,28 +829,39 @@ exports.testAttachUnwrapped = function (
     });
 
   });
 }
 */
 
 exports['test window focus changes active tab'] = function(test) {
   test.waitUntilDone();
+
+  let url1 = "data:text/html;charset=utf-8," + encodeURIComponent("test window focus changes active tab</br><h1>Window #1");
+
   let win1 = openBrowserWindow(function() {
+    test.pass("window 1 is open");
+
     let win2 = openBrowserWindow(function() {
-      tabs.on("activate", function onActivate() {
+      test.pass("window 2 is open");
+
+      tabs.on("activate", function onActivate(tab) {
         tabs.removeListener("activate", onActivate);
         test.pass("activate was called on windows focus change.");
-        closeBrowserWindow(win1, function() {
-          closeBrowserWindow(win2, function() { test.done(); });
-        });
+        test.assertEqual(tab.url, url1, 'the activated tab url is correct');
+
+        close(win2).then(function() {
+          test.pass('window 2 was closed');
+          return close(win1);
+        }).then(test.done.bind(test));
       });
+
       win1.focus();
     }, "data:text/html;charset=utf-8,test window focus changes active tab</br><h1>Window #2");
-  }, "data:text/html;charset=utf-8,test window focus changes active tab</br><h1>Window #1");
+  }, url1);
 };
 
 exports['test ready event on new window tab'] = function(test) {
   test.waitUntilDone();
   let uri = encodeURI("data:text/html;charset=utf-8,Waiting for ready event!");
 
   require("sdk/tabs").on("ready", function onReady(tab) {
     if (tab.url === uri) {
--- a/addon-sdk/source/test/test-panel.js
+++ b/addon-sdk/source/test/test-panel.js
@@ -124,36 +124,39 @@ exports["test Show Hide Panel"] = functi
       done();
     }
   });
 };
 
 exports["test Document Reload"] = function(assert, done) {
   const { Panel } = require('sdk/panel');
 
+  let url2 = "data:text/html;charset=utf-8,page2";
   let content =
     "<script>" +
     "window.onload = function() {" +
     "  setTimeout(function () {" +
-    "    window.location = 'about:blank';" +
+    "    window.location = '" + url2 + "';" +
     "  }, 0);" +
     "}" +
     "</script>";
   let messageCount = 0;
   let panel = Panel({
     // using URL here is intentional, see bug 859009
     contentURL: URL("data:text/html;charset=utf-8," + encodeURIComponent(content)),
     contentScript: "self.postMessage(window.location.href)",
     onMessage: function (message) {
       messageCount++;
+      assert.notEqual(message, 'about:blank', 'about:blank is not a message ' + messageCount);
+
       if (messageCount == 1) {
         assert.ok(/data:text\/html/.test(message), "First document had a content script " + message);
       }
       else if (messageCount == 2) {
-        assert.equal(message, "about:blank", "Second document too");
+        assert.equal(message, url2, "Second document too");
         panel.destroy();
         done();
       }
     }
   });
   assert.pass('Panel was created');
 };
 
--- a/browser/base/content/highlighter.css
+++ b/browser/base/content/highlighter.css
@@ -2,19 +2,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/. */
  
 .highlighter-container {
   pointer-events: none;
 }
 
 .highlighter-controls {
-  position: absolute;
-  top: 0;
-  left: 0;
+  position: relative;
 }
 
 .highlighter-outline-container {
   overflow: hidden;
   position: relative;
 }
 
 .highlighter-outline {
--- a/mobile/android/base/GeckoProfile.java
+++ b/mobile/android/base/GeckoProfile.java
@@ -158,17 +158,17 @@ public final class GeckoProfile {
         GeckoProfile profile = getGuestProfile(context);
         if (profile != null) {
             profile.unlock();
         }
     }
 
     private static File getGuestDir(Context context) {
         if (mGuestDir == null) {
-            mGuestDir = context.getDir("guest", Context.MODE_PRIVATE);
+            mGuestDir = context.getFileStreamPath("guest");
         }
         return mGuestDir;
     }
 
     private static GeckoProfile getGuestProfile(Context context) {
         if (mGuestProfile == null) {
             File guestDir = getGuestDir(context);
             mGuestProfile = get(context, "guest", guestDir);
@@ -176,18 +176,22 @@ public final class GeckoProfile {
         }
 
         return mGuestProfile;
     }
 
     public static boolean maybeCleanupGuestProfile(final Context context) {
         // Don't use profile.getDir() here, so that we don't accidently create the dir
         File guestDir = getGuestDir(context);
+        if (!guestDir.exists()) {
+            return false;
+        }
+
         final GeckoProfile profile = getGuestProfile(context);
-        if (guestDir.exists() && !profile.locked()) {
+        if (!profile.locked()) {
             // if the guest dir exists, but its unlocked, delete it
             ThreadUtils.postToBackgroundThread(new Runnable() {
                 @Override
                 public void run() {
                     removeGuestProfile(context);
                 }
             });
             return true;
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-10.js
@@ -0,0 +1,74 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Check that we source map frame locations for the frame we are paused at.
+ */
+
+var gDebuggee;
+var gClient;
+var gThreadClient;
+
+const promise = devtools.require("sdk/core/promise");
+Components.utils.import('resource:///modules/devtools/SourceMap.jsm');
+
+function run_test() {
+  initTestDebuggerServer();
+  gDebuggee = addTestGlobal("test-source-map");
+  gClient = new DebuggerClient(DebuggerServer.connectPipe());
+  gClient.connect(function() {
+    attachTestTabAndResume(gClient, "test-source-map", function(aResponse, aTabClient, aThreadClient) {
+      gThreadClient = aThreadClient;
+      promise.resolve(define_code())
+        .then(run_code)
+        .then(test_frame_location)
+        .then(null, error => {
+          dump(error + "\n");
+          dump(error.stack);
+          do_check_true(false);
+        })
+        .then(() => {
+          finishClient(gClient);
+        });
+    });
+  });
+  do_test_pending();
+}
+
+function define_code() {
+  let { code, map } = (new SourceNode(null, null, null, [
+    new SourceNode(1, 0, "a.js", "function a() {\n"),
+    new SourceNode(2, 0, "a.js", "  b();\n"),
+    new SourceNode(3, 0, "a.js", "}\n"),
+    new SourceNode(1, 0, "b.js", "function b() {\n"),
+    new SourceNode(2, 0, "b.js", "  c();\n"),
+    new SourceNode(3, 0, "b.js", "}\n"),
+    new SourceNode(1, 0, "c.js", "function c() {\n"),
+    new SourceNode(2, 0, "c.js", "  debugger;\n"),
+    new SourceNode(3, 0, "c.js", "}\n"),
+  ])).toStringWithSourceMap({
+    file: "abc.js",
+    sourceRoot: "http://example.com/www/js/"
+  });
+
+  code += "//# sourceMappingURL=data:text/json," + map.toString();
+
+  Components.utils.evalInSandbox(code, gDebuggee, "1.8",
+                                 "http://example.com/www/js/abc.js", 1);
+}
+
+function run_code() {
+  const d = promise.defer();
+  gClient.addOneTimeListener("paused", function (aEvent, aPacket) {
+    d.resolve(aPacket);
+    gThreadClient.resume();
+  });
+  gDebuggee.a();
+  return d.promise;
+}
+
+function test_frame_location({ frame: { where: { url, line, column } } }) {
+  do_check_eq(url, "http://example.com/www/js/c.js");
+  do_check_eq(line, 2);
+  do_check_eq(column, 0);
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/unit/test_sourcemaps-11.js
@@ -0,0 +1,84 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Check that we source map frame locations returned by "frames" requests.
+ */
+
+var gDebuggee;
+var gClient;
+var gThreadClient;
+
+const promise = devtools.require("sdk/core/promise");
+Components.utils.import('resource:///modules/devtools/SourceMap.jsm');
+
+function run_test() {
+  initTestDebuggerServer();
+  gDebuggee = addTestGlobal("test-source-map");
+  gClient = new DebuggerClient(DebuggerServer.connectPipe());
+  gClient.connect(function() {
+    attachTestTabAndResume(gClient, "test-source-map", function(aResponse, aTabClient, aThreadClient) {
+      gThreadClient = aThreadClient;
+      promise.resolve(define_code())
+        .then(run_code)
+        .then(test_frames)
+        .then(null, error => {
+          dump(error + "\n");
+          dump(error.stack);
+          do_check_true(false);
+        })
+        .then(() => {
+          finishClient(gClient);
+        });
+    });
+  });
+  do_test_pending();
+}
+
+function define_code() {
+  let { code, map } = (new SourceNode(null, null, null, [
+    new SourceNode(1, 0, "a.js", "function a() {\n"),
+    new SourceNode(2, 0, "a.js", "  b();\n"),
+    new SourceNode(3, 0, "a.js", "}\n"),
+    new SourceNode(1, 0, "b.js", "function b() {\n"),
+    new SourceNode(2, 0, "b.js", "  c();\n"),
+    new SourceNode(3, 0, "b.js", "}\n"),
+    new SourceNode(1, 0, "c.js", "function c() {\n"),
+    new SourceNode(2, 0, "c.js", "  debugger;\n"),
+    new SourceNode(3, 0, "c.js", "}\n"),
+  ])).toStringWithSourceMap({
+    file: "abc.js",
+    sourceRoot: "http://example.com/www/js/"
+  });
+
+  code += "//# sourceMappingURL=data:text/json," + map.toString();
+
+  Components.utils.evalInSandbox(code, gDebuggee, "1.8",
+                                 "http://example.com/www/js/abc.js", 1);
+}
+
+function run_code() {
+  const d = promise.defer();
+  gClient.addOneTimeListener("paused", function () {
+    gThreadClient.getFrames(0, 3, function (aResponse) {
+      d.resolve(aResponse);
+      gThreadClient.resume();
+    })
+  });
+  gDebuggee.a();
+  return d.promise;
+}
+
+function test_frames({ error, frames }) {
+  do_check_true(!error);
+  do_check_eq(frames.length, 3);
+  check_frame(frames[0], "http://example.com/www/js/c.js");
+  check_frame(frames[1], "http://example.com/www/js/b.js");
+  check_frame(frames[2], "http://example.com/www/js/a.js");
+}
+
+function check_frame({ where: { url, line, column } }, aExpectedUrl) {
+  do_check_eq(url, aExpectedUrl);
+  do_check_eq(line, 2);
+  do_check_eq(column, 0);
+}
--- a/toolkit/devtools/server/tests/unit/xpcshell.ini
+++ b/toolkit/devtools/server/tests/unit/xpcshell.ini
@@ -108,16 +108,18 @@ reason = bug 820380
 skip-if = toolkit == "gonk"
 reason = bug 820380
 [test_sourcemaps-06.js]
 [test_sourcemaps-07.js]
 skip-if = toolkit == "gonk"
 reason = bug 820380
 [test_sourcemaps-08.js]
 [test_sourcemaps-09.js]
+[test_sourcemaps-10.js]
+[test_sourcemaps-11.js]
 [test_objectgrips-01.js]
 [test_objectgrips-02.js]
 [test_objectgrips-03.js]
 [test_objectgrips-04.js]
 [test_objectgrips-05.js]
 [test_objectgrips-06.js]
 [test_objectgrips-07.js]
 [test_objectgrips-08.js]