зеркало из https://github.com/mozilla/pjs.git
Merging mozilla-central to Places.
This commit is contained in:
Коммит
9bd9238f38
|
@ -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)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче