This commit is contained in:
Ryan VanderMeulen 2013-08-12 17:43:24 -04:00
Родитель b7704a2398 2fb3fd7e55
Коммит 9339de4f3f
62 изменённых файлов: 1061 добавлений и 705 удалений

Просмотреть файл

@ -141,6 +141,9 @@ exports.testTabPropertiesInNewWindow = function(test) {
exports.testTabPropertiesInSameWindow = function(test) {
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;
function onReadyOrLoad (tab) {
if (count++) {
@ -156,7 +159,7 @@ exports.testTabPropertiesInSameWindow = function(test) {
test.assertEqual(tab.url, url, "URL of the new tab matches");
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.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.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.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.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.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
// items the same label.
function TestHelper(test) {
// default waitUntilDone timeout is 10s, which is too short on the win7
// buildslave
test.waitUntilDone(30*1000);
test.waitUntilDone();
this.test = test;
this.loaders = [];
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.nntp", false);
// Warning for about:networking page
pref("network.warnOnAboutNetworking", true);
pref("accessibility.typeaheadfind", false);
pref("accessibility.typeaheadfind.timeout", 5000);
pref("accessibility.typeaheadfind.linksonly", false);

Просмотреть файл

@ -42,16 +42,9 @@ SocialUI = {
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
SocialChatBar.init();
SocialMark.init();
SocialShare.init();
SocialMenu.init();
SocialToolbar.init();
SocialSidebar.init();
if (!Social.initialized) {
Social.init();
} else {
} else if (Social.enabled) {
// social was previously initialized, so it's not going to notify us of
// anything, so handle that now.
this.observe(null, "social:providers-changed", null);
@ -346,8 +339,6 @@ SocialUI = {
}
SocialChatBar = {
init: function() {
},
closeWindows: function() {
// close all windows of type Social:Chat
let windows = Services.wm.getEnumerator("Social:Chat");
@ -586,9 +577,6 @@ SocialFlyout = {
}
SocialShare = {
// Called once, after window load, when the Social.provider object is initialized
init: function() {},
get panel() {
return document.getElementById("social-share-panel");
},
@ -846,10 +834,6 @@ SocialShare = {
};
SocialMark = {
// Called once, after window load, when the Social.provider object is initialized
init: function SSB_init() {
},
get button() {
return document.getElementById("social-mark-button");
},
@ -925,9 +909,6 @@ SocialMark = {
};
SocialMenu = {
init: function SocialMenu_init() {
},
populate: function SocialMenu_populate() {
let submenu = document.getElementById("menu_social-statusarea-popup");
let ambientMenuItems = submenu.getElementsByClassName("ambient-menuitem");
@ -961,8 +942,10 @@ SocialMenu = {
SocialToolbar = {
// Called once, after window load, when the Social.provider object is
// initialized.
init: function SocialToolbar_init() {
get _dynamicResizer() {
delete this._dynamicResizer;
this._dynamicResizer = new DynamicResizeWatcher();
return this._dynamicResizer;
},
update: function() {
@ -1299,14 +1282,6 @@ SocialToolbar = {
}
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.
get canShow() {
return SocialUI.enabled && Social.provider.sidebarURL;
@ -1367,6 +1342,9 @@ SocialSidebar = {
// Make sure the right sidebar URL is loaded
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);
PopupNotifications.locationChange(sbrowser);
}

Просмотреть файл

@ -35,6 +35,10 @@ function testSimpleCall() {
let localVar3 = localScope.addItem("localVar3");
let localVar4 = localScope.addItem("localVar4");
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);
localVar1.setGrip(true);
@ -43,6 +47,10 @@ function testSimpleCall() {
localVar3.setGrip({ "type": "undefined" });
localVar4.setGrip({ "type": "null" });
localVar5.setGrip({ "type": "object", "class": "Object" });
localVar6.setGrip({ "type": "Infinity" });
localVar7.setGrip({ "type": "-Infinity" });
localVar8.setGrip({ "type": "NaN" });
localVar9.setGrip({ "type": "-0" });
localVar5.addItems({
"someProp0": { "value": 42, "enumerable": true },
@ -54,15 +62,16 @@ function testSimpleCall() {
"value": { "type": "object", "class": "Object" },
"enumerable": true
},
"someUndefined": {
"value": { "type": "undefined" },
"enumerable": true
},
"someAccessor": {
"someProp6": { "value": { "type": "Infinity" }, "enumerable": true },
"someProp7": { "value": { "type": "-Infinity" }, "enumerable": true },
"someProp8": { "value": { "type": "NaN" }, "enumerable": true },
"someProp9": { "value": { "type": "undefined" }, "enumerable": true },
"someProp10": { "value": { "type": "-0" }, "enumerable": true },
"someProp11": {
"get": { "type": "object", "class": "Function" },
"set": { "type": "undefined" },
"enumerable": true
}
},
});
localVar5.get("someProp5").addItems({
@ -75,15 +84,16 @@ function testSimpleCall() {
"value": { "type": "object", "class": "Object" },
"enumerable": true
},
"someUndefined": {
"value": { "type": "undefined" },
"enumerable": true
},
"someAccessor": {
"someProp6": { "value": { "type": "Infinity" }, "enumerable": true },
"someProp7": { "value": { "type": "-Infinity" }, "enumerable": true },
"someProp8": { "value": { "type": "NaN" }, "enumerable": true },
"someProp9": { "value": { "type": "undefined" }, "enumerable": true },
"someProp10": { "value": { "type": "-0" }, "enumerable": true },
"someProp11": {
"get": { "type": "object", "class": "Function" },
"set": { "type": "undefined" },
"enumerable": true
}
},
});
windowVar.setGrip({ "type": "object", "class": "Window" });
@ -110,6 +120,10 @@ function testSimpleCall() {
ok(localVar3, "The localVar3 hasn't been created correctly.");
ok(localVar4, "The localVar4 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) {
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) {
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.");
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.");
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.");
is(windowVar.target.querySelector(".value").getAttribute("value"), "Window",
@ -145,40 +159,64 @@ function testSimpleCall() {
"The grip information for the localVar4 wasn't set correctly.");
is(localVar5.target.querySelector(".value").getAttribute("value"), "Object",
"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",
"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",
"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\"",
"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",
"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",
"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",
"The grip information for the localVar5 wasn't set correctly.");
is(localVar5.get("someUndefined").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the someUndefined wasn't set correctly.");
is(localVar5.get("someAccessor").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the someAccessor wasn't set correctly.");
"The grip information for the someProp5 wasn't set correctly.");
is(localVar5.get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the someProp6 wasn't set correctly.");
is(localVar5.get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
"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",
"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",
"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\"",
"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",
"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",
"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",
"The grip information for the sub-localVar5 wasn't set correctly.");
is(localVar5.get("someProp5").get("someUndefined").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the sub-someUndefined wasn't set correctly.");
is(localVar5.get("someProp5").get("someAccessor").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the sub-someAccessor wasn't set correctly.");
"The grip information for the sub-someProp5 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the sub-someProp6 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
"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() {
closeDebuggerAndFinish();

Просмотреть файл

@ -3005,9 +3005,16 @@ VariablesView.isPrimitive = function(aDescriptor) {
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;
if (type == "undefined" || type == "null" || type == "longString") {
if (type == "undefined" ||
type == "null" ||
type == "Infinity" ||
type == "-Infinity" ||
type == "NaN" ||
type == "-0" ||
type == "longString") {
return true;
}
@ -3054,9 +3061,12 @@ VariablesView.isFalsy = function(aDescriptor) {
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;
if (type == "undefined" || type == "null") {
if (type == "undefined" ||
type == "null" ||
type == "NaN" ||
type == "-0") {
return true;
}
@ -3082,16 +3092,38 @@ VariablesView.isVariable = function(aValue) {
* The value's grip.
*/
VariablesView.getGrip = function(aValue) {
if (aValue === undefined) {
return { type: "undefined" };
switch (typeof aValue) {
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") {
switch (aGrip.type) {
case "undefined":
return "undefined";
case "null":
return "null";
case "NaN":
case "Infinity":
case "-Infinity":
case "-0":
return aGrip.type;
case "longString":
return "\"" + aGrip.initial + "\"";
default:
if (!aConciseFlag) {
return "[" + aGrip.type + " " + aGrip.class + "]";
} else {
return aGrip.class;
}
}
} else {
switch (typeof aGrip) {
case "string":
return "\"" + aGrip + "\"";
case "boolean":
return aGrip ? "true" : "false";
return aGrip.class;
}
}
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";
case "null":
return "token-null";
case "Infinity":
case "-Infinity":
case "NaN":
case "-0":
return "token-number";
case "longString":
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
// Automatically submit crash reports
#ifdef RELEASE_BUILD
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?
pref("app.crashreporter.prompted", false);

Просмотреть файл

@ -28,7 +28,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "unescapeService",
function prefObserver(subject, topic, data) {
let enable = Services.prefs.getBoolPref("social.enabled");
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) {
Social.provider = null;
}
@ -83,7 +88,7 @@ function promiseGetAnnotation(aURI) {
this.Social = {
initialized: false,
lastEventReceived: 0,
providers: null,
providers: [],
_disabledForSafeMode: false,
get _currentProviderPref() {
@ -151,10 +156,12 @@ this.Social = {
}
this.initialized = true;
// Retrieve the current set of providers, and set the current provider.
SocialService.getOrderedProviderList(function (providers) {
this._updateProviderCache(providers);
}.bind(this));
if (SocialService.enabled) {
// Retrieve the current set of providers, and set the current provider.
SocialService.getOrderedProviderList(function (providers) {
this._updateProviderCache(providers);
}.bind(this));
}
// Register an observer for changes to the provider list
SocialService.registerProviderListener(function providerListener(topic, data) {
@ -168,17 +175,13 @@ this.Social = {
// a provider has self-updated its manifest, we need to update our
// cache and possibly reload if it was the current provider.
let provider = data;
SocialService.getOrderedProviderList(function(providers) {
Social._updateProviderCache(providers);
Services.obs.notifyObservers(null, "social:providers-changed", null);
// if we need a reload, do it now
if (provider.enabled) {
Social.enabled = false;
Services.tm.mainThread.dispatch(function() {
Social.enabled = true;
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
}
});
// if we need a reload, do it now
if (provider.enabled) {
Social.enabled = false;
Services.tm.mainThread.dispatch(function() {
Social.enabled = true;
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
}
}
}.bind(this));
},

Просмотреть файл

@ -2118,36 +2118,7 @@ nsDOMWindowUtils::LeaveModalState()
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
window->LeaveModalState(nullptr);
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);
window->LeaveModalState();
return NS_OK;
}

Просмотреть файл

@ -239,6 +239,10 @@
#include "mozilla/dom/SpeechSynthesis.h"
#endif
#ifdef MOZ_JSDEBUGGER
#include "jsdIDebuggerService.h"
#endif
// Apple system headers seem to have a check() macro. <sigh>
#ifdef check
#undef check
@ -5867,9 +5871,9 @@ nsGlobalWindow::Print()
printSettingsService->GetNewPrintSettings(getter_AddRefs(printSettings));
}
nsCOMPtr<nsIDOMWindow> callerWin = EnterModalState();
EnterModalState();
webBrowserPrint->Print(printSettings, nullptr);
LeaveModalState(callerWin);
LeaveModalState();
bool savePrintSettings =
Preferences::GetBool("print.save_print_settings", false);
@ -7257,7 +7261,7 @@ nsGlobalWindow::ReallyCloseWindow()
}
}
nsIDOMWindow *
void
nsGlobalWindow::EnterModalState()
{
// GetScriptableTop, not GetTop, so that EnterModalState works properly with
@ -7266,8 +7270,7 @@ nsGlobalWindow::EnterModalState()
if (!topWin) {
NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
return nullptr;
return;
}
// If there is an active ESM in this window, clear it. Otherwise, this can
@ -7301,21 +7304,6 @@ nsGlobalWindow::EnterModalState()
}
}
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
@ -7389,7 +7377,7 @@ private:
};
void
nsGlobalWindow::LeaveModalState(nsIDOMWindow *aCallerWin)
nsGlobalWindow::LeaveModalState()
{
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.
nsGlobalWindow *inner = topWin->GetCurrentInnerWindowInternal();
if (inner)
@ -7812,7 +7787,7 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs_,
options.AppendLiteral(",scrollbars=1,centerscreen=1,resizable=0");
nsCOMPtr<nsIDOMWindow> callerWin = EnterModalState();
EnterModalState();
uint32_t oldMicroTaskLevel = nsContentUtils::MicroTaskLevel();
nsContentUtils::SetMicroTaskLevel(0);
nsresult rv = OpenInternal(aURI, EmptyString(), options,
@ -7826,7 +7801,7 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs_,
nullptr, // aJSCallerContext
getter_AddRefs(dlgWin));
nsContentUtils::SetMicroTaskLevel(oldMicroTaskLevel);
LeaveModalState(callerWin);
LeaveModalState();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMModalContentWindow> dialog = do_QueryInterface(dlgWin);
@ -9374,6 +9349,167 @@ nsGlobalWindow::HandleIdleActiveEvent()
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
nsGlobalWindow::FindInsertionIndex(IdleObserverHolder* aIdleObserver)
{

Просмотреть файл

@ -446,8 +446,8 @@ public:
// Outer windows only.
virtual NS_HIDDEN_(void) EnsureSizeUpToDate();
virtual NS_HIDDEN_(nsIDOMWindow*) EnterModalState();
virtual NS_HIDDEN_(void) LeaveModalState(nsIDOMWindow* aWindow);
virtual NS_HIDDEN_(void) EnterModalState();
virtual NS_HIDDEN_(void) LeaveModalState();
virtual NS_HIDDEN_(bool) CanClose();
virtual NS_HIDDEN_(nsresult) ForceClose();
@ -692,6 +692,13 @@ public:
mAllowScriptsToClose = true;
}
enum SlowScriptResponse {
ContinueSlowScript = 0,
AlwaysContinueSlowScript,
KillSlowScript
};
SlowScriptResponse ShowSlowScriptDialog();
#ifdef MOZ_GAMEPAD
void AddGamepad(uint32_t aIndex, mozilla::dom::Gamepad* aGamepad);
void RemoveGamepad(uint32_t aIndex);

Просмотреть файл

@ -28,8 +28,8 @@ class nsIDOMWindow;
class nsIURI;
#define NS_ISCRIPTCONTEXT_IID \
{ 0x9173717f, 0x0722, 0x44bc, \
{ 0x99, 0x6c, 0x69, 0xa9, 0xf9, 0x6d, 0x73, 0xac } }
{ 0xfd05ba99, 0x2906, 0x4c51, \
{ 0x89, 0xb3, 0xbc, 0xdf, 0xf6, 0x3b, 0xf2, 0xde } }
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
know what language we have is a little silly... */
@ -185,9 +185,6 @@ public:
* Tell the context we're done reinitializing it.
*/
virtual void DidInitializeContext() = 0;
virtual void EnterModalState() = 0;
virtual void LeaveModalState() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)

Просмотреть файл

@ -195,9 +195,6 @@ static bool sDidShutdown;
static bool sShuttingDown;
static int32_t sContextCount;
static PRTime sMaxScriptRunTime;
static PRTime sMaxChromeScriptRunTime;
static nsIScriptSecurityManager *sSecurityManager;
// nsJSEnvironmentObserver observes the memory-pressure notifications
@ -679,278 +676,6 @@ DumpString(const nsAString &str)
}
#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."
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
Preferences::RegisterCallback(JSOptionChangedCallback,
js_options_dot_str, this);
::JS_SetOperationCallback(mContext, DOMOperationCallback);
}
mIsInitialized = false;
mScriptsEnabled = true;
mOperationCallbackTime = 0;
mModalStateTime = 0;
mModalStateDepth = 0;
mProcessingScriptTag = false;
}
@ -2185,8 +1905,6 @@ nsJSContext::ScriptEvaluated(bool aTerminated)
}
if (aTerminated) {
mOperationCallbackTime = 0;
mModalStateTime = 0;
mActive = true;
}
}
@ -3008,31 +2726,6 @@ nsJSRuntime::Startup()
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
ReportAllJSExceptionsPrefChangedCallback(const char* aPrefName, void* aClosure)
{
@ -3223,12 +2916,6 @@ nsJSRuntime::Init()
SetDOMCallbacks(sRuntime, &DOMcallbacks);
// 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,
"dom.report_all_js_exceptions");

Просмотреть файл

@ -82,9 +82,6 @@ public:
virtual nsresult Deserialize(nsIObjectInputStream* aStream,
JS::MutableHandle<JSScript*> aResult) MOZ_OVERRIDE;
virtual void EnterModalState() MOZ_OVERRIDE;
virtual void LeaveModalState() MOZ_OVERRIDE;
NS_DECL_NSIXPCSCRIPTNOTIFY
static void LoadStart();

Просмотреть файл

@ -58,8 +58,8 @@ class Element;
}
#define NS_PIDOMWINDOW_IID \
{ 0xc7f20d00, 0xed38, 0x4d60, \
{ 0x90, 0xf6, 0x3e, 0xde, 0x7b, 0x71, 0xc3, 0xb3 } }
{ 0x4f4eadf9, 0xe795, 0x48e5, \
{ 0x89, 0x4b, 0x04, 0x40, 0xb2, 0x5d, 0xa6, 0xfa } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -385,8 +385,8 @@ public:
* Callback for notifying a window about a modal dialog being
* opened/closed with the window as a parent.
*/
virtual nsIDOMWindow *EnterModalState() = 0;
virtual void LeaveModalState(nsIDOMWindow *) = 0;
virtual void EnterModalState() = 0;
virtual void LeaveModalState() = 0;
virtual bool CanClose() = 0;
virtual nsresult ForceClose() = 0;

Просмотреть файл

@ -346,12 +346,7 @@ BrowserElementChild.prototype = {
debug("Entering modal state (outerWindowID=" + outerWindowID + ", " +
"innerWindowID=" + innerWindowID + ")");
// In theory, we're supposed to pass |modalStateWin| back to
// 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();
utils.enterModalState();
// We'll decrement win.modalDepth when we receive a unblock-modal-prompt message
// for the window.
@ -388,7 +383,7 @@ BrowserElementChild.prototype = {
delete win.modalReturnValue;
if (!this._shuttingDown) {
utils.leaveModalStateWithWindow(modalStateWin);
utils.leaveModalState();
}
debug("Leaving modal state (outerID=" + outerWindowID + ", " +

Просмотреть файл

@ -42,7 +42,7 @@ interface nsIURI;
interface nsIDOMEventTarget;
interface nsIRunnable;
[scriptable, uuid(cbe333d7-5b2c-4a9b-b99b-e6e388afa62b)]
[scriptable, uuid(ff1cec22-b183-40d3-8b42-b81a2f0ba4e6)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1034,26 +1034,13 @@ interface nsIDOMWindowUtils : nsISupports {
* Put the window into a state where scripts are frozen and events
* 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
* delivered.
*/
[noscript] 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);
void leaveModalState();
/**
* 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
// abusive pages.
var winUtils = SpecialPowers.getDOMWindowUtils(this.domWindow);
var w = winUtils.enterModalStateWithWindow();
winUtils.leaveModalStateWithWindow(w);
winUtils.enterModalState();
winUtils.leaveModalState();
},
alert: function(aDialogTitle, aText)

Просмотреть файл

@ -801,7 +801,7 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
JS_SetErrorReporter(workerCx, ErrorReporter);
JS_SetOperationCallback(workerCx, OperationCallback);
JS_SetOperationCallback(aRuntime, OperationCallback);
js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);

Просмотреть файл

@ -28,7 +28,7 @@ nsAutoWindowStateHelper::nsAutoWindowStateHelper(nsIDOMWindow *aWindow)
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
if (window) {
mCallerWindow = window->EnterModalState();
window->EnterModalState();
}
}
@ -37,7 +37,7 @@ nsAutoWindowStateHelper::~nsAutoWindowStateHelper()
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mWindow));
if (window) {
window->LeaveModalState(mCallerWindow);
window->LeaveModalState();
}
if (mDefaultEnabled) {

Просмотреть файл

@ -30,7 +30,6 @@ protected:
bool DispatchEventToChrome(const char *aEventName);
nsIDOMWindow *mWindow;
nsCOMPtr<nsIDOMWindow> mCallerWindow;
bool mDefaultEnabled;
};

Просмотреть файл

@ -453,7 +453,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
// Apply the render 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
// will apply the resolution scale again when computing the effective
// 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
// offset in the view transform we obtained from Java in order to compute the
// 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()) {
geckoScroll = metrics.mScrollOffset * metrics.mDevPixelsPerCSSPixel;
geckoScroll = scrollOffsetLayerPixels;
}
LayoutDevicePoint translation = (userScroll / zoomAdjust) - geckoScroll;
LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll;
treeTransform = gfx3DMatrix(ViewTransform(-translation, userZoom / metrics.mDevPixelsPerCSSPixel));
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
gfx3DMatrix computedTransform = currentTransform * treeTransform;
gfx3DMatrix computedTransform = treeTransform * currentTransform;
computedTransform.Scale(1.0f/container->GetPreXScale(),
1.0f/container->GetPreYScale(),
1);

Просмотреть файл

@ -27,7 +27,7 @@ class AutoResolveRefLayers;
// Represents (affine) transforms that are calculated from a content view.
struct ViewTransform {
ViewTransform(LayoutDevicePoint aTranslation = LayoutDevicePoint(),
ViewTransform(LayerPoint aTranslation = LayerPoint(),
LayoutDeviceToScreenScale aScale = LayoutDeviceToScreenScale())
: mTranslation(aTranslation)
, mScale(aScale)
@ -48,7 +48,7 @@ struct ViewTransform {
return !(*this == rhs);
}
LayoutDevicePoint mTranslation;
LayerPoint mTranslation;
LayoutDeviceToScreenScale mScale;
};

Просмотреть файл

@ -1160,8 +1160,8 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
lastPaintScrollOffset = mLastContentPaintMetrics.mScrollOffset;
}
CSSToScreenScale localScale = mFrameMetrics.CalculateResolution();
LayoutDevicePoint translation = (mFrameMetrics.mScrollOffset - lastPaintScrollOffset)
* mLastContentPaintMetrics.mDevPixelsPerCSSPixel;
LayerPoint translation = (mFrameMetrics.mScrollOffset - lastPaintScrollOffset)
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
return ViewTransform(-translation, localScale / mLastContentPaintMetrics.mDevPixelsPerCSSPixel);
}

Просмотреть файл

@ -196,39 +196,39 @@ TEST(AsyncPanZoomController, ComplexTransform) {
apzc->SetFrameMetrics(metrics);
apzc->NotifyLayersUpdated(metrics, true);
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);
childApzc->SetFrameMetrics(childMetrics);
childApzc->NotifyLayersUpdated(childMetrics, true);
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);
// do an async scroll by 5 pixels and check the transform
metrics.mScrollOffset += CSSPoint(5, 0);
apzc->SetFrameMetrics(metrics);
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);
childMetrics.mScrollOffset += CSSPoint(5, 0);
childApzc->SetFrameMetrics(childMetrics);
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);
// do an async zoom of 1.5x and check the transform
metrics.mZoom.scale *= 1.5f;
apzc->SetFrameMetrics(metrics);
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);
childMetrics.mZoom.scale *= 1.5f;
childApzc->SetFrameMetrics(childMetrics);
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);
}

Просмотреть файл

@ -5419,17 +5419,17 @@ JS_New(JSContext *cx, JSObject *ctorArg, unsigned argc, jsval *argv)
}
JS_PUBLIC_API(JSOperationCallback)
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback)
JS_SetOperationCallback(JSRuntime *rt, JSOperationCallback callback)
{
JSOperationCallback old = cx->operationCallback;
cx->operationCallback = callback;
JSOperationCallback old = rt->operationCallback;
rt->operationCallback = callback;
return old;
}
JS_PUBLIC_API(JSOperationCallback)
JS_GetOperationCallback(JSContext *cx)
JS_GetOperationCallback(JSRuntime *rt)
{
return cx->operationCallback;
return rt->operationCallback;
}
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.
*/
extern JS_PUBLIC_API(JSOperationCallback)
JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback);
JS_SetOperationCallback(JSRuntime *rt, JSOperationCallback callback);
extern JS_PUBLIC_API(JSOperationCallback)
JS_GetOperationCallback(JSContext *cx);
JS_GetOperationCallback(JSRuntime *rt);
extern JS_PUBLIC_API(void)
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
* callback is disconnected before attempting such re-entry.
*/
JSOperationCallback cb = cx->operationCallback;
JSOperationCallback cb = cx->runtime()->operationCallback;
return !cb || cb(cx);
}
@ -1072,7 +1072,6 @@ JSContext::JSContext(JSRuntime *rt)
defaultCompartmentObject_(NULL),
cycleDetectorSet(MOZ_THIS_IN_INITIALIZER_LIST()),
errorReporter(NULL),
operationCallback(NULL),
data(NULL),
data2(NULL),
#ifdef JS_THREADSAFE

Просмотреть файл

@ -445,9 +445,6 @@ struct JSContext : public js::ExclusiveContext,
/* Per-context optional error reporter. */
JSErrorReporter errorReporter;
/* Branch callback. */
JSOperationCallback operationCallback;
/* Client opaque pointers. */
void *data;
void *data2;

Просмотреть файл

@ -374,12 +374,6 @@ ShellOperationCallback(JSContext *cx)
return result;
}
static void
SetContextOptions(JSContext *cx)
{
JS_SetOperationCallback(cx, ShellOperationCallback);
}
/*
* 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
@ -572,8 +566,6 @@ Process(JSContext *cx, JSObject *obj_, const char *filename, bool forceTTY)
}
AutoCloseInputFile autoClose(file);
SetContextOptions(cx);
if (!forceTTY && !isatty(fileno(file))) {
// It's not interactive - just execute it.
RunFile(cx, obj, filename, file, compileOnly);
@ -4865,7 +4857,6 @@ NewContext(JSRuntime *rt)
JS_SetContextPrivate(cx, data);
JS_SetErrorReporter(cx, my_ErrorReporter);
SetContextOptions(cx);
if (enableTypeInference)
JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
if (enableIon)
@ -5470,6 +5461,7 @@ main(int argc, char **argv, char **envp)
JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals);
JS_SetSecurityCallbacks(rt, &securityCallbacks);
JS_SetOperationCallback(rt, ShellOperationCallback);
JS_SetNativeStackQuota(rt, gMaxStackSize);

Просмотреть файл

@ -99,6 +99,7 @@ PerThreadData::removeFromThreadList()
JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
: mainThread(this),
interrupt(0),
operationCallback(NULL),
#ifdef JS_THREADSAFE
operationCallbackLock(NULL),
#ifdef DEBUG

Просмотреть файл

@ -693,6 +693,9 @@ struct JSRuntime : public JS::shadow::Runtime,
*/
volatile int32_t interrupt;
/* Branch callback */
JSOperationCallback operationCallback;
#ifdef JS_THREADSAFE
private:
/*

Просмотреть файл

@ -1466,10 +1466,8 @@ XPCShellErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
static bool
ContextCallback(JSContext *cx, unsigned contextOp)
{
if (contextOp == JSCONTEXT_NEW) {
if (contextOp == JSCONTEXT_NEW)
JS_SetErrorReporter(cx, XPCShellErrorReporter);
JS_SetOperationCallback(cx, XPCShellOperationCallback);
}
return true;
}
@ -1642,6 +1640,11 @@ main(int argc, char **argv, char **envp)
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);
if (!cx) {
printf("JS_NewContext failed!\n");

Просмотреть файл

@ -3737,10 +3737,7 @@ public:
NS_DECL_ISUPPORTS
private:
static bool ContextHolderOperationCallback(JSContext *cx);
JSContext* mJSContext;
JSContext* mOrigCx;
nsCOMPtr<nsIPrincipal> mPrincipal;
};
@ -3750,7 +3747,6 @@ ContextHolder::ContextHolder(JSContext *aOuterCx,
HandleObject aSandbox,
nsIPrincipal *aPrincipal)
: mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
mOrigCx(aOuterCx),
mPrincipal(aPrincipal)
{
if (mJSContext) {
@ -3765,7 +3761,6 @@ ContextHolder::ContextHolder(JSContext *aOuterCx,
JSOPTION_PRIVATE_IS_NSISUPPORTS);
js::SetDefaultObjectForContext(mJSContext, aSandbox);
JS_SetContextPrivate(mJSContext, this);
JS_SetOperationCallback(mJSContext, ContextHolderOperationCallback);
}
}
@ -3775,21 +3770,6 @@ ContextHolder::~ContextHolder()
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); */

Просмотреть файл

@ -39,6 +39,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/Attributes.h"
#include "AccessCheck.h"
#include "nsGlobalWindow.h"
#include "GeckoProfiler.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
XPCJSRuntime::SizeOfIncludingThis(MallocSizeOf mallocSizeOf)
{
@ -2877,6 +2933,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
JS_SetAccumulateTelemetryCallback(runtime, AccumulateTelemetryCallback);
js::SetActivityCallback(runtime, ActivityCallback, this);
js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
JS_SetOperationCallback(runtime, OperationCallback);
// 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

Просмотреть файл

@ -1182,6 +1182,9 @@ nsXPConnect::AfterProcessNextEvent(nsIThreadInternal *aThread,
return NS_OK;
mEventDepth--;
// Now that we're back to the event loop, reset the slow script checkpoint.
mRuntime->OnAfterProcessNextEvent();
// Call cycle collector occasionally.
MOZ_ASSERT(NS_IsMainThread());
nsJSContext::MaybePokeCC();

Просмотреть файл

@ -827,6 +827,7 @@ public:
static void ActivityCallback(void *arg, bool active);
static void CTypesActivityCallback(JSContext *cx,
js::CTypesActivityType type);
static bool OperationCallback(JSContext *cx);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
@ -836,6 +837,7 @@ public:
void DeleteJunkScope();
PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory);
void OnAfterProcessNextEvent() { mSlowScriptCheckpoint = mozilla::TimeStamp(); }
private:
XPCJSRuntime(); // no implementation
@ -876,6 +878,8 @@ private:
JSObject* mJunkScope;
nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
mozilla::TimeStamp mSlowScriptCheckpoint;
nsCOMPtr<nsIException> mPendingException;
nsCOMPtr<nsIExceptionManager> mExceptionManager;
bool mExceptionManagerNotAvailable;

Просмотреть файл

@ -128,6 +128,7 @@ SYNC_JAVA_FILES := \
sync/net/BrowserIDAuthHeaderProvider.java \
sync/net/ConnectionMonitorThread.java \
sync/net/HandleProgressException.java \
sync/net/HawkAuthHeaderProvider.java \
sync/net/HMACAuthHeaderProvider.java \
sync/net/HttpResponseObserver.java \
sync/net/Resource.java \

Просмотреть файл

@ -178,13 +178,21 @@ public class Utils {
// Truncates towards 0.
return (long)(decimal * 1000);
}
public static long decimalSecondsToMilliseconds(Long decimal) {
return decimal * 1000;
}
public static long decimalSecondsToMilliseconds(Integer decimal) {
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)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
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>&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 id="addons-list" class="list" style="display: none;">
</div>

Просмотреть файл

@ -2560,7 +2560,7 @@ function Tab(aURL, aParams) {
this.viewportExcludesHorizontalMargins = true;
this.viewportExcludesVerticalMargins = true;
this.viewportMeasureCallback = null;
this.lastPageSizeUsedForViewportChange = { width: 0, height: 0 };
this.lastPageSizeAfterViewportRemeasure = { width: 0, height: 0 };
this.contentDocumentIsDisplayed = true;
this.pluginDoorhangerTimeout = null;
this.shouldShowPluginDoorhanger = true;
@ -3301,8 +3301,8 @@ Tab.prototype = {
let pageWidth = viewport.pageRight - viewport.pageLeft;
let pageHeight = viewport.pageBottom - viewport.pageTop;
if (Math.abs(pageWidth - this.lastPageSizeUsedForViewportChange.width) >= 0.5 ||
Math.abs(pageHeight - this.lastPageSizeUsedForViewportChange.height) >= 0.5) {
if (Math.abs(pageWidth - this.lastPageSizeAfterViewportRemeasure.width) >= 0.5 ||
Math.abs(pageHeight - this.lastPageSizeAfterViewportRemeasure.height) >= 0.5) {
this.updateViewportSize(gScreenWidth);
}
}.bind(this), kViewportRemeasureThrottle);
@ -3881,13 +3881,6 @@ Tab.prototype = {
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 = this.clampZoom(minScale);
@ -3916,6 +3909,14 @@ Tab.prototype = {
this.setResolution(zoom, false);
this.setScrollClampingSize(zoom);
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() {

Просмотреть файл

@ -160,7 +160,7 @@ FilePicker.prototype = {
if (this._domWin) {
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
callerWin = winUtils.enterModalStateWithWindow();
winUtils.enterModalState();
}
this._promptActive = true;

Просмотреть файл

@ -152,11 +152,10 @@ InternalPrompt.prototype = {
* for a response
*/
showPrompt: function showPrompt(aPrompt) {
let callerWin;
if (this._domWin) {
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
callerWin = winUtils.enterModalStateWithWindow();
winUtils.enterModalState();
}
let retval = null;
@ -171,7 +170,7 @@ InternalPrompt.prototype = {
if (this._domWin) {
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
winUtils.leaveModalStateWithWindow(callerWin);
winUtils.leaveModalState();
PromptUtils.fireDialogEvent(this._domWin, "DOMModalDialogClosed");
}

Просмотреть файл

@ -5,6 +5,7 @@
<!ENTITY aboutAddons.title2 "Add-ons">
<!ENTITY aboutAddons.header2 "Your Add-ons">
<!ENTITY aboutAddons.options "Options">
<!ENTITY aboutAddons.browseAll "Browse all Firefox Add-ons">
<!ENTITY addonAction.enable "Enable">
<!ENTITY addonAction.disable "Disable">

Просмотреть файл

@ -115,6 +115,7 @@ sync/net/BasicAuthHeaderProvider.java
sync/net/BrowserIDAuthHeaderProvider.java
sync/net/ConnectionMonitorThread.java
sync/net/HandleProgressException.java
sync/net/HawkAuthHeaderProvider.java
sync/net/HMACAuthHeaderProvider.java
sync/net/HttpResponseObserver.java
sync/net/Resource.java

Просмотреть файл

@ -913,6 +913,9 @@ pref("network.protocol-handler.external.moz-icon", false);
// to override this value.
pref("network.protocol-handler.expose-all", true);
// Warning for about:networking page
pref("network.warnOnAboutNetworking", true);
// Example: make IMAP an exposed protocol
// pref("network.protocol-handler.expose.imap", true);

Просмотреть файл

@ -700,11 +700,11 @@ function test_info() {
startMs = start.getTime() - 1000;
stopMs = stop.getTime() + 1000;
birth = stat.creationDate;
let birth = stat.creationDate;
ok(birth.getTime() <= stopMs,
"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
&& access.getTime() <= stopMs,
"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();
/** 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 mozproxy, proxiedHost = "http://mochi.test:8888";
var proxyChannel;
var testNum = 1;
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"].
getService(Ci.nsILoginManager);
ioService = Cc["@mozilla.org/network/io-service;1"].
@ -96,6 +100,8 @@ function initLogins(pi) {
function finishTest() {
try {
ok(true, "finishTest removing testing logins...");
observerService.removeObserver(storageObserver, "passwordmgr-storage-changed");
dumpLogins(pwmgr);
ok(true, "removing login 1...");
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
*

Просмотреть файл

@ -399,7 +399,7 @@ function openTabPrompt(domWin, tabPrompt, args) {
let winUtils = domWin.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let callerWin = winUtils.enterModalStateWithWindow();
winUtils.enterModalState();
// 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
@ -413,7 +413,7 @@ function openTabPrompt(domWin, tabPrompt, args) {
if (newPrompt)
tabPrompt.removePrompt(newPrompt);
winUtils.leaveModalStateWithWindow(callerWin);
winUtils.leaveModalState();
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
}

Просмотреть файл

@ -456,7 +456,7 @@ this.PageThumbs = {
let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
.getService(Ci.nsIScreenManager);
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._thumbnailHeight = Math.round(height.value / 3);
}

Просмотреть файл

@ -713,6 +713,7 @@ nsUrlClassifierDBServiceWorker::CacheCompletions(CacheResultArray *results)
for (uint32_t table = 0; table < tables.Length(); table++) {
if (tables[table].Equals(resultsPtr->ElementAt(i).table)) {
activeTable = true;
break;
}
}
if (activeTable) {

Просмотреть файл

@ -669,7 +669,7 @@
<constructor>
<![CDATA[
try {
if (!this.hasAttribute("disablehistory")) {
if (this.docShell && !this.hasAttribute("disablehistory")) {
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.addObserver(this, "browser:purge-session-history", false);
@ -678,7 +678,7 @@
Components.classes["@mozilla.org/browser/shistory;1"]
.createInstance(Components.interfaces.nsISHistory);
// enable global history if we weren't told otherwise
if (this.docShell && !this.hasAttribute("disableglobalhistory"))
if (!this.hasAttribute("disableglobalhistory"))
this.docShell.useGlobalHistory = true;
}
}

Просмотреть файл

@ -1544,30 +1544,37 @@ ThreadActor.prototype = {
if (!aPool) {
aPool = this._pausePool;
}
let type = typeof(aValue);
if (type === "string" && this._stringIsLong(aValue)) {
return this.longStringGrip(aValue, aPool);
switch (typeof aValue) {
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.
*/
function createValueGrip(aValue, aUseDescriptor) {
let type = typeof aValue;
if (type === "string" && aValue.length >= DebuggerServer.LONG_STRING_LENGTH) {
return {
type: "longString",
initial: aValue.substring(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH),
length: aValue.length
};
switch (typeof aValue) {
case "boolean":
return aValue;
case "string":
if (aValue.length >= DebuggerServer.LONG_STRING_LENGTH) {
return {
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"');
do_check_eq(typeof obj.ownProperties.arr.value, "object",
'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.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.arr.value.type, "object");
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,
nil: null,
obj: obj,
arr: [1,2,3,4,5]
arr: [1,2,3,4,5],
inf: Infinity,
ninf: -Infinity,
nan: NaN,
nzero: -0
};
}
foo();

Просмотреть файл

@ -120,6 +120,7 @@ reason = bug 820380
[test_objectgrips-05.js]
[test_objectgrips-06.js]
[test_objectgrips-07.js]
[test_objectgrips-08.js]
[test_interrupt.js]
[test_stepping-01.js]
[test_stepping-02.js]

Просмотреть файл

@ -317,29 +317,36 @@ let WebConsoleUtils = {
*/
createValueGrip: function WCU_createValueGrip(aValue, aObjectWrapper)
{
let type = typeof(aValue);
switch (type) {
switch (typeof aValue) {
case "boolean":
case "number":
return aValue;
case "string":
return aObjectWrapper(aValue);
case "object":
case "function":
if (aValue) {
return aObjectWrapper(aValue);
return aObjectWrapper(aValue);
case "number":
if (aValue === Infinity) {
return { type: "Infinity" };
}
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) {
return { type: "null" };
}
if (aValue === undefined) {
return { type: "undefined" };
}
Cu.reportError("Failed to provide a grip for value of " + type + ": " +
aValue);
case "function":
return aObjectWrapper(aValue);
default:
Cu.reportError("Failed to provide a grip for value of " + typeof aValue
+ ": " + aValue);
return null;
}
},

Просмотреть файл

@ -37,6 +37,8 @@ public:
/*
* 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;

Просмотреть файл

@ -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
MetroWidget::InitEvent(nsGUIEvent& event, nsIntPoint* aPoint)
{
if (!aPoint) {
event.refPoint.x = event.refPoint.y = 0;
} else {
CSSIntPoint cssPoint(aPoint->x, aPoint->y);
LayoutDeviceIntPoint layoutDeviceIntPoint = CSSIntPointToLayoutDeviceIntPoint(cssPoint);
event.refPoint.x = layoutDeviceIntPoint.x;
event.refPoint.y = layoutDeviceIntPoint.y;
event.refPoint.x = aPoint->x;
event.refPoint.y = aPoint->y;
}
event.time = ::GetMessageTime();
}

Просмотреть файл

@ -69,10 +69,12 @@ public:
static HWND GetICoreWindowHWND() { return sICoreHwnd; }
// nsWindowBase
virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) MOZ_OVERRIDE;
virtual bool DispatchWindowEvent(nsGUIEvent* aEvent) MOZ_OVERRIDE;
virtual bool IsTopLevelWidget() MOZ_OVERRIDE { return true; }
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
virtual CompositorParent* NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight);