Merging mozilla-central to Places.

This commit is contained in:
Shawn Wilsher 2010-10-29 11:39:41 -07:00
Родитель 6f48d0fb79 28678340e7
Коммит 9bd9238f38
124 изменённых файлов: 4165 добавлений и 2998 удалений

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

@ -91,14 +91,6 @@ nsAccDocManager::FindAccessibleInCache(nsINode* aNode) const
return arg.mAccessible; return arg.mAccessible;
} }
void
nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocument *aDocument)
{
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(container);
ShutdownDocAccessiblesInTree(treeItem, aDocument);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsAccDocManager protected // nsAccDocManager protected
@ -132,21 +124,6 @@ nsAccDocManager::Shutdown()
ClearDocCache(); ClearDocCache();
} }
void
nsAccDocManager::ShutdownDocAccessible(nsIDocument *aDocument)
{
nsDocAccessible* docAccessible = mDocAccessibleCache.GetWeak(aDocument);
if (!docAccessible)
return;
// We're allowed to not remove listeners when accessible document is shutdown
// since we don't keep strong reference on chrome event target and listeners
// are removed automatically when chrome event target goes away.
docAccessible->Shutdown();
mDocAccessibleCache.Remove(aDocument);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsISupports // nsISupports
@ -316,7 +293,14 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
return NS_OK; return NS_OK;
// Shutdown this one and sub document accessibles. // Shutdown this one and sub document accessibles.
ShutdownDocAccessiblesInTree(document);
// We're allowed to not remove listeners when accessible document is
// shutdown since we don't keep strong reference on chrome event target and
// listeners are removed automatically when chrome event target goes away.
nsDocAccessible* docAccessible = mDocAccessibleCache.GetWeak(document);
if (docAccessible)
docAccessible->Shutdown();
return NS_OK; return NS_OK;
} }
@ -500,35 +484,6 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
return docAcc; return docAcc;
} }
void
nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
nsIDocument *aDocument)
{
nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aTreeItem));
if (treeNode) {
PRInt32 subDocumentsCount = 0;
treeNode->GetChildCount(&subDocumentsCount);
for (PRInt32 idx = 0; idx < subDocumentsCount; idx++) {
nsCOMPtr<nsIDocShellTreeItem> treeItemChild;
treeNode->GetChildAt(idx, getter_AddRefs(treeItemChild));
NS_ASSERTION(treeItemChild, "No tree item when there should be");
if (!treeItemChild)
continue;
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(treeItemChild));
nsCOMPtr<nsIContentViewer> contentViewer;
docShell->GetContentViewer(getter_AddRefs(contentViewer));
if (!contentViewer)
continue;
ShutdownDocAccessiblesInTree(treeItemChild, contentViewer->GetDocument());
}
}
ShutdownDocAccessible(aDocument);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsAccDocManager static // nsAccDocManager static

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

@ -75,13 +75,6 @@ public:
*/ */
nsAccessible* FindAccessibleInCache(nsINode* aNode) const; nsAccessible* FindAccessibleInCache(nsINode* aNode) const;
/**
* Shutdown document accessibles in the tree starting from the given one.
*
* @param aDocument [in] the DOM document of start document accessible
*/
void ShutdownDocAccessiblesInTree(nsIDocument *aDocument);
/** /**
* Return document accessible from the cache. Convenient method for testing. * Return document accessible from the cache. Convenient method for testing.
*/ */
@ -90,6 +83,14 @@ public:
return mDocAccessibleCache.GetWeak(aDocument); return mDocAccessibleCache.GetWeak(aDocument);
} }
/**
* Called by document accessible when it gets shutdown.
*/
inline void NotifyOfDocumentShutdown(nsIDocument* aDocument)
{
mDocAccessibleCache.Remove(aDocument);
}
protected: protected:
nsAccDocManager() { }; nsAccDocManager() { };
@ -103,11 +104,6 @@ protected:
*/ */
void Shutdown(); void Shutdown();
/**
* Shutdown the document accessible.
*/
void ShutdownDocAccessible(nsIDocument* aDocument);
private: private:
nsAccDocManager(const nsAccDocManager&); nsAccDocManager(const nsAccDocManager&);
nsAccDocManager& operator =(const nsAccDocManager&); nsAccDocManager& operator =(const nsAccDocManager&);
@ -156,12 +152,6 @@ private:
*/ */
nsDocAccessible *CreateDocOrRootAccessible(nsIDocument *aDocument); nsDocAccessible *CreateDocOrRootAccessible(nsIDocument *aDocument);
/**
* Shutdown document accessibles in the tree starting from given tree item.
*/
void ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
nsIDocument *aDocument);
typedef nsRefPtrHashtable<nsPtrHashKey<const nsIDocument>, nsDocAccessible> typedef nsRefPtrHashtable<nsPtrHashKey<const nsIDocument>, nsDocAccessible>
nsDocAccessibleHashtable; nsDocAccessibleHashtable;

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

@ -382,7 +382,8 @@ nsAccessNode::ScrollTo(PRUint32 aScrollType)
PRInt16 vPercent, hPercent; PRInt16 vPercent, hPercent;
nsCoreUtils::ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent); nsCoreUtils::ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
return shell->ScrollContentIntoView(content, vPercent, hPercent); return shell->ScrollContentIntoView(content, vPercent, hPercent,
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -543,7 +543,10 @@ nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
return; return;
NS_LOG_ACCDOCDESTROY("presshell destroyed", doc) NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
ShutdownDocAccessible(doc);
nsDocAccessible* docAccessible = GetDocAccessibleFromCache(doc);
if (docAccessible)
docAccessible->Shutdown();
} }
void void

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

@ -2368,7 +2368,8 @@ nsAccessible::DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex)
// Scroll into view. // Scroll into view.
presShell->ScrollContentIntoView(aContent, NS_PRESSHELL_SCROLL_ANYWHERE, presShell->ScrollContentIntoView(aContent, NS_PRESSHELL_SCROLL_ANYWHERE,
NS_PRESSHELL_SCROLL_ANYWHERE); NS_PRESSHELL_SCROLL_ANYWHERE,
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
// Fire mouse down and mouse up events. // Fire mouse down and mouse up events.
PRBool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell, PRBool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,

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

@ -675,6 +675,10 @@ nsDocAccessible::Shutdown()
mParent->RemoveChild(this); mParent->RemoveChild(this);
} }
PRUint32 childDocCount = mChildDocuments.Length();
for (PRUint32 idx = 0; idx < childDocCount; idx++)
mChildDocuments[idx]->Shutdown();
mChildDocuments.Clear(); mChildDocuments.Clear();
mWeakShell = nsnull; // Avoid reentrancy mWeakShell = nsnull; // Avoid reentrancy
@ -686,6 +690,8 @@ nsDocAccessible::Shutdown()
mDocument = nsnull; mDocument = nsnull;
nsHyperTextAccessibleWrap::Shutdown(); nsHyperTextAccessibleWrap::Shutdown();
GetAccService()->NotifyOfDocumentShutdown(kungFuDeathGripDoc);
} }
nsIFrame* nsIFrame*

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

@ -169,7 +169,7 @@ nsOuterDocAccessible::Shutdown()
if (childAcc) { if (childAcc) {
NS_LOG_ACCDOCDESTROY("outerdoc's child document shutdown", NS_LOG_ACCDOCDESTROY("outerdoc's child document shutdown",
childAcc->GetDocumentNode()) childAcc->GetDocumentNode())
GetAccService()->ShutdownDocAccessiblesInTree(childAcc->GetDocumentNode()); childAcc->Shutdown();
} }
nsAccessibleWrap::Shutdown(); nsAccessibleWrap::Shutdown();

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

@ -826,12 +826,7 @@
#ifdef WINCE #ifdef WINCE
defaulticonsize="small" iconsize="small" defaulticonsize="small" iconsize="small"
#endif #endif
#ifdef XP_WIN
tabsontop="true" tabsontop="true"
#endif
#ifdef XP_MACOSX
tabsontop="true"
#endif
persist="tabsontop"> persist="tabsontop">
<!-- Menu --> <!-- Menu -->
<toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true" <toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"

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

@ -380,8 +380,7 @@ CSPRep.prototype = {
}, },
/** /**
* Generates string representation of the policy. Should be fairly similar * Generates canonical string representation of the policy.
* to the original.
*/ */
toString: toString:
function csp_toString() { function csp_toString() {
@ -607,8 +606,7 @@ CSPSourceList.prototype = {
}, },
/** /**
* Generates string representation of the Source List. * Generates canonical string representation of the Source List.
* Should be fairly similar to the original.
*/ */
toString: toString:
function() { function() {
@ -639,7 +637,7 @@ CSPSourceList.prototype = {
}, },
/** /**
* Makes a new instance that resembles this object. * Makes a new deep copy of this object.
* @returns * @returns
* a new CSPSourceList * a new CSPSourceList
*/ */
@ -951,7 +949,7 @@ CSPSource.fromString = function(aStr, self, enforceSelfChecks) {
// Allow scheme-only sources! These default to wildcard host/port, // Allow scheme-only sources! These default to wildcard host/port,
// especially since host and port don't always matter. // especially since host and port don't always matter.
// Example: "javascript:" and "data:" // Example: "javascript:" and "data:"
if (!sObj._host) sObj._host = "*"; if (!sObj._host) sObj._host = CSPHost.fromString("*");
if (!sObj._port) sObj._port = "*"; if (!sObj._port) sObj._port = "*";
} else { } else {
// some host was defined. // some host was defined.
@ -1050,8 +1048,7 @@ CSPSource.prototype = {
}, },
/** /**
* Generates string representation of the Source. * Generates canonical string representation of the Source.
* Should be fairly similar to the original.
*/ */
toString: toString:
function() { function() {
@ -1069,7 +1066,7 @@ CSPSource.prototype = {
}, },
/** /**
* Makes a new instance that resembles this object. * Makes a new deep copy of this object.
* @returns * @returns
* a new CSPSource * a new CSPSource
*/ */
@ -1172,13 +1169,28 @@ CSPSource.prototype = {
return null; return null;
} }
// NOTE: Both sources must have a host, if they don't, something funny is
// going on. The fromString() factory method should have set the host to
// * if there's no host specified in the input. Regardless, if a host is
// not present either the scheme is hostless or any host should be allowed.
// This means we can use the other source's host as the more restrictive
// host expression, or if neither are present, we can use "*", but the
// error should still be reported.
// host // host
if (!this._host) if (this._host && that._host) {
newSource._host = that._host;
else if (!that._host)
newSource._host = this._host;
else // both this and that have hosts
newSource._host = this._host.intersectWith(that._host); newSource._host = this._host.intersectWith(that._host);
} else if (this._host) {
CSPError("intersecting source with undefined host: " + that.toString());
newSource._host = this._host.clone();
} else if (that._host) {
CSPError("intersecting source with undefined host: " + this.toString());
newSource._host = that._host.clone();
} else {
CSPError("intersecting two sources with undefined hosts: " +
this.toString() + " and " + that.toString());
newSource._host = CSPHost.fromString("*");
}
return newSource; return newSource;
}, },
@ -1266,8 +1278,7 @@ CSPHost.fromString = function(aStr) {
CSPHost.prototype = { CSPHost.prototype = {
/** /**
* Generates string representation of the Source. * Generates canonical string representation of the Host.
* Should be fairly similar to the original.
*/ */
toString: toString:
function() { function() {
@ -1275,7 +1286,7 @@ CSPHost.prototype = {
}, },
/** /**
* Makes a new instance that resembles this object. * Makes a new deep copy of this object.
* @returns * @returns
* a new CSPHost * a new CSPHost
*/ */
@ -1297,7 +1308,7 @@ CSPHost.prototype = {
*/ */
permits: permits:
function(aHost) { function(aHost) {
if (!aHost) return false; if (!aHost) aHost = CSPHost.fromString("*");
if (!(aHost instanceof CSPHost)) { if (!(aHost instanceof CSPHost)) {
// -- compare CSPHost to String // -- compare CSPHost to String

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

@ -5325,7 +5325,7 @@ nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
nsIEventStateManager* esm = nsIEventStateManager* esm =
aVisitor.mPresContext->EventStateManager(); aVisitor.mPresContext->EventStateManager();
nsEventStateManager::SetGlobalActiveContent( nsEventStateManager::SetActiveManager(
static_cast<nsEventStateManager*>(esm), this); static_cast<nsEventStateManager*>(esm), this);
} }
} }

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

@ -35,6 +35,7 @@
//load('CSPUtils.jsm'); //load('CSPUtils.jsm');
Components.utils.import('resource://gre/modules/CSPUtils.jsm'); Components.utils.import('resource://gre/modules/CSPUtils.jsm');
Components.utils.import('resource://gre/modules/NetUtil.jsm');
// load the HTTP server // load the HTTP server
do_load_httpd_js(); do_load_httpd_js();
@ -190,6 +191,7 @@ test(
//"funny characters (#) should not work for host."); //"funny characters (#) should not work for host.");
do_check_eq(null, CSPSource.fromString("a#2-c.com")); do_check_eq(null, CSPSource.fromString("a#2-c.com"));
//print(" --- Stop ignoring errors that print ---\n"); //print(" --- Stop ignoring errors that print ---\n");
//"failed to parse host with port."); //"failed to parse host with port.");
@ -229,6 +231,16 @@ test(
do_check_true(src.permits("https://foobar.com")); do_check_true(src.permits("https://foobar.com"));
//"src should reject other hosts" //"src should reject other hosts"
do_check_false(src.permits("https://a.com")); do_check_false(src.permits("https://a.com"));
src = CSPSource.create("javascript:", "https://foobar.com:443");
//"hostless schemes should be parseable."
var aUri = NetUtil.newURI("javascript:alert('foo');");
do_check_true(src.permits(aUri));
//"src should reject other hosts"
do_check_false(src.permits("https://a.com"));
//"nothing else should be allowed"
do_check_false(src.permits("https://foobar.com"));
}); });
///////////////////// Test the source list ////////////////////// ///////////////////// Test the source list //////////////////////

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

@ -2074,6 +2074,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
PRBool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer, PRBool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
targetContent, isSelection); targetContent, isSelection);
if (dragStarted) { if (dragStarted) {
sActiveESM = nsnull;
aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH; aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
} }
} }
@ -2935,7 +2936,6 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
if (par) if (par)
activeContent = par; activeContent = par;
} }
SetGlobalActiveContent(this, activeContent);
} }
} }
else { else {
@ -2943,11 +2943,12 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
// any of our own processing of a drag. Workaround for bug 43258. // any of our own processing of a drag. Workaround for bug 43258.
StopTrackingDragGesture(); StopTrackingDragGesture();
} }
SetActiveManager(this, activeContent);
} }
break; break;
case NS_MOUSE_BUTTON_UP: case NS_MOUSE_BUTTON_UP:
{ {
ClearGlobalActiveContent(); ClearGlobalActiveContent(this);
if (IsMouseEventReal(aEvent)) { if (IsMouseEventReal(aEvent)) {
if (!mCurrentTarget) { if (!mCurrentTarget) {
nsIFrame* targ; nsIFrame* targ;
@ -3206,6 +3207,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
targetContent, &status); targetContent, &status);
} }
} }
ClearGlobalActiveContent(this);
break; break;
} }
case NS_DRAGDROP_EXIT: case NS_DRAGDROP_EXIT:
@ -4706,22 +4708,25 @@ nsEventStateManager::DoContentCommandScrollEvent(nsContentCommandEvent* aEvent)
} }
void void
nsEventStateManager::SetGlobalActiveContent(nsEventStateManager* aNewESM, nsEventStateManager::SetActiveManager(nsEventStateManager* aNewESM,
nsIContent* aContent) nsIContent* aContent)
{ {
if (sActiveESM && aNewESM != sActiveESM) { if (sActiveESM && aNewESM != sActiveESM) {
sActiveESM->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE); sActiveESM->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
} }
sActiveESM = aNewESM; sActiveESM = aNewESM;
if (sActiveESM) { if (sActiveESM && aContent) {
sActiveESM->SetContentState(aContent, NS_EVENT_STATE_ACTIVE); sActiveESM->SetContentState(aContent, NS_EVENT_STATE_ACTIVE);
} }
} }
void void
nsEventStateManager::ClearGlobalActiveContent() nsEventStateManager::ClearGlobalActiveContent(nsEventStateManager* aClearer)
{ {
if (sActiveESM) { if (aClearer) {
aClearer->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
}
if (sActiveESM && aClearer != sActiveESM) {
sActiveESM->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE); sActiveESM->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
} }
sActiveESM = nsnull; sActiveESM = nsnull;

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

@ -159,8 +159,10 @@ public:
static nsIEventStateManager* GetActiveEventStateManager() { return sActiveESM; } static nsIEventStateManager* GetActiveEventStateManager() { return sActiveESM; }
static void SetGlobalActiveContent(nsEventStateManager* aNewESM, // Sets aNewESM to be the active event state manager, and
nsIContent* aContent); // if aContent is non-null, marks the object as active.
static void SetActiveManager(nsEventStateManager* aNewESM,
nsIContent* aContent);
protected: protected:
void UpdateCursor(nsPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus); void UpdateCursor(nsPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
/** /**
@ -415,7 +417,7 @@ protected:
static nsEventStateManager* sActiveESM; static nsEventStateManager* sActiveESM;
static void ClearGlobalActiveContent(); static void ClearGlobalActiveContent(nsEventStateManager* aClearer);
// Functions used for click hold context menus // Functions used for click hold context menus
PRBool mClickHoldContextMenu; PRBool mClickHoldContextMenu;

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

@ -808,7 +808,8 @@ nsGenericHTMLElement::ScrollIntoView(PRBool aTop, PRUint8 optional_argc)
NS_PRESSHELL_SCROLL_BOTTOM; NS_PRESSHELL_SCROLL_BOTTOM;
presShell->ScrollContentIntoView(this, vpercent, presShell->ScrollContentIntoView(this, vpercent,
NS_PRESSHELL_SCROLL_ANYWHERE); NS_PRESSHELL_SCROLL_ANYWHERE,
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
return NS_OK; return NS_OK;
} }

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

@ -439,7 +439,7 @@ nsHTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
if (NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) { if (NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
nsIEventStateManager* esm = nsIEventStateManager* esm =
aVisitor.mPresContext->EventStateManager(); aVisitor.mPresContext->EventStateManager();
nsEventStateManager::SetGlobalActiveContent( nsEventStateManager::SetActiveManager(
static_cast<nsEventStateManager*>(esm), this); static_cast<nsEventStateManager*>(esm), this);
} }
nsIFocusManager* fm = nsFocusManager::GetFocusManager(); nsIFocusManager* fm = nsFocusManager::GetFocusManager();

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

@ -236,6 +236,8 @@ _TEST_FILES = \
test_bug600155.html \ test_bug600155.html \
test_bug556007.html \ test_bug556007.html \
test_bug606817.html \ test_bug606817.html \
test_bug297761.html \
file_bug297761.html \
$(NULL) $(NULL)
libs:: $(_TEST_FILES) libs:: $(_TEST_FILES)

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

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<base href="http://www.mozilla.org/">
</head>
<body>
<form action="">
<input type='submit' formaction="">
<button type='submit' formaction=""></button>
<input id='i' type='image' formaction="">
</form>
</body>
</html>

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

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=297761
-->
<head>
<title>Test for Bug 297761</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=297761">Mozilla Bug 297761</a>
<p id="display"></p>
<div id="content">
<iframe src="file_bug297761.html"></iframe>
<iframe src="file_bug297761.html"></iframe>
<iframe src="file_bug297761.html"></iframe>
<iframe src="file_bug297761.html"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 297761 **/
SimpleTest.waitForExplicitFinish();
var nbTests = 4;
var curTest = 0;
function nextTest()
{
if (curTest == 3) {
frames[curTest].document.forms[0].submit();
} else {
var el = null;
if (curTest == 2) {
el = frames[curTest].document.getElementById('i');
} else {
el = frames[curTest].document.forms[0].elements[curTest];
}
el.focus();
el.click();
}
}
function frameLoaded(aFrame)
{
var documentLocation = location.href.replace(/\.html.*/, "\.html");
is(aFrame.contentWindow.location.href.replace(/\?x=0&y=0/, ""),
documentLocation.replace(/test_bug/, "file_bug"),
"form should have been submitted to the document location");
if (++curTest == nbTests) {
SimpleTest.finish();
} else {
nextTest();
}
}
function runTest()
{
// Initialize event handlers.
var frames = document.getElementsByTagName('iframe');
for (var i=0; i<nbTests; ++i) {
frames[i].setAttribute('onload', "frameLoaded(this);");
}
nextTest();
}
addLoadEvent(runTest);
</script>
</pre>
</body>
</html>

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

@ -22,57 +22,68 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=392567
/** Test for Bug 392567 **/ /** Test for Bug 392567 **/
var dataUrl = "http://mochi.test:8888/tests/content/html/content/test/bug392567.jar"; SimpleTest.waitForExplicitFinish();
var jarUrl = "jar:" + dataUrl + "!/index.html";
var httpUrl = location.href.replace(/\.html.*/, "_404");
var previousDir = location.href.replace(/test\/[^\/]*$/, "");
var form = document.forms.testForm; function runTests()
var frame = frames.testFrame; {
document.getElementById("testFrame").onload = processTestResult; if (window.location.search.match(/\?key=value/)) {
// List of tests to run, each test consists of form action URL and expected result URL
var tests = [
[jarUrl, jarUrl + "?$PARAMS", null],
[jarUrl + "?jarTest1=jarTest2", jarUrl + "?$PARAMS", null],
[jarUrl + "?jarTest3=jarTest4#jarTest5", jarUrl + "?$PARAMS#jarTest5", null],
["data:text/html,<html></html>", "data:text/html,<html></html>?$PARAMS", null],
["data:text/html,<html>How%20about%20this?</html>", "data:text/html,<html>How%20about%20this?$PARAMS", null],
[httpUrl, httpUrl + "?$PARAMS", null],
[httpUrl + "?httpTest1=httpTest2", httpUrl + "?$PARAMS", null ],
[httpUrl + "?httpTest3=httpTest4#httpTest5", httpUrl + "?$PARAMS#httpTest5", null],
["", jarUrl + "?key=value0", null],
[" ", jarUrl + "?key=value0", document.location],
["../", previousDir + "?$PARAMS", previousDir],
];
var currentTest = -1;
SimpleTest.waitForExplicitFinish();
runNextTest();
function runNextTest() {
currentTest++;
if (currentTest >= tests.length) {
SimpleTest.finish();
return; return;
} }
form.setAttribute("action", tests[currentTest][0]); var dataUrl = "http://mochi.test:8888/tests/content/html/content/test/bug392567.jar";
is(form.action, tests[currentTest][0], var jarUrl = "jar:" + dataUrl + "!/index.html";
"action IDL attribute should reflect the action content attribute"); var httpUrl = location.href.replace(/\.html.*/, "_404");
is(form.mozActionUri, tests[currentTest][2] ? tests[currentTest][2] : tests[currentTest][0], var previousDir = location.href.replace(/test\/[^\/]*$/, "");
"mozActionUri IDL attribute should resolve the action URI"); var documentURL = location.href.replace(/\.html.*/, "\.html");
form.key.value = "value" + currentTest;
form.submit(); var form = document.forms.testForm;
var frame = frames.testFrame;
document.getElementById("testFrame").onload = processTestResult;
// List of tests to run, each test consists of form action URL and expected result URL
var tests = [
[jarUrl, jarUrl + "?$PARAMS", null],
[jarUrl + "?jarTest1=jarTest2", jarUrl + "?$PARAMS", null],
[jarUrl + "?jarTest3=jarTest4#jarTest5", jarUrl + "?$PARAMS#jarTest5", null],
["data:text/html,<html></html>", "data:text/html,<html></html>?$PARAMS", null],
["data:text/html,<html>How%20about%20this?</html>", "data:text/html,<html>How%20about%20this?$PARAMS", null],
[httpUrl, httpUrl + "?$PARAMS", null],
[httpUrl + "?httpTest1=httpTest2", httpUrl + "?$PARAMS", null ],
[httpUrl + "?httpTest3=httpTest4#httpTest5", httpUrl + "?$PARAMS#httpTest5", null],
["", documentURL + "?$PARAMS", null],
[" ", documentURL + "?$PARAMS", document.location],
["../", previousDir + "?$PARAMS", previousDir],
];
var currentTest = -1;
runNextTest();
function runNextTest() {
currentTest++;
if (currentTest >= tests.length) {
SimpleTest.finish();
return;
}
form.setAttribute("action", tests[currentTest][0]);
is(form.action, tests[currentTest][0],
"action IDL attribute should reflect the action content attribute");
is(form.mozActionUri, tests[currentTest][2] ? tests[currentTest][2] : tests[currentTest][0],
"mozActionUri IDL attribute should resolve the action URI");
form.key.value = "value" + currentTest;
form.submit();
}
function processTestResult() {
var expected = tests[currentTest][1].replace(/\$PARAMS/, "key=value" + currentTest);
is(frame.location.href, expected, "Submitting to " + tests[currentTest][0]);
setTimeout(runNextTest, 0);
}
} }
function processTestResult() { addLoadEvent(runTests);
var expected = tests[currentTest][1].replace(/\$PARAMS/, "key=value" + currentTest);
is(frame.location.href, expected, "Submitting to " + tests[currentTest][0]);
setTimeout(runNextTest, 0);
}
</script> </script>
</pre> </pre>

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

@ -145,6 +145,7 @@ NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult)
nsXULPrototypeCache *p = result; nsXULPrototypeCache *p = result;
obsSvc->AddObserver(p, "chrome-flush-skin-caches", PR_FALSE); obsSvc->AddObserver(p, "chrome-flush-skin-caches", PR_FALSE);
obsSvc->AddObserver(p, "chrome-flush-caches", PR_FALSE); obsSvc->AddObserver(p, "chrome-flush-caches", PR_FALSE);
obsSvc->AddObserver(p, "startupcache-invalidate", PR_FALSE);
} }
return rv; return rv;
@ -410,10 +411,6 @@ nsXULPrototypeCache::AbortFastLoads()
NS_BREAK(); NS_BREAK();
#endif #endif
// Save a strong ref to the FastLoad file, so we can remove it after we
// close open streams to it.
nsCOMPtr<nsIFile> file = gFastLoadFile;
// Flush the XUL cache for good measure, in case we cached a bogus/downrev // Flush the XUL cache for good measure, in case we cached a bogus/downrev
// script, somehow. // script, somehow.
Flush(); Flush();
@ -421,29 +418,42 @@ nsXULPrototypeCache::AbortFastLoads()
// Clear the FastLoad set // Clear the FastLoad set
mFastLoadURITable.Clear(); mFastLoadURITable.Clear();
if (! gFastLoadService) nsCOMPtr<nsIFastLoadService> fastLoadService = gFastLoadService;
return; nsCOMPtr<nsIFile> file = gFastLoadFile;
nsresult rv;
if (! fastLoadService) {
fastLoadService = do_GetFastLoadService();
if (! fastLoadService)
return;
rv = fastLoadService->NewFastLoadFile(XUL_FASTLOAD_FILE_BASENAME,
getter_AddRefs(file));
if (NS_FAILED(rv))
return;
}
// Fetch the current input (if FastLoad file existed) or output (if we're // Fetch the current input (if FastLoad file existed) or output (if we're
// creating the FastLoad file during this app startup) stream. // creating the FastLoad file during this app startup) stream.
nsCOMPtr<nsIObjectInputStream> objectInput; nsCOMPtr<nsIObjectInputStream> objectInput;
nsCOMPtr<nsIObjectOutputStream> objectOutput; nsCOMPtr<nsIObjectOutputStream> objectOutput;
gFastLoadService->GetInputStream(getter_AddRefs(objectInput)); fastLoadService->GetInputStream(getter_AddRefs(objectInput));
gFastLoadService->GetOutputStream(getter_AddRefs(objectOutput)); fastLoadService->GetOutputStream(getter_AddRefs(objectOutput));
if (objectOutput) { if (objectOutput) {
gFastLoadService->SetOutputStream(nsnull); fastLoadService->SetOutputStream(nsnull);
if (NS_SUCCEEDED(objectOutput->Close()) && gChecksumXULFastLoadFile) if (NS_SUCCEEDED(objectOutput->Close()) && gChecksumXULFastLoadFile)
gFastLoadService->CacheChecksum(gFastLoadFile, fastLoadService->CacheChecksum(file,
objectOutput); objectOutput);
} }
if (objectInput) { if (objectInput) {
// If this is the last of one or more XUL master documents loaded // If this is the last of one or more XUL master documents loaded
// together at app startup, close the FastLoad service's singleton // together at app startup, close the FastLoad service's singleton
// input stream now. // input stream now.
gFastLoadService->SetInputStream(nsnull); fastLoadService->SetInputStream(nsnull);
objectInput->Close(); objectInput->Close();
} }
@ -462,13 +472,15 @@ nsXULPrototypeCache::AbortFastLoads()
} }
file->MoveToNative(nsnull, NS_LITERAL_CSTRING("Aborted.mfasl")); file->MoveToNative(nsnull, NS_LITERAL_CSTRING("Aborted.mfasl"));
#else #else
file->Remove(PR_FALSE); rv = file->Remove(PR_FALSE);
if (NS_FAILED(rv))
NS_WARNING("Failed to remove fastload file, fastload data may be outdated");
#endif #endif
} }
// If the list is empty now, the FastLoad process is done. // If the list is empty now, the FastLoad process is done.
NS_RELEASE(gFastLoadService); NS_IF_RELEASE(gFastLoadService);
NS_RELEASE(gFastLoadFile); NS_IF_RELEASE(gFastLoadFile);
} }

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

@ -1800,7 +1800,8 @@ nsFocusManager::ScrollIntoView(nsIPresShell* aPresShell,
if (!(aFlags & FLAG_NOSCROLL)) if (!(aFlags & FLAG_NOSCROLL))
aPresShell->ScrollContentIntoView(aContent, aPresShell->ScrollContentIntoView(aContent,
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE); NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
} }

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

@ -1052,7 +1052,6 @@ PluginInstanceChild::CreatePluginWindow()
return false; return false;
// Apparently some plugins require an ASCII WndProc. // Apparently some plugins require an ASCII WndProc.
printf("setting DefWindowProcA\n");
SetWindowLongPtrA(mPluginWindowHWND, GWLP_WNDPROC, SetWindowLongPtrA(mPluginWindowHWND, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(DefWindowProcA)); reinterpret_cast<LONG_PTR>(DefWindowProcA));

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

@ -57,6 +57,7 @@ public class CrashReporter extends Activity
{ {
static final String kMiniDumpPathKey = "upload_file_minidump"; static final String kMiniDumpPathKey = "upload_file_minidump";
static final String kPageURLKey = "URL"; static final String kPageURLKey = "URL";
static final String kNotesKey = "Notes";
ProgressDialog mProgressDialog; ProgressDialog mProgressDialog;
File mPendingMinidumpFile; File mPendingMinidumpFile;
File mPendingExtrasFile; File mPendingExtrasFile;
@ -230,10 +231,35 @@ public class CrashReporter extends Activity
if (key.equals(kPageURLKey)) { if (key.equals(kPageURLKey)) {
if (includeURLCheckbox.isChecked()) if (includeURLCheckbox.isChecked())
sendPart(os, boundary, key, extras.get(key)); sendPart(os, boundary, key, extras.get(key));
} else if (!key.equals("ServerURL")){ } else if (!key.equals("ServerURL") && !key.equals(kNotesKey)) {
sendPart(os, boundary, key, extras.get(key)); sendPart(os, boundary, key, extras.get(key));
} }
} }
// Add some extra information to notes so its displayed by
// crash-stats.mozilla.org. Remove this when bug 607942 is fixed.
String notes = extras.containsKey(kNotesKey) ? extras.get(kNotesKey) +
"\n" : "";
if (@MOZ_MIN_CPU_VERSION@ < 7)
notes += "nothumb Build\n";
notes += Build.MANUFACTURER + " ";
notes += Build.MODEL + "\n";
notes += Build.FINGERPRINT;
sendPart(os, boundary, kNotesKey, notes);
sendPart(os, boundary, "Min_ARM_Version", "@MOZ_MIN_CPU_VERSION@");
sendPart(os, boundary, "Android_Manufacturer", Build.MANUFACTURER);
sendPart(os, boundary, "Android_Model", Build.MODEL);
sendPart(os, boundary, "Android_Board", Build.BOARD);
sendPart(os, boundary, "Android_Brand", Build.BRAND);
sendPart(os, boundary, "Android_CPU_ABI", Build.CPU_ABI);
sendPart(os, boundary, "Android_CPU_ABI2", Build.CPU_ABI2);
sendPart(os, boundary, "Android_Device", Build.DEVICE);
sendPart(os, boundary, "Android_Display", Build.DISPLAY);
sendPart(os, boundary, "Android_Fingerprint", Build.FINGERPRINT);
sendPart(os, boundary, "Android_Hardware", Build.HARDWARE);
sendPart(os, boundary, "Android_Version", Build.VERSION.SDK_INT + " (" + Build.VERSION.CODENAME + ")");
sendFile(os, boundary, kMiniDumpPathKey, minidumpFile); sendFile(os, boundary, kMiniDumpPathKey, minidumpFile);
os.write(("\r\n--" + boundary + "--\r\n").getBytes()); os.write(("\r\n--" + boundary + "--\r\n").getBytes());
os.flush(); os.flush();

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

@ -81,7 +81,11 @@
// Because the QPainter backend has some problems with glyphs rendering // Because the QPainter backend has some problems with glyphs rendering
// it is better to use image or xlib cairo backends by default // it is better to use image or xlib cairo backends by default
#if (MOZ_PLATFORM_MAEMO == 6)
#define DEFAULT_RENDER_MODE RENDER_BUFFERED #define DEFAULT_RENDER_MODE RENDER_BUFFERED
#else
#define DEFAULT_RENDER_MODE RENDER_DIRECT
#endif
static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::X11; static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::X11;
gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nsnull; gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nsnull;
@ -146,6 +150,9 @@ gfxQtPlatform::gfxQtPlatform()
case 1: case 1:
mRenderMode = RENDER_BUFFERED; mRenderMode = RENDER_BUFFERED;
break; break;
case 2:
mRenderMode = RENDER_DIRECT;
break;
default: default:
mRenderMode = RENDER_QPAINTER; mRenderMode = RENDER_QPAINTER;
} }
@ -207,7 +214,7 @@ gfxQtPlatform::CreateOffscreenSurface(const gfxIntSize& size,
} }
#endif #endif
if (mRenderMode == RENDER_BUFFERED && if ((mRenderMode == RENDER_BUFFERED || mRenderMode == RENDER_DIRECT) &&
sDefaultQtPaintEngineType != QPaintEngine::X11) { sDefaultQtPaintEngineType != QPaintEngine::X11) {
newSurface = new gfxImageSurface(size, imageFormat); newSurface = new gfxImageSurface(size, imageFormat);
return newSurface.forget(); return newSurface.forget();

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

@ -60,6 +60,8 @@ public:
RENDER_QPAINTER = 0, RENDER_QPAINTER = 0,
/* Use offscreen buffer for rendering with image or xlib gfx backend */ /* Use offscreen buffer for rendering with image or xlib gfx backend */
RENDER_BUFFERED, RENDER_BUFFERED,
/* Direct rendering to Widget surface */
RENDER_DIRECT,
/* max */ /* max */
RENDER_MODE_MAX RENDER_MODE_MAX
}; };

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

@ -90,25 +90,29 @@ gfxWindowsNativeDrawing::BeginNativeDrawing()
(surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA && (surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA &&
(mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA)))) (mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA))))
{ {
if (mTransformType == TRANSLATION_ONLY) { // grab the DC. This can fail if there is a complex clipping path,
mRenderState = RENDER_STATE_NATIVE_DRAWING; // in which case we'll have to fall back.
mWinSurface = static_cast<gfxWindowsSurface*>(static_cast<gfxASurface*>(surf.get()));
mDC = mWinSurface->GetDCWithClip(mContext);
mTranslation = m.GetTranslation(); if (mDC) {
if (mTransformType == TRANSLATION_ONLY) {
mRenderState = RENDER_STATE_NATIVE_DRAWING;
mWinSurface = static_cast<gfxWindowsSurface*>(static_cast<gfxASurface*>(surf.get())); mTranslation = m.GetTranslation();
} else if (((mTransformType == AXIS_ALIGNED_SCALE) } else if (((mTransformType == AXIS_ALIGNED_SCALE)
&& (mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) || && (mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) ||
(mNativeDrawFlags & CAN_COMPLEX_TRANSFORM)) (mNativeDrawFlags & CAN_COMPLEX_TRANSFORM))
{ {
mWorldTransform.eM11 = (FLOAT) m.xx; mWorldTransform.eM11 = (FLOAT) m.xx;
mWorldTransform.eM12 = (FLOAT) m.yx; mWorldTransform.eM12 = (FLOAT) m.yx;
mWorldTransform.eM21 = (FLOAT) m.xy; mWorldTransform.eM21 = (FLOAT) m.xy;
mWorldTransform.eM22 = (FLOAT) m.yy; mWorldTransform.eM22 = (FLOAT) m.yy;
mWorldTransform.eDx = (FLOAT) m.x0; mWorldTransform.eDx = (FLOAT) m.x0;
mWorldTransform.eDy = (FLOAT) m.y0; mWorldTransform.eDy = (FLOAT) m.y0;
mRenderState = RENDER_STATE_NATIVE_DRAWING; mRenderState = RENDER_STATE_NATIVE_DRAWING;
mWinSurface = static_cast<gfxWindowsSurface*>(static_cast<gfxASurface*>(surf.get())); }
} }
} }
@ -156,9 +160,6 @@ gfxWindowsNativeDrawing::BeginNativeDrawing()
if (mRenderState == RENDER_STATE_NATIVE_DRAWING) { if (mRenderState == RENDER_STATE_NATIVE_DRAWING) {
// we can just do native drawing directly to the context's surface // we can just do native drawing directly to the context's surface
// grab the DC
mDC = mWinSurface->GetDCWithClip(mContext);
// do we need to use SetWorldTransform? // do we need to use SetWorldTransform?
if (mTransformType != TRANSLATION_ONLY) { if (mTransformType != TRANSLATION_ONLY) {
SetGraphicsMode(mDC, GM_ADVANCED); SetGraphicsMode(mDC, GM_ADVANCED);

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

@ -104,18 +104,6 @@ js_GetStringChars(JSContext *cx, JSString *str)
void void
JSString::flatten() JSString::flatten()
{ {
// Diagnostic: serialize all calls to this function to see
// if concurrent calls are crashing us.
JS_LOCK_RUNTIME(asCell()->compartment()->rt);
// The main body of this function can be executed only if
// the string is a rope. With multiple threads, it's possible
// we waited while another one ran, and the string has
// already been flattened for us.
if (!isRope()) {
JS_UNLOCK_RUNTIME(asCell()->compartment()->rt);
return;
}
JSString *topNode; JSString *topNode;
jschar *chars; jschar *chars;
size_t capacity; size_t capacity;
@ -193,8 +181,6 @@ JSString::flatten()
/* Set null terminator. */ /* Set null terminator. */
chars[pos] = 0; chars[pos] = 0;
topNode->initFlatMutable(chars, pos, capacity); topNode->initFlatMutable(chars, pos, capacity);
JS_UNLOCK_RUNTIME(asCell()->compartment()->rt);
} }
#ifdef JS_TRACER #ifdef JS_TRACER

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

@ -255,7 +255,7 @@ JSWrapper::obj_toString(JSContext *cx, JSObject *wrapper)
JSString *str; JSString *str;
if (!enter(cx, wrapper, JSID_VOID, GET)) if (!enter(cx, wrapper, JSID_VOID, GET))
return NULL; return NULL;
str = JSProxyHandler::obj_toString(cx, wrapper); str = obj_toStringHelper(cx, wrappedObject(wrapper));
leave(cx, wrapper); leave(cx, wrapper);
return str; return str;
} }

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

@ -1624,6 +1624,8 @@ DocumentViewerImpl::Destroy()
mPresContext = nsnull; mPresContext = nsnull;
} }
mWindow = nsnull;
mViewManager = nsnull;
mContainer = nsnull; mContainer = nsnull;
return NS_OK; return NS_OK;
@ -2679,7 +2681,8 @@ NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode)
// Tell the PresShell to scroll to the primary frame of the content. // Tell the PresShell to scroll to the primary frame of the content.
NS_ENSURE_SUCCESS(presShell->ScrollContentIntoView(content, NS_ENSURE_SUCCESS(presShell->ScrollContentIntoView(content,
NS_PRESSHELL_SCROLL_TOP, NS_PRESSHELL_SCROLL_TOP,
NS_PRESSHELL_SCROLL_ANYWHERE), NS_PRESSHELL_SCROLL_ANYWHERE,
nsIPresShell::SCROLL_OVERFLOW_HIDDEN),
NS_ERROR_FAILURE); NS_ERROR_FAILURE);
return NS_OK; return NS_OK;
} }

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

@ -22,6 +22,7 @@
* Contributor(s): * Contributor(s):
* Steve Clark <buster@netscape.com> * Steve Clark <buster@netscape.com>
* Dan Rosen <dr@netscape.com> * Dan Rosen <dr@netscape.com>
* Mihai Șucan <mihai.sucan@gmail.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"), * either of the GNU General Public License Version 2 or later (the "GPL"),
@ -139,8 +140,8 @@ typedef struct CapturingContentInfo {
} CapturingContentInfo; } CapturingContentInfo;
#define NS_IPRESSHELL_IID \ #define NS_IPRESSHELL_IID \
{ 0xb79574cd, 0x2555, 0x4b57, \ { 0xd1978bee, 0x43b9, 0x40de, \
{ 0xb3, 0xf8, 0x27, 0x57, 0x3e, 0x60, 0x74, 0x01 } } { 0x95, 0x47, 0x85, 0x06, 0x5e, 0x02, 0xec, 0xb4 } }
// Constants for ScrollContentIntoView() function // Constants for ScrollContentIntoView() function
#define NS_PRESSHELL_SCROLL_TOP 0 #define NS_PRESSHELL_SCROLL_TOP 0
@ -544,10 +545,18 @@ public:
* horizontally . A value of NS_PRESSHELL_SCROLL_ANYWHERE means move * horizontally . A value of NS_PRESSHELL_SCROLL_ANYWHERE means move
* the frame the minimum amount necessary in order for the entire * the frame the minimum amount necessary in order for the entire
* frame to be visible horizontally (if possible) * frame to be visible horizontally (if possible)
* @param aFlags If SCROLL_FIRST_ANCESTOR_ONLY is set, only the nearest
* scrollable ancestor is scrolled, otherwise all
* scrollable ancestors may be scrolled if necessary.
* If SCROLL_OVERFLOW_HIDDEN is set then we may scroll in a
* direction even if overflow:hidden is specified in that
* direction; otherwise we will not scroll in that direction
* when overflow:hidden is set for that direction.
*/ */
virtual NS_HIDDEN_(nsresult) ScrollContentIntoView(nsIContent* aContent, virtual NS_HIDDEN_(nsresult) ScrollContentIntoView(nsIContent* aContent,
PRIntn aVPercent, PRIntn aVPercent,
PRIntn aHPercent) = 0; PRIntn aHPercent,
PRUint32 aFlags) = 0;
enum { enum {
SCROLL_FIRST_ANCESTOR_ONLY = 0x01, SCROLL_FIRST_ANCESTOR_ONLY = 0x01,

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

@ -26,6 +26,7 @@
* Dan Rosen <dr@netscape.com> * Dan Rosen <dr@netscape.com>
* Daniel Glazman <glazman@netscape.com> * Daniel Glazman <glazman@netscape.com>
* Mats Palmgren <matspal@gmail.com> * Mats Palmgren <matspal@gmail.com>
* Mihai Șucan <mihai.sucan@gmail.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"), * either of the GNU General Public License Version 2 or later (the "GPL"),
@ -773,7 +774,8 @@ public:
virtual NS_HIDDEN_(nsresult) ScrollContentIntoView(nsIContent* aContent, virtual NS_HIDDEN_(nsresult) ScrollContentIntoView(nsIContent* aContent,
PRIntn aVPercent, PRIntn aVPercent,
PRIntn aHPercent); PRIntn aHPercent,
PRUint32 aFlags);
virtual PRBool ScrollFrameRectIntoView(nsIFrame* aFrame, virtual PRBool ScrollFrameRectIntoView(nsIFrame* aFrame,
const nsRect& aRect, const nsRect& aRect,
PRIntn aVPercent, PRIntn aVPercent,
@ -1005,7 +1007,8 @@ protected:
// Helper for ScrollContentIntoView // Helper for ScrollContentIntoView
void DoScrollContentIntoView(nsIContent* aContent, void DoScrollContentIntoView(nsIContent* aContent,
PRIntn aVPercent, PRIntn aVPercent,
PRIntn aHPercent); PRIntn aHPercent,
PRUint32 aFlags);
friend struct AutoRenderingStateSaveRestore; friend struct AutoRenderingStateSaveRestore;
friend struct RenderingState; friend struct RenderingState;
@ -3906,7 +3909,8 @@ PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll)
if (content) { if (content) {
if (aScroll) { if (aScroll) {
rv = ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_TOP, rv = ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_TOP,
NS_PRESSHELL_SCROLL_ANYWHERE); NS_PRESSHELL_SCROLL_ANYWHERE,
SCROLL_OVERFLOW_HIDDEN);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsIScrollableFrame* rootScroll = GetRootScrollFrameAsScrollable(); nsIScrollableFrame* rootScroll = GetRootScrollFrameAsScrollable();
@ -4013,7 +4017,8 @@ PresShell::ScrollToAnchor()
return NS_OK; return NS_OK;
nsresult rv = ScrollContentIntoView(mLastAnchorScrolledTo, NS_PRESSHELL_SCROLL_TOP, nsresult rv = ScrollContentIntoView(mLastAnchorScrolledTo, NS_PRESSHELL_SCROLL_TOP,
NS_PRESSHELL_SCROLL_ANYWHERE); NS_PRESSHELL_SCROLL_ANYWHERE,
SCROLL_OVERFLOW_HIDDEN);
mLastAnchorScrolledTo = nsnull; mLastAnchorScrolledTo = nsnull;
return rv; return rv;
} }
@ -4196,7 +4201,8 @@ static void ScrollToShowRect(nsIScrollableFrame* aScrollFrame,
nsresult nsresult
PresShell::ScrollContentIntoView(nsIContent* aContent, PresShell::ScrollContentIntoView(nsIContent* aContent,
PRIntn aVPercent, PRIntn aVPercent,
PRIntn aHPercent) PRIntn aHPercent,
PRUint32 aFlags)
{ {
nsCOMPtr<nsIContent> content = aContent; // Keep content alive while flushing. nsCOMPtr<nsIContent> content = aContent; // Keep content alive while flushing.
NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
@ -4221,7 +4227,7 @@ PresShell::ScrollContentIntoView(nsIContent* aContent,
// than a single best-effort scroll followed by one final scroll on the first // than a single best-effort scroll followed by one final scroll on the first
// completed reflow. // completed reflow.
if (mContentToScrollTo) { if (mContentToScrollTo) {
DoScrollContentIntoView(content, aVPercent, aHPercent); DoScrollContentIntoView(content, aVPercent, aHPercent, aFlags);
} }
return NS_OK; return NS_OK;
} }
@ -4229,7 +4235,8 @@ PresShell::ScrollContentIntoView(nsIContent* aContent,
void void
PresShell::DoScrollContentIntoView(nsIContent* aContent, PresShell::DoScrollContentIntoView(nsIContent* aContent,
PRIntn aVPercent, PRIntn aVPercent,
PRIntn aHPercent) PRIntn aHPercent,
PRUint32 aFlags)
{ {
NS_ASSERTION(mDidInitialReflow, "should have done initial reflow by now"); NS_ASSERTION(mDidInitialReflow, "should have done initial reflow by now");
@ -4272,7 +4279,7 @@ PresShell::DoScrollContentIntoView(nsIContent* aContent,
} while ((frame = frame->GetNextContinuation())); } while ((frame = frame->GetNextContinuation()));
ScrollFrameRectIntoView(container, frameBounds, aVPercent, aHPercent, ScrollFrameRectIntoView(container, frameBounds, aVPercent, aHPercent,
SCROLL_OVERFLOW_HIDDEN); aFlags);
} }
PRBool PRBool
@ -4873,7 +4880,8 @@ PresShell::FlushPendingNotifications(mozFlushType aType)
if (ProcessReflowCommands(aType < Flush_Layout) && mContentToScrollTo) { if (ProcessReflowCommands(aType < Flush_Layout) && mContentToScrollTo) {
// We didn't get interrupted. Go ahead and scroll to our content // We didn't get interrupted. Go ahead and scroll to our content
DoScrollContentIntoView(mContentToScrollTo, mContentScrollVPosition, DoScrollContentIntoView(mContentToScrollTo, mContentScrollVPosition,
mContentScrollHPosition); mContentScrollHPosition,
SCROLL_OVERFLOW_HIDDEN);
mContentToScrollTo = nsnull; mContentToScrollTo = nsnull;
} }
} }
@ -7161,7 +7169,8 @@ PresShell::PrepareToUseCaretPosition(nsIWidget* aEventWidget, nsIntPoint& aTarge
// an edit box below the current view, you'll get the edit box aligned with // an edit box below the current view, you'll get the edit box aligned with
// the top of the window. This is arguably better behavior anyway. // the top of the window. This is arguably better behavior anyway.
rv = ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE, rv = ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE); NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
SCROLL_OVERFLOW_HIDDEN);
NS_ENSURE_SUCCESS(rv, PR_FALSE); NS_ENSURE_SUCCESS(rv, PR_FALSE);
frame = content->GetPrimaryFrame(); frame = content->GetPrimaryFrame();
NS_WARN_IF_FALSE(frame, "No frame for focused content?"); NS_WARN_IF_FALSE(frame, "No frame for focused content?");
@ -7224,7 +7233,8 @@ PresShell::GetCurrentItemAndPositionForElement(nsIDOMElement *aCurrentEl,
{ {
nsCOMPtr<nsIContent> focusedContent(do_QueryInterface(aCurrentEl)); nsCOMPtr<nsIContent> focusedContent(do_QueryInterface(aCurrentEl));
ScrollContentIntoView(focusedContent, NS_PRESSHELL_SCROLL_ANYWHERE, ScrollContentIntoView(focusedContent, NS_PRESSHELL_SCROLL_ANYWHERE,
NS_PRESSHELL_SCROLL_ANYWHERE); NS_PRESSHELL_SCROLL_ANYWHERE,
SCROLL_OVERFLOW_HIDDEN);
nsPresContext* presContext = GetPresContext(); nsPresContext* presContext = GetPresContext();

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

@ -54,6 +54,33 @@ function sendMouseUp(el) {
utils.sendMouseEvent('mouseup', rect.left + 5, rect.top + 5, 0, 1, 0); utils.sendMouseEvent('mouseup', rect.left + 5, rect.top + 5, 0, 1, 0);
} }
function fireEvent(target, event) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var utils =
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.dispatchDOMEventViaPresShell(target, event, true);
}
function fireDrop(element) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var ds = Components.classes["@mozilla.org/widget/dragservice;1"].
getService(Components.interfaces.nsIDragService);
ds.startDragSession();
var event = document.createEvent("DragEvents");
event.initDragEvent("dragover", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, null);
fireEvent(element, event);
event = document.createEvent("DragEvents");
event.initDragEvent("drop", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, null);
fireEvent(element, event);
ds.endDragSession(false);
ok(!ds.getCurrentSession(), "There shouldn't be a drag session anymore!");
}
function runTest() { function runTest() {
var d1 = document.getElementById("d1"); var d1 = document.getElementById("d1");
var didGetMouseMove = false; var didGetMouseMove = false;
@ -65,7 +92,27 @@ function runTest() {
true); true);
sendMouseMoveFaraway(d1); sendMouseMoveFaraway(d1);
ok(didGetMouseMove, "Should have got mousemove!"); ok(didGetMouseMove, "Should have got mousemove!");
sendMouseUp(d1) sendMouseUp(d1);
didGetMouseMove = false;
document.addEventListener("mousedown",
function (e) {
e.preventDefault();
},
true);
sendMouseDown(d1);
sendMouseMoveFaraway(d1);
ok(didGetMouseMove, "Should have got mousemove! (2)");
sendMouseUp(d1);
didGetMouseMove = false;
sendMouseDown(d1);
fireDrop(d1);
sendMouseMoveFaraway(d1);
ok(!didGetMouseMove, "Shouldn't have got mousemove!");
SimpleTest.finish(); SimpleTest.finish();
} }

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

@ -365,6 +365,7 @@ public:
static void RemoveFromCARefreshTimer(nsPluginInstanceOwner *aPluginInstance); static void RemoveFromCARefreshTimer(nsPluginInstanceOwner *aPluginInstance);
void SetupCARefresh(); void SetupCARefresh();
void* FixUpPluginWindow(PRInt32 inPaintState); void* FixUpPluginWindow(PRInt32 inPaintState);
void HidePluginWindow();
// Set a flag that (if true) indicates the plugin port info has changed and // Set a flag that (if true) indicates the plugin port info has changed and
// SetWindow() needs to be called. // SetWindow() needs to be called.
void SetPluginPortChanged(PRBool aState) { mPluginPortChanged = aState; } void SetPluginPortChanged(PRBool aState) { mPluginPortChanged = aState; }
@ -1102,8 +1103,6 @@ nsObjectFrame::CallSetWindow()
if (IsHidden()) if (IsHidden())
return; return;
PRBool windowless = (window->type == NPWindowTypeDrawable);
// refresh the plugin port as well // refresh the plugin port as well
window->window = mInstanceOwner->GetPluginPortFromWidget(); window->window = mInstanceOwner->GetPluginPortFromWidget();
@ -2463,7 +2462,11 @@ DoStopPlugin(nsPluginInstanceOwner *aInstanceOwner, PRBool aDelayedStop)
if (DoDelayedStop(aInstanceOwner, aDelayedStop)) if (DoDelayedStop(aInstanceOwner, aDelayedStop))
return; return;
#if defined(XP_MACOSX)
aInstanceOwner->HidePluginWindow();
#endif
inst->Stop(); inst->Stop();
nsCOMPtr<nsIPluginHost> pluginHost = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID); nsCOMPtr<nsIPluginHost> pluginHost = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
@ -2554,7 +2557,6 @@ nsObjectFrame::StopPluginInternal(PRBool aDelayedStop)
nsTArray<nsIWidget::Configuration> configurations; nsTArray<nsIWidget::Configuration> configurations;
GetEmptyClipConfiguration(&configurations); GetEmptyClipConfiguration(&configurations);
parent->ConfigureChildren(configurations); parent->ConfigureChildren(configurations);
DidSetWidgetGeometry();
} }
} }
else { else {
@ -6429,6 +6431,19 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
return nsnull; return nsnull;
} }
void
nsPluginInstanceOwner::HidePluginWindow()
{
if (!mPluginWindow || !mInstance) {
return;
}
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
mWidgetVisible = PR_FALSE;
mInstance->SetWindow(mPluginWindow);
}
#endif // XP_MACOSX #endif // XP_MACOSX
// Little helper function to resolve relative URL in // Little helper function to resolve relative URL in

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

@ -196,7 +196,8 @@ inFlasher::ScrollElementIntoView(nsIDOMElement *aElement)
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement); nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
presShell->ScrollContentIntoView(content, presShell->ScrollContentIntoView(content,
NS_PRESSHELL_SCROLL_ANYWHERE /* VPercent */, NS_PRESSHELL_SCROLL_ANYWHERE /* VPercent */,
NS_PRESSHELL_SCROLL_ANYWHERE /* HPercent */); NS_PRESSHELL_SCROLL_ANYWHERE /* HPercent */,
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
return NS_OK; return NS_OK;
} }

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

@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="padding:50px; border-radius:50px; width:400px; height:400px;">
<input type="radio">
<input type="checkbox">
</div>
</body>
</html>

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

@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="padding:50px; border-radius:50px; width:400px; height:400px; overflow:hidden;">
<input type="radio">
<input type="checkbox">
</div>
</body>
</html>

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

@ -61,4 +61,6 @@ skip-if(gtk2Widget) random-if(d2d) == resizer-bottomend-rtl.xul resizer-bottomen
skip-if(!winWidget) == scroll-thumb-minimum-size-notheme.html scroll-thumb-minimum-size-notheme-ref.html skip-if(!winWidget) == scroll-thumb-minimum-size-notheme.html scroll-thumb-minimum-size-notheme-ref.html
# skip-if(!winWidget) == scroll-thumb-minimum-size-theme.html scroll-thumb-minimum-size-theme-ref.html # Bug 512206 # skip-if(!winWidget) == scroll-thumb-minimum-size-theme.html scroll-thumb-minimum-size-theme-ref.html # Bug 512206
== border-radius.html border-radius-ref.html
== checkbox-dynamic-1.html checkbox-dynamic-1-ref.html == checkbox-dynamic-1.html checkbox-dynamic-1-ref.html

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

@ -21,6 +21,7 @@
* *
* Contributor(s): * Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com) * Original Author: David W. Hyatt (hyatt@netscape.com)
* Mihai Șucan <mihai.sucan@gmail.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"), * either of the GNU General Public License Version 2 or later (the "GPL"),
@ -254,56 +255,18 @@ NS_IMETHODIMP nsScrollBoxObject::ScrollToLine(PRInt32 line)
NS_IMETHODIMP nsScrollBoxObject::ScrollToElement(nsIDOMElement *child) NS_IMETHODIMP nsScrollBoxObject::ScrollToElement(nsIDOMElement *child)
{ {
NS_ENSURE_ARG_POINTER(child); NS_ENSURE_ARG_POINTER(child);
nsIScrollableFrame* sf = GetScrollFrame();
if (!sf)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPresShell> shell = GetPresShell(PR_FALSE); nsCOMPtr<nsIPresShell> shell = GetPresShell(PR_FALSE);
if (!shell) { if (!shell) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
nsIFrame* scrolledBox = GetScrolledBox(this); nsCOMPtr<nsIContent> content = do_QueryInterface(child);
if (!scrolledBox) shell->ScrollContentIntoView(content,
return NS_ERROR_FAILURE; NS_PRESSHELL_SCROLL_TOP,
NS_PRESSHELL_SCROLL_LEFT,
nsRect rect, crect; nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY |
nsCOMPtr<nsIDOMDocument> doc; nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
child->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDocument> nsDoc(do_QueryInterface(doc));
if(!nsDoc)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIBoxObject> childBoxObject;
nsDoc->GetBoxObjectFor(child, getter_AddRefs(childBoxObject));
if(!childBoxObject)
return NS_ERROR_UNEXPECTED;
PRInt32 x,y;
childBoxObject->GetX(&x);
childBoxObject->GetY(&y);
// get the twips rectangle from the boxobject (which has pixels)
rect.x = nsPresContext::CSSPixelsToAppUnits(x);
rect.y = nsPresContext::CSSPixelsToAppUnits(y);
// TODO: make sure the child is inside the box
// get our current info
nsPoint cp = sf->GetScrollPosition();
nsIntRect prect;
GetOffsetRect(prect);
crect = prect.ToAppUnits(nsPresContext::AppUnitsPerCSSPixel());
nscoord newx=cp.x, newy=cp.y;
// we only scroll in the direction of the scrollbox orientation
// always scroll to left or top edge of child element
if (scrolledBox->IsHorizontal()) {
newx = rect.x - crect.x;
} else {
newy = rect.y - crect.y;
}
// scroll away
sf->ScrollTo(nsPoint(newx, newy), nsIScrollableFrame::INSTANT);
return NS_OK; return NS_OK;
} }
@ -347,68 +310,17 @@ NS_IMETHODIMP nsScrollBoxObject::EnsureElementIsVisible(nsIDOMElement *child)
{ {
NS_ENSURE_ARG_POINTER(child); NS_ENSURE_ARG_POINTER(child);
// Start with getting info about the child, since that will flush nsCOMPtr<nsIPresShell> shell = GetPresShell(PR_FALSE);
// layout and possibly destroy scrollable views, presshells, etc. if (!shell) {
nsCOMPtr<nsIDOMDocument> doc;
// XXXbz sXBL/XBL2 issue -- which document?
child->GetOwnerDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDocument> nsDoc(do_QueryInterface(doc));
if(!nsDoc)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIBoxObject> childBoxObject;
nsDoc->GetBoxObjectFor(child, getter_AddRefs(childBoxObject));
if(!childBoxObject)
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
PRInt32 x, y, width, height;
childBoxObject->GetX(&x);
childBoxObject->GetY(&y);
childBoxObject->GetWidth(&width);
childBoxObject->GetHeight(&height);
nsIScrollableFrame* sf = GetScrollFrame();
if (!sf)
return NS_ERROR_FAILURE;
nsIFrame* scrolledBox = GetScrolledBox(this);
if (!scrolledBox)
return NS_ERROR_FAILURE;
nsRect rect, crect;
// get the twips rectangle from the boxobject (which has pixels)
rect.x = nsPresContext::CSSPixelsToAppUnits(x);
rect.y = nsPresContext::CSSPixelsToAppUnits(y);
rect.width = nsPresContext::CSSPixelsToAppUnits(width);
rect.height = nsPresContext::CSSPixelsToAppUnits(height);
// TODO: make sure the child is inside the box
// get our current info
nsPoint cp = sf->GetScrollPosition();
nsIntRect prect;
GetOffsetRect(prect);
crect = prect.ToAppUnits(nsPresContext::AppUnitsPerCSSPixel());
nscoord newx=cp.x, newy=cp.y;
// we only scroll in the direction of the scrollbox orientation
if (scrolledBox->IsHorizontal()) {
if ((rect.x - crect.x) + rect.width > cp.x + crect.width) {
newx = cp.x + (((rect.x - crect.x) + rect.width)-(cp.x + crect.width));
} else if (rect.x - crect.x < cp.x) {
newx = rect.x - crect.x;
}
} else {
if ((rect.y - crect.y) + rect.height > cp.y + crect.height) {
newy = cp.y + (((rect.y - crect.y) + rect.height)-(cp.y + crect.height));
} else if (rect.y - crect.y < cp.y) {
newy = rect.y - crect.y;
}
} }
// scroll away nsCOMPtr<nsIContent> content = do_QueryInterface(child);
sf->ScrollTo(nsPoint(newx, newy), nsIScrollableFrame::INSTANT); shell->ScrollContentIntoView(content,
NS_PRESSHELL_SCROLL_ANYWHERE,
NS_PRESSHELL_SCROLL_ANYWHERE,
nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY |
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
return NS_OK; return NS_OK;
} }

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

@ -99,7 +99,7 @@ nsServerSocket::~nsServerSocket()
void void
nsServerSocket::OnMsgClose() nsServerSocket::OnMsgClose()
{ {
LOG(("nsServerSocket::OnMsgClose [this=%p]\n", this)); SOCKET_LOG(("nsServerSocket::OnMsgClose [this=%p]\n", this));
if (NS_FAILED(mCondition)) if (NS_FAILED(mCondition))
return; return;
@ -116,7 +116,7 @@ nsServerSocket::OnMsgClose()
void void
nsServerSocket::OnMsgAttach() nsServerSocket::OnMsgAttach()
{ {
LOG(("nsServerSocket::OnMsgAttach [this=%p]\n", this)); SOCKET_LOG(("nsServerSocket::OnMsgAttach [this=%p]\n", this));
if (NS_FAILED(mCondition)) if (NS_FAILED(mCondition))
return; return;

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

@ -140,7 +140,7 @@ static PRErrorCode RandomizeConnectError(PRErrorCode code)
}; };
n = n % (sizeof(errors)/sizeof(errors[0])); n = n % (sizeof(errors)/sizeof(errors[0]));
code = errors[n].err_code; code = errors[n].err_code;
LOG(("simulating NSPR error %d [%s]\n", code, errors[n].err_name)); SOCKET_LOG(("simulating NSPR error %d [%s]\n", code, errors[n].err_name));
} }
return code; return code;
} }
@ -202,7 +202,7 @@ ErrorAccordingToNSPR(PRErrorCode errorCode)
rv = GetXPCOMFromNSSError(errorCode); rv = GetXPCOMFromNSSError(errorCode);
break; break;
} }
LOG(("ErrorAccordingToNSPR [in=%d out=%x]\n", errorCode, rv)); SOCKET_LOG(("ErrorAccordingToNSPR [in=%d out=%x]\n", errorCode, rv));
return rv; return rv;
} }
@ -230,7 +230,7 @@ nsSocketInputStream::~nsSocketInputStream()
void void
nsSocketInputStream::OnSocketReady(nsresult condition) nsSocketInputStream::OnSocketReady(nsresult condition)
{ {
LOG(("nsSocketInputStream::OnSocketReady [this=%x cond=%x]\n", SOCKET_LOG(("nsSocketInputStream::OnSocketReady [this=%x cond=%x]\n",
this, condition)); this, condition));
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@ -284,7 +284,7 @@ nsSocketInputStream::Close()
NS_IMETHODIMP NS_IMETHODIMP
nsSocketInputStream::Available(PRUint32 *avail) nsSocketInputStream::Available(PRUint32 *avail)
{ {
LOG(("nsSocketInputStream::Available [this=%x]\n", this)); SOCKET_LOG(("nsSocketInputStream::Available [this=%x]\n", this));
*avail = 0; *avail = 0;
@ -329,7 +329,7 @@ nsSocketInputStream::Available(PRUint32 *avail)
NS_IMETHODIMP NS_IMETHODIMP
nsSocketInputStream::Read(char *buf, PRUint32 count, PRUint32 *countRead) nsSocketInputStream::Read(char *buf, PRUint32 count, PRUint32 *countRead)
{ {
LOG(("nsSocketInputStream::Read [this=%x count=%u]\n", this, count)); SOCKET_LOG(("nsSocketInputStream::Read [this=%x count=%u]\n", this, count));
*countRead = 0; *countRead = 0;
@ -345,14 +345,14 @@ nsSocketInputStream::Read(char *buf, PRUint32 count, PRUint32 *countRead)
return NS_BASE_STREAM_WOULD_BLOCK; return NS_BASE_STREAM_WOULD_BLOCK;
} }
LOG((" calling PR_Read [count=%u]\n", count)); SOCKET_LOG((" calling PR_Read [count=%u]\n", count));
// cannot hold lock while calling NSPR. (worried about the fact that PSM // cannot hold lock while calling NSPR. (worried about the fact that PSM
// synchronously proxies notifications over to the UI thread, which could // synchronously proxies notifications over to the UI thread, which could
// mistakenly try to re-enter this code.) // mistakenly try to re-enter this code.)
PRInt32 n = PR_Read(fd, buf, count); PRInt32 n = PR_Read(fd, buf, count);
LOG((" PR_Read returned [n=%d]\n", n)); SOCKET_LOG((" PR_Read returned [n=%d]\n", n));
nsresult rv; nsresult rv;
{ {
@ -403,7 +403,7 @@ nsSocketInputStream::IsNonBlocking(PRBool *nonblocking)
NS_IMETHODIMP NS_IMETHODIMP
nsSocketInputStream::CloseWithStatus(nsresult reason) nsSocketInputStream::CloseWithStatus(nsresult reason)
{ {
LOG(("nsSocketInputStream::CloseWithStatus [this=%x reason=%x]\n", this, reason)); SOCKET_LOG(("nsSocketInputStream::CloseWithStatus [this=%x reason=%x]\n", this, reason));
// may be called from any thread // may be called from any thread
@ -427,7 +427,7 @@ nsSocketInputStream::AsyncWait(nsIInputStreamCallback *callback,
PRUint32 amount, PRUint32 amount,
nsIEventTarget *target) nsIEventTarget *target)
{ {
LOG(("nsSocketInputStream::AsyncWait [this=%x]\n", this)); SOCKET_LOG(("nsSocketInputStream::AsyncWait [this=%x]\n", this));
// This variable will be non-null when we want to call the callback // This variable will be non-null when we want to call the callback
// directly from this function, but outside the lock. // directly from this function, but outside the lock.
@ -489,7 +489,7 @@ nsSocketOutputStream::~nsSocketOutputStream()
void void
nsSocketOutputStream::OnSocketReady(nsresult condition) nsSocketOutputStream::OnSocketReady(nsresult condition)
{ {
LOG(("nsSocketOutputStream::OnSocketReady [this=%x cond=%x]\n", SOCKET_LOG(("nsSocketOutputStream::OnSocketReady [this=%x cond=%x]\n",
this, condition)); this, condition));
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@ -549,7 +549,7 @@ nsSocketOutputStream::Flush()
NS_IMETHODIMP NS_IMETHODIMP
nsSocketOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *countWritten) nsSocketOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *countWritten)
{ {
LOG(("nsSocketOutputStream::Write [this=%x count=%u]\n", this, count)); SOCKET_LOG(("nsSocketOutputStream::Write [this=%x count=%u]\n", this, count));
*countWritten = 0; *countWritten = 0;
@ -568,14 +568,14 @@ nsSocketOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *countWrit
return NS_BASE_STREAM_WOULD_BLOCK; return NS_BASE_STREAM_WOULD_BLOCK;
} }
LOG((" calling PR_Write [count=%u]\n", count)); SOCKET_LOG((" calling PR_Write [count=%u]\n", count));
// cannot hold lock while calling NSPR. (worried about the fact that PSM // cannot hold lock while calling NSPR. (worried about the fact that PSM
// synchronously proxies notifications over to the UI thread, which could // synchronously proxies notifications over to the UI thread, which could
// mistakenly try to re-enter this code.) // mistakenly try to re-enter this code.)
PRInt32 n = PR_Write(fd, buf, count); PRInt32 n = PR_Write(fd, buf, count);
LOG((" PR_Write returned [n=%d]\n", n)); SOCKET_LOG((" PR_Write returned [n=%d]\n", n));
NS_ASSERTION(n != 0, "unexpected return value"); NS_ASSERTION(n != 0, "unexpected return value");
nsresult rv; nsresult rv;
@ -645,7 +645,7 @@ nsSocketOutputStream::IsNonBlocking(PRBool *nonblocking)
NS_IMETHODIMP NS_IMETHODIMP
nsSocketOutputStream::CloseWithStatus(nsresult reason) nsSocketOutputStream::CloseWithStatus(nsresult reason)
{ {
LOG(("nsSocketOutputStream::CloseWithStatus [this=%x reason=%x]\n", this, reason)); SOCKET_LOG(("nsSocketOutputStream::CloseWithStatus [this=%x reason=%x]\n", this, reason));
// may be called from any thread // may be called from any thread
@ -669,7 +669,7 @@ nsSocketOutputStream::AsyncWait(nsIOutputStreamCallback *callback,
PRUint32 amount, PRUint32 amount,
nsIEventTarget *target) nsIEventTarget *target)
{ {
LOG(("nsSocketOutputStream::AsyncWait [this=%x]\n", this)); SOCKET_LOG(("nsSocketOutputStream::AsyncWait [this=%x]\n", this));
{ {
nsAutoLock lock(mTransport->mLock); nsAutoLock lock(mTransport->mLock);
@ -721,7 +721,7 @@ nsSocketTransport::nsSocketTransport()
, mOutput(this) , mOutput(this)
, mQoSBits(0x00) , mQoSBits(0x00)
{ {
LOG(("creating nsSocketTransport @%x\n", this)); SOCKET_LOG(("creating nsSocketTransport @%x\n", this));
NS_ADDREF(gSocketTransportService); NS_ADDREF(gSocketTransportService);
@ -731,7 +731,7 @@ nsSocketTransport::nsSocketTransport()
nsSocketTransport::~nsSocketTransport() nsSocketTransport::~nsSocketTransport()
{ {
LOG(("destroying nsSocketTransport @%x\n", this)); SOCKET_LOG(("destroying nsSocketTransport @%x\n", this));
// cleanup socket type info // cleanup socket type info
if (mTypes) { if (mTypes) {
@ -779,7 +779,7 @@ nsSocketTransport::Init(const char **types, PRUint32 typeCount,
proxyType = nsnull; proxyType = nsnull;
} }
LOG(("nsSocketTransport::Init [this=%x host=%s:%hu proxy=%s:%hu]\n", SOCKET_LOG(("nsSocketTransport::Init [this=%x host=%s:%hu proxy=%s:%hu]\n",
this, mHost.get(), mPort, mProxyHost.get(), mProxyPort)); this, mHost.get(), mPort, mProxyHost.get(), mProxyPort));
// include proxy type as a socket type if proxy type is not "http" // include proxy type as a socket type if proxy type is not "http"
@ -869,7 +869,7 @@ nsSocketTransport::InitWithConnectedSocket(PRFileDesc *fd, const PRNetAddr *addr
opt.value.non_blocking = PR_TRUE; opt.value.non_blocking = PR_TRUE;
PR_SetSocketOption(mFD, &opt); PR_SetSocketOption(mFD, &opt);
LOG(("nsSocketTransport::InitWithConnectedSocket [this=%p addr=%s:%hu]\n", SOCKET_LOG(("nsSocketTransport::InitWithConnectedSocket [this=%p addr=%s:%hu]\n",
this, mHost.get(), mPort)); this, mHost.get(), mPort));
// jump to InitiateSocket to get ourselves attached to the STS poll list. // jump to InitiateSocket to get ourselves attached to the STS poll list.
@ -879,7 +879,7 @@ nsSocketTransport::InitWithConnectedSocket(PRFileDesc *fd, const PRNetAddr *addr
nsresult nsresult
nsSocketTransport::PostEvent(PRUint32 type, nsresult status, nsISupports *param) nsSocketTransport::PostEvent(PRUint32 type, nsresult status, nsISupports *param)
{ {
LOG(("nsSocketTransport::PostEvent [this=%p type=%u status=%x param=%p]\n", SOCKET_LOG(("nsSocketTransport::PostEvent [this=%p type=%u status=%x param=%p]\n",
this, type, status, param)); this, type, status, param));
nsCOMPtr<nsIRunnable> event = new nsSocketEvent(this, type, status, param); nsCOMPtr<nsIRunnable> event = new nsSocketEvent(this, type, status, param);
@ -892,7 +892,7 @@ nsSocketTransport::PostEvent(PRUint32 type, nsresult status, nsISupports *param)
void void
nsSocketTransport::SendStatus(nsresult status) nsSocketTransport::SendStatus(nsresult status)
{ {
LOG(("nsSocketTransport::SendStatus [this=%x status=%x]\n", this, status)); SOCKET_LOG(("nsSocketTransport::SendStatus [this=%x status=%x]\n", this, status));
nsCOMPtr<nsITransportEventSink> sink; nsCOMPtr<nsITransportEventSink> sink;
PRUint64 progress; PRUint64 progress;
@ -918,7 +918,7 @@ nsSocketTransport::SendStatus(nsresult status)
nsresult nsresult
nsSocketTransport::ResolveHost() nsSocketTransport::ResolveHost()
{ {
LOG(("nsSocketTransport::ResolveHost [this=%x]\n", this)); SOCKET_LOG(("nsSocketTransport::ResolveHost [this=%x]\n", this));
nsresult rv; nsresult rv;
@ -955,7 +955,7 @@ nsSocketTransport::ResolveHost()
rv = dns->AsyncResolve(SocketHost(), dnsFlags, this, nsnull, rv = dns->AsyncResolve(SocketHost(), dnsFlags, this, nsnull,
getter_AddRefs(mDNSRequest)); getter_AddRefs(mDNSRequest));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
LOG((" advancing to STATE_RESOLVING\n")); SOCKET_LOG((" advancing to STATE_RESOLVING\n"));
mState = STATE_RESOLVING; mState = STATE_RESOLVING;
// only report that we are resolving if we are still resolving... // only report that we are resolving if we are still resolving...
if (mResolving) if (mResolving)
@ -967,7 +967,7 @@ nsSocketTransport::ResolveHost()
nsresult nsresult
nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool &usingSSL) nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool &usingSSL)
{ {
LOG(("nsSocketTransport::BuildSocket [this=%x]\n", this)); SOCKET_LOG(("nsSocketTransport::BuildSocket [this=%x]\n", this));
nsresult rv; nsresult rv;
@ -995,7 +995,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool
for (i=0; i<mTypeCount; ++i) { for (i=0; i<mTypeCount; ++i) {
nsCOMPtr<nsISocketProvider> provider; nsCOMPtr<nsISocketProvider> provider;
LOG((" pushing io layer [%u:%s]\n", i, mTypes[i])); SOCKET_LOG((" pushing io layer [%u:%s]\n", i, mTypes[i]));
rv = spserv->GetSocketProvider(mTypes[i], getter_AddRefs(provider)); rv = spserv->GetSocketProvider(mTypes[i], getter_AddRefs(provider));
if (NS_FAILED(rv)) if (NS_FAILED(rv))
@ -1043,7 +1043,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool
nsAutoLock lock(mLock); nsAutoLock lock(mLock);
mSecInfo = secinfo; mSecInfo = secinfo;
callbacks = mCallbacks; callbacks = mCallbacks;
LOG((" [secinfo=%x callbacks=%x]\n", mSecInfo.get(), mCallbacks.get())); SOCKET_LOG((" [secinfo=%x callbacks=%x]\n", mSecInfo.get(), mCallbacks.get()));
} }
// don't call into PSM while holding mLock!! // don't call into PSM while holding mLock!!
nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(secinfo)); nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(secinfo));
@ -1063,7 +1063,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool
} }
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
LOG((" error pushing io layer [%u:%s rv=%x]\n", i, mTypes[i], rv)); SOCKET_LOG((" error pushing io layer [%u:%s rv=%x]\n", i, mTypes[i], rv));
if (fd) if (fd)
PR_Close(fd); PR_Close(fd);
} }
@ -1075,7 +1075,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool
nsresult nsresult
nsSocketTransport::InitiateSocket() nsSocketTransport::InitiateSocket()
{ {
LOG(("nsSocketTransport::InitiateSocket [this=%x]\n", this)); SOCKET_LOG(("nsSocketTransport::InitiateSocket [this=%x]\n", this));
nsresult rv; nsresult rv;
@ -1118,7 +1118,7 @@ nsSocketTransport::InitiateSocket()
rv = BuildSocket(fd, proxyTransparent, usingSSL); rv = BuildSocket(fd, proxyTransparent, usingSSL);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
LOG((" BuildSocket failed [rv=%x]\n", rv)); SOCKET_LOG((" BuildSocket failed [rv=%x]\n", rv));
return rv; return rv;
} }
@ -1165,16 +1165,16 @@ nsSocketTransport::InitiateSocket()
mFDconnected = PR_FALSE; mFDconnected = PR_FALSE;
} }
LOG((" advancing to STATE_CONNECTING\n")); SOCKET_LOG((" advancing to STATE_CONNECTING\n"));
mState = STATE_CONNECTING; mState = STATE_CONNECTING;
mPollTimeout = mTimeouts[TIMEOUT_CONNECT]; mPollTimeout = mTimeouts[TIMEOUT_CONNECT];
SendStatus(STATUS_CONNECTING_TO); SendStatus(STATUS_CONNECTING_TO);
#if defined(PR_LOGGING) #if defined(PR_LOGGING)
if (LOG_ENABLED()) { if (SOCKET_LOG_ENABLED()) {
char buf[64]; char buf[64];
PR_NetAddrToString(&mNetAddr, buf, sizeof(buf)); PR_NetAddrToString(&mNetAddr, buf, sizeof(buf));
LOG((" trying address: %s\n", buf)); SOCKET_LOG((" trying address: %s\n", buf));
} }
#endif #endif
@ -1215,7 +1215,7 @@ nsSocketTransport::InitiateSocket()
nsCOMPtr<nsISSLSocketControl> secCtrl = nsCOMPtr<nsISSLSocketControl> secCtrl =
do_QueryInterface(mSecInfo); do_QueryInterface(mSecInfo);
if (secCtrl) { if (secCtrl) {
LOG((" calling ProxyStartSSL()\n")); SOCKET_LOG((" calling ProxyStartSSL()\n"));
secCtrl->ProxyStartSSL(); secCtrl->ProxyStartSSL();
} }
// XXX what if we were forced to poll on the socket for a successful // XXX what if we were forced to poll on the socket for a successful
@ -1243,7 +1243,7 @@ nsSocketTransport::RecoverFromError()
{ {
NS_ASSERTION(NS_FAILED(mCondition), "there should be something wrong"); NS_ASSERTION(NS_FAILED(mCondition), "there should be something wrong");
LOG(("nsSocketTransport::RecoverFromError [this=%x state=%x cond=%x]\n", SOCKET_LOG(("nsSocketTransport::RecoverFromError [this=%x state=%x cond=%x]\n",
this, mState, mCondition)); this, mState, mCondition));
// can only recover from errors in these states // can only recover from errors in these states
@ -1267,7 +1267,7 @@ nsSocketTransport::RecoverFromError()
if (mState == STATE_CONNECTING && mDNSRecord) { if (mState == STATE_CONNECTING && mDNSRecord) {
nsresult rv = mDNSRecord->GetNextAddr(SocketPort(), &mNetAddr); nsresult rv = mDNSRecord->GetNextAddr(SocketPort(), &mNetAddr);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
LOG((" trying again with next ip address\n")); SOCKET_LOG((" trying again with next ip address\n"));
tryAgain = PR_TRUE; tryAgain = PR_TRUE;
} }
} }
@ -1311,7 +1311,7 @@ nsSocketTransport::RecoverFromError()
void void
nsSocketTransport::OnMsgInputClosed(nsresult reason) nsSocketTransport::OnMsgInputClosed(nsresult reason)
{ {
LOG(("nsSocketTransport::OnMsgInputClosed [this=%x reason=%x]\n", SOCKET_LOG(("nsSocketTransport::OnMsgInputClosed [this=%x reason=%x]\n",
this, reason)); this, reason));
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@ -1333,7 +1333,7 @@ nsSocketTransport::OnMsgInputClosed(nsresult reason)
void void
nsSocketTransport::OnMsgOutputClosed(nsresult reason) nsSocketTransport::OnMsgOutputClosed(nsresult reason)
{ {
LOG(("nsSocketTransport::OnMsgOutputClosed [this=%x reason=%x]\n", SOCKET_LOG(("nsSocketTransport::OnMsgOutputClosed [this=%x reason=%x]\n",
this, reason)); this, reason));
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@ -1354,7 +1354,7 @@ nsSocketTransport::OnMsgOutputClosed(nsresult reason)
void void
nsSocketTransport::OnSocketConnected() nsSocketTransport::OnSocketConnected()
{ {
LOG((" advancing to STATE_TRANSFERRING\n")); SOCKET_LOG((" advancing to STATE_TRANSFERRING\n"));
mPollFlags = (PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT); mPollFlags = (PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT);
mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE]; mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE];
@ -1391,7 +1391,7 @@ nsSocketTransport::ReleaseFD_Locked(PRFileDesc *fd)
NS_ASSERTION(mFD == fd, "wrong fd"); NS_ASSERTION(mFD == fd, "wrong fd");
if (--mFDref == 0) { if (--mFDref == 0) {
LOG(("nsSocketTransport: calling PR_Close [this=%x]\n", this)); SOCKET_LOG(("nsSocketTransport: calling PR_Close [this=%x]\n", this));
PR_Close(mFD); PR_Close(mFD);
mFD = nsnull; mFD = nsnull;
} }
@ -1403,12 +1403,12 @@ nsSocketTransport::ReleaseFD_Locked(PRFileDesc *fd)
void void
nsSocketTransport::OnSocketEvent(PRUint32 type, nsresult status, nsISupports *param) nsSocketTransport::OnSocketEvent(PRUint32 type, nsresult status, nsISupports *param)
{ {
LOG(("nsSocketTransport::OnSocketEvent [this=%p type=%u status=%x param=%p]\n", SOCKET_LOG(("nsSocketTransport::OnSocketEvent [this=%p type=%u status=%x param=%p]\n",
this, type, status, param)); this, type, status, param));
if (NS_FAILED(mCondition)) { if (NS_FAILED(mCondition)) {
// block event since we're apparently already dead. // block event since we're apparently already dead.
LOG((" blocking event [condition=%x]\n", mCondition)); SOCKET_LOG((" blocking event [condition=%x]\n", mCondition));
// //
// notify input/output streams in case either has a pending notify. // notify input/output streams in case either has a pending notify.
// //
@ -1419,7 +1419,7 @@ nsSocketTransport::OnSocketEvent(PRUint32 type, nsresult status, nsISupports *pa
switch (type) { switch (type) {
case MSG_ENSURE_CONNECT: case MSG_ENSURE_CONNECT:
LOG((" MSG_ENSURE_CONNECT\n")); SOCKET_LOG((" MSG_ENSURE_CONNECT\n"));
// //
// ensure that we have created a socket, attached it, and have a // ensure that we have created a socket, attached it, and have a
// connection. // connection.
@ -1427,11 +1427,11 @@ nsSocketTransport::OnSocketEvent(PRUint32 type, nsresult status, nsISupports *pa
if (mState == STATE_CLOSED) if (mState == STATE_CLOSED)
mCondition = ResolveHost(); mCondition = ResolveHost();
else else
LOG((" ignoring redundant event\n")); SOCKET_LOG((" ignoring redundant event\n"));
break; break;
case MSG_DNS_LOOKUP_COMPLETE: case MSG_DNS_LOOKUP_COMPLETE:
LOG((" MSG_DNS_LOOKUP_COMPLETE\n")); SOCKET_LOG((" MSG_DNS_LOOKUP_COMPLETE\n"));
mDNSRequest = 0; mDNSRequest = 0;
if (param) { if (param) {
mDNSRecord = static_cast<nsIDNSRecord *>(param); mDNSRecord = static_cast<nsIDNSRecord *>(param);
@ -1459,35 +1459,35 @@ nsSocketTransport::OnSocketEvent(PRUint32 type, nsresult status, nsISupports *pa
break; break;
case MSG_INPUT_CLOSED: case MSG_INPUT_CLOSED:
LOG((" MSG_INPUT_CLOSED\n")); SOCKET_LOG((" MSG_INPUT_CLOSED\n"));
OnMsgInputClosed(status); OnMsgInputClosed(status);
break; break;
case MSG_INPUT_PENDING: case MSG_INPUT_PENDING:
LOG((" MSG_INPUT_PENDING\n")); SOCKET_LOG((" MSG_INPUT_PENDING\n"));
OnMsgInputPending(); OnMsgInputPending();
break; break;
case MSG_OUTPUT_CLOSED: case MSG_OUTPUT_CLOSED:
LOG((" MSG_OUTPUT_CLOSED\n")); SOCKET_LOG((" MSG_OUTPUT_CLOSED\n"));
OnMsgOutputClosed(status); OnMsgOutputClosed(status);
break; break;
case MSG_OUTPUT_PENDING: case MSG_OUTPUT_PENDING:
LOG((" MSG_OUTPUT_PENDING\n")); SOCKET_LOG((" MSG_OUTPUT_PENDING\n"));
OnMsgOutputPending(); OnMsgOutputPending();
break; break;
case MSG_TIMEOUT_CHANGED: case MSG_TIMEOUT_CHANGED:
LOG((" MSG_TIMEOUT_CHANGED\n")); SOCKET_LOG((" MSG_TIMEOUT_CHANGED\n"));
mPollTimeout = mTimeouts[(mState == STATE_TRANSFERRING) mPollTimeout = mTimeouts[(mState == STATE_TRANSFERRING)
? TIMEOUT_READ_WRITE : TIMEOUT_CONNECT]; ? TIMEOUT_READ_WRITE : TIMEOUT_CONNECT];
break; break;
default: default:
LOG((" unhandled event!\n")); SOCKET_LOG((" unhandled event!\n"));
} }
if (NS_FAILED(mCondition)) { if (NS_FAILED(mCondition)) {
LOG((" after event [this=%x cond=%x]\n", this, mCondition)); SOCKET_LOG((" after event [this=%x cond=%x]\n", this, mCondition));
if (!mAttached) // need to process this error ourselves... if (!mAttached) // need to process this error ourselves...
OnSocketDetached(nsnull); OnSocketDetached(nsnull);
} }
@ -1501,11 +1501,11 @@ nsSocketTransport::OnSocketEvent(PRUint32 type, nsresult status, nsISupports *pa
void void
nsSocketTransport::OnSocketReady(PRFileDesc *fd, PRInt16 outFlags) nsSocketTransport::OnSocketReady(PRFileDesc *fd, PRInt16 outFlags)
{ {
LOG(("nsSocketTransport::OnSocketReady [this=%x outFlags=%hd]\n", SOCKET_LOG(("nsSocketTransport::OnSocketReady [this=%x outFlags=%hd]\n",
this, outFlags)); this, outFlags));
if (outFlags == -1) { if (outFlags == -1) {
LOG(("socket timeout expired\n")); SOCKET_LOG(("socket timeout expired\n"));
mCondition = NS_ERROR_NET_TIMEOUT; mCondition = NS_ERROR_NET_TIMEOUT;
return; return;
} }
@ -1557,7 +1557,7 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, PRInt16 outFlags)
mCondition = ErrorAccordingToNSPR(code); mCondition = ErrorAccordingToNSPR(code);
if ((mCondition == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty()) if ((mCondition == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
mCondition = NS_ERROR_PROXY_CONNECTION_REFUSED; mCondition = NS_ERROR_PROXY_CONNECTION_REFUSED;
LOG((" connection failed! [reason=%x]\n", mCondition)); SOCKET_LOG((" connection failed! [reason=%x]\n", mCondition));
} }
} }
} }
@ -1574,7 +1574,7 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, PRInt16 outFlags)
void void
nsSocketTransport::OnSocketDetached(PRFileDesc *fd) nsSocketTransport::OnSocketDetached(PRFileDesc *fd)
{ {
LOG(("nsSocketTransport::OnSocketDetached [this=%x cond=%x]\n", SOCKET_LOG(("nsSocketTransport::OnSocketDetached [this=%x cond=%x]\n",
this, mCondition)); this, mCondition));
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@ -1651,7 +1651,7 @@ nsSocketTransport::OpenInputStream(PRUint32 flags,
PRUint32 segcount, PRUint32 segcount,
nsIInputStream **result) nsIInputStream **result)
{ {
LOG(("nsSocketTransport::OpenInputStream [this=%x flags=%x]\n", SOCKET_LOG(("nsSocketTransport::OpenInputStream [this=%x flags=%x]\n",
this, flags)); this, flags));
NS_ENSURE_TRUE(!mInput.IsReferenced(), NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(!mInput.IsReferenced(), NS_ERROR_UNEXPECTED);
@ -1699,7 +1699,7 @@ nsSocketTransport::OpenOutputStream(PRUint32 flags,
PRUint32 segcount, PRUint32 segcount,
nsIOutputStream **result) nsIOutputStream **result)
{ {
LOG(("nsSocketTransport::OpenOutputStream [this=%x flags=%x]\n", SOCKET_LOG(("nsSocketTransport::OpenOutputStream [this=%x flags=%x]\n",
this, flags)); this, flags));
NS_ENSURE_TRUE(!mOutput.IsReferenced(), NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(!mOutput.IsReferenced(), NS_ERROR_UNEXPECTED);

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

@ -117,7 +117,7 @@ nsSocketTransportService::GetThreadSafely()
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransportService::Dispatch(nsIRunnable *event, PRUint32 flags) nsSocketTransportService::Dispatch(nsIRunnable *event, PRUint32 flags)
{ {
LOG(("STS dispatch [%p]\n", event)); SOCKET_LOG(("STS dispatch [%p]\n", event));
nsCOMPtr<nsIThread> thread = GetThreadSafely(); nsCOMPtr<nsIThread> thread = GetThreadSafely();
NS_ENSURE_TRUE(thread, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(thread, NS_ERROR_NOT_INITIALIZED);
@ -144,7 +144,7 @@ nsSocketTransportService::IsOnCurrentThread(PRBool *result)
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransportService::NotifyWhenCanAttachSocket(nsIRunnable *event) nsSocketTransportService::NotifyWhenCanAttachSocket(nsIRunnable *event)
{ {
LOG(("nsSocketTransportService::NotifyWhenCanAttachSocket\n")); SOCKET_LOG(("nsSocketTransportService::NotifyWhenCanAttachSocket\n"));
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@ -159,7 +159,7 @@ nsSocketTransportService::NotifyWhenCanAttachSocket(nsIRunnable *event)
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransportService::AttachSocket(PRFileDesc *fd, nsASocketHandler *handler) nsSocketTransportService::AttachSocket(PRFileDesc *fd, nsASocketHandler *handler)
{ {
LOG(("nsSocketTransportService::AttachSocket [handler=%x]\n", handler)); SOCKET_LOG(("nsSocketTransportService::AttachSocket [handler=%x]\n", handler));
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@ -181,7 +181,7 @@ nsSocketTransportService::AttachSocket(PRFileDesc *fd, nsASocketHandler *handler
nsresult nsresult
nsSocketTransportService::DetachSocket(SocketContext *sock) nsSocketTransportService::DetachSocket(SocketContext *sock)
{ {
LOG(("nsSocketTransportService::DetachSocket [handler=%x]\n", sock->mHandler)); SOCKET_LOG(("nsSocketTransportService::DetachSocket [handler=%x]\n", sock->mHandler));
// inform the handler that this socket is going away // inform the handler that this socket is going away
sock->mHandler->OnSocketDetached(sock->mFD); sock->mHandler->OnSocketDetached(sock->mFD);
@ -213,7 +213,7 @@ nsSocketTransportService::DetachSocket(SocketContext *sock)
nsresult nsresult
nsSocketTransportService::AddToPollList(SocketContext *sock) nsSocketTransportService::AddToPollList(SocketContext *sock)
{ {
LOG(("nsSocketTransportService::AddToPollList [handler=%x]\n", sock->mHandler)); SOCKET_LOG(("nsSocketTransportService::AddToPollList [handler=%x]\n", sock->mHandler));
if (mActiveCount == NS_SOCKET_MAX_COUNT) { if (mActiveCount == NS_SOCKET_MAX_COUNT) {
NS_ERROR("too many active sockets"); NS_ERROR("too many active sockets");
@ -227,19 +227,19 @@ nsSocketTransportService::AddToPollList(SocketContext *sock)
mPollList[mActiveCount].in_flags = sock->mHandler->mPollFlags; mPollList[mActiveCount].in_flags = sock->mHandler->mPollFlags;
mPollList[mActiveCount].out_flags = 0; mPollList[mActiveCount].out_flags = 0;
LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount));
return NS_OK; return NS_OK;
} }
void void
nsSocketTransportService::RemoveFromPollList(SocketContext *sock) nsSocketTransportService::RemoveFromPollList(SocketContext *sock)
{ {
LOG(("nsSocketTransportService::RemoveFromPollList [handler=%x]\n", sock->mHandler)); SOCKET_LOG(("nsSocketTransportService::RemoveFromPollList [handler=%x]\n", sock->mHandler));
PRUint32 index = sock - mActiveList; PRUint32 index = sock - mActiveList;
NS_ASSERTION(index < NS_SOCKET_MAX_COUNT, "invalid index"); NS_ASSERTION(index < NS_SOCKET_MAX_COUNT, "invalid index");
LOG((" index=%u mActiveCount=%u\n", index, mActiveCount)); SOCKET_LOG((" index=%u mActiveCount=%u\n", index, mActiveCount));
if (index != mActiveCount-1) { if (index != mActiveCount-1) {
mActiveList[index] = mActiveList[mActiveCount-1]; mActiveList[index] = mActiveList[mActiveCount-1];
@ -247,13 +247,13 @@ nsSocketTransportService::RemoveFromPollList(SocketContext *sock)
} }
mActiveCount--; mActiveCount--;
LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount));
} }
nsresult nsresult
nsSocketTransportService::AddToIdleList(SocketContext *sock) nsSocketTransportService::AddToIdleList(SocketContext *sock)
{ {
LOG(("nsSocketTransportService::AddToIdleList [handler=%x]\n", sock->mHandler)); SOCKET_LOG(("nsSocketTransportService::AddToIdleList [handler=%x]\n", sock->mHandler));
if (mIdleCount == NS_SOCKET_MAX_COUNT) { if (mIdleCount == NS_SOCKET_MAX_COUNT) {
NS_ERROR("too many idle sockets"); NS_ERROR("too many idle sockets");
@ -263,14 +263,14 @@ nsSocketTransportService::AddToIdleList(SocketContext *sock)
mIdleList[mIdleCount] = *sock; mIdleList[mIdleCount] = *sock;
mIdleCount++; mIdleCount++;
LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount));
return NS_OK; return NS_OK;
} }
void void
nsSocketTransportService::RemoveFromIdleList(SocketContext *sock) nsSocketTransportService::RemoveFromIdleList(SocketContext *sock)
{ {
LOG(("nsSocketTransportService::RemoveFromIdleList [handler=%x]\n", sock->mHandler)); SOCKET_LOG(("nsSocketTransportService::RemoveFromIdleList [handler=%x]\n", sock->mHandler));
PRUint32 index = sock - &mIdleList[0]; PRUint32 index = sock - &mIdleList[0];
NS_ASSERTION(index < NS_SOCKET_MAX_COUNT, "invalid index"); NS_ASSERTION(index < NS_SOCKET_MAX_COUNT, "invalid index");
@ -279,7 +279,7 @@ nsSocketTransportService::RemoveFromIdleList(SocketContext *sock)
mIdleList[index] = mIdleList[mIdleCount-1]; mIdleList[index] = mIdleList[mIdleCount-1];
mIdleCount--; mIdleCount--;
LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount));
} }
void void
@ -320,7 +320,7 @@ nsSocketTransportService::PollTimeout()
if (r < minR) if (r < minR)
minR = r; minR = r;
} }
LOG(("poll timeout: %lu\n", minR)); SOCKET_LOG(("poll timeout: %lu\n", minR));
return PR_SecondsToInterval(minR); return PR_SecondsToInterval(minR);
} }
@ -352,13 +352,13 @@ nsSocketTransportService::Poll(PRBool wait, PRUint32 *interval)
PRIntervalTime ts = PR_IntervalNow(); PRIntervalTime ts = PR_IntervalNow();
LOG((" timeout = %i milliseconds\n", SOCKET_LOG((" timeout = %i milliseconds\n",
PR_IntervalToMilliseconds(pollTimeout))); PR_IntervalToMilliseconds(pollTimeout)));
PRInt32 rv = PR_Poll(pollList, pollCount, pollTimeout); PRInt32 rv = PR_Poll(pollList, pollCount, pollTimeout);
PRIntervalTime passedInterval = PR_IntervalNow() - ts; PRIntervalTime passedInterval = PR_IntervalNow() - ts;
LOG((" ...returned after %i milliseconds\n", SOCKET_LOG((" ...returned after %i milliseconds\n",
PR_IntervalToMilliseconds(passedInterval))); PR_IntervalToMilliseconds(passedInterval)));
*interval = PR_IntervalToSeconds(passedInterval); *interval = PR_IntervalToSeconds(passedInterval);
@ -409,7 +409,7 @@ nsSocketTransportService::Init()
// //
if (!mThreadEvent) { if (!mThreadEvent) {
NS_WARNING("running socket transport thread without a pollable event"); NS_WARNING("running socket transport thread without a pollable event");
LOG(("running socket transport thread without a pollable event")); SOCKET_LOG(("running socket transport thread without a pollable event"));
} }
} }
@ -440,7 +440,7 @@ nsSocketTransportService::Init()
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransportService::Shutdown() nsSocketTransportService::Shutdown()
{ {
LOG(("nsSocketTransportService::Shutdown\n")); SOCKET_LOG(("nsSocketTransportService::Shutdown\n"));
NS_ENSURE_STATE(NS_IsMainThread()); NS_ENSURE_STATE(NS_IsMainThread());
@ -559,7 +559,7 @@ nsSocketTransportService::AfterProcessNextEvent(nsIThreadInternal* thread,
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransportService::Run() nsSocketTransportService::Run()
{ {
LOG(("STS thread init\n")); SOCKET_LOG(("STS thread init\n"));
gSocketThread = PR_GetCurrentThread(); gSocketThread = PR_GetCurrentThread();
@ -589,7 +589,7 @@ nsSocketTransportService::Run()
NS_ProcessNextEvent(thread); NS_ProcessNextEvent(thread);
} }
LOG(("STS shutting down thread\n")); SOCKET_LOG(("STS shutting down thread\n"));
// detach any sockets // detach any sockets
PRInt32 i; PRInt32 i;
@ -604,14 +604,14 @@ nsSocketTransportService::Run()
gSocketThread = nsnull; gSocketThread = nsnull;
LOG(("STS thread exit\n")); SOCKET_LOG(("STS thread exit\n"));
return NS_OK; return NS_OK;
} }
nsresult nsresult
nsSocketTransportService::DoPollIteration(PRBool wait) nsSocketTransportService::DoPollIteration(PRBool wait)
{ {
LOG(("STS poll iter [%d]\n", wait)); SOCKET_LOG(("STS poll iter [%d]\n", wait));
PRInt32 i, count; PRInt32 i, count;
@ -629,7 +629,7 @@ nsSocketTransportService::DoPollIteration(PRBool wait)
count = mIdleCount; count = mIdleCount;
for (i=mActiveCount-1; i>=0; --i) { for (i=mActiveCount-1; i>=0; --i) {
//--- //---
LOG((" active [%u] { handler=%x condition=%x pollflags=%hu }\n", i, SOCKET_LOG((" active [%u] { handler=%x condition=%x pollflags=%hu }\n", i,
mActiveList[i].mHandler, mActiveList[i].mHandler,
mActiveList[i].mHandler->mCondition, mActiveList[i].mHandler->mCondition,
mActiveList[i].mHandler->mPollFlags)); mActiveList[i].mHandler->mPollFlags));
@ -649,7 +649,7 @@ nsSocketTransportService::DoPollIteration(PRBool wait)
} }
for (i=count-1; i>=0; --i) { for (i=count-1; i>=0; --i) {
//--- //---
LOG((" idle [%u] { handler=%x condition=%x pollflags=%hu }\n", i, SOCKET_LOG((" idle [%u] { handler=%x condition=%x pollflags=%hu }\n", i,
mIdleList[i].mHandler, mIdleList[i].mHandler,
mIdleList[i].mHandler->mCondition, mIdleList[i].mHandler->mCondition,
mIdleList[i].mHandler->mPollFlags)); mIdleList[i].mHandler->mPollFlags));
@ -660,14 +660,14 @@ nsSocketTransportService::DoPollIteration(PRBool wait)
MoveToPollList(&mIdleList[i]); MoveToPollList(&mIdleList[i]);
} }
LOG((" calling PR_Poll [active=%u idle=%u]\n", mActiveCount, mIdleCount)); SOCKET_LOG((" calling PR_Poll [active=%u idle=%u]\n", mActiveCount, mIdleCount));
// Measures seconds spent while blocked on PR_Poll // Measures seconds spent while blocked on PR_Poll
PRUint32 pollInterval; PRUint32 pollInterval;
PRInt32 n = Poll(wait, &pollInterval); PRInt32 n = Poll(wait, &pollInterval);
if (n < 0) { if (n < 0) {
LOG((" PR_Poll error [%d]\n", PR_GetError())); SOCKET_LOG((" PR_Poll error [%d]\n", PR_GetError()));
pollError = PR_TRUE; pollError = PR_TRUE;
} }
else { else {
@ -722,7 +722,7 @@ nsSocketTransportService::DoPollIteration(PRBool wait)
if (!mThreadEvent) { if (!mThreadEvent) {
NS_WARNING("running socket transport thread without " NS_WARNING("running socket transport thread without "
"a pollable event"); "a pollable event");
LOG(("running socket transport thread without " SOCKET_LOG(("running socket transport thread without "
"a pollable event")); "a pollable event"));
} }
mPollList[0].fd = mThreadEvent; mPollList[0].fd = mThreadEvent;

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

@ -59,8 +59,8 @@
// //
extern PRLogModuleInfo *gSocketTransportLog; extern PRLogModuleInfo *gSocketTransportLog;
#endif #endif
#define LOG(args) PR_LOG(gSocketTransportLog, PR_LOG_DEBUG, args) #define SOCKET_LOG(args) PR_LOG(gSocketTransportLog, PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(gSocketTransportLog, PR_LOG_DEBUG) #define SOCKET_LOG_ENABLED() PR_LOG_TEST(gSocketTransportLog, PR_LOG_DEBUG)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

15
netwerk/cache/nsCacheService.cpp поставляемый
Просмотреть файл

@ -793,14 +793,6 @@ nsCacheService::DispatchToCacheIOThread(nsIRunnable* event)
PRBool PRBool
nsCacheProfilePrefObserver::DiskCacheEnabled() nsCacheProfilePrefObserver::DiskCacheEnabled()
{ {
#ifdef MOZ_IPC
// Bad Things (tm) are likely to happen if child and parent both write to
// disk cache.
// - TODO: remove once we turn off caching entirely in child (bug 559714)
if (mozilla::net::IsNeckoChild())
return PR_FALSE;
#endif
if ((mDiskCacheCapacity == 0) || (!mDiskCacheParentDirectory)) return PR_FALSE; if ((mDiskCacheCapacity == 0) || (!mDiskCacheParentDirectory)) return PR_FALSE;
return mDiskCacheEnabled; return mDiskCacheEnabled;
} }
@ -858,13 +850,6 @@ nsCacheProfilePrefObserver::MemoryCacheEnabled()
PRInt32 PRInt32
nsCacheProfilePrefObserver::MemoryCacheCapacity() nsCacheProfilePrefObserver::MemoryCacheCapacity()
{ {
#ifdef MOZ_IPC
// For now use small memory cache (1 MB) on child, just for FTP/wyciwyg
// - TODO: remove once we turn off caching entirely in child (bug 559714)
if (mozilla::net::IsNeckoChild())
return 1024;
#endif
PRInt32 capacity = mMemoryCacheCapacity; PRInt32 capacity = mMemoryCacheCapacity;
if (capacity >= 0) { if (capacity >= 0) {
CACHE_LOG_DEBUG(("Memory cache capacity forced to %d\n", capacity)); CACHE_LOG_DEBUG(("Memory cache capacity forced to %d\n", capacity));

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

@ -143,6 +143,12 @@ HttpChannelParentListener::GetInterface(const nsIID& aIID, void **result)
return mActiveChannel->mTabParent->QueryInterface(aIID, result); return mActiveChannel->mTabParent->QueryInterface(aIID, result);
} }
if (aIID.Equals(NS_GET_IID(nsISecureBrowserUI))) {
if (!mActiveChannel || !mActiveChannel->mTabParent)
return NS_NOINTERFACE;
return mActiveChannel->mTabParent->QueryInterface(aIID, result);
}
if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) { if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) {
if (!mActiveChannel) if (!mActiveChannel)
return NS_NOINTERFACE; return NS_NOINTERFACE;

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

@ -206,6 +206,8 @@ nsHttpConnectionMgr::StopPruneDeadConnectionsTimer()
{ {
LOG(("nsHttpConnectionMgr::StopPruneDeadConnectionsTimer\n")); LOG(("nsHttpConnectionMgr::StopPruneDeadConnectionsTimer\n"));
// Reset mTimeOfNextWakeUp so that we can find a new shortest value.
mTimeOfNextWakeUp = LL_MAXUINT;
if (mTimer) { if (mTimer) {
mTimer->Cancel(); mTimer->Cancel();
mTimer = NULL; mTimer = NULL;
@ -412,8 +414,8 @@ nsHttpConnectionMgr::PruneDeadConnectionsCB(nsHashKey *key, void *data, void *cl
// If time to next expire found is shorter than time to next wake-up, we need to // If time to next expire found is shorter than time to next wake-up, we need to
// change the time for next wake-up. // change the time for next wake-up.
PRUint32 now = NowInSeconds();
if (0 < ent->mIdleConns.Length()) { if (0 < ent->mIdleConns.Length()) {
PRUint32 now = NowInSeconds();
PRUint64 timeOfNextExpire = now + timeToNextExpire; PRUint64 timeOfNextExpire = now + timeToNextExpire;
// If pruning of dead connections is not already scheduled to happen // If pruning of dead connections is not already scheduled to happen
// or time found for next connection to expire is is before // or time found for next connection to expire is is before
@ -556,7 +558,8 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap
LOG(("nsHttpConnectionMgr::AtActiveConnectionLimit [ci=%s caps=%x]\n", LOG(("nsHttpConnectionMgr::AtActiveConnectionLimit [ci=%s caps=%x]\n",
ci->HashKey().get(), caps)); ci->HashKey().get(), caps));
// use >= just to be safe // If we have more active connections than the limit, then we're done --
// purging idle connections won't get us below it.
if (mNumActiveConns >= mMaxConns) { if (mNumActiveConns >= mMaxConns) {
LOG((" num active conns == max conns\n")); LOG((" num active conns == max conns\n"));
return PR_TRUE; return PR_TRUE;
@ -602,11 +605,6 @@ nsHttpConnectionMgr::GetConnection(nsConnectionEntry *ent, PRUint8 caps,
*result = nsnull; *result = nsnull;
if (AtActiveConnectionLimit(ent, caps)) {
LOG((" at active connection limit!\n"));
return;
}
nsHttpConnection *conn = nsnull; nsHttpConnection *conn = nsnull;
if (caps & NS_HTTP_ALLOW_KEEPALIVE) { if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
@ -624,15 +622,31 @@ nsHttpConnectionMgr::GetConnection(nsConnectionEntry *ent, PRUint8 caps,
LOG((" reusing connection [conn=%x]\n", conn)); LOG((" reusing connection [conn=%x]\n", conn));
ent->mIdleConns.RemoveElementAt(0); ent->mIdleConns.RemoveElementAt(0);
mNumIdleConns--; mNumIdleConns--;
// If there are no idle connections left at all, we need to make
// sure that we are not pruning dead connections anymore.
if (0 == mNumIdleConns)
StopPruneDeadConnectionsTimer();
} }
} }
if (!conn) { if (!conn) {
// No reusable idle connection found for this entry. If there are no // Check if we need to purge an idle connection. Note that we may have
// idle connections left at all, we need to make sure that we are not // removed one above; if so, this will be a no-op. We do this before
// pruning dead connections anymore. // checking the active connection limit to catch the case where we do
if (0 == mNumIdleConns) // have an idle connection, but the purge timer hasn't fired yet.
StopPruneDeadConnectionsTimer(); // XXX this just purges a random idle connection. we should instead
// enumerate the entire hash table to find the eldest idle connection.
if (mNumIdleConns && mNumIdleConns + mNumActiveConns + 1 >= mMaxConns)
mCT.Enumerate(PurgeOneIdleConnectionCB, this);
// Need to make a new TCP connection. First, we check if we've hit
// either the maximum connection limit globally or for this particular
// host or proxy. If we have, we're done.
if (AtActiveConnectionLimit(ent, caps)) {
LOG((" at active connection limit!\n"));
return;
}
conn = new nsHttpConnection(); conn = new nsHttpConnection();
if (!conn) if (!conn)
@ -644,15 +658,6 @@ nsHttpConnectionMgr::GetConnection(nsConnectionEntry *ent, PRUint8 caps,
NS_RELEASE(conn); NS_RELEASE(conn);
return; return;
} }
// We created a new connection that will become active, purge the
// oldest idle connection if we've reached the upper limit.
// This only needs to be done if there is a idle connection.
if (0 < mNumIdleConns && mNumIdleConns + mNumActiveConns + 1 > mMaxConns)
mCT.Enumerate(PurgeOneIdleConnectionCB, this);
// XXX this just purges a random idle connection. we should instead
// enumerate the entire hash table to find the eldest idle connection.
} }
*result = conn; *result = conn;
@ -932,6 +937,8 @@ nsHttpConnectionMgr::OnMsgPruneDeadConnections(PRInt32, void *)
{ {
LOG(("nsHttpConnectionMgr::OnMsgPruneDeadConnections\n")); LOG(("nsHttpConnectionMgr::OnMsgPruneDeadConnections\n"));
// Reset mTimeOfNextWakeUp so that we can find a new shortest value.
mTimeOfNextWakeUp = LL_MAXUINT;
if (mNumIdleConns > 0) if (mNumIdleConns > 0)
mCT.Enumerate(PruneDeadConnectionsCB, this); mCT.Enumerate(PruneDeadConnectionsCB, this);
} }

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

@ -76,6 +76,7 @@
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsIOService.h" #include "nsIOService.h"
#include "nsAsyncRedirectVerifyHelper.h" #include "nsAsyncRedirectVerifyHelper.h"
#include "nsSocketTransportService2.h"
#include "nsIXULAppInfo.h" #include "nsIXULAppInfo.h"
@ -854,7 +855,7 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
if (PREF_CHANGED(HTTP_PREF("max-connections"))) { if (PREF_CHANGED(HTTP_PREF("max-connections"))) {
rv = prefs->GetIntPref(HTTP_PREF("max-connections"), &val); rv = prefs->GetIntPref(HTTP_PREF("max-connections"), &val);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
mMaxConnections = (PRUint16) NS_CLAMP(val, 1, 0xffff); mMaxConnections = (PRUint16) NS_CLAMP(val, 1, NS_SOCKET_MAX_COUNT);
if (mConnMgr) if (mConnMgr)
mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS, mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS,
mMaxConnections); mMaxConnections);

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

@ -102,6 +102,7 @@ CPPSRCS = \
nsIdentityChecking.cpp \ nsIdentityChecking.cpp \
nsDataSignatureVerifier.cpp \ nsDataSignatureVerifier.cpp \
nsRandomGenerator.cpp \ nsRandomGenerator.cpp \
NSSErrorsService.cpp \
$(NULL) $(NULL)
ifdef MOZ_XUL ifdef MOZ_XUL

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

@ -0,0 +1,189 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Personal Security Manager.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Hubbie Shaw
* Doug Turner <dougt@netscape.com>
* Mitch Stoltz <mstoltz@netscape.com>
* Brian Ryner <bryner@brianryner.com>
* Kai Engert <kaie@netscape.com>
* Vipul Gupta <vipul.gupta@sun.com>
* Douglas Stebila <douglas@stebila.ca>
* Kai Engert <kengert@redhat.com>
* honzab.moz@firemni.cz
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "NSSErrorsService.h"
#include "nsNSSComponent.h"
#include "nsServiceManagerUtils.h"
#include "secerr.h"
#include "sslerr.h"
#define PIPNSS_STRBUNDLE_URL "chrome://pipnss/locale/pipnss.properties"
#define NSSERR_STRBUNDLE_URL "chrome://pipnss/locale/nsserrors.properties"
namespace mozilla {
namespace psm {
NS_IMPL_ISUPPORTS1(NSSErrorsService, nsINSSErrorsService)
nsresult
NSSErrorsService::Init()
{
nsresult rv;
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
if (NS_FAILED(rv) || !bundleService)
return NS_ERROR_FAILURE;
bundleService->CreateBundle(PIPNSS_STRBUNDLE_URL,
getter_AddRefs(mPIPNSSBundle));
if (!mPIPNSSBundle)
rv = NS_ERROR_FAILURE;
bundleService->CreateBundle(NSSERR_STRBUNDLE_URL,
getter_AddRefs(mNSSErrorsBundle));
if (!mNSSErrorsBundle)
rv = NS_ERROR_FAILURE;
return rv;
}
#define EXPECTED_SEC_ERROR_BASE (-0x2000)
#define EXPECTED_SSL_ERROR_BASE (-0x3000)
#if SEC_ERROR_BASE != EXPECTED_SEC_ERROR_BASE || SSL_ERROR_BASE != EXPECTED_SSL_ERROR_BASE
#error "Unexpected change of error code numbers in lib NSS, please adjust the mapping code"
/*
* Please ensure the NSS error codes are mapped into the positive range 0x1000 to 0xf000
* Search for NS_ERROR_MODULE_SECURITY to ensure there are no conflicts.
* The current code also assumes that NSS library error codes are negative.
*/
#endif
NS_IMETHODIMP
NSSErrorsService::IsNSSErrorCode(PRInt32 aNSPRCode, PRBool *_retval)
{
if (!_retval)
return NS_ERROR_FAILURE;
*_retval = IS_SEC_ERROR(aNSPRCode) || IS_SSL_ERROR(aNSPRCode);
return NS_OK;
}
NS_IMETHODIMP
NSSErrorsService::GetXPCOMFromNSSError(PRInt32 aNSPRCode, nsresult *aXPCOMErrorCode)
{
if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode))
return NS_ERROR_FAILURE;
if (!aXPCOMErrorCode)
return NS_ERROR_INVALID_ARG;
// The error codes within each module may be a 16 bit value.
// For simplicity let's use the positive value of the NSS code.
*aXPCOMErrorCode =
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY,
-1 * aNSPRCode);
return NS_OK;
}
NS_IMETHODIMP
NSSErrorsService::GetErrorClass(nsresult aXPCOMErrorCode, PRUint32 *aErrorClass)
{
NS_ENSURE_ARG(aErrorClass);
if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY
|| NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR)
return NS_ERROR_FAILURE;
PRInt32 aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode);
if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode))
return NS_ERROR_FAILURE;
switch (aNSPRCode)
{
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_CA_CERT_INVALID:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
case SEC_ERROR_UNTRUSTED_CERT:
case SEC_ERROR_INADEQUATE_KEY_USAGE:
case SSL_ERROR_BAD_CERT_DOMAIN:
case SEC_ERROR_EXPIRED_CERTIFICATE:
*aErrorClass = ERROR_CLASS_BAD_CERT;
break;
default:
*aErrorClass = ERROR_CLASS_SSL_PROTOCOL;
break;
}
return NS_OK;
}
NS_IMETHODIMP
NSSErrorsService::GetErrorMessage(nsresult aXPCOMErrorCode, nsAString &aErrorMessage)
{
if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY
|| NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR)
return NS_ERROR_FAILURE;
PRInt32 aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode);
if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode))
return NS_ERROR_FAILURE;
nsCOMPtr<nsIStringBundle> theBundle = mPIPNSSBundle;
const char *id_str = nsNSSErrors::getOverrideErrorStringName(aNSPRCode);
if (!id_str) {
id_str = nsNSSErrors::getDefaultErrorStringName(aNSPRCode);
theBundle = mNSSErrorsBundle;
}
if (!id_str || !theBundle)
return NS_ERROR_FAILURE;
nsAutoString msg;
nsresult rv =
theBundle->GetStringFromName(NS_ConvertASCIItoUTF16(id_str).get(),
getter_Copies(msg));
if (NS_SUCCEEDED(rv)) {
aErrorMessage = msg;
}
return rv;
}
} // psm
} // mozilla

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

@ -0,0 +1,68 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Personal Security Manager.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Hubbie Shaw
* Doug Turner <dougt@netscape.com>
* Brian Ryner <bryner@brianryner.com>
* Kai Engert <kaie@netscape.com>
* Kai Engert <kengert@redhat.com>
* honzab.moz@firemni.cz
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsINSSErrorsService.h"
#include "nsIStringBundle.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace psm {
class NSSErrorsService : public nsINSSErrorsService
{
NS_DECL_ISUPPORTS
NS_DECL_NSINSSERRORSSERVICE
public:
nsresult Init();
private:
nsCOMPtr<nsIStringBundle> mPIPNSSBundle;
nsCOMPtr<nsIStringBundle> mNSSErrorsBundle;
};
} // psm
} // mozilla
#define NS_NSSERRORSSERVICE_CID \
{ 0x9ef18451, 0xa157, 0x4d17, { 0x81, 0x32, 0x47, 0xaf, 0xef, 0x21, 0x36, 0x89 } }

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

@ -1953,14 +1953,13 @@ nsNSSComponent::Init()
} }
/* nsISupports Implementation for the class */ /* nsISupports Implementation for the class */
NS_IMPL_THREADSAFE_ISUPPORTS7(nsNSSComponent, NS_IMPL_THREADSAFE_ISUPPORTS6(nsNSSComponent,
nsISignatureVerifier, nsISignatureVerifier,
nsIEntropyCollector, nsIEntropyCollector,
nsINSSComponent, nsINSSComponent,
nsIObserver, nsIObserver,
nsISupportsWeakReference, nsISupportsWeakReference,
nsITimerCallback, nsITimerCallback)
nsINSSErrorsService)
/* Callback functions for decoder. For now, use empty/default functions. */ /* Callback functions for decoder. For now, use empty/default functions. */
@ -2453,112 +2452,6 @@ nsNSSComponent::RememberCert(CERTCertificate *cert)
return NS_OK; return NS_OK;
} }
#define EXPECTED_SEC_ERROR_BASE (-0x2000)
#define EXPECTED_SSL_ERROR_BASE (-0x3000)
#if SEC_ERROR_BASE != EXPECTED_SEC_ERROR_BASE || SSL_ERROR_BASE != EXPECTED_SSL_ERROR_BASE
#error "Unexpected change of error code numbers in lib NSS, please adjust the mapping code"
/*
* Please ensure the NSS error codes are mapped into the positive range 0x1000 to 0xf000
* Search for NS_ERROR_MODULE_SECURITY to ensure there are no conflicts.
* The current code also assumes that NSS library error codes are negative.
*/
#endif
NS_IMETHODIMP
nsNSSComponent::IsNSSErrorCode(PRInt32 aNSPRCode, PRBool *_retval)
{
if (!_retval)
return NS_ERROR_FAILURE;
*_retval = IS_SEC_ERROR(aNSPRCode) || IS_SSL_ERROR(aNSPRCode);
return NS_OK;
}
NS_IMETHODIMP
nsNSSComponent::GetXPCOMFromNSSError(PRInt32 aNSPRCode, nsresult *aXPCOMErrorCode)
{
if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode))
return NS_ERROR_FAILURE;
if (!aXPCOMErrorCode)
return NS_ERROR_INVALID_ARG;
// The error codes within each module may be a 16 bit value.
// For simplicity let's use the positive value of the NSS code.
*aXPCOMErrorCode =
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY,
-1 * aNSPRCode);
return NS_OK;
}
NS_IMETHODIMP
nsNSSComponent::GetErrorClass(nsresult aXPCOMErrorCode, PRUint32 *aErrorClass)
{
NS_ENSURE_ARG(aErrorClass);
if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY
|| NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR)
return NS_ERROR_FAILURE;
PRInt32 aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode);
if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode))
return NS_ERROR_FAILURE;
switch (aNSPRCode)
{
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_CA_CERT_INVALID:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
case SEC_ERROR_UNTRUSTED_CERT:
case SEC_ERROR_INADEQUATE_KEY_USAGE:
case SSL_ERROR_BAD_CERT_DOMAIN:
case SEC_ERROR_EXPIRED_CERTIFICATE:
*aErrorClass = ERROR_CLASS_BAD_CERT;
break;
default:
*aErrorClass = ERROR_CLASS_SSL_PROTOCOL;
break;
}
return NS_OK;
}
NS_IMETHODIMP
nsNSSComponent::GetErrorMessage(nsresult aXPCOMErrorCode, nsAString &aErrorMessage)
{
if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY
|| NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR)
return NS_ERROR_FAILURE;
PRInt32 aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode);
if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode))
return NS_ERROR_FAILURE;
nsCOMPtr<nsIStringBundle> theBundle = mPIPNSSBundle;
const char *id_str = nsNSSErrors::getOverrideErrorStringName(aNSPRCode);
if (!id_str) {
id_str = nsNSSErrors::getDefaultErrorStringName(aNSPRCode);
theBundle = mNSSErrorsBundle;
}
if (!id_str || !theBundle)
return NS_ERROR_FAILURE;
nsAutoString msg;
nsresult rv =
theBundle->GetStringFromName(NS_ConvertASCIItoUTF16(id_str).get(),
getter_Copies(msg));
if (NS_SUCCEEDED(rv)) {
aErrorMessage = msg;
}
return rv;
}
void void
nsNSSComponent::DoProfileApproveChange(nsISupports* aSubject) nsNSSComponent::DoProfileApproveChange(nsISupports* aSubject)
{ {

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

@ -239,8 +239,7 @@ class nsNSSComponent : public nsISignatureVerifier,
public nsINSSComponent, public nsINSSComponent,
public nsIObserver, public nsIObserver,
public nsSupportsWeakReference, public nsSupportsWeakReference,
public nsITimerCallback, public nsITimerCallback
public nsINSSErrorsService
{ {
public: public:
NS_DEFINE_STATIC_CID_ACCESSOR( NS_NSSCOMPONENT_CID ) NS_DEFINE_STATIC_CID_ACCESSOR( NS_NSSCOMPONENT_CID )
@ -253,7 +252,6 @@ public:
NS_DECL_NSIENTROPYCOLLECTOR NS_DECL_NSIENTROPYCOLLECTOR
NS_DECL_NSIOBSERVER NS_DECL_NSIOBSERVER
NS_DECL_NSITIMERCALLBACK NS_DECL_NSITIMERCALLBACK
NS_DECL_NSINSSERRORSSERVICE
NS_METHOD Init(); NS_METHOD Init();

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

@ -379,6 +379,11 @@ nsNSSSocketInfo::EnsureDocShellDependentStuffKnown()
// with a socket close, and the socket transport might detach the callbacks // with a socket close, and the socket transport might detach the callbacks
// instance prior to our error reporting. // instance prior to our error reporting.
nsISecureBrowserUI* secureUI = nsnull;
#ifdef MOZ_IPC
CallGetInterface(proxiedCallbacks.get(), &secureUI);
#endif
nsCOMPtr<nsIDocShell> docshell; nsCOMPtr<nsIDocShell> docshell;
nsCOMPtr<nsIDocShellTreeItem> item(do_GetInterface(proxiedCallbacks)); nsCOMPtr<nsIDocShellTreeItem> item(do_GetInterface(proxiedCallbacks));
@ -397,7 +402,7 @@ nsNSSSocketInfo::EnsureDocShellDependentStuffKnown()
NS_ASSERTION(docshell, "rootItem do_QI is null"); NS_ASSERTION(docshell, "rootItem do_QI is null");
} }
if (docshell) if (docshell && !secureUI)
{ {
nsCOMPtr<nsIDocShell> proxiedDocShell; nsCOMPtr<nsIDocShell> proxiedDocShell;
NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
@ -405,28 +410,28 @@ nsNSSSocketInfo::EnsureDocShellDependentStuffKnown()
docshell.get(), docshell.get(),
NS_PROXY_SYNC, NS_PROXY_SYNC,
getter_AddRefs(proxiedDocShell)); getter_AddRefs(proxiedDocShell));
nsISecureBrowserUI* secureUI = nsnull;
if (proxiedDocShell) if (proxiedDocShell)
proxiedDocShell->GetSecurityUI(&secureUI); proxiedDocShell->GetSecurityUI(&secureUI);
if (secureUI) }
{
nsCOMPtr<nsIThread> mainThread(do_GetMainThread());
NS_ProxyRelease(mainThread, secureUI, PR_FALSE);
mExternalErrorReporting = PR_TRUE;
// If this socket is associated to a docshell, let's try to remember if (secureUI)
// the currently used cert. If this socket gets a notification from NSS {
// having the same raw socket, we can keep the PSM wrapper object nsCOMPtr<nsIThread> mainThread(do_GetMainThread());
// and all the data it has cached (like verification results). NS_ProxyRelease(mainThread, secureUI, PR_FALSE);
nsCOMPtr<nsISSLStatusProvider> statprov = do_QueryInterface(secureUI); mExternalErrorReporting = PR_TRUE;
if (statprov) {
nsCOMPtr<nsISupports> isup_stat; // If this socket is associated to a docshell, let's try to remember
statprov->GetSSLStatus(getter_AddRefs(isup_stat)); // the currently used cert. If this socket gets a notification from NSS
if (isup_stat) { // having the same raw socket, we can keep the PSM wrapper object
nsCOMPtr<nsISSLStatus> sslstat = do_QueryInterface(isup_stat); // and all the data it has cached (like verification results).
if (sslstat) { nsCOMPtr<nsISSLStatusProvider> statprov = do_QueryInterface(secureUI);
sslstat->GetServerCert(getter_AddRefs(mPreviousCert)); if (statprov) {
} nsCOMPtr<nsISupports> isup_stat;
statprov->GetSSLStatus(getter_AddRefs(isup_stat));
if (isup_stat) {
nsCOMPtr<nsISSLStatus> sslstat = do_QueryInterface(isup_stat);
if (sslstat) {
sslstat->GetServerCert(getter_AddRefs(mPreviousCert));
} }
} }
} }

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

@ -78,6 +78,7 @@
#include "nsRecentBadCerts.h" #include "nsRecentBadCerts.h"
#include "nsSSLStatus.h" #include "nsSSLStatus.h"
#include "nsNSSIOLayer.h" #include "nsNSSIOLayer.h"
#include "NSSErrorsService.h"
#ifdef MOZ_IPC #ifdef MOZ_IPC
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
@ -261,6 +262,9 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsRecentBadCertsService, Init
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsNSSSocketInfo) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsNSSSocketInfo)
typedef mozilla::psm::NSSErrorsService NSSErrorsService;
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(NSSErrorsService, Init)
NS_DEFINE_NAMED_CID(NS_NSSCOMPONENT_CID); NS_DEFINE_NAMED_CID(NS_NSSCOMPONENT_CID);
NS_DEFINE_NAMED_CID(NS_SSLSOCKETPROVIDER_CID); NS_DEFINE_NAMED_CID(NS_SSLSOCKETPROVIDER_CID);
NS_DEFINE_NAMED_CID(NS_STARTTLSSOCKETPROVIDER_CID); NS_DEFINE_NAMED_CID(NS_STARTTLSSOCKETPROVIDER_CID);
@ -296,6 +300,7 @@ NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID);
NS_DEFINE_NAMED_CID(NS_RECENTBADCERTS_CID); NS_DEFINE_NAMED_CID(NS_RECENTBADCERTS_CID);
NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID); NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID);
NS_DEFINE_NAMED_CID(NS_NSSSOCKETINFO_CID); NS_DEFINE_NAMED_CID(NS_NSSSOCKETINFO_CID);
NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID);
static const mozilla::Module::CIDEntry kNSSCIDs[] = { static const mozilla::Module::CIDEntry kNSSCIDs[] = {
@ -334,12 +339,13 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = {
{ &kNS_RECENTBADCERTS_CID, false, NULL, nsRecentBadCertsServiceConstructor }, { &kNS_RECENTBADCERTS_CID, false, NULL, nsRecentBadCertsServiceConstructor },
{ &kNS_SSLSTATUS_CID, false, NULL, nsSSLStatusConstructor }, { &kNS_SSLSTATUS_CID, false, NULL, nsSSLStatusConstructor },
{ &kNS_NSSSOCKETINFO_CID, false, NULL, nsNSSSocketInfoConstructor }, { &kNS_NSSSOCKETINFO_CID, false, NULL, nsNSSSocketInfoConstructor },
{ &kNS_NSSERRORSSERVICE_CID, false, NULL, NSSErrorsServiceConstructor },
{ NULL } { NULL }
}; };
static const mozilla::Module::ContractIDEntry kNSSContracts[] = { static const mozilla::Module::ContractIDEntry kNSSContracts[] = {
{ PSM_COMPONENT_CONTRACTID, &kNS_NSSCOMPONENT_CID }, { PSM_COMPONENT_CONTRACTID, &kNS_NSSCOMPONENT_CID },
{ NS_NSS_ERRORS_SERVICE_CONTRACTID, &kNS_NSSCOMPONENT_CID }, { NS_NSS_ERRORS_SERVICE_CONTRACTID, &kNS_NSSERRORSSERVICE_CID },
{ NS_SSLSOCKETPROVIDER_CONTRACTID, &kNS_SSLSOCKETPROVIDER_CID }, { NS_SSLSOCKETPROVIDER_CONTRACTID, &kNS_SSLSOCKETPROVIDER_CID },
{ NS_STARTTLSSOCKETPROVIDER_CONTRACTID, &kNS_STARTTLSSOCKETPROVIDER_CID }, { NS_STARTTLSSOCKETPROVIDER_CONTRACTID, &kNS_STARTTLSSOCKETPROVIDER_CID },
{ NS_SDR_CONTRACTID, &kNS_SDR_CID }, { NS_SDR_CONTRACTID, &kNS_SDR_CID },

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

@ -71,12 +71,6 @@ WeaveCrypto.prototype = {
} }
}, },
// This is its own method so that it can be overridden.
// (Components.Exception isn't thread-safe for instance)
makeException : function makeException(message, result) {
return Components.Exception(message, result);
},
init : function() { init : function() {
try { try {
// Preferences. Add observer so we get notified of changes. // Preferences. Add observer so we get notified of changes.
@ -108,34 +102,21 @@ WeaveCrypto.prototype = {
Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
// Open the NSS library. // Open the NSS library.
let nssfile = Services.dirsvc.get("GreD", Ci.nsILocalFile); let path = ctypes.libraryName("nss3");
let os = Services.appinfo.OS;
switch (os) {
case "WINNT":
case "WINMO":
case "WINCE":
nssfile.append("nss3.dll");
break;
case "Darwin":
nssfile.append("libnss3.dylib");
break;
case "Linux":
case "SunOS":
case "WebOS": // Palm Pre
nssfile.append("libnss3.so");
break;
case "Android":
// Android uses a $GREDIR/lib/ subdir.
nssfile.append("lib");
nssfile.append("libnss3.so");
break;
default:
throw this.makeException("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED);
}
this.log("Using NSS library " + nssfile.path);
// XXX really want to be able to pass specific dlopen flags here. // XXX really want to be able to pass specific dlopen flags here.
let nsslib = ctypes.open(nssfile.path); var nsslib;
try {
this.log("Trying NSS library without path");
nsslib = ctypes.open(path);
} catch(e) {
// In case opening the library without a full path fails,
// try again with a full path.
let file = Services.dirsvc.get("GreD", Ci.nsILocalFile);
file.append(path);
this.log("Trying again with path " + file.path);
nsslib = ctypes.open(file.path);
}
this.log("Initializing NSS types and function declarations..."); this.log("Initializing NSS types and function declarations...");
@ -530,31 +511,31 @@ WeaveCrypto.prototype = {
let mechanism = this.nss.PK11_AlgtagToMechanism(this.algorithm); let mechanism = this.nss.PK11_AlgtagToMechanism(this.algorithm);
mechanism = this.nss.PK11_GetPadMechanism(mechanism); mechanism = this.nss.PK11_GetPadMechanism(mechanism);
if (mechanism == this.nss.CKM_INVALID_MECHANISM) if (mechanism == this.nss.CKM_INVALID_MECHANISM)
throw this.makeException("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE); throw Components.Exception("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE);
let ctx, symKey, slot, ivParam; let ctx, symKey, slot, ivParam;
try { try {
ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem.address()); ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem.address());
if (ivParam.isNull()) if (ivParam.isNull())
throw this.makeException("can't convert IV to param", Cr.NS_ERROR_FAILURE); throw Components.Exception("can't convert IV to param", Cr.NS_ERROR_FAILURE);
slot = this.nss.PK11_GetInternalKeySlot(); slot = this.nss.PK11_GetInternalKeySlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("can't get internal key slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("can't get internal key slot", Cr.NS_ERROR_FAILURE);
symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem.address(), null); symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem.address(), null);
if (symKey.isNull()) if (symKey.isNull())
throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE);
ctx = this.nss.PK11_CreateContextBySymKey(mechanism, operation, symKey, ivParam); ctx = this.nss.PK11_CreateContextBySymKey(mechanism, operation, symKey, ivParam);
if (ctx.isNull()) if (ctx.isNull())
throw this.makeException("couldn't create context for symkey", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't create context for symkey", Cr.NS_ERROR_FAILURE);
let maxOutputSize = output.length; let maxOutputSize = output.length;
let tmpOutputSize = new ctypes.int(); // Note 1: NSS uses a signed int here... let tmpOutputSize = new ctypes.int(); // Note 1: NSS uses a signed int here...
if (this.nss.PK11_CipherOp(ctx, output, tmpOutputSize.address(), maxOutputSize, input, input.length)) if (this.nss.PK11_CipherOp(ctx, output, tmpOutputSize.address(), maxOutputSize, input, input.length))
throw this.makeException("cipher operation failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("cipher operation failed", Cr.NS_ERROR_FAILURE);
let actualOutputSize = tmpOutputSize.value; let actualOutputSize = tmpOutputSize.value;
let finalOutput = output.addressOfElement(actualOutputSize); let finalOutput = output.addressOfElement(actualOutputSize);
@ -565,7 +546,7 @@ WeaveCrypto.prototype = {
// cipher operation. You'd think it would be called PK11_CipherOpFinal... // cipher operation. You'd think it would be called PK11_CipherOpFinal...
let tmpOutputSize2 = new ctypes.unsigned_int(); // Note 2: ...but an unsigned here! let tmpOutputSize2 = new ctypes.unsigned_int(); // Note 2: ...but an unsigned here!
if (this.nss.PK11_DigestFinal(ctx, finalOutput, tmpOutputSize2.address(), maxOutputSize)) if (this.nss.PK11_DigestFinal(ctx, finalOutput, tmpOutputSize2.address(), maxOutputSize))
throw this.makeException("cipher finalize failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("cipher finalize failed", Cr.NS_ERROR_FAILURE);
actualOutputSize += tmpOutputSize2.value; actualOutputSize += tmpOutputSize2.value;
let newOutput = ctypes.cast(output, ctypes.unsigned_char.array(actualOutputSize)); let newOutput = ctypes.cast(output, ctypes.unsigned_char.array(actualOutputSize));
@ -604,7 +585,7 @@ WeaveCrypto.prototype = {
slot = this.nss.PK11_GetInternalSlot(); slot = this.nss.PK11_GetInternalSlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
// Generate the keypair. // Generate the keypair.
privKey = this.nss.PK11_GenerateKeyPairWithFlags(slot, privKey = this.nss.PK11_GenerateKeyPairWithFlags(slot,
@ -613,18 +594,18 @@ WeaveCrypto.prototype = {
pubKey.address(), pubKey.address(),
attrFlags, null); attrFlags, null);
if (privKey.isNull()) if (privKey.isNull())
throw this.makeException("keypair generation failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("keypair generation failed", Cr.NS_ERROR_FAILURE);
let s = this.nss.PK11_SetPrivateKeyNickname(privKey, "Weave User PrivKey"); let s = this.nss.PK11_SetPrivateKeyNickname(privKey, "Weave User PrivKey");
if (s) if (s)
throw this.makeException("key nickname failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("key nickname failed", Cr.NS_ERROR_FAILURE);
let wrappedPrivateKey = this._wrapPrivateKey(privKey, passphrase, salt, iv); let wrappedPrivateKey = this._wrapPrivateKey(privKey, passphrase, salt, iv);
out_wrappedPrivateKey.value = wrappedPrivateKey; // outparam out_wrappedPrivateKey.value = wrappedPrivateKey; // outparam
let derKey = this.nss.SECKEY_EncodeDERSubjectPublicKeyInfo(pubKey); let derKey = this.nss.SECKEY_EncodeDERSubjectPublicKeyInfo(pubKey);
if (derKey.isNull()) if (derKey.isNull())
throw this.makeException("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE);
let encodedPublicKey = this.encodeBase64(derKey.contents.data, derKey.contents.len); let encodedPublicKey = this.encodeBase64(derKey.contents.data, derKey.contents.len);
out_encodedPublicKey.value = encodedPublicKey; // outparam out_encodedPublicKey.value = encodedPublicKey; // outparam
@ -664,27 +645,27 @@ WeaveCrypto.prototype = {
break; break;
default: default:
throw this.makeException("unknown algorithm", Cr.NS_ERROR_FAILURE); throw Components.Exception("unknown algorithm", Cr.NS_ERROR_FAILURE);
} }
let slot, randKey, keydata; let slot, randKey, keydata;
try { try {
slot = this.nss.PK11_GetInternalSlot(); slot = this.nss.PK11_GetInternalSlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
randKey = this.nss.PK11_KeyGen(slot, keygenMech, null, keySize, null); randKey = this.nss.PK11_KeyGen(slot, keygenMech, null, keySize, null);
if (randKey.isNull()) if (randKey.isNull())
throw this.makeException("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE);
// Slightly odd API, this call just prepares the key value for // Slightly odd API, this call just prepares the key value for
// extraction, we get the actual bits from the call to PK11_GetKeyData(). // extraction, we get the actual bits from the call to PK11_GetKeyData().
if (this.nss.PK11_ExtractKeyValue(randKey)) if (this.nss.PK11_ExtractKeyValue(randKey))
throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE);
keydata = this.nss.PK11_GetKeyData(randKey); keydata = this.nss.PK11_GetKeyData(randKey);
if (keydata.isNull()) if (keydata.isNull())
throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE);
return this.encodeBase64(keydata.contents.data, keydata.contents.len); return this.encodeBase64(keydata.contents.data, keydata.contents.len);
} catch (e) { } catch (e) {
@ -715,7 +696,7 @@ WeaveCrypto.prototype = {
// Temporary buffer to hold the generated data. // Temporary buffer to hold the generated data.
let scratch = new ctypes.ArrayType(ctypes.unsigned_char, byteCount)(); let scratch = new ctypes.ArrayType(ctypes.unsigned_char, byteCount)();
if (this.nss.PK11_GenerateRandom(scratch, byteCount)) if (this.nss.PK11_GenerateRandom(scratch, byteCount))
throw this.makeException("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE);
return this.encodeBase64(scratch.address(), scratch.length); return this.encodeBase64(scratch.address(), scratch.length);
}, },
@ -738,7 +719,7 @@ WeaveCrypto.prototype = {
try { try {
slot = this.nss.PK11_GetInternalSlot(); slot = this.nss.PK11_GetInternalSlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
// ImportSymKey wants a mechanism, from which it derives the key type. // ImportSymKey wants a mechanism, from which it derives the key type.
let keyMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); let keyMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
@ -747,7 +728,7 @@ WeaveCrypto.prototype = {
// really matter because we're just going to wrap it up and not use it. // really matter because we're just going to wrap it up and not use it.
symKey = this.nss.PK11_ImportSymKey(slot, keyMech, this.nss.PK11_OriginUnwrap, this.nss.CKA_ENCRYPT, symKeyData.address(), null); symKey = this.nss.PK11_ImportSymKey(slot, keyMech, this.nss.PK11_OriginUnwrap, this.nss.CKA_ENCRYPT, symKeyData.address(), null);
if (symKey.isNull()) if (symKey.isNull())
throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE);
// Step 3. Put the public key bits into a P11 key object. // Step 3. Put the public key bits into a P11 key object.
@ -755,11 +736,11 @@ WeaveCrypto.prototype = {
// pubKey = SECKEY_ImportDERPublicKey(&pubKeyData, CKK_RSA); // pubKey = SECKEY_ImportDERPublicKey(&pubKeyData, CKK_RSA);
pubKeyInfo = this.nss.SECKEY_DecodeDERSubjectPublicKeyInfo(pubKeyData.address()); pubKeyInfo = this.nss.SECKEY_DecodeDERSubjectPublicKeyInfo(pubKeyData.address());
if (pubKeyInfo.isNull()) if (pubKeyInfo.isNull())
throw this.makeException("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE);
pubKey = this.nss.SECKEY_ExtractPublicKey(pubKeyInfo); pubKey = this.nss.SECKEY_ExtractPublicKey(pubKeyInfo);
if (pubKey.isNull()) if (pubKey.isNull())
throw this.makeException("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE);
// Step 4. Wrap the symmetric key with the public key. // Step 4. Wrap the symmetric key with the public key.
@ -767,7 +748,7 @@ WeaveCrypto.prototype = {
let s = this.nss.PK11_PubWrapSymKey(wrapMech, pubKey, symKey, wrappedKey.address()); let s = this.nss.PK11_PubWrapSymKey(wrapMech, pubKey, symKey, wrappedKey.address());
if (s) if (s)
throw this.makeException("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE);
// Step 5. Base64 encode the wrapped key, cleanup, and return to caller. // Step 5. Base64 encode the wrapped key, cleanup, and return to caller.
return this.encodeBase64(wrappedKey.data, wrappedKey.len); return this.encodeBase64(wrappedKey.data, wrappedKey.len);
@ -807,16 +788,16 @@ WeaveCrypto.prototype = {
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
if (wrapMech == this.nss.CKM_INVALID_MECHANISM) if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
throw this.makeException("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); throw Components.Exception("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
if (ivParam.isNull()) if (ivParam.isNull())
throw this.makeException("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
// Step 3. Unwrap the private key with the key from the passphrase. // Step 3. Unwrap the private key with the key from the passphrase.
slot = this.nss.PK11_GetInternalSlot(); slot = this.nss.PK11_GetInternalSlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
// Normally, one wants to associate a private key with a public key. // Normally, one wants to associate a private key with a public key.
// P11_UnwrapPrivKey() passes its keyID arg to PK11_MakeIDFromPubKey(), // P11_UnwrapPrivKey() passes its keyID arg to PK11_MakeIDFromPubKey(),
@ -837,7 +818,7 @@ WeaveCrypto.prototype = {
privKeyUsage.addressOfElement(0), privKeyUsageLength, privKeyUsage.addressOfElement(0), privKeyUsageLength,
null); // wincx null); // wincx
if (privKey.isNull()) if (privKey.isNull())
throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE);
// Step 4. Unwrap the symmetric key with the user's private key. // Step 4. Unwrap the symmetric key with the user's private key.
@ -846,15 +827,15 @@ WeaveCrypto.prototype = {
symKey = this.nss.PK11_PubUnwrapSymKey(privKey, wrappedSymKey.address(), wrapMech, symKey = this.nss.PK11_PubUnwrapSymKey(privKey, wrappedSymKey.address(), wrapMech,
this.nss.CKA_DECRYPT, 0); this.nss.CKA_DECRYPT, 0);
if (symKey.isNull()) if (symKey.isNull())
throw this.makeException("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE);
// Step 5. Base64 encode the unwrapped key, cleanup, and return to caller. // Step 5. Base64 encode the unwrapped key, cleanup, and return to caller.
if (this.nss.PK11_ExtractKeyValue(symKey)) if (this.nss.PK11_ExtractKeyValue(symKey))
throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE);
symKeyData = this.nss.PK11_GetKeyData(symKey); symKeyData = this.nss.PK11_GetKeyData(symKey);
if (symKeyData.isNull()) if (symKeyData.isNull())
throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE);
return this.encodeBase64(symKeyData.contents.data, symKeyData.contents.len); return this.encodeBase64(symKeyData.contents.data, symKeyData.contents.len);
} catch (e) { } catch (e) {
@ -894,16 +875,16 @@ WeaveCrypto.prototype = {
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
if (wrapMech == this.nss.CKM_INVALID_MECHANISM) if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
if (ivParam.isNull()) if (ivParam.isNull())
throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
// Step 3. Unwrap the private key with the key from the passphrase. // Step 3. Unwrap the private key with the key from the passphrase.
slot = this.nss.PK11_GetInternalSlot(); slot = this.nss.PK11_GetInternalSlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
let keyID = ivItem.address(); let keyID = ivItem.address();
@ -917,7 +898,7 @@ WeaveCrypto.prototype = {
privKeyUsage.addressOfElement(0), privKeyUsageLength, privKeyUsage.addressOfElement(0), privKeyUsageLength,
null); // wincx null); // wincx
if (privKey.isNull()) if (privKey.isNull())
throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE);
// Step 4. Rewrap the private key with the new passphrase. // Step 4. Rewrap the private key with the new passphrase.
return this._wrapPrivateKey(privKey, newPassphrase, salt, iv); return this._wrapPrivateKey(privKey, newPassphrase, salt, iv);
@ -956,16 +937,16 @@ WeaveCrypto.prototype = {
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
if (wrapMech == this.nss.CKM_INVALID_MECHANISM) if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE); throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
if (ivParam.isNull()) if (ivParam.isNull())
throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
// Step 3. Unwrap the private key with the key from the passphrase. // Step 3. Unwrap the private key with the key from the passphrase.
slot = this.nss.PK11_GetInternalSlot(); slot = this.nss.PK11_GetInternalSlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
let keyID = ivItem.address(); let keyID = ivItem.address();
@ -1059,15 +1040,15 @@ WeaveCrypto.prototype = {
algid = this.nss.PK11_CreatePBEV2AlgorithmID(pbeAlg, cipherAlg, prfAlg, algid = this.nss.PK11_CreatePBEV2AlgorithmID(pbeAlg, cipherAlg, prfAlg,
keyLength, iterations, saltItem.address()); keyLength, iterations, saltItem.address());
if (algid.isNull()) if (algid.isNull())
throw this.makeException("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE);
slot = this.nss.PK11_GetInternalSlot(); slot = this.nss.PK11_GetInternalSlot();
if (slot.isNull()) if (slot.isNull())
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE); throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem.address(), false, null); symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem.address(), false, null);
if (symKey.isNull()) if (symKey.isNull())
throw this.makeException("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE);
} catch (e) { } catch (e) {
this.log("_deriveKeyFromPassphrase: failed: " + e); this.log("_deriveKeyFromPassphrase: failed: " + e);
throw e; throw e;
@ -1095,11 +1076,11 @@ WeaveCrypto.prototype = {
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm); let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech); wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
if (wrapMech == this.nss.CKM_INVALID_MECHANISM) if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
throw this.makeException("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE); throw Components.Exception("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE);
let ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address()); let ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
if (ivParam.isNull()) if (ivParam.isNull())
throw this.makeException("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
// Use a buffer to hold the wrapped key. NSS says about 1200 bytes for // Use a buffer to hold the wrapped key. NSS says about 1200 bytes for
// a 2048-bit RSA key, so a 4096 byte buffer should be plenty. // a 2048-bit RSA key, so a 4096 byte buffer should be plenty.
@ -1111,7 +1092,7 @@ WeaveCrypto.prototype = {
wrapMech, ivParam, wrapMech, ivParam,
wrappedKey.address(), null); wrappedKey.address(), null);
if (s) if (s)
throw this.makeException("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE); throw Components.Exception("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE);
return this.encodeBase64(wrappedKey.data, wrappedKey.len); return this.encodeBase64(wrappedKey.data, wrappedKey.len);
} catch (e) { } catch (e) {

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

@ -1,150 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Firefox Sync.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Philipp von Weitershausen <philipp@weitershausen>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const EXPORTED_SYMBOLS = ["ThreadedCrypto"];
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-sync/ext/Sync.js");
Cu.import("resource://services-crypto/WeaveCrypto.js");
/*
* Execute a function in a thread.
*/
function Runner(func, thisObj, returnval, error) {
this.func = func;
this.thisObj = thisObj;
this.returnval = returnval;
this.error = error;
}
Runner.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]),
run: function run() {
let ex = this.error;
if (ex) {
this.func.throw(ex);
} else {
this.func.call(this.thisObj, this.returnval);
}
}
};
/*
* Execute a function in a thread and notify a callback on another thread
* afterward.
*/
function CallbackRunner(func, thisObj, args, callback, cbThread) {
this.func = func;
this.thisObj = thisObj;
this.args = args;
this.callback = callback;
this.cbThread = cbThread;
}
CallbackRunner.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]),
run: function run() {
let returnval, error;
try {
returnval = this.func.apply(this.thisObj, this.args);
} catch(ex) {
error = ex;
}
this.cbThread.dispatch(new Runner(this.callback, this.thisObj,
returnval, error),
Ci.nsIThread.DISPATCH_NORMAL);
}
};
/*
* Implementation of IWeaveCrypto that defers method calls to another thread
* but keeps the synchronous API. (Don't ask...)
*/
function ThreadedCrypto() {
this.backgroundThread = Services.tm.newThread(0);
this.crypto = new WeaveCrypto();
// Components.Exception isn't thread-safe.
this.crypto.makeException = function makeException(message, result) {
return result;
};
// Make sure to kill the thread before XPCOM shuts down.
Services.obs.addObserver(this, "profile-before-change", true);
}
ThreadedCrypto.deferToThread = function deferToThread(methodname) {
return function threadMethod() {
// Dispatch method call to background thread.
let args = Array.slice(arguments);
return Sync(function(callback) {
let runner = new CallbackRunner(this.crypto[methodname], this.crypto,
args, callback, Services.tm.mainThread);
this.backgroundThread.dispatch(runner, Ci.nsIThread.DISPATCH_NORMAL);
}, this)();
};
};
ThreadedCrypto.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.IWeaveCrypto,
Ci.nsISupportsWeakReference]),
observe: function observe() {
this.backgroundThread.shutdown();
},
get algorithm() this.crypto.algorithm,
set algorithm(value) this.crypto.algorithm = value,
get keypairBits() this.crypto.keypairBits,
set keypairBits(value) this.crypto.keypairBits = value,
encrypt: ThreadedCrypto.deferToThread("encrypt"),
decrypt: ThreadedCrypto.deferToThread("decrypt"),
generateKeypair: ThreadedCrypto.deferToThread("generateKeypair"),
generateRandomKey: ThreadedCrypto.deferToThread("generateRandomKey"),
generateRandomIV: ThreadedCrypto.deferToThread("generateRandomIV"),
generateRandomBytes: ThreadedCrypto.deferToThread("generateRandomBytes"),
wrapSymmetricKey: ThreadedCrypto.deferToThread("wrapSymmetricKey"),
unwrapSymmetricKey: ThreadedCrypto.deferToThread("unwrapSymmetricKey"),
rewrapPrivateKey: ThreadedCrypto.deferToThread("rewrapPrivateKey"),
verifyPassphrase: ThreadedCrypto.deferToThread("verifyPassphrase")
};

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

@ -11,8 +11,6 @@ try {
} }
catch(ex) { catch(ex) {
do_get_profile();
// Make sure to provide the right OS so crypto loads the right binaries // Make sure to provide the right OS so crypto loads the right binaries
let OS = "XPCShell"; let OS = "XPCShell";
if ("@mozilla.org/windows-registry-key;1" in Cc) if ("@mozilla.org/windows-registry-key;1" in Cc)

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

@ -1,7 +1,7 @@
let cryptoSvc; let cryptoSvc;
try { try {
Components.utils.import("resource://services-crypto/threaded.js"); Components.utils.import("resource://services-crypto/WeaveCrypto.js");
cryptoSvc = new ThreadedCrypto(); cryptoSvc = new WeaveCrypto();
} catch (ex) { } catch (ex) {
// Fallback to binary WeaveCrypto // Fallback to binary WeaveCrypto
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]

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

@ -1,7 +1,7 @@
let cryptoSvc; let cryptoSvc;
try { try {
Components.utils.import("resource://services-crypto/threaded.js"); Components.utils.import("resource://services-crypto/WeaveCrypto.js");
cryptoSvc = new ThreadedCrypto(); cryptoSvc = new WeaveCrypto();
} catch (ex) { } catch (ex) {
// Fallback to binary WeaveCrypto // Fallback to binary WeaveCrypto
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]

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

@ -1,7 +1,7 @@
let cryptoSvc; let cryptoSvc;
try { try {
Components.utils.import("resource://services-crypto/threaded.js"); Components.utils.import("resource://services-crypto/WeaveCrypto.js");
cryptoSvc = new ThreadedCrypto(); cryptoSvc = new WeaveCrypto();
} catch (ex) { } catch (ex) {
// Fallback to binary WeaveCrypto // Fallback to binary WeaveCrypto
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]

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

@ -1,7 +1,7 @@
let cryptoSvc; let cryptoSvc;
try { try {
Components.utils.import("resource://services-crypto/threaded.js"); Components.utils.import("resource://services-crypto/WeaveCrypto.js");
cryptoSvc = new ThreadedCrypto(); cryptoSvc = new WeaveCrypto();
} catch (ex) { } catch (ex) {
// Fallback to binary WeaveCrypto // Fallback to binary WeaveCrypto
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]

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

@ -1,7 +1,7 @@
let cryptoSvc; let cryptoSvc;
try { try {
Components.utils.import("resource://services-crypto/threaded.js"); Components.utils.import("resource://services-crypto/WeaveCrypto.js");
cryptoSvc = new ThreadedCrypto(); cryptoSvc = new WeaveCrypto();
} catch (ex) { } catch (ex) {
// Fallback to binary WeaveCrypto // Fallback to binary WeaveCrypto
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"] cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]

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

@ -1039,8 +1039,8 @@ Svc.__defineGetter__("Crypto", function() {
let cryptoSvc; let cryptoSvc;
try { try {
let ns = {}; let ns = {};
Cu.import("resource://services-crypto/threaded.js", ns); Cu.import("resource://services-crypto/WeaveCrypto.js", ns);
cryptoSvc = new ns.ThreadedCrypto(); cryptoSvc = new ns.WeaveCrypto();
} catch (ex) { } catch (ex) {
// Fallback to binary WeaveCrypto // Fallback to binary WeaveCrypto
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]. cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"].

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

@ -3,6 +3,9 @@ Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-sync/log4moz.js"); Cu.import("resource://services-sync/log4moz.js");
function run_test() { function run_test() {
if (DISABLE_TESTS_BUG_604565)
return;
let logger = Log4Moz.repository.rootLogger; let logger = Log4Moz.repository.rootLogger;
Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender()); Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());

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

@ -3907,159 +3907,152 @@ function JSPropertyProvider(aScope, aInputValue)
*/ */
function JSTermHelper(aJSTerm) function JSTermHelper(aJSTerm)
{ {
return { /**
/** * Returns the result of document.getElementById(aId).
* Returns the result of document.getElementById(aId). *
* * @param string aId
* @param string aId * A string that is passed to window.document.getElementById.
* A string that is passed to window.document.getElementById. * @returns nsIDOMNode or null
* @returns nsIDOMNode or null */
*/ aJSTerm.sandbox.$ = function JSTH_$(aId)
$: function JSTH_$(aId) {
{ try {
try { return aJSTerm._window.document.getElementById(aId);
return aJSTerm._window.document.getElementById(aId);
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
},
/**
* Returns the result of document.querySelectorAll(aSelector).
*
* @param string aSelector
* A string that is passed to window.document.querySelectorAll.
* @returns array of nsIDOMNode
*/
$$: function JSTH_$$(aSelector)
{
try {
return aJSTerm._window.document.querySelectorAll(aSelector);
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
},
/**
* Runs a xPath query and returns all matched nodes.
*
* @param string aXPath
* xPath search query to execute.
* @param [optional] nsIDOMNode aContext
* Context to run the xPath query on. Uses window.document if not set.
* @returns array of nsIDOMNode
*/
$x: function JSTH_$x(aXPath, aContext)
{
let nodes = [];
let doc = aJSTerm._window.wrappedJSObject.document;
let aContext = aContext || doc;
try {
let results = doc.evaluate(aXPath, aContext, null,
Ci.nsIDOMXPathResult.ANY_TYPE, null);
let node;
while (node = results.iterateNext()) {
nodes.push(node);
}
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
return nodes;
},
/**
* Clears the output of the JSTerm.
*/
clear: function JSTH_clear()
{
aJSTerm.clearOutput();
},
/**
* Returns the result of Object.keys(aObject).
*
* @param object aObject
* Object to return the property names from.
* @returns array of string
*/
keys: function JSTH_keys(aObject)
{
try {
return Object.keys(XPCNativeWrapper.unwrap(aObject));
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
},
/**
* Returns the values of all properties on aObject.
*
* @param object aObject
* Object to display the values from.
* @returns array of string
*/
values: function JSTH_values(aObject)
{
let arrValues = [];
let obj = XPCNativeWrapper.unwrap(aObject);
try {
for (let prop in obj) {
arrValues.push(obj[prop]);
}
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
return arrValues;
},
/**
* Inspects the passed aObject. This is done by opening the PropertyPanel.
*
* @param object aObject
* Object to inspect.
* @returns void
*/
inspect: function JSTH_inspect(aObject)
{
let obj = XPCNativeWrapper.unwrap(aObject);
aJSTerm.openPropertyPanel(null, obj);
},
/**
* Prints aObject to the output.
*
* @param object aObject
* Object to print to the output.
* @returns void
*/
pprint: function JSTH_pprint(aObject)
{
if (aObject === null || aObject === undefined || aObject === true || aObject === false) {
aJSTerm.console.error(HUDService.getStr("helperFuncUnsupportedTypeError"));
return;
}
let output = [];
if (typeof aObject != "string") {
aObject = XPCNativeWrapper.unwrap(aObject);
}
let pairs = namesAndValuesOf(aObject);
pairs.forEach(function(pair) {
output.push(" " + pair.display);
});
aJSTerm.writeOutput(output.join("\n"));
} }
} catch (ex) {
aJSTerm.console.error(ex.message);
}
};
/**
* Returns the result of document.querySelectorAll(aSelector).
*
* @param string aSelector
* A string that is passed to window.document.querySelectorAll.
* @returns array of nsIDOMNode
*/
aJSTerm.sandbox.$$ = function JSTH_$$(aSelector)
{
try {
return aJSTerm._window.document.querySelectorAll(aSelector);
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
};
/**
* Runs a xPath query and returns all matched nodes.
*
* @param string aXPath
* xPath search query to execute.
* @param [optional] nsIDOMNode aContext
* Context to run the xPath query on. Uses window.document if not set.
* @returns array of nsIDOMNode
*/
aJSTerm.sandbox.$x = function JSTH_$x(aXPath, aContext)
{
let nodes = [];
let doc = aJSTerm._window.document;
let aContext = aContext || doc;
try {
let results = doc.evaluate(aXPath, aContext, null,
Ci.nsIDOMXPathResult.ANY_TYPE, null);
let node;
while (node = results.iterateNext()) {
nodes.push(node);
}
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
return nodes;
};
/**
* Clears the output of the JSTerm.
*/
aJSTerm.sandbox.clear = function JSTH_clear()
{
aJSTerm.clearOutput();
};
/**
* Returns the result of Object.keys(aObject).
*
* @param object aObject
* Object to return the property names from.
* @returns array of string
*/
aJSTerm.sandbox.keys = function JSTH_keys(aObject)
{
try {
return Object.keys(aObject);
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
};
/**
* Returns the values of all properties on aObject.
*
* @param object aObject
* Object to display the values from.
* @returns array of string
*/
aJSTerm.sandbox.values = function JSTH_values(aObject)
{
let arrValues = [];
try {
for (let prop in aObject) {
arrValues.push(aObject[prop]);
}
}
catch (ex) {
aJSTerm.console.error(ex.message);
}
return arrValues;
};
/**
* Inspects the passed aObject. This is done by opening the PropertyPanel.
*
* @param object aObject
* Object to inspect.
* @returns void
*/
aJSTerm.sandbox.inspect = function JSTH_inspect(aObject)
{
aJSTerm.openPropertyPanel(null, aObject);
};
/**
* Prints aObject to the output.
*
* @param object aObject
* Object to print to the output.
* @returns void
*/
aJSTerm.sandbox.pprint = function JSTH_pprint(aObject)
{
if (aObject === null || aObject === undefined || aObject === true || aObject === false) {
aJSTerm.console.error(HUDService.getStr("helperFuncUnsupportedTypeError"));
return;
}
let output = [];
let pairs = namesAndValuesOf(aObject);
pairs.forEach(function(pair) {
output.push(" " + pair.display);
});
aJSTerm.writeOutput(output.join("\n"));
};
} }
/** /**
@ -4146,11 +4139,10 @@ JSTerm.prototype = {
createSandbox: function JST_setupSandbox() createSandbox: function JST_setupSandbox()
{ {
// create a JS Sandbox out of this.context // create a JS Sandbox out of this.context
this.sandbox = new Cu.Sandbox(this._window); this.sandbox = new Cu.Sandbox(this._window,
this.sandbox.window = this._window; { sandboxPrototype: this._window, wantXrays: false });
this.sandbox.console = this.console; this.sandbox.console = this.console;
this.sandbox.__helperFunctions__ = JSTermHelper(this); JSTermHelper(this);
this.sandbox.__proto__ = this._window.wrappedJSObject;
}, },
get _window() get _window()
@ -4168,8 +4160,7 @@ JSTerm.prototype = {
*/ */
evalInSandbox: function JST_evalInSandbox(aString) evalInSandbox: function JST_evalInSandbox(aString)
{ {
let execStr = "with(__helperFunctions__) { with(window) {" + aString + "} }"; return Cu.evalInSandbox(aString, this.sandbox, "1.8", "HUD Console", 1);
return Cu.evalInSandbox(execStr, this.sandbox, "default", "HUD Console", 1);
}, },

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

@ -98,6 +98,7 @@ _BROWSER_TEST_FILES = \
browser_webconsole_bug_594497_history_arrow_keys.js \ browser_webconsole_bug_594497_history_arrow_keys.js \
browser_webconsole_bug_588342_document_focus.js \ browser_webconsole_bug_588342_document_focus.js \
browser_webconsole_bug_595934_message_categories.js \ browser_webconsole_bug_595934_message_categories.js \
browser_webconsole_bug_601352_scroll.js \
head.js \ head.js \
$(NULL) $(NULL)

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

@ -0,0 +1,62 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** BEGIN LICENSE BLOCK *****
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* Contributor(s):
* Mihai Șucan <mihai.sucan@gmail.com>
*
* ***** END LICENSE BLOCK ***** */
function tabLoad(aEvent) {
browser.removeEventListener(aEvent.type, arguments.callee, true);
openConsole();
let hudId = HUDService.getHudIdByWindow(content);
let HUD = HUDService.hudWeakReferences[hudId].get();
let longMessage = "";
for (let i = 0; i < 20; i++) {
longMessage += "LongNonwrappingMessage";
}
for (let i = 0; i < 100; i++) {
HUD.console.log("test message " + i);
}
HUD.console.log(longMessage);
for (let i = 0; i < 100; i++) {
HUD.console.log("test message " + i);
}
HUD.jsterm.execute("1+1");
executeSoon(function() {
isnot(HUD.outputNode.scrollTop, 0, "scroll location is not at the top");
let node = HUD.outputNode.querySelector(".hud-group > *:last-child");
let rectNode = node.getBoundingClientRect();
let rectOutput = HUD.outputNode.getBoundingClientRect();
// Visible scroll viewport.
let height = HUD.outputNode.scrollHeight - HUD.outputNode.scrollTop;
// Top position of the last message node, relative to the outputNode.
let top = rectNode.top - rectOutput.top;
// Bottom position of the last message node, relative to the outputNode.
let bottom = rectNode.bottom - rectOutput.top;
ok(top >= 0 && bottom <= height, "last message is visible");
finishTest();
});
}
function test() {
addTab("data:text/html,Web Console test for bug 601352");
browser.addEventListener("load", tabLoad, true);
}

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

@ -98,5 +98,21 @@ function testJSTerm()
let label = jsterm.outputNode.querySelector(".jsterm-output-line"); let label = jsterm.outputNode.querySelector(".jsterm-output-line");
is(label.textContent.trim(), "a: 1\n b: 2", "pprint() worked"); is(label.textContent.trim(), "a: 1\n b: 2", "pprint() worked");
// check instanceof correctness, bug 599940
jsterm.clearOutput();
jsterm.execute("[] instanceof Array");
checkResult("true", "[] instanceof Array == true", 1);
jsterm.clearOutput();
jsterm.execute("({}) instanceof Object");
checkResult("true", "({}) instanceof Object == true", 1);
// check for occurrences of Object XRayWrapper, bug 604430
jsterm.clearOutput();
jsterm.execute("document");
let label = jsterm.outputNode.querySelector(".jsterm-output-line");
is(label.textContent.trim().search(/\[object XrayWrapper/), -1,
"check for non-existence of [object XrayWrapper ");
finishTest(); finishTest();
} }

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

@ -124,6 +124,33 @@ ok(true, "whee, done!");
SimpleTest.finish(); SimpleTest.finish();
} }
function addNotificationCallback(cb)
{
storageObserver.notificationCallbacks.push(cb);
}
var storageObserver = {
notificationCallbacks: [],
QueryInterface : function (iid) {
const interfaces = [Ci.nsIObserver,
Ci.nsISupports, Ci.nsISupportsWeakReference];
if (!interfaces.some( function(v) { return iid.equals(v) } ))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
observe : function (subject, topic, data) {
if (this.notificationCallbacks.length)
this.notificationCallbacks.splice(0, 1)[0]();
}
};
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(storageObserver, "passwordmgr-storage-changed", false);
/* /*
* handleDialog * handleDialog
* *
@ -417,12 +444,6 @@ function handleLoad() {
is(username, "mochiuser1", "Checking for echoed username"); is(username, "mochiuser1", "Checking for echoed username");
is(password, "mochipass1-new", "Checking for echoed password"); is(password, "mochipass1-new", "Checking for echoed password");
// Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-change");
ok(popup, "got popup notification");
clickPopupButton(popup, kChangeButton);
popup.remove();
// Housekeeping: change it back // Housekeeping: change it back
function resetIt() { function resetIt() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
@ -430,7 +451,13 @@ function handleLoad() {
"mochiuser1", "mochipass1-new", "", ""); "mochiuser1", "mochipass1-new", "", "");
pwmgr.modifyLogin(tmpLogin, login3A); pwmgr.modifyLogin(tmpLogin, login3A);
} }
setTimeout(resetIt, 0); addNotificationCallback(resetIt);
// Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-change");
ok(popup, "got popup notification");
clickPopupButton(popup, kChangeButton);
popup.remove();
// Same as last test, but for a realm we haven't already authenticated // Same as last test, but for a realm we haven't already authenticated
// to (but have an existing saved login for, so that we'll trigger // to (but have an existing saved login for, so that we'll trigger
@ -445,30 +472,30 @@ function handleLoad() {
is(username, "mochiuser3", "Checking for echoed username"); is(username, "mochiuser3", "Checking for echoed username");
is(password, "mochipass3-new", "Checking for echoed password"); is(password, "mochipass3-new", "Checking for echoed password");
// Housekeeping: change it back to the original login4. Actually,
// just delete it and we'll re-add it as the next test.
function clearIt() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
tmpLogin.init("http://mochi.test:8888", null, "mochitest3",
"mochiuser3", "mochipass3-new", "", "");
pwmgr.removeLogin(tmpLogin);
// Trigger a new prompt, so we can test adding a new login.
startCallbackTimer();
iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-old&realm=mochitest3";
}
addNotificationCallback(clearIt);
// Check for the popup notification, and change the password. // Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-change"); popup = getPopup(popupNotifications, "password-change");
ok(popup, "got popup notification"); ok(popup, "got popup notification");
clickPopupButton(popup, kChangeButton); clickPopupButton(popup, kChangeButton);
popup.remove(); popup.remove();
// Housekeeping: change it back to the original login4. Actually,
// just delete it and we'll re-add it as the next test.
function clearIt() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
tmpLogin.init("http://mochi.test:8888", null, "mochitest3",
"mochiuser3", "mochipass3-new", "", "");
pwmgr.removeLogin(tmpLogin);
}
setTimeout(clearIt, 0);
// Clear cached auth from this subtest, and avoid leaking due to bug 459620. // Clear cached auth from this subtest, and avoid leaking due to bug 459620.
var authMgr = Cc['@mozilla.org/network/http-auth-manager;1']. var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
getService(Ci.nsIHttpAuthManager); getService(Ci.nsIHttpAuthManager);
authMgr.clearAll(); authMgr.clearAll();
// Trigger a new prompt, so we can test adding a new login.
startCallbackTimer();
iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-old&realm=mochitest3";
break; break;
case 1005: case 1005:
@ -477,17 +504,17 @@ function handleLoad() {
is(username, "mochiuser3", "Checking for echoed username"); is(username, "mochiuser3", "Checking for echoed username");
is(password, "mochipass3-old", "Checking for echoed password"); is(password, "mochipass3-old", "Checking for echoed password");
function finishIt() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
finishTest();
}
addNotificationCallback(finishIt);
// Check for the popup notification, and change the password. // Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-save"); popup = getPopup(popupNotifications, "password-save");
ok(popup, "got popup notification"); ok(popup, "got popup notification");
clickPopupButton(popup, kRememberButton); clickPopupButton(popup, kRememberButton);
popup.remove(); popup.remove();
function finishIt() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
finishTest();
}
setTimeout(finishIt, 0);
break; break;
default: default:

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

@ -1181,12 +1181,27 @@ History::RegisterVisitedCallback(nsIURI* aURI,
// Links wanting to know about this URI. Therefore, we should query the // Links wanting to know about this URI. Therefore, we should query the
// database now. // database now.
nsresult rv = VisitedQuery::Start(aURI); nsresult rv = VisitedQuery::Start(aURI);
// In IPC builds, we are passed a NULL Link from
// ContentParent::RecvStartVisitedQuery. Since we won't be adding a NULL
// entry to our list of observers, and the code after this point assumes
// that aLink is non-NULL, we will need to return now.
if (NS_FAILED(rv) || !aLink) { if (NS_FAILED(rv) || !aLink) {
// Remove our array from the hashtable so we don't keep it around. // Remove our array from the hashtable so we don't keep it around.
mObservers.RemoveEntry(aURI); mObservers.RemoveEntry(aURI);
return rv; return rv;
} }
} }
#ifdef MOZ_IPC
// In IPC builds, we are passed a NULL Link from
// ContentParent::RecvStartVisitedQuery. All of our code after this point
// assumes aLink is non-NULL, so we have to return now.
else if (!aLink) {
NS_ASSERTION(XRE_GetProcessType() == GeckoProcessType_Default,
"We should only ever get a null Link in the default process!");
return NS_OK;
}
#endif
// Sanity check that Links are not registered more than once for a given URI. // Sanity check that Links are not registered more than once for a given URI.
// This will not catch a case where it is registered for two different URIs. // This will not catch a case where it is registered for two different URIs.

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

@ -550,6 +550,34 @@ test_visituri_transition_embed()
run_next_test(); run_next_test();
} }
////////////////////////////////////////////////////////////////////////////////
//// IPC-only Tests
#ifdef MOZ_IPC
void
test_two_null_links_same_uri()
{
// Tests that we do not crash when we have had two NULL Links passed to
// RegisterVisitedCallback and then the visit occurs (bug 607469). This only
// happens in IPC builds.
nsCOMPtr<nsIURI> testURI(new_test_uri());
nsCOMPtr<IHistory> history(do_get_IHistory());
nsresult rv = history->RegisterVisitedCallback(testURI, NULL);
do_check_success(rv);
rv = history->RegisterVisitedCallback(testURI, NULL);
do_check_success(rv);
rv = history->VisitURI(testURI, NULL, mozilla::IHistory::TOP_LEVEL);
do_check_success(rv);
nsCOMPtr<VisitURIObserver> finisher = new VisitURIObserver();
finisher->WaitForNotification();
run_next_test();
}
#endif // MOZ_IPC
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// Test Harness //// Test Harness
@ -571,6 +599,11 @@ Test gTests[] = {
TEST(test_visituri_creates_visit), TEST(test_visituri_creates_visit),
TEST(test_visituri_transition_typed), TEST(test_visituri_transition_typed),
TEST(test_visituri_transition_embed), TEST(test_visituri_transition_embed),
// The rest of these tests are tests that are only run in IPC builds.
#ifdef MOZ_IPC
TEST(test_two_null_links_same_uri),
#endif // MOZ_IPC
}; };
const char* file = __FILE__; const char* file = __FILE__;

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

@ -45,116 +45,56 @@ const Cc = Components.classes;
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/CommonDialog.jsm");
let gArgs = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2) let propBag, args, Dialog;
.QueryInterface(Ci.nsIWritablePropertyBag);
let promptType, numButtons, iconClass, soundID, hasInputField = true; function commonDialogOnLoad() {
propBag = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2)
.QueryInterface(Ci.nsIWritablePropertyBag);
function earlyInit() { // Convert to a JS object
// This is called before onload fires, so we can't be certain that any elements args = {};
// in the document have their bindings ready, so don't call any methods/properties let propEnum = propBag.enumerator;
// here on xul elements that come from xbl bindings. while (propEnum.hasMoreElements()) {
let prop = propEnum.getNext().QueryInterface(Ci.nsIProperty);
promptType = gArgs.getProperty("promptType"); args[prop.name] = prop.value;
switch (promptType) {
case "alert":
case "alertCheck":
hasInputField = false;
numButtons = 1;
iconClass = "alert-icon";
soundID = Ci.nsISound.EVENT_ALERT_DIALOG_OPEN;
break;
case "confirmCheck":
case "confirm":
hasInputField = false;
numButtons = 2;
iconClass = "question-icon";
soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
break;
case "confirmEx":
numButtons = 0;
if (gArgs.hasKey("button0Label"))
numButtons++;
if (gArgs.hasKey("button1Label"))
numButtons++;
if (gArgs.hasKey("button2Label"))
numButtons++;
if (gArgs.hasKey("button3Label"))
numButtons++;
if (numButtons == 0)
throw "A dialog with no buttons? Can not haz.";
hasInputField = false;
iconClass = "question-icon";
soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
break;
case "prompt":
numButtons = 2;
iconClass = "question-icon";
soundID = Ci.nsISound.EVENT_PROMPT_DIALOG_OPEN;
initTextbox("login", gArgs.getProperty("value"));
// Clear the label, since this isn't really a username prompt.
document.getElementById("loginLabel").setAttribute("value", "");
break;
case "promptUserAndPass":
numButtons = 2;
iconClass = "authentication-icon question-icon";
soundID = Ci.nsISound.EVENT_PROMPT_DIALOG_OPEN;
initTextbox("login", gArgs.getProperty("user"));
initTextbox("password1", gArgs.getProperty("pass"));
break;
case "promptPassword":
numButtons = 2;
iconClass = "authentication-icon question-icon";
soundID = Ci.nsISound.EVENT_PROMPT_DIALOG_OPEN;
initTextbox("password1", gArgs.getProperty("pass"));
// Clear the label, since the message presumably indicates its purpose.
document.getElementById("password1Label").setAttribute("value", "");
break;
default:
Cu.reportError("commonDialog opened for unknown type: " + promptType);
window.close();
} }
let dialog = document.documentElement;
let ui = {
loginContainer : document.getElementById("loginContainer"),
loginTextbox : document.getElementById("loginTextbox"),
loginLabel : document.getElementById("loginLabel"),
password1Container : document.getElementById("password1Container"),
password1Textbox : document.getElementById("password1Textbox"),
password1Label : document.getElementById("password1Label"),
infoBody : document.getElementById("info.body"),
infoTitle : document.getElementById("info.title"),
infoIcon : document.getElementById("info.icon"),
checkbox : document.getElementById("checkbox"),
checkboxContainer : document.getElementById("checkboxContainer"),
button3 : dialog.getButton("extra2"),
button2 : dialog.getButton("extra1"),
button1 : dialog.getButton("cancel"),
button0 : dialog.getButton("accept"),
focusTarget : window,
};
// limit the dialog to the screen width
document.getElementById("filler").maxWidth = screen.availWidth;
Services.obs.addObserver(softkbObserver, "softkb-change", false);
Dialog = new CommonDialog(args, ui);
Dialog.onLoad(dialog);
window.getAttention();
} }
function initTextbox(aName, aValue) { function commonDialogOnUnload() {
document.getElementById(aName + "Container").hidden = false; Services.obs.removeObserver(softkbObserver, "softkb-change");
document.getElementById(aName + "Textbox").setAttribute("value", aValue); // Convert args back into property bag
} for (let propName in args)
propBag.setProperty(propName, args[propName]);
function setLabelForNode(aNode, aLabel, aIsLabelFlag) {
// This is for labels which may contain embedded access keys.
// If we end in (&X) where X represents the access key, optionally preceded
// by spaces and/or followed by the ':' character, store the access key and
// remove the access key placeholder + leading spaces from the label.
// Otherwise a character preceded by one but not two &s is the access key.
// Store it and remove the &.
// Note that if you change the following code, see the comment of
// nsTextBoxFrame::UpdateAccessTitle.
var accessKey = null;
if (/ *\(\&([^&])\)(:)?$/.test(aLabel)) {
aLabel = RegExp.leftContext + RegExp.$2;
accessKey = RegExp.$1;
} else if (/^(.*[^&])?\&(([^&]).*$)/.test(aLabel)) {
aLabel = RegExp.$1 + RegExp.$2;
accessKey = RegExp.$3;
}
// && is the magic sequence to embed an & in your label.
aLabel = aLabel.replace(/\&\&/g, "&");
if (aIsLabelFlag) { // Set text for <label> element
aNode.setAttribute("value", aLabel);
} else { // Set text for other xul elements
aNode.label = aLabel;
}
// XXXjag bug 325251
// Need to set this after aNode.setAttribute("value", aLabel);
if (accessKey)
aNode.accessKey = accessKey;
} }
function softkbObserver(subject, topic, data) { function softkbObserver(subject, topic, data) {
@ -167,201 +107,3 @@ function softkbObserver(subject, topic, data) {
window.moveTo(left, top); window.moveTo(left, top);
} }
} }
function commonDialogOnLoad() {
// limit the dialog to the screen width
document.getElementById("filler").maxWidth = screen.availWidth;
// set the document title
let title = gArgs.getProperty("title");
#ifdef XP_MACOSX
document.getElementById("info.title").appendChild(document.createTextNode(title));
#else
document.title = title;
#endif
Services.obs.addObserver(softkbObserver, "softkb-change", false);
// Set button visibility
let dialog = document.documentElement;
switch (numButtons) {
case 1:
dialog.getButton("cancel").hidden = true;
break;
case 4:
dialog.getButton("extra2").hidden = false;
case 3:
dialog.getButton("extra1").hidden = false;
}
// Set button labels
switch (numButtons) {
case 4:
setLabelForNode(document.documentElement.getButton("extra2"), gArgs.getProperty("button3Label"));
// fall through
case 3:
setLabelForNode(document.documentElement.getButton("extra1"), gArgs.getProperty("button2Label"));
// fall through
default:
case 2:
if (gArgs.hasKey("button1Label"))
setLabelForNode(document.documentElement.getButton("cancel"), gArgs.getProperty("button1Label"));
// fall through
case 1:
if (gArgs.hasKey("button0Label"))
setLabelForNode(document.documentElement.getButton("accept"), gArgs.getProperty("button0Label"));
break;
}
// display the main text
// Bug 317334 - crop string length as a workaround.
let croppedMessage = gArgs.getProperty("text").substr(0, 10000);
document.getElementById("info.body").appendChild(document.createTextNode(croppedMessage));
if (gArgs.hasKey("checkLabel")) {
let label = gArgs.getProperty("checkLabel")
// Only show the checkbox if label has a value.
if (label) {
document.getElementById("checkboxContainer").hidden = false;
let checkboxElement = document.getElementById("checkbox");
setLabelForNode(checkboxElement, label);
checkboxElement.checked = gArgs.getProperty("checked");
}
}
// set the icon
document.getElementById("info.icon").className += " " + iconClass;
// set default result to cancelled
gArgs.setProperty("ok", false);
gArgs.setProperty("buttonNumClicked", 1);
// If there are no input fields on the dialog, select the default button.
// Otherwise, select the appropriate input field.
if (!hasInputField) {
let dlgButtons = ['accept', 'cancel', 'extra1', 'extra2'];
// Set the default button and focus it on non-OS X systems
let b = 0;
if (gArgs.hasKey("defaultButtonNum"))
b = gArgs.getProperty("defaultButtonNum");
let dButton = dlgButtons[b];
// XXX shouldn't we set the default even when a textbox is focused?
document.documentElement.defaultButton = dButton;
#ifndef XP_MACOSX
document.documentElement.getButton(dButton).focus();
#endif
} else {
if (promptType == "promptPassword")
document.getElementById("password1Textbox").select();
else
document.getElementById("loginTextbox").select();
}
if (gArgs.hasKey("enableDelay") && gArgs.getProperty("enableDelay")) {
let delayInterval = Services.prefs.getIntPref("security.dialog_enable_delay");
document.documentElement.getButton("accept").disabled = true;
document.documentElement.getButton("extra1").disabled = true;
document.documentElement.getButton("extra2").disabled = true;
setTimeout(commonDialogReenableButtons, delayInterval);
addEventListener("blur", commonDialogBlur, false);
addEventListener("focus", commonDialogFocus, false);
}
window.getAttention();
// play sound
try {
if (soundID) {
Cc["@mozilla.org/sound;1"].
createInstance(Ci.nsISound).
playEventSound(soundID);
}
} catch (e) { }
Services.obs.notifyObservers(window, "common-dialog-loaded", null);
}
function commonDialogOnUnload() {
Services.obs.removeObserver(softkbObserver, "softkb-change");
}
var gDelayExpired = false;
var gBlurred = false;
function commonDialogBlur(aEvent) {
if (aEvent.target != document)
return;
gBlurred = true;
document.documentElement.getButton("accept").disabled = true;
document.documentElement.getButton("extra1").disabled = true;
document.documentElement.getButton("extra2").disabled = true;
}
function commonDialogFocus(aEvent) {
if (aEvent.target != document)
return;
gBlurred = false;
// When refocusing the window, don't enable the buttons unless the countdown
// delay has expired.
if (gDelayExpired) {
let script;
script = "document.documentElement.getButton('accept').disabled = false; ";
script += "document.documentElement.getButton('extra1').disabled = false; ";
script += "document.documentElement.getButton('extra2').disabled = false;";
setTimeout(script, 250);
}
}
function commonDialogReenableButtons() {
// Don't automatically enable the buttons if we're not in the foreground
if (!gBlurred) {
document.documentElement.getButton("accept").disabled = false;
document.documentElement.getButton("extra1").disabled = false;
document.documentElement.getButton("extra2").disabled = false;
}
gDelayExpired = true;
}
function onCheckboxClick(aCheckboxElement) {
gArgs.setProperty("checked", aCheckboxElement.checked);
}
function commonDialogOnAccept() {
gArgs.setProperty("ok", true);
gArgs.setProperty("buttonNumClicked", 0);
let username = document.getElementById("loginTextbox").value;
let password = document.getElementById("password1Textbox").value;
// Return textfield values
switch (promptType) {
case "prompt":
gArgs.setProperty("value", username);
break;
case "promptUserAndPass":
gArgs.setProperty("user", username);
gArgs.setProperty("pass", password);
break;
case "promptPassword":
gArgs.setProperty("pass", password);
break;
}
}
function commonDialogOnExtra1() {
// .setProperty("ok", true)?
gArgs.setProperty("buttonNumClicked", 2);
window.close();
}
function commonDialogOnExtra2() {
// .setProperty("ok", true)?
gArgs.setProperty("buttonNumClicked", 3);
window.close();
}

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

@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://global/content/commonDialog.css" type="text/css"?> <?xml-stylesheet href="chrome://global/content/commonDialog.css" type="text/css"?>
@ -7,15 +7,16 @@
<!DOCTYPE dialog SYSTEM "chrome://global/locale/commonDialog.dtd"> <!DOCTYPE dialog SYSTEM "chrome://global/locale/commonDialog.dtd">
<dialog id="commonDialog" <dialog id="commonDialog"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
aria-describedby="info.body" aria-describedby="info.body"
onload="commonDialogOnLoad();" onload="commonDialogOnLoad();"
onunload="commonDialogOnUnload();" onunload="commonDialogOnUnload();"
ondialogaccept="return commonDialogOnAccept();" ondialogaccept="Dialog.onButton0(); return true;"
ondialogextra1="return commonDialogOnExtra1();" ondialogcancel="Dialog.onButton1(); return true;"
ondialogextra2="return commonDialogOnExtra2();" ondialogextra1="Dialog.onButton2(); window.close();"
ondialogextra2="Dialog.onButton3(); window.close();"
buttonpack="center"> buttonpack="center">
<script type="application/javascript" src="chrome://global/content/commonDialog.js"/> <script type="application/javascript" src="chrome://global/content/commonDialog.js"/>
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/> <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
@ -55,10 +56,12 @@
<image id="info.icon" class="spaced"/> <image id="info.icon" class="spaced"/>
</hbox> </hbox>
<vbox id="infoContainer"> <vbox id="infoContainer">
#ifdef XP_MACOSX <!-- Only shown on OS X, since it has no dialog title -->
<!-- Dialog title is inside dialog for OS X --> <description id="info.title"
<description id="info.title"/> #ifndef XP_MACOSX
style="display: none"
#endif #endif
/>
<spacer style="height: 1em"/> <spacer style="height: 1em"/>
<description id="info.body" context="contentAreaContextMenu" noinitialfocus="true"/> <description id="info.body" context="contentAreaContextMenu" noinitialfocus="true"/>
</vbox> </vbox>
@ -73,16 +76,9 @@
</row> </row>
<row id="checkboxContainer" hidden="true"> <row id="checkboxContainer" hidden="true">
<spacer/> <spacer/>
<checkbox id="checkbox" oncommand="onCheckboxClick(this);"/> <checkbox id="checkbox" oncommand="Dialog.onCheckbox()"/>
</row> </row>
</rows> </rows>
</grid> </grid>
<!-- This method is called inline because it may unset hidden="true" on the
above boxes, causing their frames to be build and bindings to load.
So, by calling this inline, we guarantee the textboxes and checkboxes
above will have their bindings before initButtons is called, and the
dialog will be intrinsically sized correctly. -->
<script type="application/javascript">earlyInit();</script>
</dialog> </dialog>

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

@ -41,12 +41,12 @@ const Cr = Components.results;
const Cc = Components.classes; const Cc = Components.classes;
const Cu = Components.utils; const Cu = Components.utils;
let gArgs = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2) let gArgs, listBox;
.QueryInterface(Ci.nsIWritablePropertyBag);
let listBox;
function dialogOnLoad() { function dialogOnLoad() {
gArgs = window.arguments[0].QueryInterface(Ci.nsIWritablePropertyBag2)
.QueryInterface(Ci.nsIWritablePropertyBag);
let promptType = gArgs.getProperty("promptType"); let promptType = gArgs.getProperty("promptType");
if (promptType != "select") { if (promptType != "select") {
Cu.reportError("selectDialog opened for unknown type: " + promptType); Cu.reportError("selectDialog opened for unknown type: " + promptType);

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

@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK ***** <!-- ***** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1 Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -37,10 +37,10 @@
***** END LICENSE BLOCK ***** --> ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://global/locale/commonDialog.dtd"> <!DOCTYPE dialog SYSTEM "chrome://global/locale/commonDialog.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" <dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="dialogOnLoad()" onload="dialogOnLoad()"
ondialogaccept="return dialogOK();"> ondialogaccept="return dialogOK();">

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

@ -0,0 +1,350 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is CommonDialog.jsm code.
*
* The Initial Developer of the Original Code is the Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Justin Dolske <dolske@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var EXPORTED_SYMBOLS = ["CommonDialog"];
const Ci = Components.interfaces;
const Cr = Components.results;
const Cc = Components.classes;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function CommonDialog(args, ui) {
this.args = args;
this.ui = ui;
}
CommonDialog.prototype = {
args : null,
ui : null,
hasInputField : true,
numButtons : undefined,
iconClass : undefined,
soundID : undefined,
focusTimer : null,
onLoad : function(xulDialog) {
switch (this.args.promptType) {
case "alert":
case "alertCheck":
this.hasInputField = false;
this.numButtons = 1;
this.iconClass = ["alert-icon"];
this.soundID = Ci.nsISound.EVENT_ALERT_DIALOG_OPEN;
break;
case "confirmCheck":
case "confirm":
this.hasInputField = false;
this.numButtons = 2;
this.iconClass = ["question-icon"];
this.soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
break;
case "confirmEx":
var numButtons = 0;
if (this.args.button0Label)
numButtons++;
if (this.args.button1Label)
numButtons++;
if (this.args.button2Label)
numButtons++;
if (this.args.button3Label)
numButtons++;
if (numButtons == 0)
throw "A dialog with no buttons? Can not haz.";
this.numButtons = numButtons;
this.hasInputField = false;
this.iconClass = ["question-icon"];
this.soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
break;
case "prompt":
this.numButtons = 2;
this.iconClass = ["question-icon"];
this.soundID = Ci.nsISound.EVENT_PROMPT_DIALOG_OPEN;
this.initTextbox("login", this.args.value);
// Clear the label, since this isn't really a username prompt.
this.ui.loginLabel.setAttribute("value", "");
break;
case "promptUserAndPass":
this.numButtons = 2;
this.iconClass = ["authentication-icon", "question-icon"];
this.soundID = Ci.nsISound.EVENT_PROMPT_DIALOG_OPEN;
this.initTextbox("login", this.args.user);
this.initTextbox("password1", this.args.pass);
break;
case "promptPassword":
this.numButtons = 2;
this.iconClass = ["authentication-icon", "question-icon"];
this.soundID = Ci.nsISound.EVENT_PROMPT_DIALOG_OPEN;
this.initTextbox("password1", this.args.pass);
// Clear the label, since the message presumably indicates its purpose.
this.ui.password1Label.setAttribute("value", "");
break;
default:
Cu.reportError("commonDialog opened for unknown type: " + this.args.promptType);
throw "unknown dialog type";
}
// set the document title
let title = this.args.title;
// OS X doesn't have a title on modal dialogs, this is hidden on other platforms.
let infoTitle = this.ui.infoTitle;
infoTitle.appendChild(infoTitle.ownerDocument.createTextNode(title));
if (xulDialog)
xulDialog.ownerDocument.title = title;
// Set button labels and visibility
//
// This assumes that button0 defaults to a visible "ok" button, and
// button1 defaults to a visible "cancel" button. The other 2 buttons
// have no default labels (and are hidden).
switch (this.numButtons) {
case 4:
this.setLabelForNode(this.ui.button3, this.args.button3Label);
this.ui.button3.hidden = false;
// fall through
case 3:
this.setLabelForNode(this.ui.button2, this.args.button2Label);
this.ui.button2.hidden = false;
// fall through
case 2:
// Defaults to a visible "cancel" button
if (this.args.button1Label)
this.setLabelForNode(this.ui.button1, this.args.button1Label);
break;
case 1:
this.ui.button1.hidden = true;
break;
}
// Defaults to a visible "ok" button
if (this.args.button0Label)
this.setLabelForNode(this.ui.button0, this.args.button0Label);
// display the main text
// Bug 317334 - crop string length as a workaround.
let croppedMessage = this.args.text.substr(0, 10000);
let infoBody = this.ui.infoBody;
infoBody.appendChild(infoBody.ownerDocument.createTextNode(croppedMessage));
let label = this.args.checkLabel;
if (label) {
// Only show the checkbox if label has a value.
this.ui.checkboxContainer.hidden = false;
this.setLabelForNode(this.ui.checkbox, label);
this.ui.checkbox.checked = this.args.checked;
}
// set the icon
let icon = this.ui.infoIcon;
this.iconClass.forEach(function(el,idx,arr) icon.classList.add(el));
// set default result to cancelled
this.args.ok = false;
this.args.buttonNumClicked = 1;
// If there are no input fields on the dialog, select the default button.
// Otherwise, select the appropriate input field.
// XXX shouldn't we set an unfocused default even when a textbox is focused?
if (!this.hasInputField) {
// Set the default button (and focus it on non-OS X systems)
let b = 0;
if (this.args.defaultButtonNum)
b = this.args.defaultButtonNum;
let button = this.ui["button" + b];
if (xulDialog) {
xulDialog.defaultButton = ['accept', 'cancel', 'extra1', 'extra2'][b];
let isOSX = ("nsILocalFileMac" in Components.interfaces);
if (!isOSX)
button.focus();
}
// TODO:
// else
// (tabmodal prompts need to set a default button for Enter to act upon)
} else {
if (this.args.promptType == "promptPassword")
this.ui.password1Textbox.select();
else
this.ui.loginTextbox.select();
}
if (this.args.enableDelay) {
this.setButtonsEnabledState(false);
// Use a longer, pref-controlled delay when the dialog is first opened.
let delayTime = Services.prefs.getIntPref("security.dialog_enable_delay");
this.startOnFocusDelay(delayTime);
let self = this;
this.ui.focusTarget.addEventListener("blur", function(e) { self.onBlur(e); }, false);
this.ui.focusTarget.addEventListener("focus", function(e) { self.onFocus(e); }, false);
}
// play sound
try {
if (this.soundID) {
Cc["@mozilla.org/sound;1"].
createInstance(Ci.nsISound).
playEventSound(soundID);
}
} catch (e) { }
if (xulDialog)
Services.obs.notifyObservers(xulDialog.ownerDocument.defaultView, "common-dialog-loaded", null);
// TODO:
// else
// (notify using what as the subject?)
},
setLabelForNode: function(aNode, aLabel) {
// This is for labels which may contain embedded access keys.
// If we end in (&X) where X represents the access key, optionally preceded
// by spaces and/or followed by the ':' character, store the access key and
// remove the access key placeholder + leading spaces from the label.
// Otherwise a character preceded by one but not two &s is the access key.
// Store it and remove the &.
// Note that if you change the following code, see the comment of
// nsTextBoxFrame::UpdateAccessTitle.
var accessKey = null;
if (/ *\(\&([^&])\)(:)?$/.test(aLabel)) {
aLabel = RegExp.leftContext + RegExp.$2;
accessKey = RegExp.$1;
} else if (/^(.*[^&])?\&(([^&]).*$)/.test(aLabel)) {
aLabel = RegExp.$1 + RegExp.$2;
accessKey = RegExp.$3;
}
// && is the magic sequence to embed an & in your label.
aLabel = aLabel.replace(/\&\&/g, "&");
aNode.label = aLabel;
// XXXjag bug 325251
// Need to set this after aNode.setAttribute("value", aLabel);
if (accessKey)
aNode.accessKey = accessKey;
},
initTextbox : function (aName, aValue) {
this.ui[aName + "Container"].hidden = false;
this.ui[aName + "Textbox"].setAttribute("value", aValue);
},
setButtonsEnabledState : function(enabled) {
this.ui.button0.disabled = !enabled;
// button1 (cancel) remains enabled.
this.ui.button2.disabled = !enabled;
this.ui.button3.disabled = !enabled;
},
onBlur : function (aEvent) {
if (aEvent.target != this.ui.focusTarget)
return;
this.setButtonsEnabledState(false);
// If we blur while waiting to enable the buttons, just cancel the
// timer to ensure the delay doesn't fire while not focused.
if (this.focusTimer) {
this.focusTimer.cancel();
this.focusTimer = null;
}
},
onFocus : function (aEvent) {
if (aEvent.target != this.ui.focusTarget)
return;
this.startOnFocusDelay();
},
startOnFocusDelay : function(delayTime) {
// Shouldn't already have a timer, but just in case...
if (this.focusTimer)
return;
// If no delay specified, use 250ms. (This is the normal case for when
// after the dialog has been opened and focus shifts.)
if (!delayTime)
delayTime = 250;
let self = this;
this.focusTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this.focusTimer.initWithCallback(function() { self.onFocusTimeout(); },
delayTime, Ci.nsITimer.TYPE_ONE_SHOT);
},
onFocusTimeout : function() {
this.focusTimer = null;
this.setButtonsEnabledState(true);
},
onCheckbox : function() {
this.args.checked = this.ui.checkbox.checked;
},
onButton0 : function() {
this.args.ok = true;
this.args.buttonNumClicked = 0;
let username = this.ui.loginTextbox.value;
let password = this.ui.password1Textbox.value;
// Return textfield values
switch (this.args.promptType) {
case "prompt":
this.args.value = username;
break;
case "promptUserAndPass":
this.args.user = username;
this.args.pass = password;
break;
case "promptPassword":
this.args.pass = password;
break;
}
},
onButton1 : function() {
this.args.buttonNumClicked = 1;
},
onButton2 : function() {
this.args.buttonNumClicked = 2;
},
onButton3 : function() {
this.args.buttonNumClicked = 3;
},
};

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

@ -48,4 +48,8 @@ EXTRA_COMPONENTS = \
nsPrompter.manifest \ nsPrompter.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
CommonDialog.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

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

@ -322,6 +322,25 @@ let PromptUtils = {
return text; return text;
}, },
objectToPropBag : function (obj) {
let bag = Cc["@mozilla.org/hash-property-bag;1"].
createInstance(Ci.nsIWritablePropertyBag2);
bag.QueryInterface(Ci.nsIWritablePropertyBag);
for (let propName in obj)
bag.setProperty(propName, obj[propName]);
return bag;
},
propBagToObject : function (propBag, obj) {
// Here we iterate over the object's original properties, not the bag
// (ie, the prompt can't return more/different properties than were
// passed in). This just helps ensure that the caller provides default
// values, lest the prompt forget to set them.
for (let propName in obj)
obj[propName] = propBag.getProperty(propName);
},
}; };
XPCOMUtils.defineLazyGetter(PromptUtils, "strBundle", function () { XPCOMUtils.defineLazyGetter(PromptUtils, "strBundle", function () {
@ -343,8 +362,19 @@ XPCOMUtils.defineLazyGetter(PromptUtils, "ellipsis", function () {
const COMMON_DIALOG = "chrome://global/content/commonDialog.xul"; function openModalWindow(domWin, uri, args) {
const SELECT_DIALOG = "chrome://global/content/selectDialog.xul"; // XXX do we want to do modal state if we fall back to .activeWindow?
if (!domWin)
domWin = Services.ww.activeWindow;
// XXX domWin may still be null here if there are _no_ windows open.
// Note that we don't need to fire DOMWillOpenModalDialog and
// DOMModalDialogClosed events here, wwatcher's OpenWindowJSInternal
// will do that. Similarly for enterModalState / leaveModalState.
Services.ww.openWindow(domWin, uri, "_blank", "centerscreen,chrome,modal,titlebar", args);
}
function ModalPrompter(domWin) { function ModalPrompter(domWin) {
this.domWin = domWin; this.domWin = domWin;
@ -358,25 +388,15 @@ ModalPrompter.prototype = {
/* ---------- internal methods ---------- */ /* ---------- internal methods ---------- */
newPropBag : function () { openPrompt : function (args) {
let bag = Cc["@mozilla.org/hash-property-bag;1"]. const COMMON_DIALOG = "chrome://global/content/commonDialog.xul";
createInstance(Ci.nsIWritablePropertyBag2); const SELECT_DIALOG = "chrome://global/content/selectDialog.xul";
return bag.QueryInterface(Ci.nsIWritablePropertyBag);
},
openPrompt : function (uri, args) { let uri = (args.promptType == "select") ? SELECT_DIALOG : COMMON_DIALOG;
// XXX do we want to do modal state if we fall back to .activeWindow?
let domWin = this.domWin;
if (!domWin)
domWin = Services.ww.activeWindow;
// XXX domWin may still be null here if there are _no_ windows open. let propBag = PromptUtils.objectToPropBag(args);
openModalWindow(this.domWin, uri, propBag);
// Note that we don't need to fire DOMWillOpenModalDialog and PromptUtils.propBagToObject(propBag, args);
// DOMModalDialogClosed events here, wwatcher's OpenWindowJSInternal
// will do that. Similarly for enterModalState / leaveModalState.
Services.ww.openWindow(domWin, uri, "_blank", "centerscreen,chrome,modal,titlebar", args);
}, },
@ -421,66 +441,70 @@ ModalPrompter.prototype = {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("Alert"); title = PromptUtils.getLocalizedString("Alert");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "alert"); promptType: "alert",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
};
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
}, },
alertCheck : function (title, text, checkLabel, checkValue) { alertCheck : function (title, text, checkLabel, checkValue) {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("Alert"); title = PromptUtils.getLocalizedString("Alert");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "alertCheck"); promptType: "alertCheck",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("checkLabel", checkLabel); checkLabel: checkLabel,
args.setProperty("checked", checkValue.value); checked: checkValue.value,
};
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
// Checkbox state always returned, even if cancel clicked. // Checkbox state always returned, even if cancel clicked.
checkValue.value = args.getProperty("checked"); checkValue.value = args.checked;
}, },
confirm : function (title, text) { confirm : function (title, text) {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("Confirm"); title = PromptUtils.getLocalizedString("Confirm");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "confirm"); promptType: "confirm",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("ok", false); ok: false,
};
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
// Did user click Ok or Cancel? // Did user click Ok or Cancel?
return args.getProperty("ok"); return args.ok;
}, },
confirmCheck : function (title, text, checkLabel, checkValue) { confirmCheck : function (title, text, checkLabel, checkValue) {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("ConfirmCheck"); title = PromptUtils.getLocalizedString("ConfirmCheck");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "confirmCheck"); promptType: "confirmCheck",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("checkLabel", checkLabel); checkLabel: checkLabel,
args.setProperty("checked", checkValue.value); checked: checkValue.value,
args.setProperty("ok", false); ok: false,
};
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
// Checkbox state always returned, even if cancel clicked. // Checkbox state always returned, even if cancel clicked.
checkValue.value = args.getProperty("checked"); checkValue.value = args.checked;
// Did user click Ok or Cancel? // Did user click Ok or Cancel?
return args.getProperty("ok"); return args.ok;
}, },
confirmEx : function (title, text, flags, button0, button1, button2, confirmEx : function (title, text, flags, button0, button1, button2,
@ -489,60 +513,62 @@ ModalPrompter.prototype = {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("Confirm"); title = PromptUtils.getLocalizedString("Confirm");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "confirmEx"); promptType: "confirmEx",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("checkLabel", checkLabel); checkLabel: checkLabel,
args.setProperty("checked", checkValue.value); checked: checkValue.value,
args.setProperty("ok", false); ok: false,
args.setProperty("buttonNumClicked", 1); buttonNumClicked: 1,
};
let [label0, label1, label2, defaultButtonNum, isDelayEnabled] = let [label0, label1, label2, defaultButtonNum, isDelayEnabled] =
PromptUtils.confirmExHelper(flags, button0, button1, button2); PromptUtils.confirmExHelper(flags, button0, button1, button2);
args.setProperty("defaultButtonNum", defaultButtonNum); args.defaultButtonNum = defaultButtonNum;
args.setProperty("enableDelay", isDelayEnabled); args.enableDelay = isDelayEnabled;
if (label0) { if (label0) {
args.setProperty("button0Label", label0); args.button0Label = label0;
if (label1) { if (label1) {
args.setProperty("button1Label", label1); args.button1Label = label1;
if (label2) { if (label2) {
args.setProperty("button2Label", label2); args.button2Label = label2;
} }
} }
} }
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
// Checkbox state always returned, even if cancel clicked. // Checkbox state always returned, even if cancel clicked.
checkValue.value = args.getProperty("checked"); checkValue.value = args.checked;
// Get the number of the button the user clicked. // Get the number of the button the user clicked.
return args.getProperty("buttonNumClicked"); return args.buttonNumClicked;
}, },
nsIPrompt_prompt : function (title, text, value, checkLabel, checkValue) { nsIPrompt_prompt : function (title, text, value, checkLabel, checkValue) {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("Prompt"); title = PromptUtils.getLocalizedString("Prompt");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "prompt"); promptType: "prompt",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("value", value.value); value: value.value,
args.setProperty("checkLabel", checkLabel); checkLabel: checkLabel,
args.setProperty("checked", checkValue.value); checked: checkValue.value,
args.setProperty("ok", false); ok: false,
};
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
// Did user click Ok or Cancel? // Did user click Ok or Cancel?
let ok = args.getProperty("ok"); let ok = args.ok;
if (ok) { if (ok) {
checkValue.value = args.getProperty("checked"); checkValue.value = args.checked;
value.value = args.getProperty("value"); value.value = args.value;
} }
return ok; return ok;
@ -552,24 +578,25 @@ ModalPrompter.prototype = {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("PromptUsernameAndPassword2"); title = PromptUtils.getLocalizedString("PromptUsernameAndPassword2");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "promptUserAndPass"); promptType: "promptUserAndPass",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("user", user.value); user: user.value,
args.setProperty("pass", pass.value); pass: pass.value,
args.setProperty("checkLabel", checkLabel); checkLabel: checkLabel,
args.setProperty("checked", checkValue.value); checked: checkValue.value,
args.setProperty("ok", false); ok: false,
};
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
// Did user click Ok or Cancel? // Did user click Ok or Cancel?
let ok = args.getProperty("ok"); let ok = args.ok;
if (ok) { if (ok) {
checkValue.value = args.getProperty("checked"); checkValue.value = args.checked;
user.value = args.getProperty("user"); user.value = args.user;
pass.value = args.getProperty("pass"); pass.value = args.pass;
} }
return ok; return ok;
@ -579,22 +606,23 @@ ModalPrompter.prototype = {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("PromptPassword2"); title = PromptUtils.getLocalizedString("PromptPassword2");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "promptPassword"); promptType: "promptPassword",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("pass", pass.value); pass: pass.value,
args.setProperty("checkLabel", checkLabel); checkLabel: checkLabel,
args.setProperty("checked", checkValue.value); checked: checkValue.value,
args.setProperty("ok", false); ok: false,
}
this.openPrompt(COMMON_DIALOG, args); this.openPrompt(args);
// Did user click Ok or Cancel? // Did user click Ok or Cancel?
let ok = args.getProperty("ok"); let ok = args.ok;
if (ok) { if (ok) {
checkValue.value = args.getProperty("checked"); checkValue.value = args.checked;
pass.value = args.getProperty("pass"); pass.value = args.pass;
} }
return ok; return ok;
@ -604,19 +632,21 @@ ModalPrompter.prototype = {
if (!title) if (!title)
title = PromptUtils.getLocalizedString("Select"); title = PromptUtils.getLocalizedString("Select");
let args = this.newPropBag(); let args = {
args.setProperty("promptType", "select"); promptType: "select",
args.setProperty("title", title); title: title,
args.setProperty("text", text); text: text,
args.setProperty("list", list); list: list,
args.setProperty("ok", false); selected: -1,
ok: false,
};
this.openPrompt(SELECT_DIALOG, args); this.openPrompt(args);
// Did user click Ok or Cancel? // Did user click Ok or Cancel?
let ok = args.getProperty("ok"); let ok = args.ok;
if (ok) if (ok)
selected.value = args.getProperty("selected"); selected.value = args.selected;
return ok; return ok;
}, },

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

@ -24,6 +24,20 @@ let prompter = Cc["@mozilla.org/embedcomp/prompt-service;1"].
getService(Ci.nsIPromptService2); getService(Ci.nsIPromptService2);
let ioService = Cc["@mozilla.org/network/io-service;1"]. let ioService = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService); getService(Ci.nsIIOService);
let pollTimer;
function pollDialog(dialog) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (dialog.getButton("accept").disabled)
return;
ok(true, "dialog button is enabled now");
pollTimer.cancel();
pollTimer = null;
dialog.acceptDialog();
didDialog = true;
}
function checkExpectedState(doc, state) { function checkExpectedState(doc, state) {
let msg = doc.getElementById("info.body").textContent; let msg = doc.getElementById("info.body").textContent;
@ -654,6 +668,27 @@ function handleDialog(doc, testNum) {
checkExpectedState(doc, state); checkExpectedState(doc, state);
break; break;
case 30:
// ConfirmEx (with delay, ok)
state = {
msg : "This is the confirmEx delay text.",
title : "TestTitle",
iconClass : "question-icon",
textHidden : true,
passHidden : true,
checkHidden : true,
textValue : "",
passValue : "",
checkMsg : "",
checked : false,
};
is(dialog.getButton("accept").label, "OK", "Checking accept-button label");
is(dialog.getButton("cancel").label, "Cancel", "Checking cancel-button label");
is(dialog.getButton("accept").disabled, true, "Checking accept-button is disabled");
is(dialog.getButton("cancel").disabled, false, "Checking cancel-button isn't disabled ");
checkExpectedState(doc, state);
break;
case 100: case 100:
// PromptAuth (no realm, ok, with checkbox) // PromptAuth (no realm, ok, with checkbox)
@ -711,6 +746,14 @@ function handleDialog(doc, testNum) {
if (testNum == 28) { if (testNum == 28) {
dialog._doButtonCommand("extra1"); dialog._doButtonCommand("extra1");
} else if (testNum == 30) {
// Buttons are disabled at the moment, poll until they're reenabled.
// Can't use setInterval here, because the window's in a modal state
// and thus DOM events are suppressed.
pollTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
pollTimer.initWithCallback(function() { pollDialog(dialog); },
100, Ci.nsITimer.TYPE_REPEATING_SLACK);
return;
} else { } else {
if (clickOK) if (clickOK)
dialog.acceptDialog(); dialog.acceptDialog();
@ -1049,6 +1092,15 @@ prompter.alert(null, "TestTitle", "This is the alert text.");
ok(didDialog, "handleDialog was invoked"); ok(didDialog, "handleDialog was invoked");
// ===== test 30 =====
// ConfirmEx (delay, ok)
testNum++;
startCallbackTimer();
flags = (Ci.nsIPromptService.STD_OK_CANCEL_BUTTONS | Ci.nsIPromptService.BUTTON_DELAY_ENABLE);
clickedButton = prompter.confirmEx(window, "TestTitle", "This is the confirmEx delay text.", flags, null, null, null, null, {});
is(clickedButton, 0, "checked expected button num click");
ok(didDialog, "handleDialog was invoked");
// promptAuth already tested via password manager but do a few specific things here. // promptAuth already tested via password manager but do a few specific things here.

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

@ -294,7 +294,8 @@ nsFormFillController::SetPopupOpen(PRBool aPopupOpen)
NS_ENSURE_STATE(presShell); NS_ENSURE_STATE(presShell);
presShell->ScrollContentIntoView(content, presShell->ScrollContentIntoView(content,
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE, NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE); NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
// mFocusedPopup can be destroyed after ScrollContentIntoView, see bug 420089 // mFocusedPopup can be destroyed after ScrollContentIntoView, see bug 420089
if (mFocusedPopup) if (mFocusedPopup)
mFocusedPopup->OpenAutocompletePopup(this, mFocusedInput); mFocusedPopup->OpenAutocompletePopup(this, mFocusedInput);

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

@ -259,6 +259,7 @@
</setter> </setter>
</property> </property>
<field name="_newElementCount">0</field>
<method name="_getToolbarItem"> <method name="_getToolbarItem">
<parameter name="aId"/> <parameter name="aId"/>
<body> <body>
@ -273,7 +274,10 @@
case "spring": case "spring":
case "spacer": case "spacer":
newItem = document.createElementNS(XUL_NS, "toolbar" + aId); newItem = document.createElementNS(XUL_NS, "toolbar" + aId);
newItem.id = aId + Date.now() + this.childNodes.length; // Due to timers resolution Date.now() can be the same for
// elements created in small timeframes. So ids are
// differentiated through a unique count suffix.
newItem.id = aId + Date.now() + (++this._newElementCount);
if (aId == "spring") if (aId == "spring")
newItem.flex = 1; newItem.flex = 1;
break; break;

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

@ -22,6 +22,19 @@ btnPageCSS=CSS
tipPageCSS=Log CSS parsing errors tipPageCSS=Log CSS parsing errors
btnPageJS=JS btnPageJS=JS
tipPageJS=Log JavaScript exceptions tipPageJS=Log JavaScript exceptions
# LOCALIZATION NOTE (btnPageWebDeveloper):
#
# This is used as the text of the "Web Developer" button on the toolbar. It
# shows or hides messages that the web developer inserted on the page for
# debugging purposes, using calls such console.log() and console.error(). You
# may wish to localize this as "Page" if that is clearer in your locale. See
# bug 601667 for more information.
btnPageWebDeveloper=Web Developer
# LOCALIZATION NOTE (tipPageWebDeveloper):
#
# This is used as the text of the tool tip for the "Web Developer" button on
# the toolbar.
tipPageWebDeveloper=Log messages sent to the "console" object
btnConsoleErrors=Errors btnConsoleErrors=Errors
tipConsoleErrors=Log calls to console.error() tipConsoleErrors=Log calls to console.error()
btnConsoleInfo=Info btnConsoleInfo=Info
@ -35,6 +48,11 @@ tipGlobal=Toggle Global Message logging
localConsole=Local Console localConsole=Local Console
clearConsoleCmd.label=Clear Console clearConsoleCmd.label=Clear Console
clearConsoleCmd.accesskey=e clearConsoleCmd.accesskey=e
# LOCALIZATION NOTE (btnClear):
#
# This is used as the text of the "Clear" button for the toolbar. It clears the
# contents of the console.
btnClear=Clear
stringFilter=Filter stringFilter=Filter
close.button=Close close.button=Close
close.accesskey=C close.accesskey=C

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

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="addon-test-pref-window"> id="addon-test-pref-window">
<label value="Oh hai!"/> <label value="Oh hai!"/>
</window> </window>

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

@ -1,77 +1,78 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Bug 557943 - Searching for addons can result in wrong results // Bug 557943 - Searching for addons can result in wrong results
var gManagerWindow; var gManagerWindow;
var gProvider;
function test() {
waitForExplicitFinish(); function test() {
waitForExplicitFinish();
gProvider = new MockProvider();
gProvider = new MockProvider();
gProvider.createAddons([{
id: "addon1@tests.mozilla.org", gProvider.createAddons([{
name: "Microsoft .NET Framework Assistant", id: "addon1@tests.mozilla.org",
description: "", name: "Microsoft .NET Framework Assistant",
version: "6.66" description: "",
}, { version: "6.66"
id: "addon2@tests.mozilla.org", }, {
name: "AwesomeNet Addon", id: "addon2@tests.mozilla.org",
description: "" name: "AwesomeNet Addon",
}, { description: ""
id: "addon3@tests.mozilla.org", }, {
name: "Dictionnaire MySpell en Francais (réforme 1990)", id: "addon3@tests.mozilla.org",
description: "" name: "Dictionnaire MySpell en Francais (réforme 1990)",
}]); description: ""
}]);
open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow; open_manager("addons://list/extension", function(aWindow) {
run_next_test(); gManagerWindow = aWindow;
}); run_next_test();
} });
}
function end_test() {
close_manager(gManagerWindow, function() { function end_test() {
finish(); close_manager(gManagerWindow, function() {
}); finish();
} });
}
function perform_search(aQuery, aCallback) {
var searchBox = gManagerWindow.document.getElementById("header-search"); function perform_search(aQuery, aCallback) {
searchBox.value = aQuery; var searchBox = gManagerWindow.document.getElementById("header-search");
searchBox.value = aQuery;
EventUtils.synthesizeMouse(searchBox, 2, 2, { }, gManagerWindow);
EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow); EventUtils.synthesizeMouse(searchBox, 2, 2, { }, gManagerWindow);
wait_for_view_load(gManagerWindow, function() { EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow);
var list = gManagerWindow.document.getElementById("search-list"); wait_for_view_load(gManagerWindow, function() {
var rows = list.getElementsByTagName("richlistitem"); var list = gManagerWindow.document.getElementById("search-list");
aCallback(rows); var rows = list.getElementsByTagName("richlistitem");
}); aCallback(rows);
} });
}
add_test(function() {
perform_search(".net", function(aRows) { add_test(function() {
is(aRows.length, 1, "Should only get one result"); perform_search(".net", function(aRows) {
is(aRows[0].mAddon.id, "addon1@tests.mozilla.org", "Should get expected addon as only result"); is(aRows.length, 1, "Should only get one result");
run_next_test(); is(aRows[0].mAddon.id, "addon1@tests.mozilla.org", "Should get expected addon as only result");
}); run_next_test();
}); });
});
add_test(function() {
perform_search("réf", function(aRows) { add_test(function() {
is(aRows.length, 1, "Should only get one result"); perform_search("réf", function(aRows) {
is(aRows[0].mAddon.id, "addon3@tests.mozilla.org", "Should get expected addon as only result"); is(aRows.length, 1, "Should only get one result");
run_next_test(); is(aRows[0].mAddon.id, "addon3@tests.mozilla.org", "Should get expected addon as only result");
}); run_next_test();
}); });
});
add_test(function() {
perform_search("javascript:void()", function(aRows) { add_test(function() {
is(aRows.length, 0, "Should not get any results"); perform_search("javascript:void()", function(aRows) {
run_next_test(); is(aRows.length, 0, "Should not get any results");
}); run_next_test();
}); });
});

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

@ -119,7 +119,8 @@ function open_compatibility_window(aInactiveAddonIds, aCallback) {
info("Compatibility dialog opened"); info("Compatibility dialog opened");
function page_shown(aEvent) { function page_shown(aEvent) {
info("Page " + aEvent.target.id + " shown"); if (aEvent.target.pageid)
info("Page " + aEvent.target.pageid + " shown");
} }
win.addEventListener("pageshow", page_shown, false); win.addEventListener("pageshow", page_shown, false);

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

@ -7,7 +7,9 @@
*/ */
function test() { function test() {
requestLongerTimeout(2); // Set the timeout to 300 seconds since this test can easily take 220 seconds
// to run on a Windows debug build when it runs in a tab.
requestLongerTimeout(10);
waitForExplicitFinish(); waitForExplicitFinish();

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

@ -1,159 +1,159 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Tests bug 567127 - Add install button to the add-ons manager // Tests bug 567127 - Add install button to the add-ons manager
var gFilePickerFiles = []; var gFilePickerFiles = [];
var gMockFilePickerFactory; var gMockFilePickerFactory;
var gMockFilePickerFactoryCID; var gMockFilePickerFactoryCID;
var gManagerWindow; var gManagerWindow;
function MockFilePicker() { } function MockFilePicker() { }
MockFilePicker.prototype = { MockFilePicker.prototype = {
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIFilePicker]), QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIFilePicker]),
init: function(aParent, aTitle, aMode) { }, init: function(aParent, aTitle, aMode) { },
appendFilters: function(aFilterMask) { }, appendFilters: function(aFilterMask) { },
appendFilter: function(aTitle, aFilter) { }, appendFilter: function(aTitle, aFilter) { },
defaultString: "", defaultString: "",
defaultExtension: "", defaultExtension: "",
filterIndex: 0, filterIndex: 0,
displayDirectory: null, displayDirectory: null,
file: null, file: null,
fileURL: null, fileURL: null,
get files() { get files() {
var i = 0; var i = 0;
return { return {
getNext: function() gFilePickerFiles[i++], getNext: function() gFilePickerFiles[i++],
hasMoreElements: function() gFilePickerFiles.length > i hasMoreElements: function() gFilePickerFiles.length > i
}; };
}, },
show: function() { show: function() {
return gFilePickerFiles.length == 0 ? return gFilePickerFiles.length == 0 ?
Components.interfaces.nsIFilePicker.returnCancel : Components.interfaces.nsIFilePicker.returnCancel :
Components.interfaces.nsIFilePicker.returnOK; Components.interfaces.nsIFilePicker.returnOK;
} }
}; };
// This listens for the next opened window and checks it is of the right url. // This listens for the next opened window and checks it is of the right url.
// opencallback is called when the new window is fully loaded // opencallback is called when the new window is fully loaded
// closecallback is called when the window is closed // closecallback is called when the window is closed
function WindowOpenListener(url, opencallback, closecallback) { function WindowOpenListener(url, opencallback, closecallback) {
this.url = url; this.url = url;
this.opencallback = opencallback; this.opencallback = opencallback;
this.closecallback = closecallback; this.closecallback = closecallback;
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator); .getService(Components.interfaces.nsIWindowMediator);
wm.addListener(this); wm.addListener(this);
} }
WindowOpenListener.prototype = { WindowOpenListener.prototype = {
url: null, url: null,
opencallback: null, opencallback: null,
closecallback: null, closecallback: null,
window: null, window: null,
domwindow: null, domwindow: null,
handleEvent: function(event) { handleEvent: function(event) {
is(this.domwindow.document.location.href, this.url, "Should have opened the correct window"); is(this.domwindow.document.location.href, this.url, "Should have opened the correct window");
this.domwindow.removeEventListener("load", this, false); this.domwindow.removeEventListener("load", this, false);
// Allow any other load handlers to execute // Allow any other load handlers to execute
var self = this; var self = this;
executeSoon(function() { self.opencallback(self.domwindow); } ); executeSoon(function() { self.opencallback(self.domwindow); } );
}, },
onWindowTitleChange: function(window, title) { onWindowTitleChange: function(window, title) {
}, },
onOpenWindow: function(window) { onOpenWindow: function(window) {
if (this.window) if (this.window)
return; return;
this.window = window; this.window = window;
this.domwindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) this.domwindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowInternal); .getInterface(Components.interfaces.nsIDOMWindowInternal);
this.domwindow.addEventListener("load", this, false); this.domwindow.addEventListener("load", this, false);
}, },
onCloseWindow: function(window) { onCloseWindow: function(window) {
if (this.window != window) if (this.window != window)
return; return;
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator); .getService(Components.interfaces.nsIWindowMediator);
wm.removeListener(this); wm.removeListener(this);
this.opencallback = null; this.opencallback = null;
this.window = null; this.window = null;
this.domwindow = null; this.domwindow = null;
// Let the window close complete // Let the window close complete
executeSoon(this.closecallback); executeSoon(this.closecallback);
this.closecallback = null; this.closecallback = null;
} }
}; };
function test_confirmation(aWindow, aExpectedURLs) { function test_confirmation(aWindow, aExpectedURLs) {
var list = aWindow.document.getElementById("itemList"); var list = aWindow.document.getElementById("itemList");
is(list.childNodes.length, aExpectedURLs.length, "Should be the right number of installs"); is(list.childNodes.length, aExpectedURLs.length, "Should be the right number of installs");
aExpectedURLs.forEach(function(aURL) { aExpectedURLs.forEach(function(aURL) {
var node = list.firstChild; var node = list.firstChild;
while (node) { while (node) {
if (node.url == aURL) { if (node.url == aURL) {
ok(true, "Should have seen " + aURL + " in the list"); ok(true, "Should have seen " + aURL + " in the list");
return; return;
} }
node = node.nextSibling; node = node.nextSibling;
} }
ok(false, "Should have seen " + aURL + " in the list"); ok(false, "Should have seen " + aURL + " in the list");
}); });
aWindow.document.documentElement.cancelDialog(); aWindow.document.documentElement.cancelDialog();
} }
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
gMockFilePickerFactoryCID = Components.ID("{4f595df2-9108-42c6-9910-0dc392a310c9}"); gMockFilePickerFactoryCID = Components.ID("{4f595df2-9108-42c6-9910-0dc392a310c9}");
gMockFilePickerFactory = XPCOMUtils._getFactory(MockFilePicker); gMockFilePickerFactory = XPCOMUtils._getFactory(MockFilePicker);
var compReg = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar); var compReg = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compReg.registerFactory(gMockFilePickerFactoryCID, compReg.registerFactory(gMockFilePickerFactoryCID,
"Mock FilePicker", "Mock FilePicker",
"@mozilla.org/filepicker;1", "@mozilla.org/filepicker;1",
gMockFilePickerFactory); gMockFilePickerFactory);
open_manager("addons://list/extension", function(aWindow) { open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow; gManagerWindow = aWindow;
run_next_test(); run_next_test();
}); });
} }
function end_test() { function end_test() {
var compReg = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar); var compReg = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compReg.unregisterFactory(gMockFilePickerFactoryCID, compReg.unregisterFactory(gMockFilePickerFactoryCID,
gMockFilePickerFactory); gMockFilePickerFactory);
close_manager(gManagerWindow, function() { close_manager(gManagerWindow, function() {
finish(); finish();
}); });
} }
add_test(function() { add_test(function() {
var filePaths = [ var filePaths = [
get_addon_file_url("browser_bug567127_1.xpi"), get_addon_file_url("browser_bug567127_1.xpi"),
get_addon_file_url("browser_bug567127_2.xpi") get_addon_file_url("browser_bug567127_2.xpi")
]; ];
gFilePickerFiles = filePaths.map(function(aPath) aPath.file); gFilePickerFiles = filePaths.map(function(aPath) aPath.file);
new WindowOpenListener(INSTALL_URI, function(aWindow) { new WindowOpenListener(INSTALL_URI, function(aWindow) {
test_confirmation(aWindow, filePaths.map(function(aPath) aPath.spec)); test_confirmation(aWindow, filePaths.map(function(aPath) aPath.spec));
}, run_next_test); }, run_next_test);
gManagerWindow.gViewController.doCommand("cmd_installFromFile"); gManagerWindow.gViewController.doCommand("cmd_installFromFile");
}); });

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

@ -1,129 +1,129 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Bug 581076 - No "See all results" link present when searching for add-ons and not all are displayed (extensions.getAddons.maxResults) // Bug 581076 - No "See all results" link present when searching for add-ons and not all are displayed (extensions.getAddons.maxResults)
const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL"; const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL";
const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url"; const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url";
const PREF_GETADDONS_MAXRESULTS = "extensions.getAddons.maxResults"; const PREF_GETADDONS_MAXRESULTS = "extensions.getAddons.maxResults";
const SEARCH_URL = TESTROOT + "browser_searching.xml"; const SEARCH_URL = TESTROOT + "browser_searching.xml";
const SEARCH_EXPECTED_TOTAL = 100; const SEARCH_EXPECTED_TOTAL = 100;
const SEARCH_QUERY = "search"; const SEARCH_QUERY = "search";
var gManagerWindow; var gManagerWindow;
function test() { function test() {
Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, SEARCH_URL); Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, SEARCH_URL);
Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15); Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
waitForExplicitFinish(); waitForExplicitFinish();
open_manager("addons://list/extension", function(aWindow) { open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow; gManagerWindow = aWindow;
run_next_test(); run_next_test();
}); });
} }
function end_test() { function end_test() {
Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS); Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS);
// Test generates a lot of available installs so just cancel them all // Test generates a lot of available installs so just cancel them all
AddonManager.getAllInstalls(function(aInstalls) { AddonManager.getAllInstalls(function(aInstalls) {
aInstalls.forEach(function(aInstall) { aInstalls.forEach(function(aInstall) {
aInstall.cancel(); aInstall.cancel();
}); });
close_manager(gManagerWindow, finish); close_manager(gManagerWindow, finish);
}); });
} }
function search(aRemoteSearch, aCallback) { function search(aRemoteSearch, aCallback) {
var searchBox = gManagerWindow.document.getElementById("header-search"); var searchBox = gManagerWindow.document.getElementById("header-search");
searchBox.value = SEARCH_QUERY; searchBox.value = SEARCH_QUERY;
EventUtils.synthesizeMouseAtCenter(searchBox, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(searchBox, { }, gManagerWindow);
EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow); EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow);
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
if (aRemoteSearch) if (aRemoteSearch)
var filter = gManagerWindow.document.getElementById("search-filter-remote"); var filter = gManagerWindow.document.getElementById("search-filter-remote");
else else
var filter = gManagerWindow.document.getElementById("search-filter-local"); var filter = gManagerWindow.document.getElementById("search-filter-local");
EventUtils.synthesizeMouseAtCenter(filter, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(filter, { }, gManagerWindow);
executeSoon(aCallback); executeSoon(aCallback);
}); });
} }
function check_allresultslink(aShouldShow) { function check_allresultslink(aShouldShow) {
var list = gManagerWindow.document.getElementById("search-list"); var list = gManagerWindow.document.getElementById("search-list");
var link = gManagerWindow.document.getElementById("search-allresults-link"); var link = gManagerWindow.document.getElementById("search-allresults-link");
is(link.parentNode, list.lastChild, "Footer should be at the end of the richlistbox"); is(link.parentNode, list.lastChild, "Footer should be at the end of the richlistbox");
if (aShouldShow) { if (aShouldShow) {
is_element_visible(link, "All Results link should be visible"); is_element_visible(link, "All Results link should be visible");
is(link.value, "See all " + SEARCH_EXPECTED_TOTAL + " results", "All Results link should show the correct message"); is(link.value, "See all " + SEARCH_EXPECTED_TOTAL + " results", "All Results link should show the correct message");
var scope = {}; var scope = {};
Components.utils.import("resource://gre/modules/AddonRepository.jsm", scope); Components.utils.import("resource://gre/modules/AddonRepository.jsm", scope);
is(link.href, scope.AddonRepository.getSearchURL(SEARCH_QUERY), "All Results link should have the correct href"); is(link.href, scope.AddonRepository.getSearchURL(SEARCH_QUERY), "All Results link should have the correct href");
} else { } else {
is_element_hidden(link, "All Results link should be hidden"); is_element_hidden(link, "All Results link should be hidden");
} }
} }
add_test(function() { add_test(function() {
info("Searching locally"); info("Searching locally");
search(false, function() { search(false, function() {
check_allresultslink(false); check_allresultslink(false);
restart_manager(gManagerWindow, null, function(aManager) { restart_manager(gManagerWindow, null, function(aManager) {
gManagerWindow = aManager; gManagerWindow = aManager;
run_next_test(); run_next_test();
}); });
}); });
}); });
add_test(function() { add_test(function() {
info("Searching remotely - more results than cap"); info("Searching remotely - more results than cap");
Services.prefs.setIntPref(PREF_GETADDONS_MAXRESULTS, 3); Services.prefs.setIntPref(PREF_GETADDONS_MAXRESULTS, 3);
search(true, function() { search(true, function() {
check_allresultslink(true); check_allresultslink(true);
restart_manager(gManagerWindow, null, function(aManager) { restart_manager(gManagerWindow, null, function(aManager) {
gManagerWindow = aManager; gManagerWindow = aManager;
run_next_test(); run_next_test();
}); });
}); });
}); });
add_test(function() { add_test(function() {
info("Searching remotely - less results than cap"); info("Searching remotely - less results than cap");
Services.prefs.setIntPref(PREF_GETADDONS_MAXRESULTS, 200); Services.prefs.setIntPref(PREF_GETADDONS_MAXRESULTS, 200);
search(true, function() { search(true, function() {
check_allresultslink(false); check_allresultslink(false);
restart_manager(gManagerWindow, null, function(aManager) { restart_manager(gManagerWindow, null, function(aManager) {
gManagerWindow = aManager; gManagerWindow = aManager;
run_next_test(); run_next_test();
}); });
}); });
}); });
add_test(function() { add_test(function() {
info("Searching remotely - more results than cap"); info("Searching remotely - more results than cap");
Services.prefs.setIntPref(PREF_GETADDONS_MAXRESULTS, 3); Services.prefs.setIntPref(PREF_GETADDONS_MAXRESULTS, 3);
search(true, function() { search(true, function() {
check_allresultslink(true); check_allresultslink(true);
run_next_test(); run_next_test();
}); });
}); });
add_test(function() { add_test(function() {
info("Switching views"); info("Switching views");
gManagerWindow.loadView("addons://list/extension"); gManagerWindow.loadView("addons://list/extension");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
info("Re-loading previous search"); info("Re-loading previous search");
search(true, function() { search(true, function() {
check_allresultslink(true); check_allresultslink(true);
run_next_test(); run_next_test();
}); });
}); });
}); });

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

@ -1,152 +1,152 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Bug 587970 - Provide ability "Update all now" within 'Available Updates' screen // Bug 587970 - Provide ability "Update all now" within 'Available Updates' screen
var gManagerWindow; var gManagerWindow;
var gProvider; var gProvider;
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
gProvider = new MockProvider(); gProvider = new MockProvider();
gProvider.createAddons([{ gProvider.createAddons([{
id: "addon1@tests.mozilla.org", id: "addon1@tests.mozilla.org",
name: "addon 1", name: "addon 1",
version: "1.0", version: "1.0",
applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE
}, { }, {
id: "addon2@tests.mozilla.org", id: "addon2@tests.mozilla.org",
name: "addon 2", name: "addon 2",
version: "2.0", version: "2.0",
applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE
}]); }]);
open_manager("addons://updates/available", function(aWindow) { open_manager("addons://updates/available", function(aWindow) {
gManagerWindow = aWindow; gManagerWindow = aWindow;
run_next_test(); run_next_test();
}); });
} }
function end_test() { function end_test() {
close_manager(gManagerWindow, finish); close_manager(gManagerWindow, finish);
} }
add_test(function() { add_test(function() {
var list = gManagerWindow.document.getElementById("updates-list"); var list = gManagerWindow.document.getElementById("updates-list");
is(list.childNodes.length, 0, "Available updates list should be empty"); is(list.childNodes.length, 0, "Available updates list should be empty");
var emptyNotice = gManagerWindow.document.getElementById("empty-availableUpdates-msg"); var emptyNotice = gManagerWindow.document.getElementById("empty-availableUpdates-msg");
is_element_visible(emptyNotice, "Empty notice should be visible"); is_element_visible(emptyNotice, "Empty notice should be visible");
var updateSelected = gManagerWindow.document.getElementById("update-selected-btn"); var updateSelected = gManagerWindow.document.getElementById("update-selected-btn");
is_element_hidden(updateSelected, "Update Selected button should be hidden"); is_element_hidden(updateSelected, "Update Selected button should be hidden");
info("Adding updates"); info("Adding updates");
gProvider.createInstalls([{ gProvider.createInstalls([{
name: "addon 1", name: "addon 1",
version: "1.1", version: "1.1",
existingAddon: gProvider.addons[0] existingAddon: gProvider.addons[0]
}, { }, {
name: "addon 2", name: "addon 2",
version: "2.1", version: "2.1",
existingAddon: gProvider.addons[1] existingAddon: gProvider.addons[1]
}]); }]);
function wait_for_refresh() { function wait_for_refresh() {
if (list.childNodes.length == 2 && if (list.childNodes.length == 2 &&
list.childNodes[0].mManualUpdate && list.childNodes[0].mManualUpdate &&
list.childNodes[1].mManualUpdate) { list.childNodes[1].mManualUpdate) {
run_next_test(); run_next_test();
} else { } else {
info("Waiting for pane to refresh"); info("Waiting for pane to refresh");
setTimeout(wait_for_refresh, 10); setTimeout(wait_for_refresh, 10);
} }
} }
info("Waiting for pane to refresh"); info("Waiting for pane to refresh");
setTimeout(wait_for_refresh, 10); setTimeout(wait_for_refresh, 10);
}); });
add_test(function() { add_test(function() {
var list = gManagerWindow.document.getElementById("updates-list"); var list = gManagerWindow.document.getElementById("updates-list");
is(list.childNodes.length, 2, "Available updates list should have 2 items"); is(list.childNodes.length, 2, "Available updates list should have 2 items");
var item1 = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org"); var item1 = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org");
isnot(item1, null, "Item for addon1@tests.mozilla.org should be in list"); isnot(item1, null, "Item for addon1@tests.mozilla.org should be in list");
var item2 = get_addon_element(gManagerWindow, "addon2@tests.mozilla.org"); var item2 = get_addon_element(gManagerWindow, "addon2@tests.mozilla.org");
isnot(item2, null, "Item for addon2@tests.mozilla.org should be in list"); isnot(item2, null, "Item for addon2@tests.mozilla.org should be in list");
var emptyNotice = gManagerWindow.document.getElementById("empty-availableUpdates-msg"); var emptyNotice = gManagerWindow.document.getElementById("empty-availableUpdates-msg");
is_element_hidden(emptyNotice, "Empty notice should be hidden"); is_element_hidden(emptyNotice, "Empty notice should be hidden");
var updateSelected = gManagerWindow.document.getElementById("update-selected-btn"); var updateSelected = gManagerWindow.document.getElementById("update-selected-btn");
is_element_visible(updateSelected, "Update Selected button should be visible"); is_element_visible(updateSelected, "Update Selected button should be visible");
is(updateSelected.disabled, false, "Update Selected button should be enabled by default"); is(updateSelected.disabled, false, "Update Selected button should be enabled by default");
is(item1._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon1"); is(item1._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon1");
is(item2._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon2"); is(item2._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon2");
info("Unchecking Include Update checkbox for addon1"); info("Unchecking Include Update checkbox for addon1");
EventUtils.synthesizeMouse(item1._includeUpdate, 2, 2, { }, gManagerWindow); EventUtils.synthesizeMouse(item1._includeUpdate, 2, 2, { }, gManagerWindow);
is(item1._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon1"); is(item1._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon1");
is(updateSelected.disabled, false, "Update Selected button should still be enabled"); is(updateSelected.disabled, false, "Update Selected button should still be enabled");
info("Unchecking Include Update checkbox for addon2"); info("Unchecking Include Update checkbox for addon2");
EventUtils.synthesizeMouse(item2._includeUpdate, 2, 2, { }, gManagerWindow); EventUtils.synthesizeMouse(item2._includeUpdate, 2, 2, { }, gManagerWindow);
is(item2._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon2"); is(item2._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon2");
is(updateSelected.disabled, true, "Update Selected button should now be disabled"); is(updateSelected.disabled, true, "Update Selected button should now be disabled");
info("Checking Include Update checkbox for addon2"); info("Checking Include Update checkbox for addon2");
EventUtils.synthesizeMouse(item2._includeUpdate, 2, 2, { }, gManagerWindow); EventUtils.synthesizeMouse(item2._includeUpdate, 2, 2, { }, gManagerWindow);
is(item2._includeUpdate.checked, true, "Include Update checkbox should now be be checked for addon2"); is(item2._includeUpdate.checked, true, "Include Update checkbox should now be be checked for addon2");
is(updateSelected.disabled, false, "Update Selected button should now be enabled"); is(updateSelected.disabled, false, "Update Selected button should now be enabled");
var listener = { var listener = {
onInstallEnded: function() { onInstallEnded: function() {
gProvider.installs[1].removeTestListener(listener); gProvider.installs[1].removeTestListener(listener);
is(gProvider.installs[0].state, AddonManager.STATE_AVAILABLE, "addon1 should not have been upgraded"); is(gProvider.installs[0].state, AddonManager.STATE_AVAILABLE, "addon1 should not have been upgraded");
is(gProvider.installs[1].state, AddonManager.STATE_INSTALLED, "addon2 should have been upgraded"); is(gProvider.installs[1].state, AddonManager.STATE_INSTALLED, "addon2 should have been upgraded");
} }
} }
gProvider.installs[1].addTestListener(listener); gProvider.installs[1].addTestListener(listener);
info("Clicking Update Selected button"); info("Clicking Update Selected button");
EventUtils.synthesizeMouse(updateSelected, 2, 2, { }, gManagerWindow); EventUtils.synthesizeMouse(updateSelected, 2, 2, { }, gManagerWindow);
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
function wait_for_refresh() { function wait_for_refresh() {
var item = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org"); var item = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org");
if (item.mManualUpdate) { if (item.mManualUpdate) {
run_next_test(); run_next_test();
} else { } else {
info("Waiting for pane to refresh"); info("Waiting for pane to refresh");
setTimeout(wait_for_refresh, 10); setTimeout(wait_for_refresh, 10);
} }
} }
info("Waiting for pane to refresh"); info("Waiting for pane to refresh");
setTimeout(wait_for_refresh, 10); setTimeout(wait_for_refresh, 10);
}, true); }, true);
}); });
add_test(function() { add_test(function() {
var updateSelected = gManagerWindow.document.getElementById("update-selected-btn"); var updateSelected = gManagerWindow.document.getElementById("update-selected-btn");
is(updateSelected.disabled, false, "Update Selected button should now be enabled"); is(updateSelected.disabled, false, "Update Selected button should now be enabled");
var item1 = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org"); var item1 = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org");
isnot(item1, null, "Item for addon1@tests.mozilla.org should be in list"); isnot(item1, null, "Item for addon1@tests.mozilla.org should be in list");
is(item1._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon1"); is(item1._includeUpdate.checked, true, "Include Update checkbox should be checked by default for addon1");
info("Unchecking Include Update checkbox for addon1"); info("Unchecking Include Update checkbox for addon1");
EventUtils.synthesizeMouse(item1._includeUpdate, 2, 2, { }, gManagerWindow); EventUtils.synthesizeMouse(item1._includeUpdate, 2, 2, { }, gManagerWindow);
is(item1._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon1"); is(item1._includeUpdate.checked, false, "Include Update checkbox should now be be unchecked for addon1");
is(updateSelected.disabled, true, "Update Selected button should now be disabled"); is(updateSelected.disabled, true, "Update Selected button should now be disabled");
run_next_test(); run_next_test();
}); });

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

@ -1,351 +1,351 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Bug 591465 - Context menu of add-ons miss context related state change entries // Bug 591465 - Context menu of add-ons miss context related state change entries
const PREF_GETADDONS_MAXRESULTS = "extensions.getAddons.maxResults"; const PREF_GETADDONS_MAXRESULTS = "extensions.getAddons.maxResults";
const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url"; const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url";
const SEARCH_URL = TESTROOT + "browser_bug591465.xml"; const SEARCH_URL = TESTROOT + "browser_bug591465.xml";
const SEARCH_QUERY = "SEARCH"; const SEARCH_QUERY = "SEARCH";
var gManagerWindow; var gManagerWindow;
var gProvider; var gProvider;
var gContextMenu; var gContextMenu;
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
gProvider = new MockProvider(); gProvider = new MockProvider();
gProvider.createAddons([{ gProvider.createAddons([{
id: "addon1@tests.mozilla.org", id: "addon1@tests.mozilla.org",
name: "addon 1", name: "addon 1",
version: "1.0" version: "1.0"
}, { }, {
id: "addon2@tests.mozilla.org", id: "addon2@tests.mozilla.org",
name: "addon 2", name: "addon 2",
version: "1.0", version: "1.0",
_userDisabled: true _userDisabled: true
}, { }, {
id: "theme1@tests.mozilla.org", id: "theme1@tests.mozilla.org",
name: "theme 1", name: "theme 1",
version: "1.0", version: "1.0",
type: "theme" type: "theme"
}, { }, {
id: "theme2@tests.mozilla.org", id: "theme2@tests.mozilla.org",
name: "theme 2", name: "theme 2",
version: "1.0", version: "1.0",
type: "theme", type: "theme",
_userDisabled: true _userDisabled: true
}, { }, {
id: "theme3@tests.mozilla.org", id: "theme3@tests.mozilla.org",
name: "theme 3", name: "theme 3",
version: "1.0", version: "1.0",
type: "theme", type: "theme",
permissions: 0 permissions: 0
}]); }]);
open_manager("addons://list/extension", function(aWindow) { open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow; gManagerWindow = aWindow;
gContextMenu = aWindow.document.getElementById("addonitem-popup"); gContextMenu = aWindow.document.getElementById("addonitem-popup");
run_next_test(); run_next_test();
}); });
} }
function end_test() { function end_test() {
Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS); Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS);
close_manager(gManagerWindow, finish); close_manager(gManagerWindow, finish);
} }
function check_contextmenu(aIsTheme, aIsEnabled, aIsRemote, aIsDetails, aIsSingleItemCase) { function check_contextmenu(aIsTheme, aIsEnabled, aIsRemote, aIsDetails, aIsSingleItemCase) {
if (aIsTheme || aIsEnabled || aIsRemote) if (aIsTheme || aIsEnabled || aIsRemote)
is_element_hidden(gManagerWindow.document.getElementById("menuitem_enableItem"), is_element_hidden(gManagerWindow.document.getElementById("menuitem_enableItem"),
"'Enable' should be hidden"); "'Enable' should be hidden");
else else
is_element_visible(gManagerWindow.document.getElementById("menuitem_enableItem"), is_element_visible(gManagerWindow.document.getElementById("menuitem_enableItem"),
"'Enable' should be visible"); "'Enable' should be visible");
if (aIsTheme || !aIsEnabled || aIsRemote) if (aIsTheme || !aIsEnabled || aIsRemote)
is_element_hidden(gManagerWindow.document.getElementById("menuitem_disableItem"), is_element_hidden(gManagerWindow.document.getElementById("menuitem_disableItem"),
"'Disable' should be hidden"); "'Disable' should be hidden");
else else
is_element_visible(gManagerWindow.document.getElementById("menuitem_disableItem"), is_element_visible(gManagerWindow.document.getElementById("menuitem_disableItem"),
"'Disable' should be visible"); "'Disable' should be visible");
if (!aIsTheme || aIsEnabled || aIsRemote || aIsSingleItemCase) if (!aIsTheme || aIsEnabled || aIsRemote || aIsSingleItemCase)
is_element_hidden(gManagerWindow.document.getElementById("menuitem_enableTheme"), is_element_hidden(gManagerWindow.document.getElementById("menuitem_enableTheme"),
"'Wear Theme' should be hidden"); "'Wear Theme' should be hidden");
else else
is_element_visible(gManagerWindow.document.getElementById("menuitem_enableTheme"), is_element_visible(gManagerWindow.document.getElementById("menuitem_enableTheme"),
"'Wear Theme' should be visible"); "'Wear Theme' should be visible");
if (!aIsTheme || !aIsEnabled || aIsRemote || aIsSingleItemCase) if (!aIsTheme || !aIsEnabled || aIsRemote || aIsSingleItemCase)
is_element_hidden(gManagerWindow.document.getElementById("menuitem_disableTheme"), is_element_hidden(gManagerWindow.document.getElementById("menuitem_disableTheme"),
"'Stop Wearing Theme' should be hidden"); "'Stop Wearing Theme' should be hidden");
else else
is_element_visible(gManagerWindow.document.getElementById("menuitem_disableTheme"), is_element_visible(gManagerWindow.document.getElementById("menuitem_disableTheme"),
"'Stop Wearing Theme' should be visible"); "'Stop Wearing Theme' should be visible");
if (aIsRemote) if (aIsRemote)
is_element_visible(gManagerWindow.document.getElementById("menuitem_installItem"), is_element_visible(gManagerWindow.document.getElementById("menuitem_installItem"),
"'Install' should be visible"); "'Install' should be visible");
else else
is_element_hidden(gManagerWindow.document.getElementById("menuitem_installItem"), is_element_hidden(gManagerWindow.document.getElementById("menuitem_installItem"),
"'Install' should be hidden"); "'Install' should be hidden");
if (aIsDetails) if (aIsDetails)
is_element_hidden(gManagerWindow.document.getElementById("menuitem_showDetails"), is_element_hidden(gManagerWindow.document.getElementById("menuitem_showDetails"),
"'Show More Information' should be hidden in details view"); "'Show More Information' should be hidden in details view");
else else
is_element_visible(gManagerWindow.document.getElementById("menuitem_showDetails"), is_element_visible(gManagerWindow.document.getElementById("menuitem_showDetails"),
"'Show More Information' should be visible in list view"); "'Show More Information' should be visible in list view");
if (aIsSingleItemCase) if (aIsSingleItemCase)
is_element_hidden(gManagerWindow.document.getElementById("addonitem-menuseparator"), is_element_hidden(gManagerWindow.document.getElementById("addonitem-menuseparator"),
"Menu separator should be hidden with only one menu item"); "Menu separator should be hidden with only one menu item");
else else
is_element_visible(gManagerWindow.document.getElementById("addonitem-menuseparator"), is_element_visible(gManagerWindow.document.getElementById("addonitem-menuseparator"),
"Menu separator should be visible with multiple menu items"); "Menu separator should be visible with multiple menu items");
} }
add_test(function() { add_test(function() {
var el = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org"); var el = get_addon_element(gManagerWindow, "addon1@tests.mozilla.org");
isnot(el, null, "Should have found addon element"); isnot(el, null, "Should have found addon element");
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(false, true, false, false, false); check_contextmenu(false, true, false, false, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on enabled extension item"); info("Opening context menu on enabled extension item");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
add_test(function() { add_test(function() {
var el = get_addon_element(gManagerWindow, "addon2@tests.mozilla.org"); var el = get_addon_element(gManagerWindow, "addon2@tests.mozilla.org");
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(false, false, false, false, false); check_contextmenu(false, false, false, false, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on disabled extension item"); info("Opening context menu on disabled extension item");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
add_test(function() { add_test(function() {
gManagerWindow.loadView("addons://list/theme"); gManagerWindow.loadView("addons://list/theme");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
var el = get_addon_element(gManagerWindow, "theme1@tests.mozilla.org"); var el = get_addon_element(gManagerWindow, "theme1@tests.mozilla.org");
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(true, true, false, false, false); check_contextmenu(true, true, false, false, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on enabled theme item"); info("Opening context menu on enabled theme item");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });
add_test(function() { add_test(function() {
var el = get_addon_element(gManagerWindow, "theme2@tests.mozilla.org"); var el = get_addon_element(gManagerWindow, "theme2@tests.mozilla.org");
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(true, false, false, false, false); check_contextmenu(true, false, false, false, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on disabled theme item"); info("Opening context menu on disabled theme item");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
add_test(function() { add_test(function() {
gManagerWindow.loadView("addons://detail/addon1@tests.mozilla.org"); gManagerWindow.loadView("addons://detail/addon1@tests.mozilla.org");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(false, true, false, true, false); check_contextmenu(false, true, false, true, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on enabled extension, in detail view"); info("Opening context menu on enabled extension, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container"); var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });
add_test(function() { add_test(function() {
gManagerWindow.loadView("addons://detail/addon2@tests.mozilla.org"); gManagerWindow.loadView("addons://detail/addon2@tests.mozilla.org");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(false, false, false, true, false); check_contextmenu(false, false, false, true, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on disabled extension, in detail view"); info("Opening context menu on disabled extension, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container"); var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });
add_test(function() { add_test(function() {
gManagerWindow.loadView("addons://detail/theme1@tests.mozilla.org"); gManagerWindow.loadView("addons://detail/theme1@tests.mozilla.org");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(true, true, false, true, false); check_contextmenu(true, true, false, true, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on enabled theme, in detail view"); info("Opening context menu on enabled theme, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container"); var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });
add_test(function() { add_test(function() {
gManagerWindow.loadView("addons://detail/theme2@tests.mozilla.org"); gManagerWindow.loadView("addons://detail/theme2@tests.mozilla.org");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(true, false, false, true, false); check_contextmenu(true, false, false, true, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on disabled theme, in detail view"); info("Opening context menu on disabled theme, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container"); var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });
add_test(function() { add_test(function() {
gManagerWindow.loadView("addons://detail/theme3@tests.mozilla.org"); gManagerWindow.loadView("addons://detail/theme3@tests.mozilla.org");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(true, true, false, true, true); check_contextmenu(true, true, false, true, true);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu with single menu item on enabled theme, in detail view"); info("Opening context menu with single menu item on enabled theme, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container"); var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });
add_test(function() { add_test(function() {
info("Searching for remote addons"); info("Searching for remote addons");
Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, SEARCH_URL); Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, SEARCH_URL);
Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15); Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
var searchBox = gManagerWindow.document.getElementById("header-search"); var searchBox = gManagerWindow.document.getElementById("header-search");
searchBox.value = SEARCH_QUERY; searchBox.value = SEARCH_QUERY;
EventUtils.synthesizeMouseAtCenter(searchBox, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(searchBox, { }, gManagerWindow);
EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow); EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow);
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
var filter = gManagerWindow.document.getElementById("search-filter-remote"); var filter = gManagerWindow.document.getElementById("search-filter-remote");
EventUtils.synthesizeMouseAtCenter(filter, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(filter, { }, gManagerWindow);
executeSoon(function() { executeSoon(function() {
var el = get_addon_element(gManagerWindow, "remote1@tests.mozilla.org"); var el = get_addon_element(gManagerWindow, "remote1@tests.mozilla.org");
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(false, false, true, false, false); check_contextmenu(false, false, true, false, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on remote extension item"); info("Opening context menu on remote extension item");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });
}); });
add_test(function() { add_test(function() {
gManagerWindow.loadView("addons://detail/remote1@tests.mozilla.org"); gManagerWindow.loadView("addons://detail/remote1@tests.mozilla.org");
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
gContextMenu.addEventListener("popupshown", function() { gContextMenu.addEventListener("popupshown", function() {
gContextMenu.removeEventListener("popupshown", arguments.callee, false); gContextMenu.removeEventListener("popupshown", arguments.callee, false);
check_contextmenu(false, false, true, true, false); check_contextmenu(false, false, true, true, false);
gContextMenu.hidePopup(); gContextMenu.hidePopup();
run_next_test(); run_next_test();
}, false); }, false);
info("Opening context menu on remote extension, in detail view"); info("Opening context menu on remote extension, in detail view");
var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container"); var el = gManagerWindow.document.querySelector("#detail-view .detail-view-container");
EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { }, gManagerWindow);
EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow); EventUtils.synthesizeMouse(el, 4, 4, { type: "contextmenu", button: 2 }, gManagerWindow);
}); });
}); });

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

@ -10,6 +10,7 @@ const SEARCH_URL = TESTROOT + "browser_details.xml";
var gManagerWindow; var gManagerWindow;
var gCategoryUtilities; var gCategoryUtilities;
var gProvider;
var gApp = document.getElementById("bundle_brand").getString("brandShortName"); var gApp = document.getElementById("bundle_brand").getString("brandShortName");
var gVersion = Services.appinfo.version; var gVersion = Services.appinfo.version;

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

@ -1,65 +1,65 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Bug 566194 - safe mode / security & compatibility check status are not exposed in new addon manager UI // Bug 566194 - safe mode / security & compatibility check status are not exposed in new addon manager UI
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
run_next_test(); run_next_test();
} }
function end_test() { function end_test() {
finish(); finish();
} }
add_test(function() { add_test(function() {
info("Testing compatibility checking warning"); info("Testing compatibility checking warning");
var version = Services.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/gi, "$1"); var version = Services.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/gi, "$1");
var pref = "extensions.checkCompatibility." + version; var pref = "extensions.checkCompatibility." + version;
info("Setting " + pref + " pref to false") info("Setting " + pref + " pref to false")
Services.prefs.setBoolPref(pref, false); Services.prefs.setBoolPref(pref, false);
open_manager("addons://list/extension", function(aWindow) { open_manager("addons://list/extension", function(aWindow) {
var label = aWindow.document.querySelector("#list-view label.global-warning-checkcompatibility"); var label = aWindow.document.querySelector("#list-view label.global-warning-checkcompatibility");
is_element_visible(label, "Check Compatibility warning label should be visible"); is_element_visible(label, "Check Compatibility warning label should be visible");
var button = aWindow.document.querySelector("#list-view button.global-warning-checkcompatibility"); var button = aWindow.document.querySelector("#list-view button.global-warning-checkcompatibility");
is_element_visible(button, "Check Compatibility warning button should be visible"); is_element_visible(button, "Check Compatibility warning button should be visible");
info("Clicking 'Enable' button"); info("Clicking 'Enable' button");
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow); EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
is(Services.prefs.prefHasUserValue(pref), false, "Check Compatability pref should be cleared"); is(Services.prefs.prefHasUserValue(pref), false, "Check Compatability pref should be cleared");
is_element_hidden(label, "Check Compatibility warning label should be hidden"); is_element_hidden(label, "Check Compatibility warning label should be hidden");
is_element_hidden(button, "Check Compatibility warning button should be hidden"); is_element_hidden(button, "Check Compatibility warning button should be hidden");
close_manager(aWindow, function() { close_manager(aWindow, function() {
run_next_test(); run_next_test();
}); });
}); });
}); });
add_test(function() { add_test(function() {
info("Testing update security checking warning"); info("Testing update security checking warning");
var pref = "extensions.checkUpdateSecurity"; var pref = "extensions.checkUpdateSecurity";
info("Setting " + pref + " pref to false") info("Setting " + pref + " pref to false")
Services.prefs.setBoolPref(pref, false); Services.prefs.setBoolPref(pref, false);
open_manager(null, function(aWindow) { open_manager(null, function(aWindow) {
var label = aWindow.document.querySelector("#list-view label.global-warning-updatesecurity"); var label = aWindow.document.querySelector("#list-view label.global-warning-updatesecurity");
is_element_visible(label, "Check Update Security warning label should be visible"); is_element_visible(label, "Check Update Security warning label should be visible");
var button = aWindow.document.querySelector("#list-view button.global-warning-updatesecurity"); var button = aWindow.document.querySelector("#list-view button.global-warning-updatesecurity");
is_element_visible(button, "Check Update Security warning button should be visible"); is_element_visible(button, "Check Update Security warning button should be visible");
info("Clicking 'Enable' button"); info("Clicking 'Enable' button");
EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow); EventUtils.synthesizeMouse(button, 2, 2, { }, aWindow);
is(Services.prefs.prefHasUserValue(pref), false, "Check Update Security pref should be cleared"); is(Services.prefs.prefHasUserValue(pref), false, "Check Update Security pref should be cleared");
is_element_hidden(label, "Check Update Security warning label should be hidden"); is_element_hidden(label, "Check Update Security warning label should be hidden");
is_element_hidden(button, "Check Update Security warning button should be hidden"); is_element_hidden(button, "Check Update Security warning button should be hidden");
close_manager(aWindow, function() { close_manager(aWindow, function() {
run_next_test(); run_next_test();
}); });
}); });
}); });

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

@ -1,188 +1,188 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Tests manual updates, including the Available Updates pane // Tests manual updates, including the Available Updates pane
var gProvider; var gProvider;
var gManagerWindow; var gManagerWindow;
var gCategoryUtilities; var gCategoryUtilities;
var gAvailableCategory; var gAvailableCategory;
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
gProvider = new MockProvider(); gProvider = new MockProvider();
gProvider.createAddons([{ gProvider.createAddons([{
id: "addon1@tests.mozilla.org", id: "addon1@tests.mozilla.org",
name: "auto updating addon", name: "auto updating addon",
version: "1.0", version: "1.0",
applyBackgroundUpdates: AddonManager.AUTOUPDATE_ENABLE applyBackgroundUpdates: AddonManager.AUTOUPDATE_ENABLE
}]); }]);
open_manager("addons://list/extension", function(aWindow) { open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow; gManagerWindow = aWindow;
gCategoryUtilities = new CategoryUtilities(gManagerWindow); gCategoryUtilities = new CategoryUtilities(gManagerWindow);
run_next_test(); run_next_test();
}); });
} }
function end_test() { function end_test() {
close_manager(gManagerWindow, function() { close_manager(gManagerWindow, function() {
finish(); finish();
}); });
} }
add_test(function() { add_test(function() {
gAvailableCategory = gManagerWindow.gCategories.get("addons://updates/available"); gAvailableCategory = gManagerWindow.gCategories.get("addons://updates/available");
is(gCategoryUtilities.isVisible(gAvailableCategory), false, "Available Updates category should initially be hidden"); is(gCategoryUtilities.isVisible(gAvailableCategory), false, "Available Updates category should initially be hidden");
gProvider.createAddons([{ gProvider.createAddons([{
id: "addon2@tests.mozilla.org", id: "addon2@tests.mozilla.org",
name: "manually updating addon", name: "manually updating addon",
version: "1.0", version: "1.0",
isCompatible: false, isCompatible: false,
blocklistState: Ci.nsIBlocklistService.STATE_BLOCKED, blocklistState: Ci.nsIBlocklistService.STATE_BLOCKED,
applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE
}]); }]);
is(gCategoryUtilities.isVisible(gAvailableCategory), true, "Available Updates category should now be visible"); is(gCategoryUtilities.isVisible(gAvailableCategory), true, "Available Updates category should now be visible");
gAvailableCategory.addEventListener("CategoryVisible", function() { gAvailableCategory.addEventListener("CategoryVisible", function() {
gAvailableCategory.removeEventListener("CategoryVisible", arguments.callee, false); gAvailableCategory.removeEventListener("CategoryVisible", arguments.callee, false);
is(gCategoryUtilities.isVisible(gAvailableCategory), false, "Available Updates category should not be visible"); is(gCategoryUtilities.isVisible(gAvailableCategory), false, "Available Updates category should not be visible");
gAvailableCategory.addEventListener("CategoryVisible", function() { gAvailableCategory.addEventListener("CategoryVisible", function() {
gAvailableCategory.removeEventListener("CategoryVisible", arguments.callee, false); gAvailableCategory.removeEventListener("CategoryVisible", arguments.callee, false);
is(gCategoryUtilities.isVisible(gAvailableCategory), true, "Available Updates category should be visible"); is(gCategoryUtilities.isVisible(gAvailableCategory), true, "Available Updates category should be visible");
run_next_test(); run_next_test();
}, false); }, false);
gProvider.addons[1].applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE; gProvider.addons[1].applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
}, false); }, false);
gProvider.addons[1].applyBackgroundUpdates = AddonManager.AUTOUPDATE_ENABLE; gProvider.addons[1].applyBackgroundUpdates = AddonManager.AUTOUPDATE_ENABLE;
}); });
add_test(function() { add_test(function() {
gAvailableCategory.addEventListener("CategoryBadgeUpdated", function() { gAvailableCategory.addEventListener("CategoryBadgeUpdated", function() {
gAvailableCategory.removeEventListener("CategoryBadgeUpdated", arguments.callee, false); gAvailableCategory.removeEventListener("CategoryBadgeUpdated", arguments.callee, false);
is(gAvailableCategory.badgeCount, 1, "Badge for Available Updates should now be 1"); is(gAvailableCategory.badgeCount, 1, "Badge for Available Updates should now be 1");
run_next_test(); run_next_test();
}, false); }, false);
gCategoryUtilities.openType("extension", function() { gCategoryUtilities.openType("extension", function() {
gProvider.createInstalls([{ gProvider.createInstalls([{
name: "manually updating addon (new and improved!)", name: "manually updating addon (new and improved!)",
existingAddon: gProvider.addons[1], existingAddon: gProvider.addons[1],
version: "1.1", version: "1.1",
releaseNotesURI: Services.io.newURI(TESTROOT + "thereIsNoFileHere.xhtml", null, null) releaseNotesURI: Services.io.newURI(TESTROOT + "thereIsNoFileHere.xhtml", null, null)
}]); }]);
var item = get_addon_element(gManagerWindow, "addon2@tests.mozilla.org"); var item = get_addon_element(gManagerWindow, "addon2@tests.mozilla.org");
is(item._version.value, "1.0", "Should still show the old version in the normal list"); is(item._version.value, "1.0", "Should still show the old version in the normal list");
}); });
}); });
add_test(function() { add_test(function() {
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
is(gManagerWindow.document.getElementById("categories").selectedItem.value, "addons://updates/available", "Available Updates category should now be selected"); is(gManagerWindow.document.getElementById("categories").selectedItem.value, "addons://updates/available", "Available Updates category should now be selected");
is(gManagerWindow.gViewController.currentViewId, "addons://updates/available", "Available Updates view should be the current view"); is(gManagerWindow.gViewController.currentViewId, "addons://updates/available", "Available Updates view should be the current view");
run_next_test(); run_next_test();
}, true); }, true);
EventUtils.synthesizeMouseAtCenter(gAvailableCategory, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(gAvailableCategory, { }, gManagerWindow);
}); });
add_test(function() { add_test(function() {
var list = gManagerWindow.document.getElementById("updates-list"); var list = gManagerWindow.document.getElementById("updates-list");
is(list.itemCount, 1, "Should be 1 available update listed"); is(list.itemCount, 1, "Should be 1 available update listed");
var item = list.firstChild; var item = list.firstChild;
is(item.mAddon.id, "addon2@tests.mozilla.org", "Update item should be for the manually updating addon"); is(item.mAddon.id, "addon2@tests.mozilla.org", "Update item should be for the manually updating addon");
// for manual update items, update-related properties are updated asynchronously, // for manual update items, update-related properties are updated asynchronously,
// so we poll for one of the expected changes to know when its done // so we poll for one of the expected changes to know when its done
function waitForAsyncInit() { function waitForAsyncInit() {
if (item._version.value == "1.1") { if (item._version.value == "1.1") {
run_next_test(); run_next_test();
return; return;
} }
info("Update item not initialized yet, checking again in 100ms"); info("Update item not initialized yet, checking again in 100ms");
setTimeout(waitForAsyncInit, 100); setTimeout(waitForAsyncInit, 100);
} }
waitForAsyncInit(); waitForAsyncInit();
}); });
add_test(function() { add_test(function() {
var list = gManagerWindow.document.getElementById("updates-list"); var list = gManagerWindow.document.getElementById("updates-list");
var item = list.firstChild; var item = list.firstChild;
is(item._version.value, "1.1", "Update item should have version number of the update"); is(item._version.value, "1.1", "Update item should have version number of the update");
var postfix = gManagerWindow.document.getAnonymousElementByAttribute(item, "class", "update-postfix"); var postfix = gManagerWindow.document.getAnonymousElementByAttribute(item, "class", "update-postfix");
is_element_visible(postfix, "'Update' postfix should be visible"); is_element_visible(postfix, "'Update' postfix should be visible");
is_element_visible(item._updateAvailable, ""); is_element_visible(item._updateAvailable, "");
is_element_visible(item._relNotesToggle, "Release notes toggle should be visible"); is_element_visible(item._relNotesToggle, "Release notes toggle should be visible");
is_element_hidden(item._warning, "Incompatible warning should be hidden"); is_element_hidden(item._warning, "Incompatible warning should be hidden");
is_element_hidden(item._error, "Blocklist error should be hidden"); is_element_hidden(item._error, "Blocklist error should be hidden");
info("Opening release notes"); info("Opening release notes");
item.addEventListener("RelNotesToggle", function() { item.addEventListener("RelNotesToggle", function() {
item.removeEventListener("RelNotesToggle", arguments.callee, false); item.removeEventListener("RelNotesToggle", arguments.callee, false);
info("Release notes now open"); info("Release notes now open");
is_element_hidden(item._relNotesLoading, "Release notes loading message should be hidden"); is_element_hidden(item._relNotesLoading, "Release notes loading message should be hidden");
is_element_visible(item._relNotesError, "Release notes error message should be visible"); is_element_visible(item._relNotesError, "Release notes error message should be visible");
is(item._relNotes.childElementCount, 0, "Release notes should be empty"); is(item._relNotes.childElementCount, 0, "Release notes should be empty");
info("Closing release notes"); info("Closing release notes");
item.addEventListener("RelNotesToggle", function() { item.addEventListener("RelNotesToggle", function() {
item.removeEventListener("RelNotesToggle", arguments.callee, false); item.removeEventListener("RelNotesToggle", arguments.callee, false);
info("Release notes now closed"); info("Release notes now closed");
info("Setting Release notes URI to something that should load"); info("Setting Release notes URI to something that should load");
gProvider.installs[0].releaseNotesURI = Services.io.newURI(TESTROOT + "releaseNotes.xhtml", null, null) gProvider.installs[0].releaseNotesURI = Services.io.newURI(TESTROOT + "releaseNotes.xhtml", null, null)
info("Re-opening release notes"); info("Re-opening release notes");
item.addEventListener("RelNotesToggle", function() { item.addEventListener("RelNotesToggle", function() {
item.removeEventListener("RelNotesToggle", arguments.callee, false); item.removeEventListener("RelNotesToggle", arguments.callee, false);
info("Release notes now open"); info("Release notes now open");
is_element_hidden(item._relNotesLoading, "Release notes loading message should be hidden"); is_element_hidden(item._relNotesLoading, "Release notes loading message should be hidden");
is_element_hidden(item._relNotesError, "Release notes error message should be hidden"); is_element_hidden(item._relNotesError, "Release notes error message should be hidden");
isnot(item._relNotes.childElementCount, 0, "Release notes should have been inserted into container"); isnot(item._relNotes.childElementCount, 0, "Release notes should have been inserted into container");
run_next_test(); run_next_test();
}, false); }, false);
EventUtils.synthesizeMouseAtCenter(item._relNotesToggle, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(item._relNotesToggle, { }, gManagerWindow);
is_element_visible(item._relNotesLoading, "Release notes loading message should be visible"); is_element_visible(item._relNotesLoading, "Release notes loading message should be visible");
}, false); }, false);
EventUtils.synthesizeMouseAtCenter(item._relNotesToggle, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(item._relNotesToggle, { }, gManagerWindow);
}, false); }, false);
EventUtils.synthesizeMouseAtCenter(item._relNotesToggle, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(item._relNotesToggle, { }, gManagerWindow);
is_element_visible(item._relNotesLoading, "Release notes loading message should be visible"); is_element_visible(item._relNotesLoading, "Release notes loading message should be visible");
}); });
add_test(function() { add_test(function() {
var list = gManagerWindow.document.getElementById("updates-list"); var list = gManagerWindow.document.getElementById("updates-list");
var item = list.firstChild; var item = list.firstChild;
var updateBtn = item._updateBtn; var updateBtn = item._updateBtn;
is_element_visible(updateBtn, "Update button should be visible"); is_element_visible(updateBtn, "Update button should be visible");
var install = gProvider.installs[0]; var install = gProvider.installs[0];
var listener = { var listener = {
onInstallStarted: function() { onInstallStarted: function() {
info("Install started"); info("Install started");
is_element_visible(item._installStatus, "Install progress widget should be visible"); is_element_visible(item._installStatus, "Install progress widget should be visible");
}, },
onInstallEnded: function() { onInstallEnded: function() {
install.removeTestListener(this); install.removeTestListener(this);
info("install ended"); info("install ended");
is_element_hidden(item._installStatus, "Install progress widget should be hidden"); is_element_hidden(item._installStatus, "Install progress widget should be hidden");
run_next_test(); run_next_test();
} }
}; };
install.addTestListener(listener); install.addTestListener(listener);
EventUtils.synthesizeMouseAtCenter(updateBtn, { }, gManagerWindow); EventUtils.synthesizeMouseAtCenter(updateBtn, { }, gManagerWindow);
}); });

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

@ -1,86 +1,86 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ * http://creativecommons.org/publicdomain/zero/1.0/
*/ */
// Tests the recent updates pane // Tests the recent updates pane
var gProvider; var gProvider;
var gManagerWindow; var gManagerWindow;
var gCategoryUtilities; var gCategoryUtilities;
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
gProvider = new MockProvider(); gProvider = new MockProvider();
gProvider.createAddons([{ gProvider.createAddons([{
id: "addon1@tests.mozilla.org", id: "addon1@tests.mozilla.org",
name: "updated 6 hours ago", name: "updated 6 hours ago",
version: "1.0", version: "1.0",
updateDate: new Date(Date.now() - (1000 * 60 * 60 * 6)), updateDate: new Date(Date.now() - (1000 * 60 * 60 * 6)),
releaseNotesURI: Services.io.newURI(TESTROOT + "releaseNotes.xhtml", null, null) releaseNotesURI: Services.io.newURI(TESTROOT + "releaseNotes.xhtml", null, null)
}, { }, {
id: "addon2@tests.mozilla.org", id: "addon2@tests.mozilla.org",
name: "updated 5 seconds ago", name: "updated 5 seconds ago",
version: "1.0", version: "1.0",
updateDate: new Date(Date.now() - (1000 * 5)) updateDate: new Date(Date.now() - (1000 * 5))
}, { }, {
id: "addon3@tests.mozilla.org", id: "addon3@tests.mozilla.org",
name: "updated 1 month ago", name: "updated 1 month ago",
version: "1.0", version: "1.0",
updateDate: new Date(Date.now() - (1000 * 60 * 60 * 25 * 30)) updateDate: new Date(Date.now() - (1000 * 60 * 60 * 25 * 30))
}]); }]);
open_manager("addons://list/extension", function(aWindow) { open_manager("addons://list/extension", function(aWindow) {
gManagerWindow = aWindow; gManagerWindow = aWindow;
gCategoryUtilities = new CategoryUtilities(gManagerWindow); gCategoryUtilities = new CategoryUtilities(gManagerWindow);
run_next_test(); run_next_test();
}); });
} }
function end_test() { function end_test() {
close_manager(gManagerWindow, function() { close_manager(gManagerWindow, function() {
finish(); finish();
}); });
} }
add_test(function() { add_test(function() {
info("Checking menuitem for Recent Updates opens that pane"); info("Checking menuitem for Recent Updates opens that pane");
var recentCat = gManagerWindow.gCategories.get("addons://updates/recent"); var recentCat = gManagerWindow.gCategories.get("addons://updates/recent");
is(gCategoryUtilities.isVisible(recentCat), false, "Recent Updates category should initially be hidden"); is(gCategoryUtilities.isVisible(recentCat), false, "Recent Updates category should initially be hidden");
var utilsBtn = gManagerWindow.document.getElementById("header-utils-btn"); var utilsBtn = gManagerWindow.document.getElementById("header-utils-btn");
utilsBtn.addEventListener("popupshown", function() { utilsBtn.addEventListener("popupshown", function() {
wait_for_view_load(gManagerWindow, function() { wait_for_view_load(gManagerWindow, function() {
is(gCategoryUtilities.isVisible(recentCat), true, "Recent Updates category should now be visible"); is(gCategoryUtilities.isVisible(recentCat), true, "Recent Updates category should now be visible");
is(gManagerWindow.document.getElementById("categories").selectedItem.value, "addons://updates/recent", "Recent Updates category should now be selected"); is(gManagerWindow.document.getElementById("categories").selectedItem.value, "addons://updates/recent", "Recent Updates category should now be selected");
is(gManagerWindow.gViewController.currentViewId, "addons://updates/recent", "Recent Updates view should be the current view"); is(gManagerWindow.gViewController.currentViewId, "addons://updates/recent", "Recent Updates view should be the current view");
run_next_test(); run_next_test();
}, true); }, true);
var menuitem = gManagerWindow.document.getElementById("utils-viewUpdates"); var menuitem = gManagerWindow.document.getElementById("utils-viewUpdates");
EventUtils.synthesizeMouse(menuitem, 2, 2, { }, gManagerWindow); EventUtils.synthesizeMouse(menuitem, 2, 2, { }, gManagerWindow);
}, false); }, false);
EventUtils.synthesizeMouse(utilsBtn, 2, 2, { }, gManagerWindow); EventUtils.synthesizeMouse(utilsBtn, 2, 2, { }, gManagerWindow);
}); });
add_test(function() { add_test(function() {
var updatesList = gManagerWindow.document.getElementById("updates-list"); var updatesList = gManagerWindow.document.getElementById("updates-list");
var items = updatesList.getElementsByTagName("richlistitem"); var items = updatesList.getElementsByTagName("richlistitem");
var possible = ["addon1@tests.mozilla.org", "addon2@tests.mozilla.org", "addon2@tests.mozilla.org"]; var possible = ["addon1@tests.mozilla.org", "addon2@tests.mozilla.org", "addon2@tests.mozilla.org"];
var expected = ["addon2@tests.mozilla.org", "addon1@tests.mozilla.org"]; var expected = ["addon2@tests.mozilla.org", "addon1@tests.mozilla.org"];
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
let item = items[i]; let item = items[i];
let itemId = item.mAddon.id; let itemId = item.mAddon.id;
if (possible.indexOf(itemId) == -1) if (possible.indexOf(itemId) == -1)
continue; // skip over any other addons, such as shipped addons that would update on every build continue; // skip over any other addons, such as shipped addons that would update on every build
isnot(expected.length, 0, "Should be expecting more items"); isnot(expected.length, 0, "Should be expecting more items");
is(itemId, expected.shift(), "Should get expected item based on recenty of update"); is(itemId, expected.shift(), "Should get expected item based on recenty of update");
if (itemId == "addon1@tests.mozilla.org") if (itemId == "addon1@tests.mozilla.org")
is_element_visible(item._relNotesToggle, "Release notes toggle should be visible for addon with release notes"); is_element_visible(item._relNotesToggle, "Release notes toggle should be visible for addon with release notes");
else else
is_element_hidden(item._relNotesToggle, "Release notes toggle should be hidden for addon with no release notes"); is_element_hidden(item._relNotesToggle, "Release notes toggle should be hidden for addon with no release notes");
} }
run_next_test(); run_next_test();
}); });

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

@ -393,8 +393,8 @@ CertOverrideListener.prototype = {
}, },
notifyCertProblem: function (socketInfo, sslStatus, targetHost) { notifyCertProblem: function (socketInfo, sslStatus, targetHost) {
cert = sslStatus.QueryInterface(Components.interfaces.nsISSLStatus) var cert = sslStatus.QueryInterface(Components.interfaces.nsISSLStatus)
.serverCert; .serverCert;
var cos = Cc["@mozilla.org/security/certoverride;1"]. var cos = Cc["@mozilla.org/security/certoverride;1"].
getService(Ci.nsICertOverrideService); getService(Ci.nsICertOverrideService);
cos.rememberValidityOverride(this.host, -1, cert, this.bits, false); cos.rememberValidityOverride(this.host, -1, cert, this.bits, false);

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

@ -1,15 +1,15 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en-US" dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <html lang="en-US" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title> <title></title>
</head> </head>
<body> <body>
<h1>OMG, an update!!!!</h1> <h1>OMG, an update!!!!</h1>
<ul> <ul>
<li>Made everything more awesome</li> <li>Made everything more awesome</li>
<li>Added hot sauce</li> <li>Added hot sauce</li>
</ul> </ul>
</body> </body>
</html> </html>

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

@ -12,6 +12,10 @@ const Ci = Components.interfaces;
const extDir = gProfD.clone(); const extDir = gProfD.clone();
extDir.append("extensions"); extDir.append("extensions");
var gFastLoadService = AM_Cc["@mozilla.org/fast-load-service;1"].
getService(AM_Ci.nsIFastLoadService);
var gFastLoadFile = null;
/** /**
* Start the test by installing extensions. * Start the test by installing extensions.
*/ */
@ -27,10 +31,19 @@ function run_test() {
} }
}, "startupcache-invalidate", false); }, "startupcache-invalidate", false);
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
gFastLoadFile = gFastLoadService.newFastLoadFile("XUL");
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
startupManager(); startupManager();
// nsAppRunner takes care of clearing this when a new app is installed
do_check_true(gFastLoadFile.exists());
installAllFiles([do_get_addon("test_bug594058")], function() { installAllFiles([do_get_addon("test_bug594058")], function() {
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
do_check_true(cachePurged); do_check_true(cachePurged);
cachePurged = false; cachePurged = false;
@ -47,15 +60,20 @@ function run_test() {
otherFile.lastModifiedTime = pastTime; otherFile.lastModifiedTime = pastTime;
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
cachePurged = false; cachePurged = false;
otherFile.lastModifiedTime = pastTime + 5000; otherFile.lastModifiedTime = pastTime + 5000;
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
do_check_true(cachePurged); do_check_true(cachePurged);
cachePurged = false; cachePurged = false;
restartManager(); restartManager();
do_check_true(!cachePurged); do_check_true(gFastLoadFile.exists());
do_check_false(cachePurged);
do_test_finished(); do_test_finished();
}); });

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

@ -85,11 +85,19 @@ registerDirectory("XREUSysExt", userDir.parent);
const profileDir = gProfD.clone(); const profileDir = gProfD.clone();
profileDir.append("extensions"); profileDir.append("extensions");
var gFastLoadService = AM_Cc["@mozilla.org/fast-load-service;1"].
getService(AM_Ci.nsIFastLoadService);
var gFastLoadFile = null;
// Set up the profile // Set up the profile
function run_test() { function run_test() {
do_test_pending(); do_test_pending();
startupManager(); startupManager();
gFastLoadFile = gFastLoadService.newFastLoadFile("XUL");
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
"addon3@tests.mozilla.org", "addon3@tests.mozilla.org",
@ -127,6 +135,9 @@ function run_test_1() {
writeInstallRDFForExtension(addon5, profileDir); writeInstallRDFForExtension(addon5, profileDir);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
"addon3@tests.mozilla.org", "addon3@tests.mozilla.org",
@ -203,6 +214,8 @@ function run_test_2() {
dest.remove(true); dest.remove(true);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -257,6 +270,8 @@ function run_test_3() {
writeInstallRDFForExtension(addon3, profileDir, "addon4@tests.mozilla.org"); writeInstallRDFForExtension(addon3, profileDir, "addon4@tests.mozilla.org");
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -308,6 +323,8 @@ function run_test_4() {
Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_SYSTEM); Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_SYSTEM);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -340,6 +357,8 @@ function run_test_5() {
Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_USER); Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_USER);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -378,6 +397,8 @@ function run_test_6() {
Services.prefs.clearUserPref("extensions.enabledScopes"); Services.prefs.clearUserPref("extensions.enabledScopes");
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -420,6 +441,8 @@ function run_test_7() {
dest.remove(true); dest.remove(true);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -467,6 +490,8 @@ function run_test_8() {
Services.prefs.setIntPref("extensions.enabledScopes", 0); Services.prefs.setIntPref("extensions.enabledScopes", 0);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -508,6 +533,8 @@ function run_test_9() {
writeInstallRDFForExtension(addon2, profileDir); writeInstallRDFForExtension(addon2, profileDir);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -558,6 +585,8 @@ function run_test_10() {
writeInstallRDFForExtension(addon1, userDir); writeInstallRDFForExtension(addon1, userDir);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",
@ -608,6 +637,8 @@ function run_test_11() {
dest.remove(true); dest.remove(true);
restartManager(); restartManager();
do_check_false(gFastLoadFile.exists());
gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org", "addon2@tests.mozilla.org",

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

@ -1,5 +1,7 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Test whether a request for auth for an XPI switches to the appropriate tab // Test whether a request for auth for an XPI switches to the appropriate tab
var gNewTab;
function test() { function test() {
Harness.authenticationCallback = get_auth_info; Harness.authenticationCallback = get_auth_info;
Harness.downloadFailedCallback = download_failed; Harness.downloadFailedCallback = download_failed;

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

@ -27,10 +27,11 @@ function get_item(items, url) {
return items[i]; return items[i];
} }
ok(false, "Item for " + url + " was not listed"); ok(false, "Item for " + url + " was not listed");
return null;
} }
function confirm_install(window) { function confirm_install(window) {
items = window.document.getElementById("itemList").childNodes; let items = window.document.getElementById("itemList").childNodes;
is(items.length, 2, "Should be 2 items listed in the confirmation dialog"); is(items.length, 2, "Should be 2 items listed in the confirmation dialog");
let item = get_item(items, TESTROOT + "signed.xpi"); let item = get_item(items, TESTROOT + "signed.xpi");
if (item) { if (item) {

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

@ -16,6 +16,7 @@ function get_item(items, name) {
return items[i]; return items[i];
} }
ok(false, "Item for " + name + " was not listed"); ok(false, "Item for " + name + " was not listed");
return null;
} }
function confirm_install(window) { function confirm_install(window) {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше