зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound.
This commit is contained in:
Коммит
9339de4f3f
|
@ -141,6 +141,9 @@ exports.testTabPropertiesInNewWindow = function(test) {
|
||||||
exports.testTabPropertiesInSameWindow = function(test) {
|
exports.testTabPropertiesInSameWindow = function(test) {
|
||||||
test.waitUntilDone();
|
test.waitUntilDone();
|
||||||
|
|
||||||
|
// Get current count of tabs so we know the index of the
|
||||||
|
// new tab, bug 893846
|
||||||
|
let tabCount = tabs.length;
|
||||||
let count = 0;
|
let count = 0;
|
||||||
function onReadyOrLoad (tab) {
|
function onReadyOrLoad (tab) {
|
||||||
if (count++) {
|
if (count++) {
|
||||||
|
@ -156,7 +159,7 @@ exports.testTabPropertiesInSameWindow = function(test) {
|
||||||
test.assertEqual(tab.url, url, "URL of the new tab matches");
|
test.assertEqual(tab.url, url, "URL of the new tab matches");
|
||||||
test.assert(tab.favicon, "favicon of the new tab is not empty");
|
test.assert(tab.favicon, "favicon of the new tab is not empty");
|
||||||
test.assertEqual(tab.style, null, "style of the new tab matches");
|
test.assertEqual(tab.style, null, "style of the new tab matches");
|
||||||
test.assertEqual(tab.index, 1, "index of the new tab matches");
|
test.assertEqual(tab.index, tabCount, "index of the new tab matches");
|
||||||
test.assertNotEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
|
test.assertNotEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
|
||||||
test.assertNotEqual(tab.id, null, "a tab object always has an id property.");
|
test.assertNotEqual(tab.id, null, "a tab object always has an id property.");
|
||||||
|
|
||||||
|
@ -167,7 +170,7 @@ exports.testTabPropertiesInSameWindow = function(test) {
|
||||||
test.assertEqual(tab.url, url, "URL of the new tab matches");
|
test.assertEqual(tab.url, url, "URL of the new tab matches");
|
||||||
test.assert(tab.favicon, "favicon of the new tab is not empty");
|
test.assert(tab.favicon, "favicon of the new tab is not empty");
|
||||||
test.assertEqual(tab.style, null, "style of the new tab matches");
|
test.assertEqual(tab.style, null, "style of the new tab matches");
|
||||||
test.assertEqual(tab.index, 1, "index of the new tab matches");
|
test.assertEqual(tab.index, tabCount, "index of the new tab matches");
|
||||||
test.assertNotEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
|
test.assertNotEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
|
||||||
test.assertNotEqual(tab.id, null, "a tab object always has an id property.");
|
test.assertNotEqual(tab.id, null, "a tab object always has an id property.");
|
||||||
|
|
||||||
|
|
|
@ -3144,9 +3144,7 @@ exports.testSelectionInOuterFrameNoMatch = function (test) {
|
||||||
// WARNING: This looks up items in popups by comparing labels, so don't give two
|
// WARNING: This looks up items in popups by comparing labels, so don't give two
|
||||||
// items the same label.
|
// items the same label.
|
||||||
function TestHelper(test) {
|
function TestHelper(test) {
|
||||||
// default waitUntilDone timeout is 10s, which is too short on the win7
|
test.waitUntilDone();
|
||||||
// buildslave
|
|
||||||
test.waitUntilDone(30*1000);
|
|
||||||
this.test = test;
|
this.test = test;
|
||||||
this.loaders = [];
|
this.loaders = [];
|
||||||
this.browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
|
this.browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||||
|
|
|
@ -624,9 +624,6 @@ pref("network.protocol-handler.expose.news", false);
|
||||||
pref("network.protocol-handler.expose.snews", false);
|
pref("network.protocol-handler.expose.snews", false);
|
||||||
pref("network.protocol-handler.expose.nntp", false);
|
pref("network.protocol-handler.expose.nntp", false);
|
||||||
|
|
||||||
// Warning for about:networking page
|
|
||||||
pref("network.warnOnAboutNetworking", true);
|
|
||||||
|
|
||||||
pref("accessibility.typeaheadfind", false);
|
pref("accessibility.typeaheadfind", false);
|
||||||
pref("accessibility.typeaheadfind.timeout", 5000);
|
pref("accessibility.typeaheadfind.timeout", 5000);
|
||||||
pref("accessibility.typeaheadfind.linksonly", false);
|
pref("accessibility.typeaheadfind.linksonly", false);
|
||||||
|
|
|
@ -42,16 +42,9 @@ SocialUI = {
|
||||||
|
|
||||||
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
|
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
|
||||||
|
|
||||||
SocialChatBar.init();
|
|
||||||
SocialMark.init();
|
|
||||||
SocialShare.init();
|
|
||||||
SocialMenu.init();
|
|
||||||
SocialToolbar.init();
|
|
||||||
SocialSidebar.init();
|
|
||||||
|
|
||||||
if (!Social.initialized) {
|
if (!Social.initialized) {
|
||||||
Social.init();
|
Social.init();
|
||||||
} else {
|
} else if (Social.enabled) {
|
||||||
// social was previously initialized, so it's not going to notify us of
|
// social was previously initialized, so it's not going to notify us of
|
||||||
// anything, so handle that now.
|
// anything, so handle that now.
|
||||||
this.observe(null, "social:providers-changed", null);
|
this.observe(null, "social:providers-changed", null);
|
||||||
|
@ -346,8 +339,6 @@ SocialUI = {
|
||||||
}
|
}
|
||||||
|
|
||||||
SocialChatBar = {
|
SocialChatBar = {
|
||||||
init: function() {
|
|
||||||
},
|
|
||||||
closeWindows: function() {
|
closeWindows: function() {
|
||||||
// close all windows of type Social:Chat
|
// close all windows of type Social:Chat
|
||||||
let windows = Services.wm.getEnumerator("Social:Chat");
|
let windows = Services.wm.getEnumerator("Social:Chat");
|
||||||
|
@ -586,9 +577,6 @@ SocialFlyout = {
|
||||||
}
|
}
|
||||||
|
|
||||||
SocialShare = {
|
SocialShare = {
|
||||||
// Called once, after window load, when the Social.provider object is initialized
|
|
||||||
init: function() {},
|
|
||||||
|
|
||||||
get panel() {
|
get panel() {
|
||||||
return document.getElementById("social-share-panel");
|
return document.getElementById("social-share-panel");
|
||||||
},
|
},
|
||||||
|
@ -846,10 +834,6 @@ SocialShare = {
|
||||||
};
|
};
|
||||||
|
|
||||||
SocialMark = {
|
SocialMark = {
|
||||||
// Called once, after window load, when the Social.provider object is initialized
|
|
||||||
init: function SSB_init() {
|
|
||||||
},
|
|
||||||
|
|
||||||
get button() {
|
get button() {
|
||||||
return document.getElementById("social-mark-button");
|
return document.getElementById("social-mark-button");
|
||||||
},
|
},
|
||||||
|
@ -925,9 +909,6 @@ SocialMark = {
|
||||||
};
|
};
|
||||||
|
|
||||||
SocialMenu = {
|
SocialMenu = {
|
||||||
init: function SocialMenu_init() {
|
|
||||||
},
|
|
||||||
|
|
||||||
populate: function SocialMenu_populate() {
|
populate: function SocialMenu_populate() {
|
||||||
let submenu = document.getElementById("menu_social-statusarea-popup");
|
let submenu = document.getElementById("menu_social-statusarea-popup");
|
||||||
let ambientMenuItems = submenu.getElementsByClassName("ambient-menuitem");
|
let ambientMenuItems = submenu.getElementsByClassName("ambient-menuitem");
|
||||||
|
@ -961,8 +942,10 @@ SocialMenu = {
|
||||||
SocialToolbar = {
|
SocialToolbar = {
|
||||||
// Called once, after window load, when the Social.provider object is
|
// Called once, after window load, when the Social.provider object is
|
||||||
// initialized.
|
// initialized.
|
||||||
init: function SocialToolbar_init() {
|
get _dynamicResizer() {
|
||||||
|
delete this._dynamicResizer;
|
||||||
this._dynamicResizer = new DynamicResizeWatcher();
|
this._dynamicResizer = new DynamicResizeWatcher();
|
||||||
|
return this._dynamicResizer;
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function() {
|
update: function() {
|
||||||
|
@ -1299,14 +1282,6 @@ SocialToolbar = {
|
||||||
}
|
}
|
||||||
|
|
||||||
SocialSidebar = {
|
SocialSidebar = {
|
||||||
// Called once, after window load, when the Social.provider object is initialized
|
|
||||||
init: function SocialSidebar_init() {
|
|
||||||
let sbrowser = document.getElementById("social-sidebar-browser");
|
|
||||||
Social.setErrorListener(sbrowser, this.setSidebarErrorMessage.bind(this));
|
|
||||||
// setting isAppTab causes clicks on untargeted links to open new tabs
|
|
||||||
sbrowser.docShell.isAppTab = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Whether the sidebar can be shown for this window.
|
// Whether the sidebar can be shown for this window.
|
||||||
get canShow() {
|
get canShow() {
|
||||||
return SocialUI.enabled && Social.provider.sidebarURL;
|
return SocialUI.enabled && Social.provider.sidebarURL;
|
||||||
|
@ -1367,6 +1342,9 @@ SocialSidebar = {
|
||||||
|
|
||||||
// Make sure the right sidebar URL is loaded
|
// Make sure the right sidebar URL is loaded
|
||||||
if (sbrowser.getAttribute("src") != Social.provider.sidebarURL) {
|
if (sbrowser.getAttribute("src") != Social.provider.sidebarURL) {
|
||||||
|
Social.setErrorListener(sbrowser, this.setSidebarErrorMessage.bind(this));
|
||||||
|
// setting isAppTab causes clicks on untargeted links to open new tabs
|
||||||
|
sbrowser.docShell.isAppTab = true;
|
||||||
sbrowser.setAttribute("src", Social.provider.sidebarURL);
|
sbrowser.setAttribute("src", Social.provider.sidebarURL);
|
||||||
PopupNotifications.locationChange(sbrowser);
|
PopupNotifications.locationChange(sbrowser);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,10 @@ function testSimpleCall() {
|
||||||
let localVar3 = localScope.addItem("localVar3");
|
let localVar3 = localScope.addItem("localVar3");
|
||||||
let localVar4 = localScope.addItem("localVar4");
|
let localVar4 = localScope.addItem("localVar4");
|
||||||
let localVar5 = localScope.addItem("localVar5");
|
let localVar5 = localScope.addItem("localVar5");
|
||||||
|
let localVar6 = localScope.addItem("localVar6");
|
||||||
|
let localVar7 = localScope.addItem("localVar7");
|
||||||
|
let localVar8 = localScope.addItem("localVar8");
|
||||||
|
let localVar9 = localScope.addItem("localVar9");
|
||||||
|
|
||||||
localVar0.setGrip(42);
|
localVar0.setGrip(42);
|
||||||
localVar1.setGrip(true);
|
localVar1.setGrip(true);
|
||||||
|
@ -43,6 +47,10 @@ function testSimpleCall() {
|
||||||
localVar3.setGrip({ "type": "undefined" });
|
localVar3.setGrip({ "type": "undefined" });
|
||||||
localVar4.setGrip({ "type": "null" });
|
localVar4.setGrip({ "type": "null" });
|
||||||
localVar5.setGrip({ "type": "object", "class": "Object" });
|
localVar5.setGrip({ "type": "object", "class": "Object" });
|
||||||
|
localVar6.setGrip({ "type": "Infinity" });
|
||||||
|
localVar7.setGrip({ "type": "-Infinity" });
|
||||||
|
localVar8.setGrip({ "type": "NaN" });
|
||||||
|
localVar9.setGrip({ "type": "-0" });
|
||||||
|
|
||||||
localVar5.addItems({
|
localVar5.addItems({
|
||||||
"someProp0": { "value": 42, "enumerable": true },
|
"someProp0": { "value": 42, "enumerable": true },
|
||||||
|
@ -54,15 +62,16 @@ function testSimpleCall() {
|
||||||
"value": { "type": "object", "class": "Object" },
|
"value": { "type": "object", "class": "Object" },
|
||||||
"enumerable": true
|
"enumerable": true
|
||||||
},
|
},
|
||||||
"someUndefined": {
|
"someProp6": { "value": { "type": "Infinity" }, "enumerable": true },
|
||||||
"value": { "type": "undefined" },
|
"someProp7": { "value": { "type": "-Infinity" }, "enumerable": true },
|
||||||
"enumerable": true
|
"someProp8": { "value": { "type": "NaN" }, "enumerable": true },
|
||||||
},
|
"someProp9": { "value": { "type": "undefined" }, "enumerable": true },
|
||||||
"someAccessor": {
|
"someProp10": { "value": { "type": "-0" }, "enumerable": true },
|
||||||
|
"someProp11": {
|
||||||
"get": { "type": "object", "class": "Function" },
|
"get": { "type": "object", "class": "Function" },
|
||||||
"set": { "type": "undefined" },
|
"set": { "type": "undefined" },
|
||||||
"enumerable": true
|
"enumerable": true
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
localVar5.get("someProp5").addItems({
|
localVar5.get("someProp5").addItems({
|
||||||
|
@ -75,15 +84,16 @@ function testSimpleCall() {
|
||||||
"value": { "type": "object", "class": "Object" },
|
"value": { "type": "object", "class": "Object" },
|
||||||
"enumerable": true
|
"enumerable": true
|
||||||
},
|
},
|
||||||
"someUndefined": {
|
"someProp6": { "value": { "type": "Infinity" }, "enumerable": true },
|
||||||
"value": { "type": "undefined" },
|
"someProp7": { "value": { "type": "-Infinity" }, "enumerable": true },
|
||||||
"enumerable": true
|
"someProp8": { "value": { "type": "NaN" }, "enumerable": true },
|
||||||
},
|
"someProp9": { "value": { "type": "undefined" }, "enumerable": true },
|
||||||
"someAccessor": {
|
"someProp10": { "value": { "type": "-0" }, "enumerable": true },
|
||||||
|
"someProp11": {
|
||||||
"get": { "type": "object", "class": "Function" },
|
"get": { "type": "object", "class": "Function" },
|
||||||
"set": { "type": "undefined" },
|
"set": { "type": "undefined" },
|
||||||
"enumerable": true
|
"enumerable": true
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
windowVar.setGrip({ "type": "object", "class": "Window" });
|
windowVar.setGrip({ "type": "object", "class": "Window" });
|
||||||
|
@ -110,6 +120,10 @@ function testSimpleCall() {
|
||||||
ok(localVar3, "The localVar3 hasn't been created correctly.");
|
ok(localVar3, "The localVar3 hasn't been created correctly.");
|
||||||
ok(localVar4, "The localVar4 hasn't been created correctly.");
|
ok(localVar4, "The localVar4 hasn't been created correctly.");
|
||||||
ok(localVar5, "The localVar5 hasn't been created correctly.");
|
ok(localVar5, "The localVar5 hasn't been created correctly.");
|
||||||
|
ok(localVar6, "The localVar6 hasn't been created correctly.");
|
||||||
|
ok(localVar7, "The localVar7 hasn't been created correctly.");
|
||||||
|
ok(localVar8, "The localVar8 hasn't been created correctly.");
|
||||||
|
ok(localVar9, "The localVar8 hasn't been created correctly.");
|
||||||
|
|
||||||
for each (let elt in globalScope.target.querySelector(".nonenum").childNodes) {
|
for each (let elt in globalScope.target.querySelector(".nonenum").childNodes) {
|
||||||
info("globalScope :: " + { id: elt.id, className: elt.className }.toSource());
|
info("globalScope :: " + { id: elt.id, className: elt.className }.toSource());
|
||||||
|
@ -120,12 +134,12 @@ function testSimpleCall() {
|
||||||
for each (let elt in localScope.target.querySelector(".nonenum").childNodes) {
|
for each (let elt in localScope.target.querySelector(".nonenum").childNodes) {
|
||||||
info("localScope :: " + { id: elt.id, className: elt.className }.toSource());
|
info("localScope :: " + { id: elt.id, className: elt.className }.toSource());
|
||||||
}
|
}
|
||||||
is(localScope.target.querySelector(".nonenum").childNodes.length, 6,
|
is(localScope.target.querySelector(".nonenum").childNodes.length, 10,
|
||||||
"The localScope doesn't contain all the created variable elements.");
|
"The localScope doesn't contain all the created variable elements.");
|
||||||
|
|
||||||
is(localVar5.target.querySelector(".variables-view-element-details").childNodes.length, 8,
|
is(localVar5.target.querySelector(".variables-view-element-details").childNodes.length, 12,
|
||||||
"The localVar5 doesn't contain all the created properties.");
|
"The localVar5 doesn't contain all the created properties.");
|
||||||
is(localVar5.get("someProp5").target.querySelector(".variables-view-element-details").childNodes.length, 8,
|
is(localVar5.get("someProp5").target.querySelector(".variables-view-element-details").childNodes.length, 12,
|
||||||
"The localVar5.someProp5 doesn't contain all the created properties.");
|
"The localVar5.someProp5 doesn't contain all the created properties.");
|
||||||
|
|
||||||
is(windowVar.target.querySelector(".value").getAttribute("value"), "Window",
|
is(windowVar.target.querySelector(".value").getAttribute("value"), "Window",
|
||||||
|
@ -145,40 +159,64 @@ function testSimpleCall() {
|
||||||
"The grip information for the localVar4 wasn't set correctly.");
|
"The grip information for the localVar4 wasn't set correctly.");
|
||||||
is(localVar5.target.querySelector(".value").getAttribute("value"), "Object",
|
is(localVar5.target.querySelector(".value").getAttribute("value"), "Object",
|
||||||
"The grip information for the localVar5 wasn't set correctly.");
|
"The grip information for the localVar5 wasn't set correctly.");
|
||||||
|
is(localVar6.target.querySelector(".value").getAttribute("value"), "Infinity",
|
||||||
|
"The grip information for the localVar6 wasn't set correctly.");
|
||||||
|
is(localVar7.target.querySelector(".value").getAttribute("value"), "-Infinity",
|
||||||
|
"The grip information for the localVar7 wasn't set correctly.");
|
||||||
|
is(localVar8.target.querySelector(".value").getAttribute("value"), "NaN",
|
||||||
|
"The grip information for the localVar8 wasn't set correctly.");
|
||||||
|
is(localVar9.target.querySelector(".value").getAttribute("value"), "-0",
|
||||||
|
"The grip information for the localVar9 wasn't set correctly.");
|
||||||
|
|
||||||
is(localVar5.get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
|
is(localVar5.get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
|
||||||
"The grip information for the localVar0 wasn't set correctly.");
|
"The grip information for the someProp0 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
|
is(localVar5.get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
|
||||||
"The grip information for the localVar1 wasn't set correctly.");
|
"The grip information for the someProp1 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
|
is(localVar5.get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
|
||||||
"The grip information for the localVar2 wasn't set correctly.");
|
"The grip information for the someProp2 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
|
is(localVar5.get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
|
||||||
"The grip information for the localVar3 wasn't set correctly.");
|
"The grip information for the someProp3 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
|
is(localVar5.get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
|
||||||
"The grip information for the localVar4 wasn't set correctly.");
|
"The grip information for the someProp4 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
|
is(localVar5.get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
|
||||||
"The grip information for the localVar5 wasn't set correctly.");
|
"The grip information for the someProp5 wasn't set correctly.");
|
||||||
is(localVar5.get("someUndefined").target.querySelector(".value").getAttribute("value"), "undefined",
|
is(localVar5.get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
|
||||||
"The grip information for the someUndefined wasn't set correctly.");
|
"The grip information for the someProp6 wasn't set correctly.");
|
||||||
is(localVar5.get("someAccessor").target.querySelector(".value").getAttribute("value"), "",
|
is(localVar5.get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
|
||||||
"The grip information for the someAccessor wasn't set correctly.");
|
"The grip information for the someProp7 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp8").target.querySelector(".value").getAttribute("value"), "NaN",
|
||||||
|
"The grip information for the someProp8 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp9").target.querySelector(".value").getAttribute("value"), "undefined",
|
||||||
|
"The grip information for the someProp9 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp10").target.querySelector(".value").getAttribute("value"), "-0",
|
||||||
|
"The grip information for the someProp10 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp11").target.querySelector(".value").getAttribute("value"), "",
|
||||||
|
"The grip information for the someProp11 wasn't set correctly.");
|
||||||
|
|
||||||
is(localVar5.get("someProp5").get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
|
is(localVar5.get("someProp5").get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
|
||||||
"The grip information for the sub-localVar0 wasn't set correctly.");
|
"The grip information for the sub-someProp0 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
|
is(localVar5.get("someProp5").get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
|
||||||
"The grip information for the sub-localVar1 wasn't set correctly.");
|
"The grip information for the sub-someProp1 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
|
is(localVar5.get("someProp5").get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
|
||||||
"The grip information for the sub-localVar2 wasn't set correctly.");
|
"The grip information for the sub-someProp2 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
|
is(localVar5.get("someProp5").get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
|
||||||
"The grip information for the sub-localVar3 wasn't set correctly.");
|
"The grip information for the sub-someProp3 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
|
is(localVar5.get("someProp5").get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
|
||||||
"The grip information for the sub-localVar4 wasn't set correctly.");
|
"The grip information for the sub-someProp4 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
|
is(localVar5.get("someProp5").get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
|
||||||
"The grip information for the sub-localVar5 wasn't set correctly.");
|
"The grip information for the sub-someProp5 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").get("someUndefined").target.querySelector(".value").getAttribute("value"), "undefined",
|
is(localVar5.get("someProp5").get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
|
||||||
"The grip information for the sub-someUndefined wasn't set correctly.");
|
"The grip information for the sub-someProp6 wasn't set correctly.");
|
||||||
is(localVar5.get("someProp5").get("someAccessor").target.querySelector(".value").getAttribute("value"), "",
|
is(localVar5.get("someProp5").get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
|
||||||
"The grip information for the sub-someAccessor wasn't set correctly.");
|
"The grip information for the sub-someProp7 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp5").get("someProp8").target.querySelector(".value").getAttribute("value"), "NaN",
|
||||||
|
"The grip information for the sub-someProp8 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp5").get("someProp9").target.querySelector(".value").getAttribute("value"), "undefined",
|
||||||
|
"The grip information for the sub-someProp9 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp5").get("someProp10").target.querySelector(".value").getAttribute("value"), "-0",
|
||||||
|
"The grip information for the sub-someProp10 wasn't set correctly.");
|
||||||
|
is(localVar5.get("someProp5").get("someProp11").target.querySelector(".value").getAttribute("value"), "",
|
||||||
|
"The grip information for the sub-someProp11 wasn't set correctly.");
|
||||||
|
|
||||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||||
closeDebuggerAndFinish();
|
closeDebuggerAndFinish();
|
||||||
|
|
|
@ -3005,9 +3005,16 @@ VariablesView.isPrimitive = function(aDescriptor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For convenience, undefined, null and long strings are considered types.
|
// For convenience, undefined, null, Infinity, -Infinity, NaN, -0, and long
|
||||||
|
// strings are considered types.
|
||||||
let type = grip.type;
|
let type = grip.type;
|
||||||
if (type == "undefined" || type == "null" || type == "longString") {
|
if (type == "undefined" ||
|
||||||
|
type == "null" ||
|
||||||
|
type == "Infinity" ||
|
||||||
|
type == "-Infinity" ||
|
||||||
|
type == "NaN" ||
|
||||||
|
type == "-0" ||
|
||||||
|
type == "longString") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3054,9 +3061,12 @@ VariablesView.isFalsy = function(aDescriptor) {
|
||||||
return !grip;
|
return !grip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For convenience, undefined and null are both considered types.
|
// For convenience, undefined, null, NaN, and -0 are all considered types.
|
||||||
let type = grip.type;
|
let type = grip.type;
|
||||||
if (type == "undefined" || type == "null") {
|
if (type == "undefined" ||
|
||||||
|
type == "null" ||
|
||||||
|
type == "NaN" ||
|
||||||
|
type == "-0") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3082,16 +3092,38 @@ VariablesView.isVariable = function(aValue) {
|
||||||
* The value's grip.
|
* The value's grip.
|
||||||
*/
|
*/
|
||||||
VariablesView.getGrip = function(aValue) {
|
VariablesView.getGrip = function(aValue) {
|
||||||
if (aValue === undefined) {
|
switch (typeof aValue) {
|
||||||
return { type: "undefined" };
|
case "boolean":
|
||||||
|
case "string":
|
||||||
|
return aValue;
|
||||||
|
case "number":
|
||||||
|
if (aValue === Infinity) {
|
||||||
|
return { type: "Infinity" };
|
||||||
|
} else if (aValue === -Infinity) {
|
||||||
|
return { type: "-Infinity" };
|
||||||
|
} else if (Number.isNaN(aValue)) {
|
||||||
|
return { type: "NaN" };
|
||||||
|
} else if (1 / aValue === -Infinity) {
|
||||||
|
return { type: "-0" };
|
||||||
|
}
|
||||||
|
return aValue;
|
||||||
|
case "undefined":
|
||||||
|
// document.all is also "undefined"
|
||||||
|
if (aValue === undefined) {
|
||||||
|
return { type: "undefined" };
|
||||||
|
}
|
||||||
|
case "object":
|
||||||
|
if (aValue === null) {
|
||||||
|
return { type: "null" };
|
||||||
|
}
|
||||||
|
case "function":
|
||||||
|
return { type: "object",
|
||||||
|
class: WebConsoleUtils.getObjectClassName(aValue) };
|
||||||
|
default:
|
||||||
|
Cu.reportError("Failed to provide a grip for value of " + typeof value +
|
||||||
|
": " + aValue);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
if (aValue === null) {
|
|
||||||
return { type: "null" };
|
|
||||||
}
|
|
||||||
if (typeof aValue == "object" || typeof aValue == "function") {
|
|
||||||
return { type: "object", class: WebConsoleUtils.getObjectClassName(aValue) };
|
|
||||||
}
|
|
||||||
return aValue;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3108,27 +3140,33 @@ VariablesView.getString = function(aGrip, aConciseFlag) {
|
||||||
if (aGrip && typeof aGrip == "object") {
|
if (aGrip && typeof aGrip == "object") {
|
||||||
switch (aGrip.type) {
|
switch (aGrip.type) {
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return "undefined";
|
|
||||||
case "null":
|
case "null":
|
||||||
return "null";
|
case "NaN":
|
||||||
|
case "Infinity":
|
||||||
|
case "-Infinity":
|
||||||
|
case "-0":
|
||||||
|
return aGrip.type;
|
||||||
case "longString":
|
case "longString":
|
||||||
return "\"" + aGrip.initial + "\"";
|
return "\"" + aGrip.initial + "\"";
|
||||||
default:
|
default:
|
||||||
if (!aConciseFlag) {
|
if (!aConciseFlag) {
|
||||||
return "[" + aGrip.type + " " + aGrip.class + "]";
|
return "[" + aGrip.type + " " + aGrip.class + "]";
|
||||||
} else {
|
|
||||||
return aGrip.class;
|
|
||||||
}
|
}
|
||||||
}
|
return aGrip.class;
|
||||||
} else {
|
|
||||||
switch (typeof aGrip) {
|
|
||||||
case "string":
|
|
||||||
return "\"" + aGrip + "\"";
|
|
||||||
case "boolean":
|
|
||||||
return aGrip ? "true" : "false";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return aGrip + "";
|
switch (typeof aGrip) {
|
||||||
|
case "string":
|
||||||
|
return "\"" + aGrip + "\"";
|
||||||
|
case "boolean":
|
||||||
|
return aGrip ? "true" : "false";
|
||||||
|
case "number":
|
||||||
|
if (!aGrip && 1 / aGrip === -Infinity) {
|
||||||
|
return "-0";
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return aGrip + "";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3146,20 +3184,25 @@ VariablesView.getClass = function(aGrip) {
|
||||||
return "token-undefined";
|
return "token-undefined";
|
||||||
case "null":
|
case "null":
|
||||||
return "token-null";
|
return "token-null";
|
||||||
|
case "Infinity":
|
||||||
|
case "-Infinity":
|
||||||
|
case "NaN":
|
||||||
|
case "-0":
|
||||||
|
return "token-number";
|
||||||
case "longString":
|
case "longString":
|
||||||
return "token-string";
|
return "token-string";
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
switch (typeof aGrip) {
|
|
||||||
case "string":
|
|
||||||
return "token-string";
|
|
||||||
case "boolean":
|
|
||||||
return "token-boolean";
|
|
||||||
case "number":
|
|
||||||
return "token-number";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return "token-other";
|
switch (typeof aGrip) {
|
||||||
|
case "string":
|
||||||
|
return "token-string";
|
||||||
|
case "boolean":
|
||||||
|
return "token-boolean";
|
||||||
|
case "number":
|
||||||
|
return "token-number";
|
||||||
|
default:
|
||||||
|
return "token-other";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,12 @@ pref("devtools.errorconsole.enabled", true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Automatically submit crash reports
|
// Automatically submit crash reports
|
||||||
|
#ifdef RELEASE_BUILD
|
||||||
pref("app.crashreporter.autosubmit", false);
|
pref("app.crashreporter.autosubmit", false);
|
||||||
|
#else
|
||||||
|
// For Nightly and Aurora we turn this on by default
|
||||||
|
pref("app.crashreporter.autosubmit", true);
|
||||||
|
#endif
|
||||||
// Has the user been prompted about crash reporting?
|
// Has the user been prompted about crash reporting?
|
||||||
pref("app.crashreporter.prompted", false);
|
pref("app.crashreporter.prompted", false);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "unescapeService",
|
||||||
function prefObserver(subject, topic, data) {
|
function prefObserver(subject, topic, data) {
|
||||||
let enable = Services.prefs.getBoolPref("social.enabled");
|
let enable = Services.prefs.getBoolPref("social.enabled");
|
||||||
if (enable && !Social.provider) {
|
if (enable && !Social.provider) {
|
||||||
Social.provider = Social.defaultProvider;
|
// this will result in setting Social.provider
|
||||||
|
SocialService.getOrderedProviderList(function(providers) {
|
||||||
|
Social._updateProviderCache(providers);
|
||||||
|
Social.enabled = true;
|
||||||
|
Services.obs.notifyObservers(null, "social:providers-changed", null);
|
||||||
|
});
|
||||||
} else if (!enable && Social.provider) {
|
} else if (!enable && Social.provider) {
|
||||||
Social.provider = null;
|
Social.provider = null;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +88,7 @@ function promiseGetAnnotation(aURI) {
|
||||||
this.Social = {
|
this.Social = {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
lastEventReceived: 0,
|
lastEventReceived: 0,
|
||||||
providers: null,
|
providers: [],
|
||||||
_disabledForSafeMode: false,
|
_disabledForSafeMode: false,
|
||||||
|
|
||||||
get _currentProviderPref() {
|
get _currentProviderPref() {
|
||||||
|
@ -151,10 +156,12 @@ this.Social = {
|
||||||
}
|
}
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
|
|
||||||
// Retrieve the current set of providers, and set the current provider.
|
if (SocialService.enabled) {
|
||||||
SocialService.getOrderedProviderList(function (providers) {
|
// Retrieve the current set of providers, and set the current provider.
|
||||||
this._updateProviderCache(providers);
|
SocialService.getOrderedProviderList(function (providers) {
|
||||||
}.bind(this));
|
this._updateProviderCache(providers);
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
// Register an observer for changes to the provider list
|
// Register an observer for changes to the provider list
|
||||||
SocialService.registerProviderListener(function providerListener(topic, data) {
|
SocialService.registerProviderListener(function providerListener(topic, data) {
|
||||||
|
@ -168,17 +175,13 @@ this.Social = {
|
||||||
// a provider has self-updated its manifest, we need to update our
|
// a provider has self-updated its manifest, we need to update our
|
||||||
// cache and possibly reload if it was the current provider.
|
// cache and possibly reload if it was the current provider.
|
||||||
let provider = data;
|
let provider = data;
|
||||||
SocialService.getOrderedProviderList(function(providers) {
|
// if we need a reload, do it now
|
||||||
Social._updateProviderCache(providers);
|
if (provider.enabled) {
|
||||||
Services.obs.notifyObservers(null, "social:providers-changed", null);
|
Social.enabled = false;
|
||||||
// if we need a reload, do it now
|
Services.tm.mainThread.dispatch(function() {
|
||||||
if (provider.enabled) {
|
Social.enabled = true;
|
||||||
Social.enabled = false;
|
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
|
||||||
Services.tm.mainThread.dispatch(function() {
|
}
|
||||||
Social.enabled = true;
|
|
||||||
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
|
@ -2118,36 +2118,7 @@ nsDOMWindowUtils::LeaveModalState()
|
||||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||||
NS_ENSURE_STATE(window);
|
NS_ENSURE_STATE(window);
|
||||||
|
|
||||||
window->LeaveModalState(nullptr);
|
window->LeaveModalState();
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsDOMWindowUtils::EnterModalStateWithWindow(nsIDOMWindow **aWindow)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerChrome()) {
|
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
|
||||||
NS_ENSURE_STATE(window);
|
|
||||||
|
|
||||||
*aWindow = window->EnterModalState();
|
|
||||||
NS_IF_ADDREF(*aWindow);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsDOMWindowUtils::LeaveModalStateWithWindow(nsIDOMWindow *aWindow)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerChrome()) {
|
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
|
||||||
NS_ENSURE_STATE(window);
|
|
||||||
|
|
||||||
window->LeaveModalState(aWindow);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,10 @@
|
||||||
#include "mozilla/dom/SpeechSynthesis.h"
|
#include "mozilla/dom/SpeechSynthesis.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_JSDEBUGGER
|
||||||
|
#include "jsdIDebuggerService.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Apple system headers seem to have a check() macro. <sigh>
|
// Apple system headers seem to have a check() macro. <sigh>
|
||||||
#ifdef check
|
#ifdef check
|
||||||
#undef check
|
#undef check
|
||||||
|
@ -5867,9 +5871,9 @@ nsGlobalWindow::Print()
|
||||||
printSettingsService->GetNewPrintSettings(getter_AddRefs(printSettings));
|
printSettingsService->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> callerWin = EnterModalState();
|
EnterModalState();
|
||||||
webBrowserPrint->Print(printSettings, nullptr);
|
webBrowserPrint->Print(printSettings, nullptr);
|
||||||
LeaveModalState(callerWin);
|
LeaveModalState();
|
||||||
|
|
||||||
bool savePrintSettings =
|
bool savePrintSettings =
|
||||||
Preferences::GetBool("print.save_print_settings", false);
|
Preferences::GetBool("print.save_print_settings", false);
|
||||||
|
@ -7257,7 +7261,7 @@ nsGlobalWindow::ReallyCloseWindow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDOMWindow *
|
void
|
||||||
nsGlobalWindow::EnterModalState()
|
nsGlobalWindow::EnterModalState()
|
||||||
{
|
{
|
||||||
// GetScriptableTop, not GetTop, so that EnterModalState works properly with
|
// GetScriptableTop, not GetTop, so that EnterModalState works properly with
|
||||||
|
@ -7266,8 +7270,7 @@ nsGlobalWindow::EnterModalState()
|
||||||
|
|
||||||
if (!topWin) {
|
if (!topWin) {
|
||||||
NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
|
NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
|
||||||
|
return;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is an active ESM in this window, clear it. Otherwise, this can
|
// If there is an active ESM in this window, clear it. Otherwise, this can
|
||||||
|
@ -7301,21 +7304,6 @@ nsGlobalWindow::EnterModalState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
topWin->mModalStateDepth++;
|
topWin->mModalStateDepth++;
|
||||||
|
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> callerWin;
|
|
||||||
nsIScriptContext *scx;
|
|
||||||
if (cx && (scx = GetScriptContextFromJSContext(cx))) {
|
|
||||||
scx->EnterModalState();
|
|
||||||
callerWin = do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mContext) {
|
|
||||||
mContext->EnterModalState();
|
|
||||||
}
|
|
||||||
|
|
||||||
return callerWin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -7389,7 +7377,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGlobalWindow::LeaveModalState(nsIDOMWindow *aCallerWin)
|
nsGlobalWindow::LeaveModalState()
|
||||||
{
|
{
|
||||||
nsGlobalWindow* topWin = GetScriptableTop();
|
nsGlobalWindow* topWin = GetScriptableTop();
|
||||||
|
|
||||||
|
@ -7412,19 +7400,6 @@ nsGlobalWindow::LeaveModalState(nsIDOMWindow *aCallerWin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aCallerWin) {
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(aCallerWin));
|
|
||||||
if (sgo) {
|
|
||||||
nsIScriptContext *scx = sgo->GetContext();
|
|
||||||
if (scx)
|
|
||||||
scx->LeaveModalState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mContext) {
|
|
||||||
mContext->LeaveModalState();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember the time of the last dialog quit.
|
// Remember the time of the last dialog quit.
|
||||||
nsGlobalWindow *inner = topWin->GetCurrentInnerWindowInternal();
|
nsGlobalWindow *inner = topWin->GetCurrentInnerWindowInternal();
|
||||||
if (inner)
|
if (inner)
|
||||||
|
@ -7812,7 +7787,7 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs_,
|
||||||
|
|
||||||
options.AppendLiteral(",scrollbars=1,centerscreen=1,resizable=0");
|
options.AppendLiteral(",scrollbars=1,centerscreen=1,resizable=0");
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> callerWin = EnterModalState();
|
EnterModalState();
|
||||||
uint32_t oldMicroTaskLevel = nsContentUtils::MicroTaskLevel();
|
uint32_t oldMicroTaskLevel = nsContentUtils::MicroTaskLevel();
|
||||||
nsContentUtils::SetMicroTaskLevel(0);
|
nsContentUtils::SetMicroTaskLevel(0);
|
||||||
nsresult rv = OpenInternal(aURI, EmptyString(), options,
|
nsresult rv = OpenInternal(aURI, EmptyString(), options,
|
||||||
|
@ -7826,7 +7801,7 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs_,
|
||||||
nullptr, // aJSCallerContext
|
nullptr, // aJSCallerContext
|
||||||
getter_AddRefs(dlgWin));
|
getter_AddRefs(dlgWin));
|
||||||
nsContentUtils::SetMicroTaskLevel(oldMicroTaskLevel);
|
nsContentUtils::SetMicroTaskLevel(oldMicroTaskLevel);
|
||||||
LeaveModalState(callerWin);
|
LeaveModalState();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMModalContentWindow> dialog = do_QueryInterface(dlgWin);
|
nsCOMPtr<nsIDOMModalContentWindow> dialog = do_QueryInterface(dlgWin);
|
||||||
|
@ -9374,6 +9349,167 @@ nsGlobalWindow::HandleIdleActiveEvent()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsGlobalWindow::SlowScriptResponse
|
||||||
|
nsGlobalWindow::ShowSlowScriptDialog()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(IsInnerWindow());
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
AutoJSContext cx;
|
||||||
|
|
||||||
|
// If it isn't safe to run script, then it isn't safe to bring up the prompt
|
||||||
|
// (since that spins the event loop). In that (rare) case, we just kill the
|
||||||
|
// script and report a warning.
|
||||||
|
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||||
|
JS_ReportWarning(cx, "A long running script was terminated");
|
||||||
|
return KillSlowScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the nsIPrompt interface from the docshell
|
||||||
|
nsCOMPtr<nsIDocShell> ds = GetDocShell();
|
||||||
|
NS_ENSURE_TRUE(ds, KillSlowScript);
|
||||||
|
nsCOMPtr<nsIPrompt> prompt = do_GetInterface(ds);
|
||||||
|
NS_ENSURE_TRUE(prompt, KillSlowScript);
|
||||||
|
|
||||||
|
// Check if we should offer the option to debug
|
||||||
|
JS::RootedScript script(cx);
|
||||||
|
unsigned lineno;
|
||||||
|
bool hasFrame = JS_DescribeScriptedCaller(cx, script.address(), &lineno);
|
||||||
|
|
||||||
|
bool debugPossible = hasFrame && js::CanCallContextDebugHandler(cx);
|
||||||
|
#ifdef MOZ_JSDEBUGGER
|
||||||
|
// Get the debugger service if necessary.
|
||||||
|
if (debugPossible) {
|
||||||
|
bool jsds_IsOn = false;
|
||||||
|
const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
|
||||||
|
nsCOMPtr<jsdIExecutionHook> jsdHook;
|
||||||
|
nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv);
|
||||||
|
|
||||||
|
// Check if there's a user for the debugger service that's 'on' for us
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
jsds->GetDebuggerHook(getter_AddRefs(jsdHook));
|
||||||
|
jsds->GetIsOn(&jsds_IsOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a debug handler registered for this runtime AND
|
||||||
|
// ((jsd is on AND has a hook) OR (jsd isn't on (something else debugs)))
|
||||||
|
// then something useful will be done with our request to debug.
|
||||||
|
debugPossible = ((jsds_IsOn && (jsdHook != nullptr)) || !jsds_IsOn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get localizable strings
|
||||||
|
nsXPIDLString title, msg, stopButton, waitButton, debugButton, neverShowDlg;
|
||||||
|
|
||||||
|
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"KillScriptTitle",
|
||||||
|
title);
|
||||||
|
|
||||||
|
nsresult tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"StopScriptButton",
|
||||||
|
stopButton);
|
||||||
|
if (NS_FAILED(tmp)) {
|
||||||
|
rv = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"WaitForScriptButton",
|
||||||
|
waitButton);
|
||||||
|
if (NS_FAILED(tmp)) {
|
||||||
|
rv = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"DontAskAgain",
|
||||||
|
neverShowDlg);
|
||||||
|
if (NS_FAILED(tmp)) {
|
||||||
|
rv = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debugPossible) {
|
||||||
|
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"DebugScriptButton",
|
||||||
|
debugButton);
|
||||||
|
if (NS_FAILED(tmp)) {
|
||||||
|
rv = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"KillScriptWithDebugMessage",
|
||||||
|
msg);
|
||||||
|
if (NS_FAILED(tmp)) {
|
||||||
|
rv = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"KillScriptMessage",
|
||||||
|
msg);
|
||||||
|
if (NS_FAILED(tmp)) {
|
||||||
|
rv = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStringFromName can return NS_OK and still give NULL string
|
||||||
|
if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton ||
|
||||||
|
(!debugButton && debugPossible) || !neverShowDlg) {
|
||||||
|
NS_ERROR("Failed to get localized strings.");
|
||||||
|
return ContinueSlowScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append file and line number information, if available
|
||||||
|
if (script) {
|
||||||
|
const char *filename = JS_GetScriptFilename(cx, script);
|
||||||
|
if (filename) {
|
||||||
|
nsXPIDLString scriptLocation;
|
||||||
|
NS_ConvertUTF8toUTF16 filenameUTF16(filename);
|
||||||
|
const PRUnichar *formatParams[] = { filenameUTF16.get() };
|
||||||
|
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
"KillScriptLocation",
|
||||||
|
formatParams,
|
||||||
|
scriptLocation);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) && scriptLocation) {
|
||||||
|
msg.AppendLiteral("\n\n");
|
||||||
|
msg.Append(scriptLocation);
|
||||||
|
msg.Append(':');
|
||||||
|
msg.AppendInt(lineno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t buttonPressed = 0; // In case the user exits dialog by clicking X.
|
||||||
|
bool neverShowDlgChk = false;
|
||||||
|
uint32_t buttonFlags = nsIPrompt::BUTTON_POS_1_DEFAULT +
|
||||||
|
(nsIPrompt::BUTTON_TITLE_IS_STRING *
|
||||||
|
(nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
|
||||||
|
|
||||||
|
// Add a third button if necessary.
|
||||||
|
if (debugPossible)
|
||||||
|
buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
|
||||||
|
|
||||||
|
// Null out the operation callback while we're re-entering JS here.
|
||||||
|
JSRuntime* rt = JS_GetRuntime(cx);
|
||||||
|
JSOperationCallback old = JS_SetOperationCallback(rt, nullptr);
|
||||||
|
|
||||||
|
// Open the dialog.
|
||||||
|
rv = prompt->ConfirmEx(title, msg, buttonFlags, waitButton, stopButton,
|
||||||
|
debugButton, neverShowDlg, &neverShowDlgChk,
|
||||||
|
&buttonPressed);
|
||||||
|
|
||||||
|
JS_SetOperationCallback(rt, old);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
|
||||||
|
return neverShowDlgChk ? AlwaysContinueSlowScript : ContinueSlowScript;
|
||||||
|
}
|
||||||
|
if ((buttonPressed == 2) && debugPossible) {
|
||||||
|
return js_CallContextDebugHandler(cx) ? ContinueSlowScript : KillSlowScript;
|
||||||
|
}
|
||||||
|
JS_ClearPendingException(cx);
|
||||||
|
return KillSlowScript;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
nsGlobalWindow::FindInsertionIndex(IdleObserverHolder* aIdleObserver)
|
nsGlobalWindow::FindInsertionIndex(IdleObserverHolder* aIdleObserver)
|
||||||
{
|
{
|
||||||
|
|
|
@ -446,8 +446,8 @@ public:
|
||||||
// Outer windows only.
|
// Outer windows only.
|
||||||
virtual NS_HIDDEN_(void) EnsureSizeUpToDate();
|
virtual NS_HIDDEN_(void) EnsureSizeUpToDate();
|
||||||
|
|
||||||
virtual NS_HIDDEN_(nsIDOMWindow*) EnterModalState();
|
virtual NS_HIDDEN_(void) EnterModalState();
|
||||||
virtual NS_HIDDEN_(void) LeaveModalState(nsIDOMWindow* aWindow);
|
virtual NS_HIDDEN_(void) LeaveModalState();
|
||||||
|
|
||||||
virtual NS_HIDDEN_(bool) CanClose();
|
virtual NS_HIDDEN_(bool) CanClose();
|
||||||
virtual NS_HIDDEN_(nsresult) ForceClose();
|
virtual NS_HIDDEN_(nsresult) ForceClose();
|
||||||
|
@ -692,6 +692,13 @@ public:
|
||||||
mAllowScriptsToClose = true;
|
mAllowScriptsToClose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SlowScriptResponse {
|
||||||
|
ContinueSlowScript = 0,
|
||||||
|
AlwaysContinueSlowScript,
|
||||||
|
KillSlowScript
|
||||||
|
};
|
||||||
|
SlowScriptResponse ShowSlowScriptDialog();
|
||||||
|
|
||||||
#ifdef MOZ_GAMEPAD
|
#ifdef MOZ_GAMEPAD
|
||||||
void AddGamepad(uint32_t aIndex, mozilla::dom::Gamepad* aGamepad);
|
void AddGamepad(uint32_t aIndex, mozilla::dom::Gamepad* aGamepad);
|
||||||
void RemoveGamepad(uint32_t aIndex);
|
void RemoveGamepad(uint32_t aIndex);
|
||||||
|
|
|
@ -28,8 +28,8 @@ class nsIDOMWindow;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
|
|
||||||
#define NS_ISCRIPTCONTEXT_IID \
|
#define NS_ISCRIPTCONTEXT_IID \
|
||||||
{ 0x9173717f, 0x0722, 0x44bc, \
|
{ 0xfd05ba99, 0x2906, 0x4c51, \
|
||||||
{ 0x99, 0x6c, 0x69, 0xa9, 0xf9, 0x6d, 0x73, 0xac } }
|
{ 0x89, 0xb3, 0xbc, 0xdf, 0xf6, 0x3b, 0xf2, 0xde } }
|
||||||
|
|
||||||
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
|
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
|
||||||
know what language we have is a little silly... */
|
know what language we have is a little silly... */
|
||||||
|
@ -185,9 +185,6 @@ public:
|
||||||
* Tell the context we're done reinitializing it.
|
* Tell the context we're done reinitializing it.
|
||||||
*/
|
*/
|
||||||
virtual void DidInitializeContext() = 0;
|
virtual void DidInitializeContext() = 0;
|
||||||
|
|
||||||
virtual void EnterModalState() = 0;
|
|
||||||
virtual void LeaveModalState() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)
|
||||||
|
|
|
@ -195,9 +195,6 @@ static bool sDidShutdown;
|
||||||
static bool sShuttingDown;
|
static bool sShuttingDown;
|
||||||
static int32_t sContextCount;
|
static int32_t sContextCount;
|
||||||
|
|
||||||
static PRTime sMaxScriptRunTime;
|
|
||||||
static PRTime sMaxChromeScriptRunTime;
|
|
||||||
|
|
||||||
static nsIScriptSecurityManager *sSecurityManager;
|
static nsIScriptSecurityManager *sSecurityManager;
|
||||||
|
|
||||||
// nsJSEnvironmentObserver observes the memory-pressure notifications
|
// nsJSEnvironmentObserver observes the memory-pressure notifications
|
||||||
|
@ -679,278 +676,6 @@ DumpString(const nsAString &str)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static already_AddRefed<nsIPrompt>
|
|
||||||
GetPromptFromContext(nsJSContext* ctx)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(ctx->GetGlobalObject()));
|
|
||||||
NS_ENSURE_TRUE(win, nullptr);
|
|
||||||
|
|
||||||
nsIDocShell *docShell = win->GetDocShell();
|
|
||||||
NS_ENSURE_TRUE(docShell, nullptr);
|
|
||||||
|
|
||||||
// Get the nsIPrompt interface from the docshell
|
|
||||||
nsCOMPtr<nsIPrompt> prompt = do_GetInterface(docShell);
|
|
||||||
return prompt.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
nsJSContext::DOMOperationCallback(JSContext *cx)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
// Get the native context
|
|
||||||
nsJSContext *ctx = static_cast<nsJSContext *>(::JS_GetContextPrivate(cx));
|
|
||||||
|
|
||||||
if (!ctx) {
|
|
||||||
// Can happen; see bug 355811
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX Save the operation callback time so we can restore it after the GC,
|
|
||||||
// because GCing can cause JS to run on our context, causing our
|
|
||||||
// ScriptEvaluated to be called, and clearing our operation callback time.
|
|
||||||
// See bug 302333.
|
|
||||||
PRTime callbackTime = ctx->mOperationCallbackTime;
|
|
||||||
PRTime modalStateTime = ctx->mModalStateTime;
|
|
||||||
|
|
||||||
// Now restore the callback time and count, in case they got reset.
|
|
||||||
ctx->mOperationCallbackTime = callbackTime;
|
|
||||||
ctx->mModalStateTime = modalStateTime;
|
|
||||||
|
|
||||||
PRTime now = PR_Now();
|
|
||||||
|
|
||||||
if (callbackTime == 0) {
|
|
||||||
// Initialize mOperationCallbackTime to start timing how long the
|
|
||||||
// script has run
|
|
||||||
ctx->mOperationCallbackTime = now;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->mModalStateDepth) {
|
|
||||||
// We're waiting on a modal dialog, nothing more to do here.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRTime duration = now - callbackTime;
|
|
||||||
|
|
||||||
// Check the amount of time this script has been running, or if the
|
|
||||||
// dialog is disabled.
|
|
||||||
JSObject* global = ::JS::CurrentGlobalOrNull(cx);
|
|
||||||
bool isTrackingChromeCodeTime =
|
|
||||||
global && xpc::AccessCheck::isChrome(js::GetObjectCompartment(global));
|
|
||||||
if (duration < (isTrackingChromeCodeTime ?
|
|
||||||
sMaxChromeScriptRunTime : sMaxScriptRunTime)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
|
||||||
// If it isn't safe to run script, then it isn't safe to bring up the
|
|
||||||
// prompt (since that will cause the event loop to spin). In this case
|
|
||||||
// (which is rare), we just stop the script... But report a warning so
|
|
||||||
// that developers have some idea of what went wrong.
|
|
||||||
|
|
||||||
JS_ReportWarning(cx, "A long running script was terminated");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we get here we're most likely executing an infinite loop in JS,
|
|
||||||
// we'll tell the user about this and we'll give the user the option
|
|
||||||
// of stopping the execution of the script.
|
|
||||||
nsCOMPtr<nsIPrompt> prompt = GetPromptFromContext(ctx);
|
|
||||||
NS_ENSURE_TRUE(prompt, false);
|
|
||||||
|
|
||||||
// Check if we should offer the option to debug
|
|
||||||
JS::RootedScript script(cx);
|
|
||||||
unsigned lineno;
|
|
||||||
bool hasFrame = ::JS_DescribeScriptedCaller(cx, script.address(), &lineno);
|
|
||||||
|
|
||||||
bool debugPossible = hasFrame && js::CanCallContextDebugHandler(cx);
|
|
||||||
#ifdef MOZ_JSDEBUGGER
|
|
||||||
// Get the debugger service if necessary.
|
|
||||||
if (debugPossible) {
|
|
||||||
bool jsds_IsOn = false;
|
|
||||||
const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
|
|
||||||
nsCOMPtr<jsdIExecutionHook> jsdHook;
|
|
||||||
nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv);
|
|
||||||
|
|
||||||
// Check if there's a user for the debugger service that's 'on' for us
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
jsds->GetDebuggerHook(getter_AddRefs(jsdHook));
|
|
||||||
jsds->GetIsOn(&jsds_IsOn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is a debug handler registered for this runtime AND
|
|
||||||
// ((jsd is on AND has a hook) OR (jsd isn't on (something else debugs)))
|
|
||||||
// then something useful will be done with our request to debug.
|
|
||||||
debugPossible = ((jsds_IsOn && (jsdHook != nullptr)) || !jsds_IsOn);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get localizable strings
|
|
||||||
nsXPIDLString title, msg, stopButton, waitButton, debugButton, neverShowDlg;
|
|
||||||
|
|
||||||
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"KillScriptTitle",
|
|
||||||
title);
|
|
||||||
|
|
||||||
nsresult tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"StopScriptButton",
|
|
||||||
stopButton);
|
|
||||||
if (NS_FAILED(tmp)) {
|
|
||||||
rv = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"WaitForScriptButton",
|
|
||||||
waitButton);
|
|
||||||
if (NS_FAILED(tmp)) {
|
|
||||||
rv = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"DontAskAgain",
|
|
||||||
neverShowDlg);
|
|
||||||
if (NS_FAILED(tmp)) {
|
|
||||||
rv = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (debugPossible) {
|
|
||||||
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"DebugScriptButton",
|
|
||||||
debugButton);
|
|
||||||
if (NS_FAILED(tmp)) {
|
|
||||||
rv = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"KillScriptWithDebugMessage",
|
|
||||||
msg);
|
|
||||||
if (NS_FAILED(tmp)) {
|
|
||||||
rv = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tmp = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"KillScriptMessage",
|
|
||||||
msg);
|
|
||||||
if (NS_FAILED(tmp)) {
|
|
||||||
rv = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//GetStringFromName can return NS_OK and still give NULL string
|
|
||||||
if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton ||
|
|
||||||
(!debugButton && debugPossible) || !neverShowDlg) {
|
|
||||||
NS_ERROR("Failed to get localized strings.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append file and line number information, if available
|
|
||||||
if (script) {
|
|
||||||
const char *filename = ::JS_GetScriptFilename(cx, script);
|
|
||||||
if (filename) {
|
|
||||||
nsXPIDLString scriptLocation;
|
|
||||||
NS_ConvertUTF8toUTF16 filenameUTF16(filename);
|
|
||||||
const PRUnichar *formatParams[] = { filenameUTF16.get() };
|
|
||||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
|
||||||
"KillScriptLocation",
|
|
||||||
formatParams,
|
|
||||||
scriptLocation);
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && scriptLocation) {
|
|
||||||
msg.AppendLiteral("\n\n");
|
|
||||||
msg.Append(scriptLocation);
|
|
||||||
msg.Append(':');
|
|
||||||
msg.AppendInt(lineno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t buttonPressed = 0; //In case user exits dialog by clicking X
|
|
||||||
bool neverShowDlgChk = false;
|
|
||||||
uint32_t buttonFlags = nsIPrompt::BUTTON_POS_1_DEFAULT +
|
|
||||||
(nsIPrompt::BUTTON_TITLE_IS_STRING *
|
|
||||||
(nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
|
|
||||||
|
|
||||||
// Add a third button if necessary:
|
|
||||||
if (debugPossible)
|
|
||||||
buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
|
|
||||||
|
|
||||||
// Null out the operation callback while we're re-entering JS here.
|
|
||||||
::JS_SetOperationCallback(cx, nullptr);
|
|
||||||
|
|
||||||
// Open the dialog.
|
|
||||||
rv = prompt->ConfirmEx(title, msg, buttonFlags, waitButton, stopButton,
|
|
||||||
debugButton, neverShowDlg, &neverShowDlgChk,
|
|
||||||
&buttonPressed);
|
|
||||||
|
|
||||||
::JS_SetOperationCallback(cx, DOMOperationCallback);
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
|
|
||||||
// Allow the script to continue running
|
|
||||||
|
|
||||||
if (neverShowDlgChk) {
|
|
||||||
if (isTrackingChromeCodeTime) {
|
|
||||||
Preferences::SetInt("dom.max_chrome_script_run_time", 0);
|
|
||||||
sMaxChromeScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
|
|
||||||
} else {
|
|
||||||
Preferences::SetInt("dom.max_script_run_time", 0);
|
|
||||||
sMaxScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->mOperationCallbackTime = PR_Now();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ((buttonPressed == 2) && debugPossible) {
|
|
||||||
return js_CallContextDebugHandler(cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_ClearPendingException(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsJSContext::EnterModalState()
|
|
||||||
{
|
|
||||||
if (!mModalStateDepth) {
|
|
||||||
mModalStateTime = mOperationCallbackTime ? PR_Now() : 0;
|
|
||||||
}
|
|
||||||
++mModalStateDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsJSContext::LeaveModalState()
|
|
||||||
{
|
|
||||||
if (!mModalStateDepth) {
|
|
||||||
NS_ERROR("Uh, mismatched LeaveModalState() call!");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
--mModalStateDepth;
|
|
||||||
|
|
||||||
// If we're still in a modal dialog, or mOperationCallbackTime is still
|
|
||||||
// uninitialized, do nothing.
|
|
||||||
if (mModalStateDepth || !mOperationCallbackTime) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If mOperationCallbackTime was set when we entered the first dialog
|
|
||||||
// (and mModalStateTime is thus non-zero), adjust mOperationCallbackTime
|
|
||||||
// to account for time spent in the dialog.
|
|
||||||
// If mOperationCallbackTime got set while the modal dialog was open,
|
|
||||||
// simply set mOperationCallbackTime to the closing time of the dialog so
|
|
||||||
// that we never adjust mOperationCallbackTime to be in the future.
|
|
||||||
if (mModalStateTime) {
|
|
||||||
mOperationCallbackTime += PR_Now() - mModalStateTime;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mOperationCallbackTime = PR_Now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define JS_OPTIONS_DOT_STR "javascript.options."
|
#define JS_OPTIONS_DOT_STR "javascript.options."
|
||||||
|
|
||||||
static const char js_options_dot_str[] = JS_OPTIONS_DOT_STR;
|
static const char js_options_dot_str[] = JS_OPTIONS_DOT_STR;
|
||||||
|
@ -1122,14 +847,9 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime, bool aGCOnDestruction,
|
||||||
// Watch for the JS boolean options
|
// Watch for the JS boolean options
|
||||||
Preferences::RegisterCallback(JSOptionChangedCallback,
|
Preferences::RegisterCallback(JSOptionChangedCallback,
|
||||||
js_options_dot_str, this);
|
js_options_dot_str, this);
|
||||||
|
|
||||||
::JS_SetOperationCallback(mContext, DOMOperationCallback);
|
|
||||||
}
|
}
|
||||||
mIsInitialized = false;
|
mIsInitialized = false;
|
||||||
mScriptsEnabled = true;
|
mScriptsEnabled = true;
|
||||||
mOperationCallbackTime = 0;
|
|
||||||
mModalStateTime = 0;
|
|
||||||
mModalStateDepth = 0;
|
|
||||||
mProcessingScriptTag = false;
|
mProcessingScriptTag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2185,8 +1905,6 @@ nsJSContext::ScriptEvaluated(bool aTerminated)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aTerminated) {
|
if (aTerminated) {
|
||||||
mOperationCallbackTime = 0;
|
|
||||||
mModalStateTime = 0;
|
|
||||||
mActive = true;
|
mActive = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3008,31 +2726,6 @@ nsJSRuntime::Startup()
|
||||||
sSecurityManager = nullptr;
|
sSecurityManager = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
MaxScriptRunTimePrefChangedCallback(const char *aPrefName, void *aClosure)
|
|
||||||
{
|
|
||||||
// Default limit on script run time to 10 seconds. 0 means let
|
|
||||||
// scripts run forever.
|
|
||||||
bool isChromePref =
|
|
||||||
strcmp(aPrefName, "dom.max_chrome_script_run_time") == 0;
|
|
||||||
int32_t time = Preferences::GetInt(aPrefName, isChromePref ? 20 : 10);
|
|
||||||
|
|
||||||
PRTime t;
|
|
||||||
if (time <= 0) {
|
|
||||||
t = NS_UNLIMITED_SCRIPT_RUNTIME;
|
|
||||||
} else {
|
|
||||||
t = time * PR_USEC_PER_SEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isChromePref) {
|
|
||||||
sMaxChromeScriptRunTime = t;
|
|
||||||
} else {
|
|
||||||
sMaxScriptRunTime = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ReportAllJSExceptionsPrefChangedCallback(const char* aPrefName, void* aClosure)
|
ReportAllJSExceptionsPrefChangedCallback(const char* aPrefName, void* aClosure)
|
||||||
{
|
{
|
||||||
|
@ -3223,12 +2916,6 @@ nsJSRuntime::Init()
|
||||||
SetDOMCallbacks(sRuntime, &DOMcallbacks);
|
SetDOMCallbacks(sRuntime, &DOMcallbacks);
|
||||||
|
|
||||||
// Set these global xpconnect options...
|
// Set these global xpconnect options...
|
||||||
Preferences::RegisterCallbackAndCall(MaxScriptRunTimePrefChangedCallback,
|
|
||||||
"dom.max_script_run_time");
|
|
||||||
|
|
||||||
Preferences::RegisterCallbackAndCall(MaxScriptRunTimePrefChangedCallback,
|
|
||||||
"dom.max_chrome_script_run_time");
|
|
||||||
|
|
||||||
Preferences::RegisterCallbackAndCall(ReportAllJSExceptionsPrefChangedCallback,
|
Preferences::RegisterCallbackAndCall(ReportAllJSExceptionsPrefChangedCallback,
|
||||||
"dom.report_all_js_exceptions");
|
"dom.report_all_js_exceptions");
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,6 @@ public:
|
||||||
virtual nsresult Deserialize(nsIObjectInputStream* aStream,
|
virtual nsresult Deserialize(nsIObjectInputStream* aStream,
|
||||||
JS::MutableHandle<JSScript*> aResult) MOZ_OVERRIDE;
|
JS::MutableHandle<JSScript*> aResult) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual void EnterModalState() MOZ_OVERRIDE;
|
|
||||||
virtual void LeaveModalState() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
NS_DECL_NSIXPCSCRIPTNOTIFY
|
NS_DECL_NSIXPCSCRIPTNOTIFY
|
||||||
|
|
||||||
static void LoadStart();
|
static void LoadStart();
|
||||||
|
|
|
@ -58,8 +58,8 @@ class Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NS_PIDOMWINDOW_IID \
|
#define NS_PIDOMWINDOW_IID \
|
||||||
{ 0xc7f20d00, 0xed38, 0x4d60, \
|
{ 0x4f4eadf9, 0xe795, 0x48e5, \
|
||||||
{ 0x90, 0xf6, 0x3e, 0xde, 0x7b, 0x71, 0xc3, 0xb3 } }
|
{ 0x89, 0x4b, 0x04, 0x40, 0xb2, 0x5d, 0xa6, 0xfa } }
|
||||||
|
|
||||||
class nsPIDOMWindow : public nsIDOMWindowInternal
|
class nsPIDOMWindow : public nsIDOMWindowInternal
|
||||||
{
|
{
|
||||||
|
@ -385,8 +385,8 @@ public:
|
||||||
* Callback for notifying a window about a modal dialog being
|
* Callback for notifying a window about a modal dialog being
|
||||||
* opened/closed with the window as a parent.
|
* opened/closed with the window as a parent.
|
||||||
*/
|
*/
|
||||||
virtual nsIDOMWindow *EnterModalState() = 0;
|
virtual void EnterModalState() = 0;
|
||||||
virtual void LeaveModalState(nsIDOMWindow *) = 0;
|
virtual void LeaveModalState() = 0;
|
||||||
|
|
||||||
virtual bool CanClose() = 0;
|
virtual bool CanClose() = 0;
|
||||||
virtual nsresult ForceClose() = 0;
|
virtual nsresult ForceClose() = 0;
|
||||||
|
|
|
@ -346,12 +346,7 @@ BrowserElementChild.prototype = {
|
||||||
debug("Entering modal state (outerWindowID=" + outerWindowID + ", " +
|
debug("Entering modal state (outerWindowID=" + outerWindowID + ", " +
|
||||||
"innerWindowID=" + innerWindowID + ")");
|
"innerWindowID=" + innerWindowID + ")");
|
||||||
|
|
||||||
// In theory, we're supposed to pass |modalStateWin| back to
|
utils.enterModalState();
|
||||||
// leaveModalStateWithWindow. But in practice, the window is always null,
|
|
||||||
// because it's the window associated with this script context, which
|
|
||||||
// doesn't have a window. But we'll play along anyway in case this
|
|
||||||
// changes.
|
|
||||||
var modalStateWin = utils.enterModalStateWithWindow();
|
|
||||||
|
|
||||||
// We'll decrement win.modalDepth when we receive a unblock-modal-prompt message
|
// We'll decrement win.modalDepth when we receive a unblock-modal-prompt message
|
||||||
// for the window.
|
// for the window.
|
||||||
|
@ -388,7 +383,7 @@ BrowserElementChild.prototype = {
|
||||||
delete win.modalReturnValue;
|
delete win.modalReturnValue;
|
||||||
|
|
||||||
if (!this._shuttingDown) {
|
if (!this._shuttingDown) {
|
||||||
utils.leaveModalStateWithWindow(modalStateWin);
|
utils.leaveModalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Leaving modal state (outerID=" + outerWindowID + ", " +
|
debug("Leaving modal state (outerID=" + outerWindowID + ", " +
|
||||||
|
|
|
@ -42,7 +42,7 @@ interface nsIURI;
|
||||||
interface nsIDOMEventTarget;
|
interface nsIDOMEventTarget;
|
||||||
interface nsIRunnable;
|
interface nsIRunnable;
|
||||||
|
|
||||||
[scriptable, uuid(cbe333d7-5b2c-4a9b-b99b-e6e388afa62b)]
|
[scriptable, uuid(ff1cec22-b183-40d3-8b42-b81a2f0ba4e6)]
|
||||||
interface nsIDOMWindowUtils : nsISupports {
|
interface nsIDOMWindowUtils : nsISupports {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1034,26 +1034,13 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||||
* Put the window into a state where scripts are frozen and events
|
* Put the window into a state where scripts are frozen and events
|
||||||
* suppressed, for use when the window has launched a modal prompt.
|
* suppressed, for use when the window has launched a modal prompt.
|
||||||
*/
|
*/
|
||||||
[noscript] void enterModalState();
|
void enterModalState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resume normal window state, where scripts can run and events are
|
* Resume normal window state, where scripts can run and events are
|
||||||
* delivered.
|
* delivered.
|
||||||
*/
|
*/
|
||||||
[noscript] void leaveModalState();
|
void leaveModalState();
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as enterModalState, but returns the window associated with the
|
|
||||||
* current JS context.
|
|
||||||
*/
|
|
||||||
nsIDOMWindow enterModalStateWithWindow();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as leaveModalState, but takes a window associated with the active
|
|
||||||
* context when enterModalStateWithWindow was called. The currently context
|
|
||||||
* might be different at the moment (see bug 621764).
|
|
||||||
*/
|
|
||||||
void leaveModalStateWithWindow(in nsIDOMWindow aWindow);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the window is in a modal state? [See enterModalState()]
|
* Is the window is in a modal state? [See enterModalState()]
|
||||||
|
|
|
@ -53,8 +53,8 @@ function registerMockPromptService()
|
||||||
// accounting for triggering the "stop showing more prompts" code for
|
// accounting for triggering the "stop showing more prompts" code for
|
||||||
// abusive pages.
|
// abusive pages.
|
||||||
var winUtils = SpecialPowers.getDOMWindowUtils(this.domWindow);
|
var winUtils = SpecialPowers.getDOMWindowUtils(this.domWindow);
|
||||||
var w = winUtils.enterModalStateWithWindow();
|
winUtils.enterModalState();
|
||||||
winUtils.leaveModalStateWithWindow(w);
|
winUtils.leaveModalState();
|
||||||
},
|
},
|
||||||
|
|
||||||
alert: function(aDialogTitle, aText)
|
alert: function(aDialogTitle, aText)
|
||||||
|
|
|
@ -801,7 +801,7 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
|
||||||
|
|
||||||
JS_SetErrorReporter(workerCx, ErrorReporter);
|
JS_SetErrorReporter(workerCx, ErrorReporter);
|
||||||
|
|
||||||
JS_SetOperationCallback(workerCx, OperationCallback);
|
JS_SetOperationCallback(aRuntime, OperationCallback);
|
||||||
|
|
||||||
js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
|
js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ nsAutoWindowStateHelper::nsAutoWindowStateHelper(nsIDOMWindow *aWindow)
|
||||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
|
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
|
||||||
|
|
||||||
if (window) {
|
if (window) {
|
||||||
mCallerWindow = window->EnterModalState();
|
window->EnterModalState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ nsAutoWindowStateHelper::~nsAutoWindowStateHelper()
|
||||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mWindow));
|
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mWindow));
|
||||||
|
|
||||||
if (window) {
|
if (window) {
|
||||||
window->LeaveModalState(mCallerWindow);
|
window->LeaveModalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDefaultEnabled) {
|
if (mDefaultEnabled) {
|
||||||
|
|
|
@ -30,7 +30,6 @@ protected:
|
||||||
bool DispatchEventToChrome(const char *aEventName);
|
bool DispatchEventToChrome(const char *aEventName);
|
||||||
|
|
||||||
nsIDOMWindow *mWindow;
|
nsIDOMWindow *mWindow;
|
||||||
nsCOMPtr<nsIDOMWindow> mCallerWindow;
|
|
||||||
bool mDefaultEnabled;
|
bool mDefaultEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -453,7 +453,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||||
// Apply the render offset
|
// Apply the render offset
|
||||||
mLayerManager->GetCompositor()->SetScreenRenderOffset(offset);
|
mLayerManager->GetCompositor()->SetScreenRenderOffset(offset);
|
||||||
|
|
||||||
gfx3DMatrix transform(aLayer->GetTransform() * gfx3DMatrix(treeTransform));
|
gfx3DMatrix transform(gfx3DMatrix(treeTransform) * aLayer->GetTransform());
|
||||||
// The transform already takes the resolution scale into account. Since we
|
// The transform already takes the resolution scale into account. Since we
|
||||||
// will apply the resolution scale again when computing the effective
|
// will apply the resolution scale again when computing the effective
|
||||||
// transform, we must apply the inverse resolution scale here.
|
// transform, we must apply the inverse resolution scale here.
|
||||||
|
@ -551,20 +551,20 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDev
|
||||||
// primary scrollable layer. We compare this to the user zoom and scroll
|
// primary scrollable layer. We compare this to the user zoom and scroll
|
||||||
// offset in the view transform we obtained from Java in order to compute the
|
// offset in the view transform we obtained from Java in order to compute the
|
||||||
// transformation we need to apply.
|
// transformation we need to apply.
|
||||||
LayoutDeviceToScreenScale zoomAdjust = userZoom / metrics.mDevPixelsPerCSSPixel;
|
LayerToScreenScale zoomAdjust = userZoom / geckoZoom;
|
||||||
|
|
||||||
LayoutDevicePoint geckoScroll(0, 0);
|
LayerIntPoint geckoScroll(0, 0);
|
||||||
if (metrics.IsScrollable()) {
|
if (metrics.IsScrollable()) {
|
||||||
geckoScroll = metrics.mScrollOffset * metrics.mDevPixelsPerCSSPixel;
|
geckoScroll = scrollOffsetLayerPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutDevicePoint translation = (userScroll / zoomAdjust) - geckoScroll;
|
LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll;
|
||||||
treeTransform = gfx3DMatrix(ViewTransform(-translation, userZoom / metrics.mDevPixelsPerCSSPixel));
|
treeTransform = gfx3DMatrix(ViewTransform(-translation, userZoom / metrics.mDevPixelsPerCSSPixel));
|
||||||
|
|
||||||
// The transform already takes the resolution scale into account. Since we
|
// The transform already takes the resolution scale into account. Since we
|
||||||
// will apply the resolution scale again when computing the effective
|
// will apply the resolution scale again when computing the effective
|
||||||
// transform, we must apply the inverse resolution scale here.
|
// transform, we must apply the inverse resolution scale here.
|
||||||
gfx3DMatrix computedTransform = currentTransform * treeTransform;
|
gfx3DMatrix computedTransform = treeTransform * currentTransform;
|
||||||
computedTransform.Scale(1.0f/container->GetPreXScale(),
|
computedTransform.Scale(1.0f/container->GetPreXScale(),
|
||||||
1.0f/container->GetPreYScale(),
|
1.0f/container->GetPreYScale(),
|
||||||
1);
|
1);
|
||||||
|
|
|
@ -27,7 +27,7 @@ class AutoResolveRefLayers;
|
||||||
|
|
||||||
// Represents (affine) transforms that are calculated from a content view.
|
// Represents (affine) transforms that are calculated from a content view.
|
||||||
struct ViewTransform {
|
struct ViewTransform {
|
||||||
ViewTransform(LayoutDevicePoint aTranslation = LayoutDevicePoint(),
|
ViewTransform(LayerPoint aTranslation = LayerPoint(),
|
||||||
LayoutDeviceToScreenScale aScale = LayoutDeviceToScreenScale())
|
LayoutDeviceToScreenScale aScale = LayoutDeviceToScreenScale())
|
||||||
: mTranslation(aTranslation)
|
: mTranslation(aTranslation)
|
||||||
, mScale(aScale)
|
, mScale(aScale)
|
||||||
|
@ -48,7 +48,7 @@ struct ViewTransform {
|
||||||
return !(*this == rhs);
|
return !(*this == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutDevicePoint mTranslation;
|
LayerPoint mTranslation;
|
||||||
LayoutDeviceToScreenScale mScale;
|
LayoutDeviceToScreenScale mScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1160,8 +1160,8 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
|
||||||
lastPaintScrollOffset = mLastContentPaintMetrics.mScrollOffset;
|
lastPaintScrollOffset = mLastContentPaintMetrics.mScrollOffset;
|
||||||
}
|
}
|
||||||
CSSToScreenScale localScale = mFrameMetrics.CalculateResolution();
|
CSSToScreenScale localScale = mFrameMetrics.CalculateResolution();
|
||||||
LayoutDevicePoint translation = (mFrameMetrics.mScrollOffset - lastPaintScrollOffset)
|
LayerPoint translation = (mFrameMetrics.mScrollOffset - lastPaintScrollOffset)
|
||||||
* mLastContentPaintMetrics.mDevPixelsPerCSSPixel;
|
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
|
||||||
return ViewTransform(-translation, localScale / mLastContentPaintMetrics.mDevPixelsPerCSSPixel);
|
return ViewTransform(-translation, localScale / mLastContentPaintMetrics.mDevPixelsPerCSSPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,39 +196,39 @@ TEST(AsyncPanZoomController, ComplexTransform) {
|
||||||
apzc->SetFrameMetrics(metrics);
|
apzc->SetFrameMetrics(metrics);
|
||||||
apzc->NotifyLayersUpdated(metrics, true);
|
apzc->NotifyLayersUpdated(metrics, true);
|
||||||
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||||
EXPECT_EQ(ViewTransform(LayoutDevicePoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
EXPECT_EQ(ViewTransform(LayerPoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||||
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
|
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
|
||||||
|
|
||||||
childApzc->SetFrameMetrics(childMetrics);
|
childApzc->SetFrameMetrics(childMetrics);
|
||||||
childApzc->NotifyLayersUpdated(childMetrics, true);
|
childApzc->NotifyLayersUpdated(childMetrics, true);
|
||||||
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||||
EXPECT_EQ(ViewTransform(LayoutDevicePoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
EXPECT_EQ(ViewTransform(LayerPoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||||
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
|
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
|
||||||
|
|
||||||
// do an async scroll by 5 pixels and check the transform
|
// do an async scroll by 5 pixels and check the transform
|
||||||
metrics.mScrollOffset += CSSPoint(5, 0);
|
metrics.mScrollOffset += CSSPoint(5, 0);
|
||||||
apzc->SetFrameMetrics(metrics);
|
apzc->SetFrameMetrics(metrics);
|
||||||
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||||
EXPECT_EQ(ViewTransform(LayoutDevicePoint(-15, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||||
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
|
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
|
||||||
|
|
||||||
childMetrics.mScrollOffset += CSSPoint(5, 0);
|
childMetrics.mScrollOffset += CSSPoint(5, 0);
|
||||||
childApzc->SetFrameMetrics(childMetrics);
|
childApzc->SetFrameMetrics(childMetrics);
|
||||||
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||||
EXPECT_EQ(ViewTransform(LayoutDevicePoint(-15, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||||
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
|
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
|
||||||
|
|
||||||
// do an async zoom of 1.5x and check the transform
|
// do an async zoom of 1.5x and check the transform
|
||||||
metrics.mZoom.scale *= 1.5f;
|
metrics.mZoom.scale *= 1.5f;
|
||||||
apzc->SetFrameMetrics(metrics);
|
apzc->SetFrameMetrics(metrics);
|
||||||
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||||
EXPECT_EQ(ViewTransform(LayoutDevicePoint(-15, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
|
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
|
||||||
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
|
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
|
||||||
|
|
||||||
childMetrics.mZoom.scale *= 1.5f;
|
childMetrics.mZoom.scale *= 1.5f;
|
||||||
childApzc->SetFrameMetrics(childMetrics);
|
childApzc->SetFrameMetrics(childMetrics);
|
||||||
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||||
EXPECT_EQ(ViewTransform(LayoutDevicePoint(-15, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
|
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
|
||||||
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
|
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5419,17 +5419,17 @@ JS_New(JSContext *cx, JSObject *ctorArg, unsigned argc, jsval *argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSOperationCallback)
|
JS_PUBLIC_API(JSOperationCallback)
|
||||||
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback)
|
JS_SetOperationCallback(JSRuntime *rt, JSOperationCallback callback)
|
||||||
{
|
{
|
||||||
JSOperationCallback old = cx->operationCallback;
|
JSOperationCallback old = rt->operationCallback;
|
||||||
cx->operationCallback = callback;
|
rt->operationCallback = callback;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSOperationCallback)
|
JS_PUBLIC_API(JSOperationCallback)
|
||||||
JS_GetOperationCallback(JSContext *cx)
|
JS_GetOperationCallback(JSRuntime *rt)
|
||||||
{
|
{
|
||||||
return cx->operationCallback;
|
return rt->operationCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
|
|
|
@ -4329,10 +4329,10 @@ Call(JSContext *cx, jsval thisv, JSObject *funObj, unsigned argc, jsval *argv,
|
||||||
* is disconnected before attempting such re-entry.
|
* is disconnected before attempting such re-entry.
|
||||||
*/
|
*/
|
||||||
extern JS_PUBLIC_API(JSOperationCallback)
|
extern JS_PUBLIC_API(JSOperationCallback)
|
||||||
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback);
|
JS_SetOperationCallback(JSRuntime *rt, JSOperationCallback callback);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(JSOperationCallback)
|
extern JS_PUBLIC_API(JSOperationCallback)
|
||||||
JS_GetOperationCallback(JSContext *cx);
|
JS_GetOperationCallback(JSRuntime *rt);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(void)
|
extern JS_PUBLIC_API(void)
|
||||||
JS_TriggerOperationCallback(JSRuntime *rt);
|
JS_TriggerOperationCallback(JSRuntime *rt);
|
||||||
|
|
|
@ -1028,7 +1028,7 @@ js_InvokeOperationCallback(JSContext *cx)
|
||||||
* if it re-enters the JS engine. The embedding must ensure that the
|
* if it re-enters the JS engine. The embedding must ensure that the
|
||||||
* callback is disconnected before attempting such re-entry.
|
* callback is disconnected before attempting such re-entry.
|
||||||
*/
|
*/
|
||||||
JSOperationCallback cb = cx->operationCallback;
|
JSOperationCallback cb = cx->runtime()->operationCallback;
|
||||||
return !cb || cb(cx);
|
return !cb || cb(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1072,7 +1072,6 @@ JSContext::JSContext(JSRuntime *rt)
|
||||||
defaultCompartmentObject_(NULL),
|
defaultCompartmentObject_(NULL),
|
||||||
cycleDetectorSet(MOZ_THIS_IN_INITIALIZER_LIST()),
|
cycleDetectorSet(MOZ_THIS_IN_INITIALIZER_LIST()),
|
||||||
errorReporter(NULL),
|
errorReporter(NULL),
|
||||||
operationCallback(NULL),
|
|
||||||
data(NULL),
|
data(NULL),
|
||||||
data2(NULL),
|
data2(NULL),
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
|
|
|
@ -445,9 +445,6 @@ struct JSContext : public js::ExclusiveContext,
|
||||||
/* Per-context optional error reporter. */
|
/* Per-context optional error reporter. */
|
||||||
JSErrorReporter errorReporter;
|
JSErrorReporter errorReporter;
|
||||||
|
|
||||||
/* Branch callback. */
|
|
||||||
JSOperationCallback operationCallback;
|
|
||||||
|
|
||||||
/* Client opaque pointers. */
|
/* Client opaque pointers. */
|
||||||
void *data;
|
void *data;
|
||||||
void *data2;
|
void *data2;
|
||||||
|
|
|
@ -374,12 +374,6 @@ ShellOperationCallback(JSContext *cx)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
SetContextOptions(JSContext *cx)
|
|
||||||
{
|
|
||||||
JS_SetOperationCallback(cx, ShellOperationCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some UTF-8 files, notably those written using Notepad, have a Unicode
|
* Some UTF-8 files, notably those written using Notepad, have a Unicode
|
||||||
* Byte-Order-Mark (BOM) as their first character. This is useless (byte-order
|
* Byte-Order-Mark (BOM) as their first character. This is useless (byte-order
|
||||||
|
@ -572,8 +566,6 @@ Process(JSContext *cx, JSObject *obj_, const char *filename, bool forceTTY)
|
||||||
}
|
}
|
||||||
AutoCloseInputFile autoClose(file);
|
AutoCloseInputFile autoClose(file);
|
||||||
|
|
||||||
SetContextOptions(cx);
|
|
||||||
|
|
||||||
if (!forceTTY && !isatty(fileno(file))) {
|
if (!forceTTY && !isatty(fileno(file))) {
|
||||||
// It's not interactive - just execute it.
|
// It's not interactive - just execute it.
|
||||||
RunFile(cx, obj, filename, file, compileOnly);
|
RunFile(cx, obj, filename, file, compileOnly);
|
||||||
|
@ -4865,7 +4857,6 @@ NewContext(JSRuntime *rt)
|
||||||
|
|
||||||
JS_SetContextPrivate(cx, data);
|
JS_SetContextPrivate(cx, data);
|
||||||
JS_SetErrorReporter(cx, my_ErrorReporter);
|
JS_SetErrorReporter(cx, my_ErrorReporter);
|
||||||
SetContextOptions(cx);
|
|
||||||
if (enableTypeInference)
|
if (enableTypeInference)
|
||||||
JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
|
JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
|
||||||
if (enableIon)
|
if (enableIon)
|
||||||
|
@ -5470,6 +5461,7 @@ main(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals);
|
JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals);
|
||||||
JS_SetSecurityCallbacks(rt, &securityCallbacks);
|
JS_SetSecurityCallbacks(rt, &securityCallbacks);
|
||||||
|
JS_SetOperationCallback(rt, ShellOperationCallback);
|
||||||
|
|
||||||
JS_SetNativeStackQuota(rt, gMaxStackSize);
|
JS_SetNativeStackQuota(rt, gMaxStackSize);
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ PerThreadData::removeFromThreadList()
|
||||||
JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||||
: mainThread(this),
|
: mainThread(this),
|
||||||
interrupt(0),
|
interrupt(0),
|
||||||
|
operationCallback(NULL),
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
operationCallbackLock(NULL),
|
operationCallbackLock(NULL),
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -693,6 +693,9 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
*/
|
*/
|
||||||
volatile int32_t interrupt;
|
volatile int32_t interrupt;
|
||||||
|
|
||||||
|
/* Branch callback */
|
||||||
|
JSOperationCallback operationCallback;
|
||||||
|
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1466,10 +1466,8 @@ XPCShellErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
|
||||||
static bool
|
static bool
|
||||||
ContextCallback(JSContext *cx, unsigned contextOp)
|
ContextCallback(JSContext *cx, unsigned contextOp)
|
||||||
{
|
{
|
||||||
if (contextOp == JSCONTEXT_NEW) {
|
if (contextOp == JSCONTEXT_NEW)
|
||||||
JS_SetErrorReporter(cx, XPCShellErrorReporter);
|
JS_SetErrorReporter(cx, XPCShellErrorReporter);
|
||||||
JS_SetOperationCallback(cx, XPCShellOperationCallback);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1642,6 +1640,11 @@ main(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
rtsvc->RegisterContextCallback(ContextCallback);
|
rtsvc->RegisterContextCallback(ContextCallback);
|
||||||
|
|
||||||
|
// Override the default XPConnect operation callback. We could store the
|
||||||
|
// old one and restore it before shutting down, but there's not really a
|
||||||
|
// reason to bother.
|
||||||
|
JS_SetOperationCallback(rt, XPCShellOperationCallback);
|
||||||
|
|
||||||
cx = JS_NewContext(rt, 8192);
|
cx = JS_NewContext(rt, 8192);
|
||||||
if (!cx) {
|
if (!cx) {
|
||||||
printf("JS_NewContext failed!\n");
|
printf("JS_NewContext failed!\n");
|
||||||
|
|
|
@ -3737,10 +3737,7 @@ public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool ContextHolderOperationCallback(JSContext *cx);
|
|
||||||
|
|
||||||
JSContext* mJSContext;
|
JSContext* mJSContext;
|
||||||
JSContext* mOrigCx;
|
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3750,7 +3747,6 @@ ContextHolder::ContextHolder(JSContext *aOuterCx,
|
||||||
HandleObject aSandbox,
|
HandleObject aSandbox,
|
||||||
nsIPrincipal *aPrincipal)
|
nsIPrincipal *aPrincipal)
|
||||||
: mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
|
: mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
|
||||||
mOrigCx(aOuterCx),
|
|
||||||
mPrincipal(aPrincipal)
|
mPrincipal(aPrincipal)
|
||||||
{
|
{
|
||||||
if (mJSContext) {
|
if (mJSContext) {
|
||||||
|
@ -3765,7 +3761,6 @@ ContextHolder::ContextHolder(JSContext *aOuterCx,
|
||||||
JSOPTION_PRIVATE_IS_NSISUPPORTS);
|
JSOPTION_PRIVATE_IS_NSISUPPORTS);
|
||||||
js::SetDefaultObjectForContext(mJSContext, aSandbox);
|
js::SetDefaultObjectForContext(mJSContext, aSandbox);
|
||||||
JS_SetContextPrivate(mJSContext, this);
|
JS_SetContextPrivate(mJSContext, this);
|
||||||
JS_SetOperationCallback(mJSContext, ContextHolderOperationCallback);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3775,21 +3770,6 @@ ContextHolder::~ContextHolder()
|
||||||
JS_DestroyContextNoGC(mJSContext);
|
JS_DestroyContextNoGC(mJSContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ContextHolder::ContextHolderOperationCallback(JSContext *cx)
|
|
||||||
{
|
|
||||||
ContextHolder* thisObject =
|
|
||||||
static_cast<ContextHolder*>(JS_GetContextPrivate(cx));
|
|
||||||
NS_ASSERTION(thisObject, "How did that happen?");
|
|
||||||
|
|
||||||
JSContext *origCx = thisObject->mOrigCx;
|
|
||||||
JSOperationCallback callback = JS_GetOperationCallback(origCx);
|
|
||||||
bool ok = true;
|
|
||||||
if (callback)
|
|
||||||
ok = callback(origCx);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
/* void evalInSandbox(in AString source, in nativeobj sandbox); */
|
/* void evalInSandbox(in AString source, in nativeobj sandbox); */
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "AccessCheck.h"
|
#include "AccessCheck.h"
|
||||||
|
#include "nsGlobalWindow.h"
|
||||||
|
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "nsJSPrincipals.h"
|
#include "nsJSPrincipals.h"
|
||||||
|
@ -1228,6 +1229,61 @@ XPCJSRuntime::CTypesActivityCallback(JSContext *cx, js::CTypesActivityType type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
XPCJSRuntime::OperationCallback(JSContext *cx)
|
||||||
|
{
|
||||||
|
XPCJSRuntime *self = XPCJSRuntime::Get();
|
||||||
|
|
||||||
|
// If this is the first time the operation callback has fired since we last
|
||||||
|
// returned to the event loop, mark the checkpoint.
|
||||||
|
if (self->mSlowScriptCheckpoint.IsNull()) {
|
||||||
|
self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is at least the second operation callback we've received since
|
||||||
|
// returning to the event loop. See how long it's been, and what the limit
|
||||||
|
// is.
|
||||||
|
TimeDuration duration = TimeStamp::NowLoRes() - self->mSlowScriptCheckpoint;
|
||||||
|
bool chrome =
|
||||||
|
nsContentUtils::IsSystemPrincipal(nsContentUtils::GetSubjectPrincipal());
|
||||||
|
const char *prefName = chrome ? "dom.max_chrome_script_run_time"
|
||||||
|
: "dom.max_script_run_time";
|
||||||
|
int32_t limit = Preferences::GetInt(prefName, chrome ? 20 : 10);
|
||||||
|
|
||||||
|
// If there's no limit, or we're within the limit, let it go.
|
||||||
|
if (limit == 0 || duration.ToSeconds() < limit)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// This has gone on long enough! Time to take action. ;-)
|
||||||
|
//
|
||||||
|
|
||||||
|
// Get the DOM window associated with the running script. If the script is
|
||||||
|
// running in a non-DOM scope, we have to just let it keep running.
|
||||||
|
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
|
||||||
|
nsCOMPtr<nsPIDOMWindow> win;
|
||||||
|
if (IS_WN_REFLECTOR(global))
|
||||||
|
win = do_QueryWrappedNative(XPCWrappedNative::Get(global));
|
||||||
|
if (!win)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Show the prompt to the user, and kill if requested.
|
||||||
|
nsGlobalWindow::SlowScriptResponse response =
|
||||||
|
static_cast<nsGlobalWindow*>(win.get())->ShowSlowScriptDialog();
|
||||||
|
if (response == nsGlobalWindow::KillSlowScript)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// The user chose to continue the script. Reset the timer, and disable this
|
||||||
|
// machinery with a pref of the user opted out of future slow-script dialogs.
|
||||||
|
self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
|
||||||
|
if (response == nsGlobalWindow::AlwaysContinueSlowScript)
|
||||||
|
Preferences::SetInt(prefName, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
XPCJSRuntime::SizeOfIncludingThis(MallocSizeOf mallocSizeOf)
|
XPCJSRuntime::SizeOfIncludingThis(MallocSizeOf mallocSizeOf)
|
||||||
{
|
{
|
||||||
|
@ -2877,6 +2933,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||||
JS_SetAccumulateTelemetryCallback(runtime, AccumulateTelemetryCallback);
|
JS_SetAccumulateTelemetryCallback(runtime, AccumulateTelemetryCallback);
|
||||||
js::SetActivityCallback(runtime, ActivityCallback, this);
|
js::SetActivityCallback(runtime, ActivityCallback, this);
|
||||||
js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
|
js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
|
||||||
|
JS_SetOperationCallback(runtime, OperationCallback);
|
||||||
|
|
||||||
// The JS engine needs to keep the source code around in order to implement
|
// The JS engine needs to keep the source code around in order to implement
|
||||||
// Function.prototype.toSource(). It'd be nice to not have to do this for
|
// Function.prototype.toSource(). It'd be nice to not have to do this for
|
||||||
|
|
|
@ -1182,6 +1182,9 @@ nsXPConnect::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
mEventDepth--;
|
mEventDepth--;
|
||||||
|
|
||||||
|
// Now that we're back to the event loop, reset the slow script checkpoint.
|
||||||
|
mRuntime->OnAfterProcessNextEvent();
|
||||||
|
|
||||||
// Call cycle collector occasionally.
|
// Call cycle collector occasionally.
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
nsJSContext::MaybePokeCC();
|
nsJSContext::MaybePokeCC();
|
||||||
|
|
|
@ -827,6 +827,7 @@ public:
|
||||||
static void ActivityCallback(void *arg, bool active);
|
static void ActivityCallback(void *arg, bool active);
|
||||||
static void CTypesActivityCallback(JSContext *cx,
|
static void CTypesActivityCallback(JSContext *cx,
|
||||||
js::CTypesActivityType type);
|
js::CTypesActivityType type);
|
||||||
|
static bool OperationCallback(JSContext *cx);
|
||||||
|
|
||||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
||||||
|
|
||||||
|
@ -836,6 +837,7 @@ public:
|
||||||
void DeleteJunkScope();
|
void DeleteJunkScope();
|
||||||
|
|
||||||
PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory);
|
PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory);
|
||||||
|
void OnAfterProcessNextEvent() { mSlowScriptCheckpoint = mozilla::TimeStamp(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XPCJSRuntime(); // no implementation
|
XPCJSRuntime(); // no implementation
|
||||||
|
@ -876,6 +878,8 @@ private:
|
||||||
JSObject* mJunkScope;
|
JSObject* mJunkScope;
|
||||||
nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
|
nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
|
||||||
|
|
||||||
|
mozilla::TimeStamp mSlowScriptCheckpoint;
|
||||||
|
|
||||||
nsCOMPtr<nsIException> mPendingException;
|
nsCOMPtr<nsIException> mPendingException;
|
||||||
nsCOMPtr<nsIExceptionManager> mExceptionManager;
|
nsCOMPtr<nsIExceptionManager> mExceptionManager;
|
||||||
bool mExceptionManagerNotAvailable;
|
bool mExceptionManagerNotAvailable;
|
||||||
|
|
|
@ -128,6 +128,7 @@ SYNC_JAVA_FILES := \
|
||||||
sync/net/BrowserIDAuthHeaderProvider.java \
|
sync/net/BrowserIDAuthHeaderProvider.java \
|
||||||
sync/net/ConnectionMonitorThread.java \
|
sync/net/ConnectionMonitorThread.java \
|
||||||
sync/net/HandleProgressException.java \
|
sync/net/HandleProgressException.java \
|
||||||
|
sync/net/HawkAuthHeaderProvider.java \
|
||||||
sync/net/HMACAuthHeaderProvider.java \
|
sync/net/HMACAuthHeaderProvider.java \
|
||||||
sync/net/HttpResponseObserver.java \
|
sync/net/HttpResponseObserver.java \
|
||||||
sync/net/Resource.java \
|
sync/net/Resource.java \
|
||||||
|
|
|
@ -178,13 +178,21 @@ public class Utils {
|
||||||
// Truncates towards 0.
|
// Truncates towards 0.
|
||||||
return (long)(decimal * 1000);
|
return (long)(decimal * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long decimalSecondsToMilliseconds(Long decimal) {
|
public static long decimalSecondsToMilliseconds(Long decimal) {
|
||||||
return decimal * 1000;
|
return decimal * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long decimalSecondsToMilliseconds(Integer decimal) {
|
public static long decimalSecondsToMilliseconds(Integer decimal) {
|
||||||
return (long)(decimal * 1000);
|
return (long)(decimal * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] sha256(byte[] in)
|
||||||
|
throws NoSuchAlgorithmException {
|
||||||
|
MessageDigest sha1 = MessageDigest.getInstance("SHA-256");
|
||||||
|
return sha1.digest(in);
|
||||||
|
}
|
||||||
|
|
||||||
protected static byte[] sha1(final String utf8)
|
protected static byte[] sha1(final String utf8)
|
||||||
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||||
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
|
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
|
||||||
|
|
|
@ -0,0 +1,347 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
package org.mozilla.gecko.sync.net;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
|
||||||
|
import ch.boye.httpclientandroidlib.Header;
|
||||||
|
import ch.boye.httpclientandroidlib.HttpEntity;
|
||||||
|
import ch.boye.httpclientandroidlib.HttpEntityEnclosingRequest;
|
||||||
|
import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
|
||||||
|
import ch.boye.httpclientandroidlib.client.methods.HttpUriRequest;
|
||||||
|
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
|
||||||
|
import ch.boye.httpclientandroidlib.message.BasicHeader;
|
||||||
|
import ch.boye.httpclientandroidlib.protocol.BasicHttpContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An <code>AuthHeaderProvider</code> that returns an Authorization header for
|
||||||
|
* Hawk: <a href="https://github.com/hueniverse/hawk">https://github.com/hueniverse/hawk</a>.
|
||||||
|
*
|
||||||
|
* Hawk is an HTTP authentication scheme using a message authentication code
|
||||||
|
* (MAC) algorithm to provide partial HTTP request cryptographic verification.
|
||||||
|
* Hawk is the successor to the HMAC authentication scheme.
|
||||||
|
*/
|
||||||
|
public class HawkAuthHeaderProvider implements AuthHeaderProvider {
|
||||||
|
public static final String LOG_TAG = HawkAuthHeaderProvider.class.getSimpleName();
|
||||||
|
|
||||||
|
public static final int HAWK_HEADER_VERSION = 1;
|
||||||
|
|
||||||
|
protected static final int NONCE_LENGTH_IN_BYTES = 8;
|
||||||
|
protected static final String HMAC_SHA256_ALGORITHM = "hmacSHA256";
|
||||||
|
|
||||||
|
protected final String id;
|
||||||
|
protected final byte[] key;
|
||||||
|
protected final boolean includePayloadHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Hawk Authorization header provider.
|
||||||
|
* <p>
|
||||||
|
* Hawk specifies no mechanism by which a client receives an
|
||||||
|
* identifier-and-key pair from the server.
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* to name requests with.
|
||||||
|
* @param key
|
||||||
|
* to sign request with.
|
||||||
|
*
|
||||||
|
* @param includePayloadHash
|
||||||
|
* true if message integrity hash should be included in signed
|
||||||
|
* request header. See <a href="https://github.com/hueniverse/hawk#payload-validation">https://github.com/hueniverse/hawk#payload-validation</a>.
|
||||||
|
*/
|
||||||
|
public HawkAuthHeaderProvider(String id, byte[] key, boolean includePayloadHash) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("id must not be null");
|
||||||
|
}
|
||||||
|
if (key == null) {
|
||||||
|
throw new IllegalArgumentException("key must not be null");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
this.key = key;
|
||||||
|
this.includePayloadHash = includePayloadHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Header getAuthHeader(HttpRequestBase request, BasicHttpContext context, DefaultHttpClient client) throws GeneralSecurityException {
|
||||||
|
long timestamp = System.currentTimeMillis() / 1000;
|
||||||
|
String nonce = Base64.encodeBase64String(Utils.generateRandomBytes(NONCE_LENGTH_IN_BYTES));
|
||||||
|
String extra = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
return getAuthHeader(request, context, client, timestamp, nonce, extra, this.includePayloadHash);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// We lie a little and make every exception a GeneralSecurityException.
|
||||||
|
throw new GeneralSecurityException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function that generates an HTTP Authorization: Hawk header given
|
||||||
|
* additional Hawk specific data.
|
||||||
|
*
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
* @throws InvalidKeyException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected Header getAuthHeader(HttpRequestBase request, BasicHttpContext context, DefaultHttpClient client,
|
||||||
|
long timestamp, String nonce, String extra, boolean includePayloadHash)
|
||||||
|
throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
||||||
|
if (timestamp < 0) {
|
||||||
|
throw new IllegalArgumentException("timestamp must contain only [0-9].");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonce == null) {
|
||||||
|
throw new IllegalArgumentException("nonce must not be null.");
|
||||||
|
}
|
||||||
|
if (nonce.length() == 0) {
|
||||||
|
throw new IllegalArgumentException("nonce must not be empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String payloadHash = null;
|
||||||
|
if (includePayloadHash) {
|
||||||
|
if (!(request instanceof HttpEntityEnclosingRequest)) {
|
||||||
|
throw new IllegalArgumentException("cannot specify payload for request without an entity");
|
||||||
|
}
|
||||||
|
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
|
||||||
|
if (entity == null) {
|
||||||
|
throw new IllegalArgumentException("cannot specify payload for request with a null entity");
|
||||||
|
}
|
||||||
|
payloadHash = Base64.encodeBase64String(getPayloadHash(entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
String app = null;
|
||||||
|
String dlg = null;
|
||||||
|
String requestString = getRequestString(request, "header", timestamp, nonce, payloadHash, extra, app, dlg);
|
||||||
|
String macString = getSignature(requestString.getBytes("UTF-8"), this.key);
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Hawk id=\"");
|
||||||
|
sb.append(this.id);
|
||||||
|
sb.append("\", ");
|
||||||
|
sb.append("ts=\"");
|
||||||
|
sb.append(timestamp);
|
||||||
|
sb.append("\", ");
|
||||||
|
sb.append("nonce=\"");
|
||||||
|
sb.append(nonce);
|
||||||
|
sb.append("\", ");
|
||||||
|
if (payloadHash != null) {
|
||||||
|
sb.append("hash=\"");
|
||||||
|
sb.append(payloadHash);
|
||||||
|
sb.append("\", ");
|
||||||
|
}
|
||||||
|
if (extra != null && extra.length() > 0) {
|
||||||
|
sb.append("ext=\"");
|
||||||
|
sb.append(escapeExtraHeaderAttribute(extra));
|
||||||
|
sb.append("\", ");
|
||||||
|
}
|
||||||
|
sb.append("mac=\"");
|
||||||
|
sb.append(macString);
|
||||||
|
sb.append("\"");
|
||||||
|
|
||||||
|
return new BasicHeader("Authorization", sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape the user-provided extra string for the ext="" header attribute.
|
||||||
|
* <p>
|
||||||
|
* Hawk escapes the header ext="" attribute differently than it does the extra
|
||||||
|
* line in the normalized request string.
|
||||||
|
* <p>
|
||||||
|
* See <a href="https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/browser.js#L385">https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/browser.js#L385</a>.
|
||||||
|
*
|
||||||
|
* @param extra to escape.
|
||||||
|
* @return extra escaped for the ext="" header attribute.
|
||||||
|
*/
|
||||||
|
protected static String escapeExtraHeaderAttribute(String extra) {
|
||||||
|
return extra.replaceAll("\\\\", "\\\\").replaceAll("\"", "\\\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape the user-provided extra string for inserting into the normalized
|
||||||
|
* request string.
|
||||||
|
* <p>
|
||||||
|
* Hawk escapes the header ext="" attribute differently than it does the extra
|
||||||
|
* line in the normalized request string.
|
||||||
|
* <p>
|
||||||
|
* See <a href="https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/crypto.js#L67">https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/crypto.js#L67</a>.
|
||||||
|
*
|
||||||
|
* @param extra to escape.
|
||||||
|
* @return extra escaped for the normalized request string.
|
||||||
|
*/
|
||||||
|
protected static String escapeExtraString(String extra) {
|
||||||
|
return extra.replaceAll("\\\\", "\\\\").replaceAll("\n", "\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the content type with no parameters (pieces following ;).
|
||||||
|
*
|
||||||
|
* @param contentTypeHeader to interrogate.
|
||||||
|
* @return base content type.
|
||||||
|
*/
|
||||||
|
protected static String getBaseContentType(Header contentTypeHeader) {
|
||||||
|
if (contentTypeHeader == null) {
|
||||||
|
throw new IllegalArgumentException("contentTypeHeader must not be null.");
|
||||||
|
}
|
||||||
|
String contentType = contentTypeHeader.getValue();
|
||||||
|
if (contentType == null) {
|
||||||
|
throw new IllegalArgumentException("contentTypeHeader value must not be null.");
|
||||||
|
}
|
||||||
|
int index = contentType.indexOf(";");
|
||||||
|
if (index < 0) {
|
||||||
|
return contentType.trim();
|
||||||
|
}
|
||||||
|
return contentType.substring(0, index).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the SHA-256 hash of a normalized Hawk payload generated from an
|
||||||
|
* HTTP entity.
|
||||||
|
* <p>
|
||||||
|
* <b>Warning:</b> the entity <b>must</b> be repeatable. If it is not, this
|
||||||
|
* code throws an <code>IllegalArgumentException</code>.
|
||||||
|
* <p>
|
||||||
|
* This is under-specified; the code here was reverse engineered from the code
|
||||||
|
* at
|
||||||
|
* <a href="https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/crypto.js#L81">https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/crypto.js#L81</a>.
|
||||||
|
* @param entity to normalize and hash.
|
||||||
|
* @return hash.
|
||||||
|
* @throws IllegalArgumentException if entity is not repeatable.
|
||||||
|
*/
|
||||||
|
protected static byte[] getPayloadHash(HttpEntity entity) throws UnsupportedEncodingException, IOException, NoSuchAlgorithmException {
|
||||||
|
if (!entity.isRepeatable()) {
|
||||||
|
throw new IllegalArgumentException("entity must be repeatable");
|
||||||
|
}
|
||||||
|
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
digest.update(("hawk." + HAWK_HEADER_VERSION + ".payload\n").getBytes("UTF-8"));
|
||||||
|
digest.update(getBaseContentType(entity.getContentType()).getBytes("UTF-8"));
|
||||||
|
digest.update("\n".getBytes("UTF-8"));
|
||||||
|
InputStream stream = entity.getContent();
|
||||||
|
try {
|
||||||
|
int numRead;
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
while (-1 != (numRead = stream.read(buffer))) {
|
||||||
|
if (numRead > 0) {
|
||||||
|
digest.update(buffer, 0, numRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
digest.update("\n".getBytes("UTF-8")); // Trailing newline is specified by Hawk.
|
||||||
|
return digest.digest();
|
||||||
|
} finally {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a normalized Hawk request string. This is under-specified; the
|
||||||
|
* code here was reverse engineered from the code at
|
||||||
|
* <a href="https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/crypto.js#L55">https://github.com/hueniverse/hawk/blob/871cc597973110900467bd3dfb84a3c892f678fb/lib/crypto.js#L55</a>.
|
||||||
|
* <p>
|
||||||
|
* This method trusts its inputs to be valid.
|
||||||
|
*/
|
||||||
|
protected static String getRequestString(HttpUriRequest request, String type, long timestamp, String nonce, String hash, String extra, String app, String dlg) {
|
||||||
|
String method = request.getMethod().toUpperCase(Locale.US);
|
||||||
|
|
||||||
|
URI uri = request.getURI();
|
||||||
|
String host = uri.getHost();
|
||||||
|
|
||||||
|
String path = uri.getRawPath();
|
||||||
|
if (uri.getRawQuery() != null) {
|
||||||
|
path += "?";
|
||||||
|
path += uri.getRawQuery();
|
||||||
|
}
|
||||||
|
if (uri.getRawFragment() != null) {
|
||||||
|
path += "#";
|
||||||
|
path += uri.getRawFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
int port = uri.getPort();
|
||||||
|
String scheme = uri.getScheme();
|
||||||
|
if (port != -1) {
|
||||||
|
} else if ("http".equalsIgnoreCase(scheme)) {
|
||||||
|
port = 80;
|
||||||
|
} else if ("https".equalsIgnoreCase(scheme)) {
|
||||||
|
port = 443;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported URI scheme: " + scheme + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("hawk.");
|
||||||
|
sb.append(HAWK_HEADER_VERSION);
|
||||||
|
sb.append('.');
|
||||||
|
sb.append(type);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append(timestamp);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append(nonce);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append(method);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append(path);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append(host);
|
||||||
|
sb.append('\n');
|
||||||
|
sb.append(port);
|
||||||
|
sb.append('\n');
|
||||||
|
if (hash != null) {
|
||||||
|
sb.append(hash);
|
||||||
|
}
|
||||||
|
sb.append("\n");
|
||||||
|
if (extra != null && extra.length() > 0) {
|
||||||
|
sb.append(escapeExtraString(extra));
|
||||||
|
}
|
||||||
|
sb.append("\n");
|
||||||
|
if (app != null) {
|
||||||
|
sb.append(app);
|
||||||
|
sb.append("\n");
|
||||||
|
if (dlg != null) {
|
||||||
|
sb.append(dlg);
|
||||||
|
}
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static byte[] hmacSha256(byte[] message, byte[] key)
|
||||||
|
throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
|
||||||
|
SecretKeySpec keySpec = new SecretKeySpec(key, HMAC_SHA256_ALGORITHM);
|
||||||
|
|
||||||
|
Mac hasher = Mac.getInstance(HMAC_SHA256_ALGORITHM);
|
||||||
|
hasher.init(keySpec);
|
||||||
|
hasher.update(message);
|
||||||
|
|
||||||
|
return hasher.doFinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a Hawk request string.
|
||||||
|
*
|
||||||
|
* @param requestString to sign.
|
||||||
|
* @param key as <code>String</code>.
|
||||||
|
* @return signature as base-64 encoded string.
|
||||||
|
* @throws InvalidKeyException
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
* @throws UnsupportedEncodingException
|
||||||
|
*/
|
||||||
|
protected static String getSignature(byte[] requestString, byte[] key)
|
||||||
|
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||||
|
return Base64.encodeBase64String(hmacSha256(requestString, key));
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
<div id="addons-header" class="header">
|
<div id="addons-header" class="header">
|
||||||
<div>&aboutAddons.header2;</div>
|
<div>&aboutAddons.header2;</div>
|
||||||
<div id="header-button" role="button" pref="extensions.getAddons.browseAddons" onclick="openLink(this);"/>
|
<div id="header-button" role="button" aria-label="&aboutAddons.browseAll;" pref="extensions.getAddons.browseAddons" onclick="openLink(this);"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="addons-list" class="list" style="display: none;">
|
<div id="addons-list" class="list" style="display: none;">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2560,7 +2560,7 @@ function Tab(aURL, aParams) {
|
||||||
this.viewportExcludesHorizontalMargins = true;
|
this.viewportExcludesHorizontalMargins = true;
|
||||||
this.viewportExcludesVerticalMargins = true;
|
this.viewportExcludesVerticalMargins = true;
|
||||||
this.viewportMeasureCallback = null;
|
this.viewportMeasureCallback = null;
|
||||||
this.lastPageSizeUsedForViewportChange = { width: 0, height: 0 };
|
this.lastPageSizeAfterViewportRemeasure = { width: 0, height: 0 };
|
||||||
this.contentDocumentIsDisplayed = true;
|
this.contentDocumentIsDisplayed = true;
|
||||||
this.pluginDoorhangerTimeout = null;
|
this.pluginDoorhangerTimeout = null;
|
||||||
this.shouldShowPluginDoorhanger = true;
|
this.shouldShowPluginDoorhanger = true;
|
||||||
|
@ -3301,8 +3301,8 @@ Tab.prototype = {
|
||||||
let pageWidth = viewport.pageRight - viewport.pageLeft;
|
let pageWidth = viewport.pageRight - viewport.pageLeft;
|
||||||
let pageHeight = viewport.pageBottom - viewport.pageTop;
|
let pageHeight = viewport.pageBottom - viewport.pageTop;
|
||||||
|
|
||||||
if (Math.abs(pageWidth - this.lastPageSizeUsedForViewportChange.width) >= 0.5 ||
|
if (Math.abs(pageWidth - this.lastPageSizeAfterViewportRemeasure.width) >= 0.5 ||
|
||||||
Math.abs(pageHeight - this.lastPageSizeUsedForViewportChange.height) >= 0.5) {
|
Math.abs(pageHeight - this.lastPageSizeAfterViewportRemeasure.height) >= 0.5) {
|
||||||
this.updateViewportSize(gScreenWidth);
|
this.updateViewportSize(gScreenWidth);
|
||||||
}
|
}
|
||||||
}.bind(this), kViewportRemeasureThrottle);
|
}.bind(this), kViewportRemeasureThrottle);
|
||||||
|
@ -3881,13 +3881,6 @@ Tab.prototype = {
|
||||||
this.viewportExcludesVerticalMargins = false;
|
this.viewportExcludesVerticalMargins = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the page size that was used to calculate the viewport so that we
|
|
||||||
// can verify it's changed when we consider remeasuring in updateViewportForPageSize
|
|
||||||
this.lastPageSizeUsedForViewportChange = {
|
|
||||||
width: pageWidth,
|
|
||||||
height: pageHeight
|
|
||||||
};
|
|
||||||
|
|
||||||
minScale = screenW / pageWidth;
|
minScale = screenW / pageWidth;
|
||||||
}
|
}
|
||||||
minScale = this.clampZoom(minScale);
|
minScale = this.clampZoom(minScale);
|
||||||
|
@ -3916,6 +3909,14 @@ Tab.prototype = {
|
||||||
this.setResolution(zoom, false);
|
this.setResolution(zoom, false);
|
||||||
this.setScrollClampingSize(zoom);
|
this.setScrollClampingSize(zoom);
|
||||||
this.sendViewportUpdate();
|
this.sendViewportUpdate();
|
||||||
|
|
||||||
|
// Store the page size that was used to calculate the viewport so that we
|
||||||
|
// can verify it's changed when we consider remeasuring in updateViewportForPageSize
|
||||||
|
let viewport = this.getViewport();
|
||||||
|
this.lastPageSizeAfterViewportRemeasure = {
|
||||||
|
width: viewport.pageRight - viewport.pageLeft,
|
||||||
|
height: viewport.pageBottom - viewport.pageTop
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
sendViewportMetadata: function sendViewportMetadata() {
|
sendViewportMetadata: function sendViewportMetadata() {
|
||||||
|
|
|
@ -160,7 +160,7 @@ FilePicker.prototype = {
|
||||||
if (this._domWin) {
|
if (this._domWin) {
|
||||||
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
|
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
|
||||||
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||||
callerWin = winUtils.enterModalStateWithWindow();
|
winUtils.enterModalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._promptActive = true;
|
this._promptActive = true;
|
||||||
|
|
|
@ -152,11 +152,10 @@ InternalPrompt.prototype = {
|
||||||
* for a response
|
* for a response
|
||||||
*/
|
*/
|
||||||
showPrompt: function showPrompt(aPrompt) {
|
showPrompt: function showPrompt(aPrompt) {
|
||||||
let callerWin;
|
|
||||||
if (this._domWin) {
|
if (this._domWin) {
|
||||||
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
|
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
|
||||||
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||||
callerWin = winUtils.enterModalStateWithWindow();
|
winUtils.enterModalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
let retval = null;
|
let retval = null;
|
||||||
|
@ -171,7 +170,7 @@ InternalPrompt.prototype = {
|
||||||
|
|
||||||
if (this._domWin) {
|
if (this._domWin) {
|
||||||
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||||
winUtils.leaveModalStateWithWindow(callerWin);
|
winUtils.leaveModalState();
|
||||||
PromptUtils.fireDialogEvent(this._domWin, "DOMModalDialogClosed");
|
PromptUtils.fireDialogEvent(this._domWin, "DOMModalDialogClosed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<!ENTITY aboutAddons.title2 "Add-ons">
|
<!ENTITY aboutAddons.title2 "Add-ons">
|
||||||
<!ENTITY aboutAddons.header2 "Your Add-ons">
|
<!ENTITY aboutAddons.header2 "Your Add-ons">
|
||||||
<!ENTITY aboutAddons.options "Options">
|
<!ENTITY aboutAddons.options "Options">
|
||||||
|
<!ENTITY aboutAddons.browseAll "Browse all Firefox Add-ons">
|
||||||
|
|
||||||
<!ENTITY addonAction.enable "Enable">
|
<!ENTITY addonAction.enable "Enable">
|
||||||
<!ENTITY addonAction.disable "Disable">
|
<!ENTITY addonAction.disable "Disable">
|
||||||
|
|
|
@ -115,6 +115,7 @@ sync/net/BasicAuthHeaderProvider.java
|
||||||
sync/net/BrowserIDAuthHeaderProvider.java
|
sync/net/BrowserIDAuthHeaderProvider.java
|
||||||
sync/net/ConnectionMonitorThread.java
|
sync/net/ConnectionMonitorThread.java
|
||||||
sync/net/HandleProgressException.java
|
sync/net/HandleProgressException.java
|
||||||
|
sync/net/HawkAuthHeaderProvider.java
|
||||||
sync/net/HMACAuthHeaderProvider.java
|
sync/net/HMACAuthHeaderProvider.java
|
||||||
sync/net/HttpResponseObserver.java
|
sync/net/HttpResponseObserver.java
|
||||||
sync/net/Resource.java
|
sync/net/Resource.java
|
||||||
|
|
|
@ -913,6 +913,9 @@ pref("network.protocol-handler.external.moz-icon", false);
|
||||||
// to override this value.
|
// to override this value.
|
||||||
pref("network.protocol-handler.expose-all", true);
|
pref("network.protocol-handler.expose-all", true);
|
||||||
|
|
||||||
|
// Warning for about:networking page
|
||||||
|
pref("network.warnOnAboutNetworking", true);
|
||||||
|
|
||||||
// Example: make IMAP an exposed protocol
|
// Example: make IMAP an exposed protocol
|
||||||
// pref("network.protocol-handler.expose.imap", true);
|
// pref("network.protocol-handler.expose.imap", true);
|
||||||
|
|
||||||
|
|
|
@ -700,11 +700,11 @@ function test_info() {
|
||||||
startMs = start.getTime() - 1000;
|
startMs = start.getTime() - 1000;
|
||||||
stopMs = stop.getTime() + 1000;
|
stopMs = stop.getTime() + 1000;
|
||||||
|
|
||||||
birth = stat.creationDate;
|
let birth = stat.creationDate;
|
||||||
ok(birth.getTime() <= stopMs,
|
ok(birth.getTime() <= stopMs,
|
||||||
"test_info: file 2 was created between the start of the test and now - " + start + ", " + stop + ", " + birth);
|
"test_info: file 2 was created between the start of the test and now - " + start + ", " + stop + ", " + birth);
|
||||||
|
|
||||||
let access = stat.lastModificationDate;
|
let access = stat.lastAccessDate;
|
||||||
ok(access.getTime() >= startMs
|
ok(access.getTime() >= startMs
|
||||||
&& access.getTime() <= stopMs,
|
&& access.getTime() <= stopMs,
|
||||||
"test_info: file 2 was accessed between the start of the test and now - " + start + ", " + stop + ", " + access);
|
"test_info: file 2 was accessed between the start of the test and now - " + start + ", " + stop + ", " + access);
|
||||||
|
|
|
@ -21,13 +21,17 @@ Login Manager test: username/password prompts
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
/** Test for Login Manager: username / password prompts. **/
|
/** Test for Login Manager: username / password prompts. **/
|
||||||
var pwmgr, ioService
|
var pwmgr, ioService, observerService;
|
||||||
var tmplogin, login1, login2A, login2B, login2C, login2D, login2E, login3A, login3B, login4, proxyLogin;
|
var tmplogin, login1, login2A, login2B, login2C, login2D, login2E, login3A, login3B, login4, proxyLogin;
|
||||||
var mozproxy, proxiedHost = "http://mochi.test:8888";
|
var mozproxy, proxiedHost = "http://mochi.test:8888";
|
||||||
var proxyChannel;
|
var proxyChannel;
|
||||||
var testNum = 1;
|
var testNum = 1;
|
||||||
|
|
||||||
function initLogins(pi) {
|
function initLogins(pi) {
|
||||||
|
observerService = Cc["@mozilla.org/observer-service;1"].
|
||||||
|
getService(Ci.nsIObserverService);
|
||||||
|
observerService.addObserver(storageObserver, "passwordmgr-storage-changed", false);
|
||||||
|
|
||||||
pwmgr = Cc["@mozilla.org/login-manager;1"].
|
pwmgr = Cc["@mozilla.org/login-manager;1"].
|
||||||
getService(Ci.nsILoginManager);
|
getService(Ci.nsILoginManager);
|
||||||
ioService = Cc["@mozilla.org/network/io-service;1"].
|
ioService = Cc["@mozilla.org/network/io-service;1"].
|
||||||
|
@ -96,6 +100,8 @@ function initLogins(pi) {
|
||||||
function finishTest() {
|
function finishTest() {
|
||||||
try {
|
try {
|
||||||
ok(true, "finishTest removing testing logins...");
|
ok(true, "finishTest removing testing logins...");
|
||||||
|
observerService.removeObserver(storageObserver, "passwordmgr-storage-changed");
|
||||||
|
|
||||||
dumpLogins(pwmgr);
|
dumpLogins(pwmgr);
|
||||||
ok(true, "removing login 1...");
|
ok(true, "removing login 1...");
|
||||||
pwmgr.removeLogin(login1);
|
pwmgr.removeLogin(login1);
|
||||||
|
@ -231,10 +237,6 @@ var storageObserver = SpecialPowers.wrapCallbackObject({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var observerService = Cc["@mozilla.org/observer-service;1"].
|
|
||||||
getService(Ci.nsIObserverService);
|
|
||||||
observerService.addObserver(storageObserver, "passwordmgr-storage-changed", false);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handleDialog
|
* handleDialog
|
||||||
*
|
*
|
||||||
|
|
|
@ -399,7 +399,7 @@ function openTabPrompt(domWin, tabPrompt, args) {
|
||||||
|
|
||||||
let winUtils = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
|
let winUtils = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
.getInterface(Ci.nsIDOMWindowUtils);
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
let callerWin = winUtils.enterModalStateWithWindow();
|
winUtils.enterModalState();
|
||||||
|
|
||||||
// We provide a callback so the prompt can close itself. We don't want to
|
// We provide a callback so the prompt can close itself. We don't want to
|
||||||
// wait for this event loop to return... Otherwise the presence of other
|
// wait for this event loop to return... Otherwise the presence of other
|
||||||
|
@ -413,7 +413,7 @@ function openTabPrompt(domWin, tabPrompt, args) {
|
||||||
if (newPrompt)
|
if (newPrompt)
|
||||||
tabPrompt.removePrompt(newPrompt);
|
tabPrompt.removePrompt(newPrompt);
|
||||||
|
|
||||||
winUtils.leaveModalStateWithWindow(callerWin);
|
winUtils.leaveModalState();
|
||||||
|
|
||||||
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
|
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,7 +456,7 @@ this.PageThumbs = {
|
||||||
let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
|
let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
|
||||||
.getService(Ci.nsIScreenManager);
|
.getService(Ci.nsIScreenManager);
|
||||||
let left = {}, top = {}, width = {}, height = {};
|
let left = {}, top = {}, width = {}, height = {};
|
||||||
screenManager.primaryScreen.GetRect(left, top, width, height);
|
screenManager.primaryScreen.GetRectDisplayPix(left, top, width, height);
|
||||||
this._thumbnailWidth = Math.round(width.value / 3);
|
this._thumbnailWidth = Math.round(width.value / 3);
|
||||||
this._thumbnailHeight = Math.round(height.value / 3);
|
this._thumbnailHeight = Math.round(height.value / 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -713,6 +713,7 @@ nsUrlClassifierDBServiceWorker::CacheCompletions(CacheResultArray *results)
|
||||||
for (uint32_t table = 0; table < tables.Length(); table++) {
|
for (uint32_t table = 0; table < tables.Length(); table++) {
|
||||||
if (tables[table].Equals(resultsPtr->ElementAt(i).table)) {
|
if (tables[table].Equals(resultsPtr->ElementAt(i).table)) {
|
||||||
activeTable = true;
|
activeTable = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (activeTable) {
|
if (activeTable) {
|
||||||
|
|
|
@ -669,7 +669,7 @@
|
||||||
<constructor>
|
<constructor>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
try {
|
try {
|
||||||
if (!this.hasAttribute("disablehistory")) {
|
if (this.docShell && !this.hasAttribute("disablehistory")) {
|
||||||
var os = Components.classes["@mozilla.org/observer-service;1"]
|
var os = Components.classes["@mozilla.org/observer-service;1"]
|
||||||
.getService(Components.interfaces.nsIObserverService);
|
.getService(Components.interfaces.nsIObserverService);
|
||||||
os.addObserver(this, "browser:purge-session-history", false);
|
os.addObserver(this, "browser:purge-session-history", false);
|
||||||
|
@ -678,7 +678,7 @@
|
||||||
Components.classes["@mozilla.org/browser/shistory;1"]
|
Components.classes["@mozilla.org/browser/shistory;1"]
|
||||||
.createInstance(Components.interfaces.nsISHistory);
|
.createInstance(Components.interfaces.nsISHistory);
|
||||||
// enable global history if we weren't told otherwise
|
// enable global history if we weren't told otherwise
|
||||||
if (this.docShell && !this.hasAttribute("disableglobalhistory"))
|
if (!this.hasAttribute("disableglobalhistory"))
|
||||||
this.docShell.useGlobalHistory = true;
|
this.docShell.useGlobalHistory = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1544,30 +1544,37 @@ ThreadActor.prototype = {
|
||||||
if (!aPool) {
|
if (!aPool) {
|
||||||
aPool = this._pausePool;
|
aPool = this._pausePool;
|
||||||
}
|
}
|
||||||
let type = typeof(aValue);
|
|
||||||
|
|
||||||
if (type === "string" && this._stringIsLong(aValue)) {
|
switch (typeof aValue) {
|
||||||
return this.longStringGrip(aValue, aPool);
|
case "boolean":
|
||||||
|
return aValue;
|
||||||
|
case "string":
|
||||||
|
if (this._stringIsLong(aValue)) {
|
||||||
|
return this.longStringGrip(aValue, aPool);
|
||||||
|
}
|
||||||
|
return aValue;
|
||||||
|
case "number":
|
||||||
|
if (aValue === Infinity) {
|
||||||
|
return { type: "Infinity" };
|
||||||
|
} else if (aValue === -Infinity) {
|
||||||
|
return { type: "-Infinity" };
|
||||||
|
} else if (Number.isNaN(aValue)) {
|
||||||
|
return { type: "NaN" };
|
||||||
|
} else if (!aValue && 1 / aValue === -Infinity) {
|
||||||
|
return { type: "-0" };
|
||||||
|
}
|
||||||
|
return aValue;
|
||||||
|
case "undefined":
|
||||||
|
return { type: "undefined" };
|
||||||
|
case "object":
|
||||||
|
if (aValue === null) {
|
||||||
|
return { type: "null" };
|
||||||
|
}
|
||||||
|
return this.objectGrip(aValue, aPool);
|
||||||
|
default:
|
||||||
|
dbg_assert(false, "Failed to provide a grip for: " + aValue);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === "boolean" || type === "string" || type === "number") {
|
|
||||||
return aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aValue === null) {
|
|
||||||
return { type: "null" };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aValue === undefined) {
|
|
||||||
return { type: "undefined" }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof(aValue) === "object") {
|
|
||||||
return this.objectGrip(aValue, aPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg_assert(false, "Failed to provide a grip for: " + aValue);
|
|
||||||
return null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -558,35 +558,41 @@ function serializeCompletionValue(aType, { value }) {
|
||||||
* A primitive value or a grip object.
|
* A primitive value or a grip object.
|
||||||
*/
|
*/
|
||||||
function createValueGrip(aValue, aUseDescriptor) {
|
function createValueGrip(aValue, aUseDescriptor) {
|
||||||
let type = typeof aValue;
|
switch (typeof aValue) {
|
||||||
|
case "boolean":
|
||||||
if (type === "string" && aValue.length >= DebuggerServer.LONG_STRING_LENGTH) {
|
return aValue;
|
||||||
return {
|
case "string":
|
||||||
type: "longString",
|
if (aValue.length >= DebuggerServer.LONG_STRING_LENGTH) {
|
||||||
initial: aValue.substring(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH),
|
return {
|
||||||
length: aValue.length
|
type: "longString",
|
||||||
};
|
initial: aValue.substring(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH),
|
||||||
|
length: aValue.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return aValue;
|
||||||
|
case "number":
|
||||||
|
if (aValue === Infinity) {
|
||||||
|
return { type: "Infinity" };
|
||||||
|
} else if (aValue === -Infinity) {
|
||||||
|
return { type: "-Infinity" };
|
||||||
|
} else if (Number.isNaN(aValue)) {
|
||||||
|
return { type: "NaN" };
|
||||||
|
} else if (!aValue && 1 / aValue === -Infinity) {
|
||||||
|
return { type: "-0" };
|
||||||
|
}
|
||||||
|
return aValue;
|
||||||
|
case "undefined":
|
||||||
|
return { type: "undefined" };
|
||||||
|
case "object":
|
||||||
|
if (aValue === null) {
|
||||||
|
return { type: "null" };
|
||||||
|
}
|
||||||
|
return aUseDescriptor ? objectDescriptor(aValue) : objectGrip(aValue);
|
||||||
|
default:
|
||||||
|
reportException("TraceActor",
|
||||||
|
new Error("Failed to provide a grip for: " + aValue));
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === "boolean" || type === "string" || type === "number") {
|
|
||||||
return aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aValue === null) {
|
|
||||||
return { type: "null" };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aValue === undefined) {
|
|
||||||
return { type: "undefined" };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof(aValue) === "object") {
|
|
||||||
return aUseDescriptor ? objectDescriptor(aValue) : objectGrip(aValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
reportException("TraceActor",
|
|
||||||
new Error("Failed to provide a grip for: " + aValue));
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
var gDebuggee;
|
||||||
|
var gClient;
|
||||||
|
var gThreadClient;
|
||||||
|
|
||||||
|
function run_test()
|
||||||
|
{
|
||||||
|
initTestDebuggerServer();
|
||||||
|
gDebuggee = addTestGlobal("test-grips");
|
||||||
|
gDebuggee.eval(function stopMe(arg1) {
|
||||||
|
debugger;
|
||||||
|
}.toString());
|
||||||
|
|
||||||
|
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||||
|
gClient.connect(function() {
|
||||||
|
attachTestTabAndResume(gClient, "test-grips", function(aResponse, aTabClient, aThreadClient) {
|
||||||
|
gThreadClient = aThreadClient;
|
||||||
|
test_object_grip();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
do_test_pending();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_object_grip()
|
||||||
|
{
|
||||||
|
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
|
||||||
|
let args = aPacket.frame.arguments;
|
||||||
|
|
||||||
|
do_check_eq(args[0].class, "Object");
|
||||||
|
|
||||||
|
let objClient = gThreadClient.pauseGrip(args[0]);
|
||||||
|
objClient.getPrototypeAndProperties(function(aResponse) {
|
||||||
|
do_check_eq(aResponse.ownProperties.a.configurable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.a.enumerable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.a.writable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.a.value.type, "Infinity");
|
||||||
|
|
||||||
|
do_check_eq(aResponse.ownProperties.b.configurable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.b.enumerable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.b.writable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.b.value.type, "-Infinity");
|
||||||
|
|
||||||
|
do_check_eq(aResponse.ownProperties.c.configurable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.c.enumerable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.c.writable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.c.value.type, "NaN");
|
||||||
|
|
||||||
|
do_check_eq(aResponse.ownProperties.d.configurable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.d.enumerable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.d.writable, true);
|
||||||
|
do_check_eq(aResponse.ownProperties.d.value.type, "-0");
|
||||||
|
|
||||||
|
gThreadClient.resume(function() {
|
||||||
|
finishClient(gClient);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
gDebuggee.eval("stopMe({ a: Infinity, b: -Infinity, c: NaN, d: -0 })");
|
||||||
|
}
|
||||||
|
|
|
@ -64,6 +64,22 @@ function test_enter_exit_frame()
|
||||||
'return value should have property "arr"');
|
'return value should have property "arr"');
|
||||||
do_check_eq(typeof obj.ownProperties.arr.value, "object",
|
do_check_eq(typeof obj.ownProperties.arr.value, "object",
|
||||||
'return value property "arr" should be a grip');
|
'return value property "arr" should be a grip');
|
||||||
|
do_check_eq(typeof obj.ownProperties.inf, "object",
|
||||||
|
'return value should have property "inf"');
|
||||||
|
do_check_eq(typeof obj.ownProperties.inf.value, "object",
|
||||||
|
'return value property "inf" should be a grip');
|
||||||
|
do_check_eq(typeof obj.ownProperties.ninf, "object",
|
||||||
|
'return value should have property "ninf"');
|
||||||
|
do_check_eq(typeof obj.ownProperties.ninf.value, "object",
|
||||||
|
'return value property "ninf" should be a grip');
|
||||||
|
do_check_eq(typeof obj.ownProperties.nan, "object",
|
||||||
|
'return value should have property "nan"');
|
||||||
|
do_check_eq(typeof obj.ownProperties.nan.value, "object",
|
||||||
|
'return value property "nan" should be a grip');
|
||||||
|
do_check_eq(typeof obj.ownProperties.nzero, "object",
|
||||||
|
'return value should have property "nzero"');
|
||||||
|
do_check_eq(typeof obj.ownProperties.nzero.value, "object",
|
||||||
|
'return value property "nzero" should be a grip');
|
||||||
|
|
||||||
do_check_eq(obj.prototype.type, "object");
|
do_check_eq(obj.prototype.type, "object");
|
||||||
do_check_eq(obj.ownProperties.num.value, 25);
|
do_check_eq(obj.ownProperties.num.value, 25);
|
||||||
|
@ -75,6 +91,10 @@ function test_enter_exit_frame()
|
||||||
do_check_eq(obj.ownProperties.obj.value.class, "Object");
|
do_check_eq(obj.ownProperties.obj.value.class, "Object");
|
||||||
do_check_eq(obj.ownProperties.arr.value.type, "object");
|
do_check_eq(obj.ownProperties.arr.value.type, "object");
|
||||||
do_check_eq(obj.ownProperties.arr.value.class, "Array");
|
do_check_eq(obj.ownProperties.arr.value.class, "Array");
|
||||||
|
do_check_eq(obj.ownProperties.inf.value.type, "Infinity");
|
||||||
|
do_check_eq(obj.ownProperties.ninf.value.type, "-Infinity");
|
||||||
|
do_check_eq(obj.ownProperties.nan.value.type, "NaN");
|
||||||
|
do_check_eq(obj.ownProperties.nzero.value.type, "-0");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -107,7 +127,11 @@ function eval_code()
|
||||||
undef: undefined,
|
undef: undefined,
|
||||||
nil: null,
|
nil: null,
|
||||||
obj: obj,
|
obj: obj,
|
||||||
arr: [1,2,3,4,5]
|
arr: [1,2,3,4,5],
|
||||||
|
inf: Infinity,
|
||||||
|
ninf: -Infinity,
|
||||||
|
nan: NaN,
|
||||||
|
nzero: -0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
foo();
|
foo();
|
||||||
|
|
|
@ -120,6 +120,7 @@ reason = bug 820380
|
||||||
[test_objectgrips-05.js]
|
[test_objectgrips-05.js]
|
||||||
[test_objectgrips-06.js]
|
[test_objectgrips-06.js]
|
||||||
[test_objectgrips-07.js]
|
[test_objectgrips-07.js]
|
||||||
|
[test_objectgrips-08.js]
|
||||||
[test_interrupt.js]
|
[test_interrupt.js]
|
||||||
[test_stepping-01.js]
|
[test_stepping-01.js]
|
||||||
[test_stepping-02.js]
|
[test_stepping-02.js]
|
||||||
|
|
|
@ -317,29 +317,36 @@ let WebConsoleUtils = {
|
||||||
*/
|
*/
|
||||||
createValueGrip: function WCU_createValueGrip(aValue, aObjectWrapper)
|
createValueGrip: function WCU_createValueGrip(aValue, aObjectWrapper)
|
||||||
{
|
{
|
||||||
let type = typeof(aValue);
|
switch (typeof aValue) {
|
||||||
switch (type) {
|
|
||||||
case "boolean":
|
case "boolean":
|
||||||
case "number":
|
|
||||||
return aValue;
|
return aValue;
|
||||||
case "string":
|
case "string":
|
||||||
return aObjectWrapper(aValue);
|
return aObjectWrapper(aValue);
|
||||||
case "object":
|
case "number":
|
||||||
case "function":
|
if (aValue === Infinity) {
|
||||||
if (aValue) {
|
return { type: "Infinity" };
|
||||||
return aObjectWrapper(aValue);
|
|
||||||
}
|
}
|
||||||
default:
|
else if (aValue === -Infinity) {
|
||||||
|
return { type: "-Infinity" };
|
||||||
|
}
|
||||||
|
else if (Number.isNaN(aValue)) {
|
||||||
|
return { type: "NaN" };
|
||||||
|
}
|
||||||
|
else if (!aValue && 1 / aValue === -Infinity) {
|
||||||
|
return { type: "-0" };
|
||||||
|
}
|
||||||
|
return aValue;
|
||||||
|
case "undefined":
|
||||||
|
return { type: "undefined" };
|
||||||
|
case "object":
|
||||||
if (aValue === null) {
|
if (aValue === null) {
|
||||||
return { type: "null" };
|
return { type: "null" };
|
||||||
}
|
}
|
||||||
|
case "function":
|
||||||
if (aValue === undefined) {
|
return aObjectWrapper(aValue);
|
||||||
return { type: "undefined" };
|
default:
|
||||||
}
|
Cu.reportError("Failed to provide a grip for value of " + typeof aValue
|
||||||
|
+ ": " + aValue);
|
||||||
Cu.reportError("Failed to provide a grip for value of " + type + ": " +
|
|
||||||
aValue);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -37,6 +37,8 @@ public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init a standard gecko event for this widget.
|
* Init a standard gecko event for this widget.
|
||||||
|
* @param aEvent the event to initialize.
|
||||||
|
* @param aPoint message position in physical coordinates.
|
||||||
*/
|
*/
|
||||||
virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) = 0;
|
virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) = 0;
|
||||||
|
|
||||||
|
|
|
@ -997,16 +997,16 @@ void MetroWidget::UserActivity()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitEvent assumes physical coordinates and is used by shared win32 code. Do
|
||||||
|
// not hand winrt event coordinates to this routine.
|
||||||
void
|
void
|
||||||
MetroWidget::InitEvent(nsGUIEvent& event, nsIntPoint* aPoint)
|
MetroWidget::InitEvent(nsGUIEvent& event, nsIntPoint* aPoint)
|
||||||
{
|
{
|
||||||
if (!aPoint) {
|
if (!aPoint) {
|
||||||
event.refPoint.x = event.refPoint.y = 0;
|
event.refPoint.x = event.refPoint.y = 0;
|
||||||
} else {
|
} else {
|
||||||
CSSIntPoint cssPoint(aPoint->x, aPoint->y);
|
event.refPoint.x = aPoint->x;
|
||||||
LayoutDeviceIntPoint layoutDeviceIntPoint = CSSIntPointToLayoutDeviceIntPoint(cssPoint);
|
event.refPoint.y = aPoint->y;
|
||||||
event.refPoint.x = layoutDeviceIntPoint.x;
|
|
||||||
event.refPoint.y = layoutDeviceIntPoint.y;
|
|
||||||
}
|
}
|
||||||
event.time = ::GetMessageTime();
|
event.time = ::GetMessageTime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,10 +69,12 @@ public:
|
||||||
static HWND GetICoreWindowHWND() { return sICoreHwnd; }
|
static HWND GetICoreWindowHWND() { return sICoreHwnd; }
|
||||||
|
|
||||||
// nsWindowBase
|
// nsWindowBase
|
||||||
virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) MOZ_OVERRIDE;
|
|
||||||
virtual bool DispatchWindowEvent(nsGUIEvent* aEvent) MOZ_OVERRIDE;
|
virtual bool DispatchWindowEvent(nsGUIEvent* aEvent) MOZ_OVERRIDE;
|
||||||
virtual bool IsTopLevelWidget() MOZ_OVERRIDE { return true; }
|
virtual bool IsTopLevelWidget() MOZ_OVERRIDE { return true; }
|
||||||
virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) MOZ_OVERRIDE { return nullptr; }
|
virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) MOZ_OVERRIDE { return nullptr; }
|
||||||
|
// InitEvent assumes physical coordinates and is used by shared win32 code. Do
|
||||||
|
// not hand winrt event coordinates to this routine.
|
||||||
|
virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) MOZ_OVERRIDE;
|
||||||
|
|
||||||
// nsBaseWidget
|
// nsBaseWidget
|
||||||
virtual CompositorParent* NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight);
|
virtual CompositorParent* NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче